[knopflerfish-osgi] 02/13: Imported Upstream version 5.1.0+dfsg1

Felix Natter fnatter-guest at moszumanska.debian.org
Tue Mar 3 19:14:43 UTC 2015


This is an automated email from the git hooks/post-receive script.

fnatter-guest pushed a commit to branch master
in repository knopflerfish-osgi.

commit 136782c4b6b91530e1967b9f19ac3d1a5eca7955
Author: Felix Natter <fnatter at gmx.net>
Date:   Tue Mar 3 19:26:40 2015 +0100

    Imported Upstream version 5.1.0+dfsg1
---
 LICENSE.txt                                        |   31 +
 META-INF/MANIFEST.MF                               |    9 +
 NOTICE.txt                                         |  153 ++
 README.txt                                         |   55 +
 ant/android.xml                                    |  101 +
 ant/ant_templates/mvn_repo.xml                     |  167 ++
 ant/build.xml                                      |   36 +
 ant/build_example.xml                              |   79 +
 ant/bundle_junit.xml                               |   75 +
 ant/bundlebuild.xml                                | 1102 ++++++++++
 ant/bundlebuild_include.xml                        |   52 +
 ant/bundletasks.xml                                |  286 +++
 ant/console_interactions.xml                       |  183 ++
 ant/docbuild_include.xml                           |   56 +
 ant/html_template/bundle_header.html               |   81 +
 ant/html_template/bundle_index.html                |   42 +
 ant/html_template/bundle_info.html                 |  151 ++
 ant/html_template/bundle_list.html                 |   51 +
 ant/html_template/bundle_main.html                 |   41 +
 ant/html_template/bundledoc.html                   |   34 +
 ant/html_template/bundledoc_ext.html               |   20 +
 ant/html_template/frameworkdoc.html                |   31 +
 ant/html_template/mvn_dep_mgmt.xsl                 |  153 ++
 ant/html_template/package_list.html                |   49 +
 ant/html_template/style.css                        |  205 ++
 ant/readme.txt                                     |   95 +
 .../knopflerfish/ant/taskdefs/bundle/Bundle.java   |  748 +++++++
 .../ant/taskdefs/bundle/BundleArchives.java        | 1027 ++++++++++
 .../ant/taskdefs/bundle/BundleClasspathTask.java   |  362 ++++
 .../taskdefs/bundle/BundleHTMLExtractorTask.java   | 1186 +++++++++++
 .../ant/taskdefs/bundle/BundleInfoTask.java        | 1397 +++++++++++++
 .../taskdefs/bundle/BundleJavadocHelperTask.java   |  525 +++++
 .../ant/taskdefs/bundle/BundleLocator.java         |  909 +++++++++
 .../ant/taskdefs/bundle/BundleManifestTask.java    | 1119 +++++++++++
 .../ant/taskdefs/bundle/BundleMvnAntTask.java      |  986 +++++++++
 .../ant/taskdefs/bundle/BundlePackagesInfo.java    |  733 +++++++
 .../taskdefs/bundle/BundleUserDocNavigateTask.java |  470 +++++
 .../ant/taskdefs/bundle/ByteFormatterTask.java     |  251 +++
 .../ant/taskdefs/bundle/ClassAnalyserASM.java      |  330 +++
 .../knopflerfish/ant/taskdefs/bundle/FileUtil.java |  156 ++
 .../ant/taskdefs/bundle/HtmlFragment.java          |  102 +
 .../ant/taskdefs/bundle/MakeHTMLTask.java          |  731 +++++++
 .../ant/taskdefs/bundle/MethodAnalyserASM.java     |  479 +++++
 .../ant/taskdefs/bundle/OSGiPackage.java           |   59 +
 .../org/knopflerfish/ant/taskdefs/bundle/Util.java |  870 ++++++++
 .../knopflerfish/ant/taskdefs/bundle/antlib.xml    |   25 +
 ant/xargs.xml                                      |  108 +
 ant/xsl/repository2html.xsl                        |  118 ++
 changelog.txt                                      |  374 ++++
 docs/android_dalvik_tutorial.html                  |  294 +++
 docs/building.html                                 |  239 +++
 docs/bundledoc/bundledoc_hdr.html                  |   66 +
 docs/bundledoc/bundledoc_list.html                 |   92 +
 docs/bundledoc/bundledoc_main.html                 |   33 +
 docs/bundledoc/cm/cm_data.dtd                      |  111 +
 docs/bundledoc/cm/index.html                       |  171 ++
 docs/bundledoc/cm_cmd/index.html                   |  147 ++
 docs/bundledoc/cm_desktop/images/cm_desktop.png    |  Bin 0 -> 60740 bytes
 .../bundledoc/cm_desktop/images/cm_desktop_300.png |  Bin 0 -> 36958 bytes
 .../cm_desktop/images/cm_desktop_systembundle.png  |  Bin 0 -> 47391 bytes
 .../images/cm_desktop_systembundle_300.png         |  Bin 0 -> 26009 bytes
 docs/bundledoc/cm_desktop/images/frag.png          |  Bin 0 -> 1546 bytes
 docs/bundledoc/cm_desktop/images/lib.png           |  Bin 0 -> 1479 bytes
 docs/bundledoc/cm_desktop/index.html               |  152 ++
 docs/bundledoc/component/index.html                |   71 +
 docs/bundledoc/console/index.html                  |  376 ++++
 docs/bundledoc/consoletcp/index.html               |  101 +
 docs/bundledoc/consoletelnet/index.html            |  116 ++
 docs/bundledoc/consoletty/index.html               |   65 +
 docs/bundledoc/crimson/index.html                  |   65 +
 docs/bundledoc/desktop/images/bundle.png           |  Bin 0 -> 2597 bytes
 docs/bundledoc/desktop/images/bundle_active.png    |  Bin 0 -> 7985 bytes
 docs/bundledoc/desktop/images/desktop_details.png  |  Bin 0 -> 102524 bytes
 docs/bundledoc/desktop/images/desktop_graph.png    |  Bin 0 -> 220563 bytes
 docs/bundledoc/desktop/images/desktop_icons.png    |  Bin 0 -> 61275 bytes
 docs/bundledoc/desktop/images/desktop_main.png     |  Bin 0 -> 152499 bytes
 docs/bundledoc/desktop/images/desktop_main_300.png |  Bin 0 -> 49579 bytes
 docs/bundledoc/desktop/images/frag.png             |  Bin 0 -> 1546 bytes
 docs/bundledoc/desktop/images/lib.png              |  Bin 0 -> 1604 bytes
 docs/bundledoc/desktop/images/lib_resolved.png     |  Bin 0 -> 4214 bytes
 docs/bundledoc/desktop/images/scr.png              |  Bin 0 -> 2253 bytes
 docs/bundledoc/desktop/images/scr_active.png       |  Bin 0 -> 2346 bytes
 docs/bundledoc/desktop/images/scr_resolved.png     |  Bin 0 -> 2265 bytes
 docs/bundledoc/desktop/index.html                  |  404 ++++
 docs/bundledoc/device/index.html                   |   90 +
 docs/bundledoc/dirdeployer/dirdeployer.xml         |   26 +
 docs/bundledoc/dirdeployer/index.html              |  276 +++
 docs/bundledoc/event/index.html                    |  126 ++
 docs/bundledoc/framework/index.html                | 1227 +++++++++++
 docs/bundledoc/frameworkcommands/index.html        |   86 +
 docs/bundledoc/http/index.html                     |  380 ++++
 .../bundledoc/httpconsole/images/bundle-active.png |  Bin 0 -> 2550 bytes
 .../httpconsole/images/bundle-lib-active.png       |  Bin 0 -> 1697 bytes
 docs/bundledoc/httpconsole/images/bundle.png       |  Bin 0 -> 2544 bytes
 .../bundledoc/httpconsole/images/document-open.png |  Bin 0 -> 919 bytes
 docs/bundledoc/httpconsole/images/go-home.png      |  Bin 0 -> 920 bytes
 docs/bundledoc/httpconsole/images/help.png         |  Bin 0 -> 1359 bytes
 .../httpconsole/images/httpconsole_login.png       |  Bin 0 -> 3072 bytes
 .../httpconsole/images/httpconsole_openfile.png    |  Bin 0 -> 1696 bytes
 .../httpconsole/images/httpconsole_ppc2003_1.png   |  Bin 0 -> 19629 bytes
 .../httpconsole/images/httpconsole_ppc2003_3.png   |  Bin 0 -> 18738 bytes
 docs/bundledoc/httpconsole/images/info.png         |  Bin 0 -> 1204 bytes
 docs/bundledoc/httpconsole/images/lib.png          |  Bin 0 -> 1067 bytes
 docs/bundledoc/httpconsole/images/openurl.png      |  Bin 0 -> 1319 bytes
 docs/bundledoc/httpconsole/images/player_eject.png |  Bin 0 -> 729 bytes
 docs/bundledoc/httpconsole/images/player_play.png  |  Bin 0 -> 961 bytes
 docs/bundledoc/httpconsole/images/player_stop.png  |  Bin 0 -> 513 bytes
 docs/bundledoc/httpconsole/images/view-refresh.png |  Bin 0 -> 1364 bytes
 docs/bundledoc/httpconsole/index.html              |  266 +++
 docs/bundledoc/index.html                          |   42 +
 docs/bundledoc/junit/index.html                    |  268 +++
 docs/bundledoc/kxml/index.html                     |   63 +
 docs/bundledoc/log/index.html                      |  168 ++
 docs/bundledoc/logcommands/index.html              |  433 ++++
 docs/bundledoc/prefs/index.html                    |   69 +
 .../repository_desktop/images/repository_add.png   |  Bin 0 -> 115295 bytes
 .../images/repository_add_300.png                  |  Bin 0 -> 29822 bytes
 .../images/repository_details_displayer.png        |  Bin 0 -> 114702 bytes
 .../images/repository_details_displayer_300.png    |  Bin 0 -> 47672 bytes
 .../images/repository_settings.png                 |  Bin 0 -> 30397 bytes
 .../images/repository_settings_300.png             |  Bin 0 -> 11735 bytes
 docs/bundledoc/repository_desktop/index.html       |  141 ++
 .../repository_xml/images/repository_add.png       |  Bin 0 -> 115295 bytes
 .../repository_xml/images/repository_add_300.png   |  Bin 0 -> 29822 bytes
 .../images/repository_details_displayer.png        |  Bin 0 -> 114702 bytes
 .../images/repository_details_displayer_300.png    |  Bin 0 -> 47672 bytes
 .../repository_xml/images/repository_settings.png  |  Bin 0 -> 30397 bytes
 .../images/repository_settings_300.png             |  Bin 0 -> 11735 bytes
 docs/bundledoc/repository_xml/index.html           |  127 ++
 docs/bundledoc/repositorycommands/index.html       |  203 ++
 docs/bundledoc/scrcommands/index.html              |  173 ++
 docs/bundledoc/serial/index.html                   |   69 +
 docs/bundledoc/soap/index.html                     |   49 +
 docs/bundledoc/sslj2sp/index.html                  |  169 ++
 docs/bundledoc/trayicon_fw/index.html              |   60 +
 docs/bundledoc/util/index.html                     |  139 ++
 docs/bundledoc/xalan/index.html                    |   63 +
 docs/bundledoc/xerces/index.html                   |  106 +
 docs/bundledoc/xml/index.html                      |   55 +
 docs/bundledoc/xml_index/index.html                |   50 +
 docs/changelog.html                                |  485 +++++
 docs/components.html                               |  718 +++++++
 docs/css/kf_man.css                                |  110 +
 docs/css/knopflerfish.css                          |  449 +++++
 docs/desktop.html                                  |  243 +++
 docs/examples/cpa/admin/build.xml                  |   26 +
 docs/examples/cpa/admin/bundle.manifest            |   13 +
 .../cpaexample/bundle/admin/AdminActivator.java    |   61 +
 docs/examples/cpa/build.xml                        |   34 +
 docs/examples/cpa/caller/build.xml                 |   28 +
 docs/examples/cpa/caller/bundle.manifest           |   13 +
 .../cpa/caller/resources/OSGI-INF/permissions.perm |    3 +
 .../cpaexample/bundle/caller/CallerActivator.java  |   38 +
 docs/examples/cpa/init.xargs                       |   33 +
 docs/examples/cpa/init.xargs.in                    |   33 +
 docs/examples/cpa/props.xargs                      |   13 +
 docs/examples/cpa/user/build.xml                   |   28 +
 docs/examples/cpa/user/bundle.manifest             |   13 +
 .../cpa/user/resources/OSGI-INF/permissions.perm   |    6 +
 .../cpaexample/service/user/UserService.java       |   85 +
 docs/images/active_overlay.gif                     |  Bin 0 -> 878 bytes
 docs/images/android_app.png                        |  Bin 0 -> 22953 bytes
 docs/images/bundle_active.gif                      |  Bin 0 -> 1478 bytes
 docs/images/bundle_installed.gif                   |  Bin 0 -> 1473 bytes
 docs/images/dalvik_httproot.png                    |  Bin 0 -> 97249 bytes
 docs/images/desktop-clip.png                       |  Bin 0 -> 28012 bytes
 docs/images/desktop1.gif                           |  Bin 0 -> 26607 bytes
 docs/images/desktop1_200.gif                       |  Bin 0 -> 7770 bytes
 docs/images/desktop1_small.gif                     |  Bin 0 -> 20627 bytes
 docs/images/desktop_details.gif                    |  Bin 0 -> 14071 bytes
 docs/images/desktop_details.png                    |  Bin 0 -> 11877 bytes
 docs/images/desktop_drop_view.gif                  |  Bin 0 -> 55880 bytes
 docs/images/desktop_drop_view.png                  |  Bin 0 -> 45753 bytes
 docs/images/desktop_icons.gif                      |  Bin 0 -> 11094 bytes
 docs/images/desktop_info_log.gif                   |  Bin 0 -> 59270 bytes
 docs/images/desktop_info_log.png                   |  Bin 0 -> 43437 bytes
 docs/images/desktop_info_manifest.gif              |  Bin 0 -> 30038 bytes
 docs/images/desktop_info_manifest.png              |  Bin 0 -> 45228 bytes
 docs/images/desktop_info_manifest_200.gif          |  Bin 0 -> 6943 bytes
 docs/images/desktop_info_manifest_200.png          |  Bin 0 -> 15593 bytes
 docs/images/desktop_info_manifest_400.gif          |  Bin 0 -> 26469 bytes
 docs/images/desktop_info_manifest_400.png          |  Bin 0 -> 44601 bytes
 docs/images/desktop_info_packages.gif              |  Bin 0 -> 47870 bytes
 docs/images/desktop_info_packages.png              |  Bin 0 -> 42946 bytes
 docs/images/desktop_info_services.gif              |  Bin 0 -> 51020 bytes
 docs/images/desktop_info_services.png              |  Bin 0 -> 44623 bytes
 docs/images/desktop_list.gif                       |  Bin 0 -> 10394 bytes
 docs/images/desktop_on_eclipse.png                 |  Bin 0 -> 67288 bytes
 docs/images/desktop_open_bundle.gif                |  Bin 0 -> 32814 bytes
 docs/images/desktop_open_bundle.png                |  Bin 0 -> 24701 bytes
 docs/images/desktop_set_startlevel.gif             |  Bin 0 -> 52259 bytes
 docs/images/desktop_set_startlevel.png             |  Bin 0 -> 43373 bytes
 docs/images/desktop_setbundle_startlevel.gif       |  Bin 0 -> 62956 bytes
 docs/images/desktop_setbundle_startlevel.png       |  Bin 0 -> 43113 bytes
 docs/images/desktop_spin.gif                       |  Bin 0 -> 31370 bytes
 docs/images/desktop_spin.png                       |  Bin 0 -> 31723 bytes
 docs/images/desktop_timeline.gif                   |  Bin 0 -> 8813 bytes
 docs/images/desktop_timeline.png                   |  Bin 0 -> 13117 bytes
 docs/images/fadeout_15.png                         |  Bin 0 -> 290 bytes
 docs/images/install_options.png                    |  Bin 0 -> 39642 bytes
 docs/images/kf300_black.png                        |  Bin 0 -> 6886 bytes
 docs/images/knopflerfish-bottom.jpg                |  Bin 0 -> 769 bytes
 docs/images/knopflerfish-small.gif                 |  Bin 0 -> 2988 bytes
 docs/images/knopflerfish-top.jpg                   |  Bin 0 -> 769 bytes
 docs/images/knopflerfish.jpg                       |  Bin 0 -> 12200 bytes
 docs/images/knopflerfish4_red400pxl.gif            |  Bin 0 -> 1715 bytes
 docs/images/knopflerfish_red120pxl.gif             |  Bin 0 -> 505 bytes
 docs/images/knopflerfish_red140pxl.gif             |  Bin 0 -> 582 bytes
 docs/images/knopflerfish_red200pxl.gif             |  Bin 0 -> 822 bytes
 docs/images/knopfleri.gif                          |  Bin 0 -> 10843 bytes
 docs/images/knopfleri.jpg                          |  Bin 0 -> 3331 bytes
 docs/images/knopfleri_2.jpg                        |  Bin 0 -> 3436 bytes
 docs/images/knopfleri_3.jpg                        |  Bin 0 -> 14366 bytes
 docs/images/legend.gif                             |  Bin 0 -> 1687 bytes
 docs/images/lib_installed.gif                      |  Bin 0 -> 1526 bytes
 docs/images/makewave_logo.png                      |  Bin 0 -> 1349 bytes
 docs/images/makewave_logo_126x16.gif               |  Bin 0 -> 1412 bytes
 docs/images/mem_256.gif                            |  Bin 0 -> 7571 bytes
 docs/images/no_remote_framework.png                |  Bin 0 -> 10880 bytes
 docs/images/osgi-fish.jpg                          |  Bin 0 -> 2891 bytes
 docs/images/osgi-knopflerfish.gif                  |  Bin 0 -> 10843 bytes
 docs/images/remote_framework.png                   |  Bin 0 -> 10968 bytes
 docs/images/shortfadeout_20px.png                  |  Bin 0 -> 143 bytes
 docs/images/time_256.gif                           |  Bin 0 -> 7308 bytes
 docs/images/tray.gif                               |  Bin 0 -> 7023 bytes
 docs/index.html                                    |  166 ++
 docs/installing.html                               |  177 ++
 .../applicationadmin_api-4.0.0.html                |  215 ++
 .../basicdriverlocator-4.0.0.html                  |  202 ++
 .../basicdriverlocator_all-4.0.0.html              |  202 ++
 docs/jars/blueprint/blueprint_api-5.0.0.html       |  347 ++++
 docs/jars/classpatcher/classpatcher_all-5.0.0.html |  199 ++
 docs/jars/cm/cm-5.0.1.html                         |  332 +++
 docs/jars/cm/cm_all-5.0.1.html                     |  351 ++++
 docs/jars/cm/cm_api-5.0.1.html                     |  339 ++++
 docs/jars/cm_cmd/cm_cmd-5.0.1.html                 |  204 ++
 docs/jars/cm_desktop/cm_desktop-5.0.2.html         |  281 +++
 docs/jars/cm_desktop/cm_desktop_all-5.0.2.html     |  288 +++
 docs/jars/comm-linux/comm-linux_all-3.0.0.html     |  201 ++
 docs/jars/comm-win32/comm-win32_all-3.0.0.html     |  198 ++
 docs/jars/command/command_all-0.2.html             |  284 +++
 docs/jars/command/command_api-0.2.html             |  278 +++
 docs/jars/commandtty/commandtty-4.0.1.html         |  198 ++
 .../commons-logging_all-2.0.0.kf4-001.html         |  284 +++
 docs/jars/component/component_all-5.0.3.html       |  343 ++++
 docs/jars/component/component_api-5.0.3.html       |  333 +++
 .../component_annotations_api-1.0.0.html           |  233 +++
 docs/jars/connectors/connectors-3.0.0.html         |  231 +++
 docs/jars/connectors/connectors_all-3.0.0.html     |  231 +++
 docs/jars/console/console-4.0.1.html               |  263 +++
 docs/jars/console/console_all-4.0.1.html           |  282 +++
 docs/jars/console/console_api-4.0.1.html           |  278 +++
 .../console2command/console2command-2.0.0.html     |  208 ++
 docs/jars/consoletcp/consoletcp-5.0.0.html         |  201 ++
 docs/jars/consoletcp/consoletcp_all-5.0.0.html     |  201 ++
 docs/jars/consoletelnet/consoletelnet-4.0.1.html   |  273 +++
 docs/jars/consoletty/consoletty-4.0.1.html         |  202 ++
 docs/jars/coordinator/coordinator_api-1.0.0.html   |  215 ++
 docs/jars/crimson/crimson-2.1.0.kf4-001.html       |  205 ++
 .../deploymentadmin/deploymentadmin_api-4.0.0.html |  242 +++
 docs/jars/desktop/desktop-5.0.1.html               |  825 ++++++++
 docs/jars/desktop/desktop_all-5.0.1.html           |  899 +++++++++
 docs/jars/desktop/desktop_api-5.0.1.html           |  794 ++++++++
 docs/jars/desktop_jvm/desktop_jvm-1.0.0.html       |  205 ++
 docs/jars/desktop_jvm/desktop_jvm_all-1.0.0.html   |  205 ++
 docs/jars/device/device-4.0.1.html                 |  244 +++
 docs/jars/device/device_all-4.0.1.html             |  252 +++
 docs/jars/device/device_api-4.0.1.html             |  247 +++
 docs/jars/dirdeployer/dirdeployer_all-4.0.1.html   |  242 +++
 docs/jars/dirdeployer/dirdeployer_api-4.0.1.html   |  220 ++
 docs/jars/dmt/dmt_api-5.0.0.html                   |  336 ++++
 docs/jars/event/event_all-4.0.1.html               |  284 +++
 docs/jars/event/event_api-4.0.1.html               |  272 +++
 .../foreignapplication_api-4.0.0.html              |  210 ++
 docs/jars/framework.html                           |  294 +++
 .../frameworkcommands/frameworkcommands-4.0.1.html |  216 ++
 docs/jars/header.html                              |   81 +
 docs/jars/http/http-4.0.5.html                     |  438 ++++
 docs/jars/http/http_all-4.0.5.html                 |  471 +++++
 docs/jars/http/http_api-4.0.5.html                 |  429 ++++
 docs/jars/httpconsole/httpconsole_all-4.0.1.html   |  312 +++
 docs/jars/httproot/httproot-4.0.0.html             |  201 ++
 docs/jars/index.html                               |   42 +
 docs/jars/io/io_all-4.0.0.html                     |  212 ++
 docs/jars/io/io_api-4.0.0.html                     |  210 ++
 docs/jars/jinidriver/jinidriver_all-0.1.0.html     |  277 +++
 docs/jars/jsdk/jsdk_api-2.5.0.kf3-2.html           |  392 ++++
 docs/jars/junit/junit_all-3.8.1.kf4-001.html       |  243 +++
 docs/jars/junit_runner/junit_runner_all-4.0.0.html |  190 ++
 docs/jars/kf_metatype/kf_metatype_all-5.0.2.html   |  263 +++
 docs/jars/kxml/kxml-2.3.0.kf4-001.html             |  240 +++
 docs/jars/list.html                                |  158 ++
 docs/jars/log/log-5.0.0.html                       |  287 +++
 docs/jars/log/log_all-5.0.0.html                   |  329 +++
 docs/jars/log/log_api-5.0.0.html                   |  326 +++
 docs/jars/logcommands/logcommands-5.0.0.html       |  209 ++
 docs/jars/main.html                                |  154 ++
 docs/jars/measurement/measurement-4.0.0.html       |  204 ++
 docs/jars/metatype/metatype-4.0.0.html             |  215 ++
 docs/jars/monitor/monitor_api-4.0.0.html           |  218 ++
 docs/jars/namespace/namespace_api-1.0.0.html       |  219 ++
 docs/jars/package_list.html                        |  424 ++++
 docs/jars/position/position-4.0.0.html             |  195 ++
 docs/jars/prefs/prefs_all-4.0.2.html               |  253 +++
 docs/jars/prefs/prefs_api-4.0.2.html               |  242 +++
 docs/jars/provisioning/provisioning_api-4.0.0.html |  193 ++
 docs/jars/remotefw/remotefw_api-4.0.0.html         |  189 ++
 .../remoteserviceadmin_api-1.0.0.html              |  245 +++
 docs/jars/repoindex_kf/repoindex_kf_all-1.0.1.html |  231 +++
 docs/jars/repository/repository_api-1.0.0.html     |  210 ++
 .../repository_desktop_all-1.1.1.html              |  273 +++
 .../repository_xml/repository_xml_all-1.0.2.html   |  246 +++
 .../repository_xml/repository_xml_api-1.0.2.html   |  234 +++
 .../repositorycommands-1.1.1.html                  |  202 ++
 .../repositorymanager_all-1.2.0.html               |  240 +++
 .../repositorymanager_api-1.2.0.html               |  226 +++
 docs/jars/resolver/resolver_api-1.0.0.html         |  212 ++
 .../rxtxcomm-linux-arm-2.1.7.1.html                |  183 ++
 .../rxtxcomm-linux-x86-2.2.0.pre2.html             |  183 ++
 docs/jars/rxtxcomm/rxtxcomm_api-2.2.0.pre2.html    |  345 ++++
 docs/jars/scrcommands/scrcommands-4.0.1.html       |  198 ++
 .../serialportdevice_all-4.0.0.html                |  224 +++
 .../serialportdevice_api-4.0.0.html                |  211 ++
 .../serviceloader/serviceloader_api-1.0.0.html     |  195 ++
 docs/jars/sslj2sp/sslj2sp-4.0.0.html               |  206 ++
 docs/jars/style.css                                |  205 ++
 docs/jars/subsystem/subsystem_api-1.0.0.html       |  210 ++
 docs/jars/threadio/threadio-0.2.0.html             |  209 ++
 docs/jars/threadio/threadio_all-0.2.0.html         |  214 ++
 docs/jars/threadio/threadio_api-0.2.0.html         |  212 ++
 docs/jars/trayicon_fw/trayicon_fw-4.0.0.html       |  196 ++
 docs/jars/upnp/upnp_api-4.0.0.html                 |  228 +++
 docs/jars/useradmin/useradmin-4.1.1.html           |  381 ++++
 docs/jars/useradmin/useradmin_all-4.1.1.html       |  387 ++++
 docs/jars/useradmin/useradmin_api-4.1.1.html       |  349 ++++
 docs/jars/util/util-4.1.0.html                     |  297 +++
 docs/jars/wireadmin/wireadmin_api-5.0.0.html       |  240 +++
 docs/jars/xalan/xalan-2.7.1.kf3_01.html            |  219 ++
 docs/jars/xerces/xerces-2.10.1.kf5.html            |  292 +++
 docs/jars/xml/xml-4.0.0.html                       |  196 ++
 docs/license.html                                  |  150 ++
 docs/osgi_service_tutorial.html                    |  626 ++++++
 docs/osgi_with_security.html                       |  549 +++++
 docs/programming.html                              | 1531 ++++++++++++++
 docs/release_notes.html                            |  367 ++++
 docs/running.html                                  |  308 +++
 docs/testing.html                                  |  150 ++
 docs/tutorials.html                                |  144 ++
 .../kf_osgi_tutorial/example_source/build.xml      |   31 +
 .../example_source/dateservice/build.xml           |   39 +
 .../example_source/dateservice/manifest.mf         |   10 +
 .../tutorial/dateservice/DateService.java          |    7 +
 .../tutorial/dateservice/impl/Activator.java       |   32 +
 .../tutorial/dateservice/impl/DateServiceImpl.java |   13 +
 .../example_source/dateserviceuser_bad/build.xml   |   42 +
 .../example_source/dateserviceuser_bad/manifest.mf |    9 +
 .../dateserviceuserbad/impl/Activator.java         |   35 +
 .../example_source/dateserviceuser_bad2/build.xml  |   42 +
 .../dateserviceuser_bad2/manifest.mf               |    9 +
 .../dateserviceuserbad2/impl/Activator.java        |   39 +
 .../dateserviceuser_declarative/build.xml          |   43 +
 .../dateserviceuser_declarative/manifest.mf        |    9 +
 .../resources/OSGI-INF/component.xml               |   13 +
 .../tutorial/common/ServiceUserThread.java         |   40 +
 .../dateserviceuserdeclarative/impl/Component.java |   48 +
 .../dateserviceuser_listener/build.xml             |   42 +
 .../dateserviceuser_listener/manifest.mf           |    9 +
 .../tutorial/common/ServiceUserThread.java         |   40 +
 .../dateserviceuserlistener/impl/Activator.java    |   87 +
 .../dateserviceuser_tracker/build.xml              |   42 +
 .../dateserviceuser_tracker/manifest.mf            |    9 +
 .../tutorial/common/ServiceUserThread.java         |   40 +
 .../dateserviceusertracker/impl/Activator.java     |   83 +
 .../example_source/simplebundle/build.xml          |   39 +
 .../example_source/simplebundle/manifest.mf        |    9 +
 .../tutorial/simplebundle/impl/Activator.java      |   27 +
 .../simplebundle/impl/HelloWorldThread.java        |   29 +
 .../kf_osgi_tutorial/kf_osgi_tutorial.odt          |  Bin 0 -> 361519 bytes
 .../kf_osgi_tutorial/kf_osgi_tutorial.pdf          |  Bin 0 -> 496071 bytes
 docs/tutorials/kf_osgi_tutorial/readme.txt         |    6 +
 fish16x16.gif                                      |  Bin 0 -> 990 bytes
 fish200x300.gif                                    |  Bin 0 -> 9473 bytes
 fish32x32.gif                                      |  Bin 0 -> 1328 bytes
 kf_16x16.gif                                       |  Bin 0 -> 990 bytes
 kf_32x32.gif                                       |  Bin 0 -> 1328 bytes
 knopflerfish_red400pxl.gif                         |  Bin 0 -> 7133 bytes
 osgi/build.xml                                     |  496 +++++
 osgi/framework/TODO                                |   11 +
 osgi/framework/build.xml                           |  435 ++++
 osgi/framework/doc/doc.properties                  |    3 +
 osgi/framework/doc/index.html                      | 1177 +++++++++++
 osgi/framework/libs/asm-license.txt                |   32 +
 .../org.osgi.framework.launch.FrameworkFactory     |    1 +
 osgi/framework/resources/automanifest.props        |   17 +
 osgi/framework/resources/exports                   |    1 +
 osgi/framework/resources/framework.policy          |    3 +
 osgi/framework/resources/help.txt                  |   52 +
 osgi/framework/resources/icon.png                  |  Bin 0 -> 981 bytes
 osgi/framework/resources/icon64.png                |  Bin 0 -> 1734 bytes
 osgi/framework/resources/kfsplash.gif              |  Bin 0 -> 5815 bytes
 osgi/framework/resources/packages.txt              |  255 +++
 osgi/framework/resources/release                   |    1 +
 osgi/framework/resources/version                   |    1 +
 .../src/org/knopflerfish/framework/Alias.java      |  120 ++
 .../org/knopflerfish/framework/AutoManifest.java   |  584 ++++++
 .../org/knopflerfish/framework/BundleArchive.java  |  241 +++
 .../framework/BundleCapabilityImpl.java            |  234 +++
 .../knopflerfish/framework/BundleClassLoader.java  | 1241 ++++++++++++
 .../framework/BundleClassLoaderListener.java       |   60 +
 .../knopflerfish/framework/BundleClassPath.java    |  528 +++++
 .../knopflerfish/framework/BundleContextImpl.java  |  481 +++++
 .../knopflerfish/framework/BundleGeneration.java   | 1260 ++++++++++++
 .../org/knopflerfish/framework/BundleHooks.java    |  185 ++
 .../src/org/knopflerfish/framework/BundleImpl.java | 1923 ++++++++++++++++++
 .../framework/BundleNameVersionCapability.java     |  124 ++
 .../org/knopflerfish/framework/BundlePackages.java | 1188 +++++++++++
 .../framework/BundleReferenceImpl.java             |   51 +
 .../framework/BundleRequirementImpl.java           |  284 +++
 .../framework/BundleResourceStream.java            |  167 ++
 .../knopflerfish/framework/BundleRevisionImpl.java |  231 +++
 .../framework/BundleRevisionsImpl.java             |   64 +
 .../org/knopflerfish/framework/BundleStorage.java  |  105 +
 .../org/knopflerfish/framework/BundleThread.java   |  308 +++
 .../framework/BundleURLConnection.java             |  165 ++
 .../framework/BundleURLStreamHandler.java          |  386 ++++
 .../org/knopflerfish/framework/BundleWireImpl.java |  161 ++
 .../knopflerfish/framework/BundleWiringImpl.java   |  378 ++++
 .../src/org/knopflerfish/framework/Bundles.java    |  474 +++++
 .../org/knopflerfish/framework/Capabilities.java   |   92 +
 .../framework/ContentHandlerWrapper.java           |  221 ++
 .../src/org/knopflerfish/framework/Debug.java      |  312 +++
 .../src/org/knopflerfish/framework/ExportPkg.java  |  404 ++++
 .../framework/ExportedPackageImpl.java             |  161 ++
 .../knopflerfish/framework/ExtensionContext.java   |  161 ++
 .../src/org/knopflerfish/framework/FWProps.java    |  500 +++++
 .../framework/FWResourceURLStreamHandler.java      |   75 +
 .../org/knopflerfish/framework/FileArchive.java    |  129 ++
 .../src/org/knopflerfish/framework/FileTree.java   |  138 ++
 .../src/org/knopflerfish/framework/Fragment.java   |  273 +++
 .../knopflerfish/framework/FrameworkContext.java   |  886 ++++++++
 .../framework/FrameworkFactoryImpl.java            |   52 +
 .../framework/FrameworkWiringImpl.java             |   88 +
 .../knopflerfish/framework/HeaderDictionary.java   |  163 ++
 .../src/org/knopflerfish/framework/ImportPkg.java  |  520 +++++
 .../knopflerfish/framework/IteratorIterator.java   |   84 +
 .../framework/IteratorIteratorSorted.java          |  126 ++
 .../src/org/knopflerfish/framework/LDAPExpr.java   |  742 +++++++
 .../org/knopflerfish/framework/ListenerEntry.java  |   79 +
 .../src/org/knopflerfish/framework/Listeners.java  |  547 +++++
 .../src/org/knopflerfish/framework/Main.java       | 1511 ++++++++++++++
 .../framework/MainClassBundleActivator.java        |  110 +
 .../knopflerfish/framework/PackageAdminImpl.java   |  501 +++++
 .../org/knopflerfish/framework/PermissionOps.java  |  435 ++++
 .../src/org/knopflerfish/framework/Pkg.java        |  250 +++
 .../framework/PropertiesDictionary.java            |  154 ++
 .../src/org/knopflerfish/framework/Queue.java      |  150 ++
 .../framework/ReferenceURLStreamHandler.java       |   96 +
 .../framework/RemoveOnlyCollection.java            |   74 +
 .../org/knopflerfish/framework/RequireBundle.java  |  267 +++
 .../knopflerfish/framework/RequiredBundleImpl.java |  137 ++
 .../src/org/knopflerfish/framework/Resolver.java   | 1421 +++++++++++++
 .../org/knopflerfish/framework/ResolverHooks.java  |  389 ++++
 .../framework/SecurePermissionOps.java             |  974 +++++++++
 .../framework/ServiceContentHandlerFactory.java    |  187 ++
 .../org/knopflerfish/framework/ServiceHooks.java   |  422 ++++
 .../framework/ServiceListenerEntry.java            |  104 +
 .../framework/ServiceListenerState.java            |  298 +++
 .../framework/ServiceReferenceImpl.java            |  373 ++++
 .../framework/ServiceRegistrationImpl.java         |  476 +++++
 .../framework/ServiceURLStreamHandlerFactory.java  |  285 +++
 .../src/org/knopflerfish/framework/Services.java   |  456 +++++
 .../framework/StartLevelController.java            |  680 +++++++
 .../org/knopflerfish/framework/SystemBundle.java   | 1057 ++++++++++
 .../framework/URLStreamHandlerWrapper.java         |  366 ++++
 .../src/org/knopflerfish/framework/Util.java       | 1309 ++++++++++++
 .../src/org/knopflerfish/framework/Validator.java  |   54 +
 .../org/knopflerfish/framework/WeavingHooks.java   |  508 +++++
 .../knopflerfish/framework/bundlestorage/Util.java |   90 +
 .../framework/bundlestorage/file/Archive.java      | 1546 ++++++++++++++
 .../bundlestorage/file/BundleArchiveImpl.java      |  612 ++++++
 .../bundlestorage/file/BundleStorageImpl.java      |  387 ++++
 .../framework/bundlestorage/memory/Archive.java    |  379 ++++
 .../bundlestorage/memory/BundleArchiveImpl.java    |  409 ++++
 .../bundlestorage/memory/BundleStorageImpl.java    |  227 +++
 .../permissions/ConditionalPermission.java         |  189 ++
 .../ConditionalPermissionAdminImpl.java            |  546 +++++
 .../permissions/ConditionalPermissionInfoImpl.java |  417 ++++
 .../ConditionalPermissionInfoStorage.java          |  520 +++++
 .../ConditionalPermissionSecurityManager.java      |   48 +
 .../ConditionalPermissionUpdateImpl.java           |   87 +
 .../framework/permissions/FrameworkPolicy.java     |  163 ++
 .../framework/permissions/KFSecurityManager.java   |  110 +
 .../framework/permissions/PermUtil.java            |  166 ++
 .../framework/permissions/PermissionAdminImpl.java |  164 ++
 .../permissions/PermissionInfoPermissions.java     |  263 +++
 .../permissions/PermissionInfoStorage.java         |  453 +++++
 .../framework/permissions/PermissionsHandle.java   |  163 ++
 .../framework/permissions/PermissionsWrapper.java  |  450 +++++
 .../framework/permissions/PostponementCheck.java   |  146 ++
 .../framework/validator/JKSValidator.java          |  281 +++
 .../framework/validator/SelfSignedValidator.java   |   99 +
 .../src/org/osgi/framework/AdaptPermission.java    |  613 ++++++
 .../src/org/osgi/framework/AdminPermission.java    | 1004 +++++++++
 .../src/org/osgi/framework/AllServiceListener.java |   60 +
 osgi/framework/src/org/osgi/framework/Bundle.java  | 1243 ++++++++++++
 .../src/org/osgi/framework/BundleActivator.java    |   86 +
 .../src/org/osgi/framework/BundleContext.java      |  864 ++++++++
 .../src/org/osgi/framework/BundleEvent.java        |  235 +++
 .../src/org/osgi/framework/BundleException.java    |  235 +++
 .../src/org/osgi/framework/BundleListener.java     |   47 +
 .../src/org/osgi/framework/BundlePermission.java   |  584 ++++++
 .../src/org/osgi/framework/BundleReference.java    |   36 +
 .../org/osgi/framework/CapabilityPermission.java   |  775 +++++++
 .../src/org/osgi/framework/Configurable.java       |   50 +
 .../src/org/osgi/framework/Constants.java          | 1703 ++++++++++++++++
 osgi/framework/src/org/osgi/framework/Filter.java  |  137 ++
 .../src/org/osgi/framework/FrameworkEvent.java     |  244 +++
 .../src/org/osgi/framework/FrameworkListener.java  |   48 +
 .../src/org/osgi/framework/FrameworkUtil.java      | 2121 ++++++++++++++++++++
 .../org/osgi/framework/InvalidSyntaxException.java |  120 ++
 .../src/org/osgi/framework/PackagePermission.java  |  777 +++++++
 .../src/org/osgi/framework/ServiceEvent.java       |  143 ++
 .../src/org/osgi/framework/ServiceException.java   |  131 ++
 .../src/org/osgi/framework/ServiceFactory.java     |  114 ++
 .../src/org/osgi/framework/ServiceListener.java    |   62 +
 .../src/org/osgi/framework/ServicePermission.java  |  910 +++++++++
 .../src/org/osgi/framework/ServiceReference.java   |  182 ++
 .../org/osgi/framework/ServiceRegistration.java    |  109 +
 .../src/org/osgi/framework/SignerProperty.java     |  110 +
 .../osgi/framework/SynchronousBundleListener.java  |   65 +
 .../osgi/framework/UnfilteredServiceListener.java  |   73 +
 osgi/framework/src/org/osgi/framework/Version.java |  398 ++++
 .../src/org/osgi/framework/VersionRange.java       |  509 +++++
 .../osgi/framework/hooks/bundle/CollisionHook.java |   85 +
 .../org/osgi/framework/hooks/bundle/EventHook.java |   61 +
 .../org/osgi/framework/hooks/bundle/FindHook.java  |   63 +
 .../osgi/framework/hooks/bundle/package-info.java  |   33 +
 .../org/osgi/framework/hooks/bundle/packageinfo    |    1 +
 .../framework/hooks/resolver/ResolverHook.java     |  207 ++
 .../hooks/resolver/ResolverHookFactory.java        |  104 +
 .../framework/hooks/resolver/package-info.java     |   33 +
 .../org/osgi/framework/hooks/resolver/packageinfo  |    1 +
 .../osgi/framework/hooks/service/EventHook.java    |   53 +
 .../framework/hooks/service/EventListenerHook.java |   59 +
 .../org/osgi/framework/hooks/service/FindHook.java |   60 +
 .../osgi/framework/hooks/service/ListenerHook.java |  129 ++
 .../osgi/framework/hooks/service/package-info.java |   33 +
 .../org/osgi/framework/hooks/service/packageinfo   |    1 +
 .../framework/hooks/weaving/WeavingException.java  |   51 +
 .../osgi/framework/hooks/weaving/WeavingHook.java  |   63 +
 .../osgi/framework/hooks/weaving/WovenClass.java   |  157 ++
 .../osgi/framework/hooks/weaving/package-info.java |   35 +
 .../org/osgi/framework/hooks/weaving/packageinfo   |    1 +
 .../src/org/osgi/framework/launch/Framework.java   |  360 ++++
 .../osgi/framework/launch/FrameworkFactory.java    |   72 +
 .../org/osgi/framework/launch/package-info.java    |   33 +
 .../src/org/osgi/framework/launch/packageinfo      |    1 +
 .../namespace/AbstractWiringNamespace.java         |   56 +
 .../osgi/framework/namespace/BundleNamespace.java  |  153 ++
 .../namespace/ExecutionEnvironmentNamespace.java   |   55 +
 .../osgi/framework/namespace/HostNamespace.java    |  174 ++
 .../framework/namespace/IdentityNamespace.java     |  162 ++
 .../osgi/framework/namespace/PackageNamespace.java |  112 ++
 .../org/osgi/framework/namespace/package-info.java |   29 +
 .../src/org/osgi/framework/namespace/packageinfo   |    1 +
 .../src/org/osgi/framework/package-info.java       |   33 +
 osgi/framework/src/org/osgi/framework/packageinfo  |    1 +
 .../framework/startlevel/BundleStartLevel.java     |  106 +
 .../framework/startlevel/FrameworkStartLevel.java  |  161 ++
 .../osgi/framework/startlevel/package-info.java    |   80 +
 .../src/org/osgi/framework/startlevel/packageinfo  |    1 +
 .../osgi/framework/wiring/BundleCapability.java    |   80 +
 .../osgi/framework/wiring/BundleRequirement.java   |   96 +
 .../org/osgi/framework/wiring/BundleRevision.java  |  304 +++
 .../org/osgi/framework/wiring/BundleRevisions.java |   66 +
 .../src/org/osgi/framework/wiring/BundleWire.java  |  108 +
 .../org/osgi/framework/wiring/BundleWiring.java    |  502 +++++
 .../org/osgi/framework/wiring/FrameworkWiring.java |  174 ++
 .../org/osgi/framework/wiring/package-info.java    |   32 +
 .../src/org/osgi/framework/wiring/packageinfo      |    1 +
 .../src/org/osgi/resource/Capability.java          |   86 +
 .../framework/src/org/osgi/resource/Namespace.java |  154 ++
 .../src/org/osgi/resource/Requirement.java         |   90 +
 osgi/framework/src/org/osgi/resource/Resource.java |   82 +
 osgi/framework/src/org/osgi/resource/Wire.java     |   87 +
 osgi/framework/src/org/osgi/resource/Wiring.java   |  144 ++
 .../src/org/osgi/resource/package-info.java        |   32 +
 osgi/framework/src/org/osgi/resource/packageinfo   |    1 +
 .../condpermadmin/BundleLocationCondition.java     |  127 ++
 .../condpermadmin/BundleSignerCondition.java       |  101 +
 .../org/osgi/service/condpermadmin/Condition.java  |  137 ++
 .../osgi/service/condpermadmin/ConditionInfo.java  |  340 ++++
 .../condpermadmin/ConditionalPermissionAdmin.java  |  228 +++
 .../condpermadmin/ConditionalPermissionInfo.java   |  189 ++
 .../condpermadmin/ConditionalPermissionUpdate.java |   87 +
 .../osgi/service/condpermadmin/package-info.java   |   33 +
 .../src/org/osgi/service/condpermadmin/packageinfo |    1 +
 .../osgi/service/packageadmin/ExportedPackage.java |  113 ++
 .../osgi/service/packageadmin/PackageAdmin.java    |  298 +++
 .../osgi/service/packageadmin/RequiredBundle.java  |  100 +
 .../osgi/service/packageadmin/package-info.java    |   37 +
 .../src/org/osgi/service/packageadmin/packageinfo  |    1 +
 .../service/permissionadmin/PermissionAdmin.java   |  121 ++
 .../service/permissionadmin/PermissionInfo.java    |  405 ++++
 .../osgi/service/permissionadmin/package-info.java |   33 +
 .../org/osgi/service/permissionadmin/packageinfo   |    1 +
 .../org/osgi/service/startlevel/StartLevel.java    |  276 +++
 .../org/osgi/service/startlevel/package-info.java  |   37 +
 .../src/org/osgi/service/startlevel/packageinfo    |    1 +
 .../url/AbstractURLStreamHandlerService.java       |  143 ++
 .../src/org/osgi/service/url/URLConstants.java     |   43 +
 .../osgi/service/url/URLStreamHandlerService.java  |   89 +
 .../osgi/service/url/URLStreamHandlerSetter.java   |   49 +
 .../src/org/osgi/service/url/package-info.java     |   33 +
 .../framework/src/org/osgi/service/url/packageinfo |    1 +
 .../src/org/osgi/util/tracker/AbstractTracked.java |  466 +++++
 .../src/org/osgi/util/tracker/BundleTracker.java   |  494 +++++
 .../osgi/util/tracker/BundleTrackerCustomizer.java |  100 +
 .../src/org/osgi/util/tracker/ServiceTracker.java  |  975 +++++++++
 .../util/tracker/ServiceTrackerCustomizer.java     |   93 +
 .../src/org/osgi/util/tracker/package-info.java    |   33 +
 .../src/org/osgi/util/tracker/packageinfo          |    1 +
 osgi/headless.xargs                                |   99 +
 osgi/init-tests.xargs                              |  127 ++
 osgi/init-tests.xargs.in                           |  127 ++
 osgi/init.xargs                                    |   99 +
 osgi/kf2                                           |   94 +
 osgi/minimal.xargs                                 |   22 +
 osgi/minimal.xargs.in                              |   22 +
 osgi/props.xargs                                   |   91 +
 osgi/remote-init.xargs                             |   99 +
 osgi/template.xargs.in                             |   99 +
 osgi/test-restart1.xargs                           |   34 +
 osgi/test-restart2.xargs                           |   19 +
 release_notes.html                                 |  380 ++++
 strings.properties                                 |   66 +
 636 files changed, 126508 insertions(+)

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..41f90bb
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,31 @@
+Copyright (c) 2003-2014, 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.
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..89ab27e
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.9.4
+Created-By: 1.6.0_65-b14-462-11M4609 (Apple Inc.)
+Main-class: org.knopflerfish.tools.jarunpacker.Main
+jarunpacker-destdir: knopflerfish_osgi_5.1.0
+jarunpacker-opendir: ${destdir}/osgi
+jarunpacker-licensepath: /LICENSE.txt
+knopflerfish-version: 5.1.0
+
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..57542d6
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,153 @@
+======================================================================
+=		Knopflerfish Notice file		    
+======================================================================
+
+Knopflerfish OSGi
+Copyright 2003-2014 The Knopflerfish Project
+http://www.knopflerfish.org
+
+This product includes software developed by the Knopflerfish Project
+as well as from other parties. Content not originating from the
+Knopflerfish Project is marked as such and belongs to respective
+copyright owners.   
+
+
+======================================================================
+=	General Notices
+======================================================================
+
+----------------------------------------------------------------------
+-	OSGi Alliance Notice
+----------------------------------------------------------------------
+This product includes the OSGi Service Platform API code from the OSGi
+Alliance provided under an Apache 2 license.
+http://www.osgi.org
+
+Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+
+
+----------------------------------------------------------------------
+-	Tango base icon theme Notice
+----------------------------------------------------------------------
+This product uses icons developed by the Tango Desktop Project and 
+released to the Public Domain.
+http://tango.freedesktop.org/Tango_Desktop_Project
+
+
+----------------------------------------------------------------------
+-	ASM Notice
+----------------------------------------------------------------------
+This product includes the ASM byte code manipulation library from
+INRIA (BSD Style License)
+http://asm.ow2.org/
+
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the copyright holders 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.
+
+
+======================================================================
+=	Bundle Specific Notices
+======================================================================
+
+----------------------------------------------------------------------
+-	Commons Logging Bundle Notice
+----------------------------------------------------------------------
+This product includes the commons_logging bundle which includes
+software developed by the Apache Commons Logging project released
+under Apache Software License, Version 2.0. (c) 2001-2004
+http://commons.apache.org/logging/
+
+----------------------------------------------------------------------
+-	Crimson Bundle Notice
+----------------------------------------------------------------------
+This product includes the xerces bundle which includes software
+developed by the Apache Crimson project released under Apache Software
+License, Version 1.1 (c) 1999-2003.
+http://xml.apache.org/dist/LICENSE.txt
+
+----------------------------------------------------------------------
+-	JSDK Bundle Notice
+----------------------------------------------------------------------
+This product includes the jsdk bundle which includes
+software developed by the Apache Geronimo project released
+under Apache Software License, Version 2.0. (c) 2001-2004
+
+----------------------------------------------------------------------
+-	JUnit Bundle Notice
+----------------------------------------------------------------------
+This product includes the junit bundles which includes
+software developed by the JUnit project released under a Common Public
+License, Version 1.0
+http://junit.sourceforge.net/
+
+----------------------------------------------------------------------
+-	kxml Bundle Notice
+----------------------------------------------------------------------
+This product includes the kxml bundle which includes software
+developed by Stefan Haustein provided under a BSD style license.
+http://kxml.sourceforge.net
+
+Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+
+----------------------------------------------------------------------
+-	Repository Indexer
+----------------------------------------------------------------------
+This product includes the org.osgi.service.indexer API which
+is licensed under Apache Software License, Version 2.0. (c) 2001-2004
+
+----------------------------------------------------------------------
+-	Service Component Runtime Bundle
+----------------------------------------------------------------------
+This product includes the org.apache.felix.scr.ScrService API which
+is licensed under Apache Software License, Version 2.0. (c) 2001-2004
+
+----------------------------------------------------------------------
+-	Serial port Bundles
+----------------------------------------------------------------------
+This product includes RXTX serial library which is licensed under
+LGPL and Suns javax.comm library licensed under Suns Binary Code
+License Agreement. See osgi/bundles_opt/serial/readme.txt for more
+information.
+
+----------------------------------------------------------------------
+-	Xalan Bundle Notice
+----------------------------------------------------------------------
+This product includes the xerces bundle which includes software
+developed by the Apache Xalan project released under Apache Software
+License, Version 2.0. (c) 2001-2004
+http://xml.apache.org/xalan-j/
+
+----------------------------------------------------------------------
+-	Xerces Bundle Notice
+----------------------------------------------------------------------
+This product includes the xerces bundle which includes software
+developed by the Apache Xerces project released under Apache Software
+License, Version 2.0. (c) 2001-2004
+http://xerces.apache.org/
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..4fa4476
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,55 @@
+======================================================================
+	Knopflerfish Release  5.1.0
+======================================================================
+
+Contents:
+----------------------------------------
+ README.txt       - this file.
+ release_notes.*  - the release notes for the current release.
+ changelog.html   - the subversion change log for this release.
+ NOTICE.txt       - notice file on included third party software.
+ LICENSE.txt      - the Knopflerfish license.
+
+ ant              - Ant related code and build include files.
+ docs             - online documentation (html),
+ docs/index.html  - Starting point for reading the documentation.
+ osgi             - all OSGi related code.
+ osgi/bundles     - bundles included in distribution.
+ osgi/bundles_opt - some extra bundles.
+ osgi/framework   - core OSGi framework.
+ osgi/jars        - Precompiled bundles.
+ osgi/test_jars   - Precompiled JUnit test suite bundles.
+
+
+Basic: How to start
+----------------------------------------
+ Prerequisites
+
+   - JRE 1.4 or later, available from Oracle.
+
+1. Step into the osgi dir
+2. Start the OSGi framework by:
+   > java -jar framework.jar
+
+3. This starts the framework + a large set of bundles, including
+   the desktop
+
+
+Building:
+----------------------------------------
+ Prerequisites
+
+   - JDK 1.6 (or 1.5), available from Oracle.
+     See http://java.com/en/download/faq/java_6.xml for details.
+     Note that JDK 1.7 or later can NOT be used to build Knopflerfish,
+     but Knopflerfish will run on them.
+   - Ant 1.8.1 or later, available from ant.apache.org.
+   - openssl, to create and manipulate certificates when using
+     security and the Conditional Permission Admin (CPA) service. Test
+     suites for CPA can not be built and executed without openssl.
+   - ProGuard 4, tested with 4.10. This is only need if you want
+     to build the compact version of the framework.
+
+1. Step into the osgi dir
+2. Start the build by:
+   > ant all
diff --git a/ant/android.xml b/ant/android.xml
new file mode 100644
index 0000000..ed5e17a
--- /dev/null
+++ b/ant/android.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   ** Copyright (c) 2011-2013, 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.
+  -->
+<!-- ============================================================ -->
+<!--  Android instrumentation support,                            -->
+<!--  adds a .dex-file to a bundle jar-file                       -->
+<!-- ============================================================ -->
+<project name="android_instrumentation" basedir=".">
+
+  <!-- Are we building for Dalvik/Android? -->
+  <available property="android.exists" file="${ANDROID_HOME}"/>
+
+  <!-- look for dx.jar and aapt in Android sdk -->
+  <first id="first.dx">
+    <fileset dir="${ANDROID_HOME}"
+             includes="**/dx.jar"
+             erroronmissingdir="false"/>
+  </first>
+  <first id="first.aapt">
+    <fileset dir="${ANDROID_HOME}"
+             includes="**/aapt*"
+             erroronmissingdir="false"/>
+  </first>
+  <property name="android.tool.dx" value="${toString:first.dx}" />
+  <property name="android.tool.aapt" value="${toString:first.aapt}" />
+
+
+  <macrodef name="add_dex"
+            description="Generates xargs-file from templare.">
+    <attribute name="jarfile"
+               description="The jar file to create and add a .dex-file to."/>
+    <attribute name="outdir"
+               description="Directory to write temporary file to"/>
+
+    <sequential>
+      <basename file="@{jarfile}" suffix="jar" property="jarfile.basename"/>
+      <tempfile destdir="@{outdir}" prefix="${jarfile.basename}"
+                property="temp.dir"/>
+      <mkdir dir="${temp.dir}"/>
+      <property name="temp.dex" location="${temp.dir}/classes.dex"/>
+
+      <exec executable="${android.tool.aapt}" dir="${temp.dir}">
+        <arg value="remove"/>     
+        <arg value="-f"/>
+        <arg value="@{jarfile}"/>
+        <arg value="classes.dex"/>
+      </exec>
+
+      <java fork="true" jar="${android.tool.dx}">
+        <arg value="--dex"/>
+        <arg value="--output=${temp.dex}"/>
+        <arg value="@{jarfile}"/>
+      </java>
+
+      <exec executable="${android.tool.aapt}" dir="${temp.dir}">
+        <arg value="add"/>     
+        <arg value="-f"/>
+        <arg value="@{jarfile}"/>
+        <arg value="classes.dex"/>
+      </exec>
+
+      <delete dir="${temp.dir}"/>
+    </sequential>
+  </macrodef>
+
+  <!-- Helper taget that adds Android dex data to the bundle. -->
+  <target name="add_dex" if="android.exists">
+  </target>
+
+</project>
diff --git a/ant/ant_templates/mvn_repo.xml b/ant/ant_templates/mvn_repo.xml
new file mode 100644
index 0000000..0eae103
--- /dev/null
+++ b/ant/ant_templates/mvn_repo.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   ** Copyright (c) 2010-2013, 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.
+  -->
+
+<project name="mvn_repo" default="all"
+         xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+
+  <property name="ant.dir"       location="-- PLEASE FILL IN --"/>
+  <property name="out.dir"       location="-- PLEASE FILL IN --"/>
+  <property name="mvn2.repo.dir" location="-- PLEASE FILL IN --"/>
+
+  <property name="dependency.management.file" location="-- PLEASE FILL IN --"/>
+  <property name="dependency.management.repo.file" location="-- PLEASE FILL IN --"/>
+
+  <!-- The default group id of the artefacts. -->
+  <property name="group.id"      value="-- PLEASE FILL IN --"/>
+
+  <!-- Property for the maven deploy plugin. -->
+  <property name="updateReleaseInfo" value="true"/>
+
+  <!-- Download and define maven ant tasks -->
+  <property name="maven-ant-tasks.version" value="2.1.3"/>
+  <property name="maven-ant-tasks.jar"
+            value="maven-ant-tasks-${maven-ant-tasks.version}.jar"/>
+  <property name="maven-ant-tasks.path"
+            location="${ant.dir}/lib/${maven-ant-tasks.jar}"/>
+  <path id="maven-ant-tasks.classpath"
+        path="${maven-ant-tasks.path}" />
+  <available classname="org.apache.maven.artifact.ant.WritePomTask"
+             classpathref="maven-ant-tasks.classpath"
+             property="maven-ant-tasks.present"/>
+
+  <target name="init" depends="install_maven-ant-tasks">
+    <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
+             uri="antlib:org.apache.maven.artifact.ant"
+             classpathref="maven-ant-tasks.classpath" />
+  </target>
+
+  <target name="install_maven-ant-tasks" unless="maven-ant-tasks.present">
+    <get src="http://repo1.maven.org/maven2/org/apache/maven/maven-ant-tasks/2.1.3/maven-ant-tasks-${maven-ant-tasks.version}.jar"
+         dest="${maven-ant-tasks.path}"/>
+  </target>
+
+
+  <macrodef name="mvn_deploy_bundle"
+            description="Deploys a bundle archive to a Maven 2 repository">
+    <attribute name="projDirName"
+               description="Name of directory to place output in."/>
+    <attribute name="groupId"
+               description="The id of the group that the artifact belongs to."
+               default="${group.id}"/>
+    <attribute name="artifactId"
+               description="Id of the artifact to deploy"/>
+    <attribute name="version"
+               description="Version of the artifact to deploy"/>
+    <attribute name="artifactName"
+               description="Name of the artifact to deploy"/>
+    <attribute name="description"
+               description="Description of the artifact to deploy"
+               default=""/>
+    <attribute name="orgName"
+               description="Name part of the organiztion element in the pom"
+               default="Knopflerfish"/>
+    <attribute name="orgUrl"
+               description="URL part of the organiztion element in the pom"
+               default="http://www.knopflerfish.org/"/>
+    <attribute name="artifactBundle"
+               description="Bundle jar file for the artifact to deploy"/>
+    <attribute name="packing"
+               description="Artifact packing type"
+               default="jar"/>
+    <attribute name="settingsFile"
+               description="Settings file to load"
+               default=""/>
+    <element name="dependencies"
+             optional="true"
+             description="Place holder element for pom dependency."/>
+    <element name="licenses"
+             optional="true"
+             description="Place holder element for pom license."/>
+    <element name="source-attachment"
+             optional="true"
+             description="Place holder element for source artifact attachment."/>
+    <element name="javadoc-attachment"
+             optional="true"
+             description="Place holder element for javadoc artifact attachment."/>
+    <sequential>
+      <mkdir dir="${mvn2.repo.dir}"/>
+      <mkdir dir="${out.dir}/@{projDirName}"/>
+
+      <artifact:pom id="@{artifactId}-pom"
+                    groupId="@{groupId}"
+                    artifactId="@{artifactId}"
+                    version="@{version}"
+                    packaging="@{packing}"
+                    name="@{artifactName}"
+                    description="@{description}">
+        <organization name="@{orgName}" url="@{orgUrl}"/>
+        <licenses/>
+        <dependencies/>
+      </artifact:pom>
+
+      <artifact:writepom pomRefId="@{artifactId}-pom"
+                         file="${out.dir}/@{projDirName}/@{artifactId}-pom.xml"/>
+
+      <artifact:deploy file="@{artifactBundle}">
+        <remoteRepository url="file://localhost${mvn2.repo.dir}"/>
+        <pom file="${out.dir}/@{projDirName}/@{artifactId}-pom.xml"
+             settingsFile="@{settingsFile}">
+          <profile id="release-profile" active="true"/>
+        </pom>
+	<source-attachment/>
+	<javadoc-attachment/>
+      </artifact:deploy>
+    </sequential>
+  </macrodef>
+
+  <!-- Targets for bundles will be added after this line -->
+  <target name="all"
+          description="Deploy all bundles to the Maven 2 repository."
+          depends="init">
+    <tstamp>
+      <format property="tstamp.year" pattern="yyyy" locale="en"/>
+    </tstamp>
+
+    <copy file="${dependency.management.file}"
+          toFile="${dependency.management.repo.file}"/>
+    <copy file="${ant.dir}/html_template/mvn_dep_mgmt.xsl"
+          toFile="${dependency.management.repo.file}/../mvn_dep_mgmt.xsl">
+      <filterset>
+	<filter token="YEAR" value="${tstamp.year}"/>
+      </filterset>
+    </copy>
+  </target>
+
+</project>
diff --git a/ant/build.xml b/ant/build.xml
new file mode 100644
index 0000000..a49ebb6
--- /dev/null
+++ b/ant/build.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<project name="anttasks" default="all">
+
+  <property name="javadoc.packages"
+            value="org.knopflerfish.ant.taskdefs.bundle"/>
+
+  <target name="all" description="Creates lib/bundle_tasks.jar">
+    <delete quiet="true" dir="classes"/>
+    <delete quiet="true" dir="lib" includes="bundle_tasks.jar"/>
+    <ant antfile="bundletasks.xml" target="build_bundle_tasks"/>
+  </target>
+
+  <target name="javadoc"
+          description="Generate Javadoc for the bundle tasks">
+    <mkdir dir="javadoc"/>
+    <javadoc sourcepath    = "src"
+             destdir       = "javadoc"
+             packagenames  = "${javadoc.packages}"
+             >     
+    </javadoc>
+  </target>
+  
+  <target name="clean" description="removes all generated files">
+    <delete dir="javadoc"/>
+    <delete dir="classes"/>
+    <delete dir="lib" includes="bundle_tasks.jar"/>
+
+    <delete dir="lib" includes="org.osgi.impl.bundle.repoindex.cli-*.jar"/>
+    <delete dir="lib" includes="proguard-*.jar"/>
+
+    <!-- Obsolete, not used in KF-5 and later. -->
+    <delete dir="lib" includes="bindex.jar"/>
+  </target>
+
+</project>
diff --git a/ant/build_example.xml b/ant/build_example.xml
new file mode 100644
index 0000000..5f9cbe0
--- /dev/null
+++ b/ant/build_example.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Name of generated jar files will be:  -->
+<!--  ${ant.project.name}-${version}.jar     (refered to as impl-bundle) -->
+<!--  ${ant.project.name}_api-${version}.jar  (refered to as api-bundle) -->
+<!--  ${ant.project.name}_all-${version}.jar  (refered to as all-bundle) -->
+
+<project name="build_example" default="all">
+
+  <!-- Where this project lives in the file system. -->
+  <dirname  property="proj.dir" file="${ant.file.build_example}"/>
+
+  <!-- Set to top directory, this is the root of the temporary out    -->
+  <!-- directory for compilation output named "out" and also the root -->
+  <!-- for the bundle repository directory, named "jars".             -->
+<!--
+  <property name="topdir"       location="${proj.dir}/../.."/>
+-->
+
+  <!-- Pattern that must match all private code to be included in     -->
+  <!-- the bundle. The value may contain several comma separated      -->
+  <!-- patterns. Used when compiling, and when packing the impl-,     -->
+  <!-- all- variant of the bundle.                                    -->
+  <property name  = "impl.pattern"
+            value = "org/knopflerfish/bundle/httptest/**"/>
+
+  <!-- Pattern that must match all exported (API) code to be included -->
+  <!-- in the bundle. The value may contain several comma separated   -->
+  <!-- patterns. Used when compiling, and when packing the api-,      -->
+  <!-- lib-, and all- variant of the bundle. Also used to derive the  -->
+  <!-- Export-Package manifest header if not explicitly given.        -->
+<!--
+  <property name  = "api.pattern"
+            value = "org/knopflerfish/service/http/**"/>
+-->
+
+  <!-- Pattern that must match all internal but exported code         -->
+  <!-- (internal APIs) to be included in the bundle. Used when        -->
+  <!-- compiling, and when packing the impl- and all- variant         -->
+  <!-- of the bundle, but not for the api-variant of the bundle.      -->
+  <!-- Also used to derive the Export-Package manifest header if not  -->
+  <!-- explicitly given.                                -->
+<!--
+  <property name  = "impl-api.pattern"
+            value = "org/knopflerfish/bundle/shared/http/**"/>
+-->
+
+  <!-- Compile-time dependencies, either an explicit path or a     -->
+  <!-- symbolic bundle name that ends with "N.N.N.jar".            -->
+  <!-- Path elements defined like location="console_api-N.N.N.jar" -->
+  <!-- will be expanded to the bundle with the highest version     -->
+  <!-- number available in the directory given by ${jars.dir}.     -->
+ <path id="bundle.compile.path">
+   <pathelement location="console_api-N.N.N.jar"/>
+   <pathelement location="log_api-N.N.N.jar"/>
+   <pathelement location="jsdk_api-2.N.N.jar"/>
+  </path>
+
+
+  <!-- Activator, imports, exports etc are automatically found but    -->
+  <!-- can be specified explicitly with properties or by providing a  -->
+  <!-- template bundle manifest file, named "bundle.manifest".        -->
+  <!-- See bundlebuild_include.xml for details                        -->
+
+  <!-- The default bundle name (property "bmfa.Bundle-Name") will be: -->
+  <!--   ${ant.project.name}                                          -->
+  <!-- The default bundle symbolic name (property                     -->
+  <!-- "bmfa.Bundle-SymbolicName") will be:                           -->
+  <!--   ${domain.reverse}.bundle.${ant.project.name}                 -->
+
+  <property name="domain.reverse"          value="org.knopflerfish"/>
+
+  <property name="bmfa.Bundle-Description" value="HTTP test servlet"/>
+  <property name="bmfa.Bundle-Vendor"      value="Knopflerfish"/>
+
+  <!-- Import the master build file that defines everything else. -->
+  <import file="${proj.dir}/../../../ant/bundlebuild.xml"/>
+
+</project>
diff --git a/ant/bundle_junit.xml b/ant/bundle_junit.xml
new file mode 100644
index 0000000..dcff6ab
--- /dev/null
+++ b/ant/bundle_junit.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ** Copyright (c) 2003-2008, 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.
+  -->
+
+<project name="bundle_junit" basedir=".">
+
+  <property name="http.host"          value="localhost"/>
+  <property name="http.port"          value="8080"/>
+  <property name="junit.runner.class" value="junit.swingui.TestRunner"/>
+  <property name="junit.formatter"    value="plain"/>
+  <property name="junit.outfile"      value="junit"/>
+
+  <target name="junit_ext"
+          description="Runs remote JUnit test using external runner">
+    <fail unless="test.id" message="test.id must be set to test suite id"/>
+    <java classname="${junit.runner.class}" fork="yes">
+      <classpath>
+	<path location="${jars.dir}/junit/junit_all-1.0.0.jar"/>
+	<path refid="bundle.compile.path"/>
+      </classpath>
+      <sysproperty key="suite.url"
+                   value="http://${http.host}:${http.port}/junit?id=${test.id}"/>
+      <arg value="org.knopflerfish.service.junit.client.JUnitClient"/>
+    </java>
+  </target>
+
+  <target name="junit_ant"
+          description="Runs remote JUnit test using Ant junit task">
+    <fail unless="test.id" message="test.id must be set to test suite id"/>
+    <echo message = "JUnit output file is '${junit.outfile}'"/>
+    <junit fork="yes" showoutput="true" printsummary="true">
+      <sysproperty key="suite.url"
+                   value="http://${http.host}:${http.port}/junit?id=${test.id}"/>
+      <classpath>
+	<path location="${jars.dir}/junit/junit_all-1.0.0.jar"/>
+	<path refid="bundle.compile.path"/>
+      </classpath>
+      <formatter type="${junit.formatter}"/>
+      <test name="org.knopflerfish.service.junit.client.JUnitClient"
+            outfile="${junit.outfile}"/>
+    </junit>
+  </target>
+
+</project>
diff --git a/ant/bundlebuild.xml b/ant/bundlebuild.xml
new file mode 100644
index 0000000..ad34034
--- /dev/null
+++ b/ant/bundlebuild.xml
@@ -0,0 +1,1102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   ** Copyright (c) 2003-2013, 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.
+  -->
+
+<project name="bundlebuild" basedir=".">
+
+  <dirname  property="ant.dir"   file="${ant.file.bundlebuild}"/>
+  <property name="osgi.dir"      location="${ant.dir}/../osgi"/>
+  <property name="proj.dir"      location="."/>
+  <property name="topdir"        location="${osgi.dir}"/>
+
+  <!-- Special value to be used as the value for a bundle manifest      -->
+  <!-- properties that shall not be included in the generated manifest. -->
+  <!-- DO NOT CHANGE THIS VALUE.                                        -->
+  <property name="bundle.emptystring" value="[bundle.emptystring]"/>
+
+  <!-- Map environment variables to properties starting with "sysprops."-->
+  <property environment="sysprops"/>
+
+
+  <import file="${ant.dir}/android.xml"/>
+
+
+
+  <!-- ************************************************************ -->
+  <!-- Properties configuring javac settings.                       -->
+  <!-- ************************************************************ -->
+
+  <!-- The default encoding is UTF8, other values that may be       -->
+  <!-- usefull: ISO8859_1, UTF-16, ${file.encoding}                 -->
+  <property name="javac.encoding"     value="UTF8"/>
+
+  <available property="jdk1.7+" classname="java.lang.ClassValue"/> 
+  <condition property="javac.source" value="1.5" else="1.5">
+    <isset property="jdk1.7+"/>
+  </condition>
+  <condition property="javac.target" value="1.5" else="jsr14">
+    <isset property="jdk1.7+"/>
+  </condition>
+  <!-- Since we currently can not do a strict compilation using    -->
+  <!-- OSGi/Minimum EE when on jdk 1.7, we replace any requirement -->
+  <!-- on OSGu/Minum EE with one on the JavaSE 5.                  -->
+  <condition property="ee.min.replacement"
+             value="(&(osgi.ee=JavaSE)(version>=1.5))"
+             else="">
+    <isset property="jdk1.7+"/>
+  </condition>
+
+  <!-- The bundle Execution Environment to use when compiling.       -->
+  <!-- The value is the id of a path that will be used as boot class -->
+  <!-- path during the compilation.                                  -->
+  <!-- Predefined values: ee.minimum ee.foundation                   -->
+  <!-- Used but currently undefined EE:s: ee.JavaSE_1.4, ee.JavaSE_1.5   -->
+  <property name="bundle.compile.EE" value="ee.minimum"/>
+
+
+  <!-- Define the EEs that we have (stub-)jars for.                  -->
+  <!-- The OSGi Minimum EE.                                          -->
+  <path id="ee.minimum">
+    <pathelement location="${osgi.dir}/ee/ee.minimum.jar"/>
+    <!-- Outside EE, but usefull when compling -->
+    <pathelement location="${osgi.dir}/ee/src_annotations.jar"/>
+  </path>
+
+  <!-- The OSGi Foundation EE.                                       -->
+  <path id="ee.foundation">
+    <pathelement location="${osgi.dir}/ee/ee.foundation.jar"/>
+    <pathelement location="${osgi.dir}/ee/src_annotations.jar"/>
+  </path>
+
+
+  <!-- If the EE selected by bundle.compile.EE does not exist, i.e., -->
+  <!-- is not a valid reference to a path then tell javac to use the -->
+  <!-- EE from the runtime it is executing on by setting             -->
+  <!-- includeJavaRuntime to true.                                   -->
+  <!-- For Java 7, the predefined EEs (minimum/foundation) are       -->
+  <!-- missing some interfaces (e.g., Iterable) that Java 6 with     -->
+  <!-- target jsr14 does not need, thus we let the runtime leak      -->
+  <!-- through for Java 7 and set the required EE to JavaSE 5.       -->
+  <condition property="javac.includeJavaRuntime" value="true" else="false">
+    <or>
+      <isset property="jdk1.7+"/>
+      <not>
+        <isreference refid="${bundle.compile.EE}" type="path"/>
+      </not>
+    </or>
+  </condition>
+
+  <!-- Empty path to get a valid path refid when having no class     -->
+  <!-- path the selected EE.                                         -->
+  <path id="ee.empty">
+  </path>
+
+  <!-- If the EE selected by bundle.compile.EE does not exist, i.e., -->
+  <!-- is not a valid reference to a path then use a dummy (empty)   -->
+  <!-- path as the value for bundle.bootclasspath.ref                -->
+  <!-- For Java 7, allways use the dummy EE.                         -->
+  <condition property="bundle.bootclasspath.ref"
+             value="ee.empty"
+             else="${bundle.compile.EE}">
+    <or>
+      <isset property="jdk1.7+"/>
+      <not>
+        <isreference refid="${bundle.compile.EE}" type="path"/>
+      </not>
+    </or>
+  </condition>
+
+
+
+  <!-- ************************************************************ -->
+  <!-- Properties configuring bundle contents and manifest.         -->
+  <!-- ************************************************************ -->
+
+  <!-- Shall source code be included into the bundle jar or not. -->
+  <property name="include.source"      value="false"/>
+
+  <!-- The reverse domain name of the bundle vendor.              -->
+  <!-- Used in the default definition of the bundle symbolic name -->
+  <!-- and the bundle UUID.                                       -->
+  <property name="domain.reverse"      value="org.knopflerfish"/>
+
+
+  <!-- Import-Package / Export-Package manifest headers that are found -->
+  <!-- invalid by the bundleinfo-task shall trigger build error.       -->
+  <property name="bundleinfo.failOnExports"   value="true"/>
+  <property name="bundleinfo.failOnImports"   value="true"/>
+  <property name="bundleinfo.failOnActivator" value="true"/>
+  <property name="bundleinfo.failOnClassPath" value="true"/>
+  <property name="bundleinfo.uses"            value="true"/>
+
+  <!-- Bundle manifest attributes corresponds to ant properties with  -->
+  <!-- names starting with "bmfa." (short for BundleManiFestAttribute)-->
+  <!-- followed by the manifest attribute name.                       -->
+  <property name="bundle.mf.attr.prefix"   value="bmfa."/>
+
+  <!-- Bundle manifest attribute properties can either be specified in -->
+  <!-- the build.xml before importing this file, or by creating a      -->
+  <!-- template manifest file, named "bundle.manifest", in the same    -->
+  <!-- directory as the build.xml. Such template manifest files are    -->
+  <!-- typically created by the Knopflefish eclipse plugin.            -->
+  <property name="bundlemanifest.template"
+            location="${proj.dir}/bundle.manifest"/>
+
+  <!-- Set up default values for Bundle manifest attribute properties. -->
+  <property name="bmfa.Bundle-ManifestVersion" value="2"/>
+  <property name="bmfa.Bundle-Name"            value="${ant.project.name}"/>
+  <property name="bmfa.Bundle-Version"         value="0.0.0"/>
+  <property name="bmfa.Bundle-SymbolicName"
+            value="${domain.reverse}.bundle.${ant.project.name}"/>
+  <property name="bmfa.Bundle-Classpath"       value="."/>
+  <property name="bmfa.Bundle-Vendor"          value="Knopflerfish"/>
+  <property name="bmfa.Bundle-ContactAddress"
+            value="http://www.knopflerfish.org"/>
+  <property name="bmfa.Bundle-DocURL"
+            value="http://www.knopflerfish.org"/>
+
+  <!-- Define all other known bundle mainfest attribute properties with -->
+  <!-- the special empty value so that we do not end up with headers    -->
+  <!-- like                                                             -->
+  <!-- Import-Package: ${bmfa.Import-Package}                           -->
+  <!-- in the generated manifest file.                                  -->
+  <property name="bmfa.Application-Icon"       value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-Activator"       value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-APIVendor"       value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-Category"        value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-Config"          value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-Copyright"       value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-Description"     value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-Localization"    value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-NativeCode"      value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-RequiredExecutionEnvironment"
+            value="${bundle.emptystring}"/>
+  <property name="bmfa.Bundle-UpdateLocation"  value="${bundle.emptystring}"/>
+  <property name="bmfa.DynamicImport-Package"  value="${bundle.emptystring}"/>
+  <property name="bmfa.Export-Package"         value="${bundle.emptystring}"/>
+  <property name="bmfa.Export-Service"         value="${bundle.emptystring}"/>
+  <property name="bmfa.Fragment-Host"          value="${bundle.emptystring}"/>
+  <property name="bmfa.Import-Package"         value="${bundle.emptystring}"/>
+  <property name="bmfa.Import-Service"         value="${bundle.emptystring}"/>
+  <property name="bmfa.Require-Bundle"         value="${bundle.emptystring}"/>
+  <property name="bmfa.Service-Component"      value="${bundle.emptystring}"/>
+  <!-- End of properties used as value for bundle manifest headers.   -->
+
+
+  <!-- Special values for manifest headers of the api-version of a     -->
+  <!-- bundle can be set by defining properties with the prefix        -->
+  <!-- "bmfa.api-" E.g.                                                -->
+  <!-- <property name="bmfa.api-Export-Package" value="org.kf.xx.yy"/> -->
+  <!-- Prefixing with "api-" may also be used in the manifest template.-->
+  <!-- The same prefixing rule applies for the lib- and the            -->
+  <!-- impl-variants of a bundles.  -->
+
+
+  <!-- The deault source directory to search.                          -->
+  <property name="src.dir"        location="src"/>
+
+  <!-- The deault resoruces directory to search.                       -->
+  <property name="resources.dir"  location="resources"/>
+
+  <!-- The deault doc directory to search.                             -->
+  <property name="doc.dir"        location="doc"/>
+
+  <!-- The root directory to place all intermediate build producs in.  -->
+  <property name="root.out.dir"   location="${topdir}/out"/>
+
+  <!-- The name of the directory to place all intermediate build -->
+  <!-- products for this project. -->
+  <property name="outdir.name" value="${ant.project.name}"/>
+
+  <!-- Directory to place all intermediate build products for this project. -->
+  <property name="outdir"   location="${root.out.dir}/${outdir.name}"/>
+
+  <!-- The root of the default bundle repository. -->
+  <property name="osgi.jars.dir" location="${osgi.dir}/jars"/>
+
+  <!-- The root of the local bundle repository, in which built bundles -->
+  <!-- are placed.                                                     -->
+  <property name="jars.dir" location="${topdir}/jars"/>
+
+  <!-- Name of the subdirectory of jars.dir where this projects bundles -->
+  <!-- shall be placed. -->
+  <property name="jardir.name" value="${ant.project.name}"/>
+
+  <!-- Subdirectory of jars.dir where this projects bundles shall live. -->
+  <property name="jardir"   location="${jars.dir}/${jardir.name}"/>
+
+  <!-- The root if the local bundle docs directory. -->
+  <property name="docs.dir" location="${root.out.dir}/doc"/>
+
+  <!-- Name of the directory to place generate bundle documentation in. -->
+  <property name="outdocdir.name" value="${ant.project.name}"/>
+
+  <!-- Directory to place generate bundle documentation in. -->
+  <property name="outdocdir"   location="${docs.dir}/${outdocdir.name}"/>
+
+  <!-- Location of templates used by the bundle_doc-target. -->
+  <property name="bundledoc_template"
+            location="${ant.dir}/html_template/bundledoc.html"/>
+
+  <!-- Name of file to record the name of all exported package in. -->
+  <property name="exported.file" location="${root.out.dir}/exported.txt"/>
+
+  <!-- Name of file to record the soruce tree roots in. -->
+  <property name="sources.file"  location="${root.out.dir}/sources.txt"/>
+
+  <!-- Where to store compiler output. -->
+  <property name="classes.out.dir"     location="${outdir}/classes"/>
+
+  <!-- Where the javadoc for exported packages goes. -->
+  <property name="javadoc.out.dir" location="${outdir}/javadoc"/>
+
+  <!-- Where the javadoc for exported packages goes. -->
+  <property name="resources.out.dir" location="${outdir}/resources"/>
+
+  <!-- If lib-variant of bundle shall be built or not. -->
+  <property name="bundle.build.lib"    value="false"/>
+
+  <!-- If api-variant of bundle shall be built or not. -->
+  <property name="bundle.build.api"    value="true"/>
+
+  <!-- If impl-variant of bundle shall be built or not. -->
+  <property name="bundle.build.impl"   value="true"/>
+
+  <!-- If all-variant of bundle shall be built or not. -->
+  <property name="bundle.build.all"    value="true"/>
+
+  <!-- If bundle-doc for bundle shall be built or not. -->
+  <property name="bundle.build.doc"    value="false"/>
+
+  <!-- Shall a separate source jar (for maven) be built or not. -->
+  <property name="bundle.build.source.jar" value="false"/>
+
+  <!-- Shall a separate javadoc jar (for maven) be built or not. -->
+  <property name="bundle.build.javadoc.jar" value="false"/>
+
+  <!-- Bundles that both export packages and provides implementations -->
+  <!-- shall have the implicitImport flag set in the bundleinfo task. -->
+  <property name="bundle.implicit.imports.lib"   value="false"/>
+  <property name="bundle.implicit.imports.api"   value="true"/>
+  <property name="bundle.implicit.imports.impl"  value="false"/>
+  <property name="bundle.implicit.imports.all"   value="true"/>
+
+  <!-- A comma separated list of packages that does not need to be imported. -->
+  <!-- I.e., packages that are made available through the system classloader.-->
+  <property name="bundle.stdimports"   value="java."/>
+
+  <!-- A comma separated list of packages that needs to be imported even -->
+  <!-- though that they are not explicitly referenced from inside the -->
+  <!-- bundle. E.g. classes loaded using reflection. -->
+  <property name="bundle.extraimports"   value=""/>
+
+  <!-- First part of the suffix to insert right before "-Version" in -->
+  <!-- the name of jar files to create.                              -->
+  <!-- E.g. The full name of the impl-jar will be on the form:       -->
+  <!--${jardir}/${ant.project.name}${impl.suffix.name}-${bmfa.Bundle-Version}-->
+  <property name="lib.suffix.name"  value=""/>
+  <property name="api.suffix.name"  value="_api"/>
+  <property name="impl.suffix.name" value=""/>
+  <property name="all.suffix.name"  value="_all"/>
+  <property name="source.suffix.name" value=""/>
+
+  <!-- Manifest attributes that shall not be present in the manifest -->
+  <!-- of the named bundle kind. The value is a comma separated list -->
+  <!-- of manifest attibute names to weed out from the generated manifest. -->
+  <property name="attrs.to.skip.lib"
+            value="Bundle-Activator,Export-Service,Import-Service,Bundle-Config"/>
+  <property name="attrs.to.skip.api"
+            value="Bundle-Activator,Export-Service,Import-Service,Bundle-Config"/>
+  <property name="attrs.to.skip.impl" value="Export-Package"/>
+  <property name="attrs.to.skip.all"  value=""/>
+
+  <!-- Let the bundlemanifest task print the name of the activator -->
+  <!-- and the exported and imported packages on the console.      -->
+  <property name="bundlemanifest.verbose" value="true"/>
+
+
+  <!-- Path that finds the framework API packages.                 -->
+  <path id="framework.path">
+    <pathelement location="${jars.dir}/../framework.jar"/>
+    <pathelement location="${osgi.jars.dir}/../framework.jar"/>
+    <pathelement location="${osgi.dir}/framework.jar"/>
+  </path>
+
+  <!-- Default compile path for a bundle. The referenced path,     -->
+  <!-- "bundle.compile.path" should be set in the build file that  -->
+  <!-- imports this file.                                          -->
+  <path id="bundle.path">
+    <path refid="framework.path"/>
+    <path refid="bundle.api.path"/>
+    <path refid="bundle.compile.path"/>
+  </path>
+
+  <import file="${ant.dir}/bundletasks.xml"/>
+
+  <target name="init"
+          depends="setup_build,bundle_tasks,setup_manifest_props">
+    <tstamp>
+      <format property="bundle.date"
+              pattern="EE MMMM d yyyy, HH:mm:ss"
+              locale="en"/>
+    </tstamp>
+  </target>
+
+  <!-- This target must be called before using any of the bmfa.* properties.-->
+  <target name="setup_manifest_props">
+    <!-- If old bundle manifest property names are in use fail! -->
+    <fail if="bundle.category" message="bundle.category->bmfa.Bundle-Category"/>
+    <fail if="bundle.name" message="bundle.name->bmfa.Bundle-Name"/>
+    <fail if="bundle.version" message="bundle.version->bmfa.Bundle-Version"/>
+    <fail if="bundle.manifest.version"
+          message="bundle.manifest.version->bmfa.Bundle-ManifestVersion"/>
+    <fail if="bundle.classpath"
+          message="bundle.classpath->bmfa.Bundle-Classpath"/>
+    <fail if="bundle.contactaddress"
+          message="bundle.contactaddress->bmfa.Bundle-ContactAddress"/>
+    <fail if="bundle.copyright"
+          message="bundle.copyright->bmfa.Bundle-Copyright"/>
+    <fail if="bundle.description"
+          message="bundle.description->bmfa.Bundle-Description"/>
+    <fail if="bundle.docurl" message="bundle.docurl->bmfa.Bundle-DocURL"/>
+    <fail if="bundle.localization"
+          message="bundle.localization->bmfa.Bundle-Localization"/>
+    <fail if="bundle.nativecode"
+          message="bundle.nativecode->bmfa.Bundle-NativeCode"/>
+    <fail if="bundle.requiredEE"
+          message="bundle.requiredEE->bmfa.Bundle-RequiredExecutionEnvironment"/>
+    <fail if="bundle.symbolicname"
+          message="bundle.symbolicname->bmfa.Bundle-SymbolicName"/>
+    <fail if="bundle.update.location"
+          message="bundle.update.location->bmfa.Bundle-UpdateLocation"/>
+    <fail if="bundle.vendor" message="bundle.vendor->bmfa.Bundle-Vendor"/>
+    <fail if="dynamicimport.package"
+          message="bundle.dynamicimport.package->bmfa.DynamicImport-Package"/>
+    <fail if="export.service" message="export.service->bmfa.Export-Service"/>
+    <fail if="import.service" message="import.service->bmfa.Import-Service"/>
+    <fail if="export.package" message="export.package->bmfa.Export-Package"/>
+    <fail if="import.package" message="import.package->bmfa.Import-Package"/>
+    <fail if="fragment.host"  message="fragment.host->bmfa.Fragment-Host"/>
+    <fail if="require.bundle" message="require.bundle->bmfa.Require-Bundle"/>
+    <fail if="bundle.uuid"    message="bundle.uuid->bmfa.Bundle-UUID"/>
+    <fail if="bundle.config"  message="bundle.config->bmfa.Bundle-Config"/>
+    <fail if="bundle.icon"    message="bundle.icon->bmfa.Bundle-Icon"/>
+    <fail if="bundle.subversionurl"
+          message="bundle.subversionurl->bmfa.Bundle-SubversionURL"/>
+    <fail if="bundle.apivendor"
+          message="bundle.apivendor->bmfa.Bundle-APIVendor"/>
+    <fail if="service.component"
+          message="service.component->bmfa.Service-Component"/>
+
+    <!-- Update value of all bundle manifest properties (bmfa.*) based  -->
+    <!-- on their values in the manifest template file (if present). -->
+    <bundlemanifest mode="templateOnly"
+                    attributePropertyPrefix="${bundle.mf.attr.prefix}"
+                    templateFile="${bundlemanifest.template}">
+    </bundlemanifest>
+
+    <!-- Defines default values for properties where the default value -->
+    <!-- depends on other bundle manifest header values -->
+    <!-- e.g., the bundle version.   -->
+    <property name="bmfa.Bundle-UUID"
+              value="${domain.reverse}:${ant.project.name}:${bmfa.Bundle-Version}"/>
+    <property name="bundle.jar.base.name"
+              value="${jardir}/${ant.project.name}"/>
+
+    <property name="impl.suffix"
+              value="${impl.suffix.name}-${bmfa.Bundle-Version}"/>
+    <property name="impl.jar"
+              location="${bundle.jar.base.name}${impl.suffix}.jar"/>
+    <property name="impl-source.jar"
+              location="${bundle.jar.base.name}${impl.suffix}-source.jar"/>
+    <property name="impl-javadoc.jar"
+              location="${bundle.jar.base.name}${impl.suffix}-javadoc.jar"/>
+
+    <property name="api.suffix"
+              value="${api.suffix.name}-${bmfa.Bundle-Version}"/>
+    <property name="api.jar"
+              location="${bundle.jar.base.name}${api.suffix}.jar"/>
+    <property name="api-source.jar"
+              location="${bundle.jar.base.name}${api.suffix}-source.jar"/>
+    <property name="api-javadoc.jar"
+              location="${bundle.jar.base.name}${api.suffix}-javadoc.jar"/>
+
+    <property name="lib.suffix"
+              value="${lib.suffix.name}-${bmfa.Bundle-Version}"/>
+    <property name="lib.jar"
+              location="${bundle.jar.base.name}${lib.suffix}.jar"/>
+    <property name="lib-source.jar"
+              location="${bundle.jar.base.name}${lib.suffix}-source.jar"/>
+    <property name="lib-javadoc.jar"
+              location="${bundle.jar.base.name}${lib.suffix}-javadoc.jar"/>
+
+    <property name="all.suffix"
+              value="${all.suffix.name}-${bmfa.Bundle-Version}"/>
+    <property name="all.jar"
+              location="${bundle.jar.base.name}${all.suffix}.jar"/>
+    <property name="all-source.jar"
+              location="${bundle.jar.base.name}${all.suffix}-source.jar"/>
+    <property name="all-javadoc.jar"
+              location="${bundle.jar.base.name}${all.suffix}-javadoc.jar"/>
+
+    <path id="bundle.api.path">
+      <pathelement location="${api.jar}"/>
+    </path>
+  </target>
+
+  <!-- Targets to be over ridden by individual build files when -->
+  <!-- needing to do something before / after a build.          -->
+  <target name="bundle.custom.pre"/>
+  <target name="bundle.custom.post"/>
+
+  <target name="all"
+          depends="init, bundle.custom.pre, jars, bundle.custom.post"
+          description="Builds all specified variants of the bundle.">
+  </target>
+
+  <macrodef name="bundlebuild_compile"
+            description="Compiles bundle source code">
+    <attribute name="includes"
+               description="Pattern selecting what to compile in src.dir"/>
+    <attribute name="failOnMissingBundles"
+               description="If all bundles on the bundle.path must exist or not"
+               default="true"/>
+    <sequential>
+      <mkdir dir="${classes.out.dir}"/>
+      <mkdir dir="${jars.dir}"/>
+
+      <bundle_locator classPathRef="bundle.path"
+                      newClassPathId="bundle.path.Expanded"
+                      failOnMissingBundles="@{failOnMissingBundles}">
+        <!-- Search the local repository first (where jars are placed) -->
+        <fileset dir="${jars.dir}">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+        <!-- Search the local default repository second -->
+        <fileset dir="${osgi.jars.dir}">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+        <!-- Search the default repository third -->
+        <fileset dir="${osgi.dir}/jars">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+      </bundle_locator>
+
+      <javac destdir="${classes.out.dir}"
+             debug="on"
+             includeAntRuntime="false"
+             includeJavaRuntime="${javac.includeJavaRuntime}"
+             srcdir="${src.dir}"
+             target="${javac.target}"
+             source="${javac.source}"
+             encoding="${javac.encoding}"
+             classpathref="bundle.path.Expanded"
+             bootclasspathref="${bundle.bootclasspath.ref}"
+             includes="@{includes}"
+             excludes="**/package-info.java"
+             >
+      </javac>
+      <!-- Copy resources from the src-tree to the classes-tree. -->
+      <copy toDir="${classes.out.dir}">
+        <fileset dir="${src.dir}"
+                 includes="@{includes}"
+                 excludes="**/*.java,**/*.html"/>
+      </copy>
+    </sequential>
+  </macrodef>
+
+
+  <target name="compile"
+          description="Compiles the bundle, both API and IMPL parts."
+          if="src.dir.exists">
+    <bundlebuild_compile
+       includes="${api.pattern},
+                 ${impl-api.pattern},
+                 ${impl.pattern},
+                 ${all-api.pattern},
+                 ${all.pattern}"/>
+  </target>
+
+  <target name="compile_api"
+          description="Compiles the bundles, API only"
+          if="do_compile_api">
+    <bundlebuild_compile
+       failOnMissingBundles="false"
+       includes="${api.pattern}"/>
+  </target>
+
+
+  <target name="jars" description="Compile all jars">
+    <antcall target="jar_api"             inheritRefs="true"/>
+    <antcall target="jar_lib"             inheritRefs="true"/>
+    <antcall target="jar_impl"            inheritRefs="true"/>
+    <antcall target="jar_all"             inheritRefs="true"/>
+  </target>
+
+  <!-- set up build conditions -->
+  <target name="setup_build">
+    <echo message="Building ${ant.project.name} (${basedir})"/>
+
+    <available property="src.dir.exists"       file="${src.dir}"/>
+    <available property="resources.dir.exists" file="${resources.dir}"/>
+    <available property="resources.out.dir.exists" file="${outdir}/resources"/>
+    <available property="doc.dir.exists"       file="${doc.dir}"/>
+
+    <condition property="do_build_lib">
+      <equals arg1="${bundle.build.lib}"  arg2="true"/>
+    </condition>
+
+    <condition property="do_build_api" value="true">
+      <and>
+        <equals arg1="${bundle.build.api}"  arg2="true"/>
+        <isset property="api.pattern"/>
+      </and>
+    </condition>
+
+    <condition property="do_build_impl">
+      <and>
+        <equals arg1="${bundle.build.impl}" arg2="true"/>
+        <or>
+          <isset property="impl.pattern"/>
+          <isset property="impl-api.pattern"/>
+        </or>
+      </and>
+    </condition>
+
+    <condition property="do_build_all" value="true">
+      <and>
+        <equals arg1="${bundle.build.all}"  arg2="true"/>
+        <or>
+          <isset property="api.pattern"/>
+          <isset property="impl.pattern"/>
+          <isset property="impl-api.pattern"/>
+          <isset property="all.pattern"/>
+          <isset property="all-api.pattern"/>
+        </or>
+      </and>
+    </condition>
+
+    <condition property="do_build_doc">
+      <and>
+        <equals arg1="${bundle.build.doc}"  arg2="true"/>
+        <isset property="doc.dir.exists"/>
+      </and>
+    </condition>
+    <condition property="do_include_source">
+      <and>
+        <equals arg1="${include.source}"    arg2="true"/>
+        <isset property="src.dir.exists"/>
+      </and>
+    </condition>
+
+    <condition property="do_compile_api" value="true">
+      <and>
+        <or>
+          <isset property="do_build_api"/>
+          <isset property="do_build_lib"/>
+        </or>
+        <isset property="src.dir.exists"/>
+      </and>
+    </condition>
+
+    <!-- If a template manifest file exists use it and ignore       -->
+    <!-- manifest headers defined via properties in the build file. -->
+    <condition property="bundlemanifest.mode" value="update">
+      <and>
+        <not><isset property="bundlemanifest.mode"/></not>
+        <available type="file" file="${bundlemanifest.template}"/>
+      </and>
+    </condition>
+    <property name="bundlemanifest.mode" value="replace"/>
+
+    <!-- Ensure that the compiler output dir exists (required since -->
+    <!-- it is used as the "dir"-attribute in a <fileset>.    -->
+    <mkdir dir="${classes.out.dir}"/>
+  </target>
+
+
+  <!-- ========================= PACK BUNDLE =========================== -->
+  <macrodef name="bundlebuild_pack_bundle"
+            description="Pack a bundle jar given resources and compiled files">
+    <attribute name="jar"
+               description="Name of the jar-file to create."/>
+    <attribute name="kind"
+               description="Packing kind, one of 'lib', 'api', 'impl', 'all'"/>
+    <attribute name="kind-bundlemanifest"
+               default="@{kind}"
+               description="Packing kind given to the bundlemanifest task."/>
+    <attribute name="allKinds"
+               default="lib, api, impl, all"
+               description="All kinds for the bundlemanifest task."/>
+    <attribute name="replaceEEmin"
+               default="${ee.min.replacement}"
+               description="If set replace osgi.ee capability requirement for OSGi/Minimum with the given requirement filter."/>
+    <attribute name="imports"
+               description="Name of property holding Import-Package"/>
+    <attribute name="imports-default"
+               description="The default value of Import-Package"
+               default="${bundle.emptystring}"/>
+    <attribute name="exports"
+               description="Name of property holding Export-Package"/>
+    <attribute name="exports-default"
+               description="The default value of Export-Package"
+               default="${bundle.emptystring}"/>
+    <attribute name="activator"
+               description="Name of property holding the Bundle-Activator"
+               default=""/>
+    <attribute name="activator-default"
+               description="The default value of Bundle-Activator"
+               default=""/>
+    <attribute name="includes-exports"
+               description="Includes pattern selecting classes to export"
+               default="--SHOULD-NOT-MATCH-ANY-FILE--"/>
+    <attribute name="includes-impls"
+               description="Includes pattern selecting private impl classes"
+               default="--SHOULD-NOT-MATCH-ANY-FILE--"/>
+    <element name="extraContents"
+             optional="true"
+             description="Place holder element called when the jar has been created, normally used to add more contents to the jar-file."/>
+
+    <sequential>
+      <echo message="@{jar}"/>
+
+      <!-- Use the @{kind} version of manifest properties, define defaults. -->
+      <property name="@{imports}" value="@{imports-default}"/>
+      <property name="@{exports}" value="@{exports-default}"/>
+      <property name="@{activator}" value="@{activator-default}"/>
+
+      <!-- Derive import/export package and activator headers. -->
+      <bundleinfo activator="@{activator}"
+                  imports="@{imports}"
+                  exports="@{exports}"
+                  stdimports="${bundle.stdimports}"
+                  extraimports="${bundle.extraimports}"
+                  implicitImports="${bundle.implicit.imports.@{kind}}"
+                  serviceComponent="${bmfa.Service-Component}"
+                  fragmentHost="${bmfa.Fragment-Host}"
+                  manifestVersion="${bmfa.Bundle-ManifestVersion}"
+                  uses="${bundleinfo.uses}"
+                  failOnExports="${bundleinfo.failOnExports}"
+                  failOnImports="${bundleinfo.failOnImports}"
+                  failOnActivator="${bundleinfo.failOnActivator}"
+                  failOnClassPath="${bundleinfo.failOnClassPath}">
+        <exports dir="${classes.out.dir}" includes="@{includes-exports}"/>
+        <exportsBundleClasspath bundleClasspath="${bmfa.Bundle-Classpath}"
+                                dir="${resources.dir}"
+                                includes="@{includes-exports}"/>
+        <impls dir="${classes.out.dir}" includes="@{includes-impls}"/>
+        <!-- Everything on the bundle classpath that is not exported -->
+        <!-- is classified as impls. -->
+        <implsBundleClasspath bundleClasspath="${bmfa.Bundle-Classpath}"
+                              dir="${resources.dir}"
+                              excludes="@{includes-exports}"/>
+      </bundleinfo>
+
+      <mkdir dir="${jardir}"/>
+
+      <bundlemanifest kind="@{kind-bundlemanifest}"
+                      allKinds="@{allKinds}"
+                      replaceEEmin="@{replaceEEmin}"
+                      mode="${bundlemanifest.mode}"
+                      mainAttributesToSkip="${attrs.to.skip.@{kind}}"
+                      attributePropertyPrefix="${bundle.mf.attr.prefix}"
+                      templateFile="${bundlemanifest.template}"
+                      verbose="${bundlemanifest.verbose}"
+                      file="${outdir}/@{kind}.mf">
+        <attribute name="Build-Date"       value="${bundle.date}"/>
+        <attribute name="Built-From"       value="${proj.dir}"/>
+      </bundlemanifest>
+
+      <jar basedir="${classes.out.dir}"
+           jarfile="@{jar}"
+           includes="@{includes-impls},@{includes-exports}"
+           excludes="**/pspbrwse.jbf"
+           manifestencoding="UTF-8"
+           manifest="${outdir}/@{kind}.mf">
+      </jar>
+
+      <!-- Add extra contents to the bundle jar -->
+      <extraContents/>
+
+      <!-- ** Add bundle sources to OSGI-INF/src ** -->
+      <antcall target="add_src" inheritRefs="true">
+        <param name="add.src.jarfile" value="@{jar}"/>
+      </antcall>
+
+      <!-- ** Create AID-source.jar attachment for the aritfact. ** -->
+      <antcall target="create_source.jar" inheritRefs="true">
+        <param name="includes" value="@{includes-impls},@{includes-exports}"/>
+        <param name="jar"      value="${@{kind}-source.jar}"/>
+      </antcall>
+
+      <!-- ** Create AID-javadoc.jar attachment for the aritfact. ** -->
+      <!-- ** Will document all exported packages.                ** -->
+      <!-- Java packages with source code exported by this bundle. -->
+      <local name="javadoc.src.packages"/>
+      <!-- Does any of the exported pkgs have source code to process= -->
+      <local name="pkgSrcAvail"/>
+      <!-- Add all packages exported by the compiled bundle. -->
+      <bundle_javadoc_helper exportPkgsValue="${@{exports}}"
+                             srcDir="${src.dir}"
+                             pkgWithSourcePropertyName="javadoc.src.packages"
+                             pkgSrcAvailPropertyName="pkgSrcAvail"/>
+      <antcall target="create_javadoc.jar" inheritRefs="true">
+        <param name="pkgSrcAvail" value="${pkgSrcAvail}"/>
+        <param name="sourcepath"  value="${src.dir}"/>
+        <param name="pkgs"        value="${javadoc.src.packages}"/>
+        <param name="jar"         value="${@{kind}-javadoc.jar}"/>
+      </antcall>
+
+      <!-- Save info for the release javadoc covering all bundles. -->
+      <!-- Reuses the outcome of the analysis done above for the -->
+      <!-- bundle local javadoc. -->
+      <antcall target="save_javadoc_data" inheritRefs="true">
+        <param name="pkgs"        value="${javadoc.src.packages}"/>
+        <param name="pkgSrcAvail" value="${pkgSrcAvail}"/>
+      </antcall>
+
+      <antcall target="add_dex" inheritRefs="true">
+        <param name="jarfile" value="@{jar}"/>
+      </antcall>
+
+    </sequential>
+  </macrodef>
+
+
+  <!-- ==================== PACK SOURCE ATTACHMENT ====================== -->
+  <target name="check_do_create_source.jar">
+    <!-- Build source jar when source code exists and -->
+    <!-- ${bundle.build.source.jar} is set to true. -->
+    <condition property="do_create_source.jar">
+      <and>
+        <equals arg1="${bundle.build.source.jar}" arg2="true"/>
+        <equals arg1="${src.dir.exists}"          arg2="true"/>
+      </and>
+    </condition>
+  </target>
+  <target name="create_source.jar"
+          depends="init, check_do_create_source.jar"
+          if="do_create_source.jar">
+    <mkdir dir="${jars.dir}"/>
+
+    <jar basedir="${src.dir}"
+         jarfile="${jar}"
+         includes="${includes}"
+         excludes="**/package-info.java"
+         manifestencoding="UTF-8">
+    </jar>
+  </target>
+
+  <!-- =================== PACK JAVADOC ATTACHMENT ===================== -->
+  <macrodef name="bundlebuild_pack_javadoc"
+            description="Packs a javadoc jar with the API classes for a bundle project">
+    <attribute name="sourcepath"
+               description="The root directory of the source tree to document."/>
+    <attribute name="pkgs"
+               description="Comma separated list of packages to include."/>
+    <attribute name="jar"
+               description="Name of the jar-file to create."/>
+
+    <sequential>
+      <local name="jar.name"/>
+      <basename property="jar.name" file="@{jar}" suffix=".jar"/>
+      <local name="javadoc.out.dir.local"/>
+      <property name="javadoc.out.dir.local"
+                location="${javadoc.out.dir}/${jar.name}"/>
+      <mkdir dir="${javadoc.out.dir.local}"/>
+
+      <local name="javadoc.header"/>
+      <property name="javadoc.header"
+                value="Knopflerfish OSGi bundle ${bmfa.Bundle-Name} ${bmfa.Bundle-Version}"/>
+
+      <local name="javadoc.footer"/>
+      <property name="javadoc.footer"
+                value="Knopflerfish OSGi ${version}"/>
+
+      <local name="javadoc.windowtitle"/>
+      <property name="javadoc.windowtitle"
+                value="${javadoc.header} javadoc"/>
+
+      <local name="javadoc.doctitle"/>
+      <property name="javadoc.doctitle"
+                value="${javadoc.header} API documentation"/>
+
+
+      <javadoc sourcepath="@{sourcepath}"
+               packagenames="@{pkgs}"
+               header="${javadoc.header}"
+               footer="${javadoc.footer}"
+               windowtitle="${javadoc.windowtitle}"
+               doctitle="${javadoc.doctitle}"
+               destdir="${javadoc.out.dir.local}"
+               classpathref="bundle.path.Expanded"
+               >
+        <!-- Custome tags used by OSGi -->
+        <tag name="ThreadSafe"    scope="all" description="ThreadSafe"/>
+        <tag name="NotThreadSafe" scope="all" description="NotThreadSafe"/>
+        <tag name="Immutable"     scope="all" description="Immutable"/>
+        <tag name="security"      scope="all" description="Required Permissions"/>
+        <tag name="noimplement"   scope="all"
+             description="Consumers of this API must not implement this interface"/>
+      </javadoc>
+
+      <jar basedir="${javadoc.out.dir.local}"
+           jarfile="@{jar}"
+           includes="**"
+           manifestencoding="UTF-8">
+      </jar>
+    </sequential>
+  </macrodef>
+
+  <target name="check_do_create_javadoc.jar">
+    <!-- Build javadoc jar when source code for exported pkgs -->
+    <!-- exists and ${bundle.build.javadoc.jar} is set to true. -->
+    <condition property="do_create_javadoc.jar">
+      <and>
+        <equals arg1="${bundle.build.javadoc.jar}" arg2="true"/>
+        <equals arg1="${pkgSrcAvail}"              arg2="true"/>
+      </and>
+    </condition>
+  </target>
+  <target name="create_javadoc.jar"
+          depends="init, check_do_create_javadoc.jar"
+          if="do_create_javadoc.jar">
+    <bundlebuild_pack_javadoc sourcepath="${sourcepath}"
+                              pkgs="${pkgs}"
+                              jar="${jar}"/>
+  </target>
+
+
+  
+  <!-- ============================= IMPL =============================== -->
+  <!-- Bundle with all private classes, activator and resources. -->
+  <target name="jar_impl"
+          depends="init,compile"
+          if="do_build_impl">
+    <bundlebuild_pack_bundle
+       jar="${impl.jar}"
+       kind="impl"
+       imports="bmfa.impl-Import-Package"
+       imports-default="${bmfa.Import-Package}"
+       exports="bmfa.impl-Export-Package"
+       exports-default="${bundle.emptystring}"
+       activator="bmfa.impl-Bundle-Activator"
+       activator-default="${bmfa.Bundle-Activator}"
+       includes-exports="${impl-api.pattern}"
+       includes-impls="${impl.pattern}">
+      <extraContents>
+        <antcall target="add_resources" inheritRefs="true">
+          <param name="add.resource.jarfile"  value="${impl.jar}"/>
+        </antcall>
+      </extraContents>
+    </bundlebuild_pack_bundle>
+  </target>
+
+
+
+  <!-- ============================= API =============================== -->
+  <!-- Bundle exporting public classes, no activator, no private resources. -->
+  <target name="jar_api"
+          depends="init, compile_api"
+          if="do_build_api">
+    <bundlebuild_pack_bundle
+       jar="${api.jar}"
+       kind="api"
+       imports="bmfa.api-Import-Package"
+       imports-default="${bundle.emptystring}"
+       exports="bmfa.api-Export-Package"
+       exports-default="${bmfa.Export-Package}"
+       activator=""
+       activator-default=""
+       includes-exports="${api.pattern}"/>
+  </target>
+
+
+
+  <!-- ============================= LIB =============================== -->
+  <!-- Bundle public classes and resources, no activator. -->
+  <target name="jar_lib"
+          depends="init,compile_api"
+          if="do_build_lib">
+    <bundlebuild_pack_bundle
+       jar="${lib.jar}"
+       kind="lib"
+       imports="bmfa.lib-Import-Package"
+       imports-default="${bmfa.Import-Package}"
+       exports="bmfa.lib-Export-Package"
+       exports-default="${bmfa.Export-Package}"
+       activator=""
+       activator-default=""
+       includes-exports="${api.pattern}">
+      <extraContents>
+        <antcall target="add_resources" inheritRefs="true">
+          <param name="add.resource.jarfile"  value="${lib.jar}"/>
+        </antcall>
+      </extraContents>
+    </bundlebuild_pack_bundle>
+  </target>
+
+
+  <!-- ============================= ALL =============================== -->
+  <!-- Bundle with both public and private classes, activator and resources. -->
+  <target name="jar_all"
+          depends="init,compile"
+          if="do_build_all">
+    <bundlebuild_pack_bundle
+       jar="${all.jar}"
+       kind="all"
+       kind-bundlemanifest=""
+       imports="bmfa.Import-Package"
+       imports-default="${bundle.emptystring}"
+       exports="bmfa.Export-Package"
+       exports-default="${bundle.emptystring}"
+       activator="bmfa.Bundle-Activator"
+       activator-default="${bundle.emptystring}"
+       includes-exports="${api.pattern},
+                         ${impl-api.pattern},
+                         ${all-api.pattern}"
+       includes-impls="${impl.pattern},
+                       ${all.pattern}">
+      <extraContents>
+        <antcall target="add_resources" inheritRefs="true">
+          <param name="add.resource.jarfile"  value="${all.jar}"/>
+        </antcall>
+      </extraContents>
+    </bundlebuild_pack_bundle>
+  </target>
+
+
+
+  <!-- Helper taget that adds files from the resources directory -->
+  <!-- to a bundle. -->
+  <target name="add_resources">
+    <antcall target="add_resources_bundle" inheritRefs="true"/>
+    <antcall target="add_resources_generated" inheritRefs="true"/>
+  </target>
+
+  <target name="add_resources_bundle" if="resources.dir.exists">
+    <jar jarfile="${add.resource.jarfile}" update="true">
+      <fileset dir="${resources.dir}"/>
+    </jar>
+  </target>
+
+  <!--<target name="add_resources_generated" if="resources.out.dir.exists"> -->
+  <target name="add_resources_generated" if="resources.out.dir.exists">
+    <jar jarfile="${add.resource.jarfile}" update="true">
+      <fileset dir="${resources.out.dir}"/>
+    </jar>
+  </target>
+
+  <!-- Helper taget that adds sources from the source tree to a bundle. -->
+  <target name="add_src" if="do_include_source">
+    <jar jarfile="${add.src.jarfile}" update="true">
+      <zipfileset dir="${src.dir}"
+                  includes="**/*.java"
+                  prefix="OSGI-OPT/src"/>
+    </jar>
+  </target>
+
+  <!-- Helper taget that adds Android dex data to the bundle. -->
+  <target name="add_dex" if="android.exists">
+    <echo message="add_dex ${jarfile}"/>
+    <add_dex jarfile="${jarfile}" outdir="${outdir}"/>
+  </target>
+
+
+  <!-- Should only add items to ${source.files} and ${exported.files} -->
+  <!-- when ${generate.javadoc.data} is set to "true" and there are   -->
+  <!-- source files to process. -->
+  <target name="check_do_generate_javadoc_data">
+    <condition property="do_generate_javadoc_data">
+      <and>
+        <equals arg1="${generate.javadoc.data}" arg2="true"/>
+        <equals arg1="${pkgSrcAvail}"           arg2="true"/>
+      </and>
+    </condition>
+  </target>
+  <target name="save_javadoc_data"
+          depends="check_do_generate_javadoc_data"
+          if="do_generate_javadoc_data">
+    <echo message="save_javadoc: to:${sources.file} src:${src.dir} "/>
+    <echo file="${sources.file}" append="true"
+          message="${src.dir}${line.separator}"/>
+    <echo file="${exported.file}" append="true"
+          message="${pkgs}${line.separator}"/>
+  </target>
+
+  <import file="${ant.dir}/console_interactions.xml"/>
+  <import file="${ant.dir}/bundle_junit.xml"/>
+
+  <target name="bundle_doc"
+          description="Creates bundle specific doc"
+          depends="init"
+          if="do_build_doc">
+    <makehtml title="${bmfa.Bundle-Name}"
+              description="${bmfa.Bundle-Description}"
+              template="${bundledoc_template}"
+              outdir="${outdocdir}"
+              manstyle="true">
+      <fileset dir="${doc.dir}">
+        <include name="**/*.html"/>
+      </fileset>
+    </makehtml>
+
+    <copy todir="${outdocdir}">
+      <fileset dir="${doc.dir}">
+        <exclude name="**/*.html"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="clean" description="Deletes all generated files.">
+    <delete dir="${outdir}" failonerror="false"/>
+    <delete includeEmptyDirs="true" verbose="true" failonerror="false">
+      <fileset dir="${jardir}">
+        <include name="${ant.project.name}.jar" />
+        <include name="${ant.project.name}-*.jar" />
+        <include name="${ant.project.name}_all-*.jar" />
+        <include name="${ant.project.name}_api-*.jar" />
+        <include name="${ant.project.name}_lib-*.jar" />
+      </fileset>
+      <dirset dir="${jardir}" excludes="*,**/*"/>
+    </delete>
+  </target>
+
+</project>
diff --git a/ant/bundlebuild_include.xml b/ant/bundlebuild_include.xml
new file mode 100644
index 0000000..c08a494
--- /dev/null
+++ b/ant/bundlebuild_include.xml
@@ -0,0 +1,52 @@
+<!--
+  ** Copyright (c) 2003-2008, 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.
+  -->
+
+<!-- This file is now deprecated please use the new "bundlebuild.xml". -->
+<!-- See "build_example.xml" for usage details and a brief documentation. -->
+<!-- To upgrade: Remove the old doctype-line at the begining of your -->
+<!-- build file. Insert the following lines:                         -->
+<!--    <dirname  property="proj.dir" file="${ant.file.desktop}"/>   -->
+<!--    <property name="topdir"       location="${proj.dir}/../.."/> -->
+<!-- after the project-line                                          -->
+<!-- Replace the   &bundlebuild_include; line at the end of the  -->
+<!-- file with                                                       -->
+<!--   <import file="${topdir}/../ant/bundlebuild.xml"/>             -->
+ 
+
+ <property name="topdir"   location="."/>
+ <property name="proj.dir" location="."/>
+ <property name="osgi.dir" location="${topdir}"/>
+ <property name="ant.dir"  location="${osgi.dir}/../ant"/>
+
+ <import file="${ant.dir}/bundlebuild.xml"/>
diff --git a/ant/bundletasks.xml b/ant/bundletasks.xml
new file mode 100644
index 0000000..409bfa2
--- /dev/null
+++ b/ant/bundletasks.xml
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   ** Copyright (c) 2003-2013, 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.
+  -->
+
+<project name="bundletasks" basedir="." default="default">
+
+  <dirname  property="ant.dir" file="${ant.file.bundletasks}"/>
+
+  <property name="ant.lib"       location="${ant.dir}/lib"/>
+  <property name="antclasses"    location="${ant.dir}/classes"/>
+  <property name="osgi.dir"      location="${ant.dir}/../osgi"/>
+  <property name="framework.dir" location="${osgi.dir}/framework"/>
+
+
+  <!-- ASM bytecode manipulation and analysis framework -->
+  <property name="asm.version" value="3.2"/>
+  <property name="asm.jar"
+            location="${osgi.dir}/framework/libs/asm-${asm.version}.jar"/>
+  <path id="asm.path">
+    <pathelement location="${osgi.dir}/framework/libs/asm-${asm.version}.jar"/>
+  </path>
+
+  <!-- Download and install repoindex -->
+
+  <property name="bndtools.download.url"
+            value="https://bndtools.ci.cloudbees.com/job/bindex.master/lastStableBuild/artifact/cnf/releaserepo"/>
+
+  <property name="org.osgi.impl.bundle.repoindex.cli.jar"
+            value="org.osgi.impl.bundle.repoindex.cli-0.0.4.jar"/>
+  <property name="org.osgi.impl.bundle.repoindex.cli.download.url"
+            value="${bndtools.download.url}/org.osgi.impl.bundle.repoindex.cli/"/>
+
+  <property name="org.osgi.impl.bundle.repoindex.ant.jar"
+            value="org.osgi.impl.bundle.repoindex.ant-0.0.1.jar"/>
+  <property name="org.osgi.impl.bundle.repoindex.ant.download.url"
+            value="${bndtools.download.url}/org.osgi.impl.bundle.repoindex.ant"/>
+
+  <target name="install_repoindex">
+    <get src="${org.osgi.impl.bundle.repoindex.cli.download.url}/${org.osgi.impl.bundle.repoindex.cli.jar}"
+         dest="${ant.lib}/${org.osgi.impl.bundle.repoindex.cli.jar}"
+         verbose="false"
+         skipexisting="true"/>
+    <get src="${org.osgi.impl.bundle.repoindex.ant.download.url}/${org.osgi.impl.bundle.repoindex.ant.jar}"
+         dest="${ant.lib}/${org.osgi.impl.bundle.repoindex.ant.jar}"
+         verbose="false" skipexisting="true"/>
+  </target>
+
+  <macrodef name="repoindex"
+            description="Generates repository XML description.">
+    <attribute name="name"
+               description="The name of the repository to create."/>
+    <attribute name="dir"
+               description="The directory to index."/>
+    <attribute name="stylesheet"
+               default="${ant.dir}/xsl/repository2html.xsl"
+               description="Path to xsl stylesheet."/>
+
+    <sequential>
+      <path id="repoindex.path.pre">
+        <pathelement location="org.osgi.impl.bundle.repoindex.cli-N.N.N.jar"/>
+        <pathelement location="repoindex_kf_all-N.N.N.jar"/>
+      </path>
+      <bundle_locator classPathRef="repoindex.path.pre"
+                      newClassPathId="repoindex.path"
+                      failOnMissingBundles="true">
+        <fileset dir="${ant.dir}/lib">
+          <include name="*.jar"/>
+          <exclude name="*-source.jar"/>
+          <exclude name="*-javadoc.jar"/>
+        </fileset>
+        <!-- Search the local repository first (where jars are placed) -->
+        <fileset dir="${jars.dir}/repoindex_kf">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+        <!-- Search the local default repository second -->
+        <fileset dir="${osgi.jars.dir}/repoindex_kf">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+        <!-- Search the default repository third -->
+        <fileset dir="${osgi.dir}/jars/repoindex_kf">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+        <!-- Search the repository to index fourth -->
+        <fileset dir="@{dir}">
+          <exclude name="**/*-source.jar"/>
+          <exclude name="**/*-javadoc.jar"/>
+          <include name="**/*.jar"/>
+        </fileset>
+      </bundle_locator>
+
+      <local name="repoindex.jars.line"/>
+      <fileset id="repoindex.jars" dir="@{dir}">
+        <include name="**/*.jar"/>
+        <exclude name="**/*-source.jar"/>
+        <exclude name="**/*-javadoc.jar"/>
+      </fileset>
+      <pathconvert refid="repoindex.jars" property="repoindex.jars.line" pathsep=" "/>
+      <java classname="org.osgi.impl.bundle.bindex.cli.Index"
+            fork="yes"
+            dir="@{dir}">
+        <classpath refid="repoindex.path"/>
+        <arg value="--pretty"/>
+        <arg value="-n"/>
+        <arg value="@{name}"/>
+        <arg line="${repoindex.jars.line}"/>
+      </java>
+
+      <copy file="@{stylesheet}"
+            tofile="@{dir}/repository2html.xsl"/>
+      <replace file="@{dir}/index.xml">
+        <replacetoken><![CDATA[<?xml version='1.0' encoding='utf-8'?>]]></replacetoken>
+        <replacevalue><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+        <?xml-stylesheet type='text/xsl' href='repository2html.xsl'?>]]></replacevalue>
+      </replace>
+    </sequential>
+  </macrodef>
+
+  <property name="proguard.version" value="4.10"/>
+  <property name="proguard-anttask.jar"
+            value="proguard-anttask-${proguard.version}.jar"/>
+  <property name="proguard-base.jar"
+            value="proguard-base-${proguard.version}.jar"/>
+  <property name="maven.url" value="http://repo1.maven.org/maven2"/>
+  <property name="proguard.url" value="${maven.url}/net/sf/proguard"/>
+  <property name="proguard-anttask.url"
+            value="${proguard.url}/proguard-anttask/${proguard.version}/${proguard-anttask.jar}"/>
+  <property name="proguard-base.url"
+            value="${proguard.url}/proguard-base/${proguard.version}/${proguard-base.jar}"/>
+
+  <target name="install_proguard">
+    <get src="${proguard-base.url}"
+         dest="${ant.lib}/${proguard-base.jar}"
+         verbose="false"
+         skipexisting="true"/>
+    <get src="${proguard-anttask.url}"
+         dest="${ant.lib}/${proguard-anttask.jar}"
+         verbose="false"
+         skipexisting="true"/>
+    <taskdef resource="proguard/ant/task.properties">
+      <classpath>
+        <pathelement location="${ant.lib}/${proguard-base.jar}"/>
+        <pathelement location="${ant.lib}/${proguard-anttask.jar}"/>
+      </classpath>
+    </taskdef>
+  </target>
+
+
+  <!-- Compile and pack the Knopflerfish bundle tasks.  -->
+  <property name="bundle_tasks.jar" location="${ant.lib}/bundle_tasks.jar"/>
+
+  <path id="bundle_tasks.path">
+    <pathelement location="${antclasses}"/>
+    <pathelement location="${bundle_tasks.jar}"/>
+    <path refid="asm.path"/>
+  </path>
+
+
+  <target name="chkBundleTaskSrc">
+    <condition property="bundleTasksBuild.notRequired">
+      <not>
+        <and>
+          <available type="dir"  file="${ant.dir}/src"/>
+          <available type="dir"  file="${framework.dir}/src"/>
+          <available type="file" file="${asm.jar}"/>
+        </and>
+      </not>
+    </condition>
+  </target>
+
+
+  <!-- This check is needed to be able to avoid rebuilding -->
+  <!-- when properties used in the manifest has changed.   -->
+  <target name="chkBundleTasksBuild" unless="bundleTasksBuild.notRequired">
+    <condition property="bundleTasksBuild.notRequired">
+      <uptodate>
+        <srcfiles dir="${ant.dir}/src"
+                  includes="org/knopflerfish/ant/**"/>
+        <srcfiles dir="${framework.dir}/src"
+                  includes="org/osgi/framework/Version.java,
+                            org/osgi/framework/Constants.java"/>
+        <mapper type="merge" to="${bundle_tasks.jar}"/>
+      </uptodate>
+    </condition>
+  </target>
+
+
+  <available property="jdk1.7+" classname="java.lang.ClassValue"/>
+
+  <condition property="javac.source" value="1.5" else="1.5">
+    <isset property="jdk1.7+"/>
+  </condition>
+  <condition property="javac.target" value="1.5" else="jsr14">
+    <isset property="jdk1.7+"/>
+  </condition>
+
+  <target name="build_bundle_tasks"
+          depends="chkBundleTaskSrc,chkBundleTasksBuild"
+          unless="bundleTasksBuild.notRequired">
+    <mkdir dir="${antclasses}"/>
+    <javac destdir="${antclasses}"
+           classpathref="bundle_tasks.path"
+           includeAntRuntime="true"
+           source="${javac.source}"
+           target="${javac.target}"
+           debug="on">
+      <src path="${ant.dir}/src"/>
+      <!-- org.osgi.framework.Version is used by BundleLocator. -->
+      <src path="${framework.dir}/src"/>
+      <include name="org/knopflerfish/ant/**"/>
+      <include name="org/osgi/framework/Constants.java"/>
+      <include name="org/osgi/framework/Version.java"/>
+      <include name="org/osgi/framework/VersionRange.java"/>
+    </javac>
+
+    <jar destfile="${bundle_tasks.jar}"
+         compress="true"
+         update="false"
+         filesonly="true">
+      <manifest>
+        <attribute name="Implementation-Vendor" value="Knopflerfish"/>
+        <attribute name="Implementation-Title"
+                   value="Knopflerfish Bundle Tasks"/>
+        <attribute name="Knopflerfish-Version" value="${version}"/>
+      </manifest>
+      <zipfileset dir="${ant.dir}/src"
+                  includes="**/antlib.xml"/>
+      <zipfileset dir="${antclasses}"/>
+      <zipfileset src="${asm.jar}" includes="org/**"/>
+    </jar>
+  </target>
+
+  <target name="define_bundle_tasks"
+          description="Defines the Knopflerfish bundle tasks">
+    <taskdef resource="org/knopflerfish/ant/taskdefs/bundle/antlib.xml">
+      <classpath>
+        <pathelement location="${bundle_tasks.jar}"/>
+      </classpath>
+    </taskdef>
+  </target>
+
+  <target name="bundle_tasks"
+          description="Builds and defines the Knopflerfish bundle tasks"
+          depends="build_bundle_tasks,
+                   define_bundle_tasks">
+  </target>
+
+  <target name="default" depends="bundle_tasks"/>
+
+</project>
diff --git a/ant/console_interactions.xml b/ant/console_interactions.xml
new file mode 100644
index 0000000..87f1470
--- /dev/null
+++ b/ant/console_interactions.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ** Copyright (c) 2003-2008, 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.
+  -->
+
+<project name="console_interactions" basedir=".">
+
+  <!-- Prefix for location of the bundle to install in the -->
+  <!-- install-target.                                     -->
+  <property name="install_url_prefix"  value="file:"/>
+
+  <!-- Properties for the send_console_cmd-target. -->
+  <property name="console.host"        value="localhost"/>
+  <property name="console.port"        value="23"/>
+  <property name="console.user"        value="admin"/>
+  <property name="console.pwd"         value="admin"/>
+  <property name="console.welcome"     value="Knopflerfish OSGi console"/>
+  <property name="console.loginok"     value="'quit' to end session"/>
+
+
+  <target name="check_telnet">
+    <available classname="com.oroinc.net.telnet.TelnetCommand"
+              property="telnet.available"/>
+    <fail unless="telnet.available"
+          message="Telnet lib is not available. Please download from http://www.savarese.org/oro/downloads/index.html#NetComponents and install in $$ANT_HOME/lib. You can also try  'ant install_netcomponents'"/>
+  </target>
+
+  <target name="install_netcomponents">
+    <antcall target="download_netcomponents'" />
+    <antcall target="unpack_netcomponents'"   />
+  </target>
+
+  <target name="download_netcomponents">
+    <get src="http://www.savarese.org/oro/downloads/NetComponents-1.3.8.zip"
+         dest="${sysprops.ANT_HOME}/NetComponents-1.3.8.zip"/>
+  </target>
+
+  <target name="unpack_netcomponents">
+    <unzip src="${sysprops.ANT_HOME}/NetComponents-1.3.8.zip"
+           dest="${sysprops.ANT_HOME}/lib">
+      <patternset>
+	<include name="NetComponents-1.3.8a/NetComponents.jar"/>
+      </patternset>
+    </unzip>
+
+    <move file="${sysprops.ANT_HOME}/lib/NetComponents-1.3.8a/NetComponents.jar"
+          tofile="${sysprops.ANT_HOME}/lib/NetComponents.jar"/>
+  </target>
+
+  <target name="install"
+          depends="init"
+          description="Install <bundle>.jar using telnet console">
+    <antcall target="send_console_cmd">
+      <param name="cmd"
+             value="/fr install ${install_url_prefix}${all.jar}"/>
+    </antcall>
+    <!-- give it a chance to succeed -->
+    <sleep seconds="5"/>
+  </target>
+
+  <target name="install_impl"
+          depends="init"
+          description="Install <bundle>_impl.jar using telnet console">
+    <antcall target="send_console_cmd">
+      <param name="cmd"
+             value="/fr install ${install_url_prefix}${impl.jar}"/>
+    </antcall>
+    <!-- give it a chance to succeed -->
+    <sleep seconds="5"/>
+  </target>
+
+  <target name="stop"
+          depends="init"
+          description="Stop <bundle> using telnet console">
+    <antcall target="send_console_cmd">
+      <param name="cmd"
+             value="/fr stop "${bmfa.Bundle-Name}""/>
+    </antcall>
+  </target>
+
+  <target name="start"
+          depends="init"
+          description="Start <bundle> using telnet console">
+    <antcall target="send_console_cmd">
+      <param name="cmd"
+             value="/fr start "${bmfa.Bundle-Name}""/>
+    </antcall>
+  </target>
+
+  <target name="update"
+          depends="init"
+          description="Update <bundle> using telnet console">
+    <antcall target="send_console_cmd">
+      <param name="cmd"
+             value="/fr update "${bmfa.Bundle-Name}""/>
+    </antcall>
+  </target>
+
+  <target name="uninstall"
+          depends="init"
+          description="Uninstall <bundle> using telnet console">
+    <antcall target="send_console_cmd">
+      <param name="cmd"
+           value="/fr uninstall "${bmfa.Bundle-Name}""/>
+    </antcall>
+  </target>
+
+  <target name="send_console_cmd" depends="check_telnet">
+    <telnet port="${console.port}" server="${console.host}" timeout="20">
+      <read string="${console.welcome}"/>
+      <read>ogin:</read>
+      <write echo="true">${console.user}</write>
+      <read>assword:</read>
+      <write echo="false">${console.pwd}</write>
+      <read string="${console.loginok}"/>
+      <write>${cmd}</write>
+      <read/>
+    </telnet>
+  </target>
+
+
+  <target name="junit_ext"
+          description="Runs remote JUnit test using external runner">
+    <fail unless="test.id" message="test.id must be set to test suite id"/>
+    <java classname="${junit.runner.class}" fork="yes">
+      <classpath>
+	<path location="${jars.dir}/junit/junit_all-1.0.0.jar"/>
+	<path refid="bundle.compile.path"/>
+      </classpath>
+      <sysproperty key="suite.url"
+                   value="http://${http.host}:${http.port}/junit?id=${test.id}"/>
+      <arg value="org.knopflerfish.service.junit.client.JUnitClient"/>
+    </java>
+  </target>
+
+  <target name="junit_ant"
+          description="Runs remote JUnit test using Ant junit task">
+    <fail unless="test.id" message="test.id must be set to test suite id"/>
+    <echo message = "JUnit output file is '${junit.outfile}'"/>
+    <junit fork="yes" showoutput="true" printsummary="true">
+      <sysproperty key="suite.url"
+                   value="http://${http.host}:${http.port}/junit?id=${test.id}"/>
+      <classpath>
+	<path location="${jars.dir}/junit/junit_all-1.0.0.jar"/>
+	<path refid="bundle.compile.path"/>
+      </classpath>
+      <formatter type="${junit.formatter}"/>
+      <test name="org.knopflerfish.service.junit.client.JUnitClient"
+            outfile="${junit.outfile}"/>
+    </junit>
+  </target>
+
+</project>
diff --git a/ant/docbuild_include.xml b/ant/docbuild_include.xml
new file mode 100644
index 0000000..ac832c4
--- /dev/null
+++ b/ant/docbuild_include.xml
@@ -0,0 +1,56 @@
+<project name="docbuild" basedir=".">
+
+  <dirname property="docbuild.basedir" file="${ant.file.docbuild}"/>
+
+  <target name="build_doc"
+          description="Builds user or bundle doc">
+
+    <!-- Make the makehtml-task available -->
+    <taskdef resource="org/knopflerfish/ant/taskdefs/bundle/antlib.xml"
+             classpath="${docbuild.basedir}/lib/bundle_tasks.jar"/>
+
+    <!-- Default out dir -->
+    <property name="docbuild.outdir"
+              location="${docbuild.basedir}/../osgi/out/doc/${docbuild.name}"/>
+
+    <!-- Check if there's a readme.txt, but not an index.html 
+         In that case w should create a simple readme.txt
+         Experimental!!
+      -->
+    <condition property="fix_readme_index">
+      <and>
+        <not>
+          <available file="${docbuid.fromdir}/index.html"/>
+        </not>
+        <available file="${docbuid.fromdir}/readme.txt"/>
+      </and>
+    </condition>
+    <!-- Experimental, and therefor commented out 
+         <antcall target="do_create_readme_index"/>
+         -->
+    
+    <makehtml title="${docbuild.title}"
+              description="${docbuild.description}"
+              template="${docbuild.basedir}/html_template/bundledoc_ext.html"
+              outdir="${docbuild.outdir}"
+              manstyle="${docbuild.manstyle}">
+      <!--
+         <available file="${docbuid.fromdir}/index.html" property="index.html.present">
+           <available file="${docbuid.fromdir}/readme.txt" property="readme.txt.present">
+             -->        
+      <fileset dir="${docbuild.fromdir}">
+        <include name="**/*.html"/>
+      </fileset>
+    </makehtml>
+    <copy todir="${docbuild.outdir}">
+      <fileset dir="${docbuild.fromdir}">
+        <exclude name="**/*.html"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="do_create_readme_index">
+  </target>
+
+
+</project>
diff --git a/ant/html_template/bundle_header.html b/ant/html_template/bundle_header.html
new file mode 100644
index 0000000..c608d08
--- /dev/null
+++ b/ant/html_template/bundle_header.html
@@ -0,0 +1,81 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../css/kf_man.css" rel="stylesheet" type="text/css">
+
+    <style type="text/css">
+
+    DIV.left_hdr {
+      width: 225px;
+      height: 100%;
+      background: #000;
+      margin: 0px;
+      padding-top: 10px;
+      padding-left: 15px;
+      color: #fff;
+      float:left;
+      font-weight: bold;
+    }
+
+    DIV.logo_hdr {
+      height: 100%;
+      background: #fb0b0c;
+      margin: 0px 0px 0px 225px;
+      padding-top: 10px;
+      padding-left: 50px;
+    }
+
+    DIV.header_fade {
+      height: 15px;
+      border: 0px;
+      margin: 0px;
+      padding:0px;
+      border-style: none;
+      background-image: url('../images/fadeout_15.png');
+      background-size: 15px;
+      background-repeat: repeat-x;
+      clear:both;
+      overflow: hidden; /* To prevent IE to add an extra 1px at the bottom */
+    }
+
+    BODY  {
+      background: #fff;
+      margin-top:   5px;
+      margin-left:  10px;
+      margin-right: 10px;
+      font-size: 0.8125em;
+    }
+  </style>
+    
+</head>
+
+<body>
+  <div id="header">
+    <div id="header_logo">
+      <a target="_top" href="../index.html" >
+        <img src="../images/kf300_black.png" border="0" alt="knopflerfish logo"/>
+      </a>
+    </div>
+    <div id="header_centerbox">
+      <div class="header_centerinfo_top">
+	Distribution Documentation
+      </div>
+      <div class="header_centerinfo_bottom">
+	Knopflerfish OSGi
+      </div>
+    </div>
+    <div id="header_rightinfo">
+      <div class="header_stylish">
+	Open Source OSGi Service Platform Maintained by
+      </div>
+      <a href="http://www.makewave.com">
+	<img border="0" alt="Makewave" src="../images/makewave_logo.png" border="0" style="margin-top: 4px;">
+      </a>
+    </div>
+    <!-- <div style="clear:both;"></div> -->
+    <div class="header_fade">
+    </div>
+  </div>
+</body>
+</html>
diff --git a/ant/html_template/bundle_index.html b/ant/html_template/bundle_index.html
new file mode 100644
index 0000000..37609a8
--- /dev/null
+++ b/ant/html_template/bundle_index.html
@@ -0,0 +1,42 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <title>Knopflerfish - Bundle Jar Documentation</title>
+    <script type="text/javascript" language="JavaScript">
+      <!--
+	  targetPage = "" + getPageId(window.location.search);
+
+	  function getPageId ( searchStr ) {
+	    var idStartPos = searchStr.indexOf('bundle=');
+	    if (-1==idStartPos) {
+	      return "main.html";
+	    }
+	    idStartPos += 7;
+	    var idEndPos = searchStr.indexOf('&',idStartPos);
+	    if (-1==idEndPos) {
+	      return searchStr.substr(idStartPos);
+	    } 
+	    return searchStr.substring(idStartPos,idEndPos);
+	  }
+
+	  function loadFrame() {
+	    top.bundle_main.location = top.targetPage;
+	  }
+
+          //-->
+    </script> 
+  </head>
+  <frameset rows="95px,*" onLoad="top.loadFrame()">
+    <frame name="bundle_header" src="header.html"
+           frameborder="0"      scrolling="no"
+           marginwidth="0"      marginheight="0">
+    <frameset cols="240,*">
+      <frame name="bundle_list" src="list.html"
+       frameborder="0"             scrolling="auto"
+       marginwidth="0"             marginheight="0">
+      <frame name="bundle_main" src="main.html"
+       frameborder="0"             scrolling="auto">
+    </frameset>
+  </frameset>
+</html>
+
diff --git a/ant/html_template/bundle_info.html b/ant/html_template/bundle_info.html
new file mode 100644
index 0000000..265004a
--- /dev/null
+++ b/ant/html_template/bundle_info.html
@@ -0,0 +1,151 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="${relpathup}style.css" rel="stylesheet" type="text/css">
+  <title>${FILE}</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>${FILE}</h2>
+
+<p>
+<a href="${jarRelPath}">download</a> (${FILEINFO})
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>${Bundle-Name}</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>${Bundle-SymbolicName}</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>${Bundle-Version}</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>${Bundle-Description}</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>${Bundle-Vendor}</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>${Bundle-ContactAddress}</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>${Bundle-License}</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="${Bundle-DocURL}">${Bundle-DocURL}</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>${Bundle-ManifestVersion}</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>${Bundle-Activator}</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>${Bundle-Classpath}</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>${Export-Package}</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>${Import-Package}</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td>${DynamicImport-Package}</td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>${Provide-Capability}</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>${Require-Capability}</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ ${MF.UNHANDLED}
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+${depends.list}
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+${depending.list}
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+${sources.list}
+
+</body>
+</html>
+
+
diff --git a/ant/html_template/bundle_list.html b/ant/html_template/bundle_list.html
new file mode 100644
index 0000000..12a6682
--- /dev/null
+++ b/ant/html_template/bundle_list.html
@@ -0,0 +1,51 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="style.css" rel="stylesheet" type="text/css">
+  <style type="text/css"> 
+      BODY {
+      background: #fff;
+      margin-top:    5px;
+      margin-left:  15px;
+      margin-right: 10px;
+      }
+
+      H2 {
+        color:#802060;
+        font-size:13px;
+        font-weight:bold;
+        margin:6px 0px 6px 0px;	     
+        padding:6px 0px 6px 0px;
+      }
+
+      #bundle_list {
+        margin-left: 8px;
+      }
+
+      #bundle_list A {
+        color: #000;
+        text-decoration: none;
+      }
+	      
+      #bundle_list A:hover {
+        color: #805362;	      
+        text-decoration: underline;
+        font-weight:      bold;
+      }
+  </style>
+</head>
+
+<body>
+${bundle.list.header}
+<a target="_top" href="../index.html">Knopflerfish Documentation</a><br>
+<a target="bundle_main" href="main.html">Bundle Jar Documentation</a><br>
+<a target="bundle_main" href="package_list.html">Bundle Packages</a><br>
+<p></p>
+<div id="bundle_list">
+${bundle.list}
+</div>
+</body>
+
+</html>
+
diff --git a/ant/html_template/bundle_main.html b/ant/html_template/bundle_main.html
new file mode 100644
index 0000000..1baa5c3
--- /dev/null
+++ b/ant/html_template/bundle_main.html
@@ -0,0 +1,41 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link type="text/css" href="../css/knopflerfish.css" rel="stylesheet">
+  <link type="text/css" href="style.css" rel="stylesheet">
+  <title>Knopflerfish - Bundle Jar Documentation</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+  <h1 class="kf">Bundle Jar Documentation</h1>
+
+  <p>This section contains information on all bundle jar files
+  included in this distribution of Knopflerfish.</p>
+
+  <p>Select the bundles from the bundle list to the left to view
+  detailed bundle information, including manifest headers, bundle
+  dependencies and derived javadoc links based on imported and
+  exported packages.</p>
+
+  <p>
+${unresolved.list}
+  </p>
+
+  <h2 class="filled">Bundle Jars Listing</h2>
+  <p>
+    <table>
+      ${bundle.list}
+    </table>
+  </p>
+
+</body>
+</html>
+
diff --git a/ant/html_template/bundledoc.html b/ant/html_template/bundledoc.html
new file mode 100644
index 0000000..c022351
--- /dev/null
+++ b/ant/html_template/bundledoc.html
@@ -0,0 +1,34 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - $(BUNDLE_NAME), v$(BUNDLE_VERSION)</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: $(BUNDLE_NAME)
+      </div>
+      <div class="userdoc_hdr_right">
+	Version $(BUNDLE_VERSION)
+      </div>
+      $(MAIN)
+
+      <h2>Bundle Jar docs</h2>
+      $(BUNDLE_JARDOCS)
+
+      <h2>Exported Packages</h2>
+      $(BUNDLE_EXPORT_PACKAGE)
+    </div>
+  </body>
+</html>
+
diff --git a/ant/html_template/bundledoc_ext.html b/ant/html_template/bundledoc_ext.html
new file mode 100644
index 0000000..12f18b0
--- /dev/null
+++ b/ant/html_template/bundledoc_ext.html
@@ -0,0 +1,20 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - $(TITLE)</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    $(MAIN)
+  </body>
+</html>
+    
diff --git a/ant/html_template/frameworkdoc.html b/ant/html_template/frameworkdoc.html
new file mode 100644
index 0000000..c11564d
--- /dev/null
+++ b/ant/html_template/frameworkdoc.html
@@ -0,0 +1,31 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Knopflerfish Framework Documentation version $(BUNDLE_VERSION)</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Knopflerfish Framework
+      </div>
+      <div class="userdoc_hdr_right">
+	Version $(BUNDLE_VERSION)
+      </div>
+      $(MAIN)
+
+      <h2>Exported Packages</h2>
+      $(BUNDLE_EXPORT_PACKAGE)
+    </div>
+  </body>
+</html>
+
diff --git a/ant/html_template/mvn_dep_mgmt.xsl b/ant/html_template/mvn_dep_mgmt.xsl
new file mode 100644
index 0000000..b314bbb
--- /dev/null
+++ b/ant/html_template/mvn_dep_mgmt.xsl
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:output method="html"/>
+
+  <!-- 
+       This is a naive Maven deployment management to HTML tranformation
+       style sheet.
+    -->
+
+  <xsl:template match="/">
+    <html lang="en">
+      <xsl:apply-templates/>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="KF">
+    <head>
+      <meta http-equiv ="Content-Type"
+            content    ="text/html; charset=ISO-8859-1"/>
+      
+      <meta http-equiv ="CACHE-CONTROL"
+            content    ="NO-CACHE"/>
+      
+      <title><xsl:value-of select="@product"/> <xsl:value-of select="@version"/> Maven Artifacts</title>
+      <link rel="stylesheet" type="text/css"
+	    href="http://www.knopflerfish.org./css/knopflerfish2.1.css"/>
+      <link rel="shortcut icon"
+	    href="http://www.knopflerfish.org./images/favicon.png"/>
+    </head>
+
+    <body>
+      <!-- Override default width for main (900px), since we need more space... -->
+      <div id="main" style="width:1200px">
+        <a name="top"></a>
+        <div id="header">
+          <div id="header_logo">
+            <a href="http://www.knopflerfish.org/index.html"><img src="http://www.knopflerfish.org./images/kf300_black.png" border="0" alt="Knopflerfish logo"/></a>
+          </div>
+	  <div id="header_ad">
+	    <div class="header_stylish">
+	      Open Source OSGi Service Platform Maintained by<br/>
+	      <a href="http://www.makewave.com">
+		<img style="margin-top: 4px;" alt="Makewave" border="0"
+		     src="http://www.knopflerfish.org./images/makewave_logo.png"/>
+	      </a>
+	    </div>
+	  </div>
+	  <div class="break"></div>
+	  <div id="header_menu">
+	    <a class="button_closed" href="http://www.knopflerfish.org./index.html">Home</a>
+	  </div>
+        </div>
+
+	<div id="leftmenu">
+	  <div class="nrow1_closed"><a href="http://www.knopflerfish.org./license.html">License</a></div>
+	  <div class="nrow1_closed"> </div>
+	  <div class="nrow1_closed"><a href="http://www.knopflerfish.org./mailman/listinfo">Mailing lists </a></div>
+	  <div class="nrow1_closed"><a  href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker <img border="0" alt="" src="http://www.knopflerfish.org./images/extlink.gif"/></a></div>
+	  <div class="nrow1_closed"><a href="https://sourceforge.net/forum/forum.php?forum_id=328005">Forum<img border="0" src="http://www.knopflerfish.org./images/extlink.gif" alt=""/></a></div>
+	  <div class="nrow1_closed"><a href="http://knopflerfish.blogspot.com/">Knopflerfish Blog<img border="0" src="http://www.knopflerfish.org./images/extlink.gif" alt=""/></a></div>
+	  <div class="makewave">Maintained by<br/>
+	    <a href="http://www.makewave.com"><img src="http://www.knopflerfish.org./images/makewave_logo_126x16.gif" alt="Makewave" border="0"/></a><br/>
+	    <div class="makewave_2">
+	      <a href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro<img border="0" alt="" src="http://www.knopflerfish.org./images/extlink.gif"/></a><br/>
+	      <a href="http://www.makewave.com/site.en/products/osgi_training.shtml">OSGi Training<img border="0" alt="" src="http://www.knopflerfish.org./images/extlink.gif"/></a><br/>
+	      <a href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services<img border="0" alt="" src="http://www.knopflerfish.org./images/extlink.gif"/></a><br/>
+	    </div>
+	  </div>
+	  <div class="makewave">
+	    <a href="http://www.twitter.com/knopflerfish">
+	      <img src="http://twitter-badges.s3.amazonaws.com/follow_us-b.png"
+		   alt="Follow knopflerfish on Twitter" border="0"/>
+	    </a>
+	  </div>
+	</div>
+
+	<div id="mainblock">
+          <h2><xsl:value-of select="@product"/> <xsl:value-of select="@version"/> Maven Artifacts</h2>
+
+          This page contains a listing of all bundles (artifacts) in
+          the maven2 repository that belongs to <xsl:value-of select="@product"/> 
+          <xsl:value-of select="@version"/>.<p/>
+          
+          You may copy the Maven <code><dependy></code>
+          elements from this file and paste them into the
+          <code><dependencyManagement></code>-element of the
+          <code>settings.xml</code>-file or the top-level pom-file
+          for a collection of projects that uses this Knopflerfish
+          version.<p/>
+
+          <table class="fancy" cellpadding="12" style="width:100%">
+            <colgroup>
+              <col style="width:15%"/>
+              <col style="width:40%"/>
+              <col style="width:20%"/>
+              <col style="width:15%"/>
+              <col style="width:10%"/>
+            </colgroup>
+            <tr class="fancy" >
+              <th class="fancy">Bundle</th>
+              <th class="fancy">Description</th>
+              <th class="fancy">Group id</th>
+              <th class="fancy">Artifact id</th>
+              <th class="fancy">Version</th>
+            </tr>
+
+	    <xsl:apply-templates select="bundles/bundle"/>
+
+          </table>
+        </div>
+	<div id="footer">
+	  <div id="copyright">
+	    Copyright © 2008- at YEAR@ The Knopflerfish Project. All
+	    rights reserved.
+	  </div>
+	</div>
+      </div>
+    </body>
+  </xsl:template>
+
+  <xsl:template match="dependency">
+    <tr>
+      <td class="fancy"> </td>
+      <td class="fancy"> </td>
+      <td class="fancy"><xsl:value-of select="groupId"/></td>
+      <td class="fancy"><xsl:value-of select="artifactId"/></td>
+      <td class="fancy"><xsl:value-of select="version"/></td>
+    </tr>
+  </xsl:template>
+
+  <xsl:template match="bundle">
+    <xsl:variable name="version"><xsl:value-of select="version"/></xsl:variable>
+    <tr>
+      <td class="fancy"><xsl:value-of select="name"/></td>
+      <td class="fancy"><xsl:value-of select="description"/></td>
+      <td class="fancy"><xsl:value-of select="groupId"/></td>
+      <td class="fancy">
+	<a>
+          <xsl:attribute name="href"><xsl:value-of select="substring-before(url,$version)"/></xsl:attribute>
+          <xsl:value-of select="artifactId"/>
+        </a>        
+      </td>
+      <td class="fancy"><a>
+	  <xsl:attribute name="href"><xsl:value-of select="url"/></xsl:attribute>
+	  <xsl:value-of select="version"/>
+        </a>
+      </td>
+    </tr>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/ant/html_template/package_list.html b/ant/html_template/package_list.html
new file mode 100644
index 0000000..81aa550
--- /dev/null
+++ b/ant/html_template/package_list.html
@@ -0,0 +1,49 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="style.css" rel="stylesheet" type="text/css">
+  <style type="text/css"> 
+      BODY {
+      background: #fff;
+      margin-top:    5px;
+      margin-left:  15px;
+      margin-right: 10px;
+      }
+
+      #package_list {
+        margin-left: 8px;
+      }
+
+      #package_list A {
+        color: #000;
+        text-decoration: none;
+      }
+	      
+      #package_list A:hover {
+        color: #805362;	      
+        text-decoration: underline;
+        font-weight:     bold;
+      }
+  </style>
+  <title>Knopflerfish Bundle Packages</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+  <div id="package_list">
+    <table>
+      <tr><th>Package</th><th>Provider(s)</th></tr>
+      ${package.list}
+    </table>
+  </div>
+</body>
+
+</html>
+
diff --git a/ant/html_template/style.css b/ant/html_template/style.css
new file mode 100644
index 0000000..05f36a5
--- /dev/null
+++ b/ant/html_template/style.css
@@ -0,0 +1,205 @@
+BODY  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:11px;
+ color:000000;
+ text-align:left;
+ font-weight:normal;
+ background:#fff;
+}
+
+
+
+
+TD  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ text-align:left;
+ vertical-align:top;
+ font-size:11px;
+}
+
+TD A  {
+ color:000000;
+ text-decoration:none
+ font-size:11px;
+}
+
+.mfheader  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ text-align:left;
+ vertical-align:top;
+ font-size:11px;
+ font-weight:bold;
+ /* background:   #805362; */
+ color: #fff;
+ padding-top:         4px;
+ padding-bottom:      4px;
+ /* text-align: center; */
+    border-style: solid;
+    border-color: #999999;
+    background-color: #dedede;
+    border-width: 1px;
+    color: #444444;
+    padding-left: 10px;
+
+}
+
+TH  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:11px;
+ color:000000;
+ text-align:left;
+ vertical-align:top;
+ font-weight:bold
+}
+
+TD A  {
+ color:000000;
+ text-decoration:none
+ font-size:11px;
+}
+
+PRE {
+ font-family: Courier New, Courier;
+ font-size:11px;
+ color:000000;
+ text-align:left;
+ font-weight:normal;
+}
+
+
+H1  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:19px;
+ font-weight:bold;
+ /* background: #dddddd; */
+}
+
+
+H3  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:13px;
+ font-weight:bold;
+ background:	#805362;
+ color:		#fff;
+ padding:	2px 0px 2px 3px;
+}
+
+H4  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:11px;
+ font-weight:bold;
+ background:	#805362;
+ color:		#fff;
+ padding:	2px 0px 2px 10px;
+    border-style: solid;
+    border-color: #999999;
+    background-color: #dedede;
+    border-width: 1px;
+    color: #444444;
+}
+
+H5  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:9px;
+ font-weight:bold;
+ background:	#805362;
+ color:		#fff;
+ padding:	2px 0px 2px 3px;
+}
+
+H6  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:7px;
+ font-weight:bold
+}
+
+TD.menu {
+ color: #ffffff;
+ font-size:9px;
+ font-weight:bold;
+ text-align:left;
+}
+
+A.top {
+  float: right;
+  text-decoration:  none;
+  font-weight:      bold;
+}
+
+A, A:visited, A:selected, A:active {
+ color:000000;
+ text-decoration:  none;
+ font-weight:      bold;
+}
+
+A:hover {
+ text-decoration:  underline;
+}
+
+li.A:visited, li.A:selected, li.A:active {
+ text-decoration:  none;
+ font-weight:      bold;
+}
+
+li.A:hover {
+ text-decoration:  underline;
+}
+
+.small  {
+ font-size:9px;
+}
+
+.medium  {
+ font-size:13px;
+}
+
+.big  {
+ font-size:17px;
+}
+
+.ghosted  {
+  color: #888888;
+}
+
+.framed  {
+ border-type: solid;
+ border-top: 1px solid;
+ border-left: 1px solid;
+ border-bottom: 1px solid;
+ border-right: 1px solid;
+ background:#eeeeee;
+ border-color:#000000;
+ padding-left: 2;
+ padding-top: 2;
+ padding-bottom: 2;
+ padding-right: 2;
+ text-decoration:none;
+ font-size: 11px;
+}
+
+.boxed  {
+ border-type: solid;
+ border-top: 1px solid;
+ border-left: 1px solid;
+ border-bottom: 1px solid;
+ border-right: 1px solid;
+ background:#E7DBAD;
+ border-color:#000000;
+ padding-left: 2;
+ padding-top: 1;
+ padding-bottom: 2;
+ padding-right: 2;
+ text-decoration:none;
+ float: left;
+}
+
+dt {
+ font-weight:bold;
+  margin-bottom: 5px;
+}
+
+dd {
+  margin-bottom: 5px;
+}
+
+
diff --git a/ant/readme.txt b/ant/readme.txt
new file mode 100644
index 0000000..f02246f
--- /dev/null
+++ b/ant/readme.txt
@@ -0,0 +1,95 @@
+This directory contains ant related code ant build files.
+Ant version 1.7 or higher is required.
+
+ build_example.xml          Example of bundle build.xml
+
+ bundlebuild.xml            ant build file to be imported by
+                            build.xml when building a bundle.
+
+ bundlebuild_include.xml    Left for backwards compatibility allowing
+                            older build-files to function without
+                            change.  ant build file to be included
+                            (using an external entity) in build.xml.
+
+ bundletasks.xml            ant build file included by bundlebuild_include.xml
+                            Defines and compiles the bundle build tasks.
+
+ html_template              HTML templates for generated bundle
+                              docs
+ src                        source code for bundle build task 
+
+
+Note: As of Knopflerfish 2.0 all the properties used to specify the
+bundle manifest have been renamed. The new naming scheme gives three
+major advantages:
+
+1 The properties can now be specified in a bundle manifest template
+  file, named bundle.manifest, that may be created using the
+  Knopflerfish Eclipse plug in while their values are still available
+  for use in the ant build script.
+
+2 You can now add any manifest header you like to the generated bundle
+  manifest (previously there where only support for a fixed predefined
+  set of manifest attributes).
+
+3 Easy to remember mapping from ant property name to bundle manifest
+  attribute name.
+
+
+To get the name of the ant property that corresponds to the manifest
+attribute named "Xy-Zz" simply add the prefix "bmfa." to it.
+
+E.g.,
+
+  Manifest Attribute name  ant property name
+  =======================  =================
+
+  Bundle-Name              bmfa.Bundle-Name
+  Bundle-SymbolicName      bmfa.Bundle-SymbolicName
+  Bundle-Version           bmfa.Bundle-Version
+  Bundle-Classpath         bmfa.Bundle-Classpath
+
+and so on.
+
+The default prefix, "bmfa", is a short hand for Bundle ManiFest Attribute.
+
+
+To add a non-standard attribute to the generated manifest simple
+create a property with a name that starts with "bmfa." followed by the
+manifest attribute name.
+
+E.g., the property definition
+
+<property name="bmfa.Main-Class" value="org.knopflerfish.Main"/>
+
+will add the attribute
+
+Main-Class: org.knopflerfish.Main
+
+to all the bundle manifests generated from the build file it was
+defined in.
+
+Another method to do this is to create a template bundle manifest file
+that contains the main section attribute definition you want. The
+template manifest file shall be named "bundle.manifest" and placed in
+the same directory as the build.xml file that shall use it.
+
+
+The format of the manifest template file is that of a normal manifest
+file with one exception: Line length must not obey the 72 characters
+per line requirement. The character encoding of the template manifest
+file is expected to be UTF-8, but you may specify another encoding in
+the build.xml file.
+
+The relaxed line length requirement makes it possible to format the
+template manifest file in a readable way.
+
+E.g., the Import-Package and Export-Package can be written with one
+package per line as in:
+
+Import-Service: org.knopflerfish.service.log.LogService,
+ org.osgi.service.cm.ManagedService,
+ org.osgi.service.cm.ManagedServiceFactory,
+ org.osgi.service.cm.ConfigurationPlugin
+Export-Package: org.osgi.service.cm;version=1.2.0,
+ org.knopflerfish.shared.cm;version=1.0
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/Bundle.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/Bundle.java
new file mode 100644
index 0000000..9a26f1a
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/Bundle.java
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 2005-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.jar.JarInputStream;
+import java.util.zip.ZipEntry;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.FileScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Jar;
+import org.apache.tools.ant.taskdefs.Manifest;
+import org.apache.tools.ant.taskdefs.ManifestException;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ZipFileSet;
+
+import org.osgi.framework.Version;
+
+/**
+ * <p>
+ * An extension of the <a href="http://ant.apache.org/manual/CoreTasks/jar.html"
+ * target="_top">Jar</a> task that builds an OSGi bundle. It can generate the
+ * Bundle-Activator, Bundle-ClassPath and Import-Package manifest headers based
+ * on the content specified in the task.
+ * </p>
+ *
+ * <h3>Parameters</h3>
+ * <table border="1px">
+ * <tr>
+ * <th align="left">Attribute</th>
+ * <th align="left">Description</th>
+ * <th align="left">Required</th>
+ * </tr>
+ * <tr>
+ * <td valign="top">file</td>
+ * <td valign="top">The bundle file to create.</td>
+ * <td valign="top">Yes</td>
+ * </tr>
+ * <tr>
+ * <td valign="top">activator</td>
+ * <td valign="top">
+ * The bundle activator class name. If set to "none" no Bundle-Activator
+ * manifest header will be generated. If set to "auto" the bundle task will try
+ * to find an activator in the included class files.</td>
+ * <td valign="top">No, default is "auto"</td>
+ * </tr>
+ * <tr>
+ * <td valign="top">packageanalysis</td>
+ * <td valign="top">
+ * Analyzes the class files of the bundle and the contents of the
+ * <tt>exportpackage</tt> and <tt>importpackage</tt> nested elements.
+ * <ul>
+ * <li>none – no analysis is performed.</li>
+ * <li>warn – a warning will be displayed for each referenced package not
+ * found in the bundle or the <tt>importpackage</tt> nested elements.</li>
+ * <li>auto – each referenced package not found in the bundle or the
+ * <tt>importpackage</tt> nested elements will be added to the Import-Package
+ * manifest header. Packages exported by the bundle will be added to the
+ * Import-Package manifest header with a version range following the OSGi
+ * versioning recommendation (if a package is incompatible with previous version
+ * then the major number of the version must be incremented). E.g., if the
+ * bundles exports version 1.0.2 the version range in the import will be
+ * "[1.0.2,2)".</li>
+ * </ul>
+ * </td>
+ * <td valign="top">No, default is "warn"</td>
+ * </tr>
+ * </table>
+ *
+ * <h3>Nested elements</h3>
+ *
+ * <h4>classes</h4>
+ * <p>
+ * The nested <tt>classes</tt> element specifies a <a
+ * href="http://ant.apache.org/manual/CoreTypes/zipfileset.html"
+ * target="_top">ZipFileSet</a>. The <tt>prefix</tt> attribute will be added to
+ * the Bundle-ClassPath manifest header. The classes specified by the file set
+ * will be included in the class analysis.
+ * </p>
+ *
+ * <h4>lib</h4>
+ * <p>
+ * The nested <tt>lib</tt> element specifies a <a
+ * href="http://ant.apache.org/manual/CoreTypes/zipfileset.html"
+ * target="_top">ZipFileSet</a>. The locations of all files in the file set will
+ * be added to the Bundle-ClassPath manifest header. All files of this file set
+ * must be either zip or jar files. The classes available in the zip or jar
+ * files will be included in the class analysis.
+ * </p>
+ *
+ * <h4>exportpackage</h4>
+ * <p>
+ * The nested <tt>exportpackage</tt> element specifies the name and version of a
+ * package to add to the Export-Package manifest header. If package analysis is
+ * not turned off, a warning will be issued if the specified package cannot be
+ * found in the bundle. When package analysis is turned on the version from the
+ * <tt>packageinfo</tt>-file in the directory of the package is read and used as
+ * the version of the exported package. In this case, if a version is specified
+ * in the <tt>exportpackage</tt> element that version is compared with the one
+ * from the <tt>packageinfo</tt>-file and if there is a mismatch a build error
+ * will be issued.
+ * </p>
+ *
+ * <h4>importpackage</h4>
+ * <p>
+ * The nested <tt>importpackage</tt> element specifies the name and version of a
+ * package to add to the Import-Package manifest header.
+ * </p>
+ *
+ * <h4>standardpackage</h4>
+ * <p>
+ * The nested <tt>standardpackage</tt> element specifies the name or prefix of a
+ * package that should be excluded from the package analysis. It can be used to
+ * avoid importing packages that are available in the underlying runtime
+ * environment (i.e., via boot delegation).
+ * </p>
+ *
+ * <h3>Implicit file set</h3>
+ * <p>
+ * The implicit fileset is specified by the <tt>baseDir</tt> attribute of the
+ * bundle task and the nested <tt>include</tt> and <tt>exclude</tt> elements.
+ * </p>
+ * <p>
+ * The implicit fileset of the <tt>bundle</tt> task will be included in the
+ * class analysis and in the Bundle-ClassPath manifest header if needed.
+ * </p>
+ *
+ * <h3>Examples</h3>
+ *
+ * <pre>
+ * <bundle activator="auto"
+ *         packageanalysis="auto"
+ *         file="out/${ant.project.name}.jar">
+ *
+ *   <standardpackage name="javax.imageio"/>
+ *
+ *   <exportpackage name="se.weilenmann.bundle.test" version="1.0"/>
+ *
+ *   <manifest>
+ *     <attribute name="Bundle-Name" value="testbundle"/>
+ *     <attribute name="Bundle-Version" value="1.0"/>
+ *     <attribute name="Bundle-Vendor" value="Kaspar Weilenmann"/>
+ *   </manifest>
+ *
+ *   <classes dir="out/classes">
+ *     <include name="se/weilenmann/bundle/test/**"/>
+ *   </classes>
+ *   <classes dir="out/classes" prefix="util">
+ *     <include name="se/weilenmann/util/**"/>
+ *   </classes>
+ *   <classes src="osgi/jars/log/log_api.jar" prefix="log_api">
+ *     <include name="**/*.class"/>
+ *   </classes>
+ *
+ *   <lib dir="osgi/jars/cm" includes="cm_api.jar" prefix="osgi"/>
+ *   <lib dir="lib/commons" includes="commons-logging.jar" prefix="commons"/>
+ *
+ * </bundle>
+ * </pre>
+ * <p>
+ * Creates a bundle with the following manifest:
+ * <p>
+ *
+ * <pre>
+ * Manifest-Version: 1.0
+ * Ant-Version: Apache Ant 1.6.2
+ * Created-By: 1.4.2_02-b03 (Sun Microsystems Inc.)
+ * Bundle-Name: testbundle
+ * Bundle-Version: 1.0
+ * Bundle-Vendor: Kaspar Weilenmann
+ * Bundle-Activator: se.weilenmann.bundle.test.Activator
+ * Bundle-ClassPath: .,util,log_api,osgi/cm_api.jar,commons/commons-loggi
+ * ng.jar
+ * Import-Package: se.weilenmann.bundle.test;specification-version=1.0,or
+ * g.osgi.framework
+ * Export-Package: se.weilenmann.bundle.test;specification-version=1.0
+ * </pre>
+ *
+ * @author <a href="mailto:kaspar at weilenmann.se">Kaspar Weilenmann</a>
+ */
+public class Bundle
+  extends Jar
+{
+
+  // private fields
+
+  private static final String BUNDLE_CLASS_PATH_KEY = "Bundle-ClassPath";
+  private static final String BUNDLE_ACTIVATOR_KEY = "Bundle-Activator";
+  private static final String IMPORT_PACKAGE_KEY = "Import-Package";
+  private static final String EXPORT_PACKAGE_KEY = "Export-Package";
+
+  private static final String ACTIVATOR_NONE = "none";
+  private static final String ACTIVATOR_AUTO = "auto";
+
+  private static final String PACKAGE_ANALYSIS_NONE = "none";
+  private static final String PACKAGE_ANALYSIS_WARN = "warn";
+  private static final String PACKAGE_ANALYSIS_AUTO = "auto";
+
+  private String activator = ACTIVATOR_AUTO;
+  private String packageAnalysis = PACKAGE_ANALYSIS_WARN;
+  private final Map<String, String> importPackage =
+    new HashMap<String, String>();
+  private final Map<String, String> exportPackage =
+    new HashMap<String, String>();
+  private final List<ZipFileSet> libs = new ArrayList<ZipFileSet>();
+  private final List<ZipFileSet> classes = new ArrayList<ZipFileSet>();
+
+  private File baseDir = null;
+  private final List<FileSet> zipgroups = new ArrayList<FileSet>();
+  private final List<FileSet> srcFilesets = new ArrayList<FileSet>();
+
+  private final Manifest generatedManifest = new Manifest();
+
+  private final Set<String> standardPackagePrefixes = new HashSet<String>();
+  {
+    standardPackagePrefixes.add("java.");
+  }
+
+  private final BundlePackagesInfo bpInfo = new BundlePackagesInfo(this);
+  private final ClassAnalyserASM asmAnalyser = new ClassAnalyserASM(bpInfo,
+                                                                    this);
+
+  private void analyze()
+  {
+    if (activator == ACTIVATOR_AUTO || packageAnalysis != PACKAGE_ANALYSIS_NONE) {
+      addZipGroups();
+      addImplicitFileset();
+
+      for (final FileSet fileset : srcFilesets) {
+        for (@SuppressWarnings("unchecked")
+        final Iterator<Resource> fsIt = fileset.iterator(); fsIt.hasNext();) {
+          final Resource res = fsIt.next();
+          analyze(res);
+        }
+      }
+      // Scan done
+      bpInfo.toJavaNames();
+
+      final Set<String> publicPackages = exportPackage.keySet();
+
+      if (packageAnalysis != PACKAGE_ANALYSIS_NONE) {
+        for (final String packageName : publicPackages) {
+          if (!bpInfo.providesPackage(packageName)) {
+            log("Exported package not provided by bundle: " + packageName,
+                Project.MSG_WARN);
+          }
+          // The Version from the packageinfo-file or null
+          final Version piVersion =
+            bpInfo.getProvidedPackageVersion(packageName);
+          if (null != piVersion) {
+            final String epVersionS = exportPackage.get(packageName);
+            if (null == epVersionS) {
+              // Use the version form the packageinfo-file
+              exportPackage.put(packageName, piVersion.toString());
+            } else {
+              // Check that the versions match, if not trigger a build error
+              try {
+                final Version epVersion = Version.parseVersion(epVersionS);
+                if (0 != epVersion.compareTo(piVersion)) {
+                  final String msg =
+                    "Multiple versions found for export of " + "the package '"
+                        + packageName + "'. The packageinfo file ("
+                        + bpInfo.getProvidedPackageVersionSource(packageName)
+                        + ") states '" + piVersion.toString()
+                        + "' but the <exportpackage> element says '"
+                        + epVersion.toString() + "'.";
+                  log(msg, Project.MSG_ERR);
+                  throw new BuildException(msg);
+                }
+              } catch (final IllegalArgumentException iae) {
+                final String msg =
+                  "Invalid version '" + epVersionS
+                      + "' in <exportpackage name=\"" + packageName
+                      + "\" ...>: " + iae.getMessage();
+                log(msg, Project.MSG_ERR);
+                throw new BuildException(msg, iae);
+              }
+            }
+          }
+        }
+      }
+
+      final SortedSet<String> privatePackages = bpInfo.getProvidedPackages();
+      privatePackages.removeAll(publicPackages);
+
+      final SortedSet<String> referencedPackages =
+        bpInfo.getReferencedPackages();
+      referencedPackages.removeAll(privatePackages);
+      for (final Object element : referencedPackages) {
+        final String packageName = (String) element;
+        if (!isStandardPackage(packageName)
+            && !importPackage.containsKey(packageName)) {
+          if (packageAnalysis == PACKAGE_ANALYSIS_AUTO) {
+            final String version = exportPackage.get(packageName);
+            try {
+              importPackage.put(packageName, toImportRange(version));
+            } catch (final IllegalArgumentException iae) {
+              final String msg =
+                "Invalid version value, '" + version
+                    + "' for exported package \"" + packageName
+                    + "\" can not derive version range for auto-import. "
+                    + iae.getMessage();
+              log(msg, Project.MSG_ERR);
+              throw new BuildException(msg, iae);
+            }
+          } else if (packageAnalysis == PACKAGE_ANALYSIS_WARN) {
+            log("Referenced package not found in bundle or imports: "
+                + packageName, Project.MSG_WARN);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Analyze a resource by checking its suffix and delegate to
+   * {@link #analyzeClass(Resource)}, {@link #analyzeJar(Resource)}, etc.
+   *
+   * @param res
+   *          The resource to be analyzed.
+   */
+  protected void analyze(Resource res)
+      throws BuildException
+  {
+    if (res.getName().endsWith(".class")) {
+      analyzeClass(res);
+    } else if (res.getName().endsWith(".jar")) {
+      analyzeJar(res);
+    } else if (res.getName().endsWith("/packageinfo")) {
+      analyzePackageinfo(res);
+    } else {
+      // Just ignore all other files
+    }
+  }
+
+  protected void analyzeJar(Resource res)
+      throws BuildException
+  {
+    log("Analyze jar file " + res, Project.MSG_VERBOSE);
+
+    try {
+      final JarInputStream jarStream = new JarInputStream(res.getInputStream());
+
+      ZipEntry ze = jarStream.getNextEntry();
+      while (null != ze) {
+        final String fileName = ze.getName();
+        if (fileName.endsWith(".class")) {
+          log("Analyze jar class file " + fileName, Project.MSG_VERBOSE);
+          asmAnalyser.analyseClass(jarStream, fileName);
+        }
+        ze = jarStream.getNextEntry();
+      }
+    } catch (final Exception e) {
+      e.printStackTrace();
+      throw new BuildException("Failed to analyze class-file " + res
+                               + ", exception=" + e, getLocation());
+    }
+  }
+
+  protected void analyzeClass(Resource res)
+      throws BuildException
+  {
+    log("Analyze class file " + res, Project.MSG_VERBOSE);
+
+    try {
+      asmAnalyser.analyseClass(res.getInputStream(), res.toString());
+    } catch (final BuildException be) {
+      throw be;
+    } catch (final Exception e) {
+      e.printStackTrace();
+      throw new BuildException("Failed to analyze class-file " + res
+                               + ", exception=" + e, getLocation());
+    }
+  }
+
+  protected void analyzePackageinfo(Resource res)
+      throws BuildException
+  {
+    log("Analyze packageinfo file " + res, Project.MSG_VERBOSE);
+
+    bpInfo.setPackageVersion(res);
+  }
+
+  private void addZipGroups()
+  {
+    for (int i = 0; i < zipgroups.size(); i++) {
+      final FileSet fileset = zipgroups.get(i);
+      final FileScanner fs = fileset.getDirectoryScanner(getProject());
+      final String[] files = fs.getIncludedFiles();
+      final File basedir = fs.getBasedir();
+      for (final String file : files) {
+        final ZipFileSet zipfileset = new ZipFileSet();
+        zipfileset.setSrc(new File(basedir, file));
+        srcFilesets.add(zipfileset);
+      }
+    }
+  }
+
+  private void addImplicitFileset()
+  {
+    if (baseDir != null) {
+      final FileSet fileset = (FileSet) getImplicitFileSet().clone();
+      fileset.setDir(baseDir);
+      srcFilesets.add(fileset);
+    }
+  }
+
+  private boolean isStandardPackage(String packageName)
+  {
+    for (final String prefix : standardPackagePrefixes) {
+      if (packageName.startsWith(prefix)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private void handleActivator()
+      throws ManifestException
+  {
+    if (activator == ACTIVATOR_NONE) {
+      log("No BundleActivator set", Project.MSG_DEBUG);
+    } else if (activator == ACTIVATOR_AUTO) {
+      switch (bpInfo.countProvidedActivatorClasses()) {
+      case 0: {
+        log("No class implementing BundleActivator found", Project.MSG_INFO);
+        break;
+      }
+      case 1: {
+        activator = bpInfo.getActivatorClass();
+        break;
+      }
+      default: {
+        log("More than one class implementing BundleActivator found: "
+                + bpInfo.providedActivatorClassesAsString(), Project.MSG_WARN);
+        break;
+      }
+      }
+    }
+    if (activator != ACTIVATOR_NONE && activator != ACTIVATOR_AUTO) {
+      log("Bundle-Activator: " + activator, Project.MSG_INFO);
+      generatedManifest
+          .addConfiguredAttribute(createAttribute(BUNDLE_ACTIVATOR_KEY,
+                                                  activator));
+    }
+  }
+
+  private void handleClassPath()
+      throws ManifestException
+  {
+    final StringBuffer value = new StringBuffer();
+
+    boolean rootIncluded = false;
+    if (baseDir != null || classes.size() == 0) {
+      value.append(".,");
+      rootIncluded = true;
+    }
+
+    Iterator<ZipFileSet> i = classes.iterator();
+    while (i.hasNext()) {
+      final ZipFileSet zipFileSet = i.next();
+      final String prefix = zipFileSet.getPrefix(getProject());
+      if (prefix.length() > 0) {
+        value.append(prefix);
+        value.append(',');
+      } else if (!rootIncluded) {
+        value.append(".,");
+        rootIncluded = true;
+      }
+    }
+
+    i = libs.iterator();
+    while (i.hasNext()) {
+      final ZipFileSet fileset = i.next();
+      if (fileset.getSrc(getProject()) == null) {
+        final DirectoryScanner ds = fileset.getDirectoryScanner(getProject());
+        final String[] files = ds.getIncludedFiles();
+        if (files.length != 0) {
+          zipgroups.add(fileset);
+          final String prefix = fixPrefix(fileset.getPrefix(getProject()));
+          for (final String file : files) {
+            value.append(prefix.replace('\\', '/'));
+            value.append(file.replace('\\', '/'));
+            value.append(',');
+          }
+        }
+      }
+    }
+
+    if (value.length() > 2) {
+      generatedManifest
+          .addConfiguredAttribute(createAttribute(BUNDLE_CLASS_PATH_KEY, value
+              .substring(0, value.length() - 1)));
+    }
+  }
+
+  private static String fixPrefix(String prefix)
+  {
+    if (prefix.length() > 0) {
+      final char c = prefix.charAt(prefix.length() - 1);
+      if (c != '/' && c != '\\') {
+        prefix = prefix + "/";
+      }
+    }
+    return prefix;
+  }
+
+  private void addPackageHeader(String headerName,
+                                Map<String, String> packageMap)
+      throws ManifestException
+  {
+    final Iterator<Entry<String,String>> i = packageMap.entrySet().iterator();
+    if (i.hasNext()) {
+      final StringBuffer valueBuffer = new StringBuffer();
+      while (i.hasNext()) {
+        final Entry<String, String> entry = i.next();
+        final String name = entry.getKey();
+        String version = entry.getValue();
+        valueBuffer.append(name);
+        if (version != null) {
+          version = version.trim();
+          if (0 < version.length()) {
+            valueBuffer.append(";version=");
+            final boolean quotingNeeded =
+              -1 != version.indexOf(',') && '"' != version.charAt(0);
+            if (quotingNeeded) {
+              valueBuffer.append('"');
+            }
+            valueBuffer.append(version);
+            if (quotingNeeded) {
+              valueBuffer.append('"');
+            }
+          }
+        }
+        valueBuffer.append(',');
+      }
+      valueBuffer.setLength(valueBuffer.length() - 1);
+      final String value = valueBuffer.toString();
+      generatedManifest.addConfiguredAttribute(createAttribute(headerName,
+                                                               value));
+      log(headerName + ": " + value, Project.MSG_INFO);
+    }
+  }
+
+  private static Manifest.Attribute createAttribute(String name, String value)
+  {
+    final Manifest.Attribute attribute = new Manifest.Attribute();
+    attribute.setName(name);
+    attribute.setValue(value);
+    return attribute;
+  }
+
+  /**
+   * Given a precise version create a version range suitable for an import
+   * package specification. Currently an input version of M.N.U.Q will result in
+   * an output range "[M.N.U.Q, M+1)" following the version usage recommended by
+   * OSGi (a package that is not backwards compatible must increment the major
+   * number in its version number).
+   *
+   * @param version
+   *          an OSGi compatibel version on string form.
+   * @return a quoted version range starting with the given version (inclusive)
+   *         ending with the next major version (exclusive). If the specified
+   *         version is <code>null</code> or an empty string a <code>null</code>
+   *         is returned.
+   */
+  private static String toImportRange(final String version)
+      throws IllegalArgumentException
+  {
+    if (null == version || 0 == version.length()) {
+      return null;
+    }
+
+    final Version vStart = Version.parseVersion(version);
+    final Version vEnd = new Version(vStart.getMajor() + 1, 0, 0, null);
+    return "\"[" + vStart.toString() + "," + vEnd.toString() + ")\"";
+  }
+
+  // public methods
+
+  public void setActivator(String activator)
+  {
+    if (ACTIVATOR_NONE.equalsIgnoreCase(activator)) {
+      this.activator = ACTIVATOR_NONE;
+    } else if (ACTIVATOR_AUTO.equalsIgnoreCase(activator)) {
+      this.activator = ACTIVATOR_AUTO;
+    } else {
+      this.activator = activator;
+    }
+  }
+
+  public void setPackageAnalysis(String packageAnalysis)
+  {
+    packageAnalysis = packageAnalysis.trim().toLowerCase();
+    if (PACKAGE_ANALYSIS_NONE.equals(packageAnalysis)) {
+      this.packageAnalysis = PACKAGE_ANALYSIS_NONE;
+    } else if (PACKAGE_ANALYSIS_WARN.equals(packageAnalysis)) {
+      this.packageAnalysis = PACKAGE_ANALYSIS_WARN;
+    } else if (PACKAGE_ANALYSIS_AUTO.equals(packageAnalysis)) {
+      this.packageAnalysis = PACKAGE_ANALYSIS_AUTO;
+    } else {
+      throw new BuildException("Illegal value: " + packageAnalysis);
+    }
+  }
+
+  public void addConfiguredStandardPackage(OSGiPackage osgiPackage)
+  {
+    final String name = osgiPackage.getName();
+    final String prefix = osgiPackage.getPrefix();
+    if (name != null && prefix == null) {
+      bpInfo.addProvidedPackage(name);
+    } else if (prefix != null && name == null) {
+      standardPackagePrefixes.add(prefix);
+    } else {
+      throw new BuildException(
+                               "StandardPackage must have exactly one of the name and prefix attributes defined");
+    }
+  }
+
+  public void addConfiguredImportPackage(OSGiPackage osgiPackage)
+  {
+    final String name = osgiPackage.getName();
+    if (name == null) {
+      throw new BuildException("ImportPackage must have a name");
+    } else if (osgiPackage.getPrefix() != null) {
+      throw new BuildException("ImportPackage must not have a prefix attribute");
+    } else {
+      importPackage.put(name, osgiPackage.getVersion());
+    }
+  }
+
+  public void addConfiguredExportPackage(OSGiPackage osgiPackage)
+  {
+    final String name = osgiPackage.getName();
+    if (name == null) {
+      throw new BuildException("ExportPackage must have a name");
+    } else if (osgiPackage.getPrefix() != null) {
+      throw new BuildException("ExportPackage must not have a prefix attribute");
+    } else {
+      exportPackage.put(name, osgiPackage.getVersion());
+    }
+  }
+
+  public void addConfiguredLib(ZipFileSet fileset)
+  {
+    // TODO: handle refid
+    if (fileset.getSrc(getProject()) == null) {
+      addFileset(fileset);
+      libs.add(fileset);
+    } else {
+      addClasses(fileset);
+    }
+  }
+
+  public void addClasses(ZipFileSet fileset)
+  {
+    super.addZipfileset(fileset);
+    srcFilesets.add(fileset);
+    classes.add(fileset);
+  }
+
+  // extends Jar
+
+  @Override
+  public void execute()
+  {
+    try {
+      handleClassPath();
+
+      analyze();
+
+      handleActivator();
+
+      addPackageHeader(IMPORT_PACKAGE_KEY, importPackage);
+      addPackageHeader(EXPORT_PACKAGE_KEY, exportPackage);
+
+      // TODO: better merge may be needed, currently overwrites
+      // pre-existing headers
+      addConfiguredManifest(generatedManifest);
+    } catch (final ManifestException me) {
+      throw new BuildException("Error merging manifest headers", me);
+    }
+    super.execute();
+  }
+
+  @Override
+  public void setBasedir(File baseDir)
+  {
+    super.setBasedir(baseDir);
+    this.baseDir = baseDir;
+  }
+
+  @Override
+  public void addZipGroupFileset(FileSet fileset)
+  {
+    super.addZipGroupFileset(fileset);
+    zipgroups.add(fileset);
+  }
+
+  @Override
+  public void addZipfileset(ZipFileSet fileset)
+  {
+    super.addZipfileset(fileset);
+  }
+
+} // Bundle
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleArchives.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleArchives.java
new file mode 100644
index 0000000..589b4c2
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleArchives.java
@@ -0,0 +1,1027 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.knopflerfish.ant.taskdefs.bundle.Util.HeaderEntry;
+
+/**
+ * A class that analyzes all bundle jar files given by a list of resource
+ * collections (file sets).
+ *
+ */
+public class BundleArchives {
+
+  // This constant is missing from org.osgi.framework.Constants
+  public static final String BUNDLE_BLUEPRINT = "Bundle-Blueprint";
+  public static final String BUNDLE_LICENSE = "Bundle-License";
+  public static final String SERVICE_COMPONENT = "Service-Component";
+
+  /** Path prefix for source files included into the bundle archive. */
+  public static final String SRC_PREFIX = "OSGI-OPT/src";
+
+  /**
+   * The ant task that is using this helper class. Used for logging etc.
+   */
+  private final Task task;
+
+  /**
+   * Map from bundle name (the bundles file without version and ".jar" suffixes)
+   * to a sorted set of a bundle archive object with details about the bundle .
+   * The set will contain more than one element when more than one version of
+   * the bundle has been found.
+   */
+  final Map<String, SortedSet<BundleArchive>> bnToBundleArchives =
+    new TreeMap<String, SortedSet<BundleArchive>>();
+
+  /**
+   * Map from bundle symbolic name to a sorted set of a bundle archive object
+   * with details about the bundle. The set will contain more than one element
+   * when more than one version of the bundle has been found.
+   */
+  final Map<String, SortedSet<BundleArchive>> bsnToBundleArchives =
+    new TreeMap<String, SortedSet<BundleArchive>>();
+
+  /**
+   * Set with all bundle archives specified by the given resource collections.
+   */
+  final SortedSet<BundleArchive> allBundleArchives = new TreeSet<BundleArchive>();
+
+  /**
+   * Set with all packages exported from some bundle in this collection of
+   * bundle archives. The key in the map is the package name, the value is a map
+   * from package version to a set of bundle archives that exports that version
+   * of the package.
+   *
+   * <p>
+   * A call to {@link #doProviders()} must be made to compute this mapping.
+   * </p>
+   */
+  final SortedMap<String, SortedMap<Version, SortedSet<BundleArchive>>> allExports =
+    new TreeMap<String, SortedMap<Version, SortedSet<BundleArchive>>>();
+
+  /**
+   * Traverse the given list of resource collections and create
+   * <code>BundleArchive</code>-objects for all bundle jars found.
+   *
+   * @param task
+   *          The task that uses this class, used for logging and project
+   *          access.
+   * @param resourceCollections
+   *          The collection of resource collections selecting the bundle
+   *          archives to load.
+   */
+  public BundleArchives(final Task task,
+                        final List<ResourceCollection> resourceCollections)
+  {
+    this(task, resourceCollections, false);
+  }
+
+  /**
+   * Traverse the given list of resource collections and create
+   * <code>BundleArchive</code>-objects for all bundle jars found.
+   *
+   * @param task
+   *          The task that uses this class, used for logging and project
+   *          access.
+   * @param resourceCollections
+   *          The collection of resource collections selecting the bundle
+   *          archives to load.
+   * @param parseExportImport
+   *          If <code>true</code> then the created bundle archive objects will
+   *          parse the import / export package / service headers.
+   */
+  public BundleArchives(final Task task,
+                        final List<ResourceCollection> resourceCollections,
+                        final boolean parseExportImport)
+  {
+    this.task = task;
+
+    if (resourceCollections.size() == 0) {
+      task.log("BundleArchives called without any bundle archives to analyse",
+               Project.MSG_ERR);
+      throw new BuildException("No resource collections specified");
+    }
+
+    try {
+      for (final ResourceCollection rc : resourceCollections) {
+        // Ignore file sets with a non existing root directory.
+        if (rc instanceof FileSet) {
+          final FileSet fs = (FileSet) rc;
+          final File fsRootDir = fs.getDir(task.getProject());
+          if (!fsRootDir.exists()) {
+            task.log("Skipping nested file set rooted at '" + fsRootDir
+                         + "' since that directory does not exist.",
+                     Project.MSG_WARN);
+            continue;
+          }
+          try {
+            if (fs.size() < 1) {
+              task.log("Skipping nested file set rooted at '" + fsRootDir
+                       + "' since that file set is empty.", Project.MSG_VERBOSE);
+              continue;
+
+            }
+          } catch (final Exception e) {
+            task.log("Skipping nested file set rooted at '" + fsRootDir
+                         + "' since size computation throws exception.", e,
+                     Project.MSG_VERBOSE);
+            continue;
+          }
+        }
+
+        for (@SuppressWarnings("unchecked")
+        final Iterator<Resource> rcIt = rc.iterator(); rcIt.hasNext();) {
+          final Resource res = rcIt.next();
+          if (res.getName().endsWith(".jar")) {
+            task.log("Adding bundle: " + res, Project.MSG_VERBOSE);
+            try {
+              final BundleArchive ba =
+                new BundleArchive(task, (FileResource) res, parseExportImport);
+              allBundleArchives.add(ba);
+              addToMap(bnToBundleArchives, ba.bundleName, ba);
+              addToMap(bsnToBundleArchives, ba.bsn, ba);
+            } catch (final Exception e) {
+              final String msg =
+                "Failed to analyze bundle archive: " + res + "; reason: " + e;
+              task.log(msg);
+              throw new BuildException(msg, e);
+            }
+          }
+        }
+      }// Scan done
+
+    } catch (final BuildException be) {
+      throw be;
+    } catch (final Exception e) {
+      final String msg = "Failed to analyze bundle archives: " + e;
+      task.log(msg);
+      throw new BuildException(msg, e);
+    }
+  }
+
+  SortedSet<String> getKnownNames() {
+    final TreeSet<String> knownNames = new TreeSet<String>(bnToBundleArchives.keySet());
+    knownNames.addAll(bsnToBundleArchives.keySet());
+    return knownNames;
+  }
+
+  /**
+   * Computes the global <code>allExports</code> mapping and the
+   * <code>pkgProvidersMap</code> for all bundle archives.
+   */
+  void doProviders() {
+    // First build the allExports structure.
+    allExports.clear();
+    for (final BundleArchive ba : allBundleArchives) {
+      // Clear bundle archive maps holding results from this analysis
+      ba.pkgProvidersMap.clear();
+      ba.pkgUnprovidedMap.clear();
+      ba.pkgProvidedMap.clear();
+
+      for (final Entry<String,Version> eE : ba.pkgExportMap.entrySet()) {
+        final String pkgName = eE.getKey();
+        final Version pkgVersion = eE.getValue();
+
+        SortedMap<Version, SortedSet<BundleArchive>> versions = allExports.get(pkgName);
+        if (null == versions) {
+          versions = new TreeMap<Version, SortedSet<BundleArchive>>();
+          allExports.put(pkgName, versions);
+        }
+
+        SortedSet<BundleArchive> exporters = versions.get(pkgVersion);
+        if (null == exporters) {
+          exporters = new TreeSet<BundleArchive>();
+          versions.put(pkgVersion, exporters);
+        }
+        exporters.add(ba);
+      }
+    }
+
+    // For each bundle build the pkgProvidersMap
+    for (final BundleArchive ba : allBundleArchives) {
+      for (final Entry<String,VersionRange> iE : ba.pkgImportMap.entrySet()) {
+        final String pkgName = iE.getKey();
+        final VersionRange range = iE.getValue();
+
+        final SortedMap<Version, SortedSet<BundleArchive>> versions = allExports.get(pkgName);
+        if (null != versions) {
+          for (final Entry<Version,SortedSet<BundleArchive>> vE : versions.entrySet()) {
+            final Version pkgVersion = vE.getKey();
+
+            if (range.includes(pkgVersion)) {
+              final SortedSet<BundleArchive> providers = vE.getValue();
+
+              for (final BundleArchive provider : providers) {
+                // The package pkgName may be imported by ba from provider,
+                // update ba's providers map
+                SortedSet<String> pkgNames = ba.pkgProvidersMap
+                  .get(provider);
+                if (null == pkgNames) {
+                  pkgNames = new TreeSet<String>();
+                  ba.pkgProvidersMap.put(provider, pkgNames);
+                }
+                pkgNames.add(pkgName);
+
+                // Non self exported package, add to pkgCtProvidersMap
+                if (!ba.pkgExportMap.containsKey(pkgName)) {
+                  SortedSet<String> pkgNamesCt = ba.pkgCtProvidersMap
+                    .get(provider);
+                  if (null == pkgNamesCt) {
+                    pkgNamesCt = new TreeSet<String>();
+                    ba.pkgCtProvidersMap.put(provider, pkgNamesCt);
+                  }
+                  pkgNamesCt.add(pkgName);
+                }
+
+                // The package pkgName is provided (exported) by
+                // provider to ba, update provider.pkgProvidedMap to
+                // reflect this.
+                SortedSet<String> pkgNamesProvidedToBa = provider.pkgProvidedMap
+                  .get(ba);
+                if (null == pkgNamesProvidedToBa) {
+                  pkgNamesProvidedToBa = new TreeSet<String>();
+                  provider.pkgProvidedMap.put(ba, pkgNamesProvidedToBa);
+                }
+                pkgNamesProvidedToBa.add(pkgName);
+              }
+            }
+          }
+        } else {
+          ba.pkgUnprovidedMap.put(pkgName, range);
+          task.log(ba + " importing no provider for package " + pkgName + " "
+                   + range, Project.MSG_DEBUG);
+        }
+      }
+    }
+  }
+
+  /**
+   * Format the OSGi version as Maven 2 does in versioned file names.
+   */
+  static private String toMavenVersion(final Version version) {
+    final StringBuffer sb = new StringBuffer(40);
+
+    sb.append(String.valueOf(version.getMajor())).append(".");
+    sb.append(String.valueOf(version.getMinor())).append(".");
+    sb.append(String.valueOf(version.getMicro()));
+
+    final String qualifier = version.getQualifier();
+    if (0 < qualifier.length()) {
+      sb.append("-").append(qualifier);
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Add a bundle archive to a map using the given key. The values of the map
+   * are sorted sets of bundle archives.
+   */
+  private void addToMap(final Map<String, SortedSet<BundleArchive>> map,
+                        final String key,
+                        final BundleArchive ba)
+  {
+    if (null == key) {
+      return;
+    }
+
+    SortedSet<BundleArchive> bas = map.get(key);
+    if (null == bas) {
+      bas = new TreeSet<BundleArchive>();
+      map.put(key, bas);
+      task.log("Found bundle '" + key + "'.", Project.MSG_DEBUG);
+    }
+    if (bas.add(ba)) {
+      task.log("Found bundle '" + key + "' '" + ba.version + "'.",
+               Project.MSG_DEBUG);
+    }
+  }
+
+  static String encodeBundleName(final String bundleName) {
+    String name = bundleName;
+    if (null != name) {
+      name = name.replace(':', '.');
+      name = name.replace(' ', '_');
+    }
+    return name;
+  }
+
+  /**
+   * A BundleArchive-object describes one bundle with data derived from its file
+   * name and manifest.
+   */
+  static class BundleArchive implements Comparable<BundleArchive> {
+    /** Task that uses this class, for logging. */
+    final Task task;
+
+    /** File object referencing the bundle jar. */
+    final File file;
+
+    /** The relative path from the root of the file set holding the bundle. */
+    final String relPath;
+
+    /** The name of the bundle file without version and ".jar" suffix. */
+    final String bundleName;
+
+    /** The name of the project that the bundle belongs to. */
+    final String projectName;
+
+    // The manifest attributes and some parsed values
+    final Attributes mainAttributes;
+    final String manifestVersion;
+    final String bsn;
+    final Version version;
+    final String name;
+
+    /** Mapping from exported package name to its version. */
+    final Map<String, Version> pkgExportMap;
+
+    /** Mapping from imported package name to its version range constraint. */
+    final Map<String, VersionRange> pkgImportMap;
+
+    /** Set with names of imported packages that are optional. */
+    final Set<String> pkgImportOptional = new TreeSet<String>();
+
+    /**
+     * Collection of bundles that provides packages that this bundle are
+     * importing. The mapping key is a bundle archive and the value is the set
+     * of package names that the bundle archive may provide to this bundle.
+     *
+     * <p>
+     * Initially empty, to fill in this map call {@link #doProviders()}.
+     * </p>
+     */
+    final Map<BundleArchive, SortedSet<String>> pkgProvidersMap =
+      new TreeMap<BundleArchive, SortedSet<String>>();
+
+    /**
+     * Collection of bundles that provides packages that this bundle needs
+     * access to at compile time. I.e., packages that the bundle is importing
+     * but not exporting. The mapping key is a bundle archive and the value is
+     * the set of package names that the bundle archive may provide to this
+     * bundle.
+     *
+     * <p>
+     * Initially empty, to fill in this map call {@link #doProviders()}.
+     * </p>
+     */
+    final Map<BundleArchive, SortedSet<String>> pkgCtProvidersMap =
+      new TreeMap<BundleArchive, SortedSet<String>>();
+
+    /**
+     * Collection of bundles that this bundle provides packages to, i.e.,
+     * bundles importing the exports of this bundle. The mapping key is a bundle
+     * archive and the value is the set of package names that the bundle archive
+     * may import from this bundle.
+     *
+     * <p>
+     * Initially empty, to fill in this map call {@link #doProviders()}.
+     * </p>
+     */
+    final Map<BundleArchive, SortedSet<String>> pkgProvidedMap =
+      new TreeMap<BundleArchive, SortedSet<String>>();
+
+    /**
+     * Sub set of the entries in the imported packages map for which there are
+     * no matching exporter. Mapping from package name to its version range
+     * constraint.
+     *
+     * <p>
+     * Initially empty, to fill in this map call {@link #doProviders()}.
+     * </p>
+     */
+    final Map<String, VersionRange> pkgUnprovidedMap = new TreeMap<String, VersionRange>();
+
+    /** Mapping from exported service name to its version. */
+    final Map<String, Version> serviceExportMap;
+
+    /** Mapping from imported service name to its version range constraint. */
+    final Map<String, VersionRange> serviceImportMap;
+
+    /** Number of source files inside the bundle archive. */
+    final int srcCount;
+
+    /**
+     * Create a bundle archive object for the given bundle jar file.
+     *
+     * @param task
+     *          The task that uses this class, used for logging and project
+     *          access.
+     * @param resource
+     *          The bundle jar file to create a bundle archive object for.
+     * @param parseExportImport
+     *          If <code>true</code> then populate the pkgExportMap,
+     *          pkgImportMap, pkgImportOptional set with data parsed from the
+     *          import / export package manifest attributes.
+     */
+    @SuppressWarnings("deprecation")
+	public BundleArchive(final Task task, final FileResource resource,
+                         final boolean parseExportImport) throws IOException {
+      this.task = task;
+      this.file = resource.getFile();
+      this.relPath = resource.getName();
+
+      // Get data from the bundles manifest and contents
+      final JarFile bundle = new JarFile(file);
+      try {
+        final Manifest manifest = bundle.getManifest();
+        this.mainAttributes = manifest.getMainAttributes();
+        this.manifestVersion = deriveBundleManifestVersion();
+        this.bsn = deriveBundleSymbolicName();
+        this.version = deriveBundleVersion();
+        this.name = mainAttributes.getValue(Constants.BUNDLE_NAME);
+
+        int count = 0;
+        for (final Enumeration<JarEntry> e = bundle.entries(); e.hasMoreElements();) {
+          final ZipEntry entry = e.nextElement();
+
+          if (entry.getName().startsWith(SRC_PREFIX)) {
+            count++;
+          }
+        }
+        srcCount = count;
+
+      } finally {
+        if (null != bundle) {
+          try {
+            bundle.close();
+          } catch (final IOException _ioe) {
+          }
+        }
+      }
+
+      // Derive bundle name, bn, from the file name and the manifest version.
+      // The file name format is "<bundleName>-<version>.jar"
+      String bn = null;
+      final String fileName = file.getName();
+      final String versionSuffix = "-" +this.version.toString() +".jar";
+      if (fileName.endsWith(versionSuffix)) {
+        // Simple case when Version.toString() returns the version
+        // string in the file name.
+        bn = fileName.substring(0, fileName.length() -versionSuffix.length());
+      } else {
+        // Try to find a valid version in the file name that matches
+        // the one in the manifest
+        int ix = fileName.lastIndexOf('-');
+        while (0<ix && null==bn) {
+          final String versionS
+            = fileName.substring(ix + 1, fileName.length() - 4);
+          try {
+            // Compare version from the file name with the one from the manifest
+            final Version nameVersion = new Version(versionS);
+            if (0 == nameVersion.compareTo(version)) {
+              bn = fileName.substring(0, ix);
+            } else {
+              task.log("Found version '" + nameVersion
+                       + "' in the file name '" + fileName
+                       + "', but the version in the bundle's manifest is '"
+                       + version + "'.", Project.MSG_DEBUG);
+            }
+          } catch (final NumberFormatException nfe) {
+            task.log("Invalid version in bundle file name '" + versionS + "': "
+                     + nfe, Project.MSG_VERBOSE);
+          } catch (final IllegalArgumentException iae) {
+            task.log("Invalid version in bundle file name '" + versionS + "': "
+                     + iae, Project.MSG_VERBOSE);
+          }
+          ix = fileName.lastIndexOf('-', ix-1);
+        }
+        if (null==bn) {
+          // No valid version in file name, just remove the ".jar"-suffix
+          bn = fileName.substring(0, fileName.length() - 4);
+        }
+      }
+
+      if (0 < version.getQualifier().length()) {
+        // Maven uses '-' and not '.' as separator for the qualifier
+        // in its bundle names. Check if bundleName needs to be
+        // updated.
+        final String mavenSuffix = "-" + toMavenVersion(version) + ".jar";
+        if (fileName.endsWith(mavenSuffix)) {
+          bn = fileName.substring(0, fileName.length() - mavenSuffix.length());
+        }
+      }
+
+      // The bundle name is now ready!
+      this.bundleName = bn;
+
+      // The project name is the name of the parent directory of the
+      // bundle in its relative path, if empty use the bundle name
+      // without "_all" / "_impl" suffix.
+      final File parentDir = new File(relPath).getParentFile();
+      final String parentDirName = null == parentDir ? null : parentDir
+        .getName();
+      if (null != parentDirName && 0 < parentDirName.length()) {
+        this.projectName = parentDirName;
+      } else if (bn.endsWith("_api") || bn.endsWith("_all")) {
+        this.projectName = bn.substring(0, bn.length() - 4);
+      } else {
+        this.projectName = bn;
+      }
+
+      if ("2".equals(manifestVersion) && null == bsn) {
+        final String msg = "Found bundle with Bundle-MainfestVersion >= 2 "
+          + "without Bundle-SymbolicName: " + fileName;
+        throw new BuildException(msg);
+      }
+
+      if (parseExportImport) {
+        pkgExportMap = parseNames(Constants.EXPORT_PACKAGE, false, null, Version.class);
+        pkgImportMap = parseNames(Constants.IMPORT_PACKAGE, true, pkgImportOptional, VersionRange.class);
+        serviceExportMap = parseNames(Constants.EXPORT_SERVICE, false, null, Version.class);
+        serviceImportMap = parseNames(Constants.IMPORT_SERVICE, true, null, VersionRange.class);
+      } else {
+        pkgExportMap = null;
+        pkgImportMap = null;
+        serviceExportMap = null;
+        serviceImportMap = null;
+      }
+    }
+
+    /**
+     * Sort on bundle symbolic name then on the bundle version. Compares bundle
+     * symbolic name and then bundle version.
+     *
+     * @param o
+     *          the object to compare this bundle archive to.
+     * @return a negative integer, zero, or a positive integer as this object is
+     *         less than, equal to, or greater than the specified object.
+     */
+    @Override
+    public int compareTo(BundleArchive other)
+    {
+      // The bsn may be null for pre OSGi R4 bundles!
+      final String objName = this.bsn != null
+        ? this.bsn : (this.name != null ? this.name : this.bundleName);
+
+      final String otherName = other.bsn != null
+        ? other.bsn : (other.name != null ? other.name : other.bundleName);
+
+      final int res = objName.compareTo(otherName);
+      return res != 0 ? res : this.version.compareTo(other.version);
+    }
+
+    @Override
+    public String toString() {
+      return file.toString();
+    }
+
+    /**
+     * Get the bundle manifest version from the manifest.
+     */
+    private String deriveBundleManifestVersion() throws NumberFormatException {
+      String manifestVersion = mainAttributes
+        .getValue(Constants.BUNDLE_MANIFESTVERSION);
+      if (null == manifestVersion) {
+        // Pre OSGi R4 bundle with non-standard version format; use
+        // version "1".
+        manifestVersion = "1";
+      }
+      return manifestVersion.trim();
+    }
+
+    /**
+     * Get the bundle symbolic name from the manifest. If the
+     * <tt>Bundle-SymbolicName</tt> attribute is missing use the
+     * <tt>Bundle-Name</tt> but replace all ':' with '.' and all ' ' with
+     * '_' in the returned value.
+     *
+     */
+    private String deriveBundleSymbolicName() {
+      String name = mainAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME);
+      if (null == name) {
+        if ("1".equals(manifestVersion)) {
+          name = mainAttributes.getValue(Constants.BUNDLE_NAME);
+        }
+      } else {
+        // Remove any directive from the name
+        final int semiPos = name.indexOf(";");
+        if (-1 < semiPos) {
+          name = name.substring(0, semiPos);
+        }
+        name = name.trim();
+      }
+
+      return BundleArchives.encodeBundleName(name);
+    }
+
+    /**
+     * Get the bundle version from the manifest.
+     */
+    private Version deriveBundleVersion() throws NumberFormatException {
+      final String versionS = mainAttributes.getValue(Constants.BUNDLE_VERSION);
+      if (null == versionS) {
+        return Version.emptyVersion;
+      }
+
+      try {
+        return new Version(versionS);
+      } catch (final NumberFormatException nfe) {
+        if ("1".equals(manifestVersion)) {
+          // Pre OSGi R4 bundle with non-standard version format; use
+          // the default version.
+          return Version.emptyVersion;
+        }
+        final String msg = "Invalid bundle version '" + versionS
+          + "' found in " + file + ": " + nfe;
+        task.log(msg, Project.MSG_ERR);
+        throw new BuildException(msg, nfe);
+      } catch (final IllegalArgumentException iae) {
+        if ("1".equals(manifestVersion)) {
+          // Pre OSGi R4 bundle with non-standard version format; use
+          // the default version.
+          return Version.emptyVersion;
+        }
+        final String msg = "Invalid bundle version '" + versionS
+          + "' found in " + file + ": " + iae;
+        task.log(msg, Project.MSG_ERR);
+        throw new BuildException(msg, iae);
+      }
+    }
+
+    /**
+     * Parse import/export package/service headers.
+     *
+     * @param s
+     *          The name the header to parse.
+     * @param range
+     *          if versions shall be parsed as ranges or not.
+     * @param optionals
+     *          Optional Set to add packages that are marked with the directive
+     *          resolution:=optional to.
+     *
+     * @param valueType
+     *          The desired type of the value in the returned Mapping. Supported
+     *          types are {@link Version} and {@link VersionRange}.
+     *
+     * @return Mapping from package/service name to version/version range.
+     */
+    @SuppressWarnings("deprecation")
+	private <V> Map<String, V> parseNames(String s,
+                                          boolean range,
+                                          Set<String> optionals,
+                                          Class<V> valueType)
+    {
+      final TreeMap<String, V> res = new TreeMap<String, V>();
+
+      final String v = mainAttributes.getValue(s);
+      final List<HeaderEntry> entries =
+        Util.parseManifestHeader(s, v, false, true, false);
+
+      for (final HeaderEntry entry : entries) {
+        String versionS =
+          (String) entry.attributes.get(Constants.VERSION_ATTRIBUTE);
+        // Fall back to "specification-version" for pre OSGi R4 bundles.
+        if (null == versionS) {
+          versionS =
+            (String) entry.attributes
+                .get(Constants.PACKAGE_SPECIFICATION_VERSION);
+        }
+        if (null == versionS) {
+          versionS = "0"; // The default version
+        }
+        if (valueType.equals(Version.class)) {
+          @SuppressWarnings("unchecked")
+          final
+          V version = (V) new Version(versionS);
+          for (final String key : entry.getKeys()) {
+            res.put(key, version);
+          }
+        } else if (valueType.equals(VersionRange.class)) {
+          @SuppressWarnings("unchecked")
+          final
+          V versionRange =  (V) new VersionRange(versionS);
+          for (final String key : entry.getKeys()) {
+            res.put(key, versionRange);
+          }
+        }
+
+        if (entry.directives.containsKey(Constants.RESOLUTION_DIRECTIVE)
+            && Constants.RESOLUTION_OPTIONAL.equals(entry.directives
+                .get(Constants.RESOLUTION_DIRECTIVE))) {
+          optionals.addAll(entry.getKeys());
+        }
+      }
+      return res;
+    }
+
+    public String getBundleDescription() {
+      final String res = mainAttributes.getValue(Constants.BUNDLE_DESCRIPTION);
+      return null == res ? res : res.trim();
+    }
+
+    public List<HeaderEntry> getBundleLicense() {
+      String value = mainAttributes.getValue(BundleArchives.BUNDLE_LICENSE);
+      if (null != value) {
+        value = value.trim();
+      }
+      try {
+        return Util.parseManifestHeader(BundleArchives.BUNDLE_LICENSE,
+                                        value, true,
+                                        true, false);
+      } catch (final Exception e) {
+        final String msg = "Failed to parse " + BundleArchives.BUNDLE_LICENSE
+          + " manifest header '" + value + "' in " + file + ": " + e;
+        throw new BuildException(msg, e);
+      }
+    }
+
+    /**
+     * @return <code>true</code> if this bundle includes Declarative Services
+     *         Components, <code>false</code> otherwise.
+     */
+    public boolean isSCBundle() {
+      return null != mainAttributes.getValue(BundleArchives.SERVICE_COMPONENT);
+    }
+
+    /**
+     * @return <code>true</code> if this bundle includes blueprint components,
+     *         <code>false</code> otherwise.
+     */
+    public boolean isBlueprintBundle() {
+      // TODO: If header not present the default pattern,
+      // "OSGI-INF/blueprint/*.xml" should be checked.
+
+      return null != mainAttributes.getValue(BundleArchives.BUNDLE_BLUEPRINT);
+    }
+
+    /**
+     * @return <code>true</code> if this bundle includes a bundle activator,
+     *         <code>false</code> otherwise.
+     */
+    public boolean isActivatorBundle() {
+      return null != mainAttributes.getValue(Constants.BUNDLE_ACTIVATOR);
+    }
+
+    /**
+     * @return <code>true</code> if this bundle is an API only bundle. I.e. if
+     *         it exports packages but does not have a bundle activator, service
+     *         component or blueprint component. activator, <code>false</code>
+     *         otherwise.
+     */
+    public boolean isAPIBundle() {
+      return 0 < pkgExportMap.size() && !isActivatorBundle() && !isSCBundle()
+        && !isBlueprintBundle();
+    }
+
+    /**
+     * Extract source from inside the bundle to the given destination directory.
+     * If bundle does not contain any source files try to copy source files from
+     * the bundles src-directory (derived from the <code>Built-From</code>
+     * manifest attribute.
+     *
+     * @param destDir
+     *          The directory to extract the source files to.
+     * @return List with one entry for each extracted file. The value is the
+     *         path relative to <code>destDir</code>.
+     * @throws IOException
+     */
+    public List<String> extractSources(File destDir) throws IOException {
+      final List<String> res = new ArrayList<String>();
+      final JarFile jarFile = new JarFile(file);
+      for (final Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements();) {
+        final ZipEntry entry = e.nextElement();
+
+        if (entry.getName().startsWith(SRC_PREFIX)) {
+          if (0 == res.size()) {
+            destDir.mkdirs();
+          }
+
+          if (entry.isDirectory()) {
+            makeDir(destDir, entry, SRC_PREFIX);
+          } else {
+            copyEntry(destDir, jarFile, entry, SRC_PREFIX);
+            res.add(Util.replace(entry.getName(), SRC_PREFIX + "/", ""));
+          }
+        }
+      }
+
+      if (0 == res.size()) {
+        // Check if we can copy source from original pos
+        final String sourceDir = mainAttributes.getValue("Built-From");
+        if (sourceDir != null && !"".equals(sourceDir)) {
+          final File src = new File(sourceDir, "src");
+          res.addAll(copyTree(src, destDir, src.toString() + File.separator, ".java"));
+        }
+      }
+      return res;
+    }
+
+    private static void makeDir(final File destDir, final ZipEntry entry,
+                                final String prefix) throws IOException {
+      final File d = new File(destDir,
+                              Util.replace(entry.getName(), prefix, ""));
+
+      d.mkdirs();
+    }
+
+    private static void copyEntry(File destDir, ZipFile file, ZipEntry entry,
+                                  String prefix) throws IOException {
+      final File destFile = new File(destDir, Util.replace(entry.getName(),
+                                                           prefix, ""));
+
+      final File dir = destFile.getParentFile();
+
+      if (!dir.exists()) {
+        dir.mkdirs();
+      }
+      copyStream(new BufferedInputStream(file.getInputStream(entry)),
+                 new BufferedOutputStream(new FileOutputStream(destFile)));
+    }
+
+    private static void copyStream(final InputStream is, final OutputStream os)
+      throws IOException {
+      final byte[] buf = new byte[1024];
+
+      BufferedInputStream in = null;
+      BufferedOutputStream out = null;
+
+      try {
+        in = new BufferedInputStream(is);
+        out = new BufferedOutputStream(os);
+        int n;
+        while ((n = in.read(buf)) > 0) {
+          out.write(buf, 0, n);
+        }
+      } finally {
+        try {
+          in.close();
+        } catch (final Exception ignored) {
+        }
+        try {
+          out.close();
+        } catch (final Exception ignored) {
+        }
+      }
+    }
+
+    private static List<String> copyTree(File dest, File src, String prefix,
+                                 String suffix) throws IOException {
+      final List<String> res = new ArrayList<String>();
+
+      if (src.isDirectory()) {
+        if (!dest.exists()) {
+          dest.mkdirs();
+        }
+
+        final String[] files = src.list();
+        for (final String file2 : files) {
+          res.addAll(copyTree(new File(dest, file2),
+                              new File(src, file2), prefix, suffix));
+        }
+      } else if (src.isFile()) {
+        if (src.getName().endsWith(suffix)) {
+          copyStream(new FileInputStream(src), new FileOutputStream(dest));
+          res.add(Util.replace(Util.replace(src.getAbsolutePath(), prefix, ""),
+                               "\\", "/"));
+        }
+      }
+      return res;
+    }
+
+    /**
+     * Build a mapping holding one entry for each source file found in the
+     * SVN-repository for the bundle. The repository URL of a source file is the
+     * repoUrl followed by the part of the file path that remains when the
+     * pathPrefix has been removed.
+     *
+     * @param pathPrefix
+     *          The path of source files to include must start with this value.
+     * @param repoURL
+     *          The URL to the SVN repository.
+     *
+     * @return Mapping where the key is the name (path) of the source file and
+     *         the value the repository URL to it.
+     * @throws IOException
+     */
+    public Map<String, String> getSrcRepositoryLinks(final String pathPrefix, final URL repoURL)
+      throws IOException {
+      final Map<String, String> res = new TreeMap<String, String>();
+
+      // Check if we can locate a source tree based on the
+      // "Built-From" header.
+      final String rootDir = mainAttributes.getValue("Built-From");
+      if (null != rootDir && 0 < rootDir.length()) {
+        final File src = new File(rootDir, "src");
+        if (src.isDirectory()) {
+          res.putAll(srcRepositoryLinks(pathPrefix, repoURL, src,
+                                        src.getAbsolutePath() + File.separator));
+        } else {
+          task.log(
+                   "No src sub-directory in 'Built-From' location, "
+                   + src.getAbsolutePath() + ", can not locate source files.",
+                   Project.MSG_VERBOSE);
+        }
+      } else {
+        task.log("No 'Built-From' manifest header in bundle, "
+                 + "can not locate source files.", Project.MSG_VERBOSE);
+      }
+      return res;
+    }
+
+    private Map<String, String> srcRepositoryLinks(final String pathPrefix, final URL repoURL,
+                                   final File src, final String prefix) throws IOException {
+      final Map<String, String> res = new TreeMap<String, String>();
+
+      if (src.isDirectory()) {
+        final String[] files = src.list();
+        for (final String file2 : files) {
+          res.putAll(srcRepositoryLinks(pathPrefix, repoURL, new File(src,
+                                                                      file2), prefix));
+        }
+      } else if (src.isFile()) {
+        final String path = src.getAbsolutePath();
+        if (src.getName().endsWith(".java")) {
+          final String bundlePath = Util.replace(path, prefix, "");
+          if (path.startsWith(pathPrefix)) {
+            final String repoPath = Util.replace(path, pathPrefix, "").replace(
+                                                                               File.separatorChar, '/');
+            final String href = new URL(repoURL, repoPath).toString();
+
+            res.put(bundlePath, href);
+
+            task.log("Found Java source file in repository, " + path
+                     + " with href '" + href + "'.", Project.MSG_VERBOSE);
+          } else {
+            task.log("Skipping non-repository Java source file, " + path + ".",
+                     Project.MSG_DEBUG);
+          }
+
+        } else {
+          task.log("Skipping non-Java source file, " + path + ".",
+                   Project.MSG_DEBUG);
+        }
+      }
+      return res;
+    }
+
+  } // class BundleArchive
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleClasspathTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleClasspathTask.java
new file mode 100644
index 0000000..d031deb
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleClasspathTask.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2006-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.ZipFileSet;
+
+/**
+ * Task that translates the value of the OSGi specified manifest
+ * header <tt>Bundle-Classpath</tt> into either a file set or pattern
+ * suitable for use as the includes attribute in a file set that will
+ * find all classes and jars that the framework may use given the
+ * specified Bundle-Classpath manifest attribute.
+ *
+ * <p>This task may also be used as a nested element in the bundle
+ * info task. In that case it will be used to generate a list of file
+ * sets, one for each entry in the given bundle classpath. If the
+ * excludes attribute is given the file sets will use that as exclude
+ * pattern otherwise the includes attribute is used as includes
+ * pattern. If the bundle classpath entry is a jar-file then a
+ * ZipFileSet will be created for it with the jar-file as source and
+ * the excludes (or includes) attribute as excludes (includes)
+ * pattern.</p>
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>BundleClasspath</td>
+ *   <td valign=top>The bundle class path to convert into an includes
+ *       pattern.
+ *       <p>
+ *       If unset, set to empty string, or set to the special empty
+ *       value <code>[bundle.emptystring]</code> the default bundle
+ *       classpath, "." will be used.
+ *       </p>
+ *       <p>
+ *       Note: The current value of this property will be overwritten
+ *       by the derived pattern.
+ *       </p>
+ *   </td>
+ *   <td valign=top>No.<br> Default value is "."</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>propertyName</td>
+ *   <td valign=top>Name of property that will receive the resulting
+ *       pattern.
+ *   </td>
+ *   <td valign=top>Yes.<br> No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>dir</td>
+ *   <td valign=top>The directory to use as root directory in the
+ *       created fileset.
+ *   </td>
+ *   <td valign=top>Yes.<br> No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>filesetId</td>
+ *   <td valign=top>Id of a file set with include patterns based on
+ *       the given <tt>BundleClasspath</tt> and base directory given
+ *       by <tt>dir</tt>. If <tt>dir</tt> is not given or
+ *       non-existing then an empty file set is created.
+ *   </td>
+ *   <td valign=top>No.<br>No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>includes</td>
+ *   <td valign=top>Includes pattern to apply to each file set created
+ *       from the entries in the bundle classpath when building a list
+ *       of file sets.
+ *   </td>
+ *   <td valign="top">At least one of includes and excludes must be
+ *       given when building a list of file sets from the bundle
+ *       classpath.<br>
+ *       No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign="top">excludes</td>
+ *   <td valign=top>Excludes pattern to apply to each file set created
+ *       from the entires in the bundle classpath when building a list
+ *       of file sets. Note: This attribute is only used when the
+ *       <bundleclasspath> is used as a nested element inside a
+ *       <bundleinfo> element.
+ *   </td>
+ *   <td valign=top>At least one of includes and excludes must be
+ *       given when building a list of file sets from the bundle
+ *       classpath.<br>
+ *       No default value.</td>
+ *  </tr>
+ * </table>
+ *
+ * <h3>Examples</h3>
+ * The table below shows how different bundle class path entries are
+ * translated int patterns.
+ * <table border="1">
+ *  <tr><th>Entry</th><th>Pattern</th></tr>
+ *  <tr><td>.</td><td>&#x2A;&#x2A;/&#x2A;.class</td></tr>
+ *  <tr><td> rxtx</td><td>rxtx/&#x2A;&#x2A;/&#x2A;.class</td></tr>
+ *  <tr><td>/rxtx</td><td>rxtx/&#x2A;&#x2A;/&#x2A;.class</td></tr>
+ *  <tr><td>required.jar</td><td>required.jar</td></tr>
+ *  <tr><td>xx/required.jar</td><td>xx/required.jar</td></tr>
+ *  <tr><td>/xx/required.jar</td><td>xx/required.jar</td></tr>
+ * </table>
+ */
+public class BundleClasspathTask extends Task {
+
+  private File   dir;
+  private String filesetId;
+  private String bundleClasspath = ".";
+  private String propertyName;
+  private String includes = null;
+  private String excludes = null;
+
+  public BundleClasspathTask() {
+  }
+
+  /**
+   * Set bundle class path to create a pattern for.
+   */
+  public void setBundleClasspath(String s) {
+    this.bundleClasspath
+      = (BundleManifestTask.BUNDLE_EMPTY_STRING.equals(s)) ? "." : s;
+    log("bundleClasspath="+bundleClasspath, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the bundle class path pattern.
+   */
+  public void setPropertyName(String s) {
+    this.propertyName  = s;
+    log("propertyName="+propertyName, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the file set root directory.
+   */
+  public void setDir(File f) {
+    this.dir = f;
+    log("dir="+dir, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the file set id.
+   */
+  public void setFilesetId(String s) {
+    this.filesetId = s;
+    log("filesetId="+filesetId, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set the includes pattern to use in the collection of file sets
+   * returned by {@link #getFileSets(boolean)}.
+   */
+  public void setIncludes(String s) {
+    this.includes = s;
+    log("includes="+this.includes, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set the excludes pattern to use in the collection of file sets
+   * returned by {@link #getFileSets(boolean)}.
+   */
+  public void setExcludes(String s) {
+    this.excludes = s;
+    log("excludes="+this.excludes, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Get a collection of file sets selecting all classes in the bundle
+   * class path that matches the given pattern.
+   *
+   * @return A list with file sets, one file set for each entry on the
+   *         bundle class path. If the entry is for a Jar/Zip file
+   *         then its list item will be a zip file set.
+   */
+  public List<FileSet> getFileSets(boolean failOnClassPath)
+  {
+    final List<FileSet> res = new ArrayList<FileSet>();
+    final Project proj = getProject();
+
+    if (dir==null) {
+      throw new BuildException("The dir attribute (root of the bundle "
+                               +"class path) is required.");
+    } else if (!dir.exists()) {
+      log("Bundle class path root dir '" +dir
+          +"' does not exist, returning empty list of file sets.",
+          Project.MSG_VERBOSE);
+      return res;
+    }
+
+    if (null==bundleClasspath || 0==bundleClasspath.length() ) {
+      // Use the default bundle class path
+      bundleClasspath = ".";
+    }
+
+    // Convert path entries to file sets.
+    final StringTokenizer st = new StringTokenizer(bundleClasspath, ",");
+    while (st.hasMoreTokens()) {
+      String entry = st.nextToken().trim();
+      if (entry.startsWith("/")) {
+        // Entry is a relative path, must not start with a '/', fix it.
+        entry = entry.substring(1);
+      }
+
+      FileSet fileSet = null;
+      final File src= new File(dir, entry);
+
+      // Bundle class path entries are either directories or jar/zip-files!
+      if (src.isDirectory()) {
+        fileSet = new FileSet();
+        fileSet.setDir(src);
+        fileSet.setProject(getProject());
+      } else if (src.exists()) {
+        fileSet = new ZipFileSet();
+        ((ZipFileSet) fileSet).setSrc(src);
+      } else {
+        final StringBuffer msg = new StringBuffer();
+        msg.append("The following entry in the Bundle-ClassPath")
+          .append(" header doesn't exist in the bundle: ")
+          .append(entry)
+          .append(".");
+        if (failOnClassPath) {
+          log(msg.toString(), Project.MSG_ERR);
+          throw new BuildException(msg.toString(), getLocation());
+        } else {
+          log(msg.toString(), Project.MSG_WARN);
+          continue;
+        }
+      }
+
+      fileSet.setProject(proj);
+      if (null!=includes) {
+        fileSet.setIncludes(includes);
+      }
+      if (null!=excludes) {
+        fileSet.setExcludes(excludes);
+      }
+      res.add(fileSet);
+      log("Added FileSet with root '" +src +"', includes: '" +includes
+          +"', excludes: '" +excludes +"'.", Project.MSG_DEBUG);
+    }
+
+    return res;
+  }
+
+
+  // Implements Task
+  //
+  @Override
+  public void execute() throws BuildException {
+    if (   (null==propertyName || 0==propertyName.length())
+           && (null==filesetId    || 0==filesetId.length()) ) {
+      throw new BuildException
+        ("Either propertyName or filesetId must be given.");
+    }
+    if (null!=filesetId && dir==null) {
+      throw new BuildException
+        ("dir is required when filesetId is given.");
+    }
+
+    if (null==bundleClasspath || 0==bundleClasspath.length() ) {
+      bundleClasspath = ".";
+    }
+
+    final StringBuffer sb = new StringBuffer(100);
+
+    // Convert path entries to patterns.
+    final StringTokenizer st = new StringTokenizer(bundleClasspath, ",");
+    while (st.hasMoreTokens()) {
+      String entry = st.nextToken().trim();
+      if (entry.startsWith("/")) {
+        // Entry is a relative path, must not start with a '/', fix it.
+        entry = entry.substring(1);
+      }
+
+      if (".".equals(entry)) {
+        sb.append("**/*.class");
+      } else if (entry.endsWith(".jar")) {
+        sb.append(entry);
+      } else {
+        sb.append(entry + "/**/*.class");
+      }
+      if (st.hasMoreTokens()) {
+        sb.append(",");
+      }
+    }
+
+    final Project proj = getProject();
+
+    // Conversion done - write back properties
+    if (null!=propertyName) {
+      proj.setProperty(propertyName, sb.toString());
+      log("Converted \"" +bundleClasspath +"\" to pattern \""
+          +sb.toString() +"\"",
+          Project.MSG_VERBOSE);
+    }
+
+    if (null!=filesetId) {
+      final FileSet fileSet = new FileSet();
+      fileSet.setProject(proj);
+      if (dir.exists()) {
+        fileSet.setDir(dir);
+        fileSet.setIncludes(sb.toString());
+      } else {
+        log("Bundle class path root dir '" +dir
+            +"' does not exist, returning empty file set.",
+            Project.MSG_DEBUG);
+        fileSet.setDir(new File("."));
+        fileSet.setExcludes("**/*");
+      }
+      proj.addReference(filesetId, fileSet);
+      log("Converted bundle class path \"" +bundleClasspath
+          +"\" to file set with id '" +filesetId
+          +"' and files \"" +fileSet +"\"",
+          Project.MSG_VERBOSE);
+    }
+  }
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleHTMLExtractorTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleHTMLExtractorTask.java
new file mode 100644
index 0000000..9277ea4
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleHTMLExtractorTask.java
@@ -0,0 +1,1186 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.ResourceCollection;
+
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+import org.knopflerfish.ant.taskdefs.bundle.BundleArchives.BundleArchive;
+
+/**
+ * Task that analyzes a set of bundle jar files and builds HTML documentation
+ * from these bundles. Also creates cross-references to bundle dependencies.
+ *
+ * <p>
+ * All generated HTML will be stored in the directory specified with the
+ * attribute <code>outDir</code> preserving the directory structure underneath
+ * the files sets that are scanned for jar-files.
+ *
+ * E.g., a nested file set that selects
+ *
+ * <pre>
+ * log / log - api.jar
+ * </pre>
+ *
+ * will result in an HTML-file
+ *
+ * <pre>
+ *  <it>outDir</it>/log/log-api.html
+ * </pre>
+ *
+ *
+ * <p>
+ * The bundle analyzes is based on the attributes in the manifest.
+ * </p>
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ * <tr>
+ * <td valign=top><b>Attribute</b></td>
+ * <td valign=top><b>Description</b></td>
+ * <td valign=top><b>Required</b></td>
+ * </tr>
+ * <tr>
+ * <td valign=top>javadocRelPath</td>
+ * <td valign=top>Relative path (from outDir) to javadocs.</td>
+ * <td valign=top>No.<br>
+ * Default value is "."</td>
+ * </tr>
+ * <tr>
+ * <td valign=top>outDir</td>
+ * <td valign=top>
+ * Directory to place resulting files in.</td>
+ * <td valign=top>No.<br>
+ * Default value is "."</td>
+ * </tr>
+ * <tr>
+ * <td valign=top>templateHTMLDir</td>
+ * <td valign=top>
+ * Directory containing HTML template files. This directory must contain the
+ * files:
+ *
+ * <pre>
+ *    bundle_index.html
+ *    bundle_list.html
+ *    bundle_main.html
+ *    bundle_info.html
+ *    package_list.html
+ *    style.css
+ * </pre>
+ *
+ * </td>
+ * </td>
+ * <td valign=top>No.<br>
+ * Default value is "."</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>systemPackageSet</td>
+ * <td valign=top>
+ * Comma-separated set of packages which are system packages and thus globally
+ * available. These are not cross-referenced.</td>
+ * <td valign=top>No.<br>
+ * Default value is <code>javax.swing, javax.accessibility,
+ *     javax.servlet, javax.xml,org.xml, org.w3c, java, com.sun</code></td>
+ *
+ * <tr>
+ * <td valign=top>skipAttribSet</td>
+ * <td valign=top>
+ * Comma-separated set of manifest attributes which shouldn't be printed.</td>
+ * <td valign=top>No.<br>
+ * Default value is <code>Manifest-Version, Ant-Version,
+ *     Bundle-Config, Created-By, Built-From</code></td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>includeSourceFiles</td>
+ * <td valign=top>
+ * Controls if Java source files shall be copied and linked into the HTML
+ * structure.</td>
+ * <td valign=top>No.<br>
+ * Default value "False"</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>includeSourceFileRepositoryLinks</td>
+ * <td valign=top>
+ * Controls if links to the repository version of Java source files shall be
+ * added to the HTML structure. The link target will be created from local file
+ * names by replacing the path prefix that matches the property
+ * <code>rootDir</code> by <code>repositoryURL</code>.</td>
+ * <td valign=top>No.<br>
+ * Default value "False"</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>rootDir</td>
+ * <td valign=top>
+ * The prefix of the source file absolute path to remove when creating a
+ * repository URL for the source file. See
+ * <code>includeSourceFileRepositoryLinks</code> for details.</td>
+ * <td valign=top>No.<br>
+ * Default value ""</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>repositoryURL</td>
+ * <td valign=top>
+ * The base URL to source file repository. See
+ * <code>includeSourceFileRepositoryLinks</code> for details.</td>
+ * <td valign=top>No.<br>
+ * Default value ""</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>listHeader</td>
+ * <td valign=top>
+ * Heading to print at the top of the bundle list in the left frame of the page.
+ * </td>
+ * <td valign=top>No.<br>
+ * Default value is ""</td>
+ * </tr>
+ *
+ * </table>
+ *
+ * <h3>Parameters specified as nested elements</h3> <h4>fileset</h4>
+ *
+ * (required)<br>
+ * <p>
+ * Jar files to analyze must be selected by a nested file set. All jar file
+ * selected by a nested file set will be analyzed.
+ * </p>
+ *
+ * <h3>Examples</h3>
+ *
+ * <pre>
+ * <bundlehtml templateHTMLDir    = "${ant.dir}/html_template"
+ *                outDir             = "${release.dir}/docs"
+ *                baseDir            = "${release.dir}/osgi"
+ *                javadocRelPath     = "../javadoc"
+ *   >
+ *
+ *     <fileset dir="${release.dir}/osgi/jars">
+ *       <include name = "**/*.jar"/>
+ *     </fileset>
+ * </pre>
+ *
+ */
+public class BundleHTMLExtractorTask
+  extends Task
+{
+
+  /** Last part of the javadoc URL for a class / interface. */
+  static final String HTML = ".html";
+  /** Last part of the javadoc URL for a package. */
+  static final String PACKAGE_SUMMARY_HTML = "/package-summary.html";
+
+  private BundleArchives bas;
+
+  private final String listSeparator = "<br>\n";
+  private final String indexListHeader = "<h2>${bundle.list.header}</h2>";
+
+  private final String indexListRow =
+    "<a target=\"bundle_main\" href=\"${bundledoc}\">${FILE.short}</a><br>\n";
+
+  private final String indexMainRow =
+    "<tr>"
+        + "<td><a target=\"bundle_main\" href=\"${bundledoc}\">${FILE.short}</a></td><td>"
+        + "<td>${Bundle-Description}</td>" + "</tr>\n";
+
+  private final String indexMainUnresolved =
+    "<table>\n <tr><td colspan=2 class=\"mfheader\">Unresolved packages</td></tr>\n${unresolvedRows}\n</table>\n";
+
+  private final String indexMainUnresolvedRow =
+    " <tr><td>${FILE.short}</td>\n  <td>${pkgs}</td></tr>\n";
+
+  private final String bundleRow =
+    "<tr><td><a href=\"${bundledoc}\">${FILE.short}</a></td><td>${what}</td></tr>\n";
+
+  private final String packageListRow =
+    "<tr><td>${pkg}</td><td>${providers}</td></tr>\n";
+
+  private final String missingRow =
+    "<tr><td>${name}</td><td>${version}</td></tr>\n";
+
+  private final String pkgHTML = "${namelink}";
+  private final String pkgHTMLversion = "${namelink} ${version}";
+
+  private final Map<String, Object> globalVars = new TreeMap<String, Object>();
+
+  /**
+   * Mapping from package name to bundle archive that uses the package
+   * containing one entry for each package that does not have any java doc.
+   */
+  private final Map<String, BundleArchive> missingDocs =
+    new TreeMap<String, BundleArchive>();
+
+  public BundleHTMLExtractorTask()
+  {
+
+    setListProps("Export-Package," + "Import-Package," + "Import-Service,"
+                 + "Export-Service");
+
+    setSystemPackageSet("javax.swing," + "javax.accessibility,"
+                        + "javax.servlet," + "javax.xml," + "org.xml,"
+                        + "org.w3c," + "java," + "com.sun," + "com.apple.eawt");
+
+    setSkipAttribSet("Manifest-Version," + "Ant-Version," + "Bundle-Config,"
+                     + "Created-By"
+    // "Built-From",
+    );
+
+    setAlwaysProps("Build-Date," + "Bundle-Activator," + "Bundle-Classpath,"
+                   + "Bundle-ContactAddress," + "Bundle-Description,"
+                   + "Bundle-License," + "Bundle-DocURL,"
+                   + "Bundle-ManifestVersion," + "Bundle-Name,"
+                   + "Bundle-SymbolicName," + "Bundle-Vendor,"
+                   + "DynamicImport-Package," + "Export-Package,"
+                   + "Import-Package," + "Provide-Capability,"
+                   + "Require-Capability," + "Main-class");
+  }
+
+  private boolean bCheckJavaDoc = true;
+
+  public void setCheckJavaDoc(boolean b)
+  {
+    this.bCheckJavaDoc = b;
+  }
+
+  private File templateHTMLDir = new File(".");
+
+  public void setTemplateHTMLDir(File f)
+  {
+    this.templateHTMLDir = f;
+
+    if (!templateHTMLDir.exists()) {
+      throw new BuildException("templateHTMLDir: " + f + " does not exist");
+    }
+    if (!templateHTMLDir.isDirectory()) {
+      throw new BuildException("templateHTMLDir: " + f + " is not a directory");
+    }
+  }
+
+  private boolean include_source_files = false;
+
+  public void setIncludeSourceFiles(boolean b)
+  {
+    this.include_source_files = b;
+  }
+
+  private boolean includeSourceFileRepositoryLinks = false;
+
+  public void setIncludeSourceFileRepositoryLinks(boolean b)
+  {
+    this.includeSourceFileRepositoryLinks = b;
+  }
+
+  private String rootDir = null;
+
+  public void setRootDir(File f)
+  {
+    rootDir = f.getAbsolutePath() + File.separator;
+  }
+
+  private URL repositoryURL = null;
+
+  public void setRepositoryURL(URL url)
+  {
+    repositoryURL = url;
+  }
+
+  File getBundleInfoTemplate()
+  {
+    return new File(templateHTMLDir, "bundle_info.html");
+  }
+
+  File getBundleCSSTemplate()
+  {
+    return new File(templateHTMLDir, "style.css");
+  }
+
+  File getBundleListTemplate()
+  {
+    return new File(templateHTMLDir, "bundle_list.html");
+  }
+
+  File getPackageListTemplate()
+  {
+    return new File(templateHTMLDir, "package_list.html");
+  }
+
+  File getBundleMainTemplate()
+  {
+    return new File(templateHTMLDir, "bundle_main.html");
+  }
+
+  File getBundleIndexTemplate()
+  {
+    return new File(templateHTMLDir, "bundle_index.html");
+  }
+
+  File getBundleHeaderTemplate()
+  {
+    return new File(templateHTMLDir, "bundle_header.html");
+  }
+
+  private File outDir = new File(".");
+
+  public void setOutDir(String s)
+  {
+    this.outDir = new File((new File(s)).getAbsolutePath());
+  }
+
+  private String javadocRelPath = null;
+
+  public void setJavadocRelPath(String s)
+  {
+    this.javadocRelPath = s;
+  }
+
+  private final List<ResourceCollection> filesets =
+    new ArrayList<ResourceCollection>();
+
+  public void addFileset(FileSet set)
+  {
+    filesets.add(set);
+  }
+
+  Set<String> listPropSet = new HashSet<String>();
+
+  public void setListProps(String s)
+  {
+    listPropSet = Util.parseEnumeration("list props", s);
+  }
+
+  Set<String> alwaysPropSet = new HashSet<String>();
+
+  /**
+   * Comma separated string with keys that shall have an empty default value.
+   *
+   * @param s
+   */
+  public void setAlwaysProps(String s)
+  {
+    alwaysPropSet = Util.parseEnumeration("always props", s);
+  }
+
+  Set<String> skipAttribSet = new HashSet<String>();
+
+  public void setSkipAttribSet(String s)
+  {
+    skipAttribSet = Util.parseEnumeration("skip attributes set", s);
+  }
+
+  Set<String> systemPackageSet = new HashSet<String>();
+
+  public void setSystemPackageSet(String s)
+  {
+    systemPackageSet = Util.parseEnumeration("system packages", s);
+  }
+
+  private String listHeader = "";
+
+  public void setListHeader(String s)
+  {
+    listHeader = s;
+  }
+
+  // Implements Task
+  @Override
+  public void execute()
+      throws BuildException
+  {
+    if (filesets.size() == 0) {
+      throw new BuildException("No nested file sets specified");
+    }
+
+    log("Loading bundle information:", Project.MSG_VERBOSE);
+    bas = new BundleArchives(this, filesets, true);
+    bas.doProviders();
+
+    log("Writing bundle jar docs pages.", Project.MSG_VERBOSE);
+    try {
+      for (final Entry<String, SortedSet<BundleArchive>> entry : bas.bsnToBundleArchives
+          .entrySet()) {
+        final Set<BundleArchive> bsnSet = entry.getValue();
+        // Sorted set with bundle archives, same BSN, different versions
+        for (final Object element : bsnSet) {
+          final BundleArchive ba = (BundleArchive) element;
+          writeBundlePage(ba);
+        }
+      }
+
+      final String mainPageTemplate =
+        FileUtil.loadFile(getBundleMainTemplate().getAbsolutePath());
+      writeBundlesPage(new File(outDir, "main.html"), mainPageTemplate,
+                       indexMainRow, bas);
+
+      final String menuPageTemplate =
+        FileUtil.loadFile(getBundleListTemplate().getAbsolutePath());
+      writeBundlesPage(new File(outDir, "list.html"), menuPageTemplate,
+                       indexListRow, bas);
+
+      final String pkgListPageTemplate =
+        FileUtil.loadFile(getPackageListTemplate().getAbsolutePath());
+      writePkgListPage(new File(outDir, "package_list.html"),
+                       pkgListPageTemplate, packageListRow, bas);
+
+      copyFile(getBundleIndexTemplate(), new File(outDir, "index.html"));
+      copyFile(getBundleHeaderTemplate(), new File(outDir, "header.html"));
+      copyFile(getBundleCSSTemplate(), new File(outDir, "style.css"));
+
+      for (final Object element : missingDocs.keySet()) {
+        final String name = (String) element;
+
+        log("Missing javadoc for " + name, Project.MSG_WARN);
+      }
+    } catch (final IOException e) {
+      throw new BuildException("Faild to write bundle jar docs: " + e, e);
+    }
+  }
+
+  /**
+   * Mapping from bundle archive to Map with variables and their expansion for
+   * the that particular bundle archive.
+   */
+  private final Map<BundleArchive, Map<String, Object>> ba2varMap =
+    new HashMap<BundleArchive, Map<String, Object>>();
+
+  /**
+   * Get the variable expansion map the the given bundle archive.
+   *
+   * @param ba
+   *          bundle archive to get variable expansions for.
+   * @return Mapping form variable name to expansion.
+   * @throws IOException
+   *           When outDir can not be made canonical.
+   */
+  private Map<String, Object> getVarMap(final BundleArchive ba)
+      throws IOException
+  {
+    Map<String, Object> res = ba2varMap.get(ba);
+    if (null == res) {
+      res = new HashMap<String, Object>();
+      ba2varMap.put(ba, res);
+
+      // Populate the variable expansion map
+      final String relPath = replace(ba.relPath, ".jar", "");
+      final String path = outDir.getCanonicalPath() + File.separator + relPath;
+      res.put("html.file", path + HTML);
+      res.put("html.uri", replace(relPath, "\\", "/") + HTML);
+      res.put("src.dir", path + "/src");
+      res.put("src.uri", replace(relPath, "\\", "/") + "/src");
+      // relative path from the outDir to the bundle doc file for this bundle
+      res.put("bundledoc", replace(relPath, "\\", "/") + HTML);
+
+      res.put("FILE", ba.file.getName());
+      res.put("FILE.short", replace(ba.file.getName(), ".jar", ""));
+      res.put("BYTES", String.valueOf(ba.file.length()));
+      res.put("KBYTES", String.valueOf(ba.file.length() / 1024));
+      res.put("FILEINFO", ba.file.length() + " bytes"
+                          + (0 < ba.srcCount ? ", includes source" : ""));
+
+      int sepIx = ba.relPath.indexOf(File.separator);
+      String relPathUp = "";
+      while (sepIx > -1) {
+        relPathUp += ".." + File.separator;
+        ;
+        sepIx = ba.relPath.indexOf(File.separator, sepIx + 1);
+      }
+      res.put("relpathup", relPathUp);
+
+      res.put("jarRelPath",
+              createRelPath(new File(path).getParentFile(),
+                            ba.file.getCanonicalPath()));
+      res.put("javadocdir", javadocRelPath != null ? javadocRelPath : "");
+
+      // Manifest entries
+      for (final Entry<Object, Object> entry : ba.mainAttributes.entrySet()) {
+        final String key = entry.getKey().toString();
+        String value = entry.getValue().toString();
+
+        // Special formatting of the value for some keys:
+        if ("Export-Package".equals(key)) {
+          value =
+            getPackagesJavadocString(ba, relPathUp, ba.pkgExportMap,
+                                     PACKAGE_SUMMARY_HTML);
+        } else if ("Import-Package".equals(key)) {
+          value =
+            getPackagesJavadocString(ba, relPathUp, ba.pkgImportMap,
+                                     PACKAGE_SUMMARY_HTML);
+        } else if ("Import-Service".equals(key)) {
+          value =
+            getPackagesJavadocString(ba, relPathUp, ba.serviceImportMap, HTML);
+        } else if ("Export-Service".equals(key)) {
+          value =
+            getPackagesJavadocString(ba, relPathUp, ba.serviceExportMap, HTML);
+        } else if (listPropSet.contains(key)) {
+          value = replace(value, ",", listSeparator);
+        }
+        res.put(key, value);
+      }
+
+      // Key that shall have an empty value if not set from some other data.
+      for (final Object element : alwaysPropSet) {
+        final String key = element.toString();
+
+        if (!res.containsKey(key)) {
+          res.put(key, "");
+        }
+      }
+
+    }
+    return res;
+  }
+
+  /**
+   * Build a HTML formated string with one row for each class / package in the
+   * given map.
+   *
+   * @param ba
+   *          The bundle archive that owns the package mapping to present.
+   * @param relPathUp
+   *          relative path up from the directory where the file with the return
+   *          string will be written to the specified out directory.
+   * @param map
+   *          Mapping from package name to package version.
+   * @param linkSuffix
+   *          Suffix to add to the java doc link for the package.
+   * @return String representation of the packages in the map.
+   */
+  private String getPackagesJavadocString(final BundleArchive ba,
+                                          final String relPathUp,
+                                          final Map<String, ?> map,
+                                          final String linkSuffix)
+  {
+    final StringBuffer sb = new StringBuffer();
+
+    for (final Entry<String, ?> entry : map.entrySet()) {
+      final String name = entry.getKey();
+      final String version = entry.getValue().toString();
+
+      sb.append(getJavadocString(ba, relPathUp, name, version, linkSuffix))
+          .append("<br>\n");
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Builds a comma separated string with the package names in the set (linking
+   * to javadoc).
+   *
+   * @param relPathUp
+   *          relative path up from the directory where the file with the return
+   *          string will be written to the specified out directory.
+   * @param set
+   *          The package names to present links for.
+   * @return Comma separated string with all the packages in the set.
+   */
+  private String getPackagesJavadocString(final String relPathUp,
+                                          final Set<String> set)
+  {
+    final StringBuffer sb = new StringBuffer();
+    for (final String pkgName : set) {
+      if (0 < sb.length()) {
+        sb.append(", ");
+      }
+      sb.append(getPackageJavadocString(null, relPathUp, pkgName, ""));
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Build a HTML formated string with links to the javadoc for one named
+   * package.
+   *
+   * @param ba
+   *          The bundle archive that owns the package mapping to present.
+   * @param relPathUp
+   *          relative path up from the directory where the file with the return
+   *          string will be written to the specified out directory.
+   * @param map
+   *          Mapping from package name to package version.
+   * @param linkSuffix
+   *          Suffix to add to the java doc link for the package.
+   * @return String representation of the packages in the map.
+   */
+  private String getPackageJavadocString(final BundleArchive ba,
+                                         final String relPathUp,
+                                         final String pkg,
+                                         final String version)
+  {
+    return getJavadocString(ba, relPathUp, pkg, version, PACKAGE_SUMMARY_HTML);
+  }
+
+  /**
+   * Build a HTML formated string (one row) for the given package / class.
+   *
+   * @param ba
+   *          The bundle archive that owns the package mapping to present.
+   * @param relPathUp
+   *          relative path up from the directory where the file with the return
+   *          string will be written to the specified out directory.
+   * @param pkg
+   *          The java package to present.
+   * @param version
+   *          The version of the java package to present.
+   * @param linkSuffix
+   *          Suffix to add to the java doc link for the package. Should be
+   *          {@link #HTML} for classes and {@link #PACKAGE_SUMMARY_HTML} when
+   *          <code>pkg</code> is a java package.
+   *
+   * @return HTML string representation of the package / class linking to local
+   *         Javadoc.
+   */
+  private String getJavadocString(final BundleArchive ba,
+                                  final String relPathUp,
+                                  final String pkg,
+                                  final String version,
+                                  final String linkSuffix)
+  {
+    String row =
+      (null == version || 0 == version.length()) ? pkgHTML : pkgHTMLversion;
+
+    final String docFile = replace(pkg, ".", "/") + linkSuffix;
+    final String docPath =
+      relPathUp + javadocRelPath + "/index.html?" + docFile;
+
+    final File f =
+      new File(outDir + File.separator + javadocRelPath + File.separator
+               + docFile);
+
+    if (javadocRelPath != null && !"".equals(javadocRelPath)) {
+      if (isSystemPackage(pkg)) {
+        row = replace(row, "${namelink}", "${name}");
+      } else if ((bCheckJavaDoc && !f.exists())) {
+        row = replace(row, "${namelink}", "${name}");
+        if (null != ba) {
+          missingDocs.put(pkg, ba);
+        }
+      } else {
+        row =
+          replace(row, "${namelink}",
+                  "<a target=\"_top\" href=\"${javadoc}\">${name}</a>");
+      }
+    } else {
+      row = replace(row, "${namelink}", "${name}");
+    }
+
+    row = replace(row, "${name}", pkg);
+    row = replace(row, "${version}", version);
+    row = replace(row, "${javadoc}", docPath);
+
+    return row;
+  }
+
+  private String stdReplace(final BundleArchive ba, final String template)
+      throws IOException
+  {
+    String res = template;
+
+    for (final Entry<String, Object> entry : globalVars.entrySet()) {
+      res =
+        replace(res, "${" + entry.getKey() + "}", entry.getValue().toString());
+    }
+
+    final Map<String, Object> baVars = getVarMap(ba);
+    for (final Entry<String, Object> entry : baVars.entrySet()) {
+      res =
+        replace(res, "${" + entry.getKey() + "}", entry.getValue().toString());
+    }
+
+    return res;
+  }
+
+  /**
+   * Replace <code>${MF.UNHANDLED}</code> with one line for each manifest
+   * attribute of <code>ba</code>that is not explicitly substituted in the
+   * template string and this is not included in the set of manifest attributes
+   * to be skipped.
+   *
+   * @param template
+   *          The template string to do the replacement in.
+   * @param ba
+   *          The bundle archive to insert manifest attributes from.
+   * @return the template string with <code>${MF.UNHANDLED}</code> replaced.
+   * @throws IOException
+   */
+  private String mfaReplace(final String template, final BundleArchive ba)
+      throws IOException
+  {
+    final Set<String> handledSet = new TreeSet<String>();
+    // The set of manifest attribute names in the bundle.
+    final Set<String> mfanSet = new TreeSet<String>();
+    for (final Object element : ba.mainAttributes.keySet()) {
+      final String mfan = element.toString();
+
+      mfanSet.add(mfan);
+      if (-1 != template.indexOf("${" + mfan + "}")) {
+        handledSet.add(mfan);
+      }
+    }
+
+    // Build replacement string for ${MF.UNHANDLED} that shall contain one row
+    // for
+    // each manifest attribute not in the template and not in the skip set.
+    final Map<String, Object> varMap = getVarMap(ba);
+    final Set<String> otherMfans = new TreeSet<String>(mfanSet);
+    otherMfans.removeAll(skipAttribSet);
+    otherMfans.removeAll(handledSet);
+    final StringBuffer mfOtherAttributes = new StringBuffer();
+    for (final String string : otherMfans) {
+      final String key = string.toString();
+
+      String value = (String) varMap.get(key);
+      // If value is a valid URL, present it as a link
+      try {
+        final URL url = new URL(value);
+        value = "<a target=\"_top\" href=\"" + url + "\">" + value + "</a>";
+      } catch (final MalformedURLException mue) {
+      }
+      mfOtherAttributes.append("<tr>\n").append(" <td>").append(key)
+          .append("</td>\n").append(" <td>").append(value).append("</td>\n")
+          .append("</tr>\n");
+    }
+    return replace(template, "${MF.UNHANDLED}", mfOtherAttributes.toString());
+  }
+
+  /**
+   * Replace <code>${depending.list}</code> with one row for each bundle that
+   * may import a package exported by <code>ba</code>. The row will contain the
+   * bundle name and all the packages it may import.
+   *
+   * @param template
+   *          The template string to do the replacement in.
+   * @param ba
+   *          The bundle archive to insert manifest attributes from.
+   * @return the template string with <code>${depending.list}</code> replaced.
+   * @throws IOException
+   */
+  private String dependingReplace(final String template, final BundleArchive ba)
+      throws IOException
+  {
+    final Map<String, Object> varMap = getVarMap(ba);
+    final String relPathUp = varMap.get("relpathup").toString();
+
+    // Build list of bundles depending on this bundle.
+    final StringBuffer dependingList = new StringBuffer();
+    if (ba.pkgProvidedMap.size() == 0) {
+      dependingList.append("None found");
+    } else {
+      for (final Entry<BundleArchive, SortedSet<String>> entry : ba.pkgProvidedMap
+          .entrySet()) {
+        final BundleArchive dependentBa = entry.getKey();
+        final Set<String> pkgs = entry.getValue();
+
+        String row =
+          replace(bundleRow, "${what}",
+                  getPackagesJavadocString(relPathUp, pkgs));
+        row =
+          replace(row, "${bundledoc}",
+                  relPathUp + getVarMap(dependentBa).get("html.uri"));
+        row = stdReplace(dependentBa, row);
+        dependingList.append(row);
+      }
+    }
+    return replace(template, "${depending.list}", dependingList.toString());
+  }
+
+  /**
+   * Replace <code>${depends.list}</code> with one row for each bundle that may
+   * import a package exported by <code>ba</code>. The row will contain the
+   * bundle name and all the packages it may import.
+   *
+   * @param template
+   *          The template string to do the replacement in.
+   * @param ba
+   *          The bundle archive to insert manifest attributes from.
+   * @return the template string with <code>${depends.list}</code> replaced.
+   * @throws IOException
+   */
+  private String providersReplace(final String template, final BundleArchive ba)
+      throws IOException
+  {
+    final Map<String, Object> varMap = getVarMap(ba);
+    final String relPathUp = varMap.get("relpathup").toString();
+
+    // Build list of bundles that this bundle depends on, i.e., bundles that
+    // provides pkgs to this one.
+    final StringBuffer providersList = new StringBuffer();
+    if (ba.pkgProvidersMap.size() == 0 && ba.pkgUnprovidedMap.size() == 0) {
+      providersList.append("None found");
+    } else {
+      for (final Entry<BundleArchive, SortedSet<String>> entry : ba.pkgProvidersMap
+          .entrySet()) {
+        final BundleArchive providingBa = entry.getKey();
+        final Set<String> pkgs = entry.getValue();
+
+        String row =
+          replace(bundleRow, "${what}",
+                  getPackagesJavadocString(relPathUp, pkgs));
+        row =
+          replace(row, "${bundledoc}",
+                  relPathUp + getVarMap(providingBa).get("html.uri"));
+        row = stdReplace(providingBa, row);
+        providersList.append(row);
+      }
+
+      boolean unresolvedHeadingInculded = false;
+      for (final Entry<String, VersionRange> entry : ba.pkgUnprovidedMap
+          .entrySet()) {
+        final String pkgName = entry.getKey().toString();
+
+        if (!isSystemPackage(pkgName)) {
+          if (!unresolvedHeadingInculded) {
+            String row = missingRow;
+            row = replace(row, "${name}", "<b>Unresolved</b>");
+            row = replace(row, "${version}", "");
+
+            providersList.append(row);
+            unresolvedHeadingInculded = true;
+          }
+          final Object versionRange = entry.getValue();
+
+          String row = missingRow;
+          row = replace(row, "${name}", pkgName);
+          row = replace(row, "${version}", versionRange.toString());
+
+          providersList.append(row);
+        }
+      }
+    }
+    return replace(template, "${depends.list}", providersList.toString());
+  }
+
+  /**
+   * Replace <code>${sources.list}</code> with one row for each source file that
+   * can be found.
+   *
+   * @param template
+   *          The template string to do the replacement in.
+   * @param ba
+   *          The bundle archive to insert manifest attributes from.
+   * @return the template string with <code>${sources.list}</code> replaced.
+   * @throws IOException
+   */
+  private String sourcesReplace(final String template, final BundleArchive ba)
+      throws IOException
+  {
+    final Map<String, Object> varMap = getVarMap(ba);
+    final List<String> srcList = new ArrayList<String>();
+    final StringBuffer sb = new StringBuffer();
+
+    if (include_source_files) {
+      log("including source files in jardoc", Project.MSG_VERBOSE);
+      srcList
+          .addAll(ba.extractSources(new File((String) varMap.get("src.dir"))));
+    } else {
+      log("includeSourceFiles is not set, skipping sources",
+          Project.MSG_VERBOSE);
+    }
+
+    if (srcList.size() > 0) {
+      sb.append("<table>\n");
+      for (final Object element : srcList) {
+        final String name = (String) element;
+        final String uri =
+          replace(ba.file.getName(), ".jar", "") + "/src/" + name;
+
+        sb.append(" <tr>\n");
+        sb.append("  <td>\n");
+        sb.append("    <a href=\"" + uri + "\">" + name + "<a>\n");
+        sb.append("  </td>\n");
+        sb.append(" </tr>\n");
+
+      }
+      sb.append("</table>");
+    } else {
+      // No source files extracted, shall we create links to SVN?
+      if (includeSourceFileRepositoryLinks) {
+        final Map<String, String> srcRepositoryLinkMap =
+          ba.getSrcRepositoryLinks(rootDir, repositoryURL);
+
+        if (0 < srcRepositoryLinkMap.size()) {
+          sb.append("<table>");
+          for (final Entry<String, String> entry : srcRepositoryLinkMap
+              .entrySet()) {
+            final String name = entry.getKey();
+            final String href = entry.getValue();
+
+            sb.append(" <tr>\n");
+            sb.append("  <td>\n");
+            sb.append("    <a href=\"" + href + "\">" + name + "<a>\n");
+            sb.append("  </td>\n");
+            sb.append(" </tr>\n");
+
+          }
+          sb.append("</table>");
+        }
+
+      }
+    }
+    if (0 == sb.length()) {
+      sb.append("None found");
+    }
+    return replace(template, "${sources.list}", sb.toString());
+  }
+
+  private void writeBundlePage(final BundleArchive ba)
+      throws IOException
+  {
+    final Map<String, Object> varMap = getVarMap(ba);
+
+    final String template =
+      FileUtil.load(getBundleInfoTemplate().getAbsolutePath());
+    String res = mfaReplace(template, ba);
+    res = dependingReplace(res, ba);
+    res = providersReplace(res, ba);
+    res = sourcesReplace(res, ba);
+    res = stdReplace(ba, res);
+
+    final String outName = (String) varMap.get("html.file");
+    FileUtil.writeStringToFile(new File(outName), res);
+    log("Wrote " + outName, Project.MSG_VERBOSE);
+  }
+
+  /**
+   * Write the a page that lists all bundles.
+   *
+   * @param outFile
+   *          The file to write to.
+   * @param template
+   *          The template to use for this file.
+   * @param rowTemplate
+   *          Template to use for a bundle row in the listing.
+   * @throws IOException
+   */
+  private void writeBundlesPage(final File outFile,
+                                final String template,
+                                final String rowTemplate,
+                                final BundleArchives bas)
+      throws IOException
+  {
+    final String listHeaderRow =
+      (null != listHeader && listHeader.length() > 0)
+        ? replace(indexListHeader, "${bundle.list.header}", listHeader)
+        : listHeader;
+    String html = replace(template, "${bundle.list.header}", listHeaderRow);
+
+    final StringBuffer bundleList = new StringBuffer();
+    final StringBuffer unresolvedList = new StringBuffer();
+
+    // Build the list of bundles
+    for (final Entry<String, SortedSet<BundleArchive>> entry : bas.bnToBundleArchives
+        .entrySet()) {
+      final Set<BundleArchive> bsnSet = entry.getValue();
+      // Sorted set with bundle archives, same BSN, different versions
+      for (final BundleArchive ba : bsnSet) {
+        bundleList.append(stdReplace(ba, rowTemplate));
+
+        if (0 < ba.pkgUnprovidedMap.size()) {
+          // Build one row for each unprovided, non-system package
+          final String urow = stdReplace(ba, indexMainUnresolvedRow);
+          final StringBuffer sbUpkg = new StringBuffer();
+          for (final Entry<String, VersionRange> uPkgEntry : ba.pkgUnprovidedMap
+              .entrySet()) {
+            final String pkgName = uPkgEntry.getKey();
+            if (isSystemPackage(pkgName)) {
+              continue;
+            }
+            final String version = uPkgEntry.getValue().toString();
+
+            if (0 < sbUpkg.length()) {
+              sbUpkg.append(",<br>\n   ");
+            }
+            sbUpkg.append(getPackageJavadocString(ba, "../", pkgName, version));
+            if (ba.pkgImportOptional.contains(pkgName)) {
+              sbUpkg.append(" <em>optional</em>");
+            }
+          }
+          if (0 < sbUpkg.length()) {
+            unresolvedList.append(replace(urow, "${pkgs}", sbUpkg.toString()));
+          }
+        }
+      }
+    }
+    html = replace(html, "${bundle.list}", bundleList.toString());
+    bundleList.setLength(0);
+
+    if (0 < unresolvedList.length()) {
+      final String unresolved =
+        replace(indexMainUnresolved, "${unresolvedRows}",
+                unresolvedList.toString());
+      html = replace(html, "${unresolved.list}", unresolved);
+      unresolvedList.setLength(0);
+    }
+    html = replace(html, "${unresolved.list}", "");
+
+    FileUtil.writeStringToFile(outFile, html);
+    log("wrote " + outFile, Project.MSG_VERBOSE);
+  }
+
+  /**
+   * Write a page listing all the provided Java packages and the bundles that
+   * provides each package.
+   *
+   * @param outFile
+   *          The file to write to.
+   * @param template
+   *          The template to use for this file.
+   * @param rowTemplate
+   *          Template to use for a bundle row in the listing.
+   *
+   * @throws IOException
+   */
+  private void writePkgListPage(final File outFile,
+                                final String template,
+                                final String rowTemplate,
+                                final BundleArchives bas)
+      throws IOException
+  {
+    final StringBuffer sb = new StringBuffer();
+
+    for (final Entry<String, SortedMap<Version, SortedSet<BundleArchive>>> entry : bas.allExports
+        .entrySet()) {
+      final String pkg = entry.getKey().toString();
+      final Map<Version, SortedSet<BundleArchive>> vpMap = entry.getValue();
+
+      for (final Entry<Version, SortedSet<BundleArchive>> vpEntry : vpMap
+          .entrySet()) {
+        final String version = vpEntry.getKey().toString();
+        final Set<BundleArchive> providerBas = vpEntry.getValue();
+
+        final String row =
+          replace(rowTemplate, "${pkg}",
+                  getPackageJavadocString(null, "", pkg, version));
+        final StringBuffer sbProviders = new StringBuffer();
+        for (final Object element : providerBas) {
+          final BundleArchive provider = (BundleArchive) element;
+          sbProviders.append(stdReplace(provider, indexListRow));
+        }
+        sb.append(replace(row, "${providers}", sbProviders.toString()));
+      }
+    }
+
+    FileUtil.writeStringToFile(outFile,
+                               replace(template, "${package.list}",
+                                       sb.toString()));
+    log("wrote " + outFile, Project.MSG_VERBOSE);
+  }
+
+  void copyFile(File templateFile, File outFile)
+      throws IOException
+  {
+
+    final String src = FileUtil.loadFile(templateFile.getAbsolutePath());
+
+    FileUtil.writeStringToFile(outFile, src);
+    log("copied " + outFile, Project.MSG_VERBOSE);
+  }
+
+  /**
+   * Derive relative path from <tt>fromDir</tt> to the file given by
+   * <tt>filePath</tt>.
+   */
+  static String createRelPath(File fromDir, String filePath)
+  {
+    String res = "";
+    while (fromDir != null && !filePath.startsWith(fromDir.toString())) {
+      if (res.length() > 0) {
+        res += File.separator;
+      }
+      res += "..";
+      fromDir = fromDir.getParentFile();
+    }
+    if (res.length() > 0) {
+      res += File.separator;
+    }
+    res += filePath.substring(fromDir.toString().length() + 1);
+    return res;
+  }
+
+  boolean isSystemPackage(String name)
+  {
+    for (final Object element : systemPackageSet) {
+      final String prefix = (String) element;
+      if (name.startsWith(prefix)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * A variant of {@link Util.replace(String,String,String)} that uses the empty
+   * string as replacement for null values.
+   *
+   * @param src
+   *          The template string to do replace all matches in.
+   * @param a
+   *          The math-string to be replaced.
+   * @param b
+   *          The replacement string to use.
+   * @return The template with all occurrences of <code>a</code> replaced by
+   *         <code>b</code>.
+   */
+  String replace(String src, String a, String b)
+  {
+    return Util.replace(src, a, b == null ? "" : b);
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleInfoTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleInfoTask.java
new file mode 100644
index 0000000..8c85ae3
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleInfoTask.java
@@ -0,0 +1,1397 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.util.StringUtils;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.knopflerfish.ant.taskdefs.bundle.Util.HeaderEntry;
+
+/**
+ * Task that analyzes sets of class files and jar files that will be
+ * the contents of some bundle. The output is the set of packages to
+ * be exported and imported by the bundle. Also tries to find any
+ * class implementing <tt>org.osgi.framework.BundleActivator</tt>.
+ *
+ * <p>The set of files to analyze are specified as nested ant file sets.</p>
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border="1">
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>imports</td>
+ *   <td valign=top>Name of property that will receive a comma-separated list
+ *       of all used packages.
+ *       <p>
+ *       If set to empty string, no property will be set.
+ *       </p>
+ *       <p>
+ *       <b>Note</b>: Some default packages are always added. These
+ *       defaults can be set using the <tt>defaultimports</tt> parameter.
+ *       </p>
+ *   </td>
+ *   <td valign=top>No.<br> Default value is ""</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>exports</td>
+ *   <td valign=top>Name of property that will receive a comma-separated
+ *       list of all defined packages.
+ *       <p>
+ *       If set to empty string, no property will be set.
+ *       </p>
+ *   </td>
+ *   <td valign=top>No.<br> Default value is ""</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>activator</td>
+ *   <td valign=top>
+ *       Name of property that will receive name of class which implements
+ *       <tt>org.osgi.framework.BundleActivator</tt>
+ *       <p>
+ *       If set to empty string, no property will be set.
+ *       </p>
+ *       <p>
+ *       If set to non-empty, and multiple activators are found, or
+ *       an activator not equal to any previous content in the named property
+ *       is found - a warning will be logged.
+ *       </p>
+ *  </td>
+ *   <td valign=top>No.<br> Default value is ""</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>stdimports</td>
+ *   <td valign=top>
+ *
+ *       Comma-separated list of package name prefixes for referenced
+ *       packages that shall not be included in the Import-Package
+ *       manifest attribute.
+ *
+ *       <p>Example of packages to list in this attribute are
+ *       <ul>
+ *         <li>non-standard packages obtained via boot-delegation,
+ *         <li>packages exported by a required bundle,
+ *         <li>packages referenced to by code in nested jar-files that
+ *             are never used.
+ *       </ul>
+ *
+ *       The default value, "java.", is added to any given list
+ *       since packages starting with "java.*" shall never be
+ *       imported. They are always made available to the bundle by
+ *       delegation to the parent classloader.
+ *
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "java."
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>defaultimports</td>
+ *   <td valign=top>
+ *       Comma-separated list of packages that will be unconditionally
+ *       added to the derived set of packages that the bundle needs to
+ *       import.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is ""
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>extraimports</td>
+ *   <td valign=top>
+ *       Comma-separated list of package names that must be present
+ *       in the import list even though they are not explicitly
+ *       referenced from the bundles code. E.g., packages from which
+ *       all classes are loaded using reflection.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is ""
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>importsOnly</td>
+ *   <td valign=top>
+ *       If set to <tt>true</tt> then do not update Export-Package
+ *       manifest header.
+ *  </td>
+ *   <td valign=top>No.<br>Default value is "false".</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>implicitImports</td>
+ *   <td valign=top>
+ *       Flag for ensuring that each exported packages is included in the
+ *       import package list.
+ *
+ *       <p>
+ *       If set to "true", the task will add all packages mentioned in
+ *       the property named by <code>exports</code> to the list of
+ *       imported packages in the property named by
+ *       <code>imports</code> if not already present. When this task
+ *       adds an import declaration for an exported package the import
+ *       entry will be given a version range starting with the version
+ *       from the export statement and up to the next major version
+ *       (exclusive). If some other version range is needed an
+ *       explicit import with that range should be added to the
+ *       bundle manifest template.
+ *
+ *       <p>
+ *       This emulates the implicit import behavior present in OSGi R1-R3.
+ *       </p>
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "true"
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>serviceComponent</td>
+ *   <td valign=top>
+ *       The value of the <tt>Service-Component</tt> manifest header.
+ *
+ *       <p>If set to non-empty, leave the value of the activator
+ *       property untouched and do not complain if there are no class
+ *       that implements BundleActivator in the bundle. A bundle using
+ *       declarative services does not need a bundle activator but it
+ *       may have one anyhow.</p>
+ *
+ *  </td>
+ *   <td valign=top>No.<br> Default value is ""</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>fragmentHost</td>
+ *   <td valign=top>
+ *       The value of the <tt>Fragment-Host</tt> manifest header.
+ *
+ *       <p>If set to non-empty (i.e., this is a fragment bundle),
+ *       leave the value of the activator property untouched and do
+ *       not complain if there are no class that implements
+ *       BundleActivator in the bundle.</p>
+ *
+ *  </td>
+ *   <td valign=top>No.<br> Default value is ""</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>manifestVersion</td>
+ *   <td valign=top>
+ *       The value of the <tt>Bundle-ManifestVersion</tt> manifest header.
+ *       <p>
+ *       If set to "2" and the <tt>uses</tt> attribute is also
+ *       <tt>true</tt> then a "uses" directive is computed and added
+ *       to each package in the Export-Package header generated by
+ *       this task.
+ *       </p>
+ *  </td>
+ *   <td valign=top>No.<br> Default value is "1" (pre OSGi R4 bundle).</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>uses</td>
+ *   <td valign=top>
+ *
+ *       If set to <tt>true</tt> then add / update <tt>uses</tt>
+ *       directive in the value of the Export-Package manifest header.
+ *       <p>
+ *       Note that <tt>uses</tt>-directives are not added for pre OSGi
+ *       R4 bundle. That is for bundle with <tt>manifestVersion</tt>
+ *       less than "2".
+ *       </p>
+ *  </td>
+ *   <td valign=top>No.<br>Default value is "true".</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>failOnExports</td>
+ *   <td valign=top>
+ *       If an error is detected in the given export package header
+ *       and this attribute is set to <tt>true</tt> then a build
+ *       failure is trigger.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "true"
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>failOnImports</td>
+ *   <td valign=top>
+ *       If an error is detected in the given import package header
+ *       and this attribute is set to <tt>true</tt> then a build
+ *       failure is trigger.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "true"
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>failOnActivator</td>
+ *   <td valign=top>
+ *       If an error is detected in the given bundle activator header
+ *       and this attribute is set to <tt>true</tt> then a build
+ *       failure is trigger.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "true"
+ *   </td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>failOnClassPath</td>
+ *   <td valign=top>
+ *       If a non-existing entry is detected in the given bundle
+ *       classpath header and this attribute is set to <tt>true</tt>
+ *       then a build failure is trigger.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "true"
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>addPackageinfoPackages</td>
+ *   <td valign=top>
+ *       If set to <tt>true</tt> then add packages that contains
+ *       a <tt>packageinfo</tt> file, even if the package is empty.
+ *   </td>
+ *   <td valign=top>
+ *     No.<br>
+ *     Default value is "false"
+ *   </td>
+ *  </tr>
+ * </table>
+ *
+ * <h3>Parameters specified as nested elements</h3>
+ *
+ * The set of provided packages (classes) is the union of the packages
+ * found via <exports>, <exportsBundleClasspath> and
+ * <impls>, <implsBundleClasspath> resource
+ * collections. The <code>import-package</code> header is derived
+ * (checked against) the set of provided packages.
+ *
+ * <h4>exports</h4>
+ *
+ * (optional)<br>
+ *
+ * <p>Nested <exports>-elements are filesets that will be
+ * analyzed to determine the set of provided Java packages to be
+ * exported by the bundle.</p>
+ *
+ * <p>Unsupported file types matched by the file set are ignored.</p>
+ *
+ * <h4>exportsBundleClasspath</h4>
+ *
+ * (optional)<br>
+ *
+ * <p>Nested <exportsBundleClasspath>-elements are instances of
+ * {@link BundleClasspathTask} that will derive a list of file sets to
+ * be analyzed to determine the set of provided Java packages to be
+ * exported by the bundle.</p>
+ *
+ * <p>Unsupported file types matched by the file set are ignored.</p>
+ *
+ * <h4>impls</h4>
+ *
+ * (optional)<br>
+ *
+ * <p>Nested <impls>-elements are filesets that will be analyzed
+ * to determine the set of private Java packages provided by the
+ * bundle.</p>
+ *
+ * <p>Unsupported file types matched by the file set are ignored.</p>
+ *
+ * <h4>implsBundleClasspath</h4>
+ *
+ * (optional)<br>
+ *
+ * <p>Nested <implsBundleClasspath>-elements are instances of
+ * {@link BundleClasspathTask} that will derive a list of file sets
+ * are to be analyzed to determine the set of private Java packages
+ * provided by the bundle.</p>
+ *
+ * <p>Unsupported file types matched by the file set are ignored.</p>
+ *
+ *
+ * <h3>Examples</h3>
+ *
+ * <h4>Check all imports and activator in implementation classes</h4>
+ *
+ * <p>
+ * This example assumes all implementation classes are in the package
+ * <tt>test.impl.*</tt>
+ * </p>
+ *
+ * <pre>
+ *  <bundleinfo  activator = "bmfa.Bundle-Activator"
+ *               imports   = "impl.import.package">
+ *   <impls dir="classes" includes="test/impl/*"/>
+ *  </bundleinfo>
+ *  <echo message="imports   = ${impl.import.package}"/>
+ *  <echo message="activator = ${bmfa.Bundle-Activator}"/>
+ * </pre>
+ *
+ *
+ * <h4>Check all imports and exports in API classes</h4>
+ *
+ * <p>
+ * This example assumes all API classes are in the package
+ * <tt>test.*</tt>
+ * </p>
+ *
+ * <pre>
+ *  <bundleinfo  exports  = "api.export.package"
+ *               imports  = "api.import.package">
+ *   <exports dir="classes" includes="test/*"/>
+ *   <impls   dir="classes" includes="test/impl/*"/>
+ *  </bundleinfo>
+ *  <echo message="imports  = ${api.import.package}"/>
+ *  <echo message="exports  = ${api.export.package}"/>
+ * </pre>
+ *
+ */
+public class BundleInfoTask extends Task {
+
+  private final ArrayList<ResourceCollection> implsResourceCollections =
+    new ArrayList<ResourceCollection>();
+  private final List<ResourceCollection> exportsResourceCollections =
+    new ArrayList<ResourceCollection>();
+
+  private String importsProperty   = "";
+  private String exportsProperty   = "";
+  private String activatorProperty = "";
+  private String serviceComponent  = "";
+  private String fragmentHost      = "";
+  private Version manifestVersion  = new Version("1");
+  private boolean bUses            = true;
+
+  private final Set<String> stdImports = new TreeSet<String>();
+
+  private boolean bPrintClasses      = false;
+
+  private boolean bImplicitImports       = true;
+  private boolean bSetActivator          = true;
+  private boolean bActivatorOptional     = false;
+  private boolean failOnExports          = true;
+  private boolean failOnImports          = true;
+  private boolean failOnActivator        = true;
+  private boolean failOnClassPath        = true;
+  private boolean bImportsOnly           = false;
+  private boolean addPackageinfoPackages = false;
+  /**
+   * The set of packages referenced by the included classes but not
+   * provided by them.
+   */
+  private final TreeSet<String> importSet            = new TreeSet<String>();
+  /**
+   * A set of packages used by the included classes but not
+   * referenced from them.
+   */
+  private final TreeSet<String> extraImportSet       = new TreeSet<String>();
+
+  private final BundlePackagesInfo bpInfo = new BundlePackagesInfo(this);
+  private final ClassAnalyserASM asmAnalyser
+    = new ClassAnalyserASM(bpInfo, this);
+
+  public BundleInfoTask() {
+    setDefaultImports("");
+    setStdImports("java.");
+  }
+
+  /**
+   * Set property receiving list of imported packages.
+   */
+  public void setImports(String s) {
+    this.importsProperty  = s;
+  }
+
+  public void setPrintClasses(String s) {
+    this.bPrintClasses = "true".equals(s);
+  }
+
+  public void setFailOnExports(boolean b) {
+    this.failOnExports = b;
+  }
+
+  public void setFailOnImports(boolean b) {
+    this.failOnImports = b;
+  }
+
+  public void setFailOnActivator(boolean b) {
+    this.failOnActivator = b;
+  }
+
+  public void setFailOnClassPath(boolean b) {
+    this.failOnClassPath = b;
+  }
+
+  public void setImplicitImports(String s) {
+    this.bImplicitImports = "true".equals(s);
+  }
+
+  /**
+   * Set default import set.
+   *
+   * @param packageList Comma-separated list of package names.
+   */
+  public void setDefaultImports(String packageList) {
+    importSet.clear();
+    if (null!=packageList) {
+      packageList = packageList.trim();
+      if (0<packageList.length()) {
+        @SuppressWarnings("unchecked")
+        final Vector<String> v = StringUtils.split(packageList,',');
+        for (final String pkg : v) {
+          importSet.add(pkg.trim());
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Set the extra imports set.
+   *
+   * @param packageList Comma-separated list of package names.
+   */
+  public void setExtraImports(String packageList) {
+    extraImportSet.clear();
+    if (null!=packageList) {
+      packageList = packageList.trim();
+      if (packageList.length()>0) {
+        @SuppressWarnings("unchecked")
+        final Vector<String> v = StringUtils.split(packageList,',');
+        for (final String pkg : v) {
+          extraImportSet.add(pkg.trim());
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Set property receiving list of exported packages.
+   */
+  public void setExports(String propName) {
+    this.exportsProperty = propName;
+  }
+
+  /**
+   * Set property receiving any BundleActivator class.
+   */
+  public void setActivator(String propName) {
+    this.activatorProperty = propName;
+  }
+
+  /**
+   * Set name value of the Service-Component manifest header.
+   */
+  public void setServiceComponent(String serviceComponent) {
+    this.serviceComponent = serviceComponent;
+    if (!BundleManifestTask.isPropertyValueEmpty(this.serviceComponent)) {
+      // A bundle with service components may have an activator but it
+      // is not recommended.
+      bActivatorOptional = true;
+    }
+  }
+
+  /**
+   * Set value of the Fragment-Host manifest header.
+   */
+  public void setFragmentHost(String fragmentHost) {
+    this.fragmentHost = fragmentHost;
+    if (!BundleManifestTask.isPropertyValueEmpty(this.fragmentHost)) {
+      // A fragment bundle must not have an activator.
+      bSetActivator = false;
+    }
+  }
+
+  /**
+   * Set value of the Bundle-ManifestVersion manifest header.
+   */
+  public void setManifestVersion(String manifestVersion) {
+    this.manifestVersion = new Version(manifestVersion);
+  }
+
+  /**
+   * Shall uses directives be added to the Export-Package header or not.
+   */
+  public void setUses(boolean uses) {
+    this.bUses = uses;
+  }
+
+  /**
+   * Set set of packages always imported.
+   *
+   * @param packageList Comma-separated list of package names.
+   */
+  public void setStdImports(String packageList) {
+    stdImports.clear();
+    stdImports.add("java.");
+    @SuppressWarnings("unchecked")
+    final Vector<String> v = StringUtils.split(packageList,',');
+    for (final String imp : v) {
+      stdImports.add(imp.trim());
+    }
+  }
+
+  /**
+   * Add a file set with classes that shall be exported.
+   *
+   * @param set The file set with exports to add.
+   */
+  public void addConfiguredExports(FileSet set) {
+    final Restrict restrict = new Restrict();
+    restrict.add(set);
+    restrict.add(analyzeRestriction);
+    exportsResourceCollections.add(restrict);
+  }
+
+  /**
+   * Add file sets for classes exported from the bundle classpath.
+   *
+   * @param bcpt The bundle classpath that the bundle will have.
+   */
+  public void addConfiguredExportsBundleClasspath(BundleClasspathTask bcpt) {
+    for (final Object element : bcpt.getFileSets(failOnClassPath)) {
+      final Restrict restrict = new Restrict();
+      restrict.add((ResourceCollection) element);
+      restrict.add(analyzeRestriction);
+      exportsResourceCollections.add(restrict);
+    }
+  }
+
+  /**
+   * Add a file set with classes that are private to the bundles.
+   *
+   * @param set The file set with private implementations to add.
+   */
+  public void addConfiguredImpls(FileSet set) {
+    final Restrict restrict = new Restrict();
+    restrict.add(set);
+    restrict.add(analyzeRestriction);
+    implsResourceCollections.add(restrict);
+  }
+
+  /**
+   * Add file sets for private classes on the bundle classpath.
+   *
+   * @param bcpt The bundle classpath that the bundle will have.
+   */
+  public void addConfiguredImplsBundleClasspath(BundleClasspathTask bcpt) {
+    for (final Object element : bcpt.getFileSets(failOnClassPath)) {
+      final Restrict restrict = new Restrict();
+      restrict.add((ResourceCollection) element);
+      restrict.add(analyzeRestriction);
+      implsResourceCollections.add(restrict);
+    }
+  }
+
+  /**
+   * If set to <tt>true</tt> then do not update Export-Package
+   * manifest header.
+   */
+  public void setImportsOnly(boolean importsOnly) {
+    this.bImportsOnly = importsOnly;
+  }
+
+  /**
+   * If set to <tt>true</tt> then add packages that contains
+   * a packageinfo file, even if the package is empty.
+   */
+  public void setAddPackageinfoPackages(boolean addPackageinfoPackages) {
+    this.addPackageinfoPackages = addPackageinfoPackages;
+  }
+
+  // Implements Task
+  /**
+   * Analyze all resources in the exports and impls resource
+   * collections to determine the set of Java packages provided by
+   * this bundle. Update the given properties for export- and import
+   * package accordingly.
+   */
+  @Override
+  public void execute() throws BuildException {
+    if (0==exportsResourceCollections.size()
+        && 0==implsResourceCollections.size()) {
+      throw new BuildException("Neither exports nor impls specified",
+                               getLocation());
+    }
+
+    // First analyze the exports resource collections
+    for (final Object element : exportsResourceCollections) {
+      final ResourceCollection rc = (ResourceCollection) element;
+
+      for (@SuppressWarnings("unchecked")
+      final Iterator<Resource> rcIt = rc.iterator(); rcIt.hasNext();) {
+        final Resource res = rcIt.next();
+        log("Exports resource: "+res, Project.MSG_DEBUG);
+        analyze(res);
+      }
+    }// Scan done
+
+    // Get the sub-set of the provided packages that are the exports set
+    final Set<String> providedExportSet = new TreeSet<String>(bpInfo.getProvidedPackages());
+    final SortedSet<String> manifestExportSet = getPredefinedExportSet();
+    if (null!=manifestExportSet) {
+      // An Export-Package header was given it shall contain
+      // precisely the provided export set of Java packages.
+      if (!manifestExportSet.equals(providedExportSet)) {
+        // Found export package mismatch
+        log("Provided package to export:  " +providedExportSet,
+            Project.MSG_ERR);
+        log("Given Export-Package header: " +manifestExportSet,
+            Project.MSG_ERR);
+        final StringBuffer msg = new StringBuffer();
+        final TreeSet<String> tmp = new TreeSet<String>(manifestExportSet);
+        tmp.removeAll(providedExportSet);
+        if (0<tmp.size()) {
+          msg.append("The following non-provided packages are present in the ")
+            .append("Export-Package header: ")
+            .append(tmp.toString())
+            .append(". ");
+        }
+        tmp.clear();
+        tmp.addAll(providedExportSet);
+        tmp.removeAll(manifestExportSet);
+        if (0<tmp.size()) {
+          if (0<msg.length()) {
+            msg.append("\n");
+          }
+          msg.append("The following packages are missing from ")
+            .append("the given Export-Package header: ")
+            .append(tmp.toString())
+            .append(".");
+        }
+        tmp.clear();
+        if (failOnExports) {
+          log(msg.toString(), Project.MSG_ERR);
+          throw new BuildException(msg.toString(), getLocation());
+        } else {
+          log(msg.toString(), Project.MSG_WARN);
+        }
+      }
+    }
+    log("Provided packages to export: " +providedExportSet,
+        Project.MSG_VERBOSE);
+
+
+    // Analyze the impls resource collections to find all provided
+    // Java packages.
+    for (final Object element : implsResourceCollections) {
+      final ResourceCollection rc = (ResourceCollection) element;
+
+      for (@SuppressWarnings("unchecked")
+      final Iterator<Resource> rcIt = rc.iterator(); rcIt.hasNext();) {
+        final Resource res = rcIt.next();
+        log("Impl resource: "+res, Project.MSG_DEBUG);
+        analyze(res);
+      }
+    }// Scan done
+
+    // Get the set of packages provided by the bundle
+    bpInfo.toJavaNames(); // Make package name in bpInfo '.' separated.
+    log("All provided packages: "
+        +bpInfo.getProvidedPackagesAsExportPackageValue(),
+        Project.MSG_VERBOSE);
+
+    // created importSet from the set of unprovided referenced packages
+    final SortedSet<String> unprovidedReferencedPackages
+      = bpInfo.getUnprovidedReferencedPackages();
+    log("Un-provided referenced packages: " +unprovidedReferencedPackages,
+        Project.MSG_DEBUG);
+
+    // The set of referenced packages that matches one of the
+    // stdImport patterns.
+    final SortedSet<String> ignoredReferencedPackages = new TreeSet<String>();
+
+    // Remove all packages with names like "java.*" (full set of
+    // patterns are given by the stdImports set). Such packages must
+    // not be present in the importSet.
+    for (final Iterator<String> urpIt = unprovidedReferencedPackages.iterator();
+         urpIt.hasNext(); ) {
+      final String pkgName = urpIt.next();
+      if (isStdImport(pkgName)) {
+        urpIt.remove();
+        ignoredReferencedPackages.add(pkgName);
+      }
+    }
+    log("Referenced packages to import: " +unprovidedReferencedPackages,
+        Project.MSG_DEBUG);
+    importSet.addAll(unprovidedReferencedPackages);
+
+    final SortedSet<String> unprovidedExtraImportSet = new TreeSet<String>(extraImportSet);
+    unprovidedExtraImportSet.removeAll(bpInfo.getProvidedPackages());
+    log("Un-provided extra packages to import: " +unprovidedExtraImportSet,
+        Project.MSG_DEBUG);
+    importSet.addAll(unprovidedExtraImportSet);
+
+    // The set of packages that will be mentioned in the
+    // Export-Package or the Import-Package header.
+    final Set<String> allImpExpPkgs = new TreeSet<String>(providedExportSet);
+    allImpExpPkgs.addAll(importSet);
+
+    bpInfo.postProcessUsingMap(ignoredReferencedPackages, allImpExpPkgs);
+    //log(bpInfo.toString(), Project.MSG_INFO);
+
+    // Data collection done - write back properties
+    final Project proj = getProject();
+
+    if(!"".equals(exportsProperty)) {
+      // A property name for the Export-Package header value has been specified
+      final String exportsVal = proj.getProperty(exportsProperty);
+      if (BundleManifestTask.isPropertyValueEmpty(exportsVal)) {
+        // No value given, shall it be derived?
+        if (!bImportsOnly) {
+          if (0==providedExportSet.size()) {
+            proj.setProperty(exportsProperty,
+                             BundleManifestTask.BUNDLE_EMPTY_STRING);
+            log("No packages exported, leaving '" +exportsProperty +"' empty.",
+                Project.MSG_VERBOSE);
+          } else {
+            final String newExportsVal
+              = buildExportPackagesValue(providedExportSet);
+            log("Setting '" +exportsProperty +"' to '"+newExportsVal +"'",
+                Project.MSG_VERBOSE);
+            proj.setProperty(exportsProperty, newExportsVal);
+          }
+        }
+      } else {
+        // Export-Package given; add version and uses directives.
+        final String newExportsVal = validateExportPackagesValue(exportsVal);
+        if (!exportsVal.equals(newExportsVal)) {
+          log("Updating \"" +exportsProperty +"\" to \""+newExportsVal +"\"",
+              Project.MSG_VERBOSE);
+          proj.setProperty(exportsProperty, newExportsVal);
+        }
+      }
+    }
+
+
+    if(!"".equals(importsProperty)) {
+      String importsVal = proj.getProperty(importsProperty);
+      if (BundleManifestTask.isPropertyValueEmpty(importsVal)) {
+        // No Import-Package given; use derived value.
+        if (0==importSet.size()) {
+          log("No packages to import, leaving \"" +importsProperty +"\" empty.",
+              Project.MSG_VERBOSE);
+          proj.setProperty(importsProperty,
+                           BundleManifestTask.BUNDLE_EMPTY_STRING);
+        } else {
+          importsVal = toString(importSet, ",");
+          log("Setting \"" +importsProperty +"\" to \""+importsVal +"\"",
+              Project.MSG_VERBOSE);
+          proj.setProperty(importsProperty, importsVal);
+        }
+      } else {
+        // Import-Package given; check that all derived packages are
+        // present and that there are no duplicated packages.
+        final TreeSet<String> givenImportSet = new TreeSet<String>();
+
+        final List<HeaderEntry> entries =
+          Util.parseManifestHeader(Constants.IMPORT_PACKAGE, importsVal, false,
+                                   true, false);
+        for (final HeaderEntry entry : entries) {
+          for (final String pkgName : entry.getKeys()) {
+            if (!givenImportSet.add(pkgName)) {
+              final String msg =
+                "The package '" + pkgName
+                    + "' is mentioned twice in the given '"
+                    + Constants.IMPORT_PACKAGE + "' manifest " + "header: '"
+                    + importsVal + "'.";
+              log(msg, Project.MSG_ERR);
+              throw new BuildException(msg, getLocation());
+            }
+          }
+        }
+
+        givenImportSet.removeAll(bpInfo.getProvidedPackages());
+        final TreeSet<String> missingImports = new TreeSet<String>(importSet);
+        missingImports.removeAll(givenImportSet);
+        if (0<missingImports.size()) {
+          log("External packages: "+importSet,      Project.MSG_ERR);
+          log("Imported packages: "+givenImportSet, Project.MSG_ERR);
+          log("Provided packages: "+bpInfo.getProvidedPackages(),
+              Project.MSG_ERR);
+
+          final String msg = "The following external packages are used by "
+            +"the bundle but not mentioned in the Import-Package manifest "
+            +"header: " +missingImports;
+          log(msg, Project.MSG_ERR );
+          if (failOnImports) {
+            throw new BuildException(msg, getLocation());
+          }
+        }
+        final TreeSet<String> extraImports = new TreeSet<String>(givenImportSet);
+        extraImports.removeAll(importSet);
+        if (0<extraImports.size()) {
+          log("External packages: "+importSet, Project.MSG_ERR);
+          log("Imported packages: "+givenImportSet, Project.MSG_ERR);
+
+          log("The following packages are mentioned in the Import-Package"
+              +" manifest header but not used by the included classes: "
+             +extraImports, Project.MSG_WARN );
+        }
+      }
+    }
+
+    // Try to be a bit clever when writing back bundle activator
+    if(!"".equals(activatorProperty) && bSetActivator) {
+      final String activatorVal = proj.getProperty(activatorProperty);
+      if (BundleManifestTask.isPropertyValueEmpty(activatorVal)) {
+        // No Bundle-Activator given; use derived value if possible.
+        switch(bpInfo.countProvidedActivatorClasses()) {
+        case 0:
+          if (!bActivatorOptional) {
+            final String msg1 = "Requested to derive Bundle-Activator but "
+              +"there is no class implementing BundleActivator.";
+            log(msg1, Project.MSG_ERR);
+            if (failOnActivator) {
+              throw new BuildException(msg1, getLocation());
+            }
+          }
+          break;
+        case 1:
+          final String clazz = bpInfo.getActivatorClass();
+          proj.setProperty(activatorProperty, clazz);
+          break;
+        default:
+          final String msg2 = "Manual selection of Bundle-Activator "
+            +"is needed since the set of included classes contains "
+            +"more than one candidate: "
+            +bpInfo.providedActivatorClassesAsString();
+          log(msg2, Project.MSG_ERR);
+          if (failOnActivator) {
+            throw new BuildException(msg2, getLocation());
+          }
+        }
+      } else {
+        // Bundle-Activator given; check that it is correct.
+        if (0==bpInfo.countProvidedActivatorClasses()) {
+          log("No class implementing BundleActivator found", Project.MSG_ERR);
+        } else {
+          final String givenClazz = proj.getProperty(activatorProperty).trim();
+          if (!bpInfo.providesActivatorClass(givenClazz)) {
+            final String msg = "The specified BundleActivator '" +givenClazz
+              +"' is not a member of the set of included classes that"
+              +"  implements BundleActivator: "
+              +bpInfo.providedActivatorClassesAsString();
+            log(msg, Project.MSG_WARN);
+            if (failOnActivator) {
+              throw new BuildException(msg, getLocation());
+            }
+          }
+        }
+      }
+    }
+
+    for (final Object element : bpInfo.getReferencedClasses()) {
+      final String s = (String)element;
+      if(s.endsWith("[]")) {
+      } else {
+        if(!bpInfo.providesClass(s)) {
+          if(bPrintClasses) {
+            System.out.println(s);
+          }
+        }
+      }
+    }
+
+    /* Handle the implicitImport flag. */
+    if(bImplicitImports
+       && !"".equals(importsProperty)
+       && !"".equals(exportsProperty) ) {
+      String importsSpec = proj.getProperty(importsProperty);
+      log("implicitImport - before: "+importsSpec, Project.MSG_VERBOSE);
+      importSet.clear();
+      if (!BundleManifestTask.isPropertyValueEmpty(importsSpec)) {
+        final List<HeaderEntry> entries =
+            Util.parseManifestHeader(Constants.IMPORT_PACKAGE, importsSpec, false, true, false);
+        for (final HeaderEntry entry : entries) {
+          for (final String pkgName : entry.getKeys()) {
+            importSet.add(pkgName);
+          }
+        }
+      } else {
+        // Spec is empty, must remove the emtpy value marker for now.
+        importsSpec = "";
+      }
+      final StringBuffer sb = new StringBuffer(importsSpec);
+
+      final String exportsSpec = proj.getProperty(exportsProperty);
+      if (!BundleManifestTask.isPropertyValueEmpty(exportsSpec)) {
+        final List<HeaderEntry> entries =
+            Util.parseManifestHeader(Constants.EXPORT_PACKAGE, exportsSpec, false, true, false);
+
+        for (final HeaderEntry entry : entries) {
+          for (String pkg : entry.getKeys()) {
+          if (!importSet.contains(pkg)) {
+            final String ver = (String) entry.getAttributes().get(Constants.VERSION_ATTRIBUTE);
+            @SuppressWarnings("deprecation")
+			final String sver = (String) entry.getAttributes().get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            if (null!=ver) {
+              pkg += ";version=" +toDefaultVersionRange(ver);
+            } else if (null!=sver) {
+              pkg += ";specification-version=" +toDefaultVersionRange(sver);
+            } else {
+              pkg += ";version="
+                +toDefaultVersionRange(Version.emptyVersion.toString());
+            }
+            log("implicitImport - adding: "+pkg, Project.MSG_DEBUG);
+            if (0<sb.length()) {
+              sb.append(",");
+            }
+            sb.append(pkg);
+          }
+        }
+        }
+
+        importsSpec = sb.toString();
+        if (0==importsSpec.length()) {
+          importsSpec = BundleManifestTask.BUNDLE_EMPTY_STRING;
+        }
+        log("implicitImport - after: "+importsSpec, Project.MSG_VERBOSE);
+        proj.setProperty(importsProperty, importsSpec );
+      }
+    }
+  }
+
+  private boolean doUses()
+  {
+    return bUses && manifestVersion.compareTo(new Version("1")) > 0;
+  }
+
+
+  /**
+   * Get the set of Java packages to export according to the given
+   * <code>Export-Package</code> header.
+   *
+   * @return the set of Java packages to export or null if no
+   * <code>Export-Package</code> header was given.
+   */
+  private SortedSet<String> getPredefinedExportSet()
+  {
+    if(!"".equals(exportsProperty)) {
+      final String exportsVal = getProject().getProperty(exportsProperty);
+
+      if (!BundleManifestTask.isPropertyValueEmpty(exportsVal)) {
+        log("Found non-empty Export-Package attribute: '" +exportsVal +"'",
+            Project.MSG_DEBUG);
+
+        final TreeSet<String> res = new TreeSet<String>();
+        final List<HeaderEntry> entries =
+            Util.parseManifestHeader(Constants.EXPORT_PACKAGE, exportsVal, false, true, false);
+
+        for (final HeaderEntry entry : entries) {
+          res.addAll(entry.getKeys());
+        }
+        return res;
+      }
+    }
+    return null;
+  }
+
+
+  private void appendUsesDirective(final StringBuffer sb, final String pkgName)
+  {
+    if (doUses()) {
+      final String sep = ",";
+      final Set<String> usesPkgs = bpInfo.getPackagesReferencedFromPackage(pkgName);
+
+      if (null!=usesPkgs && 0<usesPkgs.size()) {
+        sb.append(";uses:=");
+        if (1<usesPkgs.size()) {
+          sb.append("\"");
+        }
+        for (final Iterator<String> usesIt = usesPkgs.iterator(); usesIt.hasNext(); ) {
+          final String usesPkg = usesIt.next();
+          sb.append(usesPkg);
+          if (usesIt.hasNext()) {
+            sb.append(sep);
+          }
+        }
+        if (1<usesPkgs.size()) {
+          sb.append("\"");
+        }
+      }
+    }
+  }
+
+  /**
+   * Return the value of the Export-Package based on the analysis.
+   *
+   * @param exportPackages The sub-set of provided packages to be exported.
+   */
+  protected String buildExportPackagesValue(final Set<String> exportPackages) {
+    final String sep = ",";
+    final String versionPrefix = ";version=";
+
+    final StringBuffer sb = new StringBuffer();
+
+    for(final String pkgName : exportPackages) {
+      if (sb.length() > 0) {
+        sb.append(sep);
+      }
+
+      sb.append(pkgName);
+
+      final Version pkgVersion = bpInfo.getProvidedPackageVersion(pkgName);
+      if (null!=pkgVersion) {
+        sb.append(versionPrefix).append(pkgVersion);
+      }
+
+      appendUsesDirective(sb, pkgName);
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Validate a given Export-Package header value. Check existing
+   * version parameters, add missing package versions. Check uses
+   * directives and add those that are missing.
+   *
+   * @param oldExportsVal the Export-Package value to validate and update.
+   * @throws BuildException when conflicting version specifications
+   *         are found for a package.
+   */
+  protected String validateExportPackagesValue(final String oldExportsVal)
+  {
+    final StringBuffer sb = new StringBuffer();
+    final String sep = ",";
+
+    // TODO handle multiple keys per header entry (must not use destructive
+    // operations on attributes and directives).
+    final List<HeaderEntry> entries =
+        Util.parseManifestHeader(Constants.EXPORT_PACKAGE, oldExportsVal, true, true, false);
+    for (final HeaderEntry entry : entries) {
+      for (final String pkgName : entry.getKeys()) {
+        if (!bpInfo.providesPackage(pkgName)) {
+          final String msg = "The package '"+pkgName +"' is in the Export-Package"
+            +" manifest header, but there is no class belonging to it."
+            +" The following packages are provided: "
+            +bpInfo.getProvidedPackages();
+          log(msg, Project.MSG_ERR );
+          if (failOnExports) {
+            throw new BuildException(msg, getLocation());
+          }
+        }
+
+        if (sb.length()>0) {
+          sb.append(sep);
+        }
+        sb.append(pkgName);
+
+        // Add / check package version
+        String versionKey = "version";
+        String versionStr = (String) entry.getAttributes().remove(versionKey);
+        if (null==versionStr) {
+          // Fallback to pre OSGi R4 name
+          versionKey = "specification-version";
+          versionStr = (String) entry.getAttributes().remove(versionKey);
+        }
+        Version version = null;
+        if (null!=versionStr) {
+          try {
+            version = new Version(versionStr);
+          } catch (final Exception e) {
+            final String msg = "Found invalid version value in given "
+              +"Export-Package header for the package '"
+              +pkgName +"': '"+versionStr +"'; Error: "
+              +e.getMessage();
+            log(msg, Project.MSG_ERR );
+            throw new BuildException(msg, e);
+          }
+        }
+        final Version curVersion = bpInfo.getProvidedPackageVersion(pkgName);
+        if (null==version && null!=curVersion) {
+          // Version is missing, add it
+          version = curVersion;
+        } else if (null!=version && null!=curVersion
+                   && !version.equals(curVersion)) {
+          final String msg = "Found conflicting versions for the package '"
+            +pkgName +"'. The Export-Package header says '" +version +"', but '"
+            +bpInfo.getProvidedPackageVersionSource(pkgName) +" claims '"
+            +curVersion +"'.";
+
+          log(msg, Project.MSG_ERR );
+          throw new BuildException(msg);
+        }
+        if (null!=version) {
+          // Finally insert version into the new Export-Package value
+          sb.append(";").append(versionKey).append("=").append(version);
+        }
+
+        if (doUses()) {
+          if (!entry.getDirectives().containsKey(Constants.USES_DIRECTIVE)) {
+            appendUsesDirective(sb, pkgName);
+          } else {
+            // Validate the given uses directive.
+            final Set<String> usesPkgs = bpInfo.getPackagesReferencedFromPackage(pkgName);
+            final String usesValue = entry.getDirectives().remove(Constants.USES_DIRECTIVE);
+            final TreeSet<String> uPkgsMan = new TreeSet<String>
+              (Arrays.asList(Util.splitwords(usesValue, ", \t", '"')));
+            final Set<String> uPkgsMis = new TreeSet<String>(usesPkgs);
+            uPkgsMis.removeAll(uPkgsMan);
+            if (0<uPkgsMis.size()) {
+              final String msg = "The package '"+pkgName
+                +"' in the Export-Package"
+                +" manifest header has a usage directive with value '"
+                +usesValue +"', but the following packages are are also used: '"
+                +uPkgsMis +"' and should be added to the 'uses'-directive.";
+              log(msg, Project.MSG_ERR );
+              if (failOnExports) {
+                throw new BuildException(msg, getLocation());
+              }
+            }
+            final Set<String> uPkgsExtra = new TreeSet<String>(uPkgsMan);
+            uPkgsExtra.removeAll(usesPkgs);
+            if (0<uPkgsExtra.size()) {
+              final String msg = "The package '"+pkgName
+                +"' in the Export-Package"
+                +" manifest header has a usage directive with value '" +usesValue
+                +"', that contains the following unexpected (unused) packages: '"
+                +uPkgsExtra +"' that could be removed from the 'uses'-directive.";
+              log(msg, Project.MSG_ERR );
+            }
+          }
+        }
+        for (final Entry<String, Object> paramEntry : entry.getAttributes().entrySet()) {
+          final String paramName = paramEntry.getKey();
+          final String paramValue = paramEntry.getValue().toString();
+
+          sb.append(";");
+          sb.append(paramName);
+          sb.append("=");
+          final boolean quoteNeeded = -1<paramValue.indexOf(',')
+            || -1<paramValue.indexOf(';')
+            || -1<paramValue.indexOf(':')
+            || -1<paramValue.indexOf('=');
+          if (quoteNeeded) {
+            sb.append("\"");
+          }
+          sb.append(paramValue);
+          if (quoteNeeded) {
+            sb.append("\"");
+          }
+        }
+        for (final Entry<String, String> directiveEntry : entry.getDirectives().entrySet()) {
+          final String directiveName = directiveEntry.getKey();
+          final String directiveValue = directiveEntry.getValue();
+
+          sb.append(";");
+          sb.append(directiveName);
+          sb.append(":=");
+          final boolean quoteNeeded = -1<directiveValue.indexOf(',')
+            || -1<directiveValue.indexOf(';')
+            || -1<directiveValue.indexOf(':')
+            || -1<directiveValue.indexOf('=');
+          if (quoteNeeded) {
+            sb.append("\"");
+          }
+          sb.append(directiveValue);
+          if (quoteNeeded) {
+            sb.append("\"");
+          }
+        }
+      }
+    }
+    return sb.toString();
+  }
+
+
+  /**
+   * Analyze a resource by checking its suffix and delegate to {@link
+   * #analyzeClass(Resource)} or {@link
+   * #analyzePackageinfo(Resource)}.
+   *
+   * @param res The resource to be analyzed.
+   */
+  protected void analyze(Resource res) throws BuildException {
+    if(res.getName().endsWith(".class")) {
+      analyzeClass(res);
+    } else if(res.getName().endsWith("packageinfo")) {
+      analyzePackageinfo(res);
+    } else {
+      // Just ignore all other files
+    }
+  }
+
+  protected boolean isImported(String className) {
+    for (final Object element : importSet) {
+      final String pkg = (String)element;
+      if(className.startsWith(pkg)) {
+        final String rest = className.substring(pkg.length() + 1);
+        if(-1 == rest.indexOf(".")) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Check if package is included in the prefix list of packages that
+   * does not need to be in the Import-Package list.
+   *
+   * @return <tt>true</tt> if name is prefixed with any of the elements in
+   *         <tt>stdImports</tt> set, <tt>false</tt> otherwise.
+   */
+  protected boolean isStdImport(String name) {
+    for (final Object element : stdImports) {
+      final String s = (String)element;
+      if(name.startsWith(s)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  protected void analyzeClass(Resource res) throws BuildException {
+    log("Analyze class file " + res, Project.MSG_VERBOSE);
+
+    try {
+      asmAnalyser.analyseClass(res.getInputStream(), res.toString());
+    } catch (final Exception e) {
+      e.printStackTrace();
+      throw new BuildException("Failed to analyze class-file "
+                               +res + ", exception=" + e,
+                               getLocation());
+    }
+  }
+
+  protected void analyzePackageinfo(Resource res) throws BuildException {
+    log("Analyze packageinfo file " + res, Project.MSG_VERBOSE);
+
+    final String pkgName = bpInfo.setPackageVersion(res);
+    if (addPackageinfoPackages && pkgName != null) {
+      bpInfo.addProvidedPackage(pkgName);
+    }
+  }
+
+
+  /**
+   * Given an OSGi version number on the form
+   * <code>Major.Minor.Micro.Qualifier</code> return a version range
+   * of the form <code>"[Major.Minor.Micro.Qualifier,Major)"</code>.
+   *
+   * @param version the version number to convert to a version range.
+   * @return A quoted version range string.
+   */
+  public static final String toDefaultVersionRange(final String version)
+  {
+    final Version v = new Version(version);
+    return "\"[" +v.toString() +"," +String.valueOf(v.getMajor()+1) +")\"";
+  }
+
+
+  public static final Set<String> ANALYZE_SUFFIXES = new TreeSet<String>() {
+    private static final long serialVersionUID = 2628940819429424154L;
+    {
+      add(".class");
+      add("/packageinfo"); // packageinfo-files inside jar-files
+      add(File.separatorChar + "packageinfo"); // packageinfo-files in
+                                               // the file system
+    }
+  };
+
+
+  /**
+   * A resource selector that selects files to be analyzed. I.e., it selects
+   * <code>.class</code>-files and <code>packageinfo</code>-files.
+   */
+  public static final ResourceSelector analyzeRestriction =
+    new ResourceSelector() {
+      @Override
+      public boolean isSelected(final Resource r)
+      {
+        for (final String suffix : BundleInfoTask.ANALYZE_SUFFIXES) {
+          if (r.getName().endsWith(suffix)) {
+            return true;
+          }
+        }
+        return false;
+      }
+    };
+
+  /**
+   * Convert Set elements to a string.
+   *
+   * @param separator String to use as separator between elements.
+   */
+  static protected String toString(Set<String> set, String separator) {
+    final StringBuffer sb = new StringBuffer();
+
+    for(final String name : set) {
+      if(sb.length() > 0) {
+        sb.append(separator);
+      }
+      sb.append(name);
+    }
+    return sb.toString();
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleJavadocHelperTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleJavadocHelperTask.java
new file mode 100644
index 0000000..e8d49e0
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleJavadocHelperTask.java
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2008-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.apache.tools.ant.types.selectors.OrSelector;
+
+import org.osgi.framework.Constants;
+
+import org.knopflerfish.ant.taskdefs.bundle.Util.HeaderEntry;
+
+/**
+ * Task that helps building arguments to javadoc.
+ *
+ * <ul>
+ *   <li>Loads source paths from a file removes duplicates and adds them to
+ *       a path structure.
+ *
+ *   <li>Loads export package definitions from a file removes
+ *       duplicates and OSGi specific annotation, then adds them to a
+ *       comma separated string that will be set as the value of a
+ *       named property.
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>srcRootsFile</td>
+ *   <td valign=top>The file to read source tree root directories from.
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>srcPropertyName</td>
+ *   <td valign=top>Name of property that the resulting
+ *       java source roots are appended to.
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>srcPathId</td>
+ *   <td valign=top>Id of a path like structure to append the source
+ *       root dirs to. The structure is created if needed.
+ *   </td>
+ *   <td valign=top>No.<br>No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>exportPkgsFile</td>
+ *   <td valign=top>The file to read export package definitions from.
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>exportPkgsValue</td>
+ *   <td valign=top>A single Export-Package header value to convert.
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>pkgPropertyName</td>
+ *   <td valign=top>Name of property that the resulting
+ *       java package list is appended to.
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>srcDir</td>
+ *   <td valign=top>
+ *
+ *     Path to the root of a Java source tree. Used together with
+ *     {@code exportPkgsValue} to check if there are source files
+ *     availble for any of the exported packages. The result is
+ *     assigned to the property named by {@code
+ *     pkgSrcAvailPropertyName}.
+ *
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *  <tr>
+ *   <td valign=top>pkgSrcAvailPropertyName</td>
+ *   <td valign=top>
+ *
+ *      Name of property that will be set to {@code true} if any of
+ *      the packages present in the value of {@code exportPkgsValue}
+ *      has a source file (*.java or packages.html) in the Java source
+ *      tree specified by {@code srcDir}.
+ *
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>pkgWithSourcePropertyName</td>
+ *   <td valign=top>
+ *
+ *     Name of property that will be set to the sub-list of packages
+ *     with source code of the java package list saved in {@code
+ *     pkgPropertyName}.
+ *
+ *   </td>
+ *   <td valign=top>No.<br> No default value.</td>
+ *  </tr>
+ *
+ * </table>
+ *
+ * <h3>Examples</h3>
+ *
+ * Create a comma separated list of package names (without attributes,
+ * and directives) and save the list as the value of the property with
+ * name {@code javadoc.packages}. The package names are read from the
+ * file that is the value of the property {@code exported.file}. This
+ * file contains the value of one Export-Package definition per line.
+ * <pre>
+ * <bundle_javadoc_helper exportPkgsFile="${exported.file}"
+ *                           pkgPropertyName="javadoc.packages"/>
+ * </pre>
+ *
+ */
+public class BundleJavadocHelperTask extends Task {
+
+  private File   exportPkgsFile;
+  private String exportPkgsValue;
+  private String pkgPropertyName;
+
+  private File   srcDir;
+  private String pkgSrcAvailPropertyName;
+  private String pkgWithSourcePropertyName;
+
+  private File   srcRootsFile;
+  private String srcPropertyName;
+  private String srcPathId;
+
+  public BundleJavadocHelperTask() {
+  }
+
+  /**
+   * Set property receiving the file to load export package definitions from.
+   */
+  public void setExportPkgsFile(File f) {
+    this.exportPkgsFile = f;
+    log("exportPkgsFile="+exportPkgsFile, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the export package definition to handle.
+   */
+  public void setExportPkgsValue(String s) {
+    this.exportPkgsValue = s;
+    log("exportPkgsValue="+exportPkgsValue, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the bundle class path pattern.
+   */
+  public void setPkgPropertyName(String s) {
+    if (s!=null && 0==s.length() ) {
+      this.pkgPropertyName = null;
+    } else {
+      this.pkgPropertyName = s;
+    }
+    log("pkgPropertyName=" +this.pkgPropertyName, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Property receiving the root of the source tree to check for
+   * availability of javadoc source files in when setting {@code
+   * pkgSrcAvailPropertyName}.
+   */
+  public void setSrcDir(File f) {
+    this.srcDir = f;
+    log("srcDir="+srcDir, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set name of property to be set if there are javadoc source files
+   * for the packages selected by the value of {@code pkgPropertyName}
+   * available in {@code srcDir}.
+   */
+  public void setPkgSrcAvailPropertyName(String s) {
+    if (s!=null && 0==s.length() ) {
+      this.pkgSrcAvailPropertyName = null;
+    } else {
+      this.pkgSrcAvailPropertyName = s;
+    }
+    log("pkgSrcAvailPropertyName=" +this.pkgSrcAvailPropertyName,
+        Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the filtered list of exported
+   * packages. I.e., the list of exported packages that has at least
+   * one source file.
+   */
+  public void setPkgWithSourcePropertyName(String s) {
+    if (s!=null && 0==s.length() ) {
+      this.pkgWithSourcePropertyName = null;
+    } else {
+      this.pkgWithSourcePropertyName = s;
+    }
+    log("pkgWithSourcePropertyName=" +this.pkgWithSourcePropertyName,
+        Project.MSG_DEBUG);
+  }
+
+
+  /**
+   * Set property receiving the file to load source root directory
+   * names from.
+   */
+  public void setSrcRootsFile(File f) {
+    this.srcRootsFile = f;
+    log("srcRootsFile="+srcRootsFile, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set property receiving the comma separated string with source
+   * root directories.
+   */
+  public void setSrcPropertyName(String s) {
+    if (s!=null && 0==s.length()) {
+      this.srcPropertyName = null;
+    } else {
+      this.srcPropertyName = s;
+    }
+    log("srcPropertyName="+srcPropertyName, Project.MSG_DEBUG);
+  }
+
+  /**
+   * Set id of path like structure receiving to add source root
+   * directories to.
+   */
+  public void setSrcPathId(String s) {
+    if (s!=null && 0==s.length() ) {
+      this.srcPathId = null;
+    } else {
+      this.srcPathId = s;
+    }
+    log("srcPathId=" +this.srcPathId, Project.MSG_DEBUG);
+  }
+
+  /**
+   * The set of java package names for exported packages.
+   */
+  final TreeSet<String> ePkgs = new TreeSet<String>();
+
+
+  // Implements Task
+  //
+  @Override
+  public void execute() throws BuildException {
+    if ((null==exportPkgsFile&&null==exportPkgsValue)
+        && null!=pkgPropertyName ) {
+      throw new BuildException
+        ("When pkgPropertyName is set, exportPkgsValue or exportPkgsFile "
+         +"must also be set.");
+    }
+
+    if (null!=pkgSrcAvailPropertyName && null==srcDir) {
+      throw new BuildException
+        ("When pkgSrcAvailPropertyName is set, srcDir "
+         +"must also be set.");
+    }
+
+    if (null!=pkgWithSourcePropertyName && null==pkgSrcAvailPropertyName) {
+      throw new BuildException
+        ("When pkgWithSourcePropertyName is set, pkgSrcAvailPropertyName "
+         +"must also be set.");
+    }
+
+    if (null==srcRootsFile &&
+        (null!=srcPropertyName || null!=srcPathId)) {
+      throw new BuildException
+        ("srcRootsFile must be set when srcPropertyName or srcPathId is set.");
+    }
+
+    try {
+      processSrcRootsFile();
+      processExportPkgs();
+      processPkgSrcsAvailable();
+    } catch (final Exception e) {
+      throw new BuildException(e);
+    }
+  }
+
+  private void processSrcRootsFile()
+    throws FileNotFoundException, IOException
+  {
+    if (null==srcRootsFile) {
+      return;
+    }
+
+    final Set<String> srcRoots = new TreeSet<String>();
+    BufferedReader in = null;
+    try {
+      in = new BufferedReader(new FileReader(srcRootsFile));
+
+      String line = in.readLine();
+      while (null != line) {
+        srcRoots.add(line.trim());
+        line = in.readLine();
+      }
+    } finally {
+      if (in != null) {
+        in.close();
+        in = null;
+      }
+    }
+    final Project proj = getProject();
+    if (null!=srcPropertyName) {
+      String sourcepath = proj.getProperty(srcPropertyName);
+      if (null==sourcepath) {
+        sourcepath = "";
+      }
+
+      final StringBuffer sb
+        = new StringBuffer(sourcepath.length() +50*srcRoots.size());
+      sb.append(sourcepath);
+
+      for (final Object element : srcRoots) {
+        if (sb.length()>0) {
+          sb.append(",");
+        }
+        sb.append(element);
+      }
+      proj.setProperty(srcPropertyName, sb.toString());
+    }
+    if (null!=srcPathId) {
+      final Path path = new Path(proj);
+      for (final Object element : srcRoots) {
+        path.setLocation(new File( (String) element ));
+      }
+      log("Created path: "+path,Project.MSG_DEBUG);
+      final Path oldPath = (Path) proj.getReference(srcPathId);
+      if (null!=oldPath) {
+        oldPath.add(path);
+        log(srcPathId +" after extension: "+oldPath, Project.MSG_VERBOSE);
+      } else {
+        proj.addReference(srcPathId, path);
+        log("Created \"" +srcPathId +"\": "+path, Project.MSG_VERBOSE);
+      }
+    }
+  }
+
+  private void processExportPkgs()
+    throws FileNotFoundException, IOException
+  {
+    // Unconditional process of exportPkgsFile / exportPkgsValue since
+    // result is used by other process-methods.
+    if (exportPkgsFile != null) {
+      BufferedReader in= null;
+
+      try {
+        in = new BufferedReader(new FileReader(exportPkgsFile));
+
+        String line = in.readLine();
+        while (null!=line) {
+          handleOneExportPackageLine(line);
+          line = in.readLine();
+        }
+      } finally {
+        if (in != null) {
+          in.close();
+          in = null;
+        }
+      }
+    }
+
+    if (exportPkgsValue != null) {
+      handleOneExportPackageLine(exportPkgsValue);
+    }
+
+
+    if (null!=pkgPropertyName) {
+      final Project proj = getProject();
+      String packagenames = proj.getProperty(pkgPropertyName);
+      if (null==packagenames) {
+        packagenames = "";
+      }
+
+      final StringBuffer sb
+        = new StringBuffer(packagenames.length() +50*ePkgs.size());
+      sb.append(packagenames);
+
+      for (final Object element : ePkgs) {
+        if (sb.length()>0) {
+          sb.append(",");
+        }
+        sb.append(element);
+      }
+      proj.setProperty(pkgPropertyName, sb.toString());
+      log("Setting property '" +pkgPropertyName +"' -> " +sb.toString(),
+          Project.MSG_VERBOSE);
+    }
+  }
+
+  private void handleOneExportPackageLine(final String line)
+  {
+    if (!BundleManifestTask.BUNDLE_EMPTY_STRING.equals(line)) {
+      final List<HeaderEntry> entries =
+        Util.parseManifestHeader(Constants.EXPORT_PACKAGE, line.trim(), false,
+                                 true, false);
+
+      for (final HeaderEntry entry : entries) {
+        for (final String pkg : entry.getKeys()) {
+          ePkgs.add(pkg);
+        }
+      }
+    }
+  }
+
+  private void processPkgSrcsAvailable()
+  {
+    // If no srcDir then there are no source files in it.
+    if (srcDir==null || !srcDir.exists()) {
+      return;
+    }
+
+    final Project proj = getProject();
+
+    final TreeSet<String> pkgNamesWithSource = new TreeSet<String>();
+    boolean pkgSrcAvailable = false;
+
+    for (final Object element : ePkgs) {
+      final String pkg = (String) element;
+
+      final FileSet fileSet = new FileSet();
+      fileSet.setProject(proj);
+      fileSet.setDir(srcDir);
+
+      final OrSelector orSelector = new OrSelector();
+      fileSet.add(orSelector);
+
+      final FilenameSelector fnsJ = new FilenameSelector();
+      fnsJ.setName(pkg.replace('.', File.separatorChar)
+                   + File.separatorChar + "*.java");
+      orSelector.add(fnsJ);
+
+      final FilenameSelector fnsP = new FilenameSelector();
+      fnsP.setName(pkg.replace('.', File.separatorChar)
+                  + File.separatorChar + "package.html");
+      orSelector.add(fnsP);
+
+      log(" Package '" +pkg +"' has sources: " + fileSet.toString(),
+          Project.MSG_DEBUG);
+
+      if (fileSet.size() > 0) {
+        pkgSrcAvailable |= true;
+        pkgNamesWithSource.add(pkg);
+      }
+    }
+
+    if (pkgSrcAvailable) {
+      proj.setProperty(pkgSrcAvailPropertyName, "true");
+      log("Setting property '" +pkgSrcAvailPropertyName +"' -> 'true'",
+          Project.MSG_VERBOSE);
+    }
+
+    if (pkgWithSourcePropertyName != null) {
+      final StringBuffer sb
+        = new StringBuffer(50*pkgNamesWithSource.size());
+
+      for (final Object element : pkgNamesWithSource) {
+        if (sb.length()>0) {
+          sb.append(",");
+        }
+        sb.append(element);
+      }
+
+      proj.setProperty(pkgWithSourcePropertyName, sb.toString());
+      log("Setting property '" +pkgWithSourcePropertyName +"' -> "
+          + sb.toString(), Project.MSG_VERBOSE);
+    }
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleLocator.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleLocator.java
new file mode 100644
index 0000000..594f67d
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleLocator.java
@@ -0,0 +1,909 @@
+/*
+ * Copyright (c) 2008-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.SortedSet;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.ResourceCollection;
+
+import org.osgi.framework.Version;
+
+import org.knopflerfish.ant.taskdefs.bundle.BundleArchives.BundleArchive;
+
+/**
+ * Determines a sub-set of bundles from a given file set. The resulting set of
+ * bundles will only contain the highest version of each bundle in the original
+ * file set. The resulting set of bundles may then be used in several ways.
+ *
+ * <p>
+ *
+ * An <em>OSGi version specification</em> used below is a string on the format
+ * <tt><em>Major</em>.<em>Minor</em>.<em>Micro</em>.<em>Qualifier</em></tt>
+ * where major, minor and micro are integers, and all parts of the version
+ * except major are optional. See
+ * {@link org.osgi.framework.Version#Version(java.lang.String)
+ * org.osgi.framework.Version} for details. The version formatting used by Maven
+ * 2 is also recognized, i.e., a '&#x2011;' between the micro and qualifier
+ * fields:
+ * <tt><em>Major</em>.<em>Minor</em>.<em>Micro</em>&#x2011;<em>Qualifier</em></tt>.
+ *
+ * <p>
+ *
+ * Given a partial bundle name and a file set with bundles, this task may be
+ * used to select the bundle with the highest version number and name that
+ * matches. E.g.,
+ *
+ * <pre>
+ *   <bundle_locator bundleName="http" property="http.path">
+ *     <fileset dir="${jars.dir}">
+ *       <include name="**&#x002f;*.jar"/>
+ *     </fileset>
+ *   </bundle_locator>
+ * </pre>
+ *
+ * will set the project property <tt>http.path</tt> to the absolute path of the
+ * highest version of the bundle named <tt>http</tt> within the given file set.
+ * By setting the <tt>bundleName</tt> to <tt>http-1.N.N</tt> the task will
+ * select the highest version of the <tt>http</tt>-bundle with the restriction
+ * that the Major part of the version number of the selection must be exactly
+ * <tt>1</tt>.
+ *
+ * <p>
+ *
+ * The bundle locator task can also iterate over a path and replace all
+ * non-existing file resources in it that either has a name ending with
+ * <tt>-N.N.N.jar</tt> or that is the symbolic name of a bundle with the
+ * corresponding bundle with the highest version of the matching bundle from the
+ * given file set. Non-existing path entries that does not end in <tt>.jar</tt>
+ * or <tt>.zip</tt> that does not match a symbolic bundle name will trigger a
+ * build error if <tt>failOnMissingBundles</tt> is set to <tt>true</tt>. The
+ * same applies to path entries ending with <tt>-N.N.N.jar</tt> that does not
+ * yield a match. The search may be further restricted to specific versions by
+ * replacing the <tt>N</tt> in the resource name with a specific version number.
+ *
+ * <pre>
+ *   <bundle_locator classPathRef="bundle.path"
+ *                   newClassPathId="bundle.path.Expanded"
+ *                   failOnMissingBundles="true">
+ *     <fileset dir="${jars.dir}">
+ *       <include name="**&#x002f;*.jar"/>
+ *     </fileset>
+ *   </bundle_locator>
+ * </pre>
+ *
+ * this will build a new path added to the project with the id
+ * <tt>bundle.path.Expanded</tt>. The new path will be a copy of the original,
+ * <tt>bundle.path</tt>, but with all path elements with a name ending in
+ * <tt>-N.N.N.jar</tt> replaced with the corresponding match or removed if no
+ * match was found.
+ *
+ * <p>
+ *
+ * Another usage of the bundle locator task is to ensure that only the highest
+ * version of a bundle is matched by a certain pattern set.
+ *
+ * <pre>
+ *   <bundle_locator patternSetId="my.ps.exact">
+ *     <fileset dir="${jars.dir}">
+ *       <patternset refid="my.ps"/>
+ *     </fileset>
+ *   </bundle_locator>
+ * </pre>
+ *
+ * Here the original pattern set <tt>my.ps</tt> is used to find bundles in the
+ * directory <tt>jars.dir</tt>, if more than one version of a bundle matches
+ * then only the one with the highest version will be selected. A new pattern
+ * set based on the matches is created and saved in the project under the name
+ * <tt>my.ps.exact</tt>. This pattern set will contain one include pattern for
+ * each matching bundle. The value of the include pattern is the relative path
+ * of that bundle (relative to the root directory of the file set that the
+ * matching bundle originates from).
+ *
+ * <p>
+ *
+ * Finally this task may also be used to create a properties file suitable for
+ * using as a replacement filter that will replace bundle names on the form
+ * <tt>@name-N.N.N.jar@</tt> or bundle symbolic names on the form
+ * <tt>@bundleSymbolicName.jar@</tt> with the relative path within the given
+ * file set of the bundle with the given name and the highest version.
+ *
+ * <pre>
+ *   <bundle_locator replacefilterfile="my.filter">
+ *     <fileset dir="${jars.dir}">
+ *       <patternset refid="my.ps"/>
+ *     </fileset>
+ *   </bundle_locator>
+ * </pre>
+ *
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ * <tr>
+ * <td valign=top><b>Attribute</b></td>
+ * <td valign=top><b>Description</b></td>
+ * <td valign=top><b>Required</b></td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>bundleName</td>
+ * <td valign=top>
+ * The name of the bundle to look for. There are several ways to specify the
+ * bundle name.
+ * <ul>
+ * <li>If the bundle to locate is named like
+ * <tt>name&#x2011;<em>OSGi version spec</em>.jar</tt>, then the value of the
+ * <tt>bundleName</tt>-attribute may be specified as <tt>name</tt>.
+ * <li>The symbolic name of the bundle.
+ * </ul>
+ *
+ * A property with name given by the value of the attribute <tt>property</tt>
+ * with the location (absolute path) of the bundle as value is added to the
+ * project.
+ *
+ * </td>
+ * <td valign=top>No. No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>bundleNames</td>
+ * <td valign=top>
+ *
+ * A comma separated list of bundle names to look for. There are several ways to
+ * specify the bundle name.
+ * <ul>
+ * <li>If a bundle to locate is named like
+ * <tt>name&#x2011;<em>OSGi version spec</em>.jar</tt>, then the value of the
+ * <tt>bundleName</tt>-attribute may be specified as <tt>name</tt>.
+ * <li>The symbolic name of the bundle.
+ * </ul>
+ *
+ * The absolute path of the matching bundle will be stored in a project property
+ * named <tt>bap.<em>bundleName</em></tt>.
+ *
+ * <p>
+ *
+ * If the attribute <tt>property</tt> is set its value will be used as prefix
+ * for the property names in stead of the default <tt>bap.</tt>
+ *
+ * </td>
+ * <td valign=top>No. No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>property</td>
+ * <td valign=top>
+ * The name of a project property to be assigned the location of the matching
+ * bundle.</td>
+ * <td valign=top>Yes when <tt>bundleName</tt> is specified.<br>
+ * No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>classPathRef</td>
+ * <td valign=top>
+ * The reference name (id) of a path-structure to transform.</td>
+ * <td valign=top>No. No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>newClassPathId</td>
+ * <td valign=top>
+ * The transformed path-structure will be added to the current project using
+ * this name (id).</td>
+ * <td valign=top>Yes when <tt>classPathRef</tt> is specified.<br>
+ * No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>patternSetId</td>
+ * <td valign=top>
+ * Create a pattern set from the set of bundles that are selected by the nested
+ * file set(s) and add it to the project using this name (id).</td>
+ * <td valign=top>No. No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>bundlePath</td>
+ * <td valign=top>
+ * Specifies a bundle search path like the one specified in xargs files by the
+ * framework property <code>org.knopflerfish.gosg.jars</code>. Path elements are
+ * URLs separated by ';'. Setting this property will add a file set with an
+ * includes set to <code>∗∗/∗.jar</code> for each path element
+ * that is defined as a file-URL.</td>
+ * <td valign=top>No. No default value.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>baseDir</td>
+ * <td valign=top>
+ * Path to directory to use as base-directory to complete relative
+ * file URLs in the <code>bundlePath</code>.
+ * </td>
+ * <td valign=top>No. Defaults to the empty string, i.e., the current
+ * working directory.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>failOnMissingBundles</td>
+ * <td valign=top>
+ *
+ * If an entry with a file name like <tt><em>bundleName</em>-N.N.N.jar</tt> is
+ * found on the classpath to transform and there is no matching bundle in the
+ * file set then a build failure is triggered if this attribute is set to
+ * <tt>true</tt>. Same applies if the given <tt>bundleName</tt> or one of the
+ * given <tt>bundleNames</tt> does not yield a match.
+ *
+ * </td>
+ * <td valign=top>No.<br>
+ * Defaults to <tt>true</tt>.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>extendedReplaceFilter</td>
+ * <td valign=top>
+ *
+ * If set to <tt>true</tt> then the replace filter generated by the
+ * <tt>replacefilter</tt> attribute will be extended with the following set of
+ * replacements for each matching bundle.
+ *
+ * <table>
+ * <tr>
+ * <th>Key</th>
+ * <th>Value</th>
+ * </tr>
+ * <tr>
+ * <td valign="top">
+ * <tt>@<em>bundleName</em>&#x2011;N.N.N.name@</tt><br>
+ * <tt>@<em>Bundle&#x2011;SymbolicName</em>.name@</tt></td>
+ * <td valign="top">
+ *
+ * The bundle symbolic name from the manifest. For bundles with manifest version
+ * 1 (i.e., pre OSGi R4 bundles) the bundle name.
+ *
+ * </td>
+ * <tr>
+ * <tr>
+ * <td valign="top">
+ * <tt>@<em>bundleName</em>&#x2011;N.N.N.version@</tt><br>
+ * <tt>@<em>Bundle&#x2011;SymbolicName</em>.version@</tt></td>
+ * <td valign="top">
+ *
+ * The bundle version from the manifest.
+ *
+ * </td>
+ * <tr>
+ * <tr>
+ * <td valign="top">
+ * <tt>@<em>bundleName</em>&#x2011;N.N.N.location@</tt><br>
+ * <tt>@<em>Bundle&#x2011;SymbolicName</em>.location@</tt></td>
+ * <td valign="top">
+ *
+ * The absolute path of the bundle.
+ *
+ * </td>
+ * <tr>
+ * </table>
+ *
+ * </td>
+ * <td valign=top>No.<br>
+ * Defaults to <tt>false</tt>.</td>
+ * </tr>
+ *
+ * <tr>
+ * <td valign=top>replacefilterfile</td>
+ * <td valign=top>
+ *
+ * Creates a property file suitable for use as the <tt>replacefilterfile</tt>
+ * argument in the replace-task. The generated file will contain two entries for
+ * each matching bundle.
+ *
+ * <table>
+ * <tr>
+ * <th>Key</th>
+ * <th>Value</th>
+ * </tr>
+ * <tr>
+ * <td valign="top">
+ * <tt>@<em>bundleName</em>&#x2011;N.N.N.jar@</tt><br>
+ * <tt>@<em>Bundle&#x2011;SymbolicName</em>.jar@</tt></td>
+ * <td valign="top">
+ *
+ * The relative path to the bundle from the root-directory of the file set that
+ * the matching bundle originates from.
+ *
+ * </td>
+ * <tr>
+ * </table>
+ *
+ * </td>
+ * <td valign=top>No.<br>
+ * No default value.</td>
+ * </tr>
+ *
+ * </table>
+ *
+ * <h3>Parameters specified as nested elements</h3>
+ * <h4>fileset</h4>
+ *
+ * (required)<br>
+ * <p>
+ * The jar files to match against must be specified as a fileset.
+ * </p>
+ *
+ */
+public class BundleLocator extends Task {
+
+  private final static String PROPS_PREFIX = "bap.";
+
+  private final List<ResourceCollection>    filesets = new ArrayList<ResourceCollection>();
+
+  private BundleArchives bas;
+
+  private String    bundleName           = null;
+  private String    bundleNames          = null;
+  private String    property             = null;
+  private Reference classPathRef         = null;
+  private String    newClassPathId       = null;
+  private String    patternSetId         = null;
+  private boolean   failOnMissingBundles = true;
+  private File      replacefilterfile    = null;
+  private boolean   extendedReplaceFilter= false;
+  private String    bundlePath           = null;
+  private File      baseDir              = new File(".");
+
+
+  public BundleLocator() {
+  }
+
+  public void setProperty(String s) {
+    this.property = s;
+  }
+
+  public void setBundleName(String s) {
+    this.bundleName = s;
+  }
+
+  public void setBundleNames(String s) {
+    this.bundleNames = s;
+  }
+
+  public void addFileset(FileSet set) {
+    filesets.add(set);
+  }
+
+  public void setClassPathRef(Reference r) {
+    classPathRef = r;
+  }
+
+  public void setNewClassPathId(String s) {
+    newClassPathId = s;
+  }
+
+  public void setPatternSetId(String s) {
+    patternSetId = s;
+  }
+
+  public void setFailOnMissingBundles(boolean b) {
+    failOnMissingBundles = b;
+  }
+
+  public void setExtendedReplaceFilter(boolean b) {
+    extendedReplaceFilter = b;
+  }
+
+  public void setReplacefilterfile(File f) {
+    replacefilterfile = f;
+  }
+
+  public void setBundlePath(String bundlePath) throws BuildException {
+    this.bundlePath = bundlePath;
+    log("bundlePath='" + bundlePath + "'.", Project.MSG_DEBUG);
+  }
+
+  public void setBaseDir(File f)
+  {
+    baseDir = f;
+  }
+
+  private URL getBaseURL()
+  {
+    try {
+      return baseDir.toURI().toURL();
+    } catch (final MalformedURLException e) {
+      throw new BuildException("Invalid baseDir, '" + baseDir + "'.", e);
+    }
+  }
+
+  private void processBundlePath()
+  {
+    if (null!=bundlePath && 0<bundlePath.length()) {
+      final URL baseUrl = getBaseURL();
+      // Create a file set for each entry in the bundle path.
+      final String[] urls = Util.splitwords(this.bundlePath, ";", '"');
+      for (final String url2 : urls) {
+        log("Processing URL '" + url2 + "' from bundlePath '"
+            + this.bundlePath + "'.", Project.MSG_DEBUG);
+        try {
+          final URL url = new URL(baseUrl, url2.trim());
+          if ("file".equals(url.getProtocol())) {
+            final String path = url.getPath();
+            final File dir = new File(path.replace('/', File.separatorChar));
+            log("Adding file set with dir '" + dir
+                + "' for bundlePath file URL with path '" + path + "'.",
+                Project.MSG_VERBOSE);
+            final FileSet fs = new FileSet();
+            fs.setDir(dir);
+            fs.setExcludes("**/*-source.jar,**/*-javadoc.jar");
+            fs.setIncludes("**/*.jar");
+            fs.setProject(getProject());
+            filesets.add(fs);
+          }
+        } catch (final MalformedURLException e) {
+          throw new BuildException("Invalid URL, '" + url2
+                                   + "' found in bundlePath: '"
+                                   + bundlePath + "'.", e);
+        }
+      }
+    }
+  }
+
+  // Implements Task
+  @Override
+  public void execute() throws BuildException {
+    processBundlePath();
+
+    if (filesets.size() == 0) {
+      throw new BuildException("No fileset specified");
+    }
+    bas = new BundleArchives(this, filesets);
+
+    if (null!=bundleName) {
+      setProperty();
+    }
+
+    if (null!=bundleNames) {
+      setProperties();
+    }
+
+    if (classPathRef!=null && newClassPathId!=null) {
+      transformPath();
+    }
+
+    if (patternSetId!=null) {
+      createPatternSet();
+    }
+
+    if (null!=replacefilterfile) {
+      writeReplaceFilterFile();
+    }
+  }
+
+
+  /**
+   * Check if the given bundle name contains a wild-card version descriptor.
+   *
+   *
+   * @param name The bundle name to check.
+   *
+   * @return <code>true</code> if a bundle version with wild-card is
+   *         part of the bundle name, <code>false</code> otherwise.
+   */
+  static private boolean isBundleNameWithWildcardVersion(final String name)
+  {
+    final Pattern pattern = Pattern.compile
+      ("^(.+)-(\\d+|N)(?:|\\.(\\d+|N)(?:|\\.(\\d+|N)(?:|\\.([-_0-9a-zA-Z]+))))(?:.jar|.zip)$");
+    final Matcher matcher = pattern.matcher(name);
+    if (matcher.matches()) {
+      for (int i=2; i<6; i++) {
+        final String s = matcher.group(i);
+        if ("N".equals(s)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Get the bundle archive for the given bundle name.
+   *
+   * <ol>
+   *  <li> Remove any <tt>.jar</tt> or <tt>.zip</tt> suffix form the name.
+   *  <li> If <code>name</code> is a bundle name prefix return the
+   *       highest version of that bundle.
+   *  <li> If <code>name</code> is a symbolic bundle name return the
+   *       highest version of that bundle.
+   *  <li> Try to find a bundle version as part if the bundle name,
+   *       use that version to select the bundle.
+   * </ol>
+   *
+   * @param name Name of the bundle to look for. May contain a version
+   *             suffix.
+   *
+   * @return <code>null</code> if no matching bundle archive was found.
+   */
+  private BundleArchives.BundleArchive getBundleArchive(String name)
+  {
+    log("getBundleArchive("+name +")", Project.MSG_DEBUG);
+    if (null==name || 0==name.length()) {
+      return null;
+    }
+
+    if (name.endsWith(".jar")) {
+      name = name.substring(0, name.length()-4);
+    }
+    if (name.endsWith(".zip")) {
+      name = name.substring(0, name.length()-4);
+    }
+    if (name.endsWith("-N.N.N")) {
+      name = name.substring(0, name.length()-6);
+    }
+
+    SortedSet<BundleArchive> baSet = bas.bnToBundleArchives.get(name);
+    if (null==baSet) {
+      baSet = bas.bsnToBundleArchives.get(BundleArchives.encodeBundleName(name));
+    }
+    if (null!=baSet) {
+      final BundleArchives.BundleArchive ba
+        = baSet.last();
+      log("getBundleArchive("+name +")->"+ba, Project.MSG_VERBOSE);
+      return ba;
+    }
+
+    final Pattern pattern = Pattern.compile
+      ("^(.+)-(\\d+|N)(?:|\\.(\\d+|N)(?:|\\.(\\d+|N)(?:|\\.([-_0-9a-zA-Z]+))))$");
+    final Matcher matcher = pattern.matcher(name);
+    if (matcher.matches()) {
+      name = matcher.group(1);
+      String version = "";
+      int level = -1;
+
+      for (int i=2; i<6; i++) {
+        final String s = matcher.group(i);
+        if (null==s || "N".equals(s)) {// Done;
+          break;
+        }
+        level++;
+        if (version.length()>0) {
+          version += ".";
+        }
+        version += s;
+      }
+      if (level<0) {
+        return getBundleArchive(name, null, null);
+      } else {
+        final Version min = new Version(version);
+        Version max = null;
+
+        switch(level) {
+        case 0:
+          max = new Version(min.getMajor()+1, 0, 0,"");
+          break;
+        case 1:
+          max = new Version(min.getMajor(), min.getMinor()+1, 0,"");
+          break;
+        case 2:
+          max = new Version(min.getMajor(), min.getMinor(), min.getMicro()+1,
+                            "");
+          break;
+        default:
+          max = min;
+        }
+        return getBundleArchive(name, min, max);
+      }
+    } else {
+      log("getBundleArchive(" +name +") no valid version found in the name.",
+          Project.MSG_VERBOSE);
+    }
+    return null;
+  }
+
+  /**
+   * Get the bundle archive with the highest version within the given
+   * interval for the given bundle.
+   *
+   * @param name Name of the bundle to look for. Either the part of
+   *             the file name that comes before the file version or
+   *             the bundle symbolic name.
+   * @param min  The lowest acceptable version number (inclusive).
+   * @param max  The highest acceptable version number (exclusive). If
+   *             null the highest version of this bundle will be
+   *             selected.
+   * @return <code>null</code> if no matching bundle archive was found.
+   *
+   */
+  private BundleArchives.BundleArchive getBundleArchive(final String name,
+                                                        Version min,
+                                                        final Version max)
+  {
+    SortedSet<BundleArchive> baSet = bas.bnToBundleArchives.get(name);
+    if (null==baSet) {
+      baSet = bas.bsnToBundleArchives.get(BundleArchives.encodeBundleName(name));
+    }
+    BundleArchives.BundleArchive ba = null;
+
+    if (null!=baSet) {
+      if (null==max) { // Select highest available version
+        ba = baSet.last();
+      } else {
+        if (null==min) {
+          min = Version.emptyVersion;
+        }
+        for (final Object element : baSet) {
+          final BundleArchives.BundleArchive candBa
+            = (BundleArchives.BundleArchive) element;
+          if (candBa.version.compareTo(min)<0) {
+            continue;
+          }
+          if (candBa.version.compareTo(max)>=0) {
+            break;
+          }
+          ba = candBa;
+        }
+      }
+    }
+
+    log("getBundleArchive("+name +", " +min +", " +max +")->"+ba,
+        Project.MSG_VERBOSE);
+    return ba;
+  }
+
+
+  private void setProperty()
+  {
+    if (null!=property) {
+      setProperty(bundleName, property);
+    } else {
+      throw new BuildException
+        ("The attribute 'bundleName' requires 'property'");
+    }
+  }
+
+  private void setProperty(final String bn,
+                           final String propName)
+  {
+    log("Searching for a bundle with name '" +bn +"'.", Project.MSG_DEBUG);
+    final BundleArchives.BundleArchive ba = getBundleArchive(bn);
+
+    if (ba!=null) {
+      getProject().setProperty(propName, ba.file.getAbsolutePath());
+      log(propName +" = " +ba.file, Project.MSG_VERBOSE);
+    } else {
+      final int logLevel = failOnMissingBundles
+        ? Project.MSG_ERR : Project.MSG_INFO;
+      log("No bundle with name '" +bn +"' found.", logLevel);
+      log("Known bundles names: " +bas.getKnownNames(), logLevel);
+
+      if (failOnMissingBundles) {
+        throw new BuildException("No bundle with name '" +bn+"' found.");
+      }
+    }
+  }
+
+  private void setProperties()
+  {
+    final String prefix = null==property ? PROPS_PREFIX : property;
+
+    final StringTokenizer st = new StringTokenizer(bundleNames, ",");
+    while (st.hasMoreTokens()) {
+      final String bn = st.nextToken().trim();
+
+      setProperty(bn, prefix +bn);
+    }
+  }
+
+  private void transformPath()
+  {
+    final Path newPath = new Path(getProject());
+    log("Updating bundle paths in class path reference '"
+        +classPathRef.getRefId() +"'.", Project.MSG_DEBUG);
+
+    String[] pathElements = null;
+    try {
+      final Path path = (Path) classPathRef.getReferencedObject();
+      pathElements = path.list();
+    } catch (final BuildException e) {
+      // Unsatisfied ref in the given path; can not expand.
+      // Make the new path a reference to the old one.
+      log("Unresolvable reference in '" +classPathRef.getRefId()
+          +"' can not expand bundle names in it.", Project.MSG_WARN);
+      newPath.setRefid(classPathRef);
+    }
+
+    if (null!=pathElements) {
+      for (final String pathElement2 : pathElements) {
+        final File pathElement = new File(pathElement2);
+        boolean added = false;
+        log("path element: "+pathElement, Project.MSG_DEBUG);
+        if (!pathElement.exists()) {
+          log("Found non existing path element: " +pathElement,
+              Project.MSG_DEBUG);
+          final String fileName = pathElement.getName();
+          final BundleArchives.BundleArchive ba = getBundleArchive(fileName);
+          if (ba!=null) {
+            final String filePath = ba.file.getAbsolutePath();
+            newPath.setPath(filePath);
+            added = true;
+            log(fileName +" => " +filePath, Project.MSG_VERBOSE);
+          } else if (isBundleNameWithWildcardVersion(fileName)) {
+            final int logLevel = failOnMissingBundles
+              ? Project.MSG_ERR : Project.MSG_INFO;
+            log("No match for '" +fileName +"' when expanding the path named '"
+                +classPathRef.getRefId() +"'.", logLevel);
+            log("Known bundles names: " +bas.getKnownNames(), logLevel);
+            if (failOnMissingBundles) {
+              throw new BuildException
+                ("No bundle with name like '" +fileName+"' found.");
+            }
+          } else {
+            log("No match for '" +fileName +"' when expanding the path named '"
+                +classPathRef.getRefId() +"'.", Project.MSG_VERBOSE);
+          }
+        }
+        if (!added) {
+          newPath.setPath(pathElement.getAbsolutePath());
+        }
+      }
+      log(newClassPathId +" = " +newPath, Project.MSG_VERBOSE);
+    }
+    getProject().addReference(newClassPathId, newPath);
+  } // end of transform path structure.
+
+
+  private void createPatternSet()
+  {
+    final PatternSet patternSet = new PatternSet();
+
+    log("Creating a patternset for the bundles with id='" +patternSetId +"'.",
+        Project.MSG_DEBUG);
+
+    for (final Object element : bas.allBundleArchives) {
+      final BundleArchives.BundleArchive ba
+        = (BundleArchives.BundleArchive) element;
+
+      patternSet.setIncludes(ba.relPath);
+      log("Adding includes '" +ba.relPath +"'.", Project.MSG_DEBUG);
+    }
+    getProject().addReference(patternSetId, patternSet);
+  } // end of create pattern set for bundles
+
+
+  /**
+   * Get the set of version patterns (partial versions) used in the
+   * keys in replacement filters for the given version.
+   * @param version The version to create patterns for.
+   * @return Set of version patterns.
+   */
+  private static String[] getVersionPatterns(Version version)
+  {
+    if (null==version) {
+      return new String[]{"-N.N.N"};
+    }
+
+    final String qualifier = version.getQualifier();
+    final boolean usesQualifier = null != qualifier && qualifier.length() > 0;
+    final String[] res = new String[usesQualifier ? 5 : 4];
+
+    res[0] = "-N.N.N";
+    res[1] = "-" +version.getMajor() +".N.N";
+    res[2] = "-" +version.getMajor() +"." +version.getMinor() +".N";
+    res[3] = "-" +version.getMajor() +"." +version.getMinor()
+      +"." +version.getMicro();
+    if (usesQualifier) {
+      res[4] = "-" +version.getMajor() +"." +version.getMinor()
+        +"." +version.getMicro() +"." +version.getQualifier();
+    }
+
+    return res;
+  }
+
+  private void writeReplaceFilterFile()
+  {
+    final Properties props = new Properties();
+    for (final Object element : bas.allBundleArchives) {
+      final BundleArchives.BundleArchive ba
+        = (BundleArchives.BundleArchive) element;
+      //Note: since the path is an URL we must ensure that '/' is used.
+      final String relPath = ba.relPath.replace('\\','/');
+      final String[] versPatterns = getVersionPatterns(ba.version);
+
+      if (null!=ba.bsn) {
+        props.put("@" +ba.bsn +".jar@", relPath);
+        if (extendedReplaceFilter) {
+          props.put("@" +ba.bsn +".location@", ba.file.getAbsolutePath());
+          props.put("@" +ba.bsn +".name@", ba.bsn);
+          props.put("@" +ba.bsn +".version@", ba.version.toString());
+        }
+        for (final String versPattern : versPatterns) {
+          final String prefix = "@" +ba.bsn +versPattern;
+          props.put(prefix +".jar@", relPath);
+          if (extendedReplaceFilter) {
+            props.put(prefix +".location@", ba.file.getAbsolutePath());
+            props.put(prefix +".name@", ba.bsn);
+            props.put(prefix +".version@", ba.version.toString());
+          }
+        }
+      }
+
+      if (null!=ba.bundleName) {
+        for (final String versPattern : versPatterns) {
+          final String prefix = "@" +ba.bundleName +versPattern;
+          props.put(prefix +".jar@", relPath);
+          if (extendedReplaceFilter) {
+            props.put(prefix +".location@", ba.file.getAbsolutePath());
+            if (null!=ba.bsn) {
+              props.put(prefix +".name@", ba.bsn);
+            }
+            props.put(prefix +".version@", ba.version.toString());
+          }
+        }
+      }
+    }
+    OutputStream out = null;
+    try {
+      out= new FileOutputStream(replacefilterfile);
+      props.store(out, "Bundle Version Expansion Mapping");
+    } catch (final IOException ioe) {
+      log("Failed to write replacefilterfile, "+replacefilterfile
+          +", reason: "+ioe,
+          Project.MSG_ERR);
+      throw new BuildException("Failed to write replacefilterfile",ioe);
+    } finally {
+      if (null!=out) {
+        try { out.close(); } catch (final IOException _ioe) {}
+        log("Created: "+replacefilterfile, Project.MSG_VERBOSE);
+      }
+    }
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleManifestTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleManifestTask.java
new file mode 100644
index 0000000..9f9ff91
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleManifestTask.java
@@ -0,0 +1,1119 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Manifest;
+import org.apache.tools.ant.taskdefs.ManifestException;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+import org.osgi.framework.Constants;
+
+import org.knopflerfish.ant.taskdefs.bundle.Util.HeaderEntry;
+
+
+/**
+ * Extension of the standard Manifest task.
+ * <p>
+ * This task builds a manifest file from three different sources:
+ * <ol>
+ *   <li>A template manifest file.
+ *   <li>Project properties with given prefix.
+ *   <li>Nested attribute and section data.
+ * </ol>
+ * It may also be used to create properties (with a given prefix) for
+ * each main section attribute in the template manifest file.
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">file</td>
+ *    <td valign="top">the manifest-file to create.</td>
+ *    <td valign="top" align="center">
+ *      Yes if "attributePropertyPrefix" is empty, otherwise No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">encoding</td>
+ *    <td valign="top">
+ *      The encoding used to read the existing manifest when updating.</td>
+ *    <td valign="top" align="center">No, defaults to UTF-8 encoding.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">mode</td>
+ *    <td valign="top">
+ *      One of "update", "replace", "template" and "templateOnly"
+ *      default is "replace".
+ *      <p>
+ *      The "mode" determines which sources to use when creating the
+ *      resulting manifest:
+ *      <dl>
+ *       <dt><code>replace</code> <dd>Use properties and nested data.
+ *       <dt><code>update</code>  <dd>Use template, properties and nested data.
+ *       <dt><code>template</code><dd>Use template and nested data.
+ *       <dt><code>templateOnly</code><dd>Use template.
+ *      </dl>
+ *    </td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">templateFile</td>
+ *    <td valign="top">the template manifest file to load.</td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">attributePropertyPrefix</td>
+ *    <td valign="top">If set and a template file is given but no file
+ *                     to write to export all attributes
+ *                     from the main section of the template file as
+ *                     properties.
+ *                     <p>
+ *                     If set and mode is one of "update", "replace"
+ *                     then create main section attributes for all
+ *                     project properties that starts with the prefix.
+ *                     <p>
+ *                     If set and "file" is given then export all attributes
+ *                     written to the main section as properties.
+ *                     <p>
+ *                     The name of property that maps to a main
+ *                     section attribute is the value of
+ *                     "attributePropertyPrefix" followed by the
+ *                     attribute name. The value is the attribute value.
+ *    </td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">kind</td>
+ *    <td valign="top">The kind of bundle that the manifest is for.
+ *                     <p>
+ *                     If given this string will be appended to the
+ *                     following manifest attributes of the main section:
+ *                     <ul>
+ *                       <li>Bundle-Name
+ *                       <li>Bundle-SymbolicName
+ *                       <li>Bundle-UUID
+ *                       <li>Bundle-Description
+ *                       <li>Bundle-Category  (only for kind="api").
+ *                    </ul>
+ *                    All main section manifest attribute starting
+ *                    with "kind-" will be replaced with a main section
+ *                    attribute without the prefix. E.g., if kind="api"
+ *                    and there is an attribute named "api-Export-Package"
+ *                    then it will be renamed to "Export-Package", overriding
+ *                    any previous definition of "Export-Package".
+ *    </td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">allKinds</td>
+ *    <td valign="top">A comma separated list specifying all kinds.
+ *                     <p>
+ *                     If given all main section attributes starting with
+ *                     any of the kinds in <code>allKinds</code> will
+ *                     be removed after the specified kind has been used to
+ *                     override attributes. E.g., if <code>kind="all"</code>
+ *                     and <code>allKinds="api,all"</code> and there is
+ *                     an attribute named <code>"api-Export-Package"</code>
+ *                     then that attribute will be removed from the
+ *                     resulting manifest.
+ *    </td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">mainAttributesToSkip</td>
+ *    <td valign="top">Comma separated list with names of main section
+ *                     attributes to weed out when writing the
+ *                     manifest file.
+ *    </td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">replaceEEmin</td>
+ *    <td valign="top">Replace the filter part of any osgi.ee requirement
+ *                     for the OSGi/Minimum EE with the given value.
+ *                     E.g., <code>replaceEEmin="(&(osgi.ee=JavaSE)(version>=1.7))"</code>
+ *                     will replace any filter matching 'OSGi/Minimum'
+ *                     in the osgi.ee name space with the given filter expression.
+ *    </td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">verbose</td>
+ *    <td valign="top">If set to "true" then log the name of the
+ *                     bundle activator together with the imported
+ *                     and exported packages</td>
+ *    <td valign="top" align="center">No.</td>
+ *  </tr>
+ * </table>
+ *
+ * <h3>Nested elements</h3>
+ *
+ * <h4><a name="attribute">attribute</h4></h4>
+ * <p>One attribute for the manifest file.  Those attributes that are
+ * not nested into a section will be added to the "Main" section.</p>
+ * <table border="1" cellpadding="2" cellspacing="0">
+ *   <tr>
+ *     <td valign="top"><b>Attribute</b></td>
+ *     <td valign="top"><b>Description</b></td>
+ *     <td align="center" valign="top"><b>Required</b></td>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top">name</td>
+ *     <td valign="top">the name of the attribute.</td>
+ *     <td valign="top" align="center">Yes</td>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top">value</td>
+ *     <td valign="top">the value of the attribute.</td>
+ *     <td valign="top" align="center">Yes</td>
+ *   </tr>
+ * </table>
+ *
+ *
+ * <h4>section</h4>
+ * <p>A manifest section - you can nest <a
+ *  href="#attribute">attribute</a> elements into sections.</p>
+ *
+ * <table border="1" cellpadding="2" cellspacing="0">
+ *   <tr>
+ *     <td valign="top"><b>Attribute</b></td>
+ *     <td valign="top"><b>Description</b></td>
+ *     <td align="center" valign="top"><b>Required</b></td>
+ *   </tr>
+ *   <tr>
+ *     <td valign="top">name</td>
+ *     <td valign="top">the name of the section.</td>
+ *     <td valign="top" align="center">No, if omitted it will be assumed
+ *        to be the main section.</td>
+ *   </tr>
+ * </table>
+ *
+ * <h3>Examples</h3>
+ *
+ * <h4>Build bundle manifest for the impl jar</h4>
+ *
+ * <pre>
+ *  <bundlemanifest mode="template"
+ *                  kind="impl"
+ *                  mainAttributesToSkip="Export-Package"
+ *                  attributePropertyPrefix="bmfa."
+ *                  templateFile="bundle.manifest"
+ *                  verbose="true"
+ *                  file="${outdir}/impl.mf">
+ *     <attribute name="Build-Date"       value="${bundle.date}"/>
+ *     <attribute name="Built-From"       value="${proj.dir}"/>
+ *   </bundlemanifest>
+ * </pre>
+ *
+ *
+ * <h4>Create properties for main section attributes in the template
+ * manifest file</h4>
+ *
+ * <pre>
+ *   <bundlemanifest mode="template"
+ *                   attributePropertyPrefix = "bmfa."
+ *                   templateFile="bundle.manifest">
+ *   </bundlemanifest>
+ * </pre>
+ *
+ */
+public class BundleManifestTask extends Task {
+  /**
+   * Default constructor.
+   */
+  public BundleManifestTask() {
+    super();
+    mode = new Mode();
+    mode.setValue("replace");
+   }
+
+  /**
+   * Helper class for bundle manifest's mode attribute.
+   */
+  public static class Mode extends EnumeratedAttribute {
+    /**
+     * Get Allowed values for the mode attribute.
+     *
+     * @return a String array of the allowed values.
+     */
+    @Override
+    public String[] getValues() {
+      return new String[] {"update", "replace", "template", "templateOnly"};
+    }
+  }
+
+  /**
+   * The mode with which the manifest file is written
+   */
+  private Mode mode;
+
+  /**
+   * The encoding of the manifest template file.
+   */
+  private String encoding;
+
+  /**
+   * Comma separated list of names of attributes that must not be
+   * present in the main section of the resulting manifest.
+   */
+  private String mainAttributesToSkip;
+
+  /**
+   * The kind of bundle to generate manifest for.
+   * If given this string will be appended to the following manifest
+   * attributes of the main section:
+   * <ul>
+   *   <li>Bundle-Name
+   *   <li>Bundle-SymbolicName
+   *   <li>Bundle-UUID
+   * </ul>
+   */
+  private String bundleKind;
+
+  /**
+   * All known kinds of bundles. Used to remove unused kind specific main
+   * section manifest attributes.
+   */
+  private final Set<String> allBundleKinds = new HashSet<String>();
+
+  /**
+   * Prefix of project properties to add main section attributes for.
+   *
+   * For each property in the project with a name that starts with this
+   * prefix a manifest attribute in the main section will be created.
+   * The attribute name will be the property name without the prefix
+   * and the attribute value will be the property value.
+   */
+  private String attributePropertyPrefix;
+
+
+  /**
+   * The manifest template file.
+   */
+  private File manifestTemplateFile;
+
+  /**
+   * The manifest file to create.
+   */
+  private File manifestFile;
+
+  /**
+   * Holds explicit manifest data given in the build file.
+   */
+  private final Manifest manifestNested = new Manifest();
+
+  /**
+   * The encoding to use for reading in the manifest template file.
+   * Default encoding is UTF-8.
+   *
+   * @param encoding the manifest template file encoding.
+   */
+  public void setEncoding(String encoding) {
+    this.encoding = encoding;
+  }
+
+  /**
+   * The name of the template manifest file.
+   *
+   * @param f the template manifest file to load.
+   */
+  public void setTemplateFile(File f) {
+    manifestTemplateFile = f;
+  }
+
+  /**
+   * The name of the manifest file to create.
+   *
+   * @param f the manifest file to write.
+   */
+  public void setFile(File f) {
+    manifestFile = f;
+  }
+
+  /**
+   * Which sources to use when creating the resulting manifest.
+   * <dl>
+   *   <dt><code>replace</code>  <dd>Use properties and nested data.
+   *   <dt><code>update</code>   <dd>Use template, properties and nested data.
+   *   <dt><code>template</code> <dd>Use template and nested data.
+   *   <dt><code>templateOnly</code><dd>Use template.
+   * </dl>
+   * @param m the mode value one of - <code>update</code>,
+   *          <code>replace</code>, <code>template</code> and
+   *          <code>templateOnly</code>.
+   */
+  public void setMode(Mode m) {
+    mode = m;
+  }
+
+  /**
+   * Comma separated list of attributes to skip from the main section.
+   * @param s main section attributes to skip from out put.
+   */
+  public void setMainAttributesToSkip(String s) {
+    mainAttributesToSkip = s.trim();
+  }
+
+  /**
+   * Bundle kind, will be appended to some of the bundle specific
+   * attributes in the main section.
+   * @param s the kind of bundle that we are writing a manifest file for.
+   */
+  public void setKind(String s) {
+    bundleKind = s.trim();
+  }
+
+
+  /**
+   * Comma separated list of known bundle kinds. Any main section attribute
+   * starting with one of the known kind values will be removed from the
+   * resulting manifest after processing of kind specific overrides.
+   *
+   * @param s
+   *          Comma separated list of bundle kinds.
+   */
+  public void setAllKinds(String s)
+  {
+    if (s != null && (s = s.trim()).length() > 0) {
+      final StringTokenizer st = new StringTokenizer(s, ",");
+      while (st.hasMoreTokens()) {
+        final String kind = st.nextToken();
+        allBundleKinds.add(kind.trim());
+      }
+    } else {
+      allBundleKinds.clear();
+    }
+    log("All bundle kinds " + allBundleKinds + ".", Project.MSG_DEBUG);
+  }
+
+  /**
+   * The name of the OSGi/Minimum Execution Environment.
+   */
+  private final String OSGI_MINIMUM_EE_NAME = "OSGi/Minimum";
+
+  /**
+   * Replacement filter for the filter in required capabilities in the
+   * <code>osgi.ee</code> name-space that requires the OSGi/Minimum EE.
+   */
+  private String replaceEEmin;
+
+  /**
+   * Sets the replacement filter expression for required capabilities in the
+   * osgi.ee name-space that requires the OSGi/Minimum EE.
+   *
+   * @param s
+   */
+  public void setReplaceEEmin(String s)
+  {
+    if (s != null && (s = s.trim()).length() > 0) {
+      replaceEEmin = s;
+      log("replaceEEmin: '" + replaceEEmin + "'.", Project.MSG_DEBUG);
+    }
+  }
+
+  /**
+   * If set to true the bundle activator, export package and import
+   * package list in the written manifest will be printed on the
+   * console.
+   */
+  private boolean verbose = false;
+
+  /**
+   * Set the verbosity of this task.
+   * If set to true the bundle activator, export package and import
+   * package list in the written manifest will be printed on the
+   * console.
+   * @param b verbose or not.
+   */
+  public void setVerbose(boolean b) {
+    verbose = b;
+  }
+
+  private void doVerbose(Manifest mf)
+  {
+    if (verbose) {
+      final Manifest.Section   ms = mf.getMainSection();
+      doVerbose( ms, "Bundle-Activator", "activator");
+      doVerbose( ms, "Export-Package", "exports");
+      doVerbose( ms, "Import-Package", "imports");
+    }
+  }
+
+  private void doVerbose(Manifest.Section ms, String attrName, String heading)
+  {
+    final Manifest.Attribute ma = ms.getAttribute(attrName);
+    if (null!=ma) {
+      final String val = ma.getValue();
+      if (!isPropertyValueEmpty(val)) {
+        log( heading +" = "+val, Project.MSG_INFO);
+      }
+    }
+  }
+
+
+  /**
+   * Set the prefix of project properties to add main section
+   * attributes for.
+   *
+   * For each property in the project with a name that starts with this
+   * prefix a manifest attribute in the main section will be created.
+   * The attribute name will be the property name without the prefix
+   * and the attribute value will be the property value.
+   *
+   * @param s the property names prefix to check for.
+   */
+  public void setAttributePropertyPrefix( String s) {
+    attributePropertyPrefix = s;
+  }
+
+  /**
+   * If <code>attributePropertyPrefix</code> is set then iterate over
+   * all properties and add attributes to the main section of
+   * the given manifest for those properties that starts with the prefix.
+   *
+   * The name of the attribute will be the property name without the
+   * prefix and the value will be the property value.
+   *
+   * @param mf The manifest to add the property based attributes to.
+   */
+  private void addAttributesFromProperties(Manifest mf)
+  {
+    if (null!=attributePropertyPrefix) {
+      final int       prefixLength = attributePropertyPrefix.length();
+      final Project   project      = getProject();
+      final Manifest.Section mainS = mf.getMainSection();
+      @SuppressWarnings("unchecked")
+      final Hashtable<String,?> properties   = project.getProperties();
+      for (final Enumeration<String> pe = properties.keys(); pe.hasMoreElements();) {
+        final String key = pe.nextElement();
+        if (key.startsWith(attributePropertyPrefix)) {
+          final String attrName  = key.substring(prefixLength);
+          final String attrValue = (String) properties.get(key);
+          if(!BUNDLE_EMPTY_STRING.equals(attrValue)) {
+            Manifest.Attribute attr = mainS.getAttribute(attrName);
+            if (null!=attr) {
+              throw new BuildException
+                ( "Can not add main section attribute for property '"
+                  +key+"' with value '"+attrValue+"' since a "
+                  +"main section attribute with that name exists: '"
+                  +attr.getName() +": "+attr.getValue() +"'.",
+                  getLocation());
+            }
+            try {
+              attr = new Manifest.Attribute(attrName, attrValue);
+              mf.addConfiguredAttribute(attr);
+              log("from propety '" +attrName +": "+attrValue+"'.",
+                  Project.MSG_VERBOSE);
+            } catch (final ManifestException me) {
+              throw new BuildException
+                ( "Failed to add main section attribute for property '"
+                  +key+"' with value '"+attrValue+"'.\n"+me.getMessage(),
+                  me, getLocation());
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * We must ensure that the case used in attribute names when they
+   * are mapped to properties by
+   * <code>updatePropertiesFromMainSectionAttributeValues()</code> are
+   * the same as the one used in the build files, i.e., the one used
+   * in the OSGi specification. If not it may happen that a we get two
+   * properties defined for the same attribute (with different cases)
+   * if this happens there will be an error when adding back the
+   * properties to the generated manifest.  Thus we need a list of all
+   * OSGi specified attribute names in the case used in the
+   * specification.
+   */
+  private static final String[] osgiAttrNames = new String[]{
+    "Application-Icon",
+    "Bundle-APIVendor",
+    "Bundle-Activator",
+    "Bundle-Category",
+    "Bundle-Classpath",
+    "Bundle-Config",
+    "Bundle-ContactAddress",
+    "Bundle-Copyright",
+    "Bundle-Description",
+    "Bundle-DocURL",
+    "Bundle-Localization",
+    "Bundle-ManifestVersion",
+    "Bundle-Name",
+    "Bundle-NativeCode",
+    "Bundle-RequiredExecutionEnvironment",
+    "Bundle-SubversionURL",
+    "Bundle-SymbolicName",
+    "Bundle-UUID",
+    "Bundle-UpdateLocation",
+    "Bundle-Vendor",
+    "Bundle-Version",
+    "DynamicImport-Package",
+    "Export-Package",
+    "Export-Service",
+    "Fragment-Host",
+    "Import-Package",
+    "Import-Service",
+    "Require-Bundle",
+    "Service-Component",
+    };
+
+  /**
+   * Mapping from attribute key, all lower case, to attribute name
+   * with case according to the OSGi specification.
+   */
+  private static final Hashtable<String,String> osgiAttrNamesMap = new Hashtable<String, String>();
+  static {
+    for (final String osgiAttrName : osgiAttrNames) {
+      osgiAttrNamesMap.put(osgiAttrName.toLowerCase(), osgiAttrName);
+    }
+  }
+
+
+  /**
+   * If <code>attributePropertyPrefix</code> is set then iterate over
+   * all attributes in the main section and set the value for
+   * corresponding property to the value of that attribute.
+   *
+   * The name of the attribute will be the property name without the
+   * prefix and the value will be the property value.
+   */
+  private void updatePropertiesFromMainSectionAttributeValues(Manifest mf)
+  {
+    if (null!=attributePropertyPrefix) {
+      final Project   project      = getProject();
+      final Manifest.Section mainS = mf.getMainSection();
+      for (@SuppressWarnings("unchecked")
+      final Enumeration<String> ae = mainS.getAttributeKeys(); ae.hasMoreElements();) {
+        final String key = ae.nextElement();
+        final Manifest.Attribute attr = mainS.getAttribute(key);
+        // Ensure that the default case is used for OSGi specified attributes
+        final String propKey = attributePropertyPrefix
+          + (osgiAttrNamesMap.containsKey(key)
+             ? osgiAttrNamesMap.get(key) : attr.getName() );
+        final String propVal = attr.getValue();
+        log("setting '" +propKey +"'='"+propVal+"'.", Project.MSG_VERBOSE);
+        project.setProperty(propKey,propVal);
+      }
+    }
+  }
+
+  /**
+   * Replace all main section attributes that starts with the
+   * specified prefix with an attribute without that prefix,
+   * overriding any old definition.
+   * @param mf     The manifest to update
+   * @param prefix The prefix to match on.
+   */
+  private void overrideAttributes(Manifest mf, String prefix)
+  {
+    if (null!=prefix && 0<prefix.length()) {
+      final int       prefixLength = prefix.length();
+      final Manifest.Section mainS = mf.getMainSection();
+      final Vector<String> attrNames = new Vector<String>();
+      for (@SuppressWarnings("unchecked")
+      final Enumeration<String> ae = mainS.getAttributeKeys(); ae.hasMoreElements();) {
+        final String key = ae.nextElement();
+        final Manifest.Attribute attr = mainS.getAttribute(key);
+        final String attrName = attr.getName();
+        if (attrName.startsWith(prefix)) {
+          attrNames.add(attrName);
+        }
+      }
+      /* Must do the modification in a separate loop since it modifies
+       * the object that the enumeration above iterates over. */
+      for (final Object element : attrNames) {
+        final String attrName = (String) element;
+        final Manifest.Attribute attr = mainS.getAttribute(attrName);
+        final String attrVal = attr.getValue();
+        mainS.removeAttribute(attrName);
+        final String newAttrName = attrName.substring(prefixLength);
+        mainS.removeAttribute(newAttrName);
+        if (!isPropertyValueEmpty(attrVal)) {
+          try {
+            final Manifest.Attribute newAttr
+              = new Manifest.Attribute(newAttrName,attrVal);
+            mainS.addConfiguredAttribute(newAttr);
+            log("Overriding '" +newAttrName +"' with value of '"+attrName+"'.",
+                Project.MSG_VERBOSE);
+          } catch (final ManifestException me) {
+            throw new BuildException("overriding of '" +newAttrName
+                                     +"' failed: "+me,
+                                     me, getLocation());
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Remove all kind specific main section attributes.
+   *
+   * @param mf     The manifest to remove main section attributes from.
+   */
+  private void removeAttributesForOtherKinds(Manifest mf)
+  {
+    if (allBundleKinds.size() > 0) {
+      final Manifest.Section mainS = mf.getMainSection();
+
+      // Find all attributes to remove.
+      final Vector<String> attrNames = new Vector<String>();
+      for (@SuppressWarnings("unchecked")
+      final Enumeration<String> ae = mainS.getAttributeKeys(); ae
+          .hasMoreElements();) {
+        final String key = ae.nextElement();
+        final Manifest.Attribute attr = mainS.getAttribute(key);
+        final String attrName = attr.getName();
+        final int prefixEnd = attrName.indexOf('-');
+        if (prefixEnd > 0) {
+          final String prefix = attrName.substring(0, prefixEnd);
+          if (allBundleKinds.contains(prefix)) {
+            attrNames.add(attrName);
+          }
+        }
+      }
+      // Remove the attributes; must be done outside the loop above since
+      // removal modifies the collection that the loop iterates over.
+      for (final String attrName : attrNames) {
+        mainS.removeAttribute(attrName);
+        log("Removing kind specific attribute '" + attrName + "'.",
+            Project.MSG_VERBOSE);
+      }
+    }
+  }
+
+  /**
+   * If the manifest contains a capability requirement on osgi.ee for the
+   * OSGi/Minimum EE then replace the filter part of that requirement with the
+   * given replacement value.
+   *
+   * @param mf
+   *          The manifest to replace in.
+   */
+  private void replaceEEminmum(Manifest mf)
+  {
+    if (replaceEEmin != null) {
+      final Manifest.Section mainS = mf.getMainSection();
+      final Manifest.Attribute attr =
+        mainS.getAttribute(Constants.REQUIRE_CAPABILITY);
+      if (attr != null) {
+        final String reqCapValue = attr.getValue();
+        if (reqCapValue.contains(OSGI_MINIMUM_EE_NAME)) {
+          log("Found '" + Constants.REQUIRE_CAPABILITY
+              + "' attribute with requirement on '" + OSGI_MINIMUM_EE_NAME
+              + "'.", Project.MSG_DEBUG);
+
+          // Must replace...
+          final List<HeaderEntry> hes =
+            Util.parseManifestHeader(Constants.REQUIRE_CAPABILITY, reqCapValue,
+                                     true, true, false);
+          for (final HeaderEntry he : hes) {
+            log("Processing header entry '" + he.getKey()
+                    + "' with attributes " + he.getAttributes()
+                    + " and directives " + he.getDirectives() + ".",
+                Project.MSG_DEBUG);
+            for (final Entry<String, String> directiveEntry : he
+                .getDirectives().entrySet()) {
+              if ("osgi.ee".equals(he.getKey())
+                  && "filter".equals(directiveEntry.getKey())
+                  && directiveEntry.getValue().contains(OSGI_MINIMUM_EE_NAME)) {
+                log("Replacing filter '" + directiveEntry.getValue()
+                        + "' with '" + replaceEEmin + "' in '" + reqCapValue
+                        + "'.", Project.MSG_VERBOSE);
+                directiveEntry.setValue(replaceEEmin);
+                break;
+              }
+            }
+          }
+          attr.setValue(Util.toString(hes));
+        }
+      }
+    }
+  }
+
+  /**
+   * Add a section to the manifest.
+   *
+   * @param section the manifest section to be added.
+   *
+   * @exception ManifestException if the section is not valid.
+   */
+  public void addConfiguredSection(Manifest.Section section)
+    throws ManifestException {
+    manifestNested.addConfiguredSection(section);
+  }
+
+  /**
+   * Special value used to indicate that a Manifest.Attribute with
+   * this value shall be weeded out. I.e., not added to the manifest.
+   * This value is used as the default value for properties that maps
+   * to bundle manifest attributes via the attributePropertyPrefix.
+   */
+  static protected final String BUNDLE_EMPTY_STRING = "[bundle.emptystring]";
+
+  /**
+   * Check if a property value is empty or not.
+   *
+   * The value is empty if it is <code>null</code>, the empty string
+   * or the special value BundleManifestTask.BUNDLE_EMPTY_STRING.
+   *
+   * @param pval The property value to check.
+   * @return <code>true</code> if the value is empty.
+   */
+  static protected boolean isPropertyValueEmpty( String pval ) {
+     return null==pval || "".equals(pval) || BUNDLE_EMPTY_STRING.equals(pval);
+  }
+
+
+  /**
+   * Add an attribute to the main section of the manifest.
+   * Attributes with the value BUNDLE_EMPTY_STRING are not added.
+   *
+   * @param attribute the attribute to be added.
+   *
+   * @exception ManifestException if the attribute is not valid.
+   */
+  public void addConfiguredAttribute(Manifest.Attribute attribute)
+    throws ManifestException {
+    if(BUNDLE_EMPTY_STRING.equals(attribute.getValue())) {
+      return;
+    }
+    manifestNested.addConfiguredAttribute(attribute);
+  }
+
+  /**
+   * Ensure that the named main section attribute ends with the
+   * specified suffix.
+   * @param mf       The manifest object to work with.
+   * @param attrName The name of the attribute to check / update.
+   * @param suffix   The required suffix.
+   */
+  private void ensureAttrEndsWith(final Manifest mf,
+                                  final String attrName,
+                                  final String suffix){
+    final Manifest.Attribute attr = mf.getMainSection().getAttribute(attrName);
+    if (null!=attr) {
+      final String rhs = attr.getValue();
+      if (!rhs.endsWith(suffix)) {
+        attr.setValue( rhs +suffix );
+      }
+    }
+  }
+
+  /**
+   * Ensure that the first value of the named main section attribute
+   * ends with the specified suffix.
+   *
+   * @param mf       The manifest object to work with.
+   * @param attrName The name of the attribute to check / update.
+   * @param suffix   The required suffix.
+   */
+  private void ensureAttrFirstValueEndsWith(final Manifest mf,
+                                            final String attrName,
+                                            final String suffix)
+  {
+    final Manifest.Attribute attr = mf.getMainSection().getAttribute(attrName);
+    if (null != attr) {
+      final String rhs = attr.getValue();
+      if (rhs != null && 0 < rhs.length()) {
+        final int semiPos = rhs.indexOf(';');
+        if (0 < semiPos) {
+          // Found manifest attribute with parameter(s) or directive(s)
+          final String firstValue = rhs.substring(0, semiPos).trim();
+          if (!firstValue.endsWith(suffix)) {
+            attr.setValue( firstValue + suffix + rhs.substring(semiPos));
+          }
+        } else {
+          if (!rhs.endsWith(suffix)) {
+            attr.setValue( rhs +suffix );
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Ensure that the named main section attribute have the given
+   * value.
+   * @param mf       The manifest object to work with.
+   * @param attrName The name of the attribute to check / update.
+   * @param value    The required attribute value.
+   */
+  private void ensureAttrValue(Manifest mf, String attrName, String value){
+    Manifest.Attribute ma = mf.getMainSection().getAttribute(attrName);
+    if (null==ma) {
+      ma = new Manifest.Attribute(attrName,value);
+      try {
+        mf.getMainSection().addConfiguredAttribute(ma);
+      } catch (final ManifestException me) {
+        throw new BuildException("ensureAttrValue("+attrName+","
+                                 +value +") failed.",
+                                 me, getLocation());
+      }
+    } else {
+      ma.setValue(value);
+    }
+  }
+
+
+  private final static String DOC_URL_PREFIX
+    = "http://www.knopflerfish.org/releases/current/";
+  private final static String SVN_URL_PREFIX
+    = "https://www.knopflerfish.org/svn/knopflerfish.org/trunk/";
+
+  /**
+   * If this is a distribution build (the
+   * <code>Knopflerfish-Version</code> attribute is present) then use
+   * the version number as replacement for:
+   * <ul>
+   *   <li>the <code>current</code>-part of a Bundle-DocURL
+   *       value that start with {@link #DOC_URL_PREFIX}.
+   *   <li>the <code>trunk</code>-part of a Bundle-SubversionURL
+   *       value that start with {@link #SVN_URL_PREFIX}.
+   * </ul>
+   */
+  private void replaceTrunkWithVersion(Manifest mf)
+  {
+    final Manifest.Attribute kfVerAttr
+      = mf.getMainSection().getAttribute("Knopflerfish-Version");
+    if (null!=kfVerAttr) {
+      final String version = kfVerAttr.getValue();
+      final boolean isSnapshot = -1<version.indexOf("snapshot");
+
+      final String toReplace   = "/releases/current/";
+      final String replacement = isSnapshot
+        ? "/snapshots/" +version +"/"
+        : ("/releases/" +version +"/");
+      final Manifest.Attribute docAttr
+        = mf.getMainSection().getAttribute("Bundle-DocURL");
+      if (null!=docAttr) {
+        final String docURL = docAttr.getValue();
+        if (docURL.startsWith(DOC_URL_PREFIX)) {
+          final int ix = DOC_URL_PREFIX.indexOf(toReplace);
+          final String newDocURL
+            = DOC_URL_PREFIX.substring(0,ix)
+            +replacement +docURL.substring(ix + toReplace.length());
+          docAttr.setValue(newDocURL);
+        }
+      }
+
+      if (!isSnapshot) {
+        final Manifest.Attribute svnAttr
+          = mf.getMainSection().getAttribute("Bundle-SubversionURL");
+        if (null!=svnAttr) {
+          final String svnURL = svnAttr.getValue();
+          if (svnURL.startsWith(SVN_URL_PREFIX)) {
+            final String newSvnURL
+              = SVN_URL_PREFIX.substring(0,SVN_URL_PREFIX.indexOf("trunk/"))
+              +"tags/" +version +svnURL.substring(SVN_URL_PREFIX.length()-1);
+            svnAttr.setValue(newSvnURL);
+          }
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Create or update the Manifest when used as a task.
+   *
+   * @throws BuildException if the manifest cannot be written.
+   */
+  @Override
+  public void execute() throws BuildException {
+    if (mode.getValue().equals("update") && manifestTemplateFile==null) {
+      throw new BuildException("the template file attribute is required"
+                               +" when mode is \"update\"");
+    }
+    if (mode.getValue().startsWith("template") && manifestTemplateFile==null) {
+      throw new BuildException("the template file attribute is required"
+                               +" when mode is \"" +mode.getValue() +"\"");
+    }
+
+
+    final Manifest manifestProps = new Manifest();
+    if (!mode.getValue().equals("templateOnly")) {
+      addAttributesFromProperties(manifestProps);
+    }
+
+    final Manifest manifestToWrite  = Manifest.getDefaultManifest();
+    Manifest manifestTemplate = null;
+
+    if (null!=manifestTemplateFile && manifestTemplateFile.exists()) {
+      FileInputStream   is = null;
+      InputStreamReader ir = null;
+      try {
+        is = new FileInputStream(manifestTemplateFile);
+        if (encoding == null) {
+          ir = new InputStreamReader(is, "UTF-8");
+        } else {
+          ir = new InputStreamReader(is, encoding);
+        }
+        manifestTemplate = new Manifest(ir);
+      } catch (final ManifestException me) {
+        throw new BuildException("Template manifest " + manifestTemplateFile
+                                 + " is invalid. " + me.getMessage(),
+                                 me, getLocation());
+      } catch (final IOException ioe) {
+        throw new BuildException("Failed to read " + manifestTemplateFile,
+                                 ioe, getLocation());
+      } finally {
+        if (ir != null) {
+          try {
+            ir.close();
+          } catch (final IOException e) {
+            // ignore
+          }
+        }
+      }
+    }
+
+    try {
+      if (mode.getValue().equals("update")) {
+        // Resulting manifest based on data from
+        // template file + manifest properties + nested data
+        if (manifestTemplate != null) {
+          manifestToWrite.merge(manifestTemplate);
+        }
+        manifestToWrite.merge(manifestProps);
+        manifestToWrite.merge(manifestNested);
+        log("Creating bundle manifets based on '"
+            +manifestTemplateFile
+            +"' merged with data from"
+            +" manifest properties and nested elements.",
+            manifestFile==null ? Project.MSG_DEBUG: Project.MSG_VERBOSE);
+      }
+      if (mode.getValue().equals("replace")) {
+        // Resulting manifest based on properties and nested data
+        manifestToWrite.merge(manifestProps);
+        manifestToWrite.merge(manifestNested);
+        log("Creating bundle manifets based on data from"
+            +" properties and nested elements.",
+            manifestFile==null ? Project.MSG_DEBUG: Project.MSG_VERBOSE);
+      }
+      if (mode.getValue().startsWith("template")) {
+        // Resulting manifest based on template and nested data.
+        if (manifestTemplate != null) {
+          manifestToWrite.merge(manifestTemplate);
+        }
+        if (!mode.getValue().equals("templateOnly")) {
+          manifestToWrite.merge(manifestNested);
+          log("Creating bundle manifets based on '" +manifestTemplateFile
+              +"' and nested elements.",
+              manifestFile==null ? Project.MSG_DEBUG: Project.MSG_VERBOSE);
+        } else {
+          log("Creating bundle manifets based on '" +manifestTemplateFile
+              +"'.",
+              manifestFile==null ? Project.MSG_DEBUG: Project.MSG_VERBOSE);
+        }
+      }
+    } catch (final ManifestException me) {
+      throw new BuildException("Manifest is invalid", me, getLocation());
+    }
+
+    if (null!=mainAttributesToSkip && 0<mainAttributesToSkip.length()) {
+      final StringTokenizer st = new StringTokenizer(mainAttributesToSkip,",");
+      while(st.hasMoreTokens()) {
+        final String attrName = st.nextToken();
+        log("Weeding out '"+attrName+"'.", Project.MSG_VERBOSE);
+        manifestToWrite.getMainSection().removeAttribute(attrName);
+      }
+    }
+
+    if (null!=bundleKind && 0<bundleKind.length()) {
+      final String kindUC = bundleKind.toUpperCase();
+      final String kindLC = bundleKind.toLowerCase();
+      final String suffix = "-"+kindUC;
+      ensureAttrEndsWith( manifestToWrite, "Bundle-Name", suffix );
+      ensureAttrFirstValueEndsWith( manifestToWrite, "Bundle-SymbolicName",
+                                    suffix );
+      ensureAttrEndsWith( manifestToWrite, "Bundle-UUID", ":"+kindLC );
+      ensureAttrEndsWith( manifestToWrite,
+                          "Bundle-Description"," ("+kindUC+")" );
+      if ("API".equals(kindUC)) {
+        ensureAttrValue(manifestToWrite, "Bundle-Category", kindUC );
+      }
+      overrideAttributes(manifestToWrite, bundleKind+"-");
+    }
+
+    removeAttributesForOtherKinds(manifestToWrite);
+    replaceEEminmum(manifestToWrite);
+    replaceTrunkWithVersion(manifestToWrite);
+
+    if (null==manifestFile) {
+      updatePropertiesFromMainSectionAttributeValues(manifestToWrite);
+    } else {
+      PrintWriter pw = null;
+      try {
+        final FileOutputStream   os = new FileOutputStream(manifestFile);
+        final OutputStreamWriter ow = new OutputStreamWriter(os, "UTF-8");
+        pw = new PrintWriter(ow);
+        manifestToWrite.write(pw);
+        doVerbose(manifestToWrite);
+      } catch (final IOException ioe) {
+        throw new BuildException("Failed to write " + manifestFile,
+                                 ioe, getLocation());
+      } finally {
+        if (pw != null) {
+          pw.close();
+        }
+      }
+    }
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleMvnAntTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleMvnAntTask.java
new file mode 100644
index 0000000..1c22402
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleMvnAntTask.java
@@ -0,0 +1,986 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+
+import org.osgi.framework.Version;
+
+import org.knopflerfish.ant.taskdefs.bundle.BundleArchives.BundleArchive;
+import org.knopflerfish.ant.taskdefs.bundle.Util.HeaderEntry;
+
+/**
+ * Task that analyzes a set of bundle jar files and builds an ant
+ * build file that can deploy those jar files to a Maven 2 repository.
+ *
+ * <p>
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ *
+ *  <tr>
+ *   <th valign=top><b>Attribute</b></th>
+ *   <th valign=top><b>Description</b></th>
+ *   <th valign=top><b>Required</b></th>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>templateAntFile</td>
+ *   <td valign=top>
+ *   Path to a template ant file for creating Maven 2 repositories.
+ *   </td>
+ *  </td>
+ *   <td valign=top>Yes.<br>No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>outDir</td>
+ *   <td valign=top>
+ *     Directory to write generated files to. I.e., the intermediate
+ *     build file and the dependency management file.
+ *   </td>
+ *   <td valign=top>Yes.<br>No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>buildFile</td>
+ *   <td valign=top>
+ *    Name of the intermediate ant build file that this task creates.
+ *   </td>
+ *   <td valign=top>Yes.<br>No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>dependencyManagementFile</td>
+ *   <td valign=top>
+ *     Name of the XML file with a
+ *     <dependencyManagement>-element describing all the
+ *     artifacts that will be created by the generated build file. The
+ *     file is written to the <code>outDir</code> by this task, then
+ *     copied to the directory for the default group id by the
+ *     generated intermediate build file.
+ *   </td>
+ *   <td valign=top>No.<br>No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>version</td>
+ *   <td valign=top>
+ *     Value of the version attribute on the root element of the
+ *     dependency management file.
+ *   </td>
+ *   <td valign=top>No.<br>No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>product</td>
+ *   <td valign=top>
+ *     Value to put into the product attribute on the root element of the
+ *     dependency management file.
+ *   </td>
+ *   <td valign=top>No.<br>Knopflerfish</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>repoDir</td>
+ *   <td valign=top>
+ *     The path to the root of the maven 2 repository to update with
+ *     the artefacts identified by this task.
+ *   </td>
+ *   <td valign=top>Yes.<br>No default value.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>groupId</td>
+ *   <td valign=top>
+ *     Maven group id to use for bundles, for which a group id can not
+ *     be derived from the bundles symbolic name.
+ *   </td>
+ *  </td>
+ *   <td valign=top>No.<br>Default 'org.knopflerfish'.</td>
+ *  </tr>
+ *
+ *  <tr>
+ *   <td valign=top>settingsFile</td>
+ *   <td valign=top>
+ *    The maven settings.xml file to use when loading pom-files.
+ *   </td>
+ *   <td valign=top>No.<br>No default value.</td>
+ *  </tr>
+ *
+ * </table>
+ *
+ * <h3>Parameters specified as nested elements</h3>
+ * <h4>fileset</h4>
+ *
+ * (required)<br>
+ * <p>
+ * All jar files selected by the fileset will be included.
+ * </p>
+ *
+ * <h3>Examples</h3>
+ *
+ * <pre>
+ * <bundlemvnant templateAntFile  = "${ant.dir}/ant_templates/toMvn.xml"
+ *                  repoDir          = "${distrib.mvn.repo.dir}"
+ *                  outDir           = "${root.out.dir}"
+ *                  buildFile        = "toMvn.xml"
+ *   >
+ *
+ *     <fileset dir="${release.dir}/osgi/jars">
+ *       <include name = "**/*.jar"/>
+ *     </fileset>
+ * </pre>
+ *
+ */
+public class BundleMvnAntTask extends Task {
+
+  private BundleArchives bas;
+
+  public BundleMvnAntTask() {
+  }
+
+
+  private String groupId = "org.knopflerfish";
+  public void setGroupId(final String s) {
+    this.groupId = s;
+  }
+
+  private File templateAntFile;
+  public void setTemplateAntFile(File f) {
+    templateAntFile = f;
+
+    if(!templateAntFile.exists()) {
+      throw new BuildException("templateAntFile: " + f + " does not exist");
+    }
+    if(!templateAntFile.isFile()) {
+      throw new BuildException("templateAntFile: " + f + " is not a file");
+    }
+  }
+
+  private File outDir;
+  public void setOutDir(File f) {
+    outDir = f;
+  }
+
+  private String buildFileName;
+  private File buildFile;
+  public void setBuildFile(String f) {
+    if(null==f || 0==f.length()) {
+      throw new BuildException("The attribute 'buildFile' must be non-null.");
+    }
+    buildFileName = f;
+  }
+
+  private String dependencyManagementFileName;
+  private File dependencyManagementFile;
+  public void setDependencyManagementFile(String f) {
+    if(null==f || 0==f.length()) {
+      throw new BuildException("The attribute 'dependencyManagementFile' must be non-null.");
+    }
+    dependencyManagementFileName = f;
+  }
+
+  private String version = "0.0.0";
+  public void setVersion(final String s) {
+    this.version = s;
+  }
+
+  private String product = "Knopflerfish";
+  public void setProduct(final String s) {
+    this.product = s;
+  }
+
+  private File repoDir;
+  public void setRepoDir(File f) {
+    repoDir = f;
+  }
+
+  private File settingsFile;
+  public void setSettingsFile(File f) {
+    if(null!=f && f.exists() && !f.canRead()) {
+      throw new BuildException("settingsFile: " + f
+                               + " exists but is not readable");
+    }
+    settingsFile = f;
+  }
+
+  private final List<ResourceCollection> rcs =
+    new ArrayList<ResourceCollection>();
+
+  public void addFileSet(FileSet fs)
+  {
+    rcs.add(fs);
+  }
+
+  // Implements Task
+  @Override
+  public void execute() throws BuildException {
+    if (null==outDir) {
+      throw new BuildException("Mandatory attribute 'outDir' missing.");
+    }
+    outDir.mkdirs();
+
+    if (null==buildFileName) {
+      throw new BuildException("Mandatory attribute 'buildFile' missing.");
+    }
+    buildFile = new File(outDir,buildFileName);
+
+    if (null==dependencyManagementFileName) {
+      throw new BuildException("Mandatory attribute 'dependencyManagementFile' missing.");
+    }
+    dependencyManagementFile = new File(outDir, dependencyManagementFileName);
+
+    if (null==repoDir) {
+      throw new BuildException("Mandatory attribute 'repoDir' missing.");
+    }
+
+    log("Loading bundle information:", Project.MSG_VERBOSE);
+    bas = new BundleArchives(this, rcs, true);
+    bas.doProviders();
+
+    try {
+      writeBuildFile();
+      writeDependencyManagementFile();
+    } catch (final Exception e) {
+      final String msg = "Failed to create ant build file: " +e;
+      log(msg, Project.MSG_ERR);
+      throw new BuildException(msg, e);
+    }
+
+  }
+
+  private void writeBuildFile()
+    throws IOException
+  {
+    log("Creating build file: " + buildFile, Project.MSG_VERBOSE);
+
+    final String prefix1 = "  ";
+    final String prefix2 = prefix1 + "  ";
+
+    final Document doc = FileUtil.loadXML(templateAntFile);
+    final Element project = doc.getDocumentElement();
+
+    setPropertyValue(project,"group.id", groupId);
+
+    setPropertyLocation(project,"ant.dir", getProject().getProperty("ant.dir"));
+    setPropertyLocation(project,"out.dir", outDir.getAbsolutePath());
+    setPropertyLocation(project,"mvn2.repo.dir", repoDir.getAbsolutePath());
+
+    // Path to the dependency managment file that this task will write.
+    setPropertyLocation(project, "dependency.management.file",
+                        dependencyManagementFile.getAbsolutePath());
+    // Path to the dependency managment file in the repository
+    File depMgmtRepoFile = new File(repoDir,
+                                    groupId.replace('.', File.separatorChar));
+    depMgmtRepoFile = new File(depMgmtRepoFile,
+                               dependencyManagementFile.getName());
+    setPropertyLocation(project, "dependency.management.repo.file",
+                        depMgmtRepoFile.getAbsolutePath());
+
+
+    final StringBuffer targetNames = new StringBuffer(2048);
+
+    for (final Entry<String,SortedSet<BundleArchive>> entry : bas.bsnToBundleArchives.entrySet()) {
+      final SortedSet<BundleArchive> bsnSet = entry.getValue();
+      // Sorted set with bundle archives, same bsn, different versions
+      for (final BundleArchive ba : bsnSet) {
+        final String targetName = ba.bsn + "-" + ba.version;
+        targetNames.append(",").append(targetName);
+
+        final Comment comment = doc.createComment(ba.relPath);
+        final Element target = doc.createElement("target");
+        target.setAttribute("name", targetName);
+
+        final Element mvnDeployBundle = doc.createElement("mvn_deploy_bundle");
+        target.appendChild(doc.createTextNode("\n"+prefix2));
+        target.appendChild(mvnDeployBundle);
+
+        mvnDeployBundle.setAttribute("projDirName", ba.projectName);
+        addMavenCoordinates(mvnDeployBundle, ba);
+        mvnDeployBundle.setAttribute("artifactName", ba.name);
+        mvnDeployBundle.setAttribute("artifactBundle", ba.file.getAbsolutePath());
+        mvnDeployBundle.setAttribute("packing", "jar");
+
+        // Optional attributes
+        final String description = ba.getBundleDescription();
+        if (null != description) {
+          mvnDeployBundle.setAttribute("description", description);
+        }
+
+        if (null!=settingsFile) {
+          mvnDeployBundle.setAttribute("settingsFile",
+                                       settingsFile.getAbsolutePath());
+        }
+
+        addLicense(mvnDeployBundle, ba, prefix2);
+        addDependencies(mvnDeployBundle, ba, prefix2);
+        addSourceAttachment(mvnDeployBundle, ba, prefix2);
+        addJavadocAttachment(mvnDeployBundle, ba, prefix2);
+
+        // Put the end of the target-element on a separate line
+        target.appendChild(doc.createTextNode("\n"+prefix1));
+
+        project.appendChild(doc.createTextNode("\n"+prefix1));
+        project.appendChild(comment);
+        project.appendChild(doc.createTextNode("\n"+prefix1));
+        project.appendChild(target);
+        project.appendChild(doc.createTextNode("\n"+prefix1));
+      }
+    }
+
+    setTargetAttr(project, "all", "depends", "init" +targetNames.toString());
+
+    FileUtil.writeDocumentToFile(buildFile, doc);
+    log("wrote " + buildFile, Project.MSG_VERBOSE);
+  }
+
+  private void writeDependencyManagementFile()
+    throws IOException
+  {
+    if (null==dependencyManagementFile) {
+      return;
+    }
+
+    log("Creating dependency management file: " + dependencyManagementFile,
+        Project.MSG_VERBOSE);
+
+    final String prefix1 = "  ";
+    final String prefix2 = prefix1 + "  ";
+    final String prefix3 = prefix2 + "  ";
+
+    final Document doc = FileUtil.createXML("KF");
+    final Element root = doc.getDocumentElement();
+
+    // Create and add the xml-stylesheet instruction
+    final ProcessingInstruction pi
+      = doc.createProcessingInstruction("xml-stylesheet",
+                                        "type='text/xsl' href='mvn_dep_mgmt.xsl'");
+    doc.insertBefore(pi, root);
+
+    root.setAttribute("version", version);
+    root.setAttribute("product", product);
+    root.appendChild(doc.createTextNode("\n"));
+
+    final Element dm = doc.createElement("dependencyManagement");
+    root.appendChild(dm);
+
+    // Element hodling extra presentation data for each bundle artifact
+    final Element bundles = doc.createElement("bundles");
+    root.appendChild(doc.createTextNode("\n"));
+    root.appendChild(bundles);
+
+
+    dm.appendChild(doc.createTextNode("\n"+prefix1));
+    final Element dependencies = doc.createElement("dependencies");
+    dm.appendChild(dependencies);
+
+    for (final Entry<String, SortedSet<BundleArchive>> entry : bas.bsnToBundleArchives.entrySet()) {
+      final SortedSet<BundleArchive> bsnSet = entry.getValue();
+      // Sorted set with bundle archives, same bsn, different versions
+      for (final BundleArchive ba : bsnSet) {
+        dependencies.appendChild(doc.createTextNode("\n\n" +prefix2));
+        dependencies.appendChild(doc.createComment(ba.relPath));
+        dependencies.appendChild(doc.createTextNode("\n" +prefix2));
+
+        final Element dependency = doc.createElement("dependency");
+        dependencies.appendChild(dependency);
+
+        // Dummy element to read mvn coordinates from
+        final Element coordinateEl = doc.createElement("dummy");
+        addMavenCoordinates(coordinateEl, ba);
+        addMavenCoordinates(coordinateEl, dependency, prefix3);
+
+        dependency.appendChild(doc.createTextNode("\n" +prefix2));
+
+        // Bundle metadata for xsl rendering
+        final Element bundle = doc.createElement("bundle");
+        bundles.appendChild(doc.createTextNode("\n" +prefix2));
+        bundles.appendChild(bundle);
+
+        bundle.appendChild(doc.createTextNode("\n" +prefix3));
+        final Element name = doc.createElement("name");
+        bundle.appendChild(name);
+        name.appendChild(doc.createTextNode(ba.name));
+        log("name: " +ba.name, Project.MSG_VERBOSE);
+
+        String description = ba.getBundleDescription();
+        log("description: " +description, Project.MSG_VERBOSE);
+        if (null==description) {
+          description = "";
+        }
+        bundle.appendChild(doc.createTextNode("\n" +prefix3));
+        final Element descrEl = doc.createElement("description");
+        bundle.appendChild(descrEl);
+        descrEl.appendChild(doc.createTextNode(description));
+
+        addMavenCoordinates(coordinateEl, bundle, prefix3);
+
+        bundle.appendChild(doc.createTextNode("\n" +prefix3));
+        String mvnPath = getMavenPath(coordinateEl);
+        final String groupIdPath = groupId.replace('.','/');
+        if (mvnPath.startsWith(groupIdPath)) {
+          mvnPath = mvnPath.substring(groupIdPath.length()+1);
+        } else {
+          // Add one "../" to mvnPath for each level in the groupId
+          mvnPath = "../" +mvnPath;
+          int sPos = groupIdPath.indexOf('/');
+          while (-1<sPos) {
+            mvnPath = "../" +mvnPath;
+            sPos = groupIdPath.indexOf('/', sPos+1);
+          }
+        }
+        final Element url = doc.createElement("url");
+        bundle.appendChild(url);
+        log("mvnPath: " +mvnPath, Project.MSG_VERBOSE);
+        url.appendChild(doc.createTextNode(mvnPath));
+
+        bundle.appendChild(doc.createTextNode("\n" +prefix2));
+      }
+    }
+    dependencies.appendChild(doc.createTextNode("\n" +prefix1));
+    bundles.appendChild(doc.createTextNode("\n" +prefix1));
+    dm.appendChild(doc.createTextNode("\n"));
+    root.appendChild(doc.createTextNode("\n"));
+
+    FileUtil.writeDocumentToFile(dependencyManagementFile, doc);
+    log("wrote " + dependencyManagementFile, Project.MSG_VERBOSE);
+  }
+
+  /**
+   * Set the value of the named ant property. The property must exist and be
+   * a child of the specified element.
+   *
+   * @param elem
+   *          The element owning the property element to update
+   * @param name
+   *          The name of the property to set location of.
+   * @param value
+   *          The new value.
+   */
+  private void setPropertyValue(final Element el,
+                                final String name,
+                                final String value) {
+    final NodeList propertyNL = el.getElementsByTagName("property");
+    boolean found = false;
+    for (int i = 0; i<propertyNL.getLength(); i++) {
+      final Element property = (Element) propertyNL.item(i);
+      if (name.equals(property.getAttribute("name"))) {
+        log("Setting <property name=\"" +name +"\" value=\"" +value +"\" ...>.", Project.MSG_DEBUG);
+        property.setAttribute("value", value);
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      throw new BuildException("No <property name=\"" +name +"\" ...> in XML document " +el);
+    }
+  }
+
+  /**
+   * Set the location of the named ant property. The property must exist and be
+   * a child of the specified element.
+   *
+   * @param elem
+   *          The element owning the property element to update
+   * @param name
+   *          The name of the property to set location of.
+   * @param location
+   *          The new location value.
+   */
+  private void setPropertyLocation(final Element el, final String name, final String location) {
+    final NodeList propertyNL = el.getElementsByTagName("property");
+    boolean found = false;
+    for (int i = 0; i<propertyNL.getLength(); i++) {
+      final Element property = (Element) propertyNL.item(i);
+      if (name.equals(property.getAttribute("name"))) {
+        log("Setting <property name=\"" +name +"\" location=\"" +location +"\" ...>.", Project.MSG_DEBUG);
+        property.setAttribute("location", location);
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      throw new BuildException("No <property name=\"" +name +"\" ...> in XML document " +el);
+    }
+  }
+
+  /**
+   * Set an attribute on the named target element. The target element must exist
+   * and be a child of the project-element.
+   *
+   * @param el
+   *          The element owning the target element to be updated.
+   * @param name
+   *          The name of the target-element to set an attribute for.
+   * @param attrName
+   *          The name of the attribute to set.
+   * @param attrValue
+   *          The new attribute value.
+   */
+  private void setTargetAttr(final Element el, final String name, final String attrName, final String attrValue) {
+    final NodeList propertyNL = el.getElementsByTagName("target");
+    boolean found = false;
+    for (int i = 0; i<propertyNL.getLength(); i++) {
+      final Element target = (Element) propertyNL.item(i);
+      if (name.equals(target.getAttribute("name"))) {
+        log("Setting <target name=\"" +name +"\" attrName =\"" +attrValue +"\" ...>.", Project.MSG_DEBUG);
+        target.setAttribute(attrName, attrValue);
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      throw new BuildException("No <property name=\"" +name +"\" ...> in XML document " +el);
+    }
+  }
+
+  /**
+   * Add Maven coordinates as attributes for group id, artifact id and
+   * version to the given element.
+   *
+   * @param el
+   *          The element to add Maven coordinates to.
+   * @param ba
+   *          The bundle archive to defining the coordinates.
+   */
+  private void addMavenCoordinates(final Element el,
+                                   final BundleArchive ba)
+  {
+    final int ix = ba.bsn.lastIndexOf('.');
+    final String aId = -1==ix ? ba.bsn : ba.bsn.substring(ix+1);
+    final String gId = -1==ix ? (String) groupId : ba.bsn.substring(0,ix);
+    final Version v = ba.version;
+
+    if (null!=gId) {
+      el.setAttribute("groupId", gId);
+    }
+    el.setAttribute("artifactId", aId);
+    el.setAttribute("version", v.toString());
+  }
+
+  /**
+   * Add Maven coordinates specified as attributes on the first
+   * element as child elements to the second element.
+   *
+   * @param ela
+   *          The element with Maven coordinates as attributes.
+   * @param elc
+   *          The element to add Maven coordinates as childe nodes to.
+   */
+  private void addMavenCoordinates(final Element ela,
+                                   final Element elc,
+                                   final String prefix)
+  {
+    final Document doc = elc.getOwnerDocument();
+
+    elc.appendChild(doc.createTextNode("\n" +prefix));
+    final Element groupId = doc.createElement("groupId");
+    elc.appendChild(groupId);
+    groupId.appendChild(doc.createTextNode(ela.getAttribute("groupId")));
+
+    elc.appendChild(doc.createTextNode("\n" +prefix));
+    final Element artifactId = doc.createElement("artifactId");
+    elc.appendChild(artifactId);
+    artifactId.appendChild(doc.createTextNode(ela.getAttribute("artifactId")));
+
+    elc.appendChild(doc.createTextNode("\n" +prefix));
+    final Element version = doc.createElement("version");
+    elc.appendChild(version);
+    version.appendChild(doc.createTextNode(ela.getAttribute("version")));
+  }
+
+  /**
+   * Build the relative path to the bundle represented by the given
+   * maven coordinates.
+   *
+   * @param ela
+   *          An element with Maven coordinates as attributes.
+   *
+   * @return relative path from the root of the maven2 repository to
+   *         the bundle represented by the spceified coordinates.
+   */
+  private String getMavenPath(final Element ela)
+  {
+    final String path = ela.getAttribute("groupId").replace('.','/') +"/"
+      +ela.getAttribute("artifactId") +"/"
+      +ela.getAttribute("version")    +"/"
+      +ela.getAttribute("artifactId") +"-"
+      +ela.getAttribute("version")    +".jar";
+
+    return path;
+  }
+
+  /**
+   * Add licenses element for the given bundle to the string buffer.
+   *
+   * @param el
+   *          element to add the license element to.
+   * @param ba
+   *          The bundle archive to defining the coordinates.
+   * @param prefix
+   *          Whitespace to added before the owning element.
+   */
+  private void addLicense(final Element el, final BundleArchive ba, final String prefix)
+  {
+    final Element licenses = el.getOwnerDocument().createElement("licenses");
+    final String prefix1 = prefix + "  ";
+    final String prefix2 = prefix1 + "  ";
+
+    el.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix1));
+    el.appendChild(licenses);
+    el.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix));
+
+    boolean addDefault = true;
+
+    final List<HeaderEntry> licenseEntries = ba.getBundleLicense();
+    for (final HeaderEntry licenseEntry : licenseEntries) {
+      addDefault = false;
+      final Element license = el.getOwnerDocument().createElement("license");
+      license.setAttribute("name", licenseEntry.getKey());
+      licenses.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix2));
+      licenses.appendChild(license);
+
+      if (licenseEntry.getAttributes().containsKey("description")) {
+        license.setAttribute("comments", licenseEntry.getAttributes().get("description").toString());
+      }
+      if (licenseEntry.getAttributes().containsKey("link")) {
+        license.setAttribute("url", licenseEntry.getAttributes().get("link").toString());
+      }
+    }
+
+    if (addDefault) {
+      final Element license = el.getOwnerDocument().createElement("license");
+      license.setAttribute("name", "<<EXTERNAL>>");
+      licenses.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix2));
+      licenses.appendChild(license);
+    }
+    licenses.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix1));
+  }
+
+  /**
+   * Add dependencies element for the given bundle to the string buffer.
+   *
+   * @param el
+   *          element to add the dependencies to.
+   * @param ba
+   *          The bundle archive to defining the coordinates.
+   * @param prefix
+   *          Whitespace to add before the new element.
+   */
+  private void addDependencies(Element el, BundleArchive ba, String prefix)
+  {
+    final Element dependencies = el.getOwnerDocument().createElement("dependencies");
+    final String prefix1 = prefix + "  ";
+    final String prefix2 = prefix1 + "  ";
+
+    el.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix1));
+    el.appendChild(dependencies);
+    el.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix));
+
+    for (final Entry<BundleArchive,SortedSet<String>> depEntry : selectCtDeps(ba).entrySet()) {
+      final BundleArchives.BundleArchive depBa = depEntry.getKey();
+      final SortedSet<String> pkgNames = depEntry.getValue();
+
+      dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix2));
+      dependencies.appendChild(el.getOwnerDocument().createComment(pkgNames.toString()));
+
+      final Element dependency = el.getOwnerDocument().createElement("dependency");
+      addMavenCoordinates(dependency, depBa);
+      if (pkgNames.contains("org.osgi.framework")) {
+        dependency.setAttribute("scope", "provided");
+      }
+
+      dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix2));
+      dependencies.appendChild(dependency);
+      dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"));
+    }
+    dependencies.appendChild(el.getOwnerDocument().createTextNode("\n"+prefix1));
+
+    if (0<ba.pkgUnprovidedMap.size()) {
+      log("  Imports without any provider: " +ba.pkgUnprovidedMap,
+          Project.MSG_DEBUG);
+    }
+  }
+
+  /**
+   * Selects a subset of the compile time dependencies so that each
+   * package is only provided once.
+   *
+   * @param ba Bundle archive to select dependencies for.
+   */
+  private Map<BundleArchive,SortedSet<String>> selectCtDeps(final BundleArchives.BundleArchive ba)
+  {
+    log("Selecting dependencies for : "+ba, Project.MSG_VERBOSE);
+
+    // The total set of packages that are provided by the dependencies.
+    final TreeSet<String> pkgs = new TreeSet<String>();
+
+    // The sub-set of the dependency entries that are API-bundles.
+    final List<Entry<BundleArchive, SortedSet<String>>> depsApi =
+      new ArrayList<Entry<BundleArchive, SortedSet<String>>>();
+
+    // The sub-set of the dependency entries that are not API-bundles.
+    final List<Entry<BundleArchive, SortedSet<String>>> depsNonApi =
+      new ArrayList<Entry<BundleArchive, SortedSet<String>>>();
+
+    // The resulting collection of dependencies
+    final Map<BundleArchive,SortedSet<String>> res = new TreeMap<BundleArchive,SortedSet<String>>();
+
+    // Group providing bundles in to API-bundles and non-API-bundles
+    // and the set of packages provided by all providers.
+    for (final Entry<BundleArchive, SortedSet<String>> ctPEntry : ba.pkgCtProvidersMap.entrySet()) {
+      final BundleArchive ctBa = ctPEntry.getKey();
+      final SortedSet<String> ctPkgs = ctPEntry.getValue();
+
+      if (ctBa.isAPIBundle()) {
+        log("  APIbundle: "+ctBa +" provides "+ctPkgs, Project.MSG_DEBUG);
+        depsApi.add(ctPEntry);
+      } else {
+        log("  NonAPIbundle: "+ctBa +" provides "+ctPkgs, Project.MSG_DEBUG);
+        depsNonApi.add(ctPEntry);
+      }
+      pkgs.addAll(ctPkgs);
+    }
+
+    log("  Provided imported packages: "+pkgs, Project.MSG_VERBOSE);
+
+    final Comparator<Entry<BundleArchive, SortedSet<String>>> cmp = new ProvidesEntrySetComparator();
+    Collections.sort(depsApi, cmp);
+    Collections.sort(depsNonApi, cmp);
+
+    selectProviders(res, pkgs, depsApi);
+    selectProviders(res, pkgs, depsNonApi);
+
+    return res;
+  }
+
+
+  /**
+   * Add providing bundles from the <code>deps</code> list that
+   * provides at least one of the packages in <code>pkgs</code>. Try
+   * to avoid having multiple providers of the same package.
+   *
+   * @param res  The selected providers to make dependencies of.
+   * @param pkgs The set of packages that shall be provided by the
+   *             providers added to res.
+   * @param deps Provider bundles that are dependency candidates.
+   */
+  private void selectProviders(final Map<BundleArchive,SortedSet<String>> res,
+                               final Set<String> pkgs,
+                               final List<Entry<BundleArchive, SortedSet<String>>> deps)
+  {
+    // Iterate over dependency candidates that exports packages,
+    // Add bundles that contributes at least one package to res.
+    for (final Iterator<Entry<BundleArchive, SortedSet<String>>> itDeps = deps.iterator(); 0<pkgs.size() && itDeps.hasNext();){
+      final Entry<BundleArchive, SortedSet<String>> entry = itDeps.next();
+      final BundleArchives.BundleArchive ba = entry.getKey();
+      final SortedSet<String> pPkgs = entry.getValue();
+
+      log("  Trying provider: " +ba +": exporting " +pPkgs + " looking for: "
+          +pkgs, Project.MSG_DEBUG);
+
+      if (pkgs.removeAll(pPkgs)) {
+        // entry provides needed packages, add its bundle to the result.
+        log("  Selecting provider: " + ba + " exporting "+pPkgs,
+            Project.MSG_VERBOSE);
+
+        // Remove any provider that will not provide any unique
+        // package after the addition of ba.
+        for (final Iterator<Entry<BundleArchive, SortedSet<String>>> itRes = res.entrySet().iterator(); itRes.hasNext();) {
+          final Entry<BundleArchive, SortedSet<String>> resEntry = itRes.next();
+          final BundleArchives.BundleArchive resBa
+            = resEntry.getKey();
+          final SortedSet<String> resPkgs = resEntry.getValue();
+
+          if (pPkgs.containsAll(resPkgs)) {
+            log("  Removing redundant provider: "+resBa, Project.MSG_VERBOSE);
+            itRes.remove();
+          }
+        }
+        res.put(ba, pPkgs);
+      }
+    }
+  }
+
+  /**
+   * Add attachement element for the source artifact if present.
+   *
+   * <pre>
+   * <attach file="${basedir}/target/my-project-1.0-sources.jar"
+   *            type="jar"
+   *            classifier="sources">
+   * </pre>
+   *
+   * @param el
+   *          element to add the attachment to.
+   * @param ba
+   *          The bundle archive to add a source artifact for.
+   * @param prefix
+   *          Whitespace to add before the new element.
+   */
+  private void addSourceAttachment(final Element el,
+                                   final BundleArchive ba,
+                                   final String prefix)
+  {
+    String sourcePath = ba.file.getAbsolutePath();
+    // Remove ".jar" suffix.
+    sourcePath = sourcePath.substring(0,sourcePath.length()-4);
+    sourcePath = sourcePath +"-source.jar";
+    final File sourceFile = new File(sourcePath);
+
+    if (sourceFile.exists()) {
+      final Document doc = el.getOwnerDocument();
+      final String prefix1 = prefix + "  ";
+      final String prefix2 = prefix1 + "  ";
+      final Element sourceAttachment = doc.createElement("source-attachment");
+
+      el.appendChild(doc.createTextNode("\n"+prefix1));
+      el.appendChild(sourceAttachment);
+      el.appendChild(doc.createTextNode("\n"+prefix));
+
+      final Element attach = doc.createElement("attach");
+      sourceAttachment.appendChild(doc.createTextNode("\n"+prefix2));
+      sourceAttachment.appendChild(attach);
+      sourceAttachment.appendChild(doc.createTextNode("\n"+prefix1));
+
+      attach.setAttribute("file", sourcePath);
+      attach.setAttribute("type", "jar");
+      attach.setAttribute("classifier", "sources");
+    }
+  }
+
+
+  /**
+   * Add attachement element for the javadoc artifact if present.
+   *
+   * <pre>
+   *  <attach file="${basedir}/target/my-project-1.0-javadoc.jar"
+   *             type="jar"
+   *             classifier="javadoc"/>
+   * </pre>
+   *
+   * @param el
+   *          element to add the attachment to.
+   * @param ba
+   *          The bundle archive to add a source artifact for.
+   * @param prefix
+   *          Whitespace to add before the new element.
+   */
+  private void addJavadocAttachment(final Element el,
+                                    final BundleArchive ba,
+                                    final String prefix)
+  {
+    String javadocPath = ba.file.getAbsolutePath();
+    // Remove ".jar" suffix.
+    javadocPath = javadocPath.substring(0, javadocPath.length()-4);
+    javadocPath = javadocPath +"-javadoc.jar";
+
+    final File javadocFile = new File(javadocPath);
+    if (javadocFile.exists()) {
+      final Document doc = el.getOwnerDocument();
+      final String prefix1 = prefix + "  ";
+      final String prefix2 = prefix1 + "  ";
+      final Element javadocAttachment = doc.createElement("javadoc-attachment");
+
+      el.appendChild(doc.createTextNode("\n"+prefix1));
+      el.appendChild(javadocAttachment);
+      el.appendChild(doc.createTextNode("\n"+prefix));
+
+      final Element attach = doc.createElement("attach");
+      javadocAttachment.appendChild(doc.createTextNode("\n"+prefix2));
+      javadocAttachment.appendChild(attach);
+      javadocAttachment.appendChild(doc.createTextNode("\n"+prefix1));
+
+      attach.setAttribute("file", javadocPath);
+      attach.setAttribute("type", "jar");
+      attach.setAttribute("classifier", "javadoc");
+    }
+  }
+
+
+  /**
+   * Sort map entries that consists of a bundle archive as key and a
+   * set as value in increasing order based on the size of the set and
+   * if equal the natural order of the bundle archives.
+   */
+  static class ProvidesEntrySetComparator
+    implements Comparator<Entry<BundleArchive, SortedSet<String>>>
+  {
+    @Override
+    public int compare(Entry<BundleArchive, SortedSet<String>> o1,
+                       Entry<BundleArchive, SortedSet<String>> o2)
+    {
+      final int res = o1.getValue().size() - o2.getValue().size();
+
+      return 0!=res ? res
+        : o1.getKey().compareTo(o2.getKey());
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+      return this==obj;
+    }
+
+  }
+
+  static String replace(String src, String a, String b) {
+    return Util.replace(src, a, b == null ? "" : b);
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundlePackagesInfo.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundlePackagesInfo.java
new file mode 100644
index 0000000..711182d
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundlePackagesInfo.java
@@ -0,0 +1,733 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+
+import org.osgi.framework.Version;
+
+/**
+ * Class that holds the results of the Java package analysis of all
+ * classes in a bundle.
+ * <p>
+ * Class and package names should use either '/' or '.' as separator
+ * between package levels during build up phase. When all classes
+ * packages have been added, make a call to {@link #toJavaNames()} to
+ * convert all class / packages names using the internal Java
+ * representation with '/' as separator to their non-internal
+ * representation with '.' as separator.
+ * Mixing of separator kinds is not supported!
+ * </p>
+ * <p>
+ * When all classes have been added, before using the package using
+ * map a call to {@link #postProcessUsingMap(Set,Set)} should be done.
+ * </p>
+ */
+public class BundlePackagesInfo {
+
+  /**
+   * Get package name of class string representation.
+   *
+   * @param className A fully qualified class name.
+   * @return The Java package name that the named class belongs
+   *         to. Will return the empty string if the named class does
+   *         not belong to any package.
+   */
+  public static String packageName(final String className) {
+    String s = className.trim();
+    int ix = s.lastIndexOf('/');
+    if(ix == -1) {
+      ix = s.lastIndexOf('.');
+    }
+    if (ix != -1) {
+      s = s.substring(0, ix);
+    } else {
+      s = "";
+    }
+    return s;
+  }
+
+
+  // The task using this object to provide logging functionality.
+  final Task task;
+
+  public BundlePackagesInfo(final Task task)
+  {
+    this.task   = task;
+  }
+
+  /**
+   * The set of classes provided by the bundle.
+   * The elements of the set are the fully qualified class name.
+   */
+  private final SortedSet/*<String>*/<String> providedClasses = new TreeSet<String>();
+
+
+  /**
+   * Adds a named class to the set of classes provided by this
+   * bundle.
+   *
+   * This method also adds the package of the class to the set of
+   * provided packages. It also add a reference to the class from its
+   * own package.
+   *
+   * @param className the name of the class to add.
+   * @return the name of the Java package that the given class belongs
+   * to.
+   */
+  public String addProvidedClass(final String className)
+  {
+    final String pkgName = packageName(className);
+    providedClasses.add(className);
+    addProvidedPackage(pkgName);
+    addReferencedClass(pkgName, className);
+
+    task.log("Added provided class '" +className +"'.",
+             Project.MSG_DEBUG);
+    return pkgName;
+  }
+
+  /**
+   * Checks if a named class is provided by this bundle.
+   * @param className the name of the class to check for.
+   * @return <code>true</code> if the given class is in the set of
+   *         classes provided by this bundle, <code>false</code>
+   *         otherwise.
+   */
+  public boolean providesClass(final String className)
+  {
+    return providedClasses.contains(className);
+  }
+
+
+  /**
+   * The sub set of the provided classes that implements the interface
+   * {@link org.osgi.framework.BundleActivator}.
+   */
+  private final SortedSet/*<String>*/<String> activatorClasses = new TreeSet<String>();
+
+  /**
+   * Adds a named class to the set of classes that implements the
+   * interface {@link org.osgi.framework.BundleActivator}.
+   *
+   * @param className the name of the activator class to add.
+   */
+  public void addProvidedActivatorClass(final String className)
+  {
+    activatorClasses.add(className);
+    providedClasses.add(className);
+
+    task.log("Added provided BundleActivator class '" +className +"'.",
+             Project.MSG_DEBUG);
+  }
+
+  /**
+   * Gets the cardinality of the set of provided bundle activator
+   * classes.
+   *
+   * @return Number of elements in the set of provided bundle
+   *         activator classes.
+   */
+  public int countProvidedActivatorClasses()
+  {
+    return activatorClasses.size();
+  }
+
+  /**
+   * Checks if a named class is in the set of provided activator classes.
+   * @param className the name of the activator class to check for.
+   * @return <code>true</code> if the given class is in the set of
+   *         provided activator classes, <code>false</code> otherwise.
+   */
+  public boolean providesActivatorClass(final String className)
+  {
+    return activatorClasses.contains(className);
+  }
+
+  /**
+   * Return the set of provided activator classes as string suitable
+   * for use in messages.
+   * @return The provided set of activator classes as a string.
+   */
+  public String providedActivatorClassesAsString()
+  {
+    return activatorClasses.toString();
+  }
+
+  /**
+   * Get the bundle activator from the set of provided bundle
+   * activator classes.
+   * @return The one and only activator class when the size of the set
+   *         of provided bundle activator classes is <em>one</em>,
+   *         otherwise <code>null</code>.
+   */
+  public String getActivatorClass()
+  {
+    return 1== activatorClasses.size()
+      ? activatorClasses.iterator().next()
+      : (String) null;
+  }
+
+
+  /**
+   * The set of packages that are provided by the classes in the
+   * bundle.
+   */
+  private final SortedSet/*<String>*/<String> providedPackages = new TreeSet<String>();
+
+  /**
+   * Adds a named package to the set of packages provided by this
+   * bundle.
+   * @param packageName the name of the Java package to add.
+   */
+  public void addProvidedPackage(final String packageName)
+  {
+    if(packageName == null || "".equals(packageName)) {
+      return;
+    }
+
+    providedPackages.add(packageName);
+  }
+
+  /**
+   * Checks if a named Java package is provided by this bundle.
+   *
+   * @param packageName the name of the package to check for.
+   * @return <code>true</code> if the given package is in the set of
+   *         packages provided by this bundle, <code>false</code>
+   *         otherwise.
+   */
+  public boolean providesPackage(final String packageName)
+  {
+    return providedPackages.contains(packageName);
+  }
+
+  /**
+   * Get a copy of the set of provided Java packages.
+   *
+   * This method may be called before {@link #toJavaNames()}.
+   *
+   * @return A copy of the set of provided Java packages.
+   */
+  public SortedSet<String> getProvidedPackages()
+  {
+    final TreeSet<String> res = new TreeSet<String>(providedPackages);
+    toJavaNames(res); // Ensure that '.' is used as package separator
+    return res;
+  }
+
+  /**
+   * Get the provided packages formatted as the value of an
+   * Export-Package-manifest attribute with package versions.
+   *
+   * @return OSGi Export-Package header value.
+   */
+  public String getProvidedPackagesAsExportPackageValue()
+  {
+    final StringBuffer res = new StringBuffer(255);
+
+    for (final Iterator<String> ppIt = providedPackages.iterator(); ppIt.hasNext();) {
+      final String pPkg = ppIt.next();
+      res.append(pPkg);
+      final Version pPkgVersion = getProvidedPackageVersion(pPkg);
+      if (null!=pPkgVersion) {
+        res.append(";version=").append(pPkgVersion);
+      }
+      if (ppIt.hasNext()) {
+        res.append(", ");
+      }
+    }
+
+    return res.toString();
+  }
+
+  /**
+   * Gets the cardinality of the set of provided Java packages.
+   *
+   * @return Number of elements in the set of provided packages.
+   */
+  public int countProvidedPackages()
+  {
+    return providedPackages.size();
+  }
+
+  /**
+   * Mapping from the package name of a provided package to its
+   * version as given by the packageinfo-file if present.
+   */
+  private final Map<String,Version> packageToVersion = new HashMap<String, Version>();
+
+  /**
+   * Get the version of a provided package as defined by the
+   * <code>packageinfo</code>-file in the package-directory.
+   *
+   * @param pkgName The package to get the version of.
+   *
+   * @return The package version or null if not defined.
+   */
+  public Version getProvidedPackageVersion(final String pkgName)
+  {
+    return packageToVersion.get(pkgName);
+  }
+
+
+  /**
+   * Mapping from the package name of a provided package to the
+   * absolute path of the <code>packageinfo</code>-file that was used
+   * to determine the package version.
+   */
+  private final Map<String,String> packageToInfofile = new HashMap<String, String>();
+
+
+  /**
+   * Get the path of the file that the version of a provided package
+   * was found in.
+   *
+   * @param pkgName The version-ed package to get the version source of.
+   *
+   * @return The path of the <code>packageinfo</code>-file that the
+   *         version was read from.
+   */
+  public String getProvidedPackageVersionSource(final String pkgName)
+  {
+    return packageToInfofile.get(pkgName);
+  }
+
+
+  /**
+   * Read the version from a <code>packageinfo</code>-file given a
+   * resource-object.
+   *
+   * @param res Resource encapsulating a <code>packageinfo</code>-file.
+   *
+   * @return The version or <code>null</code> if no valid version was
+   *         found.
+   */
+  private Version getVersion(final Resource res)
+  {
+    BufferedReader br = null;
+    try {
+      br = new BufferedReader(new InputStreamReader(res.getInputStream()));
+      String line = br.readLine();
+      while (null!=line) {
+        if (line.startsWith("version ")) {
+          final Version version = new Version(line.substring(7).trim());
+          return version;
+        }
+        line = br.readLine();
+      }
+    } catch (final Throwable t) {
+      final String msg = "Failed to get version from '" +res.toString()
+        +"'; " +t.getMessage();
+      throw new BuildException(msg, t);
+    }
+    return null;
+  }
+
+
+  /**
+   * Try to assign a version to the Java that the given
+   * <code>packageinfo</code>-file resides in. This code assumes that
+   * the resource has been created in such a way that
+   * <code>res.getName()</code> returns a relative path to the
+   * <code>packageinfo</code>-file that starts in its package
+   * root. I.e., the path is the Java package that the
+   * <code>packageinfo</code>-file provides data for.
+   *
+   * @param res Resource encapsulating a <code>packageinfo</code>-file.
+   * @return The package name or <code>null</code> if no valid version was
+   *         found.
+   */
+  public String setPackageVersion(final Resource res)
+  {
+    // The relative path to packageinfo-file starting from the root of
+    // its classpath. Allways using forward slash as separator char.
+    final String pkgInfoPath = res.getName().replace(File.separatorChar, '/');
+    // 12 = "/packageinfo".lenght()
+    final String pkgName = pkgInfoPath.substring(0, pkgInfoPath.length()-12);
+
+    // Currently registered path for version providing packageinfo
+    // file, if any.
+    final String curPkgInfoPath = packageToInfofile.get(pkgName);
+
+    if (null==curPkgInfoPath || !curPkgInfoPath.equals(pkgInfoPath)) {
+      final Version newVersion = getVersion(res);
+      if (null!=newVersion) {
+        final Version curVersion = getProvidedPackageVersion(pkgName);
+
+        if (null==curVersion) {
+          packageToVersion.put(pkgName, newVersion);
+          packageToInfofile.put(pkgName, pkgInfoPath);
+          task.log("Package version for '" +pkgName +"' set to "
+                   +newVersion +" based on data from '" +pkgInfoPath +"'.",
+                   Project.MSG_VERBOSE);
+          return pkgName;
+        } else if (!newVersion.equals(curVersion)) {
+          // May happen when the classes of a package are in two
+          // different directories on the class path.
+          throw new BuildException("Conflicting versions for '"
+                                   +pkgName +"' previous  '"
+                                   +curVersion +"' from '"
+                                   +curPkgInfoPath +"', new '"
+                                   +newVersion +"' in '"
+                                   +pkgInfoPath +"'.");
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * The set of classes that are referenced from the provided classes.
+   * I.e., classes that are used somehow by the provided classes.
+   */
+  private final SortedSet<String> referencedClasses = new TreeSet<String>();
+
+  /**
+   * The set of Java packages that are referenced from the provided
+   * classes.
+   */
+  private final SortedSet<String> referencedPackages = new TreeSet<String>();
+
+  /**
+   * Get a copy of the set of referenced Java classes.
+   *
+   * @return A copy of the set of referenced Java packages.
+   */
+  public SortedSet<String> getReferencedClasses()
+  {
+    return new TreeSet<String>(referencedClasses);
+  }
+
+
+  /**
+   * Get a the set of Java packages that are referenced by this bundle
+   * but not provided by it.
+   *
+   * @return The set of un-provided referenced Java packages.
+   */
+  public SortedSet/*<String>*/<String> getUnprovidedReferencedPackages()
+  {
+    final SortedSet<String> res = new TreeSet<String>(referencedPackages);
+    res.removeAll(providedPackages);
+
+    return res;
+  }
+
+
+  /**
+   * Get a copy of the set of Java packages that are referenced by
+   * this bundle.
+   *
+   * @return The set of referenced Java packages.
+   */
+  public SortedSet<String> getReferencedPackages()
+  {
+    return new TreeSet<String>(referencedPackages);
+  }
+
+
+  /**
+   * A mapping from a provided Java package name to the set of Java
+   * package names referenced by the classes in that provided package.
+   */
+  private final Map<String,Set<String>>
+    packageToReferencedPackages = new HashMap<String, Set<String>>();
+
+
+  /**
+   * Add a reference to a named class from some class in the
+   * referencing Java package.
+   *
+   * If the given referenced class is an inner class, then we also add
+   * a reference for its outer class. This is not really needed for
+   * static inner classes, but there is no way to detect that on this
+   * level.
+   *
+   * @param referencingPackage The Java package of the class having a
+   *                           reference to <tt>className</tt>.
+   * @param referencedClass Fully qualified name of the referenced
+   *                        class.
+   */
+  public void addReferencedClass(final String referencingPackage,
+                                 final String referencedClass)
+  {
+    if(null==referencedClass || 0==referencedClass.length()) {
+      return;
+    }
+
+    final String referencedPackage = packageName(referencedClass);
+    if("".equals(referencedPackage)) {
+      // Referenced class is in the default package; skip it.
+      return;
+    }
+
+    referencedClasses.add(referencedClass);
+    final int dollarIdx = referencedClass.indexOf('$');
+    if (-1<dollarIdx) {
+      // This is an inner class add its outer class as well.
+      referencedClasses.add(referencedClass.substring(0, dollarIdx));
+    }
+    referencedPackages.add(referencedPackage);
+    if (null!=referencingPackage && 0<referencingPackage.length()) {
+      SortedSet<String> using = (SortedSet<String>)
+        packageToReferencedPackages.get(referencingPackage);
+      if (null==using) {
+        using = new TreeSet<String>();
+        packageToReferencedPackages.put(referencingPackage, using);
+      }
+      using.add(referencedPackage);
+    }
+    task.log("Added reference to class '" +referencedClass
+             +"' from the package '" +referencingPackage +"'.",
+             Project.MSG_DEBUG);
+  }
+
+  /**
+   * Post process the package to referenced packages map.
+   *
+   * <ol>
+   * <li>Remove all self references.
+   * <li>Remove all references to "java.*".
+   * <li>Remove all packages in the remove from referenced set are removed from
+   * all referenced sets.
+   * <li>Retain all packages in the retain in referenced set. I.e., the
+   * referenced sets will only contain packages present in this set.
+   * </ol>
+   *
+   * @param removeFromReferencedSets
+   *          Packages to remove
+   * @param retainInReferencedSets
+   *          Packages to retain.
+   */
+  public void postProcessUsingMap(Set<String> removeFromReferencedSets,
+                                  Set<String> retainInReferencedSets)
+  {
+    for (final Entry<String,Set<String>> entry : packageToReferencedPackages.entrySet()) {
+      final Set<String> using = entry.getValue();
+      using.remove(entry.getKey());
+      using.removeAll(removeFromReferencedSets);
+      using.retainAll(retainInReferencedSets);
+    }
+  }
+
+  /**
+   * Get a the set of Java packages that are referenced by the
+   * given Java package.
+   *
+   * @param  packageName The name of the Java package to get
+   *                     referenced Java packages for.
+   * @return The set of referenced Java packages.
+   */
+  public SortedSet<String>
+    getPackagesReferencedFromPackage(final String packageName)
+  {
+    return (SortedSet<String>) packageToReferencedPackages.get(packageName);
+  }
+
+
+  /**
+   * Replaces all '/' in class and package names with '.' in all the
+   * collections that this class is holding.
+   */
+  public void toJavaNames()
+  {
+    toJavaNames(providedClasses);
+    toJavaNames(providedPackages);
+    toJavaNames(activatorClasses);
+    toJavaNames(referencedClasses);
+    toJavaNames(referencedPackages);
+    toJavaNames(packageToReferencedPackages);
+    toJavaNames(packageToVersion);
+    toJavaNames(packageToInfofile);
+  }
+
+  /**
+   * Replaces all '/' in class and package names with '.' in the
+   * elements of the given set.
+   *
+   * @param set the set of names to process.
+   */
+  private void toJavaNames(SortedSet<String> set)
+  {
+    final TreeSet<String> tmpSet = new TreeSet<String>();
+    for (final String item : set) {
+      tmpSet.add(item.replace('/', '.'));
+    }
+    set.clear();
+    set.addAll(tmpSet);
+    tmpSet.clear();
+  }
+
+  /**
+   * Replaces all '/' in class and package names with '.' in the keys of the
+   * given map. If the value is a sorted set of strings call
+   * {@link #toJavaNames(SortedSet)} on it.
+   *
+   * @param map
+   *          the map of with keys to process.
+   */
+  private <V> void toJavaNames(Map<String, V> map)
+  {
+    final HashMap<String, V> tmpMap = new HashMap<String, V>();
+
+    for (final Entry<String, V> entry : map.entrySet()) {
+      final String key = entry.getKey();
+      final V value = entry.getValue();
+      if (value instanceof SortedSet) {
+        @SuppressWarnings("unchecked")
+        final SortedSet<String> set = (SortedSet<String>) value;
+        toJavaNames(set);
+      }
+      tmpMap.put(key.replace('/', '.'), value);
+    }
+    map.clear();
+    map.putAll(tmpMap);
+    tmpMap.clear();
+  }
+
+  @Override
+  public boolean equals(Object other)
+  {
+    if (!(other instanceof BundlePackagesInfo)) {
+      return false;
+    }
+    final BundlePackagesInfo otherBpInfo = (BundlePackagesInfo) other;
+
+    if (!providedPackages.equals(otherBpInfo.providedPackages)) {
+      System.out.println("Diff for provided packages: mine="
+                         +providedPackages
+                         +", other=" +otherBpInfo.providedPackages);
+      return false;
+    }
+
+    if (!providedClasses.equals(otherBpInfo.providedClasses)) {
+      System.out.println("Diff for provided classes: mine="
+                         +providedClasses
+                         +", other=" +otherBpInfo.providedClasses);
+      return false;
+    }
+
+    if (!activatorClasses.equals(otherBpInfo.activatorClasses)) {
+      System.out.println("Diff for activator classes: mine="
+                         +activatorClasses
+                         +", other=" +otherBpInfo.activatorClasses);
+      return false;
+    }
+
+    if (!referencedPackages.equals(otherBpInfo.referencedPackages)) {
+      System.out.println("Diff for referenced packages: mine="
+                         +referencedPackages
+                         +", other=" +otherBpInfo.referencedPackages);
+      final SortedSet<String> all = new TreeSet<String>(referencedPackages);
+      all.addAll(otherBpInfo.referencedPackages);
+      final SortedSet<String> tmp = new TreeSet<String>(all);
+      tmp.removeAll(referencedPackages);
+      System.out.println(" Other extra referenced packages: " +tmp);
+
+      tmp.addAll(all);
+      tmp.removeAll(otherBpInfo.referencedPackages);
+      System.out.println(" My extra referenced packages: " +tmp);
+
+      return false;
+    }
+
+    if (!referencedClasses.equals(otherBpInfo.referencedClasses)) {
+      System.out.println("Diff for referenced classes: mine="
+                         +referencedClasses
+                         +", other=" +otherBpInfo.referencedClasses);
+
+      final SortedSet<String> all = new TreeSet<String>(referencedClasses);
+      all.addAll(otherBpInfo.referencedClasses);
+      final SortedSet<String> tmp = new TreeSet<String>(all);
+      tmp.removeAll(referencedClasses);
+      System.out.println(" Other extra referenced classes: " +tmp);
+
+      tmp.addAll(all);
+      tmp.removeAll(otherBpInfo.referencedClasses);
+      System.out.println(" My extra referenced classes: " +tmp);
+
+      return false;
+    }
+
+    return true;
+  }
+
+
+  @Override
+  public String toString()
+  {
+    final StringBuffer res = new StringBuffer(200);
+    res.append("BundlePackagesInfo:\n\t");
+    res.append("Provided packages: [");
+    for (final Iterator<String> ppIt = providedPackages.iterator(); ppIt.hasNext();) {
+      final String pPkg = ppIt.next();
+      res.append(pPkg);
+      final Version pPkgVersion = getProvidedPackageVersion(pPkg);
+      if (null!=pPkgVersion) {
+        res.append(";version=").append(pPkgVersion);
+      }
+      if (ppIt.hasNext()) {
+        res.append(", ");
+      }
+    }
+    res.append("]\n\t");
+
+    res.append("Provided classes: ").append(providedClasses).append("\n\t");
+    res.append("Provided Activators: ").append(activatorClasses).append("\n\t");
+
+    res.append("Referenced packages: ").append(referencedPackages).append("\n\t");
+    res.append("Referenced classes: ").append(referencedClasses).append("\n\t");
+
+    res.append("Using map: ").append(packageToReferencedPackages).append("\n");
+
+    return res.toString();
+  }
+
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleUserDocNavigateTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleUserDocNavigateTask.java
new file mode 100644
index 0000000..efdba24
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleUserDocNavigateTask.java
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * <p>
+ *  This task is used when building bundle user documentation for a
+ *  Knopflerfish release, it builds the navigation frame listing
+ *  bundles with user documentation.  If you don't intend to create a
+ *  new distribution type of Knopflerfish then you're in the wrong
+ *  place.
+ * </p>
+ *
+ * <p>
+ *  Here is a outline of how to use the task and a description
+ *  of different parameters and used system properties.
+ * </p>
+ *
+ * <p>
+ *
+ * <table border=1>
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    outdir
+ *   </td>
+ *   <td>
+ *    Where to put the generated file (directory).
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    tofile
+ *   </td>
+ *   <td>
+ *    The relative path to where the generated file should be
+ *    copied. That is the actual location of the generated file
+ *    will be <code>outdir</code>/<code>tofile</code>.
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    template
+ *   </td>
+ *   <td>
+ *    The file which describes what the page should look like.
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    title
+ *   </td>
+ *   <td>
+ *    The title to use on the generated page.
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    docdir
+ *   </td>
+ *   <td>
+ *    The directory with one sub-directory for each user documentation
+ *    link to create. Defaults to <code>outdir</code>.
+ *
+ *    <p>All sub-directories of <tt>docdir</tt> will result in a link
+ *       on the generated navigation page. The link will belong to the
+ *       default category, have a title set to the name of the
+ *       sub-directory and a link path pointing to the file
+ *       "index.html" inside the sub-directory. The default link properties
+ *       may be overridden by specifying other values in a
+ *       properties file named <tt>doc.properties</tt> in the
+ *       sub-directory.</p>
+ *
+ *    <p>The following keys in the properties file are used:</p>
+ *
+ *    <dl>
+ *
+ *     <dt><tt>category</tt></dt>
+ *     <dd>The name of the category to present the link under.</dd>
+ *
+ *     <dd>The link text.</dd>
+ *     <dt><tt>title</tt></dt>
+ *
+ *     <dt><tt>linkPath</tt></dt>
+ *     <dd>The path that the link points to. The default is a relative
+ *         path pointing to the file <tt>index.html</tt> inside the
+ *         sub-directory holding the properties file.</dd>
+ *
+ *     <dt><tt>linkRef</tt></dt>
+ *     <dd>A reference part to append to the generated link. I.e., this will
+ *         make a link that points a named anchor on the linked page.
+ *
+ *     <dt><tt>sortKey</tt></dt>
+ *     <dd>String to use when sorting links. Default is the value of
+ *         the title key.</dd>
+ *
+ *     <dt><tt>depth</tt></dt>
+ *     <dd>Nesting depth of link presentation. Default is 1. Must
+ *         be one or greater.</dd>
+ *
+ *    </dl>
+ *
+ *    <p>It is possible to generate more than one link from the same
+ *       <tt>doc.properties</tt> file. To do this insert a
+ *       <tt>linkCount</tt> key with the number of links to create as
+ *       its value. Then for each link add all the keys defined above
+ *       with the link number followed by a '.' as key-prefix. Link
+ *       number prefixes starts with 0 and must be strictly smaller
+ *       than the value of <tt>linkCount</tt>. If there is no category
+ *       value with a link number prefix the un-prefixed category value
+ *       will be used. I.e., if all links belongs to the same category
+ *       it suffices to write the category name once.</p>
+ *
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    defaultcategory
+ *   </td>
+ *   <td>
+ *    The name of the category to place links under when not specified
+ *    in the doc-subdirectory.
+ *   </td>
+ *   <td>
+ *    No, defaults to "bundle".
+ *   </td>
+ *  </tr>
+ * </table>
+ */
+
+public class BundleUserDocNavigateTask
+  extends Task
+{
+  public static final String DOC_PROPS_FILE_NAME = "doc.properties";
+
+  /**
+   * Target directory, where everything will end up
+   */
+  private File outDir;
+
+
+  public void setOutdir(File f) {
+    outDir = f;
+    if (null==docDir) {
+      docDir = f;
+    }
+  }
+
+
+  /**
+   * The relative path to the target file from output dir
+   */
+  private String toFileName;
+
+  public void setTofile(String s) {
+    toFileName = s;
+  }
+
+  /**
+   * Template file
+   */
+  private File template;
+
+  public void setTemplate(File f) {
+    template = f;
+  }
+
+
+  /**
+   * The title of the generated page
+   */
+  private String pageTitle;
+
+  public void setTitle(String s) {
+    pageTitle = s;
+  }
+
+
+  /**
+   * The directory to analyze sub-directories in.
+   */
+  private File docDir;
+
+
+  public void setDocdir(File f) {
+    docDir = f;
+  }
+
+
+  /**
+   * The default category name
+   */
+  private String defaultCategory = "bundle";
+
+  public void setDefaultcategory(String s) {
+    defaultCategory = s;
+  }
+
+  // Mapping from category name to sorted set with link data.
+  private final Map<String, SortedSet<LinkData>> categories =
+    new HashMap<String, SortedSet<LinkData>>();
+
+  // Insert a link data item to a category in the categories map
+  private void add(final String category, final LinkData ld)
+  {
+    SortedSet<LinkData> lds = categories.get(category);
+    if (null==lds) {
+      lds = new TreeSet<LinkData>();
+      categories.put(category, lds);
+    }
+    lds.add(ld);
+  }
+
+  // Build a html-string with links to the lds in the set.
+  private String links(final Set<LinkData> lds)
+  {
+    final StringBuffer sb = new StringBuffer(1024);
+    for (final LinkData ld : lds) {
+      sb.append("      <dd class=\"leftmenu");
+      sb.append(ld.depth +1);
+      sb.append("\">");
+      sb.append("<a target=\"bundledoc_main\" href=\"");
+      sb.append(ld.linkPath);
+      if (ld.linkRef != null && ld.linkRef.length() > 0) {
+        sb.append("#").append(ld.linkRef);
+      }
+      sb.append("\">");
+      sb.append(ld.title);
+      sb.append("</a></dd>\n");
+    }
+
+    return sb.toString();
+  }
+
+  // The data needed to create a document link in a category.
+  static class LinkData implements Comparable<LinkData>
+  {
+    String title;
+    String linkPath;
+    String linkRef;
+    String sortKey;
+    int depth = 1;
+
+    public LinkData(final String title, final String linkPath)
+    {
+      this.title = title;
+      this.sortKey = title.toLowerCase();
+      this.linkPath = linkPath;
+    }
+
+    @Override
+    public int compareTo(LinkData other)
+    {
+      return sortKey.compareTo(other.sortKey);
+    }
+  }
+
+  private String fillLinkData(final Properties docProps,
+                              final String prefix,
+                              final LinkData ld)
+  {
+    ld.title = docProps.getProperty(prefix +"title", ld.title);
+    ld.sortKey = docProps.getProperty(prefix +"sortKey", ld.title);
+    ld.linkPath = docProps.getProperty(prefix +"linkPath", ld.linkPath);
+    ld.linkRef = docProps.getProperty(prefix +"linkRef", ld.linkRef);
+    final String sd = docProps.getProperty(prefix +"depth");
+    if (null!=sd && 0<sd.length()) {
+      try {
+        ld.depth = Integer.parseInt(sd);
+      } catch (final NumberFormatException nfe) {
+      }
+    }
+    final String category = docProps.getProperty("category", defaultCategory);
+    return docProps.getProperty(prefix +"category", category);
+  }
+
+  private void analyzeDocDir()
+  {
+    final File[] files = docDir.listFiles();
+    for (final File file2 : files) {
+      final File file = file2;
+
+      // Only interested in directories.
+      if (!file.isDirectory()) {
+        continue;
+      }
+
+      final String defaultTitle = file.getName();
+      final String defaultLinkPath = file.getName() +"/index.html";
+
+      final File docPropsFile = new File(file, DOC_PROPS_FILE_NAME);
+      if (docPropsFile.canRead()) {
+        try {
+          final Properties docProps = new Properties();
+          docProps.load(new FileInputStream(docPropsFile));
+
+          final String linkCntS = docProps.getProperty("linkCount");
+          int linkCnt = 0;
+          if (null!=linkCntS && 0<linkCntS.length()) {
+            try {
+              linkCnt = Integer.parseInt(linkCntS);
+            } catch (final NumberFormatException nfe) {
+              log("Invalid linkCount value, '"+linkCntS
+                  +"' found in '"+docPropsFile +"': "+nfe.getMessage(),
+                  Project.MSG_WARN);
+            }
+          }
+          if (0==linkCnt) {
+            final LinkData ld = new LinkData(defaultTitle, defaultLinkPath);
+            final String category = fillLinkData(docProps, "", ld);
+            add(category, ld);
+          } else {
+            for (int j=0; j<linkCnt; j++) {
+              final LinkData ld = new LinkData(defaultTitle, defaultLinkPath);
+              final String category = fillLinkData(docProps,
+                                                   String.valueOf(j)+".",
+                                                   ld);
+              add(category, ld);
+            }
+          }
+        } catch (final IOException ioe) {
+          log("Failed to load user documentation property description from '"
+              +docPropsFile +"': "+ioe.getMessage(), Project.MSG_ERR);
+        }
+      } else {
+        // No doc.properties; create a default link
+        final LinkData ld = new LinkData(defaultTitle, defaultLinkPath);
+        add(defaultCategory, ld);
+      }
+    }
+  }
+
+
+  @Override
+  public void execute() {
+    if (template == null) {
+      throw new BuildException("template must be set");
+    }
+    if (docDir == null) {
+      throw new BuildException("docdir must be set");
+    }
+    if (outDir == null) {
+      throw new BuildException("outdir must be set");
+    }
+    if (toFileName == null) {
+      throw new BuildException("tofile must be set");
+    }
+
+    if (defaultCategory == null) {
+      throw new BuildException("defaultCategory must not be null.");
+    }
+
+    analyzeDocDir();
+
+    transform(template, toFileName);
+  }
+
+  private void transform(final File fromFile, final String toFileName) {
+
+    try {
+      // Ensure that the directory to write the output file to exists
+      final File toFile = new File(outDir, toFileName);
+      final File tmp = toFile.getParentFile();
+      if (!tmp.exists()) {
+        if (tmp.exists() || !tmp.mkdirs()) {
+          throw new IOException("Could not create " + tmp);
+        }
+      }
+
+      String content = FileUtil.loadFile(fromFile.getAbsolutePath());
+      content = Util.replace(content, "$(TITLE)", pageTitle);
+
+      for (final Entry<String,SortedSet<LinkData>> entry : categories.entrySet()) {
+        final String category = entry.getKey();
+        final Set<LinkData> lds = entry.getValue();
+
+        final String ldHtml = links(lds);
+        if (0<ldHtml.length()) {
+          final int oldContentLength = content.length();
+          content = Util.replace(content, "$("+category+")", links(lds));
+          if (oldContentLength == content.length()) {
+            final String msg = "Found bundle user documentation with category '"
+              +category +"', but there is no such category in the bundle user "
+              +"documentation navigate list template, '"
+              +fromFile.getAbsolutePath() +"'.";
+
+            log(msg, Project.MSG_ERR);
+            throw new BuildException(msg);
+          }
+        }
+      }
+
+      FileUtil.writeStringToFile(toFile, content);
+      log("Created: " + toFile.getAbsolutePath());
+    } catch (final IOException e) {
+      e.printStackTrace();
+      throw new BuildException(e);
+    } catch (final Exception e) {
+      e.printStackTrace();
+      throw new BuildException(e);
+    }
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/ByteFormatterTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/ByteFormatterTask.java
new file mode 100644
index 0000000..bcd4af4
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/ByteFormatterTask.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2008-2010, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+
+/**
+ * Sets a property to a formatted value in ki, Mi, Gi, Ti, Pi, Ei, Zi
+ * and Yi with an optional unit.
+ *
+ * Here <tt>ki</tt> is short for <tt>kibi</tt>, (a contraction of kilo
+ * binary) see <a
+ * href="http://en.wikipedia.org/wiki/Kibibyte">http://en.wikipedia.org/wiki/Kibibyte</a>
+ * for a detailed explanation.  <p>
+ *
+ * <h3>Parameters</h3>
+ *
+ * <table border=>
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">property</td>
+ *    <td valign="top">
+ *      The name of the property to assign the formatted value to.</td>
+ *    <td valign="top" align="center">Yes.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">binaryPrefixURL</td>
+ *    <td valign="top">An URL pointing to a page explaining the binary
+ *                     unit suffixes.</td>
+ *    <td valign="top" align="center">
+ *      http://en.wikipedia.org/wiki/Binary_prefix#IEC_standard_prefixes
+ *    </td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">unit</td>
+ *    <td valign="top">The unit to append to the formatted value. E.g., byte</td>
+ *    <td valign="top" align="center">
+ *      No, default is the empty string.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">sep</td>
+ *    <td valign="top">The string placed between the number and the
+ *                     unit.</td>
+ *    <td valign="top" align="center">
+ *      No, default is the HTML non-breaking space, "&nbsp;".</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">value</td>
+ *    <td valign="top">The value to format.</td>
+ *    <td valign="top" align="center">
+ *      One of value and file must be given.</td>
+ *  </tr>
+ *  <tr>
+ *    <td valign="top">file</td>
+ *    <td valign="top">The file whose size is the value to format.</td>
+ *    <td valign="top" align="center">
+ *      One of value and file must be given.</td>
+ *  </tr>
+ * </table>
+ *
+ * <h3>Nested elements</h3>
+ *
+ * Not applicable.
+ *
+ * <h3>Examples</h3>
+ *
+ * <h4>Format a value as bytes</h4>
+ *
+ * <pre>
+ *  <byteformatter value="9093663"
+ *                    property="myFormatedFilesize"
+ *                    unit="B" />
+ * </pre>
+ *
+ *
+ * <h4>Format the size of the file <tt>archive.jar</tt> appending the
+ * unit <tt>B</tt></h4>
+ *
+ * <pre>
+ *  <byteformatter file="archive.jar"
+ *                    property="archive.size"
+ *                    unit="B" />
+ * </pre>
+ *
+ *
+ *
+ */
+public class ByteFormatterTask extends Task {
+  /**
+   * Default constructor.
+   */
+  public ByteFormatterTask() {
+    super();
+   }
+
+  private String property;
+  /**
+   * The name of the property to save the formatted value to.
+   *
+   * @param property the name of the property to set.
+   */
+  public void setProperty(String property) {
+    this.property = property;
+  }
+
+
+  private String unit = "";
+  /**
+   * The unit to append to the formatted value.
+   *
+   * @param unit the unit text to append to the formatted value.
+   */
+  public void setUnit(String unit) {
+    this.unit = unit;
+  }
+
+
+  private String binaryPrefixURL
+    = "http://en.wikipedia.org/wiki/Binary_prefix#IEC_standard_prefixes";
+  /**
+   * The URL that explains binary prefixes.
+   *
+   * @param url The url to let the binary prefix point to.
+   */
+  public void setBinaryPrefixURL(String url) {
+    this.binaryPrefixURL = url;
+  }
+
+
+  private String sep = " ";
+  /**
+   * The separator between the numeral and the prefixed unit.
+   *
+   * @param sep the separator string.
+   */
+  public void setSep(String sep) {
+    this.sep = sep;
+  }
+
+
+  private long value;
+  /**
+   * Set the value to format.
+   *
+   * @param value the value to format
+   */
+  public void setValue(long value) {
+    this.value = value;
+  }
+
+
+  /**
+   * Set the file to get the size of as the the value to format.
+   *
+   * @param file the file to return a formatted file size for.
+   */
+  public void setFile(final File file) {
+    this.value = file.length();
+  }
+
+
+
+  static final long step = 1024;
+
+  /**
+   * Performs the requested formatting.
+   *
+   * @throws BuildException if the manifest cannot be written.
+   */
+  public void execute() {
+    String formatedValue = "";
+    String[] suffixes = new String[]{ "",  "Ki","Mi",
+                                      "Gi","Ti","Pi",
+                                      "Ei","Zi","Yi"};
+    if (binaryPrefixURL!=null && binaryPrefixURL.length()>0) {
+      for (int i=0; i<suffixes.length; i++) {
+        if (suffixes[i].length()>0) {
+          suffixes[i] = "<a href=\"" +binaryPrefixURL +"\">"
+            +suffixes[i] + "</a>";
+        }
+      }
+    }
+
+    int ix = 0;
+    long factor = 1;
+
+    while(value/factor>step && ix<suffixes.length) {
+      factor *= step;
+      ix++;
+    }
+
+    long i = value/factor;    // Integral part of reduced value
+    long r = value -i*factor; // Remainder.
+    // Convert r to a decimal fraction
+    double fraction  = ((double) r)/((double) factor);
+    formatedValue = formatValue(i, fraction);
+
+    Project project = getProject();
+    project.setProperty(property, formatedValue +sep +suffixes[ix] +unit);
+  }
+
+  private String formatValue( long integral, double fraction)
+  {
+    String res = String.valueOf(integral);
+    if (integral<10) { // Append two digits from the fraction
+      int dec = (int) (fraction*100);
+      res = res +"." +(dec<10?"0":"") +String.valueOf(dec);
+    } else if (integral<100) { // Append one digit from the fraction
+      int dec = (int) (fraction*10);
+      res = res +"." +String.valueOf(dec);
+    }
+    return res;
+  }
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/ClassAnalyserASM.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/ClassAnalyserASM.java
new file mode 100644
index 0000000..40e8e38
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/ClassAnalyserASM.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2003-2010, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+
+
+/**
+ * Visitor implementation that populates a BundlePackagesInfo object
+ * with data about the given class.
+ */
+public class ClassAnalyserASM
+  implements ClassVisitor
+{
+
+  /**
+   * The name of the bundle activator interface on internal form.
+   */
+  final static private String BUNDLE_ACTIVATOR
+    = "org/osgi/framework/BundleActivator";
+
+  // The BundlePackagesInfo object to populate with data.
+  final BundlePackagesInfo bpInfo;
+
+  // The task using this object to provide logging functionality.
+  final Task task;
+
+  // The package of the current class.
+  String currentPackage = null;
+
+  // The File of the current class.
+  File currentClassFile = null;
+
+
+  public ClassAnalyserASM(final BundlePackagesInfo bpInfo,
+                          final Task task)
+  {
+    this.bpInfo = bpInfo;
+    this.task   = task;
+  }
+
+  public synchronized void analyseClass(File clsFile)
+  {
+    FileInputStream fis = null;
+    try {
+      fis = new FileInputStream(clsFile);
+      analyseClass(fis, clsFile.toString());
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      if (null!=fis) {
+        try { fis.close(); } catch (Exception _ec) {}
+      }
+    }
+  }
+
+  public synchronized void analyseClass(InputStream clsIn, String fileName)
+  {
+    try {
+      ClassReader cr = new ClassReader(clsIn);
+      currentClassFile = new File(fileName);
+      cr.accept(this, 0);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+
+  protected void addReferencedType(final Type type)
+  {
+    switch (type.getSort()) {
+    case Type.OBJECT:
+      bpInfo.addReferencedClass(currentPackage, type.getInternalName());
+      break;
+    case Type.ARRAY:
+      addReferencedType(type.getElementType());
+      break;
+    default:
+    }
+  }
+
+  /*
+   * Visits the header of the class.
+   *
+   * @param version the class version.
+   * @param access the class's access flags (see {@link Opcodes}). This
+   *        parameter also indicates if the class is deprecated.
+   * @param name the internal name of the class (see
+   *        {@link Type#getInternalName() getInternalName}).
+   * @param signature the signature of this class. May be <tt>null</tt> if
+   *        the class is not a generic one, and does not extend or implement
+   *        generic classes or interfaces.
+   * @param superName the internal of name of the super class (see
+   *        {@link Type#getInternalName() getInternalName}). For interfaces,
+   *        the super class is {@link Object}. May be <tt>null</tt>, but
+   *        only for the {@link Object} class.
+   * @param interfaces the internal names of the class's interfaces (see
+   *        {@link Type#getInternalName() getInternalName}). May be
+   *        <tt>null</tt>.
+   */
+  public void visit(int version,
+                    int access,
+                    String name,
+                    String signature,
+                    String superName,
+                    String[] interfaces)
+  {
+    task.log("Analysing class '" +name +"'.", Project.MSG_VERBOSE);
+
+    currentPackage = bpInfo.addProvidedClass(name);
+    if (null!=superName) {
+      addReferencedType(Type.getObjectType(superName));
+    }
+    for(int i = 0; i < interfaces.length; i++) {
+      addReferencedType(Type.getObjectType(interfaces[i]));
+      if (BUNDLE_ACTIVATOR.equals(interfaces[i])) {
+        bpInfo.addProvidedActivatorClass(name);
+      }
+    }
+  }
+
+
+  /*
+   * Visits the source of the class.
+   *
+   * @param source the name of the source file from which the class was
+   *        compiled. May be <tt>null</tt>.
+   * @param debug additional debug information to compute the correspondence
+   *        between source and compiled elements of the class. May be
+   *        <tt>null</tt>.
+   */
+  public void visitSource(String source, String debug)
+  {
+  }
+
+
+  /*
+   * Visits the enclosing class of the class. This method must be called only
+   * if the class has an enclosing class.
+   *
+   * @param owner internal name of the enclosing class of the class.
+   * @param name the name of the method that contains the class, or
+   *        <tt>null</tt> if the class is not enclosed in a method of its
+   *        enclosing class.
+   * @param desc the descriptor of the method that contains the class, or
+   *        <tt>null</tt> if the class is not enclosed in a method of its
+   *        enclosing class.
+   */
+  public void visitOuterClass(String owner, String name, String desc)
+  {
+  }
+
+
+  /*
+   * Visits an annotation of the class.
+   *
+   * @param desc the class descriptor of the annotation class.
+   * @param visible <tt>true</tt> if the annotation is visible at runtime.
+   * @return a visitor to visit the annotation values, or <tt>null</tt> if
+   *         this visitor is not interested in visiting this annotation.
+   */
+  public AnnotationVisitor visitAnnotation(String desc, boolean visible)
+  {
+    return null;
+  }
+
+
+  /*
+   * Visits a non standard attribute of the class.
+   *
+   * @param attr an attribute.
+   */
+  public void visitAttribute(Attribute attr)
+  {
+  }
+
+
+  /*
+   * Visits information about an inner class. This inner class is not
+   * necessarily a member of the class being visited.
+   *
+   * @param name the internal name of an inner class (see
+   *        {@link Type#getInternalName() getInternalName}).
+   * @param outerName the internal name of the class to which the inner class
+   *        belongs (see {@link Type#getInternalName() getInternalName}). May
+   *        be <tt>null</tt> for not member classes.
+   * @param innerName the (simple) name of the inner class inside its
+   *        enclosing class. May be <tt>null</tt> for anonymous inner
+   *        classes.
+   * @param access the access flags of the inner class as originally declared
+   *        in the enclosing class.
+   */
+  public void visitInnerClass(String name,
+                              String outerName,
+                              String innerName,
+                              int access)
+  {
+  }
+
+
+  /*
+   * Visits a field of the class.
+   *
+   * @param access the field's access flags (see {@link Opcodes}). This
+   *        parameter also indicates if the field is synthetic and/or
+   *        deprecated.
+   * @param name the field's name.
+   * @param desc the field's descriptor (see {@link Type Type}).
+   * @param signature the field's signature. May be <tt>null</tt> if the
+   *        field's type does not use generic types.
+   * @param value the field's initial value. This parameter, which may be
+   *        <tt>null</tt> if the field does not have an initial value, must
+   *        be an {@link Integer}, a {@link Float}, a {@link Long}, a
+   *        {@link Double} or a {@link String} (for <tt>int</tt>,
+   *        <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
+   *        respectively). <i>This parameter is only used for static fields</i>.
+   *        Its value is ignored for non static fields, which must be
+   *        initialized through bytecode instructions in constructors or
+   *        methods.
+   * @return a visitor to visit field annotations and attributes, or
+   *         <tt>null</tt> if this class visitor is not interested in
+   *         visiting these annotations and attributes.
+   */
+  public FieldVisitor visitField(int access,
+                                 String name,
+                                 String desc,
+                                 String signature,
+                                 Object value)
+  {
+    addReferencedType(Type.getType(desc));
+
+    return null;
+  }
+
+
+  /*
+   * Visits a method of the class. This method <i>must</i> return a new
+   * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is
+   * called, i.e., it should not return a previously returned visitor.
+   *
+   * @param access the method's access flags (see {@link Opcodes}). This
+   *        parameter also indicates if the method is synthetic and/or
+   *        deprecated.
+   * @param name the method's name.
+   * @param desc the method's descriptor (see {@link Type Type}).
+   * @param signature the method's signature. May be <tt>null</tt> if the
+   *        method parameters, return type and exceptions do not use generic
+   *        types.
+   * @param exceptions the internal names of the method's exception classes
+   *        (see {@link Type#getInternalName() getInternalName}). May be
+   *        <tt>null</tt>.
+   * @return an object to visit the byte code of the method, or <tt>null</tt>
+   *         if this class visitor is not interested in visiting the code of
+   *         this method.
+   */
+  public MethodVisitor visitMethod(int access,
+                                   String name,
+                                   String desc,
+                                   String signature,
+                                   String[] exceptions)
+  {
+    Type[] argTypes = Type.getArgumentTypes(desc);
+    for (int i=0; argTypes!=null && i<argTypes.length; i++) {
+      addReferencedType(argTypes[i]);
+    }
+    addReferencedType(Type.getReturnType(desc));
+
+
+    for (int i=0; exceptions!=null && i<exceptions.length; i++) {
+      bpInfo.addReferencedClass(currentPackage, exceptions[i]);
+    }
+
+    return new MethodAnalyserASM(this, name);
+  }
+
+
+  /*
+   * Visits the end of the class. This method, which is the last one to be
+   * called, is used to inform the visitor that all the fields and methods of
+   * the class have been visited.
+   */
+  public void visitEnd()
+  {
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/FileUtil.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/FileUtil.java
new file mode 100644
index 0000000..1d867e9
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/FileUtil.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tools.ant.BuildException;
+import org.w3c.dom.Document;
+
+public class FileUtil
+{
+
+  public static byte [] loadURL(URL url) throws IOException {
+    final int     bufSize = 1024 * 2;
+    final byte [] buf     = new byte[bufSize];
+
+    final ByteArrayOutputStream bout = new ByteArrayOutputStream();
+    final BufferedInputStream   in   = new BufferedInputStream(url.openStream());
+    int n;
+    while ((n = in.read(buf)) > 0) {
+      bout.write(buf, 0, n);
+    }
+    try { in.close(); } catch (final Exception ignored) { }
+    return bout.toByteArray();
+  }
+
+  public static String loadFile(String fname) throws IOException {
+    final byte[] bytes = loadURL(new URL("file:" + fname));
+    return new String(bytes, "UTF-8");
+  }
+
+
+  /**
+   * Load entire contents of a file or URL into a string.
+   */
+  public static String load(String fileOrURL) throws IOException {
+    try {
+      final URL url = new URL(fileOrURL);
+
+      return new String(loadURL(url));
+    } catch (final Exception e) {
+      return loadFile(fileOrURL);
+    }
+  }
+
+  /**
+   * Load an XML-formated file into a DOM-document.
+   *
+   * @param file The XML file to load.
+   * @return DOM document.
+   */
+  public static Document loadXML(final File file) {
+    final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+    try {
+      final DocumentBuilder db = dbf.newDocumentBuilder();
+      return db.parse(file);
+    } catch (final Exception e) {
+      throw new BuildException("Failed to parse XML file '" +file +"': " +e, e);
+    }
+  }
+
+  /**
+   * Create an empty DOM-document.
+   *
+   * @param rootElement The name of the root element of the new document.
+   * @return DOM document with a root element.
+   */
+  public static Document createXML(final String rootElement) {
+    final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+    try {
+      final DocumentBuilder db = dbf.newDocumentBuilder();
+      final Document res = db.newDocument();
+      res.appendChild(res.createElement(rootElement));
+      return res;
+    } catch (final Exception e) {
+      throw new BuildException("Failed to create new DOM-document:" +e, e);
+    }
+  }
+
+  // Always write files using UTF-8.
+  static void writeStringToFile(File outFile, String s) throws IOException {
+    OutputStreamWriter writer = null;
+    try {
+      outFile.getParentFile().mkdirs();
+      final OutputStream out = new FileOutputStream(outFile);
+      writer = new OutputStreamWriter(out, "UTF-8");
+      writer.write(s, 0, s.length());
+      //      System.out.println("wrote " + outFile);
+    } finally {
+      try { writer.close(); } catch (final Exception ignored) { }
+    }
+  }
+
+  public static void writeDocumentToFile(final File outFile, final Document doc) {
+    final Source source = new DOMSource(doc);
+    final Result result = new StreamResult(outFile);
+
+    // Write the DOM document to the file
+    Transformer xformer;
+    try {
+      xformer = TransformerFactory.newInstance().newTransformer();
+      xformer.transform(source, result);
+    } catch (final Exception e) {
+      throw new BuildException("Failed to write XML to '" + outFile +"', "+e, e);
+    }
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/HtmlFragment.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/HtmlFragment.java
new file mode 100644
index 0000000..c23d1d6
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/HtmlFragment.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+
+
+/**
+ * <p>An Html formated text fragment the the MakeHTMLTask can be
+ * configured with.</p>
+ *
+ * <p>When <code>$(name)</code> is found in the document to be generated
+ * that string will be replaced with the contents of the file given by
+ * <code>fromFile</code>.</p>
+ *
+ * <p>When <code>$(name_LINK)</code> is found in the document to be
+ * generated that string will be replaced with a link to the
+ * fragment. The title of the link is given by
+ * <code>linkText</code>.</p>
+ *
+ * @author Gunnar Ekolin
+ */
+public class HtmlFragment {
+
+  private String name;
+  private File fromFile;
+  private String linkText;
+
+  /**
+   * @param name the name that is the substitution key for this fragment.
+   */
+  public void setName(final String name)
+  {
+    this.name = name;
+  }
+  /**
+   * @return the name of this fragment.
+   */
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * @param fromFile the file holding the substitution text.
+   */
+  public void setFromFile(final File fromFile) {
+    this.fromFile = fromFile;
+  }
+  /**
+   * @return the file to load the fragment from.
+   */
+  public File getFromFile() {
+    return fromFile;
+  }
+
+  /**
+   * @param linkText the clickable text of the link.
+   */
+  public void setLinkText(final String linkText)
+  {
+    this.linkText = linkText;
+  }
+  /**
+   * @return the link text.
+   */
+  public String getLinkText()
+  {
+    return linkText;
+  }
+
+} // HtmlFragment
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/MakeHTMLTask.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/MakeHTMLTask.java
new file mode 100644
index 0000000..56b6f4a
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/MakeHTMLTask.java
@@ -0,0 +1,731 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.apache.tools.ant.util.FileUtils;
+
+import org.osgi.framework.Version;
+
+import org.knopflerfish.ant.taskdefs.bundle.BundleArchives.BundleArchive;
+
+/**
+ * <p>
+ *  This task is used when building distributions of Knopflerfish.
+ *  If you don't intend to create a new distribution type of
+ *  Knopflerfish then you're in the wrong place.
+ * </p>
+ *
+ * <p>
+ *  Task that creates web sites given a template and a source file.
+ *  Currently used to create parts of the <code>docs</code> directory in the KF
+ *  distribution.  It does this by simply replacing certain text strings with
+ *  others. For more information on which text strings this is please
+ *  check the source code.
+ * </p>
+ *
+ * <p>
+ *  Here is a outline of how to use the task and a description
+ *  of different parameters and used system properties.
+ * </p>
+ *
+ * <p>
+ *
+ * <table border=1>
+ *  <tr>
+ *   <td valign=top><b>Attribute</b></td>
+ *   <td valign=top><b>Description</b></td>
+ *   <td valign=top><b>Required</b></td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    outdir
+ *   </td>
+ *   <td>
+ *    What dir to put the actual the generated file
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *   <td>
+ *    tofile
+ *   </td>
+ *   <td>
+ *    The relative path to where the generated file should be
+ *    copied. That is the actual location of the generated file
+ *    will be <code>outdir</code>/<code>tofile</code>
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    template
+ *   </td>
+ *   <td>
+ *    The file which describes what the page should look like
+ *   </td>
+ *   <td>
+ *    Yes
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    title
+ *   </td>
+ *   <td>
+ *    The page's title
+ *   </td>
+ *   <td>
+ *    No, default is ""
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    description
+ *   </td>
+ *   <td>
+ *    The page's description
+ *   </td>
+ *   <td>
+ *    No, default is ""
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    disable
+ *   </td>
+ *   <td>
+ *    Allows you to disable certain links. This attribute is very ad hoc.
+ *    It will use the properties <code>htdocs.link.disabled.class</code>
+ *    and <code>htdocs.link.enabled.class</code>. The task will then use the
+ *    values of these properties to generate the file.
+ *   </td>
+ *   <td>
+ *    No
+ *   </td>
+ *  </tr>
+ *  <tr>
+ *   <td>
+ *    javadocRelPath
+ *   </td>
+ *   <td>
+ *    Relative path (from outdir) to javadocs.
+ *   </td>
+ *   <td>
+ *    ../../javadoc
+ *   </td>
+ *  </tr>
+ * </table>
+ * <p>
+ *  <b>Note:</b> instead of using the attributes <code>fromfile</code> and
+ *  <code>tofile</code> one can use filesets. It will simply run through
+ *  and perform the task on all given files.
+ * </p>
+ *
+ */
+
+public class MakeHTMLTask
+  extends Task
+{
+  private final static String TIMESTAMP
+    = new SimpleDateFormat("EE MMMM d yyyy, HH:mm:ss", Locale.ENGLISH)
+    .format(new Date());
+  private final static String YEAR
+    = new SimpleDateFormat("yyyy",  Locale.ENGLISH).format(new Date());
+
+  private String projectName = "";
+  private boolean do_manpage = false;
+  private String javadocRelPath = "../../javadoc";
+
+  /**
+   * The source file
+   */
+  private String fromFile;
+
+  /**
+   * Target directory, where everything will end up
+   */
+  private File outdir;
+
+  /**
+   * The relative path to the target file from output dir
+   */
+  private File toFile;
+
+  /**
+   * File's title
+   */
+  private String title;
+
+  /**
+   * Description
+   */
+  private String description;
+
+  /**
+   * Template file
+   */
+  private File template;
+
+  /**
+   * Bundle list
+   */
+  private String bundleList;
+
+  private final ArrayList<ResourceCollection> filesets = new ArrayList<ResourceCollection>();
+  private String disable;
+
+  private final Map<String, HtmlFragment> fragments = new HashMap<String,HtmlFragment>();
+
+  public void setFromfile(String s) {
+    fromFile = s;
+  }
+
+  public void setTofile(String s) {
+    toFile = new File(s);
+  }
+
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  @Override
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  public void setOutdir(String s) {
+    outdir = new File(s);
+  }
+
+  public void setTemplate(String template) {
+    this.template = new File(template);
+  }
+
+  public void setBundleList(String bundleList) {
+    this.bundleList = bundleList;
+  }
+
+  public void setManstyle(String manstyle) {
+    this.do_manpage = true;
+  }
+
+
+  public void setDisable(String disabled) {
+    this.disable = disabled;
+  }
+
+  public void setJavadocRelPath(String s) {
+    this.javadocRelPath = s;
+  }
+
+  public void addFileset(FileSet fs) {
+    filesets.add(fs);
+  }
+
+  public void addConfiguredHtmlFragment(HtmlFragment fragment) {
+    final String name = fragment.getName();
+    if (name == null) {
+      throw new BuildException("Nested HTML-fragments must have a name");
+    }
+    if (null==fragment.getFromFile()) {
+      throw new BuildException("Nested HTML-fragments must have a from file");
+    }
+    fragments.put(name, fragment);
+  }
+
+
+
+  @Override
+  public void execute() {
+    final Project proj = getProject();
+    this.projectName = proj.getName();
+
+    if (template == null) {
+      throw new BuildException("template must be set");
+    }
+    if (title == null) {
+      title = "";
+    }
+    if (description == null) {
+      description = "";
+    }
+
+    if (filesets.isEmpty() && fromFile == null && toFile == null) {
+      throw new BuildException("Need to specify tofile and fromfile or give a fileset");
+    }
+
+    if (filesets.isEmpty()) {
+      // log("Project base is: " + getProject().getBaseDir());
+      // log("Attempting to transform: " + fromFile);
+      if (!FileUtils.isAbsolutePath(fromFile)) {
+        fromFile = getProject().getBaseDir() + File.separator + fromFile;
+      }
+      transform(fromFile, toFile.toString());
+    } else {
+      if (fromFile != null) {
+        throw new BuildException("Can not specify fromfile when using filesets");
+      }
+      if (toFile != null) {
+        throw new BuildException("Can not specify tofile when using filesets");
+      }
+
+      for (final Object element : filesets) {
+        final FileSet fs = (FileSet) element;
+        final DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+        final String[] files = ds.getIncludedFiles();
+
+        for (final String file : files) {
+          transform(new File(fs.getDir(getProject()),
+                             file).getAbsolutePath(), file);
+        }
+      }
+    }
+  }
+
+  private void transform(String fromFile, String toFile) {
+    if (fromFile == null) {
+      throw new BuildException("fromfile must be set");
+    }
+    if (toFile == null) {
+      throw new BuildException("tofile must be set");
+    }
+
+    try {
+      final Project proj = getProject();
+      File tmp = new File(outdir, toFile).getParentFile();
+
+      if (!tmp.exists()) {
+        if (tmp.exists() || !tmp.mkdirs()) {
+          throw new IOException("Could not create " + tmp);
+        }
+      }
+
+      tmp = new File(toFile);
+      String pathToRoot = ".";
+
+      while ((tmp = tmp.getParentFile()) != null) {
+        pathToRoot = pathToRoot + "/..";
+      }
+
+      // Compute the relative path from directory holding the toFile
+      // to the javadoc direcotry.
+      String pathToOutDir = "";
+      tmp = new File(outdir, toFile).getParentFile();
+      while ((tmp = tmp.getParentFile()) != null && tmp.equals(outdir)) {
+        pathToOutDir = pathToOutDir + "../";
+      }
+      final String pathToJavadocDir = pathToOutDir + javadocRelPath;
+
+      String content = FileUtil.loadFile(template.toString());
+      content = Util.replace(content, "$(LINKS)", links());
+      content = Util.replace(content, "$(MAIN)", FileUtil.loadFile(fromFile));
+      for (final Object element : fragments.keySet()) {
+        final String key = (String) element;
+        final HtmlFragment frag = fragments.get(key);
+        final String linkText = frag.getLinkText();
+        if (null!=linkText && 0<linkText.length()) {
+          final String fragLink = "<a href=\"#" +key +"\">" +linkText +"</a>";
+          content = Util.replace(content, "$("+key +"_LINK)", fragLink);
+        }
+        String fragCont = FileUtil.loadFile(frag.getFromFile().getPath());
+        if (null!=fragCont && 0<fragCont.length()) {
+          fragCont = "<a name=\"" +key +"\"></a>\n" + fragCont;
+        }
+        content = Util.replace(content, "$("+key +")", fragCont);
+      }
+      content = Util.replace(content, "$(TITLE)", title);
+      content = Util.replace(content, "$(DESC)", description);
+      content = Util.replace(content, "$(TSTAMP)", TIMESTAMP);
+      content = Util.replace(content, "$(YEAR)", YEAR);
+      content = Util.replace(content, "$(USER)",
+                             System.getProperty("user.name"));
+      content = Util.replace(content, "$(VERSION)",
+                             proj.getProperty("version"));
+      content = Util.replace(content, "$(VERSION_PREV)",
+                             proj.getProperty("version.previous"));
+      content = Util.replace(content, "$(KF_VERSION)",
+                             proj.getProperty("kf_version"));
+      content = Util.replace(content, "$(BASE_VERSION)",
+                             proj.getProperty("base_version"));
+      content = Util.replace(content, "$(BASE_URL)",
+                             proj.getProperty("base.url"));
+      content = Util.replace(content, "$(DISTNAME)",
+                             proj.getProperty("distname"));
+      content = Util.replace(content, "$(DISTRIB_NAME)",
+                             proj.getProperty("distrib.name"));
+      content = Util.replace(content, "$(RELEASE_NAME)",
+                             proj.getProperty("release.name"));
+      content = Util.replace(content, "$(RELEASE_DATE)",
+                             proj.getProperty("release.date"));
+      content = Util.replace(content, "$(MESSAGE)",
+                             proj.getProperty("release"));
+      content = Util.replace(content, "$(BUNDLE_LIST)", bundleList);
+      content = Util.replace(content, "$(ROOT)", pathToRoot);
+      content = Util.replace(content, "$(JAVADOC)",
+                             proj.getProperty("JAVADOC"));
+      content = Util.replace(content, "$(CLASS_NAVIGATION)",
+                             proj.getProperty("css_navigation_enabled"));
+      content = Util.replace(content, "$(SVN_REPO_URL)",
+                             proj.getProperty("svn.repo.url"));
+      content = Util.replace(content, "$(SVN_TAG)",proj.getProperty("svn.tag"));
+      content = Util.replace(content, "$(JAVADOCPATH)", pathToJavadocDir);
+      content = Util.replace(content, "$(JAVADOCLINK)",
+                             pathToJavadocDir + "/index.html?");
+
+      // Used for bundle_doc generation
+      if (do_manpage) {
+        content = Util.replace(content, "$(BUNDLE_NAME)", this.projectName);
+        content = Util.replace(content, "$(BUNDLE_VERSION)",
+                               proj.getProperty("bmfa.Bundle-Version"));
+
+        final BundleArchives bas = getBundleArchives();
+
+        // Create links to jardoc for bundles built from this project
+        content = Util.replace(content, "$(BUNDLE_JARDOCS)", basToString(bas));
+
+        content = Util.replace(content, "$(BUNDLE_EXPORT_PACKAGE)",
+                               getExportPkgs(bas, pathToJavadocDir));
+
+        // Replce H1-H3 headers to man page style, if manpage style
+        content = Util.replace(content, "<h1", "<h1 class=\"man\"");
+        content = Util.replace(content, "<H1", "<h1 class=\"man\"");
+        content = Util.replace(content, "<h2", "<h2 class=\"man\"");
+        content = Util.replace(content, "<H2", "<h2 class=\"man\"");
+        content = Util.replace(content, "<h3", "<h3 class=\"man\"");
+        content = Util.replace(content, "<H3", "<h3 class=\"man\"");
+      }
+
+      final String s = proj.getProperty("navigation_pages");
+      final String navEnabled = proj.getProperty("css_navigation_enabled");
+      final String navDisabled = proj.getProperty("css_navigation_disabled");
+      // System.out.println("Navigation pages: " + s);
+      if (s != null) {
+        final String[] navPages = Util.splitwords(s);
+        for (final String navPage : navPages) {
+          // System.out.println("Checking: " + navPages[i]);
+          if (disable != null && disable.equals(navPage)) {
+            content = Util.replace(content,
+                                   "$(CLASS_NAVIGATION_" + navPage + ")",
+                                   navDisabled);
+          }
+          else {
+            content = Util.replace(content,
+                                   "$(CLASS_NAVIGATION_" + navPage + ")",
+                                   navEnabled);
+          }
+        }
+      }
+
+      FileUtil.writeStringToFile(new File(outdir, toFile), content);
+      log("Created: " + new File(outdir, toFile));
+    } catch (final IOException e) {
+      e.printStackTrace();
+      throw new BuildException(e);
+    } catch (final Exception e) {
+      e.printStackTrace();
+      throw new BuildException(e);
+    }
+  }
+
+  private static final String LINK_BASE = "htdocs.link.";
+  private static final String LINK_ID = LINK_BASE + "id.";
+  private static final String LINK_TYPE = LINK_BASE + "type.";
+  private static final String LINK_NAME = LINK_BASE + "name.";
+  private static final String LINK_URL = LINK_BASE + "url.";
+  private static final String CSS_CLASS_ENABLED = "htdocs.link.enabled.class";
+  private static final String CSS_CLASS_DISABLED = "htdocs.link.disabled.class";
+
+  private String links() {
+    final Project proj = getProject();
+    final StringBuffer buf = new StringBuffer();
+
+    for (int i = 0; ; i++) {
+      final String id   = proj.getProperty(LINK_ID + i);
+
+      if (id == null) {
+        break;
+      }
+
+      final String type = proj.getProperty(LINK_TYPE + i);
+      if (type == null) {
+        throw new BuildException("must set htdocs.link.type." + i);
+      }
+
+      if (type.equals("separator")) {
+        buf.append("<p></p>");
+
+      } else if (type.equals("link")) {
+
+        final String name = proj.getProperty(LINK_NAME + i);
+        final String url  = proj.getProperty(LINK_URL + i);
+        if (name == null) {
+          throw new BuildException("Name not set for htdocs.link.url." + i);
+        }
+
+        String cssClass = null;
+
+        if (disable != null && disable.equals(id)) {
+          cssClass = getProject().getProperty(CSS_CLASS_DISABLED);
+        } else {
+          cssClass = getProject().getProperty(CSS_CLASS_ENABLED);
+        }
+
+        buf.append("<a class=\"" + cssClass + "\" href=\"" + url
+                   + "\">" + name + "</a><br/>\n");
+      } else {
+        throw new BuildException("Do not recognize type " + type);
+      }
+    }
+
+    return buf.toString();
+  }
+
+  /**
+   * Loads the bundle archives built from this project.
+   * <p>
+   * The jar files to analyze is determined from:
+   * <ul>
+   * <li>The project property named <code>jarfile</code>. This is used to create
+   * a file set with dir set to the directory part of the property value that
+   * selects the file named by the file name part of the property value.</li>
+   * <li>The project properties <code>jars.dir</code> and
+   * <code>jardir.name</code> (set by all projects based on
+   * <code>bundlebuild.xml</code>. The file set derived from these properties
+   * will have its dir-property set to the value <code>jars.dir</code> and an
+   * includes pattern of the form
+   * <code>${jardir.name}/**/*.jar</code>.
+   * <li>The file set with id <code>docbuild.jarfiles</code>.
+   * </ul>
+   *
+   * @return bundle archives object holding the bundle archives selected by the
+   *         file sets described above or null if no file set was defined.
+   */
+  private BundleArchives getBundleArchives() {
+    final List<ResourceCollection> fileSets = new ArrayList<ResourceCollection>();
+    final Project proj = getProject();
+
+    // File set for bundlebuild.xml properties
+    final String jarsDir = proj.getProperty("jars.dir");
+    if (null != jarsDir && 0 < jarsDir.length()) {
+      final File file = new File(jarsDir);
+      if (file.exists()) {
+        final FileSet fileSet = new FileSet();
+        fileSet.setProject(proj);
+        fileSet.setDir(file);
+        final FilenameSelector fns = new FilenameSelector();
+        fns.setName(proj.getProperty("jardir.name") + "/**/*.jar");
+        fileSet.add(fns);
+        fileSet.setExcludes("**/*-source.jar,**/*-javadoc.jar");
+        fileSets.add(fileSet);
+        log("Found build results (bundlebuild): " + fileSet, Project.MSG_DEBUG);
+      }
+    }
+
+    // File set for jarfile-property (e.g., framework.jar)
+    final String jarfile = proj.getProperty("jarfile");
+    if (null!=jarfile && 0<jarfile.length()) {
+      final File file = new File(jarfile);
+      if (file.exists()) {
+        final FileSet fileSet = new FileSet();
+        fileSet.setProject(proj);
+        fileSet.setDir(file.getParentFile());
+        final FilenameSelector fns = new FilenameSelector();
+        fns.setName(file.getName());
+        fileSet.add(fns);
+        fileSets.add(fileSet);
+        log("Found build results (jarfile): " + fileSet, Project.MSG_DEBUG);
+      }
+    }
+
+    // FileSet defined with id (for bundle overview documentation).
+    final FileSet docbuildeFileSet
+      = (FileSet) proj.getReference("docbuild.jarfiles");
+    if (null!=docbuildeFileSet) {
+      fileSets.add(docbuildeFileSet);
+      log("Found build results (docbuild.jarfiles): " + docbuildeFileSet,
+          Project.MSG_DEBUG);
+    }
+
+    if (0 < fileSets.size()) {
+      final BundleArchives bas = new BundleArchives(this, fileSets, true);
+      bas.doProviders();
+      return bas;
+    }
+    return null;
+  }
+
+  static String replace(String src, String a, String b) {
+    return Util.replace(src, a, b == null ? "" : b);
+  }
+
+  /** Template row for an exported package. */
+  private static final String packageListRow
+    = " <tr><td>${namelink}</td><td align=\"center\">${version}</td><td>${providers}</td></tr>\n";
+
+  /** The table heading for the list of exported packages. */
+  private static final String packageListHeading
+    = "<table class=\"man\">\n <tr><th>Package</th><th>Version</th><th>Providers</th></tr>\n";
+
+  /** The table footer for the list of exported packages. */
+  private static final String packageListFooter
+    = "</table>\n";
+
+  /**
+   * Return HTML-formated String with one exported package per line, linking the
+   * package name to its javadoc (if present).
+   *
+   * @param bas
+   *          Bundle archives object that holds the set of packages and the
+   *          exporters.
+   * @param pathToJavadocDir
+   *          Relative path from the file we are generating to the javadoc
+   *          directory.
+   * @return HTML string with all exported packages.
+   */
+  private String getExportPkgs(final BundleArchives bas, final String pathToJavadocDir) {
+    final StringBuffer res = new StringBuffer();
+
+    if (null != bas) {
+      final boolean javadocPresent = pathToJavadocDir != null && 0<pathToJavadocDir.length();
+      for (final Entry<String, SortedMap<Version, SortedSet<BundleArchive>>> pkgEntry: bas.allExports.entrySet()) {
+        final String pkg = pkgEntry.getKey().toString();
+        final Map<Version,SortedSet<BundleArchive>> verToProvides = pkgEntry.getValue();
+
+        final String docFile = replace(pkg, ".", "/") +BundleHTMLExtractorTask.PACKAGE_SUMMARY_HTML;
+        final String docPath = pathToJavadocDir +"/index.html?" +docFile;
+        final File f = new File(outdir +File.separator
+                                +pathToJavadocDir.replace('/', File.separatorChar)
+                                +File.separator
+                                +docFile.replace('/', File.separatorChar));
+        for (final Entry<Version,SortedSet<BundleArchive>> vtpEntry : verToProvides.entrySet()) {
+          final String version = vtpEntry.getKey().toString();
+          final Set<BundleArchive> providers = vtpEntry.getValue();
+
+          String row = packageListRow;
+          if(javadocPresent) {
+            if (!f.exists()) {
+              row = replace(row, "${namelink}", "${name}");
+            } else {
+              row = replace(row,
+                            "${namelink}",
+                            "<a target=\"_top\" href=\"${javadoc}\">${name}</a>");
+            }
+          } else {
+            row = replace(row, "${namelink}", "${name}");
+          }
+          row = replace(row, "${name}", pkg);
+          row = replace(row, "${version}", version.toString());
+          row = replace(row, "${javadoc}", docPath);
+          row = replace(row, "${providers}", providersToString(providers));
+
+          res.append(row);
+        }
+      }
+    }
+    if (0<res.length()) {
+      return packageListHeading + res.toString() + packageListFooter;
+    } else {
+      return "No exported packages.";
+    }
+  }
+
+  private String basToString(final BundleArchives bas) {
+    final StringBuffer res = new StringBuffer();
+
+    if (null != bas) {
+      for (final Object element : bas.allBundleArchives) {
+        final BundleArchive ba = (BundleArchive) element;
+
+        if (0 < res.length()) {
+          res.append("<br>\n");
+        }
+        res.append(providerToString(ba));
+      }
+    }
+    return res.toString();
+  }
+
+  private String providersToString(final Set<BundleArchive> providers) {
+    final StringBuffer res = new StringBuffer();
+
+    for (final BundleArchive ba : providers) {
+      if (0 < res.length()) {
+        res.append(", ");
+      }
+      res.append(providerToString(ba));
+    }
+    return res.toString();
+  }
+
+  private static final String packageListProviderTemplate
+    = "<a target=\"_top\" href=\"../../jars/index.html?bundle=${bundledoc.uri}\">${bundle.name.short}</a>";
+
+  private String providerToString(final BundleArchive ba) {
+    final String relPath = replace(ba.relPath, ".jar", "");
+    final String htmlURI = replace(relPath, "\\", "/")
+      + BundleHTMLExtractorTask.HTML;
+    final String bundleShortName = replace(ba.file.getName(), ".jar", "");
+
+    String provider = replace(packageListProviderTemplate, "${bundledoc.uri}",
+                              htmlURI);
+    provider = replace(provider, "${bundle.name.short}", bundleShortName);
+    return provider;
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/MethodAnalyserASM.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/MethodAnalyserASM.java
new file mode 100644
index 0000000..7f803ba
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/MethodAnalyserASM.java
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2003-2009, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import org.apache.tools.ant.Project;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+
+
+/**
+ * Visitor implementation that populates a BundlePackagesInfo object
+ * with data about the method it visits.
+ */
+public class MethodAnalyserASM
+  implements MethodVisitor
+{
+
+  // The ClassAnalyserASM instance that this method analyzer is
+  // belonging to.
+  private final ClassAnalyserASM ca;
+
+  private final String methodName;
+
+  public MethodAnalyserASM(final ClassAnalyserASM ca, final String name)
+  {
+    this.ca     = ca;
+    this.methodName = name;
+  }
+
+  /*
+   * Visits the default value of this annotation interface method.
+   *
+   * @return a visitor to the visit the actual default value of this
+   *         annotation interface method, or <tt>null</tt> if this visitor
+   *         is not interested in visiting this default value. The 'name'
+   *         parameters passed to the methods of this annotation visitor are
+   *         ignored. Moreover, exactly one visit method must be called on this
+   *         annotation visitor, followed by visitEnd.
+   */
+  public AnnotationVisitor visitAnnotationDefault()
+  {
+    return null;
+  }
+
+  /*
+   * Visits an annotation of this method.
+   *
+   * @param desc the class descriptor of the annotation class.
+   * @param visible <tt>true</tt> if the annotation is visible at runtime.
+   * @return a visitor to visit the annotation values, or <tt>null</tt> if
+   *         this visitor is not interested in visiting this annotation.
+   */
+  public AnnotationVisitor visitAnnotation(String desc, boolean visible)
+  {
+    return null;
+  }
+
+  /*
+   * Visits an annotation of a parameter this method.
+   *
+   * @param parameter the parameter index.
+   * @param desc the class descriptor of the annotation class.
+   * @param visible <tt>true</tt> if the annotation is visible at runtime.
+   * @return a visitor to visit the annotation values, or <tt>null</tt> if
+   *         this visitor is not interested in visiting this annotation.
+   */
+  public AnnotationVisitor visitParameterAnnotation(
+                                             int parameter,
+                                             String desc,
+                                             boolean visible)
+  {
+    return null;
+  }
+
+  /*
+   * Visits a non standard attribute of this method.
+   *
+   * @param attr an attribute.
+   */
+  public void visitAttribute(Attribute attr)
+  {
+  }
+
+  /*
+   * Starts the visit of the method's code, if any (i.e. non abstract method).
+   */
+  public void visitCode()
+  {
+    ca.task.log("  method '" +methodName +"'.", Project.MSG_DEBUG);
+  }
+
+  /*
+   * Visits the current state of the local variables and operand stack
+   * elements. This method must(*) be called <i>just before</i> any
+   * instruction <b>i</b> that follows an unconditional branch instruction
+   * such as GOTO or THROW, that is the target of a jump instruction, or that
+   * starts an exception handler block. The visited types must describe the
+   * values of the local variables and of the operand stack elements <i>just
+   * before</i> <b>i</b> is executed. <br> <br> (*) this is mandatory only
+   * for classes whose version is greater than or equal to
+   * {@link Opcodes#V1_6 V1_6}. <br> <br> Packed frames are basically
+   * "deltas" from the state of the previous frame (very first frame is
+   * implicitly defined by the method's parameters and access flags): <ul>
+   * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
+   * locals as the previous frame and with the empty stack.</li> <li>{@link Opcodes#F_SAME1}
+   * representing frame with exactly the same locals as the previous frame and
+   * with single value on the stack (<code>nStack</code> is 1 and
+   * <code>stack[0]</code> contains value for the type of the stack item).</li>
+   * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
+   * the same as the locals in the previous frame, except that additional
+   * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
+   * <code>local</code> elements contains values representing added types).</li>
+   * <li>{@link Opcodes#F_CHOP} representing frame with current locals are
+   * the same as the locals in the previous frame, except that the last 1-3
+   * locals are absent and with the empty stack (<code>nLocals</code> is 1,
+   * 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
+   * data.</li> </li> </ul>
+   *
+   * @param type the type of this stack map frame. Must be
+   *        {@link Opcodes#F_NEW} for expanded frames, or
+   *        {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
+   *        {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+   *        {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
+   *        frames.
+   * @param nLocal the number of local variables in the visited frame.
+   * @param local the local variable types in this frame. This array must not
+   *        be modified. Primitive types are represented by
+   *        {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+   *        {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+   *        {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+   *        {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+   *        represented by a single element). Reference types are represented
+   *        by String objects (representing internal names), and uninitialized
+   *        types by Label objects (this label designates the NEW instruction
+   *        that created this uninitialized value).
+   * @param nStack the number of operand stack elements in the visited frame.
+   * @param stack the operand stack types in this frame. This array must not
+   *        be modified. Its content has the same format as the "local" array.
+   */
+  public void visitFrame(
+                  int type,
+                  int nLocal,
+                  Object[] local,
+                  int nStack,
+                  Object[] stack)
+  {
+  }
+
+  // -------------------------------------------------------------------------
+  // Normal instructions
+  // -------------------------------------------------------------------------
+
+  /*
+   * Visits a zero operand instruction.
+   *
+   * @param opcode the opcode of the instruction to be visited. This opcode is
+   *        either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
+   *        ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
+   *        FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
+   *        DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
+   *        DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
+   *        DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
+   *        DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
+   *        FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
+   *        LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
+   *        I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
+   *        I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
+   *        FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
+   *        MONITORENTER, or MONITOREXIT.
+   */
+  public void visitInsn(int opcode)
+  {
+  }
+
+  /*
+   * Visits an instruction with a single int operand.
+   *
+   * @param opcode the opcode of the instruction to be visited. This opcode is
+   *        either BIPUSH, SIPUSH or NEWARRAY.
+   * @param operand the operand of the instruction to be visited.<br> When
+   *        opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
+   *        and Byte.MAX_VALUE.<br> When opcode is SIPUSH, operand value
+   *        should be between Short.MIN_VALUE and Short.MAX_VALUE.<br> When
+   *        opcode is NEWARRAY, operand value should be one of
+   *        {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
+   *        {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
+   *        {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
+   *        {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+   */
+  public void visitIntInsn(int opcode, int operand)
+  {
+  }
+
+  /*
+   * Visits a local variable instruction. A local variable instruction is an
+   * instruction that loads or stores the value of a local variable.
+   *
+   * @param opcode the opcode of the local variable instruction to be visited.
+   *        This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
+   *        LSTORE, FSTORE, DSTORE, ASTORE or RET.
+   * @param var the operand of the instruction to be visited. This operand is
+   *        the index of a local variable.
+   */
+  public void visitVarInsn(int opcode, int var)
+  {
+  }
+
+  /*
+   * Visits a type instruction. A type instruction is an instruction that
+   * takes the internal name of a class as parameter.
+   *
+   * @param opcode the opcode of the type instruction to be visited. This
+   *        opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+   * @param type the operand of the instruction to be visited. This operand
+   *        must be the internal name of an object or array class (see {@link
+   *        Type#getInternalName() getInternalName}).
+   */
+  public void visitTypeInsn(int opcode, String type)
+  {
+    ca.addReferencedType(Type.getObjectType(type));
+  }
+
+  /*
+   * Visits a field instruction. A field instruction is an instruction that
+   * loads or stores the value of a field of an object.
+   *
+   * @param opcode the opcode of the type instruction to be visited. This
+   *        opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+   * @param owner the internal name of the field's owner class (see {@link
+   *        Type#getInternalName() getInternalName}).
+   * @param name the field's name.
+   * @param desc the field's descriptor (see {@link Type Type}).
+   */
+  public void visitFieldInsn(int opcode, String owner, String name, String desc)
+  {
+    ca.addReferencedType(Type.getObjectType(owner));
+    ca.addReferencedType(Type.getType(desc));
+  }
+
+  /*
+   * Visits a method instruction. A method instruction is an instruction that
+   * invokes a method.
+   *
+   * @param opcode the opcode of the type instruction to be visited. This
+   *        opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC,
+   *        INVOKEINTERFACE or INVOKEDYNAMIC.
+   * @param owner the internal name of the method's owner class (see {@link
+   *        Type#getInternalName() getInternalName})
+   *        or {@link org.objectweb.asm.Opcodes#INVOKEDYNAMIC_OWNER}.
+   * @param name the method's name.
+   * @param desc the method's descriptor (see {@link Type Type}).
+   */
+  public void visitMethodInsn(int opcode,
+                              String owner,
+                              String name,
+                              String desc)
+  {
+    ca.addReferencedType(Type.getObjectType(owner));
+
+    Type[] argTypes = Type.getArgumentTypes(desc);
+    for (int i=0; argTypes!=null && i<argTypes.length; i++) {
+      ca.addReferencedType(argTypes[i]);
+    }
+    ca.addReferencedType(Type.getReturnType(desc));
+  }
+
+  /*
+   * Visits a jump instruction. A jump instruction is an instruction that may
+   * jump to another instruction.
+   *
+   * @param opcode the opcode of the type instruction to be visited. This
+   *        opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+   *        IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
+   *        IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+   * @param label the operand of the instruction to be visited. This operand
+   *        is a label that designates the instruction to which the jump
+   *        instruction may jump.
+   */
+  public void visitJumpInsn(int opcode, Label label)
+  {
+  }
+
+  /*
+   * Visits a label. A label designates the instruction that will be visited
+   * just after it.
+   *
+   * @param label a {@link Label Label} object.
+   */
+  public void visitLabel(Label label)
+  {
+  }
+
+  // -------------------------------------------------------------------------
+  // Special instructions
+  // -------------------------------------------------------------------------
+
+  /*
+   * Visits a LDC instruction.
+   *
+   * @param cst the constant to be loaded on the stack. This parameter must be
+   *        a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+   *        {@link Double} a {@link String} (or a {@link Type} for
+   *        <tt>.class</tt> constants, for classes whose version is 49.0 or
+   *        more).
+   */
+  public void visitLdcInsn(Object cst)
+  {
+  }
+
+  /*
+   * Visits an IINC instruction.
+   *
+   * @param var index of the local variable to be incremented.
+   * @param increment amount to increment the local variable by.
+   */
+  public void visitIincInsn(int var, int increment)
+  {
+  }
+
+  /*
+   * Visits a TABLESWITCH instruction.
+   *
+   * @param min the minimum key value.
+   * @param max the maximum key value.
+   * @param dflt beginning of the default handler block.
+   * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
+   *        the beginning of the handler block for the <tt>min + i</tt> key.
+   */
+  public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)
+  {
+  }
+
+  /*
+   * Visits a LOOKUPSWITCH instruction.
+   *
+   * @param dflt beginning of the default handler block.
+   * @param keys the values of the keys.
+   * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
+   *        the beginning of the handler block for the <tt>keys[i]</tt> key.
+   */
+  public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)
+  {
+  }
+
+  /*
+   * Visits a MULTIANEWARRAY instruction.
+   *
+   * @param desc an array type descriptor (see {@link Type Type}).
+   * @param dims number of dimensions of the array to allocate.
+   */
+  public void visitMultiANewArrayInsn(String desc, int dims)
+  {
+    ca.addReferencedType(Type.getType(desc));
+  }
+
+  // -------------------------------------------------------------------------
+  // Exceptions table entries, debug information, max stack and max locals
+  // -------------------------------------------------------------------------
+
+  /*
+   * Visits a try catch block.
+   *
+   * @param start beginning of the exception handler's scope (inclusive).
+   * @param end end of the exception handler's scope (exclusive).
+   * @param handler beginning of the exception handler's code.
+   * @param type internal name of the type of exceptions handled by the
+   *        handler, or <tt>null</tt> to catch any exceptions (for "finally"
+   *        blocks).
+   * @throws IllegalArgumentException if one of the labels has already been
+   *         visited by this visitor (by the {@link #visitLabel visitLabel}
+   *         method).
+   */
+  public void visitTryCatchBlock(Label start,
+                                 Label end,
+                                 Label handler,
+                                 String type)
+  {
+    if (null!=type) {
+      ca.addReferencedType(Type.getObjectType(type));
+    }
+  }
+
+  /*
+   * Visits a local variable declaration.
+   *
+   * @param name the name of a local variable.
+   * @param desc the type descriptor of this local variable.
+   * @param signature the type signature of this local variable. May be
+   *        <tt>null</tt> if the local variable type does not use generic
+   *        types.
+   * @param start the first instruction corresponding to the scope of this
+   *        local variable (inclusive).
+   * @param end the last instruction corresponding to the scope of this local
+   *        variable (exclusive).
+   * @param index the local variable's index.
+   * @throws IllegalArgumentException if one of the labels has not already
+   *         been visited by this visitor (by the
+   *         {@link #visitLabel visitLabel} method).
+   */
+  public void visitLocalVariable(
+                          String name,
+                          String desc,
+                          String signature,
+                          Label start,
+                          Label end,
+                          int index)
+  {
+    ca.addReferencedType(Type.getType(desc));
+  }
+
+  /*
+   * Visits a line number declaration.
+   *
+   * @param line a line number. This number refers to the source file from
+   *        which the class was compiled.
+   * @param start the first instruction corresponding to this line number.
+   * @throws IllegalArgumentException if <tt>start</tt> has not already been
+   *         visited by this visitor (by the {@link #visitLabel visitLabel}
+   *         method).
+   */
+  public void visitLineNumber(int line, Label start)
+  {
+  }
+
+  /*
+   * Visits the maximum stack size and the maximum number of local variables
+   * of the method.
+   *
+   * @param maxStack maximum stack size of the method.
+   * @param maxLocals maximum number of local variables for the method.
+   */
+  public void visitMaxs(int maxStack, int maxLocals)
+  {
+  }
+
+  /*
+   * Visits the end of the method. This method, which is the last one to be
+   * called, is used to inform the visitor that all the annotations and
+   * attributes of the method have been visited.
+   */
+  public void visitEnd()
+  {
+  }
+
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/OSGiPackage.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/OSGiPackage.java
new file mode 100644
index 0000000..3532de1
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/OSGiPackage.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2005, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+
+/**
+ * @author Kaspar Weilenmann <kaspar at weilenmann.se>
+ */
+public class OSGiPackage {
+
+  // private fields
+
+  private String name = null;
+  private String version = null;
+  private String prefix = null;
+
+
+  // public methods
+
+  public String getName() { return name; }
+  public void setName(String name) { this.name = name; }
+
+  public String getVersion() { return version; }
+  public void setVersion(String version) { this.version = version; }
+
+  public String getPrefix() { return prefix; }
+  public void setPrefix(String prefix) { this.prefix = prefix; }
+
+} // OSGiPackage
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/Util.java b/ant/src/org/knopflerfish/ant/taskdefs/bundle/Util.java
new file mode 100644
index 0000000..11c7977
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/Util.java
@@ -0,0 +1,870 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.ant.taskdefs.bundle;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.Version;
+
+
+public class Util {
+
+  // Type names used for types OSGi attributes in manifest headers.
+  private static final String DOUBLE_TYPE = "Double";
+  private static final String LONG_TYPE = "Long";
+  private static final String LIST_TYPE = "List";
+  private static final String STRING_TYPE = "String";
+  private static final String VERSION_TYPE = "Version";
+
+
+  /**
+   * Parse strings of format:
+   *
+   * ENTRY (, ENTRY)*
+   *
+   * @param d Directive being parsed
+   * @param s String to parse
+   * @return A HashSet with enumeration or null if enumeration string was null.
+   * @exception IllegalArgumentException If syntax error in input string.
+   */
+  public static Set<String> parseEnumeration(String d, String s)
+  {
+    final HashSet<String> result = new HashSet<String>();
+    if (s != null) {
+      final AttributeTokenizer at = new AttributeTokenizer(s);
+      do {
+        final String key = at.getKey(true);
+        if (key == null) {
+          throw new IllegalArgumentException("Directive " + d
+                                             + ", unexpected character at: "
+                                             + at.getRest());
+        }
+        if (!at.getEntryEnd()) {
+          throw new IllegalArgumentException("Directive " + d
+                                             + ", expected end of entry at: "
+                                             + at.getRest());
+        }
+        result.add(key);
+      } while (!at.getEnd());
+      return result;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Parse manifest header values on format:
+   * <pre>
+   * ENTRY (',' ENTRY)*
+   * ENTRY = key (';' key)* (';' PARAM)*
+   * PARAM = attribute (':' TYPE)? '=' value
+   * PARAM = directive ':=' value
+   * TYPE = SCALAR | LIST
+   * SCALAR = 'String' | 'Version' | 'Long' | 'Double'
+   * LIST = 'List<' SCALAR '>'
+   * </pre>
+   *
+   * The default attribute value type is 'String'. For list values the 'List'
+   * and its following '<' are treated as separate tokens to comply with the
+   * OSGi TCK.
+   *
+   * The parse result is one {@link HeaderEntry}-instance for each entry.
+   * If {@code single} is true then the entry only contains one key that can be
+   * accesses by calling {@link HeaderEntry#getKey()}.
+   *
+   * If {@code unique} is true the attribute values in the map are scalars
+   * otherwise the values from different attribute definitions with the same
+   * name are wrapped in a {@code List<?>}.
+   *
+   * @param a Name of attribute being parsed, for error messages.
+   * @param s String to parse.
+   * @param single If true, only allow one key per ENTRY.
+   * @param unique Only allow unique attributes for each ENTRY.
+   * @param single_entry If true, only allow one ENTRY in {@code s}.
+   *
+   * @return List of {@link HeaderEntry}-object, one per entry in {@code s}.
+   *
+   * @exception IllegalArgumentException If syntax error in input string.
+   */
+  public static List<HeaderEntry> parseManifestHeader(String a,
+                                                      String s,
+                                                      boolean single,
+                                                      boolean unique,
+                                                      boolean single_entry)
+  {
+    final List<HeaderEntry> res = new ArrayList<Util.HeaderEntry>();
+
+    if (s != null) {
+      final AttributeTokenizer at = new AttributeTokenizer(s);
+      do {
+        final HeaderEntry he = new HeaderEntry(a, single);
+        String key = at.getKey(single);
+        if (key == null) {
+          final String msg = "Definition, " + a + ", expected key at: "
+              + at.getRest() + ". Key values are terminated "
+              + "by a ';' or a ',' and may not "
+              + "contain unquoted ':', '=' if multiple keys are allowed.";
+          throw new IllegalArgumentException(msg);
+        }
+        he.keys.add(key);
+        if (!single) {
+          while ((key = at.getKey(false)) != null) {
+            he.keys.add(key);
+          }
+        }
+        String param;
+        while ((param = at.getParam()) != null) {
+          final boolean is_directive = at.isDirective();
+          if (is_directive) {
+            if (he.directives.containsKey(param)) {
+              final String msg = "Definition, " + a + ", duplicate directive: "
+                    + param;
+              throw new IllegalArgumentException(msg);
+            }
+            final String valueStr = at.getValue(false);
+            if (valueStr == null) {
+              final String msg = "Definition, " + a + ", expected value for "
+                  + " directive " + param + " at: " + at.getRest();
+              throw new IllegalArgumentException(msg);
+            }
+            he.directives.put(param, valueStr);
+          } else {
+            // Attribute definition with optional type
+            final Object old = he.attributes.get(param);
+            if (old != null && unique) {
+              final String msg = "Definition, " + a + ", duplicate attribute: "
+                                + param;
+              throw new IllegalArgumentException(msg);
+            }
+            final String paramType = at.getParamType();
+            final boolean keepEscape = paramType != null
+                                       && paramType.startsWith("List");
+            final String valueStr = at.getValue(keepEscape);
+            if (valueStr == null) {
+              final String msg = "Definition, " + a + ", expected value for "
+                  + " attribute " + param + " at: " + at.getRest();
+              throw new IllegalArgumentException(msg);
+            }
+            final Object value = toValue(a, param, paramType, valueStr);
+            if (unique) {
+              he.attributes.put(param, value);
+            } else {
+              @SuppressWarnings("unchecked")
+              List<Object> oldValues = (List<Object>) old;
+              if (oldValues == null) {
+                oldValues = new ArrayList<Object>();
+                he.attributes.put(param, oldValues);
+              }
+              oldValues.add(value);
+            }
+          }
+        }
+        if (at.getEntryEnd()) {
+          res.add(he);
+        } else {
+          throw new IllegalArgumentException("Definition, " + a
+              + ", expected end of entry at: " + at.getRest());
+        }
+        if (single_entry && !at.getEnd()) {
+          throw new IllegalArgumentException("Definition, " + a
+              + ", expected end of single entry at: " + at.getRest());
+        }
+      } while (!at.getEnd());
+    }
+
+    return res;
+  }
+
+
+  /**
+   * Convert an attribute value from string to the requested type.
+   *
+   * The types supported are described in
+   * {@link #parseEntries(String, String, boolean, boolean, boolean)}.
+   *
+   * @param a Name of attribute being parsed, for error messages.
+   * @param p Name of parameter to assign the value to, for error messages.
+   * @param type the type to convert to.
+   * @param value the value to convert.
+   * @return attribute value converted to the desired type.
+   */
+  private static Object toValue(String a,
+                                String param,
+                                String type,
+                                String value)
+  {
+    Object res;
+
+    type = type == null ? STRING_TYPE : type.intern();
+    if (STRING_TYPE == type) {
+      res = value;
+    } else if (LONG_TYPE == type) {
+      try {
+        res = new Long(value.trim());
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new
+        IllegalArgumentException("Definition, " +a
+                                 +", expected value of type Long but found '"
+                                 +value +"' for attribute '"
+                                 +param + "'.").initCause(e);
+      }
+    } else if (DOUBLE_TYPE == type) {
+      try {
+        res = new Double(value.trim());
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new
+        IllegalArgumentException("Definition, " +a
+                                 +", expected value of type Double but found '"
+                                 +value +"' for attribute '"
+                                 +param + "'.").initCause(e);
+      }
+    } else if (VERSION_TYPE == type) {
+      try {
+        res = new Version(value);
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new
+        IllegalArgumentException("Definition, " +a
+                                 +", expected value of type Version but found '"
+                                 +value +"' for attribute '"
+                                 +param + "'.").initCause(e);
+      }
+    } else if (type.startsWith(LIST_TYPE)) {
+      String elemType = type.substring(LIST_TYPE.length()).trim();
+      // Let "List" without any "<type>" default to "List<String>"
+      if (elemType.length()>0) {
+        if ('<' != elemType.charAt(0)
+            || elemType.charAt(elemType.length() - 1) != '>') {
+          throw new IllegalArgumentException
+            ("Definition, " + a + ", expected List type definition '"
+                + type + "' for attribute '" + param + "'.");
+        }
+        elemType = elemType.substring(1, elemType.length() - 1).trim().intern();
+      }
+      // The default element type is STRING.
+      if (elemType.length()==0) {
+        elemType = STRING_TYPE;
+      }
+
+      try {
+        final List<String> elements = splitWords(value, ',', STRING_TYPE!=elemType);
+        final List<Object> l = new ArrayList<Object>(elements.size());
+        for (final String elem : elements) {
+          l.add(toValue(a, param, elemType, elem));
+        }
+        res = l;
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new IllegalArgumentException
+          ("Definition, " + a + ", expected '" + type + "' value but found '"
+              + value + "' for attribute '" + param + "'.").initCause(e);
+      }
+    } else {
+        throw new IllegalArgumentException("Definition, " +a
+                                 +", unknown type '" +type +"' for attribute '"
+                                 +param + "'.");
+    }
+    return res;
+  }
+
+  /**
+   * Default whitespace string for splitwords(). Value is <tt>" \t\n\r"</tt>)
+   */
+  protected static String WHITESPACE = " \t\n\r";
+
+  /**
+   * Default citation char for splitwords(). Value is <tt>'"'</tt>
+   */
+  protected static char CITCHAR = '"';
+
+
+  /**
+   * Utility method to split a string into words separated by whitespace.
+   *
+   * <p>
+   * Equivalent to <tt>splitwords(s, WHITESPACE)</tt>
+   * </p>
+   */
+  public static String[] splitwords(String s) {
+    return splitwords(s, WHITESPACE);
+  }
+
+
+  /**
+   * Utility method to split a string into words separated by whitespace.
+   *
+   * <p>
+   * Equivalent to <tt>splitwords(s, WHITESPACE, CITCHAR)</tt>
+   * </p>
+   */
+  public static String[] splitwords(String s, String whiteSpace) {
+    return splitwords(s, whiteSpace, CITCHAR);
+  }
+
+
+  /**
+   * Split a string into words separated by whitespace.
+   * <p>
+   * Citation chars may be used to group words with embedded whitespace.
+   * </p>
+   *
+   * @param s String to split.
+   * @param whiteSpace whitespace to use for splitting. Any of the characters in
+   *          the whiteSpace string are considered whitespace between words and
+   *          will be removed from the result. If no words are found, return an
+   *          array of length zero.
+   * @param citChar Citation character used for grouping words with embedded
+   *          whitespace. Typically '"'
+   */
+  public static String[] splitwords(String s,
+                                     String whiteSpace,
+                                     char citChar) {
+    boolean bCit = false; // true when inside citation chars.
+    final Vector<String> v = new Vector<String>(); // (String) individual words after splitting
+    StringBuffer buf = new StringBuffer();
+    int i = 0;
+
+    while (i < s.length()) {
+      final char c = s.charAt(i);
+
+      if (bCit || whiteSpace.indexOf(c) == -1) {
+        // Build up word until we breaks on either a citation char or whitespace
+        if (c == citChar) {
+          bCit = !bCit;
+        } else {
+          if (buf == null) {
+            buf = new StringBuffer();
+          }
+          buf.append(c);
+        }
+        i++;
+      } else {
+        // found whitespace or end of citation, append word if we have one
+        if (buf != null) {
+          v.addElement(buf.toString());
+          buf = null;
+        }
+
+        // and skip whitespace so we start clean on a word or citation char
+        while ((i < s.length()) && (-1 != whiteSpace.indexOf(s.charAt(i)))) {
+          i++;
+        }
+      }
+    }
+
+    // Add possible remaining word
+    if (buf != null) {
+      v.addElement(buf.toString());
+    }
+
+    // Copy back into an array
+    final String[] r = new String[v.size()];
+    v.copyInto(r);
+
+    return r;
+  }
+
+
+  /**
+   * Split a string into words separated by a separator char.
+   *
+   * If the separator char shall be part of a word it must be escaped with a
+   * '\' (\u005C). One level of escaping is consumed by this method.
+   *
+   * @param s String to split.
+   * @param sepChar separator char to split on.
+   * @param trim trim whitespace from the words if {@code true}.
+   *
+   * @return List with the words of the specified string.
+   */
+  public static List<String> splitWords(String s,
+                                        char sepChar,
+                                        boolean trim)
+  {
+    final List<String> res = new ArrayList<String>();
+    final StringBuffer buf = new StringBuffer();
+    int pos = 0;
+    final int length = s.length();
+
+    boolean esc = false;
+    int end = 0;
+    for (; pos < length; pos++) {
+      if (esc) {
+        esc = false;
+        buf.append(s.charAt(pos));
+        end = buf.length();
+      } else {
+        final char c = s.charAt(pos);
+        if (c == '\\') {
+          esc = true;
+        } else if (c == sepChar) {
+          // trim trailing whitespace.
+          if (trim) {
+            buf.setLength(end);
+          }
+          res.add(buf.toString());
+          buf.setLength(0);
+          end = 0;
+        } else if (Character.isWhitespace(c)) {
+          if (buf.length()>0 || !trim) {
+            buf.append(c);
+          }
+        } else {
+          buf.append(c);
+          end = buf.length();
+        }
+      }
+    }
+    if (esc) {
+      throw new IllegalArgumentException("Value ends on escape character");
+    }
+    // The last element.
+    if (trim) {
+      buf.setLength(end);
+    }
+    res.add(buf.toString());
+
+    return res;
+  }
+
+
+  /**
+   * Replace all occurrences of a substring with another string.
+   *
+   * <p>
+   * The returned string will shrink or grow as necessary depending on the
+   * lengths of <tt>v1</tt> and <tt>v2</tt>.
+   * </p>
+   *
+   * <p>
+   * Implementation note: This method avoids using the standard String
+   * manipulation methods to increase execution speed. Using the
+   * <tt>replace</tt> method does however include two <tt>new</tt> operations in
+   * the case when matches are found.
+   * </p>
+   *
+   *
+   * @param s
+   *          Source string.
+   * @param v1
+   *          String to be replaced with <code>v2</code>.
+   * @param v2
+   *          String replacing <code>v1</code>.
+   * @return Modified string. If any of the input strings are <tt>null</tt>, the
+   *         source string <tt>s</tt> will be returned unmodified. If
+   *         <tt>v1.length == 0</tt>, <tt>v1.equals(v2)</tt> or no occurrences
+   *         of <tt>v1</tt> is found, also return <tt>s</tt> unmodified.
+   */
+  public static String replace(final String s,
+                               final String v1,
+                               final String v2) {
+
+    // return quick when nothing to do
+    if (s == null
+        || v1 == null
+        || v2 == null
+        || v1.length() == 0
+        || v1.equals(v2)) {
+      return s;
+    }
+
+    int ix = 0;
+    final int v1Len = v1.length();
+    int n = 0;
+
+    // count number of occurances to be able to correctly size
+    // the resulting output char array
+    while (-1 != (ix = s.indexOf(v1, ix))) {
+      n++;
+      ix += v1Len;
+    }
+
+    // No occurances at all, just return source string
+    if (n == 0) {
+      return s;
+    }
+
+    // Set up an output char array of correct size
+    int start = 0;
+    final int v2Len = v2.length();
+    final char[] r = new char[s.length() + n * (v2Len - v1Len)];
+    int rPos = 0;
+
+    // for each occurance, copy v2 where v1 used to be
+    while (-1 != (ix = s.indexOf(v1, start))) {
+      while (start < ix) {
+        r[rPos++] = s.charAt(start++);
+      }
+      for (int j = 0; j < v2Len; j++) {
+        r[rPos++] = v2.charAt(j);
+      }
+      start += v1Len;
+    }
+
+    // ...and add all remaining chars
+    ix = s.length();
+    while (start < ix) {
+      r[rPos++] = s.charAt(start++);
+    }
+
+    // ..ouch. this hurts.
+    return new String(r);
+  }
+
+
+  /**
+   * Class for tokenize an attribute string.
+   */
+  static class AttributeTokenizer {
+
+    final String s;
+    int length;
+    int pos = 0;
+
+
+    AttributeTokenizer(final String input) {
+      s = input;
+      length = s.length();
+    }
+
+    // get word (non-whitespace chars) up to the next non-quoted
+    // ',', ';' or ':', '=' if not valueWord is set
+    String getWord(boolean keepEscapse, boolean valueWord) {
+      skipWhite();
+      boolean backslash = false;
+      boolean quote = false;
+      final StringBuffer val = new StringBuffer();
+      int end = 0;
+      loop: for (; pos < length; pos++) {
+        if (backslash) {
+          backslash = false;
+          if (keepEscapse) {
+            val.append('\\');
+          }
+          val.append(s.charAt(pos));
+          end = val.length();
+        } else {
+          final char c = s.charAt(pos);
+          switch (c) {
+          case '"':
+            quote = !quote;
+            end = val.length();
+            break;
+          case '\\':
+            backslash = true;
+            break;
+          case ':':
+          case ',':
+          case ';':
+          case '=':
+            if (!quote && !(valueWord && (c==':' || c=='='))) {
+              break loop;
+            }
+            // Fall through
+          default:
+            val.append(c);
+            if (!Character.isWhitespace(c)) {
+              end = val.length();
+            }
+            break;
+          }
+        }
+      }
+      if (quote || backslash || end == 0) {
+        return null;
+      }
+      val.setLength(end);
+      return val.toString();
+    }
+
+
+    String getKey(boolean singleKey) {
+      if (pos >= length) {
+        return null;
+      }
+      final int save = pos;
+      if (s.charAt(pos) == ';') {
+        pos++;
+      }
+      final String res = getWord(false, singleKey);
+      if (res != null) {
+        if (pos == length) {
+          return res;
+        }
+        final char c = s.charAt(pos);
+        if (c == ';' || c == ',') {
+          return res;
+        }
+      }
+      pos = save;
+      return null;
+    }
+
+
+    String getParam() {
+      if (pos == length || s.charAt(pos) != ';') {
+        return null;
+      }
+      final int save = pos++;
+      final String res = getWord(false, false);
+      if (res != null) {
+        if (pos < length && s.charAt(pos) == '=') {
+          // Untyped parameter
+          return res;
+        }
+        if (pos < length && s.charAt(pos) == ':') {
+          // Typed parameter or directive
+          return res;
+        }
+      }
+      pos = save;
+      return null;
+    }
+
+
+    boolean isDirective() {
+      if (pos + 1 < length && s.charAt(pos) == ':' && s.charAt(pos + 1) == '=') {
+        pos++;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+
+    String getParamType() {
+      if (pos == length || s.charAt(pos) != ':') {
+        return null;
+      }
+      final int save = pos++;
+      final String res = getWord(false, false);
+      if (res != null) {
+        if (pos < length && s.charAt(pos) == '=') {
+          return res;
+        }
+      }
+      pos = save;
+      return null;
+    }
+
+
+    String getValue() {
+      return getValue(false);
+    }
+
+    String getValue(boolean keepEscapes) {
+      if (s.charAt(pos) != '=') {
+        return null;
+      }
+      final int save = pos++;
+      skipWhite();
+      final String val = getWord(keepEscapes, true);
+      if (val == null) {
+        pos = save;
+        return null;
+      }
+      return val;
+    }
+
+
+    boolean getEntryEnd() {
+      final int save = pos;
+      skipWhite();
+      if (pos == length) {
+        return true;
+      } else if (s.charAt(pos) == ',') {
+        pos++;
+        return true;
+      } else {
+        pos = save;
+        return false;
+      }
+    }
+
+
+    boolean getEnd() {
+      final int save = pos;
+      skipWhite();
+      if (pos == length) {
+        return true;
+      } else {
+        pos = save;
+        return false;
+      }
+    }
+
+
+    String getRest() {
+      final String res = s.substring(pos).trim();
+      return res.length() == 0 ? "<END OF LINE>" : res;
+    }
+
+
+    private void skipWhite() {
+      for (; pos < length; pos++) {
+        if (!Character.isWhitespace(s.charAt(pos))) {
+          break;
+        }
+      }
+    }
+  }
+
+
+  /**
+   * A class that holds the parse result for one entry of a manifest header
+   * following the general OSGi manifest header syntax. See
+   * {@link #parseManifestHeader(String, String, boolean, boolean, boolean)} for
+   * details on the syntax.
+   */
+  public static class HeaderEntry
+  {
+    final String headerName;
+    final boolean singleKey;
+    final List<String> keys = new ArrayList<String>();
+    final Map<String, Object> attributes = new HashMap<String, Object>();
+    final Map<String, String> directives = new HashMap<String, String>();
+
+    /**
+     * @param singleKey
+     */
+    HeaderEntry(String headerName, boolean singleKey)
+    {
+      this.headerName = headerName;
+      this.singleKey = singleKey;
+    }
+
+    public String getKey()
+    {
+      if  (singleKey) {
+        return keys.get(0);
+      }
+      throw new IllegalArgumentException("Requesting single key for multi key header clause");
+    }
+
+    public List<String> getKeys()
+    {
+      return keys;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+      return attributes;
+    }
+
+    public Map<String, String> getDirectives()
+    {
+      return directives;
+    }
+  }
+
+  /**
+   * Convert a list of {@link HeaderEntry}-objects into a valid manifest header
+   * value.
+   *
+   * @param hes
+   *          The list of header entries to make a string of.
+   * @return Manifest value that follows the generic OSGi manifest syntax.
+   */
+  public static String toString(List<HeaderEntry> hes)
+  {
+    final StringBuffer sb = new StringBuffer();
+    for (final HeaderEntry he : hes) {
+      if (sb.length() > 0) {
+        sb.append(", ");
+      }
+      sb.append(he.getKey());
+      parametersToString(sb, "=", he.getAttributes());
+      parametersToString(sb, ":=", he.getDirectives());
+    }
+    return sb.toString();
+  }
+
+  /**
+   * A pattern matching chars that needs to be quoted when quoting a parameter
+   * value.
+   */
+  static final Pattern QUOTE_PATTERN = Pattern.compile("\"");
+
+  /**
+   * A pattern matching OSGis syntax terminal called <em>extended</em>. An
+   * <em>extended</em> terminal does not need to be quoted when used as the
+   * value of a parameter. The set of allowed characters in <em>extended</em>
+   * terminals are a..z, A..Z, 0..9, '_', '-' and '.'.
+   */
+  static final Pattern EXTENDED_PATTERN = Pattern.compile("[a-zA-Z0-9_\\-.]+");
+
+  /**
+   * Convert a map with manifest entry parameters into a well formed manifest
+   * parameter string.
+   *
+   * @param sb
+   *          String buffer to append result to.
+   * @param sep
+   *          Separator between the key and the value of a parameter.
+   * @param parameters
+   *          The map with parameters to process.
+   */
+  private static void parametersToString(final StringBuffer sb,
+                                         final String sep,
+                                         final Map<String, ?> parameters)
+  {
+    for (final Entry<String, ?> attribEntry : parameters.entrySet()) {
+      sb.append("; ");
+      sb.append(attribEntry.getKey());
+      sb.append(sep);
+
+      String value = attribEntry.getValue().toString();
+      final boolean needsQuoting = !EXTENDED_PATTERN.matcher(value).matches();
+      if (needsQuoting) {
+        sb.append('"');
+        final Matcher matcher = QUOTE_PATTERN.matcher(value);
+        value = matcher.replaceAll("\\\\\"");
+      }
+      sb.append(value);
+      if (needsQuoting) {
+        sb.append('"');
+      }
+    }
+  }
+
+}
diff --git a/ant/src/org/knopflerfish/ant/taskdefs/bundle/antlib.xml b/ant/src/org/knopflerfish/ant/taskdefs/bundle/antlib.xml
new file mode 100644
index 0000000..6facde3
--- /dev/null
+++ b/ant/src/org/knopflerfish/ant/taskdefs/bundle/antlib.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<antlib>
+  <taskdef name="bundleinfo" 
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleInfoTask"/>
+  <taskdef name="bundlemanifest" 
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleManifestTask"/>
+  <taskdef name="bundle" 
+           classname="org.knopflerfish.ant.taskdefs.bundle.Bundle"/>
+  <taskdef name="bundleClasspathUtil" 
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleClasspathTask"/>
+  <taskdef name="bundlehtml" 
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleHTMLExtractorTask"/>
+  <taskdef name="makehtml"
+           classname="org.knopflerfish.ant.taskdefs.bundle.MakeHTMLTask"/>
+  <taskdef name="byteformatter"
+           classname="org.knopflerfish.ant.taskdefs.bundle.ByteFormatterTask"/>
+  <taskdef name="bundle_locator"
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleLocator"/>
+  <taskdef name="bundle_javadoc_helper"
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleJavadocHelperTask"/>
+  <taskdef name="bundle_user_doc_navigate"
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleUserDocNavigateTask"/>
+  <taskdef name="bundleMvnAnt"
+           classname="org.knopflerfish.ant.taskdefs.bundle.BundleMvnAntTask"/>
+</antlib>
diff --git a/ant/xargs.xml b/ant/xargs.xml
new file mode 100644
index 0000000..0d1fa79
--- /dev/null
+++ b/ant/xargs.xml
@@ -0,0 +1,108 @@
+<!-- ============================================================ -->
+<!--                    xargs file building                       -->
+<!-- ============================================================ -->
+
+
+<project name="xargs" basedir=".">
+
+  <!-- Users of this macro should call the check_openssl target before
+       calling this macro to ensure that the property openssl_exists
+       is correctly set. -->
+  <macrodef name="xargs"
+	    description="Generates xargs-file from template.">
+    <attribute name="template"
+	       description="Location of the template xargs file to use."/>
+    <attribute name="xargs"
+	       description="Location (path) of the xargs to create."/>
+    <attribute name="gosgJars"
+	       description="Semicolon separated URL-path to replace $(GOSG_JARS) with. Also used to search for bundles."
+	       default="file:jars/;file:test_jars/"/>
+    <attribute name="repositoryXmlUrls"
+	       description="Comma separated list of OSGi Repository xml urls to replace $(REPOSITORY_XML_URLS) with."
+	       default="file:jars/index.xml,http://www.knopflerfish.org/releases/current/osgi/jars/index.xml"/>
+    <attribute name="baseDir"
+	       description="Base directory for relative file URLs in the gosgJars path."
+	       default=""/>
+    <attribute name="testJars"
+	       description="Replacement value for $(TESTJARS); path to the root directory of the respository holding test bundles."
+	       default="$${user.dir}/test_jars"/>
+    <attribute name="xargsOsTemplate"
+	       description="Location of file with replacement for $(OS_ARGS)."
+	       default=""/>
+    <attribute name="headless"
+	       description="If set to 'true' then $(AWT) is replaced with the comment char otherwise it is replaced with an empty string."
+	       default="false"/>
+    <attribute name="outDir"
+	       description="Directory to place intermediate build files in."
+	       default="out"/>
+    <element name="bundles"
+             optional="true"
+             description="Place holder element that specifies file-sets to search for bundles to use when expanding symbolic bundle names in the template file."/>
+    <element name="replacefilters"
+             optional="true"
+             description="Additional replacefilter elements applied to the resulting xargs file."/>
+
+    <sequential>
+      <delete file="@{xargs}"/>
+
+      <loadresource property="xargs.os.args" failonerror="false" quiet="true">
+	<file file="@{xargsOsTemplate}"/>
+      </loadresource>
+      <!-- Set default value if file did not exist. -->
+      <property name="xargs.os.args" value=""/>
+
+      <mkdir dir="@{outDir}"/>
+      <local name="bundleVersionFilter"/>
+      <property name="bundleVersionFilter"
+		location="@{outDir}/bundleVersionsXargs.props"/>
+      <delete file="${bundleVersionFilter}"/>
+
+      <bundle_locator replacefilterfile="${bundleVersionFilter}"
+		      bundlePath="@{gosgJars}"
+		      baseDir="@{baseDir}">
+	<bundles/>
+      </bundle_locator>
+
+      <local name="do.cpa.test"/>
+      <condition property="do.cpa.test" value="" else="#">
+	<and>
+          <isset property="openssl_exist"/>
+          <!-- JRE 1.5 form Sun is broken -->
+          <not><equals arg1="${ant.java.version}" arg2="1.5"/></not>
+	</and>
+      </condition>
+
+      <local name="headless"/>
+      <condition property="headless" value="#" else="">
+          <equals arg1="@{headless}" arg2="true"/>
+      </condition>
+
+      <copy file="@{template}" tofile="@{xargs}"/>
+      <replace file="@{xargs}"
+               replacefilterfile="${bundleVersionFilter}">
+	<replacefilter token="$(GOSG_JARS)"    value="@{gosgJars}"/>
+    <replacefilter token="$(REPOSITORY_XML_URLS)"    value="@{repositoryXmlUrls}"/>
+	<replacefilter token="$(TESTJARS)"     value="@{testJars}"/>
+	<replacefilter token="$(VERSION)"      value="${version}"/>
+	<replacefilter token="$(OS_ARGS)"      value="${xargs.os.args}"/>
+	<replacefilter token="$(DO_CPA_TEST)"  value="${do.cpa.test}"/>
+	<replacefilter token="$(AWT)"          value="${headless}"/>
+	<replacefilters/>
+      </replace>
+    </sequential>
+  </macrodef>
+
+  <target name="check_openssl" unless="check_openssl.done">
+    <exec executable="openssl"
+          failifexecutionfails="false"
+          resultproperty="openssl_return_code">
+      <arg value="version" />
+    </exec>
+    <condition property="openssl_exist">
+      <isset property="openssl_return_code"/>
+    </condition>
+
+    <property name="check_openssl.done" value="true"/>
+  </target>
+
+</project>
diff --git a/ant/xsl/repository2html.xsl b/ant/xsl/repository2html.xsl
new file mode 100644
index 0000000..b6a069e
--- /dev/null
+++ b/ant/xsl/repository2html.xsl
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:r="http://www.osgi.org/xmlns/repository/v1.0.0"
+    version="1.0">
+  <xsl:output method="html"/>
+  
+  <xsl:template match="/">
+    <html>
+      <xsl:apply-templates/>
+    </html>
+  </xsl:template>
+  
+  <xsl:template match="r:repository">
+    <head>
+      <META HTTP-EQUIV="Content-Type"
+            CONTENT="text/html; charset=iso-8859-1"/>
+      <title>
+        <xsl:value-of select="@name"/>
+      </title>
+      <link href="../../docs/css/knopflerfish.css" rel="stylesheet" type="text/css"/>
+      <link href="../../docs/css/kf_man.css" rel="stylesheet" type="text/css"/>
+      <style type="text/css">
+        DIV.left_hdr {
+        width: 225px;
+        height: 100%;
+        background: #000;
+        margin: 0px;
+        padding-top: 10px;
+        padding-left: 15px;
+        color: #fff;
+        float:left;
+        font-weight: bold;
+        }
+
+        DIV.logo_hdr {
+        height: 100%;
+        background: #fb0b0c;
+        margin: 0px 0px 0px 225px;
+        padding-top: 10px;
+        padding-left: 50px;
+        }
+
+        BODY  {
+        background: #fff;
+        margin-top:   5px;
+        margin-left:  10px;
+        margin-right: 10px;
+        font-size: 0.8125em;
+        }
+      </style>
+    </head>
+    <body>
+      <div id="header" style="width:100%;">
+        <div id="header_logo">
+          <a href="index.html"><img src="../../docs/images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+        </div>
+        <div id="header_centerbox">
+          <div class="header_centerinfo_top">
+            Distribution Documentation
+          </div>
+          <div class="header_centerinfo_bottom">
+            <xsl:value-of select="@name"/>
+          </div>
+        </div>
+        <div id="header_rightinfo">
+          <div class="header_stylish">
+            Open Source OSGi Service Platform Maintained by
+          </div>
+          <a href="http://www.makewave.com">
+            <img border="0" alt="Makewave" src="../../docs/images/makewave_logo.png" style="margin-top: 4px;"/>
+          </a>
+        </div>
+        <!--<div style="clear:both;"></div> -->
+        <div id="header_fade">
+        </div>
+      </div>
+
+      <p>Increment:     
+      <xsl:value-of select="@increment"/></p>
+
+      <table>
+        <tr><th width="200px">Link</th><th>Version</th><th>Doc/Src</th><th>Bytes</th><th>Description</th></tr>
+        <xsl:apply-templates>
+          <xsl:sort select="r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='name']/@value"/>
+        </xsl:apply-templates>
+      </table>
+    </body>
+  </xsl:template>
+  
+  <xsl:template match="r:resource">
+    <tr>
+      <td>
+        <a href="{normalize-space(r:capability[@namespace='osgi.content']/r:attribute[@name='url']/@value)}">
+          <xsl:value-of select="r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='name']/@value"/>
+        </a>    
+      </td>
+      <td><xsl:value-of select="r:capability[@namespace='osgi.identity']/r:attribute[@name='version']/@value"/></td>
+      <td>
+        <xsl:if test="r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='documentation']/@value">
+          <a href="{normalize-space(r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='documentation']/@value)}">doc</a>
+          <xsl:if test="r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='source']/@value">/</xsl:if>
+        </xsl:if>
+        <xsl:if test="r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='source']/@value">
+          <a href="{normalize-space(r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='source']/@value)}">src</a>
+        </xsl:if>
+      </td>
+      <td>
+        <xsl:value-of select="r:capability[@namespace='osgi.content']/r:attribute[@name='size']/@value"/>
+      </td>
+      <td>
+        <xsl:value-of select="r:capability[@namespace='org.knopflerfish.extra']/r:attribute[@name='description']/@value"/>
+      </td>
+
+    </tr>
+    
+  </xsl:template>       
+</xsl:stylesheet>
diff --git a/changelog.txt b/changelog.txt
new file mode 100644
index 0000000..8c08827
--- /dev/null
+++ b/changelog.txt
@@ -0,0 +1,374 @@
+2014-06-13 00:51:04 +0200 (Fri, 13 Jun 2014), revision 4320, cl
+Renamed Application-Icon => Bundle-Icon to map 1:1 with manifest header name
+U   knopflerfish.org/trunk/ant/bundlebuild.xml
+U   knopflerfish.org/trunk/osgi/bundles_opt/desktop_displayers/boing/build.xml
+
+2014-06-12 22:19:49 +0200 (Thu, 12 Jun 2014), revision 4319, cl
+Added support to include content from ${out.dir}/resources. To be used when adding dynamically created resources in e.g. a custom.pre target
+U   knopflerfish.org/trunk/ant/bundlebuild.xml
+
+2014-06-12 17:20:29 +0200 (Thu, 12 Jun 2014), revision 4318, jan
+Fixed some small problems in preparation for next KF release.
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Main.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-12 12:17:11 +0200 (Thu, 12 Jun 2014), revision 4317, cl
+Added bundle icon for Prefs. Changed to use Bundle-Icon for UserAdmin
+U   knopflerfish.org/trunk/osgi/bundles/prefs/bundle.manifest
+A   knopflerfish.org/trunk/osgi/bundles/prefs/resources/
+A   knopflerfish.org/trunk/osgi/bundles/prefs/resources/icon.png
+U   knopflerfish.org/trunk/osgi/bundles/useradmin/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-12 11:50:26 +0200 (Thu, 12 Jun 2014), revision 4316, jan
+Changed RSA key length to avoid restrictions in Java 7 and later. Be more flexible in validation date parsing.
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/build_keystore.xml
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java
+
+2014-06-10 19:39:20 +0200 (Tue, 10 Jun 2014), revision 4315, jan
+Fixed listRescources (SF#178) and added a testcase. Detect dead-lock when doing dynamic import in permssion check (SF#179).
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/Activator.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/BadBundleListener.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/BundleWiringTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/CapabilityTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/FWTestCase.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/FragmentTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/FrameworkTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/NativeCodeTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PackageAdminTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PackageTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PermissionTest.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PermissionTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/RegListenThread.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/RegServThread.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/RequireBundleTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/ServiceListenerTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/Util.java
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/BundleClassLoader.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Resolver.java
+U   knopflerfish.org/trunk/osgi/init-tests.xargs.in
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-09 14:43:48 +0200 (Mon, 09 Jun 2014), revision 4314, jan
+Add framework property to put framework in read-only mode.
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FWProps.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Main.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/StartLevelController.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Util.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/Archive.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleArchiveImpl.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleStorageImpl.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoStorage.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-09 08:00:49 +0200 (Mon, 09 Jun 2014), revision 4313, jan
+Added framework resource protocol
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/src/org/knopflerfish/bundle/component_test/ComponentTestSuite.java
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+A   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FWResourceURLStreamHandler.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Main.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/ServiceURLStreamHandlerFactory.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-05-15 17:53:50 +0200 (Thu, 15 May 2014), revision 4312, ekolin
+Fix buidling of the compact framework version when using Java SE 7+.
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+
+2014-04-11 09:58:17 +0200 (Fri, 11 Apr 2014), revision 4311, ekolin
+Make sure that CM-Desktop can be installed by the Desktop Repository when using the Felix Resolver service.
+U   knopflerfish.org/trunk/KnopflerfishEclipseDictionary.txt
+U   knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-04-11 09:07:19 +0200 (Fri, 11 Apr 2014), revision 4310, ekolin
+The eol format was mixed, change to <CR><LF> on all lines
+U   knopflerfish.org/trunk/osgi/template.xargs.in
+
+2014-03-19 13:25:40 +0100 (Wed, 19 Mar 2014), revision 4309, perg
+Made UserAdmin self-contained wrt kf log utility
+U   knopflerfish.org/trunk/osgi/bundles/useradmin/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/useradmin/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-25 16:00:35 +0100 (Tue, 25 Feb 2014), revision 4308, perg
+Changed spelling error sources to source
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2014-02-24 21:52:00 +0100 (Mon, 24 Feb 2014), revision 4307, perg
+Fixed bug in kf_metatype bundle and refactored handling of standardized and proprietary xml formats.
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/bundle/metatype/Activator.java
+A   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/KFLegacyMetaTypeParser.java
+A   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/OsgiMetaTypeXmlParser.java
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/SystemMetatypeProvider.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-20 13:40:39 +0100 (Thu, 20 Feb 2014), revision 4306, jan
+Fixed an IllegalStateException for factory components.
+U   knopflerfish.org/trunk/osgi/bundles/component/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-14 21:46:06 +0100 (Fri, 14 Feb 2014), revision 4305, jan
+
+U   knopflerfish.org/trunk/osgi/bundles/cm/cm/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java
+U   knopflerfish.org/trunk/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationStore.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-05 17:24:41 +0100 (Wed, 05 Feb 2014), revision 4304, ekolin
+Http 4.0.5; more fixes for handling of transfer encoding chunked.
+U   knopflerfish.org/trunk/osgi/bundles/http/http/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-29 13:32:42 +0100 (Wed, 29 Jan 2014), revision 4303, ekolin
+Add missing ignore for generated file.
+_U  knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/resources/
+
+2014-01-29 12:04:57 +0100 (Wed, 29 Jan 2014), revision 4302, ekolin
+Rewrite unchunk code to simple read the number of bytes that the shunk shall contian, ignoring any CR or LF in the data.
+U   knopflerfish.org/trunk/osgi/bundles/http/http/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-29 11:10:48 +0100 (Wed, 29 Jan 2014), revision 4301, perg
+Improvements to Repository Desktop and some minor fixes
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/CapabilityImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/RequirementImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/ResourceImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-29 10:19:30 +0100 (Wed, 29 Jan 2014), revision 4300, ekolin
+Fix problem with decoding of chunked tranfer encoding in the Htt-Server.
+U   knopflerfish.org/trunk/osgi/bundles/http/http/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-22 10:43:46 +0100 (Wed, 22 Jan 2014), revision 4298, jan
+Fixed bug with ConditionalPermissionUpdate.
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/condpermadmin_test/src/org/knopflerfish/bundle/condpermadmin_test/CondPermAdminTestSuite.java
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/validator/SelfSignedValidator.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-12-12 14:55:26 +0100 (Thu, 12 Dec 2013), revision 4296, perg
+Fixed spelling error: source -> sources
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-12-12 13:44:26 +0100 (Thu, 12 Dec 2013), revision 4295, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-12 13:42:21 +0100 (Thu, 12 Dec 2013), revision 4294, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+A   knopflerfish.org/trunk/tools/mvnrepo/mvnrepoindex2html.xsl
+
+2013-12-12 13:20:25 +0100 (Thu, 12 Dec 2013), revision 4293, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-12-12 12:47:13 +0100 (Thu, 12 Dec 2013), revision 4292, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-12-12 12:25:07 +0100 (Thu, 12 Dec 2013), revision 4291, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-12 12:21:20 +0100 (Thu, 12 Dec 2013), revision 4290, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-12 12:14:02 +0100 (Thu, 12 Dec 2013), revision 4289, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-11 10:32:25 +0100 (Wed, 11 Dec 2013), revision 4288, jan
+Fixed a bug that caused factory components to be falsely created or missed being created when we use target filters. Also added test-cases for this.
+U   knopflerfish.org/trunk/osgi/bundles/component/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/Component.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/DelayedComponent.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/FactoryComponent.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ImmediateComponent.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/Reference.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/build.xml
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/src/org/knopflerfish/bundle/component_test/ComponentTestSuite.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/build.xml
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/bundle.manifest
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/resources/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/resources/service.xml
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentAImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentB1Impl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentB2Impl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentCImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/ComponentA.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/ComponentB.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/ComponentC.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-12-10 13:45:26 +0100 (Tue, 10 Dec 2013), revision 4287, perg
+Corrected bundle and package versions
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/packageinfo
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-12-09 14:56:08 +0100 (Mon, 09 Dec 2013), revision 4286, perg
+Improved support for Resolver in Repository Manager. Updated Repository console and desktop bundles to use the improved support. Embedded Resolver and Repository APIs in Repository Manager.
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/RepositoryCommandGroup.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryManager.java
+U   knopflerfish.org/trunk/osgi/template.xargs.in
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-11-18 11:26:55 +0100 (Mon, 18 Nov 2013), revision 4285, perg
+Updated w/ Resolver related updates
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-11-16 00:14:56 +0100 (Sat, 16 Nov 2013), revision 4284, perg
+Added commented out line to install a resolver
+U   knopflerfish.org/trunk/osgi/template.xargs.in
+
+2013-11-15 23:44:51 +0100 (Fri, 15 Nov 2013), revision 4283, perg
+Added support for Resolver Service 1.0
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/Activator.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/RepositoryCommandGroup.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/Activator.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java
+A   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/ResolveContextImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryManager.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/packageinfo
+
+2013-11-15 23:44:02 +0100 (Fri, 15 Nov 2013), revision 4282, perg
+Fix in equals impl
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/CapabilityImpl.java
+
+2013-10-24 14:49:23 +0200 (Thu, 24 Oct 2013), revision 4280, perg
+Updated release notes and set correct bundle version
+U   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-24 14:34:07 +0200 (Thu, 24 Oct 2013), revision 4279, perg
+Updated changelog.txt
+U   knopflerfish.org/trunk/changelog.txt
+U   knopflerfish.org/trunk/osgi/bundles_opt/junit/osgi_ct_adapter/src/org/knopflerfish/bundle/osgi_ct_adapter/Activator.java
+
+2013-10-24 14:26:15 +0200 (Thu, 24 Oct 2013), revision 4278, perg
+Fixed parsing of Bundle-License
+U   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/bundle.manifest
+
+2013-10-24 14:21:24 +0200 (Thu, 24 Oct 2013), revision 4277, perg
+Fixed parsing of Bundle-License
+U   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/KnopflerfishExtentions.java
+A   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/Util.java
+
+2013-10-23 18:00:48 +0200 (Wed, 23 Oct 2013), revision 4276, jan
+Fixed a bug that caused problems when adding a CM configuration with a target filter to an unsatisfied component.
+U   knopflerfish.org/trunk/osgi/bundles/component/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/Component.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/src/org/knopflerfish/bundle/component_test/ComponentTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/resources/service.xml
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/bundle/componentC_test/ComponentUImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/bundle/componentC_test/ComponentVImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/service/componentC_test/ComponentU.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/service/componentC_test/ComponentV.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-23 17:50:15 +0200 (Wed, 23 Oct 2013), revision 4275, jan
+Update framework documentation with some 5.0.0 changes.
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+U   knopflerfish.org/trunk/osgi/framework/resources/help.txt
+
+2013-10-23 10:17:09 +0200 (Wed, 23 Oct 2013), revision 4274, ekolin
+Switch to proguard 4.10
+U   knopflerfish.org/trunk/ant/build.xml
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+
+2013-10-22 16:44:48 +0200 (Tue, 22 Oct 2013), revision 4273, ekolin
+Automatically download proguard from maven central.
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+
+2013-10-22 15:53:19 +0200 (Tue, 22 Oct 2013), revision 4272, ekolin
+Remove reference to OSGiR4v4.3
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+
+2013-10-22 13:40:10 +0200 (Tue, 22 Oct 2013), revision 4271, ekolin
+Fix another bundle repository link.
+U   knopflerfish.org/trunk/htdocs/html_templates/template.html
+
+2013-10-22 13:03:21 +0200 (Tue, 22 Oct 2013), revision 4270, ekolin
+Nightly builds should say maintenance release, not major release...
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-22 12:56:46 +0200 (Tue, 22 Oct 2013), revision 4269, ekolin
+Remove some warnings for the ant tasks. Fix link to Makewave logo in nightlybuilds page.
+U   knopflerfish.org/trunk/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleArchives.java
+U   knopflerfish.org/trunk/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleInfoTask.java
+U   knopflerfish.org/trunk/tools/nightlybuild/snap_index.html.pre
+
+2013-10-21 21:06:51 +0200 (Mon, 21 Oct 2013), revision 4267, jan
+Post release 5.0.0 update
+U   knopflerfish.org/trunk/build.xml
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-21 21:01:35 +0200 (Mon, 21 Oct 2013), revision 4266, ekolin
+Fix href to the style sheet.
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-10-21 21:01:14 +0200 (Mon, 21 Oct 2013), revision 4265, jan
+update version
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-10-21 20:57:21 +0200 (Mon, 21 Oct 2013), revision 4264, ekolin
+Bundle repository link should point to the new repository file.
+U   knopflerfish.org/trunk/htdocs/html_src/release_page.html.in
+
+2013-10-21 19:25:29 +0200 (Mon, 21 Oct 2013), revision 4261, ekolin
+Also search for the repoindex bundle in the direcotry to index.
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-10-21 17:29:38 +0200 (Mon, 21 Oct 2013), revision 4260, ekolin
+
+U   knopflerfish.org/trunk/changelog.txt
+
+2013-10-21 17:02:56 +0200 (Mon, 21 Oct 2013), revision 4259, ekolin
+Merge of the KF-5 development branch.
diff --git a/docs/android_dalvik_tutorial.html b/docs/android_dalvik_tutorial.html
new file mode 100644
index 0000000..a7535bc
--- /dev/null
+++ b/docs/android_dalvik_tutorial.html
@@ -0,0 +1,294 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Tutorial for running KF on Android / Dalvik"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  running on Android / Dalvik"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  running on Android / Dalvik</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Knopflerfish Android / Dalvik Tutorial</h1>
+
+<h2 class="kf">Contents</h2>
+<ol>
+  <li><a href="#setup">Setting up the environment</a>
+  <li><a href="#building">Building Dalvik dex files</a>
+  <li><a href="#runtime">Creating a Dalvik KF run-time</a>
+  <li><a href="#install">Installing KF on the Android Emulator</a>
+  <li><a href="#run">Running KF under Dalvik</a>
+  <li><a href="#projects">Android projects</a>
+</ol>
+
+
+<a name="setup"></a>
+<h2 class="kf">Setting up the Environment</h2>
+<p>
+  To run Knopflerfish on the Android/Dalvik VM you need the Android
+  SDK. This SDK contains the necessary tool to convert and pack Java
+  classes and JAR files to the DEX format used by Dalvik.  
+</p>
+<p>
+  The KF ant build system has built-in support for dexifying JAR
+  files using the tools from the Android SDK.
+</p>
+<p>
+  This guide assumes the SDK for Android 4.0 API level 15 is used.
+</p>
+
+
+<a name="runtime"></a>
+<h2 class="kf">Building Dalvik dex files</h2>
+<p>
+  The KF ant build system has support to create the necessary dex
+  files for the framework and all the bundles. For any bundle, the
+  framework, or the whole KF distribution dex versions can be built by
+  specifying <tt>ANDROID_HOME</tt> to the build target.
+</p>
+<pre class="shell">
+ > ant -DANDROID_HOME=>path to android sdk top directory  <
+</pre>
+<p>
+  It is recommended you build the dex files on a clean distribution. 
+</p>
+<p>
+  The generated dex files are places in the bundle's JAR file
+  as <tt>classes.dex</tt> directly in the root. The Java class files
+  are still kept in the JAR file. This means the same bundle can run
+  on a normal JVM as well as with Dalvik without any
+  modifications. From a size perspective this is of course not optimal
+  to include both Java classes and classes.dex. A bundle get roughly
+  twice as large after dexifying it. 
+  Future KF releases may have support to create pure dex version of
+  bundles.</p>
+<p>
+  After building or dexifying KF the push the necessary files to the
+  emulator, typically using <tt>adb</tt>. There is since KF 3.3 an
+  android tool included to simplify this process, see next section.
+</p>
+<a name="runtime"></a>
+<h2 class="kf">Creating a Dalvik KF run-time</h2>
+<p>
+  The KF distribution contains a simple build tool to create and install KF
+  on an Android emulator. It is located in the <tt>tools/android</tt>
+  directory.
+</p>
+<p>
+  After specifying 
+  After stepping into this directory run <tt>ant</tt> and specify
+  where the Android SDK is installed:
+  <pre class="shell">
+ > cd tools/android
+ > ant setup -DANDROID_HOME=/Users/knopflerfish/bin/android-sdk-mac_x86/  
+  </pre>
+  Specifying <tt>ANDROID_HOME</tt> is only necessary  the first time
+  you run ant. The location is stored in
+  the android.properties file located in the same directory. You can
+  run the setup target again, pointing at another location if needed.
+  <pre class="shell">
+ > ant setup -DANDROID_HOME=/bin/android-sdk
+  </pre>
+</p>
+<p>
+  There is a small template xargs file included. This contains a very
+  basic set of bundles. Feel free to modify or add additional xargs files.
+</p>
+<p>
+  The build will create the run time in:
+  <pre class="shell">
+  > out/dalvik
+  </pre>
+
+<a name="install"></a>
+<h2 class="kf">Installing KF on the Android/Dalvik Emulator</h2>
+<p>
+  The build.xml file includes an <tt>install</tt> target. This will
+  install the created KF run time on the emulator using
+  the <tt>adb</tt> tools. For this to function the Android emulator
+  must be running of course.
+  <pre class="shell">
+  > ant install
+  </pre>
+
+  The files are installed in <tt>/data/kf-3.3.0</tt> by default on the emulator.
+</p>
+
+<a name="run"></a>
+<h2 class="kf">Running KF under Dalvik</h2>
+<p>
+  To launch KF under Dalvik you need to start Dalvik in the
+  emulator. This is typically done by starting a shell on the emulator:
+</p>
+<pre class="shell">
+  > adb shell
+  root at android:/ #   
+  root at android:/ # cd /data/kf-3.3.0/                                          
+  root at android:/data/kf-3.3.0 # 
+  root at android:/data/kf-3.3.0 # ls
+  dalvik.xargs
+  framework.jar
+  jars
+  props.xargs
+  root at android:/data/kf-3.3.0 # 
+</pre>
+  The next step is to launch KF. This is done as usual, but using
+  the <tt>dalvikvm</tt> instead.
+<pre class="shell">
+  root at android:/data/kf-3.3.0 # dalvikvm -classpath framework.jar \
+  org.knopflerfish.framework.Main -xargs dalvik.xargs
+</pre>
+  Now KF is running under the dalvik VM! The ttyconsole bundle is included in
+  the dalvik.xargs. In the emulator shell window you can interact with
+  the KF framework just as you are used to:
+<pre class="shell">
+ > lsb
+   id  level/state name
+   --------------------
+    0  0/active    System Bundle            1  1/active    Log Service
+    2  1/active    cm                       3  1/active    Console
+    4  1/active    Event-Admin              5  2/resolved  util-LIB
+    6  2/resolved  JSDK-API                 7  4/active    HTTP-Server
+    8  5/active    FW-Commands-IMPL         9  5/active    LogCommands-IMPL
+   10  5/active    CM-Commands-IMPL        11  5/active    TTY-Console-IMPL
+   12  7/active    HTTP-root-IMPL       
+ >     
+</pre>
+  To  verify we are successfully running the KF HTTP server use the
+  browser in Android emulator and connect to the KF HTTP server running on port
+  8080:
+<p>
+  <img src="images/dalvik_httproot.png" border="0" alt="httproot on
+  Android" />
+</p>
+  
+<h3 class="kf">Note on Running KF under Dalvik</h3>
+<p>
+  The framework will create <jar>.dexopt files that lives side-by-side
+  with the jar files. This can cause a problem if your bundles lives
+  in a read-only directory and have the property (which is default):
+  <pre class="shell">
+  -Forg.knopflerfish.framework.bundlestorage.file.reference=true
+  </pre>
+  You then need to set the property to false, so that the bundle jars
+  are copied into the "fwdir".
+</p>
+
+<a name="projects"></a>
+<h2 class="kf">Android Projects</h2>
+<p>
+  The latest version of KF added the <tt>apk</tt> directory
+  to <tt>tools/android</tt>. Here you can find two Android projects
+  that can be used to build an Android <tt>.apk</tt> containing
+  Knopflerfish, see the README.txt file in the <tt>projects</tt>
+  directory for more information.
+</p>
+<p>
+  <img src="images/android_app.png" border="0" alt="Android
+  application" />
+</p>
+<p>
+  These projects are built using a combination of KF and the Android ant
+  tasks. Bundles that you include in your <tt>.apk</tt> will be dexified
+  as described above and DEX files for <tt>framework.jar</tt> and Java
+  classes included in the projects will be automatically created by the
+  build system. 
+</p>
+
+
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/building.html b/docs/building.html
new file mode 100644
index 0000000..e408610
--- /dev/null
+++ b/docs/building.html
@@ -0,0 +1,239 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Building Knopflerfish OSGi"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Building"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Building</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Building Knopflerfish</h1>
+
+Knopflerfish includes an ant based build system for building a
+complete Knopflerfish distribution as well as building <a
+href="programming.html">individual bundles</a>. Ant 1.8 or later is
+required, available from <a
+href="http://ant.apache.org/">ant.apache.org</a>
+
+<p>
+Knopflerfish can be built either by 
+ <a href="http://www.knopflerfish.org/svn_info.html">
+   checking out the entire source code
+</a>,
+or by (re)building an installed distribution.
+</p>
+
+<p>
+ The top level build file is located in the <code>osgi</code>
+ directory. The default target is to build the framework and all
+ bundles in the bundles directory.
+</p>
+
+<p>
+Invoking ant with the -p option will display the possible targets.
+</p>
+
+<pre class="shell">
+$ ant -p
+Buildfile: build.xml
+
+Main targets:
+
+ all                  Builds the framework and all bundles including optional and test bundles
+ bundle_doc           Builds bundle specific docs
+ bundle_tasks         Builds and defines the Knopflerfish bundle tasks
+ clean                Removes all generated files and directories.
+ clean_local          Remove all bundles built by this build-file but keep all other bundles
+                      in the jars sub-directory.
+ default              Builds the framework and bundles in bundles-directory
+ define_bundle_tasks  Defines the Knopflerfish bundle tasks
+ javadoc              Create javadoc for all exported packages
+ rebuild              Cleans then build build all
+ run                  (Re)start the framework.
+ run-init             Initial start with default set of bundles.
+ run-kf-tests         Builds then executes the KF testsuite.
+ run-kf-tests-secure  Builds then executes the KF testsuite with security enabled.
+ run-secure           (Re)start framework with security enabled.
+ run-secure-init      Initial start with security enabled and default set of bundles.
+Default target: default
+$ 
+</pre>
+
+<p>
+To add and build additional bundles see the <a
+href="programming.html">programming</a> section.
+</p>
+
+<h2 class="kf">Building a compact Knopflerfish framework</h2>
+
+You can build a compact version of the framework called
+<code>framework_compact.jar</code>. To build this you need to download
+<a href="http://proguard.sourceforge.net/">Proguard 4.10</a>.
+Install the proguard.jar file into ${KF_ROOT}/ant/lib and build
+the framework with the property <code>compact</code> set to
+<code>true</code>.
+<p>
+This a version with a reduced memory footprint. This version has
+no security and certificate support compiled into it. This is only
+supposed to be used for running and not to compile against. So you
+also need to compile the normal <code>framework.jar</code> to be able
+to build bundles.
+</p>
+<pre class="shell">
+$ ant -Dcompact=true -f framework/build.xml 
+Buildfile: /Users/jan/workspace_osgi5/kf_osgi5/osgi/framework/build.xml
+
+compile:
+
+compile_full:
+
+compile_compact:
+
+chkBundleTaskSrc:
+
+chkBundleTasksBuild:
+
+build_bundle_tasks:
+
+define_bundle_tasks:
+
+bundle_tasks:
+
+genexports:
+   [delete] Deleting: /Users/jan/workspace_osgi5/kf_osgi5/osgi/framework/resources/exports
+
+jar:
+   [delete] Deleting: /Users/jan/workspace_osgi5/kf_osgi5/osgi/framework/resources/version
+   [delete] Deleting: /Users/jan/workspace_osgi5/kf_osgi5/osgi/framework/resources/tstamp
+
+writerelease:
+
+jar_file_full:
+
+jar_file_compact:
+      [jar] Building jar: /Users/jan/workspace_osgi5/kf_osgi5/osgi/framework_compact.jar
+
+proguard_compact:
+     [move] Moving 1 file to /Users/jan/workspace_osgi5/kf_osgi5/osgi
+ [proguard] ProGuard, version 4.10
+ [proguard] Reading program jar [/Users/jan/workspace_osgi5/kf_osgi5/osgi/framework_compact.jar.tmp.jar]
+ [proguard] Reading library jar [/Users/jan/workspace_osgi5/kf_osgi5/osgi/ee/ee.minimum.jar]
+ [proguard] Preparing output jar [/Users/jan/workspace_osgi5/kf_osgi5/osgi/framework_compact.jar]
+ [proguard]   Copying resources from program jar [/Users/jan/workspace_osgi5/kf_osgi5/osgi/framework_compact.jar.tmp.jar]
+   [delete] Deleting: /Users/jan/workspace_osgi5/kf_osgi5/osgi/framework_compact.jar.tmp.jar
+
+add_dex:
+
+source.jar:
+
+save_javadoc_data:
+
+javadoc.jar:
+
+all:
+
+BUILD SUCCESSFUL
+Total time: 14 seconds
+$ ls -l framework*jar
+-rw-r--r--  1 jan  staff  617250 16 Okt 10:44 framework.jar
+-rw-r--r--  1 jan  staff  323070 16 Okt 10:44 framework_compact.jar
+$ 
+</pre>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/bundledoc/bundledoc_hdr.html b/docs/bundledoc/bundledoc_hdr.html
new file mode 100644
index 0000000..40c9c23
--- /dev/null
+++ b/docs/bundledoc/bundledoc_hdr.html
@@ -0,0 +1,66 @@
+<html>
+  <head>
+    <LINK href="../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <LINK href="../css/kf_man.css" rel="stylesheet" type="text/css">
+
+    <style type="text/css">
+
+
+    DIV.left_hdr {
+      width: 225px;
+      height: 100%;
+      background: #000;
+      margin: 0px;
+      padding-top: 10px;
+      padding-left: 15px;
+      color: #fff;
+      float:left;
+      font-weight: bold;
+    }
+
+    DIV.logo_hdr {
+      height: 100%;
+      background: #fb0b0c;
+      margin: 0px 0px 0px 225px;
+      padding-top: 10px;
+      padding-left: 50px;
+    }
+
+    BODY  {
+      background: #fff;
+      margin-top:   5px;
+      margin-left:  10px;
+      margin-right: 10px;
+      font-size: 0.8125em;
+    }
+  </style>
+    
+</head>
+
+<body>
+  <div id="header" style="width:100%;">
+    <Div id="header_logo">
+      <a href="index.html"><img src="../images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+    </div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="../images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<!--<div style="clear:both;"></div> -->
+	<div id="header_fade">
+    </div>
+  </div>
+</body>
+</html>
diff --git a/docs/bundledoc/bundledoc_list.html b/docs/bundledoc/bundledoc_list.html
new file mode 100644
index 0000000..ba37ead
--- /dev/null
+++ b/docs/bundledoc/bundledoc_list.html
@@ -0,0 +1,92 @@
+<html>
+
+  <head>
+    <LINK href="../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <LINK href="../css/kf_man.css" rel="stylesheet" type="text/css">
+
+    <style type="text/css">
+      BODY {
+        background: #fff;
+        margin-top:    5px;
+        margin-left:  10px;
+        margin-right: 10px;
+        font-size: 0.8125em;
+      }
+      H2 {
+        color:#802060;
+        font-size:13px;
+        font-weight:bold;
+        margin:6px 0px 6px 0px;	     
+        padding:6px 0px 6px 0px;
+        border-style:none;
+      }
+    </style>
+  </head>
+
+  <body>
+    <h2>Knopflerfish OSGi 5.1.0</h2>
+    <div id="man_leftmenu">
+    <dl class="leftmenu2">
+      <dt class="leftmenu2">Navigation</dt>
+      <dd class="leftmenu2"><a target="_top" href="../index.html">Knopflerfish Documentation</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="bundledoc_main.html">Bundle Doc Home</a></dd>
+    </dl>
+
+    <dl class="leftmenu2">
+      <dt class="leftmenu2">Knopflerfish Framework and Extension Bundles</dt>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="framework/index.html">Framework</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="frameworkcommands/index.html">Console Commands</a></dd>
+
+    </dl>
+
+    <dl class="leftmenu2">
+      <dt class="leftmenu2">Knopflerfish OSGi Bundles</dt>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="cm/index.html">Configuration Management</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="cm_cmd/index.html">Console Commands</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="device/index.html">Device Manager</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="event/index.html">Event Admin</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="http/index.html">HTTP Server</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="http/index.html#cmd-http">Console Commands</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="log/index.html">Log</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="logcommands/index.html">Console Commands</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="prefs/index.html">Prefs</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="repository_xml/index.html">Repository (XML)</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="component/index.html">SCR - Component</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="scrcommands/index.html">Console Commands</a></dd>
+
+    </dl>
+
+    <dl class="leftmenu2">
+      <dt class="leftmenu2">Knopflerfish Bundles</dt> 
+      <dd class="leftmenu2"><a target="bundledoc_main" href="console/index.html">Console</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="cm_cmd/index.html">CMD - Configuration</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="frameworkcommands/index.html">CMD - Framework</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="http/index.html#cmd-http">CMD - Http</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="logcommands/index.html">CMD - Log</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="repositorycommands/index.html">CMD - Repository</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="scrcommands/index.html">CMD - SCR</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="consoletcp/index.html">UI - TCP</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="consoletelnet/index.html">UI - Telnet</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="consoletty/index.html">UI - TTY</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="desktop/index.html">Desktop</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="cm_desktop/index.html">View - CM</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="repository_desktop/index.html">View - Repository</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="dirdeployer/index.html">Directory Deployer</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="trayicon_fw/index.html">Framework Tray Icon</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="httpconsole/index.html">Http Console</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="junit/index.html">JUnit</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="sslj2sp/index.html">SSL Provider — J2SP</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="serial/index.html">Serial Port Communication</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="util/index.html">Util</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="soap/index.html">SOAP - WebServices</a></dd>
+      <dd class="leftmenu2"><a target="bundledoc_main" href="xml_index/index.html">XML</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="crimson/index.html">Crimson</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="kxml/index.html">kXML</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="xalan/index.html">Xalan</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="xerces/index.html">Xerces</a></dd>
+      <dd class="leftmenu3"><a target="bundledoc_main" href="xml/index.html">xml</a></dd>
+
+    </dl>
+    </div>
+  </body>
+</html>
diff --git a/docs/bundledoc/bundledoc_main.html b/docs/bundledoc/bundledoc_main.html
new file mode 100644
index 0000000..72d73b4
--- /dev/null
+++ b/docs/bundledoc/bundledoc_main.html
@@ -0,0 +1,33 @@
+<html>
+
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Knopflerfish - Framework and Bundle User Documentation</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+
+  <body class="mainblock" onload="windowTitle();">
+
+  <h1 class="kf">Framework and Bundle Documentation for Users and Developers</h1>
+
+    <p>This section contains user's documentation on the framework and
+    bundles included in this Knopflerfish distribution.</p>
+
+    <p>Use the list to the left to select documentation.  The list is
+    sectioned in Framework and Extension Bundles, Knopflerfish OSGi
+    bundles and Knopflerfish Bundles.</p>
+
+    <p>At the top left there are links that navigates back to the
+    other sections of the Knopflerfish documentation. </p>
+
+  </body>
+</html>
diff --git a/docs/bundledoc/cm/cm_data.dtd b/docs/bundledoc/cm/cm_data.dtd
new file mode 100644
index 0000000..8f3bea0
--- /dev/null
+++ b/docs/bundledoc/cm/cm_data.dtd
@@ -0,0 +1,111 @@
+<!-- DTD for describing configuration instances for the OSGi -->
+<!-- Configuration Management, i.e. PIDs and their name value pairs -->
+<!-- Copyright Gatespace AB 2001 -->
+<!-- The public ID of this DTD is '-//Gatespace//DTD cm_data 0.1//EN' -->
+<!-- $Revision: 1.6 $ -->
+
+
+<!ENTITY  % TYPE "(String|Integer|Long|Float|Double|Byte|Short|BigInteger|BigDecimal|Character|Boolean)">
+<!ENTITY  % PRIMITIVE "(long|int|short|char|byte|double|float|boolean)">
+
+
+<!-- Root element of cm_data files. -->
+<!ELEMENT cm_data (include|configuration|factoryconfiguration|filter)*>
+<!ATTLIST cm_data
+          version  CDATA #REQUIRED >
+
+
+<!-- Include another cm_data file, pointed to by the url -->
+<!-- attribute. Partial URLs are completed relative to the file they -->
+<!-- occur in.-->
+<!ELEMENT include EMPTY >
+<!ATTLIST include
+          url    CDATA #REQUIRED >
+
+
+<!-- Modify a configuration given its pid. There are three modes of -->
+<!-- operation for this element:-->
+<!--    new     Creates a new configuration for the specified -->
+<!--            pid with contents according to this element.-->
+<!--            Old configuration data for this pid will be discarded. -->
+<!--    update  Updates data for the properties specified in this element. -->
+<!--    delete  Deletes the configuration with the specified pid. All -->
+<!--            properties inside an element with mode delete are ignored. -->
+<!ELEMENT configuration (property)* >
+<!ATTLIST configuration
+          pid    CDATA #REQUIRED
+          mode   (new|update|delete)  "update" >
+
+
+<!-- Modify a factory configuration given its pid. There are two -->
+<!-- modes of operation for this element:-->
+<!--    new     Creates a new factory configuration for the specified -->
+<!--            factory pid with contents according to this element.-->
+<!--    update  Updates data for the instance of the factory that is -->
+<!--            matched by the specified filter. -->
+<!-- The ldapfilter value must be specified for mode update. It shall -->
+<!-- be a LDAP filter string expression that matches at most one -->
+<!-- configuration instance belonging to the factory specified by the -->
+<!-- factory pid. Matching on the factory pid is not needed in the -->
+<!-- filter string since that is added by the XML handler.-->
+<!-- To delete a factory configuration use the configuration -->
+<!-- element with the pid of the factory configuration instance.-->
+<!ELEMENT factoryconfiguration (property)* >
+<!ATTLIST factoryconfiguration
+          factorypid    CDATA #REQUIRED
+          mode   (new|update)  "new"
+          ldapfilter    CDATA #IMPLIED >
+
+
+<!-- Modify a set of configurations that matches a given (LDAP) filter -->
+<!-- expression. There are two modes of operation for this element:-->
+<!--    update  Updates data for the properties specified in this element. -->
+<!--    delete  Delete the configurations that matches the filter.-->
+<!-- The ldapfilter value must be a LDAP filter string expression that -->
+<!-- can be used as the argument to ConfigurationAdmin.listConfigurations().-->
+<!-- An empty ldapfilter will match all available configurations.-->
+<!ELEMENT filter (property)* >
+<!ATTLIST filter
+          ldapfilter CDATA            #REQUIRED
+          mode       (update|delete)  "update" >
+
+
+<!-- Description of one property in a configuration. The name of the -->
+<!-- property is a required attribute. The element must contain -->
+<!-- precisely one value (either a single object or an array or vector). -->
+<!ELEMENT property (value|vector|array) >
+<!ATTLIST property
+          name CDATA #REQUIRED >
+
+<!-- Element describing a single object value.-->
+<!-- The contents of the element is the value.-->
+<!ELEMENT value (#PCDATA)* >
+<!ATTLIST value
+          type %TYPE; #REQUIRED >
+
+<!-- Element describing a single primitive value (may only occure in -->
+<!-- arrays).-->
+<!-- The contents of the element is the value.-->
+<!ELEMENT primitiveValue (#PCDATA)* >
+<!ATTLIST primitiveValue
+          type %PRIMITIVE; #REQUIRED >
+
+<!-- Element describing a vector value.-->
+<!-- The contents of the element is either value, array or vector -->
+<!-- elements. All the contained elements MUST be of the same type.-->
+<!ELEMENT vector (value*|vector*|array*)>
+<!ATTLIST vector
+          length CDATA  #IMPLIED >
+
+<!-- Element describing a vector value.-->
+<!-- The contents of the element is either value, primitiveValue, -->
+<!-- array or vector elements. All the contained elements MUST be of -->
+<!-- the same type. The number of contained elements must be equal to -->
+<!-- the specified size. -->
+<!-- The element type is one of the names specifeid by %TYPE;, -->
+<!-- %PRIMITIVE; or Vector followed by zero or more '[]'. -->
+<!-- Where '[]' indicates that the elements are arrays. -->
+<!ELEMENT array (value*|primitiveValue*|vector*|array*)>
+<!ATTLIST array
+          length       CDATA #REQUIRED
+          elementType  CDATA #REQUIRED >
diff --git a/docs/bundledoc/cm/index.html b/docs/bundledoc/cm/index.html
new file mode 100644
index 0000000..b29e9e9
--- /dev/null
+++ b/docs/bundledoc/cm/index.html
@@ -0,0 +1,171 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - cm, v5.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: cm
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.1
+      </div>
+      <h1 class="man">Configuration Management</h1>
+
+<div class="abstract">
+  The Configuration Management bundle implements the OSGi defined
+  <a  target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">
+    org.orgi.service.cm
+  </a>
+  package, a uniform way to manage
+  bundle configurations.
+</div>
+
+<h2 class="man">Description</h2>
+<p>
+  The Configuration Management bundle is designed to be a uniform way
+  to handle bundle configuration. It contains the
+  <a  target="_top" href="../../javadoc/index.html?org/osgi/service/cm/ManagedService.html">
+    ManagedService
+  </a>
+  interfaces to be   implemented by bundles that need configuration
+  data, and the
+  <a  target="_top" href="../../javadoc/index.html?org/osgi/service/cm/ConfigurationAdmin.html">
+    ConfigurationAdmin
+  </a>
+   service to be used by management bundles that modify configuration data.
+<p>
+  The ConfigurationAdmin interface is the main interface to the
+  Configuration Management component. It is the interface that is
+  registered as a service in the Service Registry and it has methods
+  for creating, retrieving, and listing configurations. The
+  implementation of this interface is responsible for the persistent
+  storage of configurations, and listens for registrations of
+  ManagedServices and ManagedServiceFactories in the Service Registry
+  and passes out configuration data, if available, when they appear.
+</p>
+<p>
+  The
+  <a href="../cm_cmd/index.html">cm_commands</a>,
+  bundle provides a console command group to Configuration Management.
+</p>
+<p>
+  The
+  <a href="../prefs/index.html">Preference Service</a>,
+  is an alternative method for storing configuration data but it lacks
+  the administrative functions the Configuration Management bundle
+  provides.
+</p>
+
+
+<h2 class="man"><a name="cm_data.dtd">Configuration data as XML files</a></h2>
+
+<p>
+
+  The Knopflerfish CM implementation provides a legacy XML DTD, <a
+  href="cm_data.dtd">cm_data.dtd</a>, that specifies one format for
+  storing configurations as XML-documents. The Java package <a
+  href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html"><tt>org.knopflerfish.shared.cm</tt></a>
+  contains helper classes for writing and reading this XML format.
+
+</p>
+
+<p>
+
+  The cm_data XML-format is used by the import and export commands
+  provided by the <a href="../cm_cmd/index.html">cm_commands</a>
+  console command bundle.  It is also supported by the <a
+  href="../dirdeployer/index.html">Directory Deployer</a> bundle and
+  by the Desktop plug-in bundle named <em>CM-Desktop</em>.
+
+</p>
+
+<p>
+  Limitations that are not specified <tt>cm_data.dtd</tt>: <ul>
+
+    <li>The mode attribute on configurations and factory
+        configurations is deprecated and not used. If present in the
+        XML-document set the value to "new" for ordinary configuration
+        and "update" for factory configuration instances.
+
+    <li>Properties with a value of type array must have an element
+        type that is either a primitive value or one of the types
+        defined by the TYPE entity. Make sure that the length
+        attribute on the array element is correct, otherwise the
+        parsing will fail with strange error messages.
+
+    <li>Properties with a value of type Vector must have all element
+        of the same type and that type must be one of the types
+        defined by the TYPE entity. Make sure that the length
+        attribute on the array element is correct, otherwise the
+        parsing will fail with strange error messages.
+
+  </ul>
+</p>
+
+
+
+<h2 class="man">Configuration properties</h2>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>com.gatespace.bundle.cm.store</td>
+    <td>
+
+	Path to a directory that CM will use for its persistent
+	storage. The default location when this property is un-set or
+	empty is a sub-directory named <tt>cm_store</tt> in the
+	bundles data-directory. This means that all configurations are
+	lost when the framework is restarted with the <tt>-init</tt>
+	option present (i.e., the framework property
+	<tt>org.osgi.framework.storage.clean</tt> set to <tt>true</tt>).
+
+	<p>Set this to a path pointing to some writable directory
+	outside the frameworks cache directory (<tt>fwdir</tt>) if
+	configuration data are to survive <tt>-init</tt> restarts.
+
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+</table>
+
+
+<h2 class="man">See Also</h2>
+<a href="../cm_cmd/index.html">cm_commands</a>,
+<a href="../prefs/index.html">prefs</a>,
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=cm/cm_all-5.0.1.html">cm_all-5.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=cm/cm_api-5.0.1.html">cm_api-5.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=cm/cm-5.0.1.html">cm-5.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=cm/cm_all-5.0.1.html">cm_all-5.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=cm/cm-5.0.1.html">cm-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td><td align="center">1.5.0</td><td><a target="_top" href="../../jars/index.html?bundle=cm/cm_all-5.0.1.html">cm_all-5.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/cm_cmd/index.html b/docs/bundledoc/cm_cmd/index.html
new file mode 100644
index 0000000..68df0ec
--- /dev/null
+++ b/docs/bundledoc/cm_cmd/index.html
@@ -0,0 +1,147 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - cm_cmd, v5.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: cm_cmd
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.1
+      </div>
+      <h1 class="man">CM Commands</h1>
+
+<div class="abstract">
+  Console command group for Configuration Management
+</div>
+
+<h2 class="man">Description</h2>
+
+<p>
+  The CM Commands bundle provides the <b>configuration</b> <a
+  href="../console/index.html"> console</a> command group.  The
+  command group defines a set of console commands available for
+  interacting with the Configuration Manager.  The list below gives a
+  short description of what the commands do, for complete details on
+  parameters, use help on each command in the console.
+</p>
+
+<p>
+  The Knopflerfish CM implementation provides a legacy XML DTD, <a
+  href="cm_data.dtd">cm_data.dtd</a>, that specifies one format for
+  storing configurations as XML-documents. The Java package
+  <tt>org.knopflerfish.shared.cm</tt> contains helper classes for
+  writing and reading this XML format.
+</p>
+
+<p>
+  The import and export commands works with XML-documents following
+  the <a href="../cm/cm_data.dtd">cm_data.dtd</a>. See <a
+  href="../cm/index.html#cm_data.dtd">cm</a> for a description of
+  this format.
+</p>
+
+
+  <pre class="code">
+Available configuration commands:
+  create [-help] [-f] <pid> [<template>] - Create a configuration and open it for editing.
+  current [-help] [-t] - Show the currently open configuration.
+  delete [-help] <selection> - Delete an existing configuration.
+  edit [-help] <selection> - Edit an existing configuration.
+  export [-help] <file>] [<selection>] ... - Export configurations in xml format to file.
+  import [-help] <url> - Import configuration data from xml file at url.
+  list [-help] [<selection>] ... - List the PIDs of existing configurations.
+  save [-help] [-force] - Save the currently open configuration in the CM.
+  set [-help] <property> <value> [<type>] - Set a property in the currently open configuration.
+  show [-help]  [-t] [<selection>] ... - Show the saved versions of configurations.
+  unset [-help] <property> - Remove a property from the currently open configuration.
+</pre>
+    
+
+<h2 class="man">Examples</h2>
+
+<p>The following lists the PIDs of all configurations in CM, then shows
+the configuration properties of the second configuration in the output
+of list (using the list index on the beginning of the line).</p>
+
+<pre class="code">
+<b>configuration> </b>list
+Available configurations:
+[0] org.knopflerfish.bundle.consoletelnet.TelnetServer
+[1] org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL
+[2] org.knopflerfish.bundle.http.factory.HttpServer.2
+<b>configuration> </b>show 1
+[1] org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL
+ location: file:jars/consoletelnet/consoletelnet-4.0.1.jar
+ change count: 11
+ properties:
+  busywait= false
+  defaultPassword= admin
+  defaultUser= admin
+  forbiddenGroup= 
+  host= localhost
+  port= 2321
+  requiredGroup= 
+  service.pid= org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL
+  um= false
+<b>configuration> </b>
+</pre>
+
+<p>Now create a new targeted configuration that will use [1] above as
+template to initialize its properties. Then we change the port property
+and saves the edited configuration.</p>
+
+<pre class="code">
+<b>configuration> </b>create 'org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL|file:jars/consoletelnet/consoletelnet-4.0.1.jar' 1
+<b>configuration> </b>current -t
+[-] org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL|file:jars/consoletelnet/consoletelnet-4.0.1.jar
+ location: -
+ change count: 1
+ properties:
+  busywait:Boolean= false
+  defaultPassword:String= admin
+  defaultUser:String= admin
+  forbiddenGroup:String= 
+  host:String= localhost
+  port:Short= 2321
+  requiredGroup:String= 
+  service.pid:String= org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL|file:jars/consoletelnet/consoletelnet-4.0.1.jar
+  um:Boolean= false
+<b>configuration> </b>set port 2322
+<b>configuration> </b>save
+<b>configuration> </b>l
+Available configurations:
+[0] org.knopflerfish.bundle.consoletelnet.TelnetServer
+[1] org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL
+[2] org.knopflerfish.bundle.consoletelnet.TelnetServer|org.knopflerfish.bundle.consoletelnet-IMPL|file:jars/consoletelnet/consoletelnet-4.0.1.jar
+[3] org.knopflerfish.bundle.http.factory.HttpServer.2
+<b>configuration> </b>
+</pre>
+
+
+<h2 class="man">See Also</h2>
+<a href="../cm/index.html">CM - Configuration Management</a>
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/cm_desktop/images/cm_desktop.png b/docs/bundledoc/cm_desktop/images/cm_desktop.png
new file mode 100644
index 0000000..24818af
Binary files /dev/null and b/docs/bundledoc/cm_desktop/images/cm_desktop.png differ
diff --git a/docs/bundledoc/cm_desktop/images/cm_desktop_300.png b/docs/bundledoc/cm_desktop/images/cm_desktop_300.png
new file mode 100644
index 0000000..1eb2327
Binary files /dev/null and b/docs/bundledoc/cm_desktop/images/cm_desktop_300.png differ
diff --git a/docs/bundledoc/cm_desktop/images/cm_desktop_systembundle.png b/docs/bundledoc/cm_desktop/images/cm_desktop_systembundle.png
new file mode 100644
index 0000000..586f32b
Binary files /dev/null and b/docs/bundledoc/cm_desktop/images/cm_desktop_systembundle.png differ
diff --git a/docs/bundledoc/cm_desktop/images/cm_desktop_systembundle_300.png b/docs/bundledoc/cm_desktop/images/cm_desktop_systembundle_300.png
new file mode 100644
index 0000000..057d298
Binary files /dev/null and b/docs/bundledoc/cm_desktop/images/cm_desktop_systembundle_300.png differ
diff --git a/docs/bundledoc/cm_desktop/images/frag.png b/docs/bundledoc/cm_desktop/images/frag.png
new file mode 100644
index 0000000..08f8c59
Binary files /dev/null and b/docs/bundledoc/cm_desktop/images/frag.png differ
diff --git a/docs/bundledoc/cm_desktop/images/lib.png b/docs/bundledoc/cm_desktop/images/lib.png
new file mode 100644
index 0000000..5ad3805
Binary files /dev/null and b/docs/bundledoc/cm_desktop/images/lib.png differ
diff --git a/docs/bundledoc/cm_desktop/index.html b/docs/bundledoc/cm_desktop/index.html
new file mode 100644
index 0000000..c779df5
--- /dev/null
+++ b/docs/bundledoc/cm_desktop/index.html
@@ -0,0 +1,152 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - cm_desktop, v5.0.2</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: cm_desktop
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.2
+      </div>
+      <h1 class="man">The Knopflerfish Desktop CM plug-in</h1>
+<div class="abstract">
+  The Knopflerfish OSGi Desktop CM plug-in provides a bundle detail
+  view for managing OSGi configurations.
+</div>
+
+
+<h2 class="man">Description</h2>
+<div style="float:right">
+  <a href="images/cm_desktop.png">
+    <img src="images/cm_desktop_300.png" width="300" height="244">
+  </a>
+</div>
+
+  <p>The Knopflerfish OSGi Desktop CM plug-in provides a bundle detail
+  view for managing OSGi configurations. It support common operations
+  as create, update and delete for CM configurations. It can also
+  import and export configurations using the <a
+  href="../cm/cm_data.dtd">cm_data.dtd</a> XML document format.</p>
+
+<h3 class="man">The CM-desktop view</h3>
+
+  <p>The view presents configurations with associated metatype
+  information for the selected bundle. In the top part of the view
+  there will be two selectors, selecting which PID (configuration) to
+  show. The upper selector selects amongst PIDs with accompanying
+  metatype data (OCD, Object Class Definition) defining the set of
+  properties (AD Attribute Definitions) that may be configured for the
+  PID. The second selector selects Factory PIDs (configurations). For
+  more information on metatype see chapter 105 in the OSGi Compendium
+  Specification.</p>
+
+  <p>The main part of the view shows one configuration with inputs for
+  all the properties defined for it in its metatype description. On
+  top there are controls for the CRUD-operations and if it is a
+  factory PID that was selected there will be a drop down for
+  selecting the instance of the factory PID to view and work with.</p>
+
+  <p>A configuration instance can be targeted to a specific bundle by
+  appending the actual PID with a target specification. It is possible
+  to target configuration instances on
+  <ul>
+    <li>Bundle symbolic name.
+    <li>Bundles symbolic name and version.
+    <li>Bundles symbolic name, version and location.
+  </ul> Controls for selecting the target level are available in the
+  upper par of the main view.</p>
+
+
+
+<div style="clear:both"></div>
+<h3 class="man">Special presentations</h3>
+
+<div style="float:right">
+  <a href="images/cm_desktop_systembundle.png">
+    <img src="images/cm_desktop_systembundle_300.png" width="300" height="244">
+  </a>
+</div>
+
+  <p>If the system bundle is the selected bundle then this displayer
+  will show the union of all PIDs defined by metatype information in
+  all installed bundles.</p>
+
+  <p>If the CM bundle is selected and the kf-metatype bundle is the
+  provider of the MetaTypeService then this view will show all
+  configurations present in CM. In this case metatype information is
+  generated from the actual configuration data so it will not be as
+  precise as the one obtained from metatype information in a bundle.
+
+  <p>If no bundle is selected (or a bundle without any meta type
+  information) then the view will display a page that informs about
+  these special presentations, a list of all bundles with meta type
+  information and an <em>Import...</em> button that will present a
+  dialog for importing <a href="../cm/cm_data.dtd">cm_data.dtd</a> XML
+  documents.</p>
+
+
+
+<div style="clear:both"></div>
+<h3 class="man">The CM-desktop dependencies</h3>
+
+  <p>The CM-Desktop needs the metatype API and an implementation of the
+  MetaTypeService to work. These are provided by the
+  <em>metatype</em>-bundle and the <em>kf_metatype</em> bundle.
+
+<div style="clear:both"></div>
+<h2 class="man">Configuration properties</h2>
+
+The CM-Desktop bundles does not support any properties for configuration.
+
+<!--
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.bundle.log.window.impl.LogTableModel.capacity</td>
+    <td>
+
+	The maximum number of log entries to keep in memory in one log
+	view. Use a negative value (i.e., a value smaller than 1) to
+	indicate that old entries shall never be removed.
+
+    </td>
+    <td>int</td>
+    <td>342</td>
+  </tr>
+</table>
+-->
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a><br>
+<a target="_top" href="../../jars/index.html?bundle=cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/component/index.html b/docs/bundledoc/component/index.html
new file mode 100644
index 0000000..c3fea1e
--- /dev/null
+++ b/docs/bundledoc/component/index.html
@@ -0,0 +1,71 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - component, v5.0.3</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: component
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.3
+      </div>
+      <h1 class="man">SCR</h1>
+
+<div class="abstract">
+Implementation of the Service Component Runtime.<br> I.e., the extender
+that processes bundles using Declarative Services.
+</div>
+
+<!--
+<h3 class="man">Configuration using Framework Properties</h3>
+
+<table class="man">
+  <tr>
+    <th class="man">Name</th>
+    <th>Description</th>
+    <th>Type</th>
+    <th>Default</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.component.xx</td>
+    <td>
+
+      Description
+
+    </td>
+    <td></td>
+    <td></td>
+  </tr>
+</table>
+-->
+
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=component/component_all-5.0.3.html">component_all-5.0.3</a><br>
+<a target="_top" href="../../jars/index.html?bundle=component/component_api-5.0.3.html">component_api-5.0.3</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a></td><td align="center">1.6.0</td><td><a target="_top" href="../../jars/index.html?bundle=component/component_all-5.0.3.html">component_all-5.0.3</a>, <a target="_top" href="../../jars/index.html?bundle=component/component_api-5.0.3.html">component_api-5.0.3</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td><td align="center">1.2.1</td><td><a target="_top" href="../../jars/index.html?bundle=component/component_all-5.0.3.html">component_all-5.0.3</a>, <a target="_top" href="../../jars/index.html?bundle=component/component_api-5.0.3.html">component_api-5.0.3</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/console/index.html b/docs/bundledoc/console/index.html
new file mode 100644
index 0000000..2990436
--- /dev/null
+++ b/docs/bundledoc/console/index.html
@@ -0,0 +1,376 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - console, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: console
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">Console</h1>
+<div class="abstract">
+  The Knopflerfish console bundle
+</div>
+
+<h2 class="man">Description</h2>
+<h3 class="man">Introduction</h3>
+   The user's guide contains information about the console interfaces,
+   the command group concept and reference documentation for the
+   console's built in commands.
+
+<h3 class="man"> Terminology </h3>
+
+   Terms, acronyms and syntax of console commands.
+
+<dl>
+<dt>   command group
+<dd>          A set of commands exported to the console from some bundle.
+
+<dt>   EOF
+<dd>          End Of File, close of console input.
+
+<dt>   session
+<dd>          What you are in when communicating with the console
+
+<dt>   session group
+<dd>          The command group for the console built in commands.
+</dl>
+
+<h3 class="man"> Syntax Elements </h3>
+
+<dl>
+<dt>   []
+<dd>          Delimiters for optional parts of a command and optional
+          parameters.
+
+<dt>   |
+<dd>          To indicate alternate parameters.
+
+<dt>   ...
+<dd>          More parameters, same type as the previous one.
+
+<dt>   #value#
+<dd>          Parameter to a flag.
+
+<dt>   " "
+<dd>          Double quotes. Used to contain parameters that have blanks in
+          them.
+
+<dt>   <parameter>
+<dd>          Command parameter to be replaced with data.
+</dl>
+
+<h3 class="man"> Console Interfaces</h3>
+
+   The console bundle is not very useful on its own; it needs other
+   bundles to supply the commands and also at least one bundle supplying
+   a user interface. The console uses the CommandGroup service of the
+   command supplying bundles to access commands. A console user interface
+   bundle uses the ConsoleService service of the console bundle to
+   execute commands ordered by the user.
+<p>
+   The console bundle actually has some built in commands that can be
+   used for administrative tasks, that is, managing the user session.
+   These are the commands in the command group session.
+<p>
+   The following bundles implement user interfaces:
+
+   consoletty
+          Basic tty console, available in the terminal window where the
+          platform is started.
+
+   consoletelnet
+          Basic telnet console, listens on a port using the telnet protocol.
+
+<h3 class="man"> General Command Structure and Behavior</h3>
+
+   The general command format is built of:
+<pre>
+<command group> <command> [<flag [#parameter#]> ...] [<parameter> ...]
+</pre>
+   First is the command group (all commands must belong to a command
+   group), then the command. After the command is zero, one or more flags
+   with possible additional parameters and finally zero, one or more
+   parameters. See chapter [2]Terminology on page 1 for explanations of
+   delimiters.
+<p>
+   Note: To avoid having negative numbers interpreted as flags, negative
+   numbers are to be written with double hyphens (as --n).
+<p>
+   At start-up, the console is in the initial state. When entering a
+   command the command line must begin with the command group's name, as
+   described above. However, the session can enter a group with the
+   session enter command. After entering a command group, commands of
+   that group are executed without the group name as prefix. The session
+   leave command leaves the current group and the session is back in its
+   initial state.
+<p>
+   Commands from other groups than the current group can be executed by
+   prefixing the command with a slash ("/"). For example, the following
+   would execute the shutdown command from the framework command group,
+   regardless of the session's current group.
+  /framework shutdown
+<p>
+   Normally, command groups and commands may be shortened as long as they
+   are unambiguously identifiable. As an example, in command group
+   session, the command alias may be shortened to a as it is the only
+   command that starts with the letter a.
+<p>
+
+<h3 class="man"> Session Commands</h3>
+
+   This is the command group for the console's built in administrative
+   commands. It contains commands for managing a session.
+<p>
+   All of the session commands have aliases to make them quick to enter
+   regardless of the current command group. For example, /session help
+   has the alias help. In all the examples below, the alias versions of
+   the session commands are used.
+<p>
+   The commands in the session command group are:
+<pre>
+     * alias [<alias>] [<val>] ...
+     * enter <command group>
+     * help
+     * leave
+     * prompt <prompt>
+     * quit
+     * save
+     * unalias <alias name>
+</pre>
+
+<h3 class="man">Command Details</h3>
+
+   Detailed description of all session commands in alphabetical order.
+
+<h4>alias</h4>
+
+   To set or show aliases.
+<pre>
+  alias [<alias>] [<value>] ...
+
+   The command without any parameters prints a list of all existing
+   aliases:
+  > alias
+  start = /framework start
+  install = /framework install
+  prompt = /session prompt
+  lsb = /framework bundles
+  fw = /session enter framework
+  log = /log show
+  help = /session help
+  quit = /session quit
+  lss = /framework services
+  alias = /session alias
+  unalias = /session unalias
+  enter = /session enter
+  stop = /framework stop
+  bundles = /framework bundles
+  leave = /session leave
+  >
+</pre>
+   With parameters it sets an alias to the specified value. If the alias
+   exists, the old value is replaced with the new. With one parameter the
+   value of that alias is shown.
+
+<h4>enter </h4>
+
+   Enter a command group, in effect automatically prefix all commands
+   with the name of the command group. This makes it possible to use the
+   short names of the group's commands.
+<pre>
+  enter <command group>
+</pre>
+
+   The result is that the prompter is prefixed with the command group and
+   all the commands in the command group are available in short form.
+   Example: Entering a command group
+<pre>
+  > enter framework
+  framework> help
+  Available framework commands:
+    bundles [-help] [-1] [-i] [-l] [<bundle>] ... - List bundles
+    call [-help] <interface> <method> [<args>] ...
+      - Call a method in a registered service
+    headers [-help] <bundle> ... - Show bundle header values
+    package [-help] <package> ... - Show java package information
+    install [-help] [-s] <location> ... - Install one or more bundles
+    services [-help] [-i] [-l] [-r] [-s] [-u] [<bundle>] ...
+      - List registered services
+    start [-help] <bundle> ... - Start one or more bundles
+    stop [-help] <bundle> ... - Stop one or more bundles
+    shutdown [-help] [<exit code>] - Shutdown framework
+    uninstall [-help] >bundle> ... - Uninstall one or more bundles
+    update [-help] [-r] <bundle> ... - Update one or more bundles
+</pre>
+
+   It is only possible to be in one command group at a given moment. By
+   adding a slash ("/") to the group name, commands in other gruops can
+   be accessed.
+
+<h4>help</h4>
+
+   Show help information about commands and command groups.
+<pre>
+  help [<command group> | all]
+</pre>
+   Lists the commands available in the specified command group, each with
+   a short description. If no command group is specified, help for the
+   current group is displayed.
+
+   In the initial state, or if the parameter all is supplied, help shows
+   the available command groups.
+   Example: Display available command groups
+<pre>
+  > help
+  Available command groups:
+  session - Session commands built into the console
+  logconfig - Configuration commands for the log.
+  log - Log commands
+  framework - Framework commands
+  >
+</pre>
+   Note that this list can be longer as any installed bundle can export
+   its own commands.
+
+<h4>leave</h4>
+
+   Leave a command group, that is, go back to the initial state (no
+   current command group).
+<pre>
+  leave
+</pre>
+   Example: Leave the current command group
+<pre>
+  framework> leave
+  >
+</pre>
+   Note that leave only goes to the initial state, it does not go to the
+   previous command group, if any.
+
+<h4>prompt</h4>
+
+   Set the command prompter.
+<pre>
+  prompt <command prompt>
+</pre>
+   If the command group is to be visible in the prompt, a percent
+   character ("%") should be included in the prompt string. At printout,
+   the % character will be replaced by the command group name.
+   Example: Changing the prompter
+<pre>
+  > prompt "%test >"
+  test >
+  enter framework
+  frameworktest >
+</pre>
+
+<h4>quit</h4>
+
+   Exit the session.
+<pre>
+  quit
+</pre>
+   The console exits and loses contact with standard in.
+
+<h4> save</h4>
+
+   This command saves the current aliases to persistent memory. The
+   aliases are read next time the platform is started.
+  save
+
+<h4> unalias</h4>
+
+   This command removes an alias.
+<pre>
+  unalias
+</pre>
+   Example: Creating and removing an alias
+<pre>
+  > alias more less
+  > unalias more
+</pre>
+
+<h3 class="man"> Interface consoletty</h3>
+
+   The consoletty bundle allows local console access to the platform
+   without the use of the http server.
+<p>
+   If the platform starts the consoletty, it will use the text window the
+   platform was started from.
+
+<h3 class="man"> Interface consoletcp</h3>
+
+   To allow remote console access to the platform without the use of the
+   http server, the consoletcp bundle listens to a port on the platform.
+   See [[3]1] information regarding the port number.
+
+   Depending on configuration, the TCP console will require that the user
+   logs in before creating a console session. See [[4]1] for more
+   information.
+
+   The user name/password authentication method is used for
+   authentication. The Input Path is set to "tcp" and the Auhtentication
+   Method is set to "passwd".
+
+   The commands and their formats are the same as for the consoletty. To
+   access it in a simple way, use telnet.
+   Example: Using telnet and consoletcp
+<pre>
+> telnet demo.gatespace.se 8999
+Trying 127.0.0.1...
+Connected to localhost.localdomain.
+Escape character is '^]'.
+> help
+Available command groups:
+session - Session commands built into the console
+osgilog - Log commands
+messenger - Messenger route configuration commands.
+logconfig - Configuration commands for the log.
+framework - Framework commands
+
+>
+</pre>
+
+<h3 class="man"> Environmental influences</h3>
+
+   Due to the fact that console windows may be opened in many different
+   environments that have different capabilities, the console may seem to
+   behave different.
+
+   One example is the occurence of a "command history" in some
+   environments. This capability is however supplied by the window
+   manager "locally", the console does not have any command history
+   capability.
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=console/console_all-4.0.1.html">console_all-4.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=console/console_api-4.0.1.html">console_api-4.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=console/console-4.0.1.html">console-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td><td align="center">2.1.2</td><td><a target="_top" href="../../jars/index.html?bundle=console/console_all-4.0.1.html">console_all-4.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=console/console_api-4.0.1.html">console_api-4.0.1</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/consoletcp/index.html b/docs/bundledoc/consoletcp/index.html
new file mode 100644
index 0000000..d91c4b8
--- /dev/null
+++ b/docs/bundledoc/consoletcp/index.html
@@ -0,0 +1,101 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - consoletcp, v5.0.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: consoletcp
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.0
+      </div>
+      <h1 class="man">Console TCP</h1>
+<div class="abstract">
+  This bundle provides a tcp server that acts as a user interface
+  to the KF console
+</div>
+<h2 class="man">Description</h2>
+
+<p>
+
+The Console TCP bundle is a tcp server that makes Knopflerfish console
+commands available to the end user. Any tcp client can be used to
+connect to it.
+
+<p>
+This bundle is typically used during development.
+
+
+<h3 class="man">Configuration using the Configuration Manager</h3>
+
+The tcp console bundle accepts a configuration with the PID
+<pre>
+  org.knopflerfish.bundle.consoletcp.ConsoleTcp
+</pre>
+
+and with the following properties:
+
+<dl>
+
+<dt>host</dt>
+<dd>Host name (IP address) of the interface to listen for tcp
+    connections to the console on.</dd>
+
+<dt>port</dt>
+<dd>Port to listen for tcp connections to the console on.</dd>
+
+<dt>um</dt>
+<dd>If set to true User Management is required. I.e., if there is no
+    UserAdmin service in the system login will be denied. When set to
+    false and there is no UserAdmin service then the default
+    user/password will be used.</dd>
+
+<dt>requiredGroup</dt>
+<dd>When UserAdmin is used the user must belong to this group to be
+    allowed to log in.</dd>
+
+<dt>forbiddenGroup</dt>
+<dd>When UserAdmin is used the user must NOT belong to this group to be allowed to log in.</dd>
+
+<dt>useTimeout</dt>
+<dd>Enable/disable setting of SO_TIMEOUT for the client socket.</dd>
+
+<dt>exitOnLogout</dt>
+<dd>Indicates if the session should be closed if the user logs out. If
+    this is not set to true, the session will be kept open, but no
+    Authorization object will be present and hence the user will have
+    no special rights.</dd>
+
+<dt>defaultUser</dt>
+<dd>The only user name that is accepted when no UserAdmin service is
+    available.</dd>
+
+<dt>defaultPassword</dt>
+<dd>The password to accept when no UserAdmin service is
+    available.</dd>
+
+</dl>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a><br>
+<a target="_top" href="../../jars/index.html?bundle=consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/consoletelnet/index.html b/docs/bundledoc/consoletelnet/index.html
new file mode 100644
index 0000000..760178e
--- /dev/null
+++ b/docs/bundledoc/consoletelnet/index.html
@@ -0,0 +1,116 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - consoletelnet, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: consoletelnet
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">Console Telnet</h1>
+<div class="abstract">
+  This bundle provides a telnet server that acts as a user interface
+  to the KF console
+</div>
+<h2 class="man">Description</h2>
+
+<p>
+The Console Telnet bundle is a telnet server that makes Knopflerfish
+console commands available to the end user. Any telnet client can be
+used to connect to it.
+
+<p>
+This bundle is typically used during development.
+
+
+
+<h2 class="man">Configuration properties</h2>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.consoletelnet.user</td>
+    <td>
+
+	User login name for remote access.
+
+    </td>
+    <td>String</td>
+    <td>admin</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.consoletelnet.pwd</td>
+    <td>
+
+	Password for the user login name configured using the property
+	<tt>org.knopflerfish.consoletelnet.user</tt> described above.
+
+    </td>
+    <td>String</td>
+    <td>admin</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.consoletelnet.port</td>
+    <td>
+
+	Port number that the telnet server will listen on.
+
+    </td>
+    <td>int</td>
+    <td>23</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.consoletelnet.host</td>
+    <td>
+
+	Host (IP interface name) to open the telnet server socket
+	on. An empty string means all available interfaces.
+
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.consoletelnet.busywait</td>
+    <td>
+
+	If set to true use a busy-loop polling for characters from the
+	input stream. If false the reading thread will hang on the
+	read-operation until data becomes available.
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+
+</table>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/consoletty/index.html b/docs/bundledoc/consoletty/index.html
new file mode 100644
index 0000000..da9b7da
--- /dev/null
+++ b/docs/bundledoc/consoletty/index.html
@@ -0,0 +1,65 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - consoletty, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: consoletty
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">Console TTY</h1>
+<div class="abstract">
+  This bundle provides a console session on standard input for the JRE.
+</div>
+<h2 class="man">Description</h2>
+
+<p>
+
+The Console TTY bundle provides a tty console session on top of
+System.in and System.out (the standard input / output of the JVM).
+
+<p>
+This bundle is typically used during development.
+
+
+<h3 class="man">Configuration using the Configuration Manager</h3>
+
+The tty console bundle accepts a configuration with the PID
+<pre>
+  org.knopflerfish.bundle.consoletty.ConsoleTty
+</pre>
+
+and with the following properties:
+
+<dl>
+
+<dt>nonblocking</dt>
+<dd>Use non-blocking tty access. Some JVM-OS combinations cannot
+    handle blocking access to standard input.</dd>
+
+</dl>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/crimson/index.html b/docs/bundledoc/crimson/index.html
new file mode 100644
index 0000000..af6bc24
--- /dev/null
+++ b/docs/bundledoc/crimson/index.html
@@ -0,0 +1,65 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - crimson, v2.1.0.kf4-001</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: crimson
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 2.1.0.kf4-001
+      </div>
+      <h1 class="man">Crimson XML parser</h1>
+
+<div class="abstract">
+<p>
+  The Crimson XML parser
+</div>
+
+<h2 class="man">Crimson-XML</a></h2>
+<p>
+The Crimson-XML bundle is a wrapper for the Crimson XML parser and is
+primary older Java versions that does not provide built-in XML
+parsing.  
+</p><p>
+xTo enable the Java 6 parsers the Crimson XML parser bundle must not be  
+installed, or started. This is easiest done by commenting out the  
+Crimson XML bundle in the init.xargs file.
+</p>
+
+
+ 
+
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?javax/xml/parsers/package-summary.html">javax.xml.parsers</a></td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td></tr>
+ <tr><td>org.apache.crimson.jaxp</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td></tr>
+ <tr><td>org.w3c.dom</td><td align="center">2.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td></tr>
+ <tr><td>org.xml.sax</td><td align="center">2.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td></tr>
+ <tr><td>org.xml.sax.ext</td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td></tr>
+ <tr><td>org.xml.sax.helpers</td><td align="center">2.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/desktop/images/bundle.png b/docs/bundledoc/desktop/images/bundle.png
new file mode 100644
index 0000000..e0eb8cd
Binary files /dev/null and b/docs/bundledoc/desktop/images/bundle.png differ
diff --git a/docs/bundledoc/desktop/images/bundle_active.png b/docs/bundledoc/desktop/images/bundle_active.png
new file mode 100644
index 0000000..aba7c57
Binary files /dev/null and b/docs/bundledoc/desktop/images/bundle_active.png differ
diff --git a/docs/bundledoc/desktop/images/desktop_details.png b/docs/bundledoc/desktop/images/desktop_details.png
new file mode 100644
index 0000000..fc445f2
Binary files /dev/null and b/docs/bundledoc/desktop/images/desktop_details.png differ
diff --git a/docs/bundledoc/desktop/images/desktop_graph.png b/docs/bundledoc/desktop/images/desktop_graph.png
new file mode 100644
index 0000000..81f5838
Binary files /dev/null and b/docs/bundledoc/desktop/images/desktop_graph.png differ
diff --git a/docs/bundledoc/desktop/images/desktop_icons.png b/docs/bundledoc/desktop/images/desktop_icons.png
new file mode 100644
index 0000000..013343e
Binary files /dev/null and b/docs/bundledoc/desktop/images/desktop_icons.png differ
diff --git a/docs/bundledoc/desktop/images/desktop_main.png b/docs/bundledoc/desktop/images/desktop_main.png
new file mode 100644
index 0000000..f493949
Binary files /dev/null and b/docs/bundledoc/desktop/images/desktop_main.png differ
diff --git a/docs/bundledoc/desktop/images/desktop_main_300.png b/docs/bundledoc/desktop/images/desktop_main_300.png
new file mode 100644
index 0000000..e73d851
Binary files /dev/null and b/docs/bundledoc/desktop/images/desktop_main_300.png differ
diff --git a/docs/bundledoc/desktop/images/frag.png b/docs/bundledoc/desktop/images/frag.png
new file mode 100644
index 0000000..08f8c59
Binary files /dev/null and b/docs/bundledoc/desktop/images/frag.png differ
diff --git a/docs/bundledoc/desktop/images/lib.png b/docs/bundledoc/desktop/images/lib.png
new file mode 100644
index 0000000..51588e7
Binary files /dev/null and b/docs/bundledoc/desktop/images/lib.png differ
diff --git a/docs/bundledoc/desktop/images/lib_resolved.png b/docs/bundledoc/desktop/images/lib_resolved.png
new file mode 100644
index 0000000..bc4c856
Binary files /dev/null and b/docs/bundledoc/desktop/images/lib_resolved.png differ
diff --git a/docs/bundledoc/desktop/images/scr.png b/docs/bundledoc/desktop/images/scr.png
new file mode 100644
index 0000000..e2dc562
Binary files /dev/null and b/docs/bundledoc/desktop/images/scr.png differ
diff --git a/docs/bundledoc/desktop/images/scr_active.png b/docs/bundledoc/desktop/images/scr_active.png
new file mode 100644
index 0000000..43ddd06
Binary files /dev/null and b/docs/bundledoc/desktop/images/scr_active.png differ
diff --git a/docs/bundledoc/desktop/images/scr_resolved.png b/docs/bundledoc/desktop/images/scr_resolved.png
new file mode 100644
index 0000000..4ea2d09
Binary files /dev/null and b/docs/bundledoc/desktop/images/scr_resolved.png differ
diff --git a/docs/bundledoc/desktop/index.html b/docs/bundledoc/desktop/index.html
new file mode 100644
index 0000000..f5ab647
--- /dev/null
+++ b/docs/bundledoc/desktop/index.html
@@ -0,0 +1,404 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - desktop, v5.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: desktop
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.1
+      </div>
+      <h1 class="man">The Knopflerfish Desktop</h1>
+
+<div class="abstract">
+  The Knopflerfish OSGi Desktop displays a graphical overview of the OSGi
+  framework.
+</div>
+
+
+<h2 class="man">Description</h2>
+<div style="float:right">
+  <a href="images/desktop_main.png">
+    <img src="images/desktop_main_300.png" width="300" height="201">
+  </a>
+</div>
+
+  <p>The Knopflerfish OSGi Desktop displays a graphical overview of
+  the OSGi framework. Most common operations as install, start, stop
+  and update can be performed on bundles using the
+  desktop. Additionally, bundle and service detail information is
+  shown, and an experimental "Save deploy archive" is included.</p>
+
+  <p>The desktop is a standard OSGi bundle, using Swing. The desktop
+  is primarily designed to manage a locally running framework, but can
+  be used to control a remote framework, using the optional <a
+  href="../soap/index.html">SOAP bundles</a>.  Consult the description
+  of <a href="../remotefw/index.html">how to activate the "Remote
+  framework..." menu item</a>.</p>
+
+  <p>Additionally, the <a href="../httpconsole/index.html">HTTP
+  console</a> or the <a href="../consoletelnet/index.html">Telnet
+  console</a> bundle can always be used for remote control. Both are
+  available in the <a href="http://www.knopflerfish.org/repo/">KF
+  bundle repository</a>.  </p>
+
+  <p>The desktop can be customized using plug-in services, see <a
+     target="_top"
+     href="../../javadoc/index.html?org/knopflerfish/service/desktop/SwingBundleDisplayer.html">
+     SwingBundleDisplayer</a> for details.</p>
+
+<div style="clear:both"></div>
+
+
+<h3 class="man">The desktop main areas</h3>
+
+<p>
+  When started, it creates a window with four main areas:
+  <dl>
+    <dt>Toolbar
+      <dd>The top toolbar provides quick access to common operations
+	as start/stop/update bundles.
+      </dd>
+    <dt>Bundle view</dt>
+    <dd>
+      The center bundle view area display all installed bundles
+      and their states. By clicking on bundles in this are,
+      detail information is displayed in the <b>Bundle detail area</b>
+      Three different views a supported internally (new can be installed):
+      <ul>
+	<li><a href="#view_icons">Icons</a> - each bundle is displayed as an icon.
+	<li><a href="#view_graph">Graph</a> - each bundle is displayed in a really cool graphics view.
+	<li><a href="#view_details">Details</a> - each bundle is displayed as a table row.
+      </ul>
+	</dd>
+    <dt>Bundle detail area</dt>
+    <dd>
+      The rightmost bundle detail area shows detailed
+      information on various aspects of the selected bundles such as:
+      <ul>
+	<li>Manifest</li>
+	<li>Bundle closure</li>
+	<li>Services, i.e imported/exported services</li>
+	<li>Capabilities and wires, i.e. provided and required capabilites</li>
+	<li>SCR, i.e. declarative service components</li>
+	<li>Log, i.e. bundle logs</li>
+	<li>Events</li>
+	<li>Prefs, i.e. bundle preferences</li>
+      </ul>
+      New detail pages can be installed run-time using plug-ins.
+    </dd>
+    <dt>Framework console</dt>
+    <dd>
+      The bottom console area allows interaction with the
+      text console. This console acts exactly as
+      the <a href="../console/index.html">consoltty</a> bundle, but
+      does not require a shell or DOS window to run. 
+    </dd>
+  </dl>
+<p>
+
+  
+<h3 class="man"><a name="view_icons">Icon view</a></h3>
+
+<p>To view the installed bundles as icons, select</p>
+<pre>
+View -> Icons
+</pre>
+
+<div style="float:left">
+  <img src="images/desktop_icons.png" width="403" height="489">
+</div>
+
+<table class="man">
+  <tr>
+    <td><img src="images/bundle.png"></td>
+    <td>Bundle which has a BundleActivator</td>
+  </tr>
+  <tr>
+    <td><img src="images/bundle_active.png"></td>
+    <td>Active bundle</td>
+  </tr>
+  <tr>
+    <td><img src="images/lib.png"></td>
+    <td>"Library" bundle which has no BundleActivator</td>
+  </tr>
+  <tr>
+    <td><img src="images/lib_resolved.png"></td>
+    <td>Resolved "Library" bundle</td>
+  </tr>
+  <tr>
+  <tr>
+    <td><img src="images/scr.png"></td>
+    <td>Bundle using declarative services (SCR)</td>
+  </tr>
+  <tr>
+    <td><img src="images/scr_resolved.png"></td>
+    <td>Resolved declarative services bundle</td>
+  </tr>
+  <tr>
+  <tr>
+    <td><img src="images/scr_active.png"></td>
+    <td>Active declarative services bundle</td>
+  </tr>
+  <tr>
+  <tr>
+    <td><img src="images/frag.png"></td>
+    <td>Fragment bundle.</td>
+  </tr>
+  <tr>
+    <td> </td>
+    <td>
+
+      <p>A bundle may provide its own icon by listing it in the
+      manifest attribute <tt>Bundle-Icon:</tt>. See the OSGi Core
+      specification R4 v4.3 for details on this.</p>
+
+      <p>Example of bundles providing their own icon are: "System
+      Bundle", "Log Service", "cm" and "Console".</p>
+    
+    </td>
+
+  </tr>
+</table>
+<div style="clear:both"></div>
+
+<p>
+Bundles can be selected by clicking.
+</p>
+
+
+<h3 class="man"><a name="view_details">Detail list view</a></h3>
+
+  <p>To view the installed bundles as a detailed list, select</p>
+<pre>
+  View -> Details
+</pre>
+
+  <img src="images/desktop_details.png" width="825" height="431">
+
+  <p>Bundles can be selected by clicking.</p>
+
+
+
+<h3 class="man"><a name="view_graph">Graph View view</a></h3>
+
+  <div style="float:right">
+    <img src="images/desktop_graph.png" width="800" height="462">
+  </div>
+
+  <p>To view the installed bundles as graphics, select</p>
+<pre>
+View -> Graph
+</pre>
+
+
+  <p>The top left corner shows the bundle id and name of the currently
+  selected bundle.</p>
+
+  <p>The lower left corner shows a bundle selection
+  history. Double-click on any of those bundles to re-select it.</p>
+
+  <p>The left hand side of the view shows package dependencies. Lines
+  below the horizon are packages that the bundle imports and lines
+  above the horizon are the packages that the bundle exports to
+  another bundle. There is one export-line for each bundle that
+  imports the package. Holding the mouse pointer over a package-line
+  will pop-up a tool tip with the name and version of the
+  package. Holding the mouse pointer over the end of a package line
+  will pop-up a tool-tip showing the bundle that the package was
+  imported from or exported to. Click on the end of a package line to
+  select the bundle associated with it (that bundle will be
+  highlighted every where it occurs in the graph), double-click to
+  center the graph on the selected bundle. Above each export
+  package line a mini-graph showing the exports of the bundle
+  importing the package is drawn.</p>
+
+
+  <p>The right hand side of the view shows service dependencies. Lines
+  below the horizon are services that the bundle uses (imports) and
+  lines above the horizon are the services that the bundle provides
+  (exports) to another bundle. There is one export-line for each
+  bundle that uses a registered service. Holding the mouse pointer
+  over a service-line will pop-up a tool tip with the service id and
+  object-class of the service it represents. Holding the mouse pointer
+  over the end of a service line will pop-up a tool-tip showing the
+  bundle that the service was imported from or exported to. Click on
+  the end of a service line to select the bundle associated with it
+  (that bundle will be highlighted every where it occurs in the
+  graph), double-click to center the graph on the selected bundle.
+  Above each export service line is a mini-graph showing the services
+  provided by the bundle using the service that the line
+  represents.</p>
+
+  <p>The transparent blue half-circle below (or above) the selected
+  bundle is a scroll-bar that scrolls the package/service lines. Drag
+  the mouse horizontally, starting in side the half circle, to
+  scroll.</p>
+
+<div style="clear:both"></div>
+
+
+
+<h2 class="man">Configuration properties</h2>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.bundle.log.window.impl.LogTableModel.capacity</td>
+    <td>
+
+	The maximum number of log entries to keep in memory in one log
+	view. Use a negative value (i.e., a value smaller than 1) to
+	indicate that old entries shall never be removed.
+
+    </td>
+    <td>int</td>
+    <td>342</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.desktop.display.large_icons.sort</td>
+    <td>
+
+	The sort order to use for icons in the "Large Icons" bundle
+	displayer. Supported values are:
+	<dl>
+	  <dt><code>id</code></dt>          <dd>Bundle id order (default).</dd>
+	  <dt><code>name</code></dt>        <dd>Bundle name order.</dd>
+	  <dt><code>start_level</code></dt> <dd>Bundle start level order.</dd>
+	</dl>
+	Any unrecognized value will result sorting icons based o the
+	bundle id.
+
+	<p>
+	The desktop bundles stores the sort order amongst its
+        preferences (for each framework service id), if this property
+	is set it will over-ride the saved preferences value.</p>
+
+    </td>
+    <td>String</td>
+    <td>id</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.desktop.displays</td>
+    <td>
+
+	A white-space separated list of built in desktop displays to
+	instantiate on startup. Each item in the list is the full
+	class name of a displayer.
+
+    </td>
+    <td>String</td>
+    <td>
+	org.knopflerfish.bundle.desktop.swing.LargeIconsDisplayer
+	org.knopflerfish.bundle.desktop.swing.GraphDisplayer
+	org.knopflerfish.bundle.desktop.swing.TableDisplayer
+	org.knopflerfish.bundle.desktop.swing.ManifestHTMLDisplayer
+	org.knopflerfish.bundle.desktop.swing.ClosureHTMLDisplayer
+	org.knopflerfish.bundle.desktop.swing.ServiceHTMLDisplayer
+	org.knopflerfish.bundle.desktop.swing.WiringHTMLDisplayer
+	org.knopflerfish.bundle.desktop.swing.SCRHTMLDisplayer
+	org.knopflerfish.bundle.desktop.swing.LogDisplayer
+	org.knopflerfish.bundle.desktop.swing.EventDisplayer
+	org.knopflerfish.bundle.desktop.swing.PrefsDisplayer
+    </td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.desktop.displays.extra</td>
+    <td>
+
+	A white-space separated list of additional built in desktop
+	displays to instantiate on startup. Each item in the list is
+	the full class name of a displayer. Use this property when you
+	want to start all the default built in displayers and some
+	extra dislayer. This way you only need to specify the
+	additional displayer and not all of them.
+
+	<p>E.g.,
+<pre>
+	org.knopflerfish.bundle.desktop.swing.PackageHTMLDisplayer
+	org.knopflerfish.bundle.desktop.swing.SpinDisplayer
+</pre>
+	</p>
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.desktop.display.main</td>
+    <td>
+
+	The name of the default bundle displayer to show in the
+	desktop's main frame when starting.
+
+    </td>
+    <td>String</td>
+    <td>Large Icons</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.bundle.desktop.event.EventTableModel.capacity</td>
+    <td>
+
+	The maximum number of events to keep in memory in one event
+	view. Use a negative value (i.e., a value smaller than 1) to
+	indicate that old event shall never be removed.
+
+    </td>
+    <td>int</td>
+    <td>342</td>
+  </tr>
+
+</table>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=desktop/desktop-5.0.1.html">desktop-5.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a></td><td align="center">1.6.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td><td align="center">2.1.2</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td><td align="center">2.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/workerthread/package-summary.html">org.knopflerfish.util.workerthread</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td><td align="center">1.5.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td><td align="center">1.2.1</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td><td align="center">1.1.1</td><td><a target="_top" href="../../jars/index.html?bundle=desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/device/index.html b/docs/bundledoc/device/index.html
new file mode 100644
index 0000000..8524d50
--- /dev/null
+++ b/docs/bundledoc/device/index.html
@@ -0,0 +1,90 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - device, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: device
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      
+
+<h1 class="man">Device Manager</h1>
+
+<div class="abstract">
+  The Device Manager bundle implements the 
+  <a  target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">
+    OSGi Device Access Model. 
+  </a>
+</div>
+
+<h2 class="man">Description</h2>
+<p>
+  The Device Manager matches and attaches drivers to devices. With the
+  help of one or more DriverLocator services it can dynamically
+  install and start drivers on demand. 
+</p>
+<p>
+  These concepts are used in the Device Manager documentation.
+  <dl class="kf">
+    <dt>Device</dt>
+    <dd>A service that mirrors a physical device. </dd>
+    <dt>Idle Device</dt>
+    <dd>A Device that no Driver service is attached to. </dd>
+    <dt>Device Manager</dt>
+    <dd>A framework component that looks for registration and
+      unregistration of devices and finds a driver for a device.  
+    </dd>
+    <dt>Driver</dt>
+    <dd>Is called by the Device Manager to check for matches and carry
+      out attachment. 
+      </dd>
+    <dt>Driver Locator</dt>
+    <dd>A service that downloads suitable drivers. </dd>
+    <dt>Driver Selector</dt>
+    <dd>A service to break ties in case multiple drivers return the same (best) match value. </dd>
+  </dl>
+</p>
+<h2 class="man">Device Access Model</h2>
+<p>
+  The device access model is a part of the OSGi service platform
+  specification. It splits responsibilities for device
+  management into several parts. The device manager is the motor in
+  this process and it is supplied with the framework. There must never
+  be more than one device manager installed. 
+</p>
+<p>
+  Knopflerfish includes a basic driver locator bundle,
+  basicdriverlocator. 
+</p>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=device/device_all-4.0.1.html">device_all-4.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=device/device_api-4.0.1.html">device_api-4.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=device/device-4.0.1.html">device-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=device/device_all-4.0.1.html">device_all-4.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=device/device_api-4.0.1.html">device_api-4.0.1</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/dirdeployer/dirdeployer.xml b/docs/bundledoc/dirdeployer/dirdeployer.xml
new file mode 100644
index 0000000..6b5c08b
--- /dev/null
+++ b/docs/bundledoc/dirdeployer/dirdeployer.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE cm_data PUBLIC '-//Gatespace//DTD cm_data 0.1//EN' 'cm_data.dtd'>
+<cm_data version="0.1">
+  <configuration pid="org.knopflerfish.fileinstall" mode="new">
+    <property name="org.knopflerfish.fileinstall.dir">
+      <vector length="1">
+	<value type="String">./load</value>
+      </vector>
+    </property>
+    <property name="service.pid">
+      <value type="String">org.knopflerfish.fileinstall</value>
+    </property>
+    <property name="org.knopflerfish.fileinstall.uninstallOnStop">
+      <value type="Boolean">true</value>
+    </property>
+    <property name="org.knopflerfish.fileinstall.poll">
+      <value type="Long">1000</value>
+    </property>
+    <property name="org.knopflerfish.fileinstall.use.initial.startlevel">
+      <value type="Boolean">false</value>
+    </property>
+    <property name="org.knopflerfish.fileinstall.startlevel">
+      <value type="Integer">8</value>
+    </property>
+  </configuration>
+</cm_data>
diff --git a/docs/bundledoc/dirdeployer/index.html b/docs/bundledoc/dirdeployer/index.html
new file mode 100644
index 0000000..6aaab7d
--- /dev/null
+++ b/docs/bundledoc/dirdeployer/index.html
@@ -0,0 +1,276 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - dirdeployer, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: dirdeployer
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">Directory Deployer</h1>
+
+<p>
+A bundle which scans file system directories for files that it can
+install, update or uninstall. The directory deployer bundle handles
+both bundle files and configuration files.  When a file is updated the
+bundle / configuration will be updated and when a file is removed from
+the scanned directory the bundle / configuration will be removed.
+</p>
+
+<p>
+This is a quite useful tool for handle bundle and configuration
+deployment without using any console. Just copy the file that should
+be installed to the deploy directory, and the directory deployer will
+find and activate them. When the files are removed, they are
+uninstalled.
+</p>
+
+
+<h2 class="man">Deploy method</h2>
+
+<p>The procedure for scanning and deploying is as follows:
+
+<ol>
+  <li>
+      Check if any new files have appeared or if any already deployed
+      files has been replaced with newer files.
+  </li>
+
+  <li>
+      New files are installed into the framework.<br> At the end of
+      the scan any bundle that was installed will be started according
+      to its activation policy. Any fragment that was installed will
+      be attached to its host (be resolving it).
+  </li>
+
+  <li>
+      Updated files (newer than a previously deployed bundle) are not
+      installed again, instead, the installed bundle or configuration
+      is updated from the new file.
+  </li>
+
+  <li>
+      Check if there are bundles or configurations installed by the
+      directory deployer that does not correspond to a file found
+      during the directory scan. If any such bundle or configuration
+      is found uninstall it.
+  </li>
+
+  <li>
+      If any bundle update was performed during the scan, perform a
+      refresh bundles operation for them using the in the framework
+      wiring API.
+  </li>
+
+  <li>
+      Start newly installed bundles that can be started, resolve newly
+      installed fragments. Note that there will only be one start /
+      resolve attempt made for each bundle after an install or update.
+  </li>
+
+  <li>
+      Sleep a while
+  </li>
+
+  <li>
+      Repeat from 1.
+  </li>
+
+</ol>
+
+<h2 class="man">Deployable File Types</h2>
+
+The Directory Deployer supports deploying of bundles and configurations:
+
+<ul>
+
+  <li><b><tt>*.jar</tt></b> Bundle jar files.
+
+  <li><b><tt>*.xml</tt></b> OSGi CM configurations stored in XML-files
+      using the DTD <a href="../cm/cm_data.dtd">cm_data.dtd</a>.
+
+</ul>
+      
+<p>
+
+  A sample XML-file with a configuration for the Directory Deployer
+  bundle itself can be <a href="dirdeployer.xml">downloaded here</a>.
+
+</p>
+<p>
+
+  To create a CM configuration from scratch one may use the CM-tab in
+  Knopflerfish desktop, it presents a simple GUI based on
+  configuration meta type descriptions provided by configurable
+  bundles. The CM-tab is not visible in the Desktop when starting with
+  the default set of bundles, to activate it one must install and
+  start three more bundles from the Knopflerfish distribution:
+  <tt>metatype</tt> (OSGi Metatyp APIs), <tt>kf_metatype_all</tt>
+  (Knopflerfish Metatyp Service implementation) and
+  <tt>cm_desktop</tt> (the CM-tab desktop plug in itself).
+
+</p>
+<p>
+
+  To save an existing CM configuration as cm_data XML one may use the
+  CM-tab in the Knopflerfish desktop, it provides an
+  <tt>Export...</tt> button that will export the current configuration
+  as a cm_data XML file. It is also possible to use the Knopflerfish
+  console command <tt>configuration export</tt>. See <a
+  href="../cm_cmd/index.html">CM Commands</a> for details.  Avoid
+  writing cm_data XML files by hand since the parser for the
+  <tt>cm_data</tt> XML documents is written for machine generated
+  documents so it does not give usable error messages when something
+  in the XML-document is wrong.
+
+</p>
+
+
+
+<h2 class="man">Configuration</h2>
+
+<p>
+
+  See <a
+  href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/resources/OSGI-INF/metatype/metatype.xml">metatype.xml</a>
+  for specification using CM. The same properties as defined by CM are
+  also read as default values from framework properties. Thus, the
+  bundle can be both configured by CM and using system properties.
+
+</p>
+<p>
+
+  You can set the deployment directory in <tt>metatype.xml</tt> in the
+  bundle's resource directory (defaults to <tt>./load</tt>). A
+  relative deployment directory path is relative to the directory from
+  which the framework is started.
+
+</p>
+<p>
+
+  The table below describes the framework properties that may be used
+  to set the default values for the directory deployer configuration.
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Type</th>
+    <th>Default</th>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.fileinstall.dir</td>
+    <td>
+
+	Set the directories that should be scanned.
+
+	<p>The value should be a comma-separated list of directory
+	paths.</p>
+
+    </td>
+    <td>String</td>
+    <td>./load</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.fileinstall.poll</td>
+    <td>
+
+	Poll interval in milliseconds between directory scans. Must be
+	at least 100 ms. 
+
+    </td>
+    <td>long</td>
+    <td>1000</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.fileinstall.use.initial.startlevel</td>
+    <td>
+
+	<p>
+
+        When this property is true the Directory Deployer will not set
+	any start level for bundles it installs thus those bundles
+	will belong to the default start level (i.e., the current
+	initial start level according to the Framework Start Level
+	API).
+
+	</p><p>
+
+	When this property is false the Directory Deployer will assign
+	the start level given by
+	<tt>org.knopflerfish.fileinstall.startlevel</tt> to the
+	bundles it installs.
+
+	</p>
+
+    </td>
+    <td>boolean</td>
+    <td>true</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.fileinstall.startlevel</td>
+    <td>
+
+	Bundle start level to assign to all newly installed
+	bundles. Note that you must set
+	<tt>org.knopflerfish.fileinstall.startlevel</tt> to false for
+	this property to have an effect.
+
+    </td>
+    <td>int</td>
+    <td>
+
+      The initial bundle start level as returned by the
+      StartLevel-API.
+
+    </td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.fileinstall.uninstallOnStop</td>
+    <td>
+
+	If <code>true</code> then the directory deployer will
+        uninstall all bundles and configurations that it has installed
+        when it stops.
+
+    </td>
+    <td>boolean</td>
+    <td>true</td>
+  </tr>
+</table>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/event/index.html b/docs/bundledoc/event/index.html
new file mode 100644
index 0000000..e0ecaf8
--- /dev/null
+++ b/docs/bundledoc/event/index.html
@@ -0,0 +1,126 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - event, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: event
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">The Knopflerfish Event Admin Service</h1>
+
+<div class="abstract">
+  The Knopflerfish OSGi Event Admin Service is an implementation of
+  the Event Admin Service specified in the OSGi compendium
+  specification.
+</div>
+
+
+<h2 class="man">Description</h2>
+<p>
+  The Knopflerfish OSGi Event Admin Service is an implementation of
+  the Event Admin Service in the OSGi Service Compendium that provides
+  parallel delivery of events posted by different threads.
+</p>
+
+
+<h2 class="man">Configuration properties</h2>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Type</th>
+    <th>Default</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.eventadmin.timeout</td>
+    <td>
+
+	The timeout in milliseconds to apply to calls to the
+	<code>handleEvent(Event)</code> of individual event handlers.
+	The value <code>0</code> means no timeout.
+
+    </td>
+    <td>long ≥ 0</td>
+    <td>0</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.eventadmin.timewarning</td>
+    <td>
+
+	When set to a value <code>> 0</code> then measure the time
+	of each call to the <code>handleEvent(Event)</code> of event
+	handlers. If the call lasts longer than the value of this
+	property then log this event handler delivery call and its
+	duration in the OSGi log using a log entry with severity ERROR.
+
+	<p>Time warnings are only supported when the event handler
+	call timeout described above is unset (i.e., set to 0).</p>
+
+    </td>
+    <td>long ≥ 0</td>
+    <td>0</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.eventadmin.queuehandler.multiple</td>
+    <td>
+
+	If multiple event delivery queues should be used or not.  If set
+	to <code>true</code> each thread calling the
+	<code>EventAdmin.postEvent()</code>-method will be assigned
+	its own queue for delivering its events.
+
+    </td>
+    <td>boolean</td>
+    <td>true</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.eventadmin.queuehandler.timeout</td>
+    <td>
+
+	The timeout (milliseconds) before an event delivering queue
+	that has nothing to do is disposed.  That is if there has been
+	no events for the queue to deliver for more than this number
+	of milliseconds then the queue will be terminated. If the
+	thread posts another event later on a new delivery queue
+	instance will be created.
+
+	<p>This timeout is only in use when multiple even delivery
+	queues are enabled.</p>
+
+    </td>
+    <td>long ≥ 0</td>
+    <td>1100</td>
+  </tr>
+</table>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=event/event_all-4.0.1.html">event_all-4.0.1</a><br>
+<a target="_top" href="../../jars/index.html?bundle=event/event_api-4.0.1.html">event_api-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=event/event_all-4.0.1.html">event_all-4.0.1</a>, <a target="_top" href="../../jars/index.html?bundle=event/event_api-4.0.1.html">event_api-4.0.1</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/framework/index.html b/docs/bundledoc/framework/index.html
new file mode 100644
index 0000000..a7e8b82
--- /dev/null
+++ b/docs/bundledoc/framework/index.html
@@ -0,0 +1,1227 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Knopflerfish Framework Documentation version 7.1.2</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Knopflerfish Framework
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 7.1.2
+      </div>
+      <h1 class="man">Knopflerfish OSGi framework</h1>
+
+<div class="abstract">
+  This is the Knopflerfish framework. An OSGi Release 5
+  compliant framework. It supports all optional and deprecated
+  framework services, Package Admin, Start Level,
+  Conditional Permission Admin, Permission Admin, URL Handlers,
+  Bundle Hook, Resolver Hook, Service Hook and Weaving Hook.
+</div>
+
+<h2 class="man">Contents</h2>
+  <ol>
+    <li><a href="#startup">Knopflerfish framework.jar startup</a></li>
+    <li><a href="#init_restart">Initial start vs restart</a></li>
+    <li><a href="#framework">Starting the framework</a></li>
+    <li><a href="#framework_compact">Starting the compact framework</a></li>
+    <li><a href="#xargs">Default selection of .xargs</a></li>
+    <li><a href="#proxy">Using a HTTP proxy</a></li>
+    <li><a href="#props">Framework and System Properties</a></li>
+    <li><a href="#osgiprop">OSGi Specified Framework Properties</a></li>
+    <li><a href="#kfsysprop">Knopflerfish Specified System Properties</a></li>
+    <li><a href="#kffwprop">Knopflerfish Specified Framework Properties</a></li>
+  </ol>
+<a name="startup"></a>
+<h2 class="man">Knopflerfish framework.jar startup</h2>
+<p>
+This is a startup guide for the KF OSGi framework. Note that
+command-line startup of the framework is not specified by OSGi, and
+system integrators often need to create a wrapper script for FW
+startup.
+</p>
+<p>
+The KF Main startup class is primarily intended to be used in scenarios
+where current working directory is same as the one containing framework.jar,
+the framework storage directory and configuration files. In these cases
+</p>
+<p>
+<pre class="shell">java -jar framework.jar</pre>
+</p>
+<p>
+...is often enough. 
+</p>
+<p>
+To use features that requires JVM restart, e.g. extension bundles, 
+you can use our example shell start script "kf2". Open a terminal and type
+</p>
+<p>
+<pre class="shell">./kf2</pre>
+</p>
+<p>
+Note: the script requires a "sh" shell. 
+</p>
+<p>
+Other uses are possible, but require options and possibly some tweaking
+of the default startup files.
+</p>
+
+<a name="init_restart"></a>
+<h2 class="man">Initial start vs restart</h2>
+<p>
+Two cases of framework startup should be noted:
+</p>
+<ol>
+  <li>Initial, bootstrap, startup<br/>
+    An initial startup must contain enough options
+    to install bundles allowing further management, using 
+    -install options. If no bundles are installed, an empty 
+    framework will be started but nothing can be done with it..
+  </li>
+  <li>Restart of previously initialized framework<br/>
+    Any OSGi framework can remember its state from previous startup.
+    <br/>
+    In this case, startup options should only contains system properties
+    and a -launch option for restarting the bundles, but not any
+    -install options.
+  </li>
+ </ol>
+<p>
+ NB! Framework properties (-Fx=y) supplied at initial startup are saved as
+ part of the framework state, and need not to be supplied again at framework
+ restart. System properties (-Da=b) are not included in the framework state.
+ Since the two different startup cases probably will use separate startup
+ files, care must be taken so system properties are set correctly in both
+ files, when so required.
+</p>
+
+<p>
+</p>
+<p>
+It is up to a system integrator to decide when to use initial startup
+or restart. The Main KF class can help somewhat in doing this (see below)
+but might not be enough. In those cases, wrapper scripts, or modifications
+to Main.java are recommended.
+</p>
+
+<a name="framework"></a>
+<h2 class="man">Starting the framework</h2>
+<p>
+The framework can be started using the startup wrapper class
+</p>
+<p>
+<pre class="shell">org.knopflerfish.framework.Main</pre>
+</p>
+<p>
+This class is also set a Main-Class in framework.jar's manifest, meaning 
+framework.jar can be started using 
+</p>
+<p>
+<pre class="shell"> java -jar framework.jar [options] OR ./kf2 [options]</pre>
+</p>
+<p>
+The Main class supports a number of options, which can be displayed
+using:
+</p>
+<p>
+<pre class="shell">java -jar framework.jar -help OR ./kf2 -help</pre>
+</p>
+<p>
+Options can also be specified using the -xargs option, which specifies
+a .xargs text file containing lines of new options. Typically all
+options are specified in .xargs files. Combining .xargs files and
+command line options is possible. .xargs files can also use recursive
+.xargs files.
+</p>
+<p>
+When the framework is started, it uses a file system directory for
+storing the state of all installed bundles, "fwdir". The default
+directory used for this is:
+</p>
+<p>
+<pre class="shell">fwdir</pre>
+</p>
+<p>
+in the current directory. The "fwdir" directory can also be set
+specifically using the org.osgi.framework.storage property. Note that
+moving "fwdir" also changes the location for searching for default
+.xargs files.
+</p>
+<p>
+If no options are specified (any "-Fx=y", "-Da=b" or "-init" does not
+count as options in this case) an implicit
+</p>
+<p>
+<pre class="shell">-xargs "default"</pre>
+</p>
+<p>
+is added to the options. "default" means that the default .xargs (see
+below) is selected.
+</p>
+
+<a name="framework_compact"></a>
+<h2 class="man">Starting the compact framework</h2>
+<p>
+There is a compact version of the framework available for system that
+has limited amount of resources (memory and storage). This version
+doesn't contain any support for security and certificates. The internal
+classes has also been name mangled to save resources.
+</p>
+<p>
+The compact framework is started and controlled in the same way as the
+full version. The only difference is that the jar file is called
+<code>framework_compact.jar</code>.
+</p>
+
+<a name="xargs"></a>
+<h2 class="man">Default selection of .xargs</h2>
+<p>
+If _no_ args are supplied (arguments of the form "-Fx=y", "-Da=b" or
+"-init" does not count in this case), or a name of "default" is given
+as -xargs argument, a default .xargs file will be searched for, by the
+following algorithm:
+</p>
+<ol>
+  <li>If there exists a previous "fwdir" AND previous options
+      does not contain "-init", use a file in "fwdir" named:<br/>
+    <pre class="shell">fwprops.xargs</pre>
+  </li>
+  <li>If no fwdir exist, OR options contain an "-init", 
+       search for a file named:
+    <ol style="list-style-type:lower-latin">
+      <li>init_[osname].xargs</li>
+      <li>init.xargs</li>
+      <li>remote-init.xargs</li>
+    </ol>
+    The search is performed in the following directories:
+    <ol style="list-style-type:lower-latin">
+      <li>fwdir</li>
+      <li>The parent directory of fwdir (if any)</li>
+      <li>The current working directory</li>
+    </ol>
+    First match wins.<br/>
+    The [osname]-part of the file name is the unified OS name as
+    specified in Alias.java (see below). Case is important if the file
+    system is case sensitive.<br/>
+    OS aliases:
+    <ul>
+      <li>OS2</li>
+      <li>QNX</li>
+      <li>Windows95</li>
+      <li>Windows98</li>
+      <li>WindowsNT</li>
+      <li>WindowsCE</li>
+      <li>Windows2000</li>
+      <li>WindowsXP</li>
+    </ul>
+  </li>
+</ol>
+<p>
+The file fwdir/fwprops.xargs contains saved properties that is used
+when restarting a framework instance. It is written by the Knopflerfish
+framework on every startup (unless disabled by setting the property
+"org.knopflerfish.framework.write.restart.xargs" to false).
+</p>
+
+<a name="proxy"></a>
+<h2 class="man">Using a HTTP proxy</h2>
+<p>
+The standard JVM system properties
+</p>
+<ul>
+ <li>http.proxyHost</li>
+ <li>http.proxyPort</li>
+ <li>http.nonProxyHosts</li> 
+</ul>
+<p>
+should be used to set proxy information. This will be global to 
+all HTTP request from all bundles and the framework.
+</p>
+<p>
+Additionally, the KF-specific system property
+</p>
+<ul>
+ <li>http.proxyAuth</li>
+</ul>
+<p>
+can be set to a value on the form user:password
+</p>
+<p>
+If set to non-empty, this will add the 
+Proxy-Authorization header to bundle install http/https requests 
+made from the framework, However, bundles using the URL class internally
+must explicitly set this header themselves.
+</p>
+
+<a name="props"></a>
+<h2 class="man">Framework and System Properties</h2>
+<p>
+Both Framework and Java System properties are used to control the framework.
+</p>
+<p>
+Framework properties are the standard properties listed in the OSGi
+specification (section 4.5.3 in r4.core) and proprietary properties for
+the Knopflerfish framework. Framework properties are also used for
+configuration of Knopflerfish bundles. 
+</p>
+<p>
+Framework properties are specified on the command line or in .xarg files
+using "-F". If you have more than one framework instance, each instance
+has its own set of Framework properties.
+</p>
+<p>
+A framework property is accessed by using
+<pre class="shell">org.osgi.framework.BundleContext.getProperty(String)</pre>.
+</p>
+<p>
+Java System properties are specified on the command line or in .xargs
+files using "-D". System properties are accessed using
+<pre class="shell">java.lang.System.getProperty(String)</pre> but
+<pre class="shell">BundleContext.getProperty</pre> can also be used as it will look
+for a System property if there is no matching Framework property.
+</p>
+<p>
+Because of the different handling of Framework and System properties when
+the framework is <a href="#init_restart">restarted</a>, it is recommended
+to use only Framework properties in .xargs files. If you do, and use the
+default init.xargs/props.xargs files, initial starts and restarts become
+conveniently short on the command line:
+</p>
+<p>
+<pre class="shell">java -jar framework.jar -init  </pre> (initial start)
+</p>
+<p>
+<pre class="shell">java -jar framework.jar  </pre> (restart)
+</p>
+<p>
+Unfortunately, it is not always possible to avoid using Java System
+properties. For example, a bundle may include a class library that uses
+System properties for configuration. Also, properties that are read
+during start-up, before the framework has been initialized, need to be
+System properties, see <a href="#kfsysprop">KF System Properties</a>.
+</p>
+<a name="osgiprop"></a>
+<h2 class="man">OSGi Specified Framework Properties</h2>
+<p>
+OSGi Framework properties should be specified using "-F".
+</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.bootdelegation</td>
+    <td>
+      Set the boot delegation mask. A list of packages delegated from the
+      framework to the parent classloader. The package specified can contain
+      a wildcard at the end, which matches any sub-packages.
+    </td>
+    <td>String , ...</td>
+    <td></td>
+  </tr>
+  <tr>
+	<td>org.osgi.framework.bsnversion</td>
+	<td>
+	  Allow installation of multiple bundles with the same bundle symbolic
+	  name or restrict this. The property can have the following values:
+      <table class="man_inner">
+      <tr>
+	    <td class="man_inner"><b>single</b></td>
+        <td class="man_inner">
+          A combination of equal bundle symbolic name and equal version is
+          unique in the framework. Installing a second bundle with the same
+          bundle symbolic name and version is an error.
+        </td>
+      </tr>
+      <tr>
+        <td class="man_inner"><b>multiple</b></td>
+        <td class="man_inner">
+          The combination of bundle symbolic name and version is not unique
+          in the framework.
+        </td>
+      </tr>
+      <tr>
+	    <td class="man_inner"><b>managed</b></td>
+        <td class="man_inner">
+          Using a Bundle Collision Hook to filter any non-colliding bundles.
+        </td>
+      </tr>
+      </table>
+	</td>
+    <td>String</td>
+    <td>managed</td>	
+  <tr>
+    <td>org.osgi.framework.bundle.parent</td>
+    <td>
+      This property is used to specify what class loader is used for 
+      boot delegation. That is, java.* and the packages specified on 
+      the org.osgi.framework.bootdelegation.
+      This property can have the following values: boot, app, ext or
+      framework.
+    </td>
+    <td>String</td>
+    <td>boot</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.command.execpermission</td>
+    <td>
+      Specifies an optional OS specific command to set file permissions
+      on a bundle's native code. This is required on some operating
+      systems to use native libraries. For example, on a UNIX 
+      style OS you could have the following value: 
+      org.osgi.framework.command.execpermission="chmod +rx ${abspath}" 
+      The ${abspath} macro will be substituted for the actual file 
+      path. 
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.executionenvironment</td>
+    <td>
+      The current execution environment. There are no restriction on
+      the execution environment if this property isn't set.
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.language</td>
+    <td>
+      The language used by the framework for the selection of 
+      native code.
+    </td>
+    <td>String</td>
+    <td>Set based on default locale</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.library.extensions</td>
+    <td>
+      A comma separated list of additional library file extensions that
+      must be used when searching for native code. If not set, then only
+      the library name returned by System.mapLibraryName(String) will be
+      used. This list of extensions is needed for certain operating
+      systems which allow more than one extension for native libraries.
+      For example, the AIX operating system allows library extensions of
+      .a and .so, but System.mapLibraryName(String) will only return
+      names with the .a extension.
+    </td>
+    <td>String , ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.os.name</td>
+    <td>
+      The name of the operating system as used in the native code clause.
+    </td>
+    <td>String</td>
+    <td>Set based on system property os.name</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.os.version</td>
+    <td>
+      The version of the operating system as used in the native code 
+      clause.
+    </td>
+    <td>String</td>
+    <td>Set based on system property os.version</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.os.processor</td>
+    <td>
+      The name of the processor as used in the native code clause.
+    </td>
+    <td></td>
+    <td>Set based on system property os.arch</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.security</td>
+    <td>
+      Specifies the type of security manager the framework must 
+      use. If not specified then the framework will not set the VM 
+      security manager. The following type is architected: 
+      <code>osgi</code> Enables a security manager that supports all 
+      security aspects of the OSGi Release 4 specifications 
+      (including postponed conditions). 
+      If specified, and there is a security manager that doesn't
+      match already installed, then a SecurityException is thrown
+      when the Framework is initialized. 
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.startlevel.beginning</td>
+    <td>
+      Specifies the beginning start level of the framework.
+    </td>
+    <td>Integer</td>
+    <td>1</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.storage</td>
+    <td>
+      Where we store persistent data.
+
+      On systems not supporting a current working directory,
+      as Pocket PC, this path should be set to an explicit
+      full path.
+
+      Note: Knopflerfish 1.x and 2.x used the name
+      "org.osgi.framework.dir" for this property.
+    </td>
+    <td>String</td>
+    <td>${currentWorkingDirectory}/fwdir</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.storage.clean</td>
+    <td>
+      Specifies if and when the storage area for the framework 
+      should be cleaned. If no value is specified, the framework storage
+      area will not be cleaned. The possible values is: 
+      <code>onFirstInit</code> - The framework storage area will be
+      cleaned  before the Framework bundle is initialized for the first 
+      time. Subsequent inits, starts or updates of the Framework bundle
+      will not result in cleaning the framework storage area.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.system.packages</td>
+    <td>
+      Complete list of packages exported by the system bundle.
+
+      If not set the framework will export all OSGi packages and all
+      standard Java packages according to the version of the running
+      JRE. See also "org.knopflerfish.framework.system.packages.base"
+      and "org.osgi.framework.system.packages.extra"
+    </td>
+    <td>String , ...</td>
+    <td>Default is based on other properties</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.system.packages.extra</td>
+    <td>
+      Packages to add to the default list of packages exported by the
+      system bundle.
+    </td>
+    <td>String , ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.trust.repositories</td>
+    <td>
+      This property is used to configure trust repositories for the 
+      framework. The value is path of files.The file paths are separated
+      by the pathSeparator defined in the File class. Each file path
+      should point to a JKS key store. The framework will use the key
+      stores as trust repositories to authenticate certificates of
+      trusted signers. The key stores must only be used as read-only
+      trust repositories to access public keys. The keystore must not
+      have a password.
+    </td>
+    <td>String : ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.windowsystem</td>
+    <td>
+      Provide the name of the current window system. This can be used by
+      the native code clause.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+</table>
+
+
+<a name="kfsysprop"></a>
+<h2 class="man">Knopflerfish Specified System Properties</h2>
+<p>
+Knopflerfish System properties should be specified using "-D".
+</p>
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.verbosity</td>
+    <td>
+     Verbosity level of the Main class starting the framework. 0 means
+     few messages. Specify on the command line in order to see messages
+     from the very beginning.
+    </td>
+    <td>Integer</td>
+    <td>0</td>
+  </tr>
+</table>
+
+<a name="kffwprop"></a>
+<h2 class="man">Knopflerfish Specified Framework Properties</h2>
+<p>
+The recommendation is to use "-F" for Knopflerfish Framework properties
+but "-D" should also work. 
+</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.all_signed</td>
+    <td>
+      If set to true, we require that all bundles that are installed are signed.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.automanifest</td>
+    <td>
+      Flag to enable automatic manifest generation. If true, bundle
+      manifest can be modified by a special configuration file. See
+      javadoc for org.knopflerfish.framework.AutoManifest class 
+      for details.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.automanifest.config</td>
+    <td>
+      Configuration URL for automatic manifest generation. Only
+      valid if org.knopflerfish.framework.automanifest=true.
+      An URL starting with "!!" followed by path is refer to a resource
+      on the classloader that have loaded the framework.
+    </td>
+    <td>String</td>
+    <td>!!/automanifest.props</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage</td>
+    <td>
+      Storage implementation for bundles
+      [file, memory]
+    </td>
+    <td>String</td>
+    <td>file</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.always_unpack</td>
+    <td>
+     When using file bundle storage, bundle jars can be unpacked
+     or copied as-is. Unpacking leads to faster restart and class loading
+     but takes longer for initial startup.
+
+     If set to true, unpack all bundle jars.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.jar_verifier_bug</td>
+    <td>
+     There is a bug when using file bundle storage, certificate and Oracle
+     JRE (Java 6). This bug causes the JarInputStream to miss picking up
+     certificates for files under the "META-INF" directory if they directly
+     follow the META-INF signature related files. This causes KF to mark
+     the bundle as not completly signed. To ignore problem set property
+     to true.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <a name="fileref"></a>
+    <td>org.knopflerfish.framework.bundlestorage.file.reference</td>
+    <td>
+     When using file bundle storage, file: URLs can optionally
+     be referenced only, not copied to the persistent area.
+
+     If set to true, file: URLs are referenced only.
+
+     Note: Individual bundles can be reference installed
+           by using URLs of the syntax:
+
+           reference:file:<path>
+
+           This works even if the global reference flag
+           is not enabled.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.trusted</td>
+    <td>
+     Are the bundles stored in the file bundle storage to be trusted, if not
+     signed bundles will be checked every time they are read.
+     Untrusted storage leads to slower restart and class loading.
+
+     If set to true, trust bundles in bundle storage.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.unpack</td>
+    <td>
+     Most JVM requires that we unpack the bundle to access internal jars
+     and native code. Setting this to true will unpack the jar if it contains
+     internal jars or native code.
+
+     If set to true, unpack needed bundle jars.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlethread.timeout</td>
+    <td>
+     Use this proprty to set a limit on how long the framework will wait for a
+     bundle's activator to complete and return from the start and stop methods.
+     If the time-out occurs, the framework will interrupt the BundleThread that
+     is executing the start or stop method and then optionally stop it or lower
+     its priority, see property org.knopflerfish.framework.bundlethread.abort.
+     A BundleException is thrown to indicate that start/stop of the bundle
+     failed.
+
+     If set to a positive integer, the value is used as time-out in seconds.
+     If set to 0, no time out is used and the framework will wait indefinitely
+     for the activator's start and stop methods to complete.
+    </td>
+    <td>Integer</td>
+    <td>0</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlethread.abort</td>
+    <td>
+      If a bundle's start or stop method time-out (see property
+      org.knopflerfish.framework.bundlethread.timeout) or if the bundle gets
+      uninstalled before the method has returned, this property defines how to
+      manage the bundle's start/stop thread. Possible values are:
+      <table class="man_inner">
+	<tr>
+	  <td class="man_inner">"stop"</td>
+	  <td class="man_inner">Calls the stop() method of the bundle's thread</td>
+	</tr>
+	<tr>
+	  <td>"minprio"</td>
+	  <td>Sets a minium priority of the bundle's thred</td>
+	</tr>
+	<tr>
+	  <td>"ignore"</td>
+	  <td>Do nothing</td>
+	</tr>
+      </table>
+    </td>
+    <td>String</td>
+    <td>ignore</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.automanifest</td>
+    <td>
+      Print debug output for automatic manifest actions.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.bundle_resource</td>
+    <td>
+     When security is enabled, print information about resource
+     lookups that are rejected due to missing permissions for the
+     calling bundle.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.certficates</td>
+    <td>
+     Print debug information about certificate handling.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.classloader</td>
+    <td>
+     Print debug information from classloader
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.errors</td>
+    <td>
+     Print all FrameworkEvents of type ERROR
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.framework</td>
+    <td>
+     Print debug information about life-cycle events for the
+     current framework instance.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.hooks</td>
+    <td>
+     Print debug information about when service hooks are used
+     current framework instance.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.ldap</td>
+    <td>
+     Print debug information about LDAP filters
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.resolver</td>
+    <td>
+     Print debug information about resolver operation.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.patch</td>
+    <td>
+     Print debug information about class patching
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.permissions</td>
+    <td>
+     Print debug information about permission evaluation.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.print_with_do_privileged</td>
+    <td>
+     Surround all debug print-operations originating from
+     setting org.knopflerfish.debug.* properties with a
+     doPrivileged() wrapper.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.startlevel</td>
+    <td>
+     Print debug information about startlevel service
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.service_reference</td>
+    <td>
+     When security is enabled, print information about service
+     reference lookups that are rejected due to missing permissions
+     for calling bundle.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.url</td>
+    <td>
+      Print debug information about URL services
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.is_doublechecked_locking_safe</td>
+    <td>
+     Is it safe to use double-checked locking or not.
+     It is safe if JSR 133 is included in the running JRE. I.e., for
+     Java SE if version is 1.5 or higher.
+    </td>
+    <td>Boolean</td>
+    <td>
+      True if value of the system property java.version ≥ 1.5,
+      False otherwise
+    </td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.ldap.nocache</td>
+    <td>
+     Disable LDAP caching for simple filters. LDAP caching
+     speeds up framework filters considerably, but uses
+     more memory.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.class.activation</td>
+    <td>
+      A comma-separated list of locations of bundles whose Main-Class
+      (set in manifest) should be used as activator if no
+      BundleActivator is specified. 
+      The Main-Class will be used as activator if and only if the jar
+      file does not specify a Bundle-Activator header and the bundle's
+      location(see Bundle.getLocation) is found in the comma-separated
+      list (case-sensitive). 
+<pre class="man">
+> java -jar framework.jar
+    -Forg.knopflerfish.framework.main.class.activation=\ 
+    file:/foo/bar.jar,http://foo.com/bar.jar ...
+</pre>
+      </pre>
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.verbosity</td>
+    <td>
+     Verbosity level of the Main class starting the framework. 0 means
+     few messages. Specify as a System property on the command line
+     in order to see messages from the very beginning.
+    </td>
+    <td>Integer</td>
+    <td>0</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.xargs.writesysprops</td>
+    <td>
+      Properties defined using -Fname=value in xargs-files are available
+      for bundles using BundleContext.getProperty(name).
+      This property controls weather such properties shall also be
+      exported as system properties or not.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.listener.n_threads</td>
+    <td>
+    Number of threads used to deliver events to asynchronous listeners.
+    If the value is 0 then we will revert to the old behaviour and call
+    all listeners synchronously.
+    </td>
+    <td>Integer</td>
+    <td>1</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch</td>
+    <td>
+      If true AND once the classpatcher_all-N.N.N.jar bundle is installed and started,
+      run time class patching will be enabled for all classes loaded afterwards. 
+
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch.configurl</td>
+    <td>
+     URL to class patch config file. Only used when class patching is enabled.
+     This is used as a fallback if a bundle does not specify a
+     Bundle-ClassPatcher-Config manifest header.
+
+     "!!" is used to read resources from the system class path
+     "!" can be used to read bundle resources.
+    </td>
+    <td>String</td>
+    <td>!!/patches.props</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch.dumpclasses</td>
+    <td>
+     If true and class patching is enabled, dump all modified classes
+     to a directory.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch.dumpclasses.dir</td>
+    <td>
+      If dumpclasses is enabled, specifies a directory where to dump
+      modified classes
+    </td>
+    <td>String</td>
+    <td>patchedclasses</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.readonly</td>
+    <td>
+      Controls if the framework should skip saving state changes
+      permantly under framework directory. This means that if we are
+      running with the default "file" bundle storage then new bundles
+      must be installed as a referenced file URL (see property
+      <a href="#fileref">org.knopflerfish.framework.bundlestorage.file.reference</a>).
+      This also implies that no data storage will be available to bundles.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.service.conditionalpermissionadmin</td>
+    <td>
+      Controls if the framework should register the Conditional Permission
+      Admin service.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.service.permissionadmin</td>
+    <td>
+      Controls if the framework should register the Permission
+      Admin service.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.strictbootclassloading</td>
+    <td>
+      If set to true, use strict rules for loading classes from the boot class loader.
+      If false, accept class loading from the boot class path from classes themselves
+      on the boot class, but which incorrectly assumes they may access all of the boot
+      classes on any class loader (such as the bundle class loader).
+      Setting this to true will, for example, result in broken serialization on the Sun 
+      JVM if bootdelegation does not exposes sun.* classes
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.system.packages.base</td>
+    <td>
+     An alternative to setting org.osgi.framework.system.packages.
+     When this property is used the list of packages given will be
+     appended with the default set of osgi-packages for the current
+     framework and then used as the exports of the system bundle.
+    </td>
+    <td>String , ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.system.packages.file</td>
+    <td>
+      File containing list of packages exported by the system bundle.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.system.packages.version</td>
+    <td>
+      Name for selected exporting profile of system packages.
+    </td>
+    <td>String</td>
+    <td>MAJOR.MINOR from system property "java.version"</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.usingwrapperscript</td>
+    <td>
+      If set to "true", KF will assume that it has been
+      started with the "kf2" shell script, and that it will be 
+      restarted if KF exits with exit code = 200. Required to be 
+      able to use new KF2 features such as extension bundles. 
+      This flag is set to "true" by the "kf2" shell script.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator</td>
+    <td>
+      A list of which certificate validators to use. Currently available are
+      JKSValidator and SelfSignedValidator. If no validator is to be used,
+      set to "null" or "none".
+    </td>
+    <td>String</td>
+    <td>JKSValidator if org.osgi.framework.trust.repositories Is set, otherwise none</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.date</td>
+    <td>
+      Date to use when validating certificates. The date is specifed
+      in the current locales short date format. If no date is specified
+      use the current date and time.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.jks.ca_certs</td>
+    <td>
+      File name of java keystore used by JKSValidator. Used if
+      org.osgi.framework.trust.repositories isn't set.
+    </td>
+    <td>String</td>
+    <td>$JAVA_HOME/lib/security/cacerts</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.jks.ca_certs_password</td>
+    <td>
+      Password to java keystore used by JKSValidator.
+    </td>
+    <td>String</td>
+    <td>changeit</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.jks.cert_provider</td>
+    <td>
+      Provider for CertificateFactory to use.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.write.fwprops.xargs</td>
+    <td>
+      Property that tells the Knopflerfish Main if it shall write a
+      fwprops.xargs file with all framework properties inside the
+      framework directory on startup or not.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.gosg.jars</td>
+    <td>
+     Semicolon separated list of base URLs for relative install commands
+    </td>
+    <td>URL;...</td>
+    <td>URLs to the "jars" folder and all its sub-folders and
+        fwresource:jars/</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.startlevel.compat</td>
+    <td>
+      Set to true indicates startlevel compatibility mode.
+      All bundles and current start level will be 1.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.startlevel.use</td>
+    <td>
+      Use the Start Level service. If start level is not used then
+      we do not create a non daemon thread that will keep a JVM
+      with only daemon threads alive.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.osgi.setcontextclassloader</td>
+    <td>
+     If set to "true", set the bundle startup thread's context class
+     loader to the bundle's class loader. This is useful for checking
+     if an external lib will work better with a wrapped startup. It
+     doesn't set the context classloader for event callbacks.
+
+     Note that setting the context classloader is not mandated
+     by OSGi, and might introduce dependencies on the KF framework,
+     so this flag should only be enabled for testing purposes.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.servicereference.valid.during.unregistering</td>
+    <td>
+      If set to false, then the service reference can not be used to
+      fetch an instance of the service during delivery and handling of
+      the UNREGISTERING service event. The behaviour specified in the
+      OSGi R4 v4.0.1 specification (and later), according to a
+      clarification done by CPEG February 2008, is that it shall be
+      possible to obtain a service instance during delivery of
+      UNREGISTERING events thus this property now defaults to true.
+
+      <p>Note that independent of this setting the service reference
+      of an UNREGISTERING service will not be returned by any of the
+      methods searching for service references provided by the
+      BundleContext interface.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.osgi.registerserviceurlhandler</td>
+    <td>
+      Flag for installing OSGi service based URL handlers. 
+      Since the URL handler can only be installed once, there
+      might be cased where some external entity (not OSGi)
+      sets this. In this case, the OSGi handler can be disabled
+      by setting 
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+</table>
+
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td><td align="center">1.7.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/hooks/bundle/package-summary.html">org.osgi.framework.hooks.bundle</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/hooks/resolver/package-summary.html">org.osgi.framework.hooks.resolver</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/hooks/service/package-summary.html">org.osgi.framework.hooks.service</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/hooks/weaving/package-summary.html">org.osgi.framework.hooks.weaving</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/launch/package-summary.html">org.osgi.framework.launch</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/condpermadmin/package-summary.html">org.osgi.service.condpermadmin</a></td><td align="center">1.1.1</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a></td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/permissionadmin/package-summary.html">org.osgi.service.permissionadmin</a></td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/startlevel/package-summary.html">org.osgi.service.startlevel</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/url/package-summary.html">org.osgi.service.url</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td><td align="center">1.5.1</td><td><a target="_top" href="../../jars/index.html?bundle=framework.html">framework</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/frameworkcommands/index.html b/docs/bundledoc/frameworkcommands/index.html
new file mode 100644
index 0000000..a30ee38
--- /dev/null
+++ b/docs/bundledoc/frameworkcommands/index.html
@@ -0,0 +1,86 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - frameworkcommands, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: frameworkcommands
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">Framework Commands</h1>
+<div class="abstract">
+  The Knopflerfish framework console bundle
+</div>
+
+<h2 class="man">Description</h2>
+
+The Framework commands bundle includes a rich set of commands through which the Knopflerfish framework can be controlled. This includes bundle management (install, start, stop etc), OSGi service information, to package and permission management.
+
+<h2 class="man">Framework Command Group</h2>
+The console command group is <b>framework</b>
+<p>
+The available commands are:
+<pre class="code">
+Available framework commands:
+  addpermission [-help] -b #bundle# | -d | -l #location# <type> [<name> [<actions>]] - Add permissions to bundle
+  bundlelevel [-help] <level> [<bundle>] ... - Set startlevel(s) for bundles
+  bundles [-help] [-1] [-i] [-l] [-s] [-t] [<bundle>] ... - List bundles
+  call [-help] [-f #filter#] <interface> <method> [<args>] ... - Call a method with zero or more java.lang.String
+  capability [-help] [-d] [-i] [-l] [-r] [-p] [<bundle>] ... - Show information about active capablities in the current wiring for a bundle
+  cd [-help] [-reset] [-a] [<base URL>] ... - Shows or sets the base URLs used to complete bundle location
+  certificates [-help] [ -i ] <bundle> ... - List certificates for bundles
+  closure [-help] <bundle> - Display the closure for a bundle
+  condpermission [-help] [<name>] ... - Get conditional permissions
+  deletepermission [-help] [-r] -b #bundle# | -d | -l #location# <type> <name> <actions> - Delete permissions from a bundle
+  findbundles [-help] <symbolic name> - Find bundles with a given symbolic name
+  frominstall [-help] <url> [<location>] - Install a bundle with a specific location from an URL
+  fromupdate [-help] <bundle> <url> - Update a bundle from a specific URL
+  headers [-help] [-i] [-l #locale#] <bundle> ... - Show bundle header values
+  install [-help] [-s] <location> ... - Install one or more bundles
+  meminfo [-help] [-gc] [-b | -m] - Display java memory information, in kilobytes
+  package [-help] [-l] -b | -p [<selection>] ... - Show java package information
+  pending [-help] [-i] [-l] - Show the bundles that have non-current, in use bune.dle wirings
+  permissions [-help] [-d] [<selection>] ... - Show permission information
+  property [-help] [-s] [-f] [<property>] ... - Lists Framework and System properties with values.
+  refresh [-help] [<bundle>] ... - Refresh all exported java packages belong to specified bundle
+  resolve [-help] [<bundle>] ... - Resolve one or more bundles
+  services [-help] [-i] [-l] [-sid #id#] [-f #filter#] [-r] [-u] [<bundle>] ... - List registered services
+  setcondpermission [-help] [-name #name] <conditional_permission_info>... - Set conditional permission
+  showstate [-help] [<pid>] ... - Show the state of a service, if the service provides state information
+  shutdown [-help] [-r] - Shutdown framework
+  start [-help] [-t] [-e] <bundle> ... - Persistently start one or more bundles according to their 
+  startlevel [-help] [<level>] - Shows or sets the global startlevel
+  stop [-help] [-t] <bundle> ... - Persitently stop one or more bundles
+  threads [-help] [-a] [-s] [<name>] ... - Display threads within this framework
+  uninstall [-help] <bundle> ... - Uninstall one or more bundles
+  update [-help] <bundle> ... - Update one or more bundles
+  wiring [-help] [-i] [-l] [-r] [-p] [<bundle>] ... - Show information about active wires in the current wiring for a bundle
+</pre>
+
+<h2 class="man">See Also</h2>
+<a href="../console/index.html">Console</a>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/http/index.html b/docs/bundledoc/http/index.html
new file mode 100644
index 0000000..0072dec
--- /dev/null
+++ b/docs/bundledoc/http/index.html
@@ -0,0 +1,380 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - http, v4.0.5</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: http
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.5
+      </div>
+      
+
+<h1 class="man">Http server</h1>
+
+<div class="abstract">
+Small footprint OSGi HTTP server implementation for embedded use. 
+The HTTP server allows bundles to register
+resources as servlets, web pages, images or multimedia into a web server
+running on the framework.
+</div>
+
+<h2 class="man">Usage</h2>
+
+<p>
+The HTTP bundle can be configured by both CM or System properties
+</p>
+
+<p>
+As soon as the http bundle gets a valid configuration it creates and
+registers an HttpService instance into the framework. 
+</p>
+
+<p>To use HTTPS a bundle providing a <tt>SslServerSocketFactory</tt>
+must be installed. E.g., <a href="../sslj2sp/index.html">SSL Provider
+— J2SP</a>.</p>
+
+<p>
+Note: If the server fails to bind to a port, an HttpService will still
+be registered, but the service property "port" will not be present!
+</p>
+
+<a name="cmd-http"><h2 class="man">Console Commands</h2></a>
+The HTTP server has the built-in console command group <b>http</b>.
+The command group shows information about configuration, servlet and
+resource registrations, as well as transaction status of the HTTP
+server. 
+<pre class="code">
+Usage: list [-help] [-c] [-r] [-t] [-l]
+  List all the configured HTTP servers
+  -c  Show configuration info
+  -r  Show all registrations, servlets and resources
+  -t  Show info on transactions
+  -l  List in long format, same as supplying -c -r -t, providing extensive details
+</pre>
+
+
+<h3 class="man">Configuration using Framework Properties</h3>
+
+<table class="man">
+  <tr>
+    <th class="man">Name</th>
+    <th>Description</th>
+    <th>Type</th>
+    <th>Default</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.enabled</td>
+    <td>
+
+      If true, the bundle will start to listen in the http port.
+
+    </td>
+    <td>boolean</td>
+    <td>true</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.secure.enabled</td>
+    <td>
+
+      If true, the bundle will start to listen in the https
+      port. <em>Note:</em> This functionality requires that the bundle
+      is able to obtain a <tt>SslServerSocketFactory</tt> service
+      instance from the frameworks service registry.
+
+    </td>
+    <td>boolean</td>
+    <td>true</td>
+  </tr>
+  <tr>
+    <td>org.osgi.service.http.port</td>
+    <td>
+
+	Port number that the HTTP server will listen for http-requests
+	on.
+
+    </td>
+    <td>int</td>
+    <td>80</td>
+  </tr>
+  <tr>
+    <td>org.osgi.service.http.secure.port</td>
+    <td>
+
+	Port number that the HTTP server will listen for
+	https-requests on.
+
+    </td>
+    <td>int</td>
+    <td>443</td>
+  </tr>
+  <tr>
+    <td>org.osgi.service.http.hostname</td>
+    <td>
+
+	Host (IP interface name) to open the HTTP server socket
+	on. An empty string means all available interfaces.
+
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.mime.props</td>
+    <td>
+
+     URL to properties file defining MIME type mappings. The key in
+     the properties file is the file name extension and the value is
+     the associated MIME type.
+
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.dnslookup</td>
+    <td>
+
+      This boolean property decides if the server will use DNS lookup
+      when a servlet calls the HttpServletRequest.getRemoteHost
+      method. In some environments DNS lookup will cause the current
+      transaction to hang for a long period of time.
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.response.buffer.size.default</td>
+    <td>
+
+      This integer property decides the default buffer size in bytes
+      for an HTTP response. If a servlet or publisher does not exceed
+      this buffer, the server will calculate and send the content
+      length header in the response. If the buffer is exceeded the
+      servlet or publisher need to set the content length header
+      explicitly. The content length header is required for persistent
+      connections. If the content length is unknown the server will
+      send a connection close header. The buffer size can be set
+      runtime by the servlet using the HttpResponse.setBufferSize()
+      method.
+
+    </td>
+    <td>int</td>
+    <td>16384</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.connection.max</td>
+    <td>
+
+      This integer property decides the maximum number of concurrent
+      connections to the HTTP server.
+
+    </td>
+    <td>int</td>
+    <td>50</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.connection.timeout</td>
+    <td>
+
+      This integer property decides the timeout in seconds for a
+      persistent connection to the HTTP server.
+
+    </td>
+    <td>int</td>
+    <td>30</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.session.timeout.default</td>
+    <td>
+
+      This integer property decides the default timeout in seconds for
+      an HTTP session.
+
+    </td>
+    <td>int</td>
+    <td>1200</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.encoding.default</td>
+    <td>
+
+      The default character encoding to use for text in the HTTP
+      response.
+
+    </td>
+    <td>String</td>
+    <td>ISO-8859-1</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.req.client.auth</td>
+    <td>
+
+      If client authentication shall be required or not when using
+      https.
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.trace.enabled</td>
+    <td>
+      If the TRACE method shall be enabled or not
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.limit.requestline</td>
+    <td>
+      Defines the maximum length of an HTTP request line. This limit
+      is also applied for HTTP header lines. When exceeding this limit
+      a 413 response is returned - Request Entity Too Large. 
+    </td>
+    <td>int</td>
+    <td>8090</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.limit.requestheaders</td>
+    <td>
+      Defines the maximum number of headers accepted per request. 
+      When exceeding this limit a 413 response is returned - Request Entity Too Large. 
+    </td>
+    <td>int</td>
+    <td>100</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.http.limit.postsize</td>
+    <td>
+      Defines the maximum content size for a POST request. A value of
+      -1 indicates there is no limit. This is also the default behaviour.
+      When exceeding this limit a 413 response is returned - Request Entity Too Large. 
+    </td>
+    <td>int</td>
+    <td>-1</td>
+  </tr>
+</table>
+
+
+<h3 class="man">Configuration using the Configuration Manager</h3>
+
+The http bundle accepts Factory configurations on the PID
+<pre>
+  org.knopflerfish.bundle.http.factory.HttpServer
+</pre>
+..with the following properties:
+
+<dl>
+
+<dt>http.enabled</dt>
+<dd>If true, the bundle will start to listen in the http port.</dd>
+
+<dt>https.enabled</dt>
+<dd>If true, the bundle will start to listen in the https port. Note:
+    This functionality requires that the bundle is able to obtain a
+    <tt>SslServerSocketFactory</tt> service instance from the
+    frameworks service registry.</dd>
+
+<dt>port.http (Integer)</dt>
+<dd>This integer property decides the default port for the server instance.
+  The default port is 8080.</dd>
+
+
+<dt>port.https (Integer)</dt>
+<dd>This integer property decides the default port for HTTPS requests
+    to the server instance.
+  The default port is 8443.</dd>
+
+
+<dt>host (String)</dt>
+<dd>  This string property decides the default hostname for the server
+  instance. If the server is running on a multihomed machine this
+  property will be used to decide which network interface the server will
+  listen to. If this property is not set the server will listen to all network
+  interfaces. The default is to listen to all network interfaces.
+</dd>
+
+<dt>mime.map (Vector of String[2])</dt>
+<dd>
+  This property is a vector of arrays defining MIME type mappings. Each
+  entry in the vector is an array with two elements where the first is
+  the file name extension and the second is the associated MIME type.
+  By default the most common file types are defined.
+</dd>
+
+
+<dt>session.timeout.default (Integer)</dt>
+<dd>
+  This integer property decides the default timeout in seconds for an
+  HTTP session. The default is 1200 seconds.
+</dd>
+
+<dt>connection.timeout (Integer)</dt>
+<dd>
+  This integer property decides the timeout in seconds for a persistent
+  connection to the HTTP server. The default is 30 seconds.
+</dd>
+
+<dt>connection.max (Integer)</dt>
+<dd>
+  This integer property decides the maximum number of concurrent
+  connections to the HTTP server. The default is 50.
+</dd>
+
+<dt>dns.lookup (Boolean)</dt>
+<dd>
+  This boolean property decides if the server will use DNS lookup when a
+  servlet calls the HttpServletRequest.getRemoteHost method. In some
+  environments DNS lookup will cause the current transaction to hang for
+  a long period of time. The default is to do DNS lookup.
+</dd>
+
+<dt>response.buffer.size.default (Integer)</dt>
+<dd>
+  This integer property decides the default buffer size in bytes for an
+  HTTP response. If a servlet or publisher does not exceed this buffer,
+  the server will calculate and send the content length header in the
+  response. If the buffer is exceeded the servlet or publisher need to
+  set the content length header explicitly. The content length header is
+  required for persistent connections. If the content length is unknown
+  the server will send a connection close header. The buffer size can be
+  set runtime by the servlet using the HttpResponse.setBufferSize()
+  method. The default is 16384 bytes.
+</dd>
+
+</dl>
+
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=http/http_all-4.0.5.html">http_all-4.0.5</a><br>
+<a target="_top" href="../../jars/index.html?bundle=http/http_api-4.0.5.html">http_api-4.0.5</a><br>
+<a target="_top" href="../../jars/index.html?bundle=http/http-4.0.5.html">http-4.0.5</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=http/http_all-4.0.5.html">http_all-4.0.5</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td><td align="center">1.2.1</td><td><a target="_top" href="../../jars/index.html?bundle=http/http_all-4.0.5.html">http_all-4.0.5</a>, <a target="_top" href="../../jars/index.html?bundle=http/http_api-4.0.5.html">http_api-4.0.5</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/httpconsole/images/bundle-active.png b/docs/bundledoc/httpconsole/images/bundle-active.png
new file mode 100644
index 0000000..f599d52
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/bundle-active.png differ
diff --git a/docs/bundledoc/httpconsole/images/bundle-lib-active.png b/docs/bundledoc/httpconsole/images/bundle-lib-active.png
new file mode 100644
index 0000000..ed07510
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/bundle-lib-active.png differ
diff --git a/docs/bundledoc/httpconsole/images/bundle.png b/docs/bundledoc/httpconsole/images/bundle.png
new file mode 100644
index 0000000..565f406
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/bundle.png differ
diff --git a/docs/bundledoc/httpconsole/images/document-open.png b/docs/bundledoc/httpconsole/images/document-open.png
new file mode 100644
index 0000000..254a6b8
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/document-open.png differ
diff --git a/docs/bundledoc/httpconsole/images/go-home.png b/docs/bundledoc/httpconsole/images/go-home.png
new file mode 100644
index 0000000..9d62109
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/go-home.png differ
diff --git a/docs/bundledoc/httpconsole/images/help.png b/docs/bundledoc/httpconsole/images/help.png
new file mode 100644
index 0000000..c67c7a6
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/help.png differ
diff --git a/docs/bundledoc/httpconsole/images/httpconsole_login.png b/docs/bundledoc/httpconsole/images/httpconsole_login.png
new file mode 100644
index 0000000..5f0411e
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/httpconsole_login.png differ
diff --git a/docs/bundledoc/httpconsole/images/httpconsole_openfile.png b/docs/bundledoc/httpconsole/images/httpconsole_openfile.png
new file mode 100644
index 0000000..d03f786
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/httpconsole_openfile.png differ
diff --git a/docs/bundledoc/httpconsole/images/httpconsole_ppc2003_1.png b/docs/bundledoc/httpconsole/images/httpconsole_ppc2003_1.png
new file mode 100644
index 0000000..5041683
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/httpconsole_ppc2003_1.png differ
diff --git a/docs/bundledoc/httpconsole/images/httpconsole_ppc2003_3.png b/docs/bundledoc/httpconsole/images/httpconsole_ppc2003_3.png
new file mode 100644
index 0000000..1e3f0f4
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/httpconsole_ppc2003_3.png differ
diff --git a/docs/bundledoc/httpconsole/images/info.png b/docs/bundledoc/httpconsole/images/info.png
new file mode 100644
index 0000000..07cf010
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/info.png differ
diff --git a/docs/bundledoc/httpconsole/images/lib.png b/docs/bundledoc/httpconsole/images/lib.png
new file mode 100644
index 0000000..4b55b50
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/lib.png differ
diff --git a/docs/bundledoc/httpconsole/images/openurl.png b/docs/bundledoc/httpconsole/images/openurl.png
new file mode 100644
index 0000000..4125479
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/openurl.png differ
diff --git a/docs/bundledoc/httpconsole/images/player_eject.png b/docs/bundledoc/httpconsole/images/player_eject.png
new file mode 100644
index 0000000..5a232e6
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/player_eject.png differ
diff --git a/docs/bundledoc/httpconsole/images/player_play.png b/docs/bundledoc/httpconsole/images/player_play.png
new file mode 100644
index 0000000..10102d8
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/player_play.png differ
diff --git a/docs/bundledoc/httpconsole/images/player_stop.png b/docs/bundledoc/httpconsole/images/player_stop.png
new file mode 100644
index 0000000..d0e4733
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/player_stop.png differ
diff --git a/docs/bundledoc/httpconsole/images/view-refresh.png b/docs/bundledoc/httpconsole/images/view-refresh.png
new file mode 100644
index 0000000..cab4d02
Binary files /dev/null and b/docs/bundledoc/httpconsole/images/view-refresh.png differ
diff --git a/docs/bundledoc/httpconsole/index.html b/docs/bundledoc/httpconsole/index.html
new file mode 100644
index 0000000..0e81271
--- /dev/null
+++ b/docs/bundledoc/httpconsole/index.html
@@ -0,0 +1,266 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - httpconsole, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: httpconsole
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">Http Console</h1>
+
+<div class="abstract">
+The Knopflerfish HTTP/HTML OSGi console is a small servlet that can be
+run on any OSGi platform with an installed HTTP server. It has been
+designed for use on devices with a small screen like mobile phones and
+pocket PC devices.
+</div>
+
+
+<h2 class="man">Description</h2>
+
+<div style="float: right; margin: 5px;">
+<img alt="HTTP console on pocketPC 2003" src="images/httpconsole_ppc2003_1.png"/><br/>
+<i>Image 1: HTTP console on pocketPC 2003</i>
+</div>
+
+<p>The Knopflerfish HTTP/HTML OSGi console is a small servlet that
+can be run on any OSGi platform with an installed HTTP server.</p>
+
+<p>When started, the servlet registers at <tt>/servlet/console</tt>
+and allows access to the standard framework functions as bundle
+installation (both from URLs and using browser file upload), start,
+stop, update and uninstall. Additionally, detail info on a bundle such
+as state, manifest and services can be displayed.</p>
+
+<p> Optionally, the HTTP console can request a login/pwd before
+enabling access. See <a class="std" href="#conf">configuration</a> for
+details.</p>
+
+<p> The HTTP console has been tested on Knopflerfish, Eclipse 3.0 and
+Oscar. It also runs well on Pocket PC (tested using KF on the IBM J9
+VM).</p>
+
+<p> The main screen lists all installed bundles. One or more bundles
+can be selected by marking the check box on the left.  After selecting
+bundles, the operations available as toolbar icons can be
+performed.</p>
+
+<p>Source is available via <a class="std"
+href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/http/httpconsole/">KF
+subversion</a> </p>
+
+<br clear="all">
+
+<h2 class="man">Usage</h2>
+
+<h3 class="man">Toolbar</h3>
+
+<div style="float: right; margin: 5px;">
+<img alt="Open a local file" src="images/httpconsole_ppc2003_3.png"/><br/>
+<i>Image 2: Result after starting a bundle</i>
+<div>
+<img src="images/httpconsole_openfile.png"><br/>
+<i>Image 3: Open a local file</i>
+</div>
+</div>
+
+<p>The toolbar display a set of command icons. When an icon is
+selected, the command will be performed. Any command result or errors
+will be displayed to the right of the bundle list.</p>
+
+<table>
+ <tr>
+ <td>
+ <img  alt="Reload view" type="image" name="cmd_reload" src="images/go-home.png"> </td>
+ <td style="vertical-align:top;">
+Reload page</td>
+</tr>
+ <tr>
+ <td>
+ <img alt="Install bundle from file" type="image" name="cmd_installfile" src="images/document-open.png">
+ </td>
+ <td style="vertical-align:top;">
+Ask for a local bundle file, upload the file and install the bundle</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Install bundle from URL" type="image" name="dialog_cmd_installurl" src="images/openurl.png"> </td>
+ <td style="vertical-align:top;">
+Ask for a bundle URL and install this bundle</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Start selected bundles" type="image" name="cmd_start" src="images/player_play.png"> </td>
+ <td style="vertical-align:top;">
+Start selected bundles</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Stop selected bundles" type="image" name="cmd_stop" src="images/player_stop.png"> </td>
+ <td style="vertical-align:top;">
+Stop selected bundles</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Update selected bundles" type="image" name="cmd_update" src="images/view-refresh.png"> </td>
+ <td style="vertical-align:top;">
+Update selected bundles</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Uninstall selected bundles" type="image" name="cmd_uninstall" src="images/player_eject.png"> </td>
+ <td style="vertical-align:top;">
+Uninstall selected bundles</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Show info for selected bundles" type="image" name="cmd_info" src="images/info.png"> </td>
+ <td style="vertical-align:top;">
+Info about selected bundles. If no bundle is selected, show framework info</td>
+</tr>
+ <tr>
+ <td>
+ <img  alt="Show help" type="image" name="cmd_help" src="images/help.png"> </td>
+ <td style="vertical-align:top;">
+Show help page </td>
+</tr>
+</table>
+</p>
+<br clear="all"/>
+
+
+<h3 class="man">Bundle icons</h3>
+
+<div style="float: right; margin: 5px;">
+<img alt="Login screen" src="images/httpconsole_login.png"/><br/>
+<i>Image 4: Login screen</i>
+</div>
+
+<p>Each bundle is displayed using an icon, the bundle's name and the
+bundle description. If a bundle's icon is clicked, the bundle is
+selected, and the bundle info page is displayed.</p>
+
+<table>
+<tr>
+  <td><img src="images/bundle.png"></td>
+  <td>Bundle with activator</td>
+</tr>
+<tr>
+  <td><img src="images/bundle-active.png"></td>
+  <td>Started bundle with activator</td>
+</tr>
+<tr>
+  <td><img src="images/lib.png"></td>
+  <td>Bundle without activator</td>
+</tr>
+<tr>
+  <td><img src="images/bundle-lib-active.png"></td>
+  <td>Started bundle without activator</td>
+</tr>
+</table>
+<br clear="all"/>
+
+
+<h3 class="man"><a name="conf">Configuration using Framework Properties</a></h3>
+
+<p> The HTTP console can be configured using system properties:</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.httpconsole.alias</td>
+    <td>
+
+      Alias for servlet registration. If set to '/', the http root
+      will used for the console.
+
+    </td>
+    <td>String</td>
+    <td>/servlet/console</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.httpconsole.filter</td>
+    <td>
+
+      Filter string for matching HttpServices. This can be used
+      to only show the console in some registered HttpServices.
+
+    </td>
+    <td>String</td>
+    <td>(objectclass=org.osgi.service.http.HttpService)</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.httpconsole.requirelogin</td>
+    <td>
+
+      If <tt>true</tt>, require login, using name and password.
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.httpconsole.user</td>
+    <td>
+
+      User name required for login.
+
+    </td>
+    <td>String</td>
+    <td>admin</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.httpconsole.pwd</td>
+    <td>
+
+      User password required for login.
+
+    </td>
+    <td>String</td>
+    <td>admin</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.httpconsole.expirationtime</td>
+    <td>
+
+      Expiration time for login sessions, in seconds. After this time,
+      the user will be logged out.
+
+    </td>
+    <td>int (seconds)</td>
+    <td>600</td>
+  </tr>
+</table>
+
+<br clear="all"/>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/index.html b/docs/bundledoc/index.html
new file mode 100644
index 0000000..911648f
--- /dev/null
+++ b/docs/bundledoc/index.html
@@ -0,0 +1,42 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <title>Knopflerfish - Framework and Bundle User Documentation</title>
+    <script type="text/javascript" language="JavaScript">
+      <!--
+	  targetPage = "" + getPageId(window.location.search);
+
+	  function getPageId ( searchStr ) {
+	    var idStartPos = searchStr.indexOf('docpage=');
+	    if (-1==idStartPos) {
+	      return "bundledoc_main.html";
+	    }
+	    idStartPos += 8;
+	    var idEndPos = searchStr.indexOf('&',idStartPos);
+	    if (-1==idEndPos) {
+	      return searchStr.substr(idStartPos);
+	    } 
+	    return searchStr.substring(idStartPos,idEndPos);
+	  }
+
+	  function loadFrame() {
+	    top.bundledoc_main.location = top.targetPage;
+	  }
+
+          //-->
+    </script> 
+  </head>
+  <frameset rows="95px,*" onLoad="top.loadFrame()">
+    <frame name="bundledoc_hdr" src="bundledoc_hdr.html"
+           frameborder="0"      scrolling="no"
+           marginwidth="0"      marginheight="0">
+    <frameset cols="240,*">
+      <frame name="bundledoc_list" src="bundledoc_list.html"
+	     frameborder="0"             scrolling="auto"
+	     marginwidth="0"             marginheight="0">
+    
+      <frame name="bundledoc_main"	src="bundledoc_main.html"
+	     frameborder="0"             scrolling="auto">
+    </frameset>
+  </frameset>
+</html>
diff --git a/docs/bundledoc/junit/index.html b/docs/bundledoc/junit/index.html
new file mode 100644
index 0000000..ae0c82a
--- /dev/null
+++ b/docs/bundledoc/junit/index.html
@@ -0,0 +1,268 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - junit, v3.8.1.kf4-001</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: junit
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 3.8.1.kf4-001
+      </div>
+      <h1 class="man">JUnit on OSGI</h1>
+
+Bundles to support JUnit testing on a running framework. 
+<p>
+There are three bundles involved:
+<dl> 
+<dt>junit
+<dd>   bundle exporting the junit.framework.* classes
+   as well as allowing remote connection to test suites
+   in a running framework via http. This bundle also 
+   exports a JUnitService to allow other bundles in
+   the framework access to bundles.
+
+<dt> junit_runner
+<dd>    a bundle which automatically finds and runs
+    bundles in a framework. This bundle does 
+    not require any http connection, just the
+    junit bundle. See junit_runner/readme.txt
+    for more info.
+
+<dt> examples
+<dd>    some small test cases using junit
+</dl>
+
+<h2 class="man">Requirements:</h2>
+
+The junit bundle does not require any other bundles (as of revision 737)
+but can use the HTTP server and the KF console to make test access easier.
+<ul>
+<li> - optionally http server (used dynically by the server part)
+
+<li> - optionally KF console (used dynamically by the server part)
+
+<li> - XML parser (used by the client part)
+</ul>
+
+<h2 class="man">Background</h2>
+
+JUnit allows developers to write unit tests by writing classes 
+implementing junit.framework.Test, e.g TestCase, TestSuite etc.
+<p>
+A typical test looks like
+<pre class="code">
+ class MyTest extends junit.framework.TestCase {
+   public void runTest() {
+     ... do some work
+     assertTrue(someflag)
+   }
+ }
+</pre>
+As long as these test do not depend on a running framework, they
+are easy to run using normal tools, but when they depend on the
+framework, the standard test running tools become insufficient.
+<p>
+Thus, the junit bundle allows remote access to test cases running
+on a framework, from any normal test tool running on a developer 
+machine.
+
+<h2 class="man">How it works</h2>
+<ol> 
+<li>Bundle developers write tests for a bundle B just as any other 
+    JUnit tests. The tests simply extends TestCase or TestSuite.
+
+<li>The bundle developer register these tests as-is into the OSGi
+    framework, with a service.pid property giving the name
+    of the test. This should normally be the same name as the
+    test. Typically all tests from a bundle is grouped into
+    a TestSuite.
+<p>
+    Example: register a test suite into the framework.
+<pre class="code">
+      TestSuite suite = new TestSuite("example1");
+
+      suite.addTest(new MyTest());
+      Hashtable props = new Hashtable();
+      props.put("service.pid", suite.getName());
+    
+      bc.registerService(Test.class.getName(), suite, props);
+</pre>
+
+<li>The junit bundle, when started, registers a servlet in the
+    OSGi web server, if the web server exists. This servlet then 
+    allows remote running of the registered test cases.
+
+    The servlet is available at
+<pre class="shell">
+      http://<host>:<port>/junit?id=<testid>
+</pre>
+    where <testid> == value of the service.pid property exported
+    in 2) 
+<p>
+    The only interface that registered tests need to implement
+    is junit.framework.Test
+<P>
+    The junit bundle thus accesses the tests via BundleContext.getService()
+    and needs ServicePermission, if FW security is active.
+<p>
+ Note how *only* step 2) is extra work compared to writing standard
+ JUnit tests.
+
+
+
+<li>When actual testing is desired, a single client test class is used
+    on the development machine (which doesn't need to run the framework!)
+<p>
+    The client class name is:
+<pre class="shell">
+     org.knopflerfish.service.junit.client.JUnitClient
+</pre>
+    The target host and test id is passed to the client as a 
+    system property "suite.url"
+<p>
+    This client test class extends TestSuite and act as a proxy to the 
+    actual test, and can thus be passed to any test runner, as
+<p>
+     junit.swingui.TestRunner or
+     junit.textui.TestRunner
+<p>
+   as well as Ant's "junit" task.
+<p>
+   Example: Using the Swing TestRunner
+<pre  class="shell">
+    > java "-Dsuite.url=http://localhost:8080/junit?id=example1" \
+       junit.swingui.TestRunner \
+       org.knopflerfish.service.junit.client.JUnitClient
+</pre>
+    This will run the test with id "example1" on localhost:8080
+<p>
+    Note that the class path must be set fo find both junit.jar and
+    the junit_all-1.0.0.jar bundle.
+
+<li>Testing can also be done without using the servlet. The easiest
+    approach is then to use the junit_runner bundle, and provide it with
+    a list of test IDs to run. XML formatted results will then be
+    written to file.
+
+<li>If you are using the KF console, the junit bundle registers
+    a set of commands to list and run test cases.
+<pre class="shell">
+    > enter junit
+    junit> help
+    Available junit commands:
+     list [-help]  - List available tests
+     run [-help] [-out #file#] <id> - Run a test and dump XML results 
+                                      to a file or console.
+</pre>
+</ol>
+
+<b>Note1:</b><br>
+<p>
+  The servlet is also capable of exporting the test results as plain
+  HTML. In this case, the client proxy isn't needed. Just point your
+  browser at
+<pre class="shell">
+   http://<host>:<port>/junit
+</pre>
+  and you'll get a list of available tests. From this list you can
+  select suites and individual tests to run. The result will be
+  presented as HTML.
+
+<b>Note2: </b><br>
+
+  The junit_runner/resource directory contains som XSLT style
+  sheets which may be useful for formatting XML test results to
+  HTML.
+ 
+
+<h2 class="man">Monitoring test case execution</h2>
+
+  JUnit <tt>TestListener</tt>s may be used to monitor test case
+  execution.
+
+  <p>
+
+  The junit-bundle will look up all services registered
+  under the class <tt>junit.framework.TestListener</tt> in the
+  running framework and add them to the TestResult as listeners.
+
+  <p>
+    Example: register a test listener into the framework.
+<pre class="code">
+      TestListener listener = new MyTestListener();
+
+      bc.registerService(TestListener.class.getName(), listener, null);
+</pre>
+
+
+<h2 class="man">JUnit support in bundlebuild.xml</h2>
+
+As a convenience, the ant/bundlebuild.xml script
+contains support for using the JUnit client.
+
+<p>
+Example: run the swing Test runner from Ant
+<pre  class="shell">
+   > ant -Dtest.id=example1 junit_ext
+</pre>
+   
+Example: run Ant's junit task
+<pre  class="shell">
+   > ant -Dtest.id=example1 junit_ant
+</pre>
+
+Tip: Bundles can be installed using the telnet console. The telnet
+console is installed by the default init.xargs. In this case a bundle
+can be installed and started by
+<pre  class="shell">
+   > ant install start
+</pre>     
+
+The following Ant properties are set as default in bundlebuild.xml:
+<pre class="code">
+  http.host              localhost
+  http.port              8080
+  junit.runner.class     junit.swingui.TestRunner
+  junit.formatter        plain
+  junit.outfile          junit
+</pre>
+
+<h2 class="man">Known issues</h2>
+
+<ul>
+<li>TestSuites are "flattened" by the client proxy, so the
+   tree structure in the Swing runner might look a bit different
+   compared from tests run locally.
+
+<li> Proxied tests cannot (yet) be individually re-run. The entire client 
+   proxy must be re-run
+</ul>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td>junit.framework</td><td align="center">3.8.1</td><td><a target="_top" href="../../jars/index.html?bundle=junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/kxml/index.html b/docs/bundledoc/kxml/index.html
new file mode 100644
index 0000000..1d3d7b8
--- /dev/null
+++ b/docs/bundledoc/kxml/index.html
@@ -0,0 +1,63 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - kxml, v2.3.0.kf4-001</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: kxml
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 2.3.0.kf4-001
+      </div>
+      <h1 class="man">kXML 2 XML parser</h1>
+
+<div class="abstract">
+  kXML - a lightweight low-footprint XML parser.
+</div>
+
+<h2 class="man">kXML 2</a></h2>
+<p>
+  The kXML XML parser is a lighweight, low-footprint XML parser. It
+  provides basic XML parse functionality which may be well enough for
+  many siutations despite the limitations kXML has compared to a more
+  full-featured parser. 
+</p>
+
+<h2 class="man">See Also</h2>
+<a href="../xalan/index.html">Xalan</a>,
+<a href="../xerces/index.html">Xerces</a>
+and the kXML 2 project on <a target="_top"
+href="http://kxml.sourceforge.net/kxml2/">Sourceforge</a>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/kxml2/kdom/package-summary.html">org.kxml2.kdom</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/kxml2/wap/package-summary.html">org.kxml2.wap</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/kxml2/wap/syncml/package-summary.html">org.kxml2.wap.syncml</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/kxml2/wap/wml/package-summary.html">org.kxml2.wap.wml</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/kxml2/wap/wv/package-summary.html">org.kxml2.wap.wv</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+ <tr><td>org.xmlpull.v1</td><td align="center">1.1.3.1</td><td><a target="_top" href="../../jars/index.html?bundle=kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/log/index.html b/docs/bundledoc/log/index.html
new file mode 100644
index 0000000..0cbf0d2
--- /dev/null
+++ b/docs/bundledoc/log/index.html
@@ -0,0 +1,168 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - log, v5.0.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: log
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.0
+      </div>
+      <h1 class="man">Log</h1>
+
+<div class="abstract">
+  OSGi Log service implementation.
+</div>
+
+<h2 class="man">Description</h2>
+
+<p>
+This bundle provides a log-service and a log-reader-service
+according to the OSGi Compendium specification. It also exports a
+managed service implementing both
+<tt>org.osgi.service.cm.ManagedService</tt> and
+<tt>org.knopflerfish.service.log.LogConfig</tt>
+to allow for configuration of the log service.
+</p>
+
+<p>
+Console commands for interacting with the log service are provided
+by the bundle
+<a href="../logcommands/index.html"><tt>logcommands</tt></a>.
+</p>
+
+
+<h2 class="man">Configuration properties</h2>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.out</td>
+    <td>
+
+	Print new log entries on System.out when set to "true".
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.grabio</td>
+    <td>
+
+	If <code>true</code> grab all text printed on System.out and
+	System.err and add it to the log.
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.level</td>
+    <td>
+
+	The default log level. All log records that are of lesser
+	severity than this level will be skipped when writing to the
+	log file and not keept in memory.
+
+    </td>
+    <td>Case insensitive String, one of "INFO", "DEBUG", "WARNING", "ERROR",
+    "DEFAULT".</td>
+    <td>INFO</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.file</td>
+    <td>
+
+	If <code>true</code> write log entries to file. Only entires
+	with the severity given by
+	<code>org.knopflerfish.log.level</code> or higher are written.
+
+    </td>
+    <td>boolean</td>
+    <td>false</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.file.dir</td>
+    <td>
+
+	The path to the directory to write the cyclic file log to.  If
+	empty or not given the data directory of the log-bundles will
+	be used.
+
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.memory.size</td>
+    <td>
+
+	Number of log records to keep in memeory.
+
+    </td>
+    <td>Integer</td>
+    <td>250</td>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.log.timestamp.pattern</td>
+    <td>
+
+	The pattern to use when formatting the timestamp of a log
+	entry. The value of this property must follow the rules of a
+	pattern as defined by the class java.text.SimpleDateFormat.
+
+    </td>
+    <td>String</td>
+    <td>yyyyMMdd HH:mm:ss</td>
+  </tr>
+
+</table>
+
+
+<h2 class="man">See Also</h2>
+<a href="../logcommands/index.html">Logcommands</a>
+  
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=log/log_all-5.0.0.html">log_all-5.0.0</a><br>
+<a target="_top" href="../../jars/index.html?bundle=log/log_api-5.0.0.html">log_api-5.0.0</a><br>
+<a target="_top" href="../../jars/index.html?bundle=log/log-5.0.0.html">log-5.0.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=log/log_all-5.0.0.html">log_all-5.0.0</a>, <a target="_top" href="../../jars/index.html?bundle=log/log_api-5.0.0.html">log_api-5.0.0</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=log/log_all-5.0.0.html">log_all-5.0.0</a>, <a target="_top" href="../../jars/index.html?bundle=log/log_api-5.0.0.html">log_api-5.0.0</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/logcommands/index.html b/docs/bundledoc/logcommands/index.html
new file mode 100644
index 0000000..4eb48b1
--- /dev/null
+++ b/docs/bundledoc/logcommands/index.html
@@ -0,0 +1,433 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - logcommands, v5.0.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: logcommands
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 5.0.0
+      </div>
+      <h1 class="man">Logcommands</h1>
+
+<div class="abstract">
+  Log service console commands to view log entries and configure the
+  log-service.
+</div>
+
+
+<h2 class="man">Description</h2>
+The logcommands bundle publishes two command groups:
+<ul>
+  <li>log - Log commands</li>
+  <li>logconfig - Configuration commands for the log</li>
+</ul>      
+
+The <tt>log</tt> command group consists of a single command
+<tt>show</tt> that interacts directly with the log service to get and
+display available log entries.
+
+The <tt>logconfig</tt> command group offers commands for configuring a
+log service implementation. E.g., number of log entries to keep in
+memory, if entries should be printed to standard out or not, if
+entries are to be saved to a file or not.
+
+
+<h2 class="man">Log - Log commands</h2>
+
+<p>
+The <tt>log</tt> command group consists of a single command,
+<tt>show</tt>, that interacts directly with the log-reader service to
+get and display available log entries.
+</p>
+
+<p>
+  The group contains the following command:
+</p>
+
+<ul><li>
+    <tt>show [-help] [-f] [-h #hours#] [-l #level#] [-n #count#] [-s] [<bundle>] ...</tt></li>
+</ul>
+
+<p>
+This command group works with any OSGi compliant log-service
+implementation.
+</p>
+
+
+<h3 class="man">show</h3>
+
+<p>
+  The <tt>show</tt> command is used to show selected log entries
+  that are available from the log service, i.e., held in memory.
+</p>
+
+<p>
+  Entries will be ordered with the most recent entry first. If no
+  bundle argument is supplied, log entries from all bundles are
+  considered.
+</p>
+
+<pre>
+  show [-help] [-f] [-h #hours#] [-l #level#] [-n #count#] [-s] [<bundle>] ...
+</pre>
+
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  
+  <dt><b>-f</b></dt><dd>Show only entries for events from the framework.</dd>
+  <dt><b>-h #hours#</b></dt><dd>Show only entries since #hours#
+    back. Note that 'hours' is a float so that smaller time than one
+    hour is possible.</dd>
+  <dt><b>-l #level#</b></dt><dd>Show only entries with minimum #level#
+    of one of <tt>error</tt>, <tt>warning</tt>, <tt>info</tt>
+    or <tt>debug</tt>.</dd>
+  
+  <dt><b>-n #count#</b></dt><dd>Show at most #count# entries, that is, the
+    #count# most recent entries that fulfills the selection criteria.</dd>
+  <dt><b>-s</b></dt><dd>Show the stack trace for exceptions.</dd>
+  <dt><b><bundle></b></dt><dd>Name or id of bundle. The value
+    <tt>"*"</tt> may be used to list entries from all bundles
+    except the framework itself.</dd>
+</dl>
+
+<h3 class="man">Examples</h3>
+<p>
+Show log error entries.
+</p>
+<pre>
+  log> show -l error
+  07/06 15:16:41 ERROR #19, messenger -
+  Failed to load configuration / java.io.FileNotFoundException:
+  /demo/gatespace/bin/host.conf
+  (No such file or directory)
+  07/06 15:16:41 ERROR FRAMEWORK -
+  FrameworkError: org.osgi.framework.BundleException:
+  Bundle.start: BundleActivator start failed
+  07/06 15:16:41 ERROR #18, authentication -
+  Failed to read KeyStore / java.net.MalformedURLException:
+  null: java.lang.NullPointerException: 
+</pre>
+
+
+<h2 class="man">Logconfig - Configuration commands for the log</h2>
+
+<p>
+The <tt>logconfig</tt> command group offers commands for configuring a
+log service implementation.
+</p>
+
+<p>
+This command group only works with log service implementations that
+publishes a <tt>org.knopflerfish.service.log.LogConfig</tt>.
+</p>
+
+<p>
+  The group contains the following commands:
+</p>
+
+<ul><li>
+    <tt>memory [-help] [<int>] </tt></li>
+  <li>
+    <tt>setlevel [-help] <level> [<bundle>] ... </tt>
+  </li>
+
+  <li>
+    <tt>showlevel [-help] [<bundle>] ... </tt></li>
+  <li>
+    <tt>out [-help] [-on | -off] </tt></li>
+  <li>
+    <tt>file [-help] [-on | -off [-size #size#] [-gen #gen#] [-flush | -noflush] </tt></li>
+  <li>
+    <tt>timestamp [-help] [<pattern>] </tt></li>
+</ul>
+
+
+
+<h3 class="man">memory</h3>
+
+<p>
+  The memory command is used to control the number of log entries 
+  that are held in memory.
+</p>
+
+<p>
+  If the command is given without any parameters the current maximum
+  number of log entries is shown.
+</p>
+
+<p> 
+  Show and set the number of log entries in memory.
+</p>
+<pre>
+  memory [-help] [<int>]
+</pre>
+
+Parameters:
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+
+  <dt><b><int></b></dt><dd>The maximum number of log entries held in memory.
+  </dd>
+</dl>
+
+
+
+<h3 class="man">setlevel</h3>
+
+<p>
+  The setlevel command is used to control what log entries are
+  actually written to the log. There is one default log level
+  and in addition each bundle can have its own setting. A
+  log level may also be set giving a bundle short name in which
+  case all bundles with this name will be logged at the given
+  level. The default level is used for bundles without log
+  levels of their own.</p> 
+
+<p>
+  Entries with a severity level higher or the same as the
+  current default level will be logged. For example, with the
+  default level set to warning, entries with level warning or
+  error will be logged. 
+</p>
+
+<p>
+The severity order of the levels is: 
+</p>
+<ul><li>
+    ERROR </li>
+  <li>
+    Warning </li>
+  <li>
+    info </li>
+  <li>
+    debug </li>
+
+</ul>
+
+
+<p>
+  Set log level.
+</p>
+<pre>
+  setlevel [-help] <level> [<bundle>] ...
+</pre>
+
+Parameters:
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><level></b></dt><dd>The new log level. One of <tt>error</tt>,
+    <tt>warning</tt>, <tt>info</tt>,
+    <tt>debug</tt> or <tt>default</tt>.
+  </dd>
+
+  <dt><b><bundle></b></dt><dd>URL, short name, or id of bundle.
+    A URL or bundle id must be used if wanting to set the log
+    level of one specific bundle. When supplying a bundle short
+    name all bundles with this name will be logged at the given level. 
+    If no bundle is given the default log level is set.</dd>
+</dl>
+
+
+
+<h3 class="man"> showlevel</h3>
+
+<p>
+  The showlevel command lists the default log level and the levels for
+  the specified bundles, or for all bundles if no bundle is specified
+  (only bundles with a level different from the default level
+  are listed). 
+</p>
+
+<p>
+  The output has columns for bundle id, log level and bundle
+  name. A "<tt>*</tt>" in the id column indicates the
+  default level, and a "<tt>-</tt>" in the same column
+  indicates that the log level was set with a bundle short name
+  or that the bundle is not yet installed. The bundle name
+  column may contain a bundle short name or if the log level of a
+  bundle not yet installed is set the bundle location will be
+  displayed instead.
+</p>
+
+<p>
+  Show current log levels.
+</p>
+<pre>
+  showlevel [-help] [<bundle>] ...
+</pre>
+
+Parameters:
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><bundle></b></dt><dd>URL, bundle short name or id. Shows
+    level for a specific bundle if a bundle id or location is
+    given. When supplying a bundle short name the log level for all
+    bundles with this name will be displayed.</dd>
+</dl>
+
+
+<b>Example:</b> Default and bundle log levels
+<pre>
+
+  logconfig> setlevel warning console
+  logconfig> showlevel
+  *  debug    (default)
+  2  Warning  console
+  -  Warning  console   (default)</pre>
+
+
+<h3 class="man">out</h3>
+
+<p>
+  Enables printout of all log entries on standard out. The entries are
+  written to the log as well.
+</p>
+
+<p>The <tt> out </tt> command is disabled if no valid configuration has been
+  received, that is, the Configuration Management(CM) component has
+  not generated a configuration or the CM component is not available.
+  See [<a href="#IG-PROD_GDSP_CP_PFM_LOG">1</a>] for further
+  description of the configuration procedure.</p>
+
+<p>
+  If the command is given without parameters the present setting is shown.
+</p>
+
+<pre>
+  out [-help] [-on | -off]
+</pre>
+
+Parameters:
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-on</b></dt><dd>Turns on writing of log entries to standard out.</dd>
+  <dt><b>-off</b></dt><dd>Turns off writing of log entries to standard out.</dd>
+
+</dl>
+
+
+<h3 class="man">file</h3>
+<p>
+  This command controls the writing of log entries to file, the size 
+  of log files, how many generations of log files to keep and whether each
+  log entry should be flushed to file.
+</p>
+
+<p>The <tt> file </tt> command is disabled if no valid configuration has been
+  received, that is, the Configuration Management(CM) component has
+  not generated a configuration or the CM component is not
+  available. See [<a href="#IG-PROD_GDSP_CP_PFM_LOG">1</a>] for further
+  description of the configuration procedure.
+</p>
+
+<p>
+If the command is given without parameters the present setting is shown.
+</p>
+
+<p>
+Note that a change in log file size does not take effect until the
+present log file has been filled and a new is started.
+</p>
+
+<p>
+  Configures the writing of log entries to file.
+</p>
+
+<pre>
+  file [-help] [-on | -off [-size #size#] [-gen #gen#] [-flush | -noflush] 
+</pre>
+
+Parameters:
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+
+  <dt><b>-on</b></dt><dd>Turns on writing of log entries to file.</dd>
+  <dt><b>-off</b></dt><dd>Turns off writing of log entries to file.
+    <a name="B1"><a href="#F1"><sup>1</sup></a>
+    </dd>
+    <dt><b>-size #size#</b></dt><dd>Sets the maximum size (in characters) of a log file.</dd>
+    <dt><b>-gen #gen#</b></dt><dd>Sets the number of log file generations that are kept.</dd>
+    <dt><b>-flush</b></dt><dd>Turns on log file flushing after each log entry.</dd>
+
+    <dt><b>-noflush</b></dt><dd>Turns off log file flushing after each log entry.</dd>
+  </dl>
+
+
+<h3 class="man">timestamp</h3>
+
+<p>
+  The timestamp command shows or sets the formatting pattern for the
+  time-stamp in a log entry. This formatting pattern applies to log
+  entries written to the file log and to the console when
+  <code>out</code> has been activated. It does not apply to output of
+  the <code>log</code>-command.
+</p>
+
+<p>
+  When called without an argument it prints the current formatting pattern.
+</p>
+<pre>
+  timestamp [-help] [<pattern>]
+</pre>
+
+Parameters:
+<dl>
+  <dt><b>-help</b></dt>
+  <dd>Display command help text.</dd>
+
+  <dt><b><pattern></b></dt>
+  <dd>The new time-stamp formatting pattern. The pattern follows the
+      rules for time formatting patterns defined by the
+      java.text.SimpleDateFormat-class. The default pattern is
+      "<code>yyyyMMdd HH:mm:ss</code>".</dd>
+</dl>
+
+
+<b>Example:</b> Extend the time-stamp format to include milliseconds,
+then call without argument to check that the new pattern was applied.
+<pre>
+
+  logconfig> timestamp 'yyyyMMdd HH:mm:ss.SSS'
+  logconfig> timestamp
+    time stamp pattern: 'yyyyMMdd HH:mm:ss.SSS'.
+
+</pre>
+
+
+<h3 class="man">Examples</h3>
+  <p>
+    Turn on writing to standard out
+    <pre>
+      logconfig> out -on
+    </pre>
+  </p>
+  <p>Turn on flushing of buffers after each log entry.
+    <pre>
+      logconfig> file -flush
+    </pre>
+  </p>
+
+
+
+<h2 class="man">See Also</h2>
+<a href="../log/index.html">Log</a>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/prefs/index.html b/docs/bundledoc/prefs/index.html
new file mode 100644
index 0000000..33976f3
--- /dev/null
+++ b/docs/bundledoc/prefs/index.html
@@ -0,0 +1,69 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - prefs, v4.0.2</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: prefs
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.2
+      </div>
+      
+
+<h1 class="man">Preferences</h1>
+
+<div class="abstract">
+  The prefs bundle implements the 
+  <a  target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/PreferencesService.html">
+    OSGi Preferences service</a>
+  that provides easy to use persistent storage of bundle data. 
+</div>
+
+<h2 class="man">Description</h2>
+<p>
+  With Preferences, bundles can store data persistently. Data is stored
+  as named values in a tree structure where each node can have any
+  number of key-value pairs. For example, Preferences can be used by a
+  bundle to store application and user settings. A bundle typically uses
+  a number of preferences tree roots, one for system settings and one
+  for each user's settings. 
+</p>
+<p>
+  This component implements the OSGi Preferences service.
+</p>
+<p>
+  Note that preferences are tied to a bundle. The OSGi service
+  provides no way for a bundle to access the preferences of another
+  bundle. Once fetched though, it is possible for one bundle to share
+  its preferences with other bundles. 
+</p>
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a><br>
+<a target="_top" href="../../jars/index.html?bundle=prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td><td align="center">1.1.1</td><td><a target="_top" href="../../jars/index.html?bundle=prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a>, <a target="_top" href="../../jars/index.html?bundle=prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/repository_desktop/images/repository_add.png b/docs/bundledoc/repository_desktop/images/repository_add.png
new file mode 100644
index 0000000..0b9f455
Binary files /dev/null and b/docs/bundledoc/repository_desktop/images/repository_add.png differ
diff --git a/docs/bundledoc/repository_desktop/images/repository_add_300.png b/docs/bundledoc/repository_desktop/images/repository_add_300.png
new file mode 100644
index 0000000..583161e
Binary files /dev/null and b/docs/bundledoc/repository_desktop/images/repository_add_300.png differ
diff --git a/docs/bundledoc/repository_desktop/images/repository_details_displayer.png b/docs/bundledoc/repository_desktop/images/repository_details_displayer.png
new file mode 100644
index 0000000..606da0c
Binary files /dev/null and b/docs/bundledoc/repository_desktop/images/repository_details_displayer.png differ
diff --git a/docs/bundledoc/repository_desktop/images/repository_details_displayer_300.png b/docs/bundledoc/repository_desktop/images/repository_details_displayer_300.png
new file mode 100644
index 0000000..bfce667
Binary files /dev/null and b/docs/bundledoc/repository_desktop/images/repository_details_displayer_300.png differ
diff --git a/docs/bundledoc/repository_desktop/images/repository_settings.png b/docs/bundledoc/repository_desktop/images/repository_settings.png
new file mode 100644
index 0000000..a16b498
Binary files /dev/null and b/docs/bundledoc/repository_desktop/images/repository_settings.png differ
diff --git a/docs/bundledoc/repository_desktop/images/repository_settings_300.png b/docs/bundledoc/repository_desktop/images/repository_settings_300.png
new file mode 100644
index 0000000..a5d2134
Binary files /dev/null and b/docs/bundledoc/repository_desktop/images/repository_settings_300.png differ
diff --git a/docs/bundledoc/repository_desktop/index.html b/docs/bundledoc/repository_desktop/index.html
new file mode 100644
index 0000000..f507888
--- /dev/null
+++ b/docs/bundledoc/repository_desktop/index.html
@@ -0,0 +1,141 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - repository_desktop, v1.1.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: repository_desktop
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 1.1.1
+      </div>
+      <h1 class="man">The Knopflerfish Desktop Repository plug-in</h1>
+<div class="abstract">
+  The Knopflerfish OSGi Desktop Repository plug-in provides a bundle detail
+  view for interacting with the OSGi repository and resolver services.
+</div>
+
+<h2 class="man">Description</h2>
+<div style="float:right">
+  <a href="images/repository_details_displayer.png">
+    <img src="images/repository_details_displayer_300.png" width="300" height="165">
+  </a>
+</div>
+
+  <p>The Knopflerfish OSGi Desktop Repository plug-in provides a bundle detail
+  view for working with OSGi repositories. It support common operations
+  like browsing repositories and installing a bundle from a
+  repository. Future versions of this plugin will also work with OSGi
+  resolver services to be able not only to install the selected bundle
+  but also all its dependencies that are needed for the selected
+  bundle to be fully functional.</p>
+
+
+<h3 class="man">The Repository-desktop view</h3>
+
+  <p>The view presents a tree view of all resources that are
+  down-loadable bundles in the configured repositories. The tree
+  supports a number of different ways to sort the bundles. The
+  drop-down on the left in the tool-bar below the bundle tree can be
+  used to change the sort order.</p>
+
+  <p>The main part of the view (to the right of the bundle tree) shows
+  details for the selected bundle. Here you can see the download URL,
+  the size and a SHA-256 checksum for the bundle. You can also see all
+  capabilities that the bundle provides and requires.</p>
+
+
+<h3 class="man">The Repository-desktop view tool-bar</h3>
+
+  <p>The tool.bar below the bundle tree on the left of the repository
+  view provides buttons to:</p>
+
+  <ul>
+    <li> Change sort order in the bundle tree.
+    <li> Rebuild the view with data from the available set of
+         repository services.
+    <li> Install the selected bundle.
+    <li> Install and start the selected bundle.
+    <li> Show a settings window to configure repositories.
+  </ul>
+
+<div style="clear:both"></div>
+<h3 class="man">The settings window</h3>
+
+<div style="float:right">
+  <a href="images/repository_settings.png">
+    <img src="images/repository_settings_300.png" width="300" height="106">
+  </a>
+</div>
+
+  <p>In the settings window you can configure the rank of a
+  repository. The repositories are searched for resources in rank
+  order, highest rank first.</p>
+
+  <p>It is also possible to enable or disable a repository. A disabled
+  repository is not searched when searching for bundle resources. Note
+  that the enable / disable state only applies to the current
+  "session".</p>
+
+<div style="clear:both"></div>
+<div style="float:right">
+  <a href="images/repository_add.png">
+    <img src="images/repository_add_300.png" width="300" height="165">
+  </a>
+</div>
+  <p>The settings dialog also provides an "Add..." button to define
+  new XML-based repositories.</p>
+
+
+
+<div style="clear:both"></div>
+<h2 class="man">Configuration properties</h2>
+
+The Repository-Desktop bundle does not support any properties for configuration.
+
+<!--
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.bundle.log.window.impl.LogTableModel.capacity</td>
+    <td>
+
+	The maximum number of log entries to keep in memory in one log
+	view. Use a negative value (i.e., a value smaller than 1) to
+	indicate that old entries shall never be removed.
+
+    </td>
+    <td>int</td>
+    <td>342</td>
+  </tr>
+</table>
+-->
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/repository_xml/images/repository_add.png b/docs/bundledoc/repository_xml/images/repository_add.png
new file mode 100644
index 0000000..0b9f455
Binary files /dev/null and b/docs/bundledoc/repository_xml/images/repository_add.png differ
diff --git a/docs/bundledoc/repository_xml/images/repository_add_300.png b/docs/bundledoc/repository_xml/images/repository_add_300.png
new file mode 100644
index 0000000..583161e
Binary files /dev/null and b/docs/bundledoc/repository_xml/images/repository_add_300.png differ
diff --git a/docs/bundledoc/repository_xml/images/repository_details_displayer.png b/docs/bundledoc/repository_xml/images/repository_details_displayer.png
new file mode 100644
index 0000000..606da0c
Binary files /dev/null and b/docs/bundledoc/repository_xml/images/repository_details_displayer.png differ
diff --git a/docs/bundledoc/repository_xml/images/repository_details_displayer_300.png b/docs/bundledoc/repository_xml/images/repository_details_displayer_300.png
new file mode 100644
index 0000000..bfce667
Binary files /dev/null and b/docs/bundledoc/repository_xml/images/repository_details_displayer_300.png differ
diff --git a/docs/bundledoc/repository_xml/images/repository_settings.png b/docs/bundledoc/repository_xml/images/repository_settings.png
new file mode 100644
index 0000000..a16b498
Binary files /dev/null and b/docs/bundledoc/repository_xml/images/repository_settings.png differ
diff --git a/docs/bundledoc/repository_xml/images/repository_settings_300.png b/docs/bundledoc/repository_xml/images/repository_settings_300.png
new file mode 100644
index 0000000..a5d2134
Binary files /dev/null and b/docs/bundledoc/repository_xml/images/repository_settings_300.png differ
diff --git a/docs/bundledoc/repository_xml/index.html b/docs/bundledoc/repository_xml/index.html
new file mode 100644
index 0000000..2afeccf
--- /dev/null
+++ b/docs/bundledoc/repository_xml/index.html
@@ -0,0 +1,127 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - repository_xml, v1.0.2</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: repository_xml
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 1.0.2
+      </div>
+      <h1 class="man">Repository XML</h1>
+<div class="abstract">
+  The Knopflerfish OSGi Repository XML bundle provides Repository
+  services based on the contents of XML documents using the OSGi
+  specified schema
+  <code>http://www.osgi.org/xmlns/repository/v1.0.0</code>.
+</div>
+
+<h2 class="man">Description</h2>
+
+  <p>The Knopflerfish OSGi Repository XML bundle creates Repository
+  services that reflects the contents of XML documents following the
+  OSGi specified schema:
+  <code>http://www.osgi.org/xmlns/repository/v1.0.0</code>.</p>
+
+
+<div style="clear:both"></div>
+<h2 class="man">Configuration</h2>
+
+  <p>The XML documents to parse and present as Repository services can
+  be configured in several ways:</p>
+
+  <ul>
+    <li>Using framework (system) properties.
+    <li>Using CM configuration.
+    <li>Using the
+        <code>org.knopflerfish.service.repository.XmlBackedRepositoryFactory</code>
+	registered by the bundle.
+  </ul>
+
+
+<h3 class="man">Configuration properties</h3>
+
+  <p>The Repository XML bundle supports the following framework
+  properties for configuration:</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>org.knopflerfish.repository.xml.urls</td>
+    <td>
+
+        Comma separated list of OSGi Repository XML URLs for instantiating 
+        Repository Services from.
+
+    </td>
+    <td>String</td>
+    <td>—</td>
+  </tr>
+</table>
+
+
+<h3 class="man">Configuration via Configuration Management</h3>
+
+  <p>The Repository XML bundle uses a factory PID to configure
+  repository services. Each factory PID configuration instance
+  corresponds to one XML file for which one Repository service will be
+  created.</p>
+
+  <p>The factory PID is
+  <code>org.knopflerfish.repository.xml.MSF</code>.</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>url</td>
+    <td>
+
+        URL pointing to the location of an OSGi Repository XML file to instantiate
+	a Repository Service from.
+
+    </td>
+    <td>String</td>
+    <td>—</td>
+  </tr>
+</table>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a><br>
+<a target="_top" href="../../jars/index.html?bundle=repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a>, <a target="_top" href="../../jars/index.html?bundle=repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/repositorycommands/index.html b/docs/bundledoc/repositorycommands/index.html
new file mode 100644
index 0000000..eb74d23
--- /dev/null
+++ b/docs/bundledoc/repositorycommands/index.html
@@ -0,0 +1,203 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - repositorycommands, v1.1.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: repositorycommands
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 1.1.1
+      </div>
+      <h1 class="man">Repository Commands</h1>
+<div class="abstract">
+  The Knopflerfish repository manager console bundle
+</div>
+
+<h2 class="man">Description</h2>
+
+The Repository commands bundle includes a set of commands through which the Knopflerfish Repository Manager can be controlled. This includes bundle search and install, repository management (add, remove, ordering, enable and disable).
+
+<h2 class="man">Repository Command Group</h2>
+
+<pre class="code">
+Available repository commands:
+  add [-help] [-r #rank#] <url> - Add a XML based repository.
+  bundle [-help] [-l] [<symbolicname> [<versionRange>]] - List bundle resources.
+  disable [-help] <repository> ... - Disable selected repository.
+  enable [-help] <repository> ... - Enable selected repository.
+  install [-help] [-s] <symbolicname> [<versionRange>] - Install bundle resource.
+  list [-help] [-l] [<repository>] - List repositories.
+  rank [-help] <rank> <repository> ... - Change repository ranking.
+  show [-help] [-t] <namespace> [<filter>] - Show all capabilities and requirements for selected resources.
+</pre>
+
+<h3 class="man">add</h3>
+<p>
+  Add a XML based repository.
+</p>
+<pre>
+add [-help] [-r #rank#] <url>
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-r #rank#</b></dt><dd>Set rank explicitly.</dd>
+  <dt><b><url></b></dt><dd>URL for repository file.</dd>
+</dl>
+
+<h3 class="man">bundle</h3>
+<p>
+  List bundle resources. List all bundles that matches &ltsymbolicname&gt
+  and &ltversionRange&gt. Mark with a '*' in the first column if a
+  bundle is installed.
+</p>
+<pre>
+bundle [-help] [-l] [<symbolicname> [<versionRange>]]
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-l</b></dt><dd>Verbose output.</dd>
+  <dt><b><symbolicname></b></dt><dd>Bundle symbolic name to match.</dd>
+  <dt><b><versionRange></b></dt><dd>Optional bundle version range.</dd>
+</dl>
+
+<h3 class="man">disable</h3>
+<p>
+  Disable selected repository. Disables a repository so that it won't
+  be used when searching for resources.
+</p>
+<pre>
+disable [-help] <repository> ...
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><repository></b></dt><dd>Wildcard name or id of repository.</dd>
+</dl>
+
+<h3 class="man">enable</h3>
+<p>
+  Enable selected repository. Enables a repository so that it will be used
+  when searching for resources.
+</p>
+<pre>
+enable [-help] <repository> ...
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><repository></b></dt><dd>Wildcard name or id of repository.</dd>
+</dl>
+
+<h3 class="man">install</h3>
+<p>
+  Install bundle resource. Installs first bundle resource that
+  matches <symbolicname> and optional <versionRange>.
+</p>
+<pre>
+install [-help] [-s] [<symbolicname< [<versionRange<]]
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-s</b></dt><dd>Persistently start bundle according to activation policy.</dd>
+  <dt><b><symbolicname></b></dt><dd>Bundle symbolic name to match.</dd>
+  <dt><b><versionRange></b></dt><dd>Optional bundle version range.</dd>
+</dl>
+
+<h3 class="man">list</h3>
+<p>
+  List repositories. Mark with a '*' in the first column if a repository
+  is enabled.
+</p>
+<pre>
+list [-help] [-l] <repository>
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-l</b></dt><dd>Verbose output.</dd>
+  <dt><b><repository></b></dt><dd>Wildcard name or id of repository.</dd>
+</dl>
+
+<h3 class="man">rank</h3>
+<p>
+  Change repository ranking. The rank is used to can change the order
+  in which repositories are searched. Repository with highest ranking
+  is searched first.
+</p>
+<pre>
+rank [-help] <rank> <repository> ...
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><rank></b></dt><dd>New rank of repository, must be an integer.</dd>
+  <dt><b><repository></b></dt><dd>Wildcard name or id of repository.</dd>
+</dl>
+
+<h3 class="man">show</h3>
+<p>
+ Show all capabilities and requirements for selected resources.
+</p>
+<pre>
+show [-help] [-t] <namespace< [<filter<]
+</pre>
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-t</b></dt><dd>Terse output, only show namespace attribute.</dd>
+  <dt><b><namespace></b></dt><dd>Which namespace to search.</dd>
+  <dt><b><filter></b></dt><dd>OSGi filter expression for selecting resources.</dd>
+</dl>
+
+<h3 class="man">Examples</h3>
+<p>
+List all repository available.
+</p>
+<pre>
+repository> list
+E  Id Rank  Description
+------------------------
+*  15    0  XML repository from URL: file:jars/index.xml
+</pre>
+
+<p>
+List bundles with a symbolic name starting with
+"org.knopflerfish.bundle.repository" that are available
+from the repository.
+</p>
+
+<pre>
+repository> b org.knopflerfish.bundle.repository*
+I Bundle resource
+- --------------------
+  org.knopflerfish.bundle.repository.index, version=1.0.0
+* org.knopflerfish.bundle.repository-API, version=1.0.0
+* org.knopflerfish.bundle.repository_desktop, version=1.0.0
+* org.knopflerfish.bundle.repository.xml, version=1.0.0
+  org.knopflerfish.bundle.repository.xml-API, version=1.0.0
+* org.knopflerfish.bundle.repositorycommands-IMPL, version=1.0.0
+* org.knopflerfish.bundle.repositorymanager, version=1.0.0
+  org.knopflerfish.bundle.repositorymanager-API, version=1.0.0
+</pre>
+
+<h2 class="man">See Also</h2>
+<a href="../console/index.html">Console</a>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/scrcommands/index.html b/docs/bundledoc/scrcommands/index.html
new file mode 100644
index 0000000..fa599e8
--- /dev/null
+++ b/docs/bundledoc/scrcommands/index.html
@@ -0,0 +1,173 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - scrcommands, v4.0.1</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: scrcommands
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.1
+      </div>
+      <h1 class="man">ScrCommands</h1>
+
+<div class="abstract">
+  Service Component Runtime (SCR) console commands to view dynamic and
+  static state of components and enable or disable them.
+</div>
+
+
+<h2 class="man">Description</h2>
+The scrcommands bundle publishes one command group called <tt>scr</tt>.
+
+<p>
+This command group currently works with SCR that provides the
+<tt>org.apache.felix.scr.ScrService</tt> service.
+</p>
+
+<h2 class="man">Scr - Scr Commands</h2>
+
+<p>
+  The group contains the following commands:
+</p>
+
+<ul><li>
+      <tt>disable [-help] <component&gt ...</tt></li>
+    <li>
+      <tt>enable [-help] <component&gt ...</tt></li>
+    <li>
+      <tt>list [-help] [-i] [-l] [-n] [-r] [<bundle&gt] ...</tt></li>
+    <li>
+      <tt>show [-help] [-b] [-f] [-n] [-r] [<component&gt] ...</tt></li>
+</ul>
+
+<h3 class="man">disable</h3>
+
+<p>
+  The <tt>disable</tt> command is used to disable selected component(s).
+</p>
+
+<pre>
+  disable [-help] <component&gt ...
+</pre>
+
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><component></b></dt><dd>Name or id of component.</dd>
+</dl>
+
+<h3 class="man">enable</h3>
+
+<p>
+  The <tt>enable</tt> command is used to enable selected component(s).
+</p>
+
+<pre>
+  enable [-help] <component&gt ...
+</pre>
+
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b><component></b></dt><dd>Name or id of component.</dd>
+</dl>
+
+<h3 class="man">list</h3>
+
+<p>
+  The <tt>list</tt> command is used to list information about
+  components for selected bundles. Components are shown in bundle id
+  order if no order parameter is given.
+</p>
+
+<pre>
+  list [-help] [-i] [-l] [-n] [-r] [<bundle&gt] ...
+</pre>
+
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-i</b></dt><dd>List components in ID order.</dd>
+  <dt><b>-l</b></dt><dd>Show long version of information,
+    that includes information about properties, services
+    provided and referenced.</dd>
+  <dt><b>-n</b></dt><dd>List components in name order",
+  <dt><b>-r</b></dt><dd>List components in reverse order",
+  <dt><b><bundle></b></dt><dd>Name or id of bundle. If
+    no value is given or a <tt>"*"</tt>, list entries from
+    all bundles.</dd>
+</dl>
+
+<h3 class="man">show</h3>
+
+<p>
+  The <tt>show</tt> command is used to show information about
+  components. Components are shown in component id  order if
+  no order parameter is given. With the <tt>-f</tt> parameter
+  will show more information than the <tt>list</tt> command,
+  it will show some, static information about the component.
+</p>
+
+<pre>
+  show [-help] [-b] [-f] [-n] [-r] [<component&gt] ...
+</pre>
+
+<p>Parameters:</p>
+<dl><dt><b>-help</b></dt><dd>Display command help text.</dd>
+  <dt><b>-b</b></dt><dd>List components in bundle ID order.</dd>
+  <dt><b>-f</b></dt><dd>Show full version of information,
+    that includes static information about the component.</dd>
+  <dt><b>-n</b></dt><dd>List components in name order",
+  <dt><b>-r</b></dt><dd>List components in reverse order",
+  <dt><b><component></b></dt><dd>Name or id of component.
+    If no value is given, show all components registered.</dd>
+</dl>
+
+<h3 class="man">Examples</h3>
+<p>
+List all components for all bundles.
+</p>
+<pre>
+scr> list
+ID State        BID Name
+ 0 ACTIVE        19 scrCommandGroup
+ 1 REGISTERED    25 componentE_test.E1
+ 2 FACTORY       25 componentE_test.E2
+</pre>
+
+<p>
+Show full inforamtion about scrCommandGroup component.
+</p>
+<pre>
+scr> show -f scrCommandGroup
+ID State        BID Name
+ 0 ACTIVE        19 scrCommandGroup
+   > Service: org.knopflerfish.service.console.CommandGroup
+   > Satisfied reference:   org.apache.felix.scr.ScrService [1..1], static bind
+   > Property groupName = scr
+   > Delayed component, default enabled, config policy = optional
+</pre>
+
+<h2 class="man">See Also</h2>
+<a href="../console/index.html">Console</a>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/serial/index.html b/docs/bundledoc/serial/index.html
new file mode 100644
index 0000000..e8a38cf
--- /dev/null
+++ b/docs/bundledoc/serial/index.html
@@ -0,0 +1,69 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - Serial Communication</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <h1 class="man">Serial port communicaton using javax.comm</h1>
+
+This section covers bundles for handling serial ports using the
+javax.comm API
+
+<h2 class="man">Bundles</h2>
+
+<dl>
+<dt> serialport
+<dd>
+  Bundle that wraps serial ports in the OSGi Device API.
+ 
+<dt> comm-win32
+<dd>
+  Implementation for windows platforms using Sun's COMM 2.0 release.
+  Note that this bundles contains code with license from Sun, for 
+  details, see
+  
+   comm-win32/resources/COMM2.0_license.txt
+
+<dt> comm-linux
+<dd>
+  Implementation for x86 linux platforms using the RXTX library.
+  Note that this bundles contains code with license from Sun AND
+  is licensed under GPL. For details, see
+  
+   comm-linux/resources/COMM2.0_license.txt
+   comm-linux/resources/rxtx-license.txt
+
+  The RXTX source is available at
+
+   http://users.frii.com/jarvi/rxtx/
+
+</dl>
+
+<h2 class="man">Bundle Jar docs</h2>
+<a target="_top" href="../../jars/index.html?bundle=comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a><br>
+<a target="_top" href="../../jars/index.html?bundle=comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a><br>
+<a target="_top" href="../../jars/index.html?bundle=serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a><br>
+<a target="_top" href="../../jars/index.html?bundle=serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a>
+
+<h2 class="man">Exported Packages</h2>
+<table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a></td><td align="center">2.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td></tr>
+ <tr><td>javax.comm</td><td align="center">2.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a>, <a target="_top" href="../../jars/index.html?bundle=comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a>, <a target="_top" href="../../jars/index.html?bundle=serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td></tr>
+</table>
+
+
+  </body>
+</html>
+    
diff --git a/docs/bundledoc/soap/index.html b/docs/bundledoc/soap/index.html
new file mode 100644
index 0000000..3d74906
--- /dev/null
+++ b/docs/bundledoc/soap/index.html
@@ -0,0 +1,49 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - Web Services / SOAP</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <h1 class="man">SOAP and WebServices in Knopflerfish</h1>
+
+<div class="abstract">
+<p>
+
+There are no SOAP implementations in Knopflerfish 4 since they
+have been made obsolete by the compendium service Remote Service Admin
+(RSA).
+
+</p>
+</div>
+
+<p>
+
+The Knopflerfish 3 versions of Axis 1, kSOAP and Axis2 are
+availble from the latest <a
+href="http://www.knopflerfish.org/releases/current-kf_3/">Knopflerfish 3
+download page</a> and can be used together with
+Knopflerfish 4. Individual Knopflerfish 3 bundles can be
+downloaded from this <a
+href="http://www.knopflerfish.org/releases/current-kf_3/docs/jars/index.html">page.</a>
+
+</p><p>
+
+Information on available RSA implementations can be found on the <a
+href="http://en.wikipedia.org/wiki/OSGi_Specification_Implementations">OSGi
+Specification Implementations Wikipedia page</a>.
+
+</p>
+
+  </body>
+</html>
+    
diff --git a/docs/bundledoc/sslj2sp/index.html b/docs/bundledoc/sslj2sp/index.html
new file mode 100644
index 0000000..ebc9cf0
--- /dev/null
+++ b/docs/bundledoc/sslj2sp/index.html
@@ -0,0 +1,169 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - sslj2sp, v4.0.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: sslj2sp
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.0
+      </div>
+      <h1 class="man">SSL Provider — Using the Java 2 Security Architecture.</h1>
+
+<div class="abstract">
+
+  The sslj2sp bundle registers one or several
+  <tt>SslServerSocketFactory</tt> objects as OSGi services.  These
+  services can be used by other bundles to establish secure TCP
+  connections.  For example, to implement HTTPS, look at the
+  documentation of your HTTP Service bundle to see if it will support
+  the use of such services.
+
+</div>
+
+
+<h2 class="man">Java Secure Socket Extension (JSSE)</h2>
+
+This bundle relies on the presence of Sun's <em>Java™ Secure Socket
+Extensions (JSSE)</em>; more specifically, jsse.jar must be available
+on the system class-path.  This is always the case when using Sun's
+Java™ Platform Standard Edition, v1.4+. To read more about this see
+the JSSE Reference Guide for Java Platform Standard Edition <a
+target="_blank"
+href="http://docs.oracle.com/javase/1.4.2/docs/guide/security/jsse/JSSERefGuide.html">1.4</a>
+or <a target="_blank"
+href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html">7</a>.
+
+<p>
+
+To create your customized SSL certificate, see section "Creating a
+Keystore to Use with JSSE".  NOTE: This material is owned by Sun
+Microsystems, please refer to their terms and conditions.
+
+You can use the Configuration Manager to tell the <tt>sslj2sp</tt>
+bundle what <tt>SslServerSocketFactory</tt> service(s) to create, see
+section Configuration Manager. If nothing is specified, a default
+configuration will be used.
+
+
+<h3 class="man">Configuration</h3>
+
+The sslj2sp bundle may be configured using the OSGi Configuration
+Manager (CM). It accepts factory configurations with the factory PID
+
+<pre>
+  org.knopflerfish.bundle.ssl.j2sp
+</pre>
+
+If no configuration is available in CM, a default configuration with
+values equals to the defaults described below will be used.
+
+<p>
+
+Properties with a name <tt>[none]</tt> can not be configured in the
+current implementation.
+
+<p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+
+  <tr>
+    <td>[none]</td>
+    <td>
+
+	SSL protocol to use.
+
+    </td>
+    <td>String</td>
+    <td>TLSv1</td>
+  </tr>
+
+  <tr>
+    <td>[none]</td>
+    <td>
+
+	Keystore type
+
+    </td>
+    <td>String</td>
+    <td>JKS</td>
+  </tr>
+
+  <tr>
+    <td>keystore</td>
+    <td>
+
+	This property represents a keystore, which must be created as
+        described in section "JSSE".
+
+	The sslj2sp will interpret the value for this property as
+	follows:
+	<ul>
+	  <li> assume that the keystore has been stored to the CM as
+	       an array of bytes (byte[]).
+
+	  <li> assume that the value is the name of the keystore file
+               on the local file system.
+  
+	</ul>
+
+	If none of these assumptions lead to a valid key manager, the
+        bundle will log a warning and use the default.
+    </td>
+    <td>String or byte[]</td>
+    <td>[internal]</td>
+  </tr>
+
+  <tr>
+    <td>keystorepass</td>
+    <td>
+
+	The password for the store (plain text).
+
+    </td>
+    <td>String</td>
+    <td>[internal]</td>
+  </tr>
+
+  <tr>
+    <td>[none]</td>
+    <td>
+
+	Keymanager type.
+
+    </td>
+    <td>String</td>
+    <td>SunX509</td>
+  </tr>
+
+</table>
+  
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/trayicon_fw/index.html b/docs/bundledoc/trayicon_fw/index.html
new file mode 100644
index 0000000..4cf5462
--- /dev/null
+++ b/docs/bundledoc/trayicon_fw/index.html
@@ -0,0 +1,60 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - trayicon_fw, v4.0.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: trayicon_fw
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.0
+      </div>
+      <h1 class="man">Framework tray icon.</h1>
+
+<div class="abstract">
+  A simple trayicon supporting start level change and framework shutdown.
+</div>
+
+
+<h2 class="man">Description</h2>
+
+This bundle adds an icon representing the framework to the system tray
+for a desktop. See the Java-doc for java.awt.SystemTray for the
+definition of what the system tray is on different window systems.
+The standard <tt>java.awt.SystemTray</tt> and
+<tt>java.awt.TrayIcon</tt> classes was added in Java™ 6 thus this
+bundle will only be fully functional on Java™ 6 and later.
+
+<p>
+
+The Tray Icon offers two operations:
+<ul>
+
+  <li>Change start level.
+
+  <li>Stop the framework.
+
+</ul>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      No exported packages.
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/util/index.html b/docs/bundledoc/util/index.html
new file mode 100644
index 0000000..c634a26
--- /dev/null
+++ b/docs/bundledoc/util/index.html
@@ -0,0 +1,139 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - util, v4.1.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: util
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.1.0
+      </div>
+      <h1 class="man">Util</h1>
+
+<div class="abstract">
+  Library of miscellaneous utility classes.
+</div>
+
+
+<h2 class="man">Content</h2>
+<ul>
+  <li><a href="#executable">Native Executable</a></li>
+</ul>      
+
+<a name="executable"></a>
+<h2 class="man">Native Executable</h2>
+
+<p>
+The bundle activator utility class ExecutableBundleActivator can be used
+if you need to package an executable binary in your bundle that should be
+extracted and started when the bundle starts.
+</p>
+
+<p>
+  Depending on your needs you can either write your own bundle activator
+  that extends ExecutableBundleActivator or use it directly without writing
+  any Java code at all. If you use it directly, all you need to do is to
+  add custom headers to your manifest that controls the behavior of
+  ExecutableBundleActivator.
+</p>
+
+<p>
+  The following are the required headers for a simple example.
+<pre>
+ Manifest-Version: 1.0
+ Bundle-ManifestVersion: 2
+ Bundle-SymbolicName: org.knopflerfish.bundle.ebaexample
+ Bundle-Activator: org.knopflerfish.util.framework.ExecutableBundleActivator
+ Import-Package = org.knopflerfish.util.framework,org.osgi.framework
+ Bundle-Start-Executable: notepad.exe ; processor=x86 ; osname=WindowsXP
+</pre>
+</p>
+
+<p>
+In this case there is only one custom header, Bundle-Start-Executable. It
+declares that if the native environment matches OS = Windows XP and
+processor architecture = x86, the resource named notepad.exe should be
+extracted from the bundle, written to the local file system and launched
+using java.lang.Runtime.exec() when the bundle is started.
+</p>
+
+<p>
+The exec:ed process will be terminated when the bundle stops. If the
+process is terminated, the bundle will be stopped (this is the default 
+behavior).
+</p>
+
+<p>
+Complete list of custom headers for this utility class:
+<dl>
+  <dt><b>Bundle-Start-Executable</b></dt>
+  <dd>List of native environments (OS, processor, etc) and native
+      executables for those environments. If there is a match for the
+      current native environment, the executable is copied to the local
+      file system and started in the start method of
+      ExecutableBundleActivator.
+      The syntax for this header is the same as for the OSGi specified
+      <tt>Bundle-NativeCode</tt> header but instead of naming a shared
+      library you name a native executable. The <tt>Bundle-NativeCode</tt>
+      header is described in the core OSGi specification chapter 3.9.</dd>
+  <dt><b>Bundle-Start-Executable-Args</b></dt>
+  <dd>Arguments (separated with spaces) for the bundle start executable.
+  </dd>
+  <dt><b>Bundle-Stop-Executable</b></dt>
+  <dd>Similar to <tt>Bundle-Start-Executable</tt> but the executable
+      is launched when the bundle stops.</dd>
+  <dt><b>Bundle-Stop-Executable-Args</b></dt>
+  <dd>Arguments (separated with spaces) for the bundle stop executable.
+  </dd>
+  <dt><b>Bundle-Extract-Files</b></dt>
+  <dd>List of extra resources (separated with comma) that should be
+  copied from the bundle jar file to the local file system.</dd>
+  <dt><b>Bundle-Start-Executable-Exit-Means-Bundle-Stop</b></dt>
+  <dd>Set this to false if you do not want the bundle to be stopped when
+      the process that was launched in start() is terminated.</dd>
+</dl>
+
+<p>
+In many cases you want to write your own activator that extends
+ExecutableBundleActivator. You can then for example override logging
+which is on and to stdout by default. Also, you need to write your own
+activator if you want your bundle to do more than starting a native
+executable.
+</p>
+
+<p>
+Files that are extracted (executables and other resources) are written to
+the bundle's persistent storage area. Cleanup of the files takes place
+when the bundle is uninstalled.
+<p>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=util/util-4.1.0.html">util-4.1.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td><td align="center">1.1.0</td><td><a target="_top" href="../../jars/index.html?bundle=util/util-4.1.0.html">util-4.1.0</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=util/util-4.1.0.html">util-4.1.0</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=util/util-4.1.0.html">util-4.1.0</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/workerthread/package-summary.html">org.knopflerfish.util.workerthread</a></td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=util/util-4.1.0.html">util-4.1.0</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/xalan/index.html b/docs/bundledoc/xalan/index.html
new file mode 100644
index 0000000..c17d7bf
--- /dev/null
+++ b/docs/bundledoc/xalan/index.html
@@ -0,0 +1,63 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - xalan, v2.7.1.kf3_01</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: xalan
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 2.7.1.kf3_01
+      </div>
+      <h1 class="man">Xalan XML transfomer</h1>
+
+<div class="abstract">
+<p>
+  Bundle version of the Xalan XML transformer
+</div>
+
+<h2 class="man">Xalan XML transformer bundle</a></h2>
+<p>
+  This is a bundlified version of 
+  <a href="http://xml.apache.org/xalan-j/">Xalan-Java</a>.
+</p><p>
+  It will register itself as an OSGi service using the
+  <a href="../xml/index.html">OSGi XML util bundle.</a>
+</p>
+<h2 class="man">See also</h2>
+<a href="../xml/index.html">OSGi XML util bundle</a></br>
+<a href="../xerces/index.html">Xerces XML Parser bundle</a></br>
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td>javax.xml.transform</td><td align="center">1.3.0.selectFirst</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+ <tr><td>javax.xml.transform.dom</td><td align="center">1.3.0.selectFirst</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+ <tr><td>javax.xml.transform.sax</td><td align="center">1.3.0.selectFirst</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+ <tr><td>javax.xml.transform.stream</td><td align="center">1.3.0.selectFirst</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+ <tr><td>org.apache.xalan</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+ <tr><td>org.apache.xalan.processor</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+ <tr><td>org.apache.xpath.jaxp</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/xerces/index.html b/docs/bundledoc/xerces/index.html
new file mode 100644
index 0000000..07bd46f
--- /dev/null
+++ b/docs/bundledoc/xerces/index.html
@@ -0,0 +1,106 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - xerces, v2.10.1.kf5</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: xerces
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 2.10.1.kf5
+      </div>
+      <h1 class="man">Xerces XML parses</h1>
+
+<div class="abstract">
+<p>
+  Bundle version of the Xerces XML parser
+</div>
+
+<h2 class="man">Xerces XML parser bundle</a></h2>
+<p>
+  This is a bundlified version of 
+ <a href="http://xerces.apache.org/xerces2-j/">Xerces2-Java </a> XML parser.
+</p><p>
+  It will register itself as an OSGi service using the
+  <a href="../xml/index.html">OSGi XML util bundle.</a>
+</p>
+<h2 class="man">See also</h2>
+<a href="../xml/index.html">OSGi XML util bundle</a></br>
+<a href="../xalan/index.html">Xalan XML Transformer bundle</a></br>
+
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td>javax.xml</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.datatype</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.namespace</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?javax/xml/parsers/package-summary.html">javax.xml.parsers</a></td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.transform</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.transform.dom</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.transform.sax</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.transform.stream</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.validation</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>javax.xml.xpath</td><td align="center">1.3.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.html.dom</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.wml</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.wml.dom</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.dom</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.dom.events</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.dom3.as</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.jaxp</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.jaxp.datatype</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.jaxp.validation</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.parsers</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.util</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xinclude</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xni</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xni.grammars</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xni.parser</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xpointer</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xs</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xerces.xs.datatypes</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.resolver</td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.resolver.apps</td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.resolver.helpers</td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.resolver.readers</td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.resolver.tools</td><td align="center">1.2.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.serialize</td><td align="center">0.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.apache.xml.serializer</td><td align="center">1.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a></td><td align="center">1.0.1</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.bootstrap</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.css</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.events</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.html</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.ls</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.ranges</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.stylesheets</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.traversal</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.views</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.w3c.dom.xpath</td><td align="center">3.0.0</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.xml.sax</td><td align="center">2.0.2</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.xml.sax.ext</td><td align="center">2.0.2</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+ <tr><td>org.xml.sax.helpers</td><td align="center">2.0.2</td><td><a target="_top" href="../../jars/index.html?bundle=xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/xml/index.html b/docs/bundledoc/xml/index.html
new file mode 100644
index 0000000..8aee6d6
--- /dev/null
+++ b/docs/bundledoc/xml/index.html
@@ -0,0 +1,55 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - xml, v4.0.0</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <div class="manpage">
+      <div class="userdoc_hdr_left">
+	Bundle: xml
+      </div>
+      <div class="userdoc_hdr_right">
+	Version 4.0.0
+      </div>
+      <h1 class="man">OSGi defined  XML parser serive</h1>
+
+<div class="abstract">
+<p>
+  An OSGi defined XML parser utlility service.
+</div>
+
+<h2 class="man">OSGi XML</a></h2>
+<p>
+The OSGi xml bundle is a utility bundle that allows any JAXP complient XML Parser and XML Transformer to register themselves as an OSGi parser and OSGI transformer. 
+</p><p>
+Knopflerfish includes xalan and xerces bundles that have been wrapped as XML parsers and transformers using this util bundle.
+</p>
+
+<h2 class="man">See Also</h2>
+<a href="../xalan/index.html">Xalan</a>
+<a href="../xerces/index.html">Xerces</a>
+
+
+      <h2 class="man">Bundle Jar docs</h2>
+      <a target="_top" href="../../jars/index.html?bundle=xml/xml-4.0.0.html">xml-4.0.0</a>
+
+      <h2 class="man">Exported Packages</h2>
+      <table class="man">
+ <tr><th>Package</th><th>Version</th><th>Providers</th></tr>
+ <tr><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a></td><td align="center">1.0.1</td><td><a target="_top" href="../../jars/index.html?bundle=xml/xml-4.0.0.html">xml-4.0.0</a></td></tr>
+</table>
+
+    </div>
+  </body>
+</html>
+
diff --git a/docs/bundledoc/xml_index/index.html b/docs/bundledoc/xml_index/index.html
new file mode 100644
index 0000000..2b1b732
--- /dev/null
+++ b/docs/bundledoc/xml_index/index.html
@@ -0,0 +1,50 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../../css/kf_man.css" rel="stylesheet" type="text/css">
+    <title>Bundle User Documentation - XML parsers in Knopflerfish</title>
+    <script type="text/javascript">
+      function windowTitle() {
+        if (location.href.indexOf('is-external=true') == -1) {
+           parent.document.title=document.title;
+        }
+      }
+    </script>
+    <noscript></noscript>
+  </head>
+  <body class="mainblock" onload="windowTitle();">
+    <h1 class="man">XML parsers in Knopflerfish</h1>
+
+<div class="abstract">
+<p>
+  An overview of XML parsers in Knopflerfish
+</div>
+
+<h2 class="man">XML Parsers</h2>
+<p>
+  There are several XML parsers included in Knopflerfish, serving different purposes.
+</p>
+<p>
+  The <a href="../kxml/index.html">kXML</a> parser is a light-weight,
+  low foot-print xml parser that provides all the basic parse functionality,
+  but has limitations compared to a more full featured parser. 
+x</p>
+<p>
+ A more full featured parser is Xerces2 from
+ <a href="http://xerces.apache.org/xerces2-j/">Apache</a>. Knopflerfish
+ includes <a href="../xerces/index.html">xerces</a>, a bundlified version
+ of Xerces 2.10.1. Alongside with xerces is also the 
+ <a href="../xalan/index.html">xalan</a>, a bundlified version of
+ Xalan-Java, version 2.7.1.
+</p>
+<p>
+  There is also the Crimson-XML bundle which is primarily used in
+  older version of Java that does not provide built-in XML, as well as
+  for backwards compatibility.
+</p>
+
+
+  </body>
+</html>
+    
diff --git a/docs/changelog.html b/docs/changelog.html
new file mode 100644
index 0000000..8c2fc9c
--- /dev/null
+++ b/docs/changelog.html
@@ -0,0 +1,485 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "List of changes in Knopflerfish OSGi, version 5.1.0 - "/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Changelog"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Changelog</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+<pre>
+2014-06-13 00:51:04 +0200 (Fri, 13 Jun 2014), revision 4320, cl
+Renamed Application-Icon => Bundle-Icon to map 1:1 with manifest header name
+U   knopflerfish.org/trunk/ant/bundlebuild.xml
+U   knopflerfish.org/trunk/osgi/bundles_opt/desktop_displayers/boing/build.xml
+
+2014-06-12 22:19:49 +0200 (Thu, 12 Jun 2014), revision 4319, cl
+Added support to include content from ${out.dir}/resources. To be used when adding dynamically created resources in e.g. a custom.pre target
+U   knopflerfish.org/trunk/ant/bundlebuild.xml
+
+2014-06-12 17:20:29 +0200 (Thu, 12 Jun 2014), revision 4318, jan
+Fixed some small problems in preparation for next KF release.
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Main.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-12 12:17:11 +0200 (Thu, 12 Jun 2014), revision 4317, cl
+Added bundle icon for Prefs. Changed to use Bundle-Icon for UserAdmin
+U   knopflerfish.org/trunk/osgi/bundles/prefs/bundle.manifest
+A   knopflerfish.org/trunk/osgi/bundles/prefs/resources/
+A   knopflerfish.org/trunk/osgi/bundles/prefs/resources/icon.png
+U   knopflerfish.org/trunk/osgi/bundles/useradmin/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-12 11:50:26 +0200 (Thu, 12 Jun 2014), revision 4316, jan
+Changed RSA key length to avoid restrictions in Java 7 and later. Be more flexible in validation date parsing.
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/build_keystore.xml
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java
+
+2014-06-10 19:39:20 +0200 (Tue, 10 Jun 2014), revision 4315, jan
+Fixed listRescources (SF#178) and added a testcase. Detect dead-lock when doing dynamic import in permssion check (SF#179).
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/Activator.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/BadBundleListener.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/BundleWiringTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/CapabilityTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/FWTestCase.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/FragmentTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/FrameworkTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/NativeCodeTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PackageAdminTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PackageTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PermissionTest.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/PermissionTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/RegListenThread.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/RegServThread.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/RequireBundleTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/ServiceListenerTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/framework_test/src/org/knopflerfish/bundle/framework_test/Util.java
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/BundleClassLoader.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Resolver.java
+U   knopflerfish.org/trunk/osgi/init-tests.xargs.in
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-09 14:43:48 +0200 (Mon, 09 Jun 2014), revision 4314, jan
+Add framework property to put framework in read-only mode.
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FWProps.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Main.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/StartLevelController.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Util.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/Archive.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleArchiveImpl.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleStorageImpl.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoStorage.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-06-09 08:00:49 +0200 (Mon, 09 Jun 2014), revision 4313, jan
+Added framework resource protocol
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/src/org/knopflerfish/bundle/component_test/ComponentTestSuite.java
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+A   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FWResourceURLStreamHandler.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/Main.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/ServiceURLStreamHandlerFactory.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-05-15 17:53:50 +0200 (Thu, 15 May 2014), revision 4312, ekolin
+Fix buidling of the compact framework version when using Java SE 7+.
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+
+2014-04-11 09:58:17 +0200 (Fri, 11 Apr 2014), revision 4311, ekolin
+Make sure that CM-Desktop can be installed by the Desktop Repository when using the Felix Resolver service.
+U   knopflerfish.org/trunk/KnopflerfishEclipseDictionary.txt
+U   knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-04-11 09:07:19 +0200 (Fri, 11 Apr 2014), revision 4310, ekolin
+The eol format was mixed, change to <CR><LF> on all lines
+U   knopflerfish.org/trunk/osgi/template.xargs.in
+
+2014-03-19 13:25:40 +0100 (Wed, 19 Mar 2014), revision 4309, perg
+Made UserAdmin self-contained wrt kf log utility
+U   knopflerfish.org/trunk/osgi/bundles/useradmin/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/useradmin/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-25 16:00:35 +0100 (Tue, 25 Feb 2014), revision 4308, perg
+Changed spelling error sources to source
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2014-02-24 21:52:00 +0100 (Mon, 24 Feb 2014), revision 4307, perg
+Fixed bug in kf_metatype bundle and refactored handling of standardized and proprietary xml formats.
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/bundle/metatype/Activator.java
+A   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/KFLegacyMetaTypeParser.java
+A   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/OsgiMetaTypeXmlParser.java
+U   knopflerfish.org/trunk/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/SystemMetatypeProvider.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-20 13:40:39 +0100 (Thu, 20 Feb 2014), revision 4306, jan
+Fixed an IllegalStateException for factory components.
+U   knopflerfish.org/trunk/osgi/bundles/component/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-14 21:46:06 +0100 (Fri, 14 Feb 2014), revision 4305, jan
+
+U   knopflerfish.org/trunk/osgi/bundles/cm/cm/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java
+U   knopflerfish.org/trunk/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationStore.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-02-05 17:24:41 +0100 (Wed, 05 Feb 2014), revision 4304, ekolin
+Http 4.0.5; more fixes for handling of transfer encoding chunked.
+U   knopflerfish.org/trunk/osgi/bundles/http/http/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-29 13:32:42 +0100 (Wed, 29 Jan 2014), revision 4303, ekolin
+Add missing ignore for generated file.
+_U  knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/resources/
+
+2014-01-29 12:04:57 +0100 (Wed, 29 Jan 2014), revision 4302, ekolin
+Rewrite unchunk code to simple read the number of bytes that the shunk shall contian, ignoring any CR or LF in the data.
+U   knopflerfish.org/trunk/osgi/bundles/http/http/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-29 11:10:48 +0100 (Wed, 29 Jan 2014), revision 4301, perg
+Improvements to Repository Desktop and some minor fixes
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/CapabilityImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/RequirementImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/ResourceImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-29 10:19:30 +0100 (Wed, 29 Jan 2014), revision 4300, ekolin
+Fix problem with decoding of chunked tranfer encoding in the Htt-Server.
+U   knopflerfish.org/trunk/osgi/bundles/http/http/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2014-01-22 10:43:46 +0100 (Wed, 22 Jan 2014), revision 4298, jan
+Fixed bug with ConditionalPermissionUpdate.
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/condpermadmin_test/src/org/knopflerfish/bundle/condpermadmin_test/CondPermAdminTestSuite.java
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java
+U   knopflerfish.org/trunk/osgi/framework/src/org/knopflerfish/framework/validator/SelfSignedValidator.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-12-12 14:55:26 +0100 (Thu, 12 Dec 2013), revision 4296, perg
+Fixed spelling error: source -> sources
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-12-12 13:44:26 +0100 (Thu, 12 Dec 2013), revision 4295, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-12 13:42:21 +0100 (Thu, 12 Dec 2013), revision 4294, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+A   knopflerfish.org/trunk/tools/mvnrepo/mvnrepoindex2html.xsl
+
+2013-12-12 13:20:25 +0100 (Thu, 12 Dec 2013), revision 4293, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-12-12 12:47:13 +0100 (Thu, 12 Dec 2013), revision 4292, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-12-12 12:25:07 +0100 (Thu, 12 Dec 2013), revision 4291, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-12 12:21:20 +0100 (Thu, 12 Dec 2013), revision 4290, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-12 12:14:02 +0100 (Thu, 12 Dec 2013), revision 4289, perg
+Work in progress - support for repoindex
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-12-11 10:32:25 +0100 (Wed, 11 Dec 2013), revision 4288, jan
+Fixed a bug that caused factory components to be falsely created or missed being created when we use target filters. Also added test-cases for this.
+U   knopflerfish.org/trunk/osgi/bundles/component/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/Component.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/DelayedComponent.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/FactoryComponent.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ImmediateComponent.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/Reference.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/build.xml
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/src/org/knopflerfish/bundle/component_test/ComponentTestSuite.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/build.xml
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/bundle.manifest
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/resources/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/resources/service.xml
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentAImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentB1Impl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentB2Impl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/bundle/componentM_test/ComponentCImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/ComponentA.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/ComponentB.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentM_test/src/org/knopflerfish/service/componentM_test/ComponentC.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-12-10 13:45:26 +0100 (Tue, 10 Dec 2013), revision 4287, perg
+Corrected bundle and package versions
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/packageinfo
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-12-09 14:56:08 +0100 (Mon, 09 Dec 2013), revision 4286, perg
+Improved support for Resolver in Repository Manager. Updated Repository console and desktop bundles to use the improved support. Embedded Resolver and Repository APIs in Repository Manager.
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/RepositoryCommandGroup.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryManager.java
+U   knopflerfish.org/trunk/osgi/template.xargs.in
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-11-18 11:26:55 +0100 (Mon, 18 Nov 2013), revision 4285, perg
+Updated w/ Resolver related updates
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-11-16 00:14:56 +0100 (Sat, 16 Nov 2013), revision 4284, perg
+Added commented out line to install a resolver
+U   knopflerfish.org/trunk/osgi/template.xargs.in
+
+2013-11-15 23:44:51 +0100 (Fri, 15 Nov 2013), revision 4283, perg
+Added support for Resolver Service 1.0
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/Activator.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/RepositoryCommandGroup.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/build.xml
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/Activator.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java
+A   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/ResolveContextImpl.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryManager.java
+U   knopflerfish.org/trunk/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/packageinfo
+
+2013-11-15 23:44:02 +0100 (Fri, 15 Nov 2013), revision 4282, perg
+Fix in equals impl
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/CapabilityImpl.java
+
+2013-10-24 14:49:23 +0200 (Thu, 24 Oct 2013), revision 4280, perg
+Updated release notes and set correct bundle version
+U   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/bundle.manifest
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-24 14:34:07 +0200 (Thu, 24 Oct 2013), revision 4279, perg
+Updated changelog.txt
+U   knopflerfish.org/trunk/changelog.txt
+U   knopflerfish.org/trunk/osgi/bundles_opt/junit/osgi_ct_adapter/src/org/knopflerfish/bundle/osgi_ct_adapter/Activator.java
+
+2013-10-24 14:26:15 +0200 (Thu, 24 Oct 2013), revision 4278, perg
+Fixed parsing of Bundle-License
+U   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/bundle.manifest
+
+2013-10-24 14:21:24 +0200 (Thu, 24 Oct 2013), revision 4277, perg
+Fixed parsing of Bundle-License
+U   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/KnopflerfishExtentions.java
+A   knopflerfish.org/trunk/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/Util.java
+
+2013-10-23 18:00:48 +0200 (Wed, 23 Oct 2013), revision 4276, jan
+Fixed a bug that caused problems when adding a CM configuration with a target filter to an unsatisfied component.
+U   knopflerfish.org/trunk/osgi/bundles/component/bundle.manifest
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/Component.java
+U   knopflerfish.org/trunk/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/src/org/knopflerfish/bundle/component_test/ComponentTestSuite.java
+U   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/resources/service.xml
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/bundle/componentC_test/ComponentUImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/bundle/componentC_test/ComponentVImpl.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/service/componentC_test/ComponentU.java
+A   knopflerfish.org/trunk/osgi/bundles_test/regression_tests/component_test/test_target_bundles/componentC_test/src/org/knopflerfish/service/componentC_test/ComponentV.java
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-23 17:50:15 +0200 (Wed, 23 Oct 2013), revision 4275, jan
+Update framework documentation with some 5.0.0 changes.
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+U   knopflerfish.org/trunk/osgi/framework/resources/help.txt
+
+2013-10-23 10:17:09 +0200 (Wed, 23 Oct 2013), revision 4274, ekolin
+Switch to proguard 4.10
+U   knopflerfish.org/trunk/ant/build.xml
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+
+2013-10-22 16:44:48 +0200 (Tue, 22 Oct 2013), revision 4273, ekolin
+Automatically download proguard from maven central.
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+U   knopflerfish.org/trunk/osgi/framework/build.xml
+
+2013-10-22 15:53:19 +0200 (Tue, 22 Oct 2013), revision 4272, ekolin
+Remove reference to OSGiR4v4.3
+U   knopflerfish.org/trunk/osgi/framework/doc/index.html
+
+2013-10-22 13:40:10 +0200 (Tue, 22 Oct 2013), revision 4271, ekolin
+Fix another bundle repository link.
+U   knopflerfish.org/trunk/htdocs/html_templates/template.html
+
+2013-10-22 13:03:21 +0200 (Tue, 22 Oct 2013), revision 4270, ekolin
+Nightly builds should say maintenance release, not major release...
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-22 12:56:46 +0200 (Tue, 22 Oct 2013), revision 4269, ekolin
+Remove some warnings for the ant tasks. Fix link to Makewave logo in nightlybuilds page.
+U   knopflerfish.org/trunk/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleArchives.java
+U   knopflerfish.org/trunk/ant/src/org/knopflerfish/ant/taskdefs/bundle/BundleInfoTask.java
+U   knopflerfish.org/trunk/tools/nightlybuild/snap_index.html.pre
+
+2013-10-21 21:06:51 +0200 (Mon, 21 Oct 2013), revision 4267, jan
+Post release 5.0.0 update
+U   knopflerfish.org/trunk/build.xml
+U   knopflerfish.org/trunk/release_notes.in.html
+
+2013-10-21 21:01:35 +0200 (Mon, 21 Oct 2013), revision 4266, ekolin
+Fix href to the style sheet.
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-10-21 21:01:14 +0200 (Mon, 21 Oct 2013), revision 4265, jan
+update version
+U   knopflerfish.org/trunk/tools/mvnrepo/build.xml
+
+2013-10-21 20:57:21 +0200 (Mon, 21 Oct 2013), revision 4264, ekolin
+Bundle repository link should point to the new repository file.
+U   knopflerfish.org/trunk/htdocs/html_src/release_page.html.in
+
+2013-10-21 19:25:29 +0200 (Mon, 21 Oct 2013), revision 4261, ekolin
+Also search for the repoindex bundle in the direcotry to index.
+U   knopflerfish.org/trunk/ant/bundletasks.xml
+
+2013-10-21 17:29:38 +0200 (Mon, 21 Oct 2013), revision 4260, ekolin
+
+U   knopflerfish.org/trunk/changelog.txt
+
+2013-10-21 17:02:56 +0200 (Mon, 21 Oct 2013), revision 4259, ekolin
+Merge of the KF-5 development branch.
+
+</pre>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/components.html b/docs/components.html
new file mode 100644
index 0000000..cb1b41b
--- /dev/null
+++ b/docs/components.html
@@ -0,0 +1,718 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "The contents of the Knopflerfish OSGi, version 5.1.0 -  distribution"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  What is included in the Knopflerfish distribution"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  What is included in the Knopflerfish distribution</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1>About Knopflerfish 5 - an OSGi R5 distribution</h1>
+
+Knopflerfish 5 (KF5) is designed to be implemented according to
+the <a href="http://www.osgi.org/osgi_technology/download_specs.asp?section=2">
+OSGi R5 specifications</a>.  The distribution includes the
+following components:
+
+<ul>
+  <li>Knopflerfish OSGi framework - OSGi R5 Core Specification
+      implementation</li>
+
+  <li>Knopflerfish OSGi bundles - OSGi R5 Service Compendium
+      implementation</li>
+
+  <li>Knopflerfish components & extras - Knopflerfish bundles and
+      utilities</li>
+
+</ul>
+
+<h2 class="kf">Knopflerfish 5 OSGi Framework - OSGi R5 Core</h2>
+
+<p>
+  The Knopflerfish 5 OSGi framework is implemented in accordance
+  with the OSGi R5 specification.  
+</p>
+<p>
+  The numbering for the OSGi defined components
+  refer to the OSGi specification chapter numbering.
+  The Changes column indicates if the service / API has been updated
+  in R5 compared to R4v4.3  of the Core specification, in which case
+  the new specification chapter version is stated.
+</p>
+<p>
+  <table class="kf">
+    <tr> <th colspan="5">Core Specification -  Knopflerfish OSGi framework</th></tr>
+    <tr>
+      <td class="subhead">Section</td>
+      <td class="subhead">Changes</td>  
+      <td class="subhead">Status</td>  
+      <td class="subhead">R5</td>  
+      <td class="subhead">Description</td>
+    </tr>
+    <tr>
+      <td class="nowrap">2. Security Layer</td>
+      <td class="nowrap">NA</td>
+      <td class="nowrap"> Done  </td>
+      <td class="nowrap"> Full  </td>
+      <td> The OSGi Security Layer based on the Java2 security mechanism.
+      </td>
+    </tr>
+    <tr>
+      <td class="nowrap">3. Module Layer</td>
+      <td class="nowrap">NA</td>
+      <td> Done </td>
+      <td> Full </td>
+      <td>
+	The OSGi solution for Java modularization, a.k.a. OSGi bundles.
+      </td>
+    </tr>
+   
+    <tr>
+      <td>4. Life Cycle Layer </td>
+      <td class="nowrap">NA</td>
+      <td> Done </td>
+      <td> Full </td>
+      <td> Function to control the security and life cycle operations of bundles
+      </td>
+    </tr>
+
+    <tr>
+      <td> 5. Service Layer </td>
+      <td class="nowrap">NA</td>
+      <td> Done </td>
+      <td> Full </td>
+      <td> The Service Layer provides a publish, find and bind model
+           trough the service registry.
+    </tr>
+
+    <tr> <th colspan="5">Core Specification - Knopflerfish Framework API:s</th></tr>
+
+    <tr>
+      <td class="nowrap"> <div class="newkf4">6. Resource API </div></td>
+      <td class="nowrap">New</td>
+      <td class="nowrap"> Done </td>
+      <td> Full
+      <td> 
+	An API for the generic Requirement-Capability model.
+      </td>
+    </tr>
+
+    <tr>
+      <td class="nowrap"> 7. Bundle Wiring API </td>
+      <td class="nowrap">1.1</td>
+      <td class="nowrap"> Done </td>
+      <td> Full
+      <td> 
+	An API that provides access to the internal Framework package
+        sharing mechanism. This API replaces the Package Admin Service
+        from the OSGi R4 v4.2 and earlier.
+      </td>
+    </tr>
+
+    <tr>
+      <td class="nowrap"> 8. Framework Namespaces </td>
+      <td class="nowrap">New</td>
+      <td class="nowrap"> Done </td>
+      <td> Full
+      <td> 
+        A namespace definition for the generic Requirement-Capability model.
+      </td>
+    </tr>
+
+    <tr>
+      <td class="nowrap"> 9. Start Level API </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full
+      <td> 
+        An API to control the relative starting and stopping order of
+        bundles in an OSGi Service Platform. This API replaces the
+        Start Level Service from OSGi R4 v4.2 and earlier.
+      </td>
+    </tr>
+
+    
+    <tr>
+      <td class="nowrap"> 10. Framework API </td>
+      <td class="nowrap">1.7</td>
+      <td class="nowrap"> Done </td>
+      <td> Full
+      <td> 
+        The core API for bundles to interact with the OSGi Framework.
+      </td>
+    </tr>
+
+    <tr> <th colspan="5">Core Specification - Knopflerfish Framework Services</th></tr>
+
+    <tr>
+      <td class="nowrap"> 50. Conditional Permission Admin </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td> 
+      <td> Essentially a security policy and permission system for
+      OSGi bundles. Supersedes Permission Admin</td>
+    </tr>
+
+    <tr>
+      <td class="nowrap"> 51. Permission Admin </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td> 
+      <td> A permission system for bundles</td>
+   </tr>
+
+    <tr>
+      <td class="nowrap"> 52. URL Handler </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td>
+      <td> A mechanism to extend the Java run-time with new URL
+      schemes and content handlers through bundles </td>
+    </tr>
+
+    <tr>
+      <td class="nowrap"> 53. Resolver Hooks </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td>
+      <td> A set of mechanisms for close interaction with the module
+      layer resolving of bundle requirements and capabilities. 	</td>
+    </tr>
+    <tr>
+      <td class="nowrap"> 54. Bundle Hooks </td>
+      <td class="nowrap">1.1</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td>
+      <td> A set of mechanisms for controlling visibility of bundles
+      for other bundles. </td>
+    </tr>
+    <tr>
+      <td class="nowrap"> 55. Service Hooks </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td>
+      <td> A set of mechanisms for close interaction with the Service
+      Registry. </td>
+    </tr>
+    <tr>
+      <td class="nowrap"> 56. Weaving Hooks </td>
+      <td class="nowrap">No</td>
+      <td class="nowrap"> Done </td>
+      <td> Full </td>
+      <td> A set of mechanisms for doing byte code weaving of classes
+      loaded by a Bundle Class Loader.  </td>
+    </tr>
+    <tr>
+      <td> 701. Tracker Specification</td>
+      <td class="nowrap">No</td>
+      <td> Done </td>
+      <td> Full</td>
+      <td> Utility for Bundle and Service tracking</td>
+    </tr>
+  </table>
+</p>
+<br>
+
+
+<h2 class="kf">Knopflerfish 5 OSGi Bundles - OSGi R5 Compendium Services</h2>
+
+<p>
+  The Knopflerfish 5 OSGi Compendium Services are implemented in
+  accordance with the OSGi R5 specification. 
+</p>
+<p>
+  Some of the OSGi Compendium Services are only available
+  in the commercial 
+  <a href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">
+    Knopflerfish Pro 5</a> 
+  version provided by <a href="http://www.makewave.com">Makewave.</a>
+  These services are clearly marked in the table below,
+</p>
+
+<p>
+  The numbering for the OSGi defined components refer to the OSGi
+  specification chapter numbering. The Changes column indicates if the
+  service / API has been updated in R5 compared to R4v4.3 of the
+  Compendium specification, in which case the new specification
+  chapter version is stated.
+</p>
+
+<p>
+  <table class="kf">
+    <tr>
+      <th colspan="5"> <b>Knopflerfish OSGi Bundles - Service Compendium </th>
+    </tr>
+
+    <tr>
+      <td class="subhead">Specification</td>
+      <td class="subhead">Updates</td>  
+      <td class="subhead">Status</td>  
+      <td class="subhead nowrap">R5</td>  
+      <td class="subhead nowrap">Description</td>
+    </tr>
+
+    <tr>
+      <td> 101. Log </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> A message logger for the OSGi Service Platform. </td>
+    </tr>
+
+    <tr>
+      <td> 102. HTTP </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> 
+	HTTP server for the OSGi Service Platform. Supports both
+        static HTML pages, as well as Servlets serving dynamic content
+      </td>
+    </tr>
+
+    <tr>
+      <td> 103. Device Access </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> 
+	The Device Access specification supports the coordination of
+        automatic detection and attachment of existing devices on an
+        OSGi Service Platform.
+      </td>
+    </tr>
+    
+    <tr>
+      <td class="nowrap"> 104. Configuration Admin </td>
+      <td> 1.5 </td>
+      <td> Done </td>
+      <td> Full</td>
+      <td> Service for setting configuration information of OSGi bundles</td>
+    </tr>
+    
+    <tr>
+      <td> 105. Meta Type </td>
+      <td> No </td>
+      <td> Done</td>
+      <td> Full</td>
+      <td> Service that allow bundle developers to describe attribute
+           types in a computer readable form using so-called meta- data.
+      </td>
+    </tr>
+
+    <tr>
+      <td> 106. Preferences </td>
+      <td> No </td>
+      <td> Stable</td>
+      <td> Full</td>
+      <td> 
+      	Service that provides easy to use persistent storage of bundle
+	data. typically user preference.  Knopflerfish Pro includes an
+	enhanced Preferences implementation where Ubicore serves as a
+	remote Backing Store for the Preferences service.
+      </td>
+    </tr>
+
+    <tr>
+      <td> 107. User Admin </td>
+      <td> No </td>
+      <td> Stable</td>
+      <td> Full</td>
+      <td> 
+	Service that a bundle can use for Authentication and Authorization.
+      </td>
+    </tr>
+
+    <tr>
+      <td class="kfpro"> 108. Wire Admin</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro</td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro"> 
+	Wiring of OSGi services inside an OSGi Service Platform. KF Pro only
+      </td>
+    </tr>
+
+    <tr>
+      <td> 109. IO Connector </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td>
+	A connector service that adopts the Java 2 ME
+        javax.microedition.io for OSGi
+      </td>
+    </tr>
+
+    <tr>
+      <td class="kfpro"> 110. Initial Provisioning </td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro</td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro"> Defines how to initially install the
+      management agent in an OSGi Service Platform. KF Pro only</td>
+    </tr>
+
+    <tr>
+      <td class="kfpro"> 111. UPnP Device Service </td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Done KF Pro</td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro"> Service for interaction with UPnP devices and
+	Control Points. KF Pro only</td>
+    </tr>
+
+    <tr>
+      <td> 112. Declarative Services </td>
+      <td> No </td>
+      <td> Done </td>
+      <td> Full</td>
+      <td> Service that defines a declarative model for publishing,
+      finding and binding to OSGi services </td>
+    </tr>
+
+    <tr>
+      <td> 113. Event Admin </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> 
+	Provides an inter-bundle communication mechanism by sending events. 
+      </td>
+    </tr>
+    <tr>
+      <td class="kfpro">114. Deployment Admin</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro </td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro">The Deployment Admin and Device Management
+      Tree (DMT) bundle</td>
+    <tr>
+      <td class="kfpro">115. Auto Configuration</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro </td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro">The auto-configuration resource plug-in for
+      the deployment admin service.</td>
+    </tr>
+    <tr>
+      <td class="kfpro">116. Application Admin</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro </td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro">The Application Admin Service</td>
+    </tr>
+    <tr>
+      <td class="kfpro">117. DMT Admin</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro </td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro">The Device Management Tree (DMT) Admin bundle.</td>
+    </tr>
+    <tr>
+      <td class="kfpro">119. Monitor Admin</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro </td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro"> The Monitor Admin Service. KF Pro only</td>	 
+    </tr>
+    <tr>
+      <td class="kfpro">120. Foreign Application Access</td>
+      <td class="kfpro"> No </td>
+      <td class="kfpro"> Stable KF Pro </td>
+      <td class="kfpro"> Full</td>
+      <td class="kfpro">A midlet container for Application Admin</td>
+    </tr>
+    <tr>
+      <td> 132. Repository </td>
+      <td> New </td>
+      <td> In Progress </td>
+      <td> New</td>
+      <td> Repository is a service to search and retrieve general
+           resources, e.g. OSGi bundles</td>
+    </tr>
+    <tr>
+      <td> 702. XML Parser Service </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> Standardized XML Parser utility</td>
+    </tr>
+    <tr>
+      <td> 703. Position </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> Utility for handling geographic positions</td>
+    </tr>
+
+    <tr>
+      <td> 704. Measurement and State </td>
+      <td> No </td>
+      <td> Stable </td>
+      <td> Full</td>
+      <td> 
+	A utility that provides a consistent way of handling a
+	diverse range of measurements for bundle developers</td>
+    </tr>
+  </table>
+</p>
+
+<br>
+
+<h2 class="kf">Knopflerfish 5 Components - Bundles and Utilities </h2>
+
+The Knopflerfish distribution includes a set of Knopflerfish specific
+bundles and Utilities. Some of the components include, or are based on
+other popular open source components / projects. Knopflerfish has in
+this case typically provided a wrapper class, <em>bundlifying</em> the
+component / project.
+
+<p>
+  <table class="kf">
+    <tr>
+      <th colspan="4"> Knopflerfish Components</th>
+    </tr>
+
+    <tr>
+      <td class="subhead">Component</td>
+      <td class="subhead">Status</td>  
+      <td class="subhead">Includes</td>  
+      <td class="subhead">Description</td>
+    </tr>
+    <tr>
+      <td> Desktop </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	The desktop is a graphical tool for managing a running framework. The
+	desktop can be extended using plug-ins. Support added for new
+        OSGi R5 features.
+      </td>
+    </tr>
+
+    <tr>
+      <td> Log Utilities </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Utility classes for easier logging.
+      </td>
+    </tr>
+    
+    <tr>
+      <td> Misc utilities </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Misc utility classes for text, job and IO handling.
+      </td>
+    </tr>
+    <tr>
+      <td> Console </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	The Console service provides means for command-based tools to 
+	publish their commands. Any bundle can provide commands.
+      </td>
+    </tr>
+    
+    <tr>
+      <td> TTY Console </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Console using stdin/stdout
+      </td>
+    </tr>
+    <tr>
+      <td> Telnet Console </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Console using telnet
+      </td>
+    </tr>
+    <tr>
+      <td> Console - Framework Commands </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> Commands for handling the core Knopflerfish OSGi
+           framework. 
+      </td>
+    </tr>
+    <tr>
+      <td> Console - Log Commands </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Commands for handling the OSGi log
+      </td>
+    </tr>
+    <tr>
+      <td> Console - CM Commands </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Command for handling the Configuration Management data
+      </td>
+    </tr>
+    <tr>
+      <td> Console - SCR Commands </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+	Command for handling and examining Declarative Services
+        components.
+      </td>
+    </tr>
+    <tr>
+      <td> Class Patcher </td>
+      <td> Stable </td>
+      <td> NA</td>
+      <td> 
+        This bundle contains the support for class patching using ASM
+        that was previously implemented in the framework. It is
+        implemented as a Weaving Hooks. The configuration properties
+        remain the same in order to be backward compatible.
+      </td>
+    </tr>
+    <tr>
+      <th colspan="4">Knopflerfish Extras & Wrapper Components</td>
+    </tr>
+    <tr>
+      <td class="subhead">Component</td>
+      <td class="subhead">Status</td>  
+      <td class="subhead">Includes</td>  
+      <td class="subhead">Comment</td>
+    </tr>
+    <tr>
+      <td> Commons Logging </td>
+      <td> Stable </td>
+      <td> Commons Logging</td>
+      <td> 
+	The Commons logging bundle wraps the Apache
+	Commons Logging API over the OSGi log
+      </td>
+    </tr>
+    <tr>
+      <td> Serial port </td>
+      <td> Stable </td>
+      <td> RXTX</td>
+      <td> 
+	Serial ports are supported via the OSGi device model and the 
+	<code>javax.comm</code> API. Implementations from Sun (win32) and
+	RXTX (linux) are used for the included bundles.
+      </td>
+    </tr>
+    <tr>
+      <td> KF Test Suite </td>
+      <td> Stable </td>
+      <td> JUnit</td>
+      <td> 
+	A JUnit based test suite for Knopflerfish bundle & framework
+        testing.
+      </td>
+    </tr>
+  </table>
+</p>
+
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/css/kf_man.css b/docs/css/kf_man.css
new file mode 100644
index 0000000..6aec975
--- /dev/null
+++ b/docs/css/kf_man.css
@@ -0,0 +1,110 @@
+BODY {
+ /* font-size:12px; */
+ font-family: Lucida Grande, Tahoma, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+}
+
+.mainblock {
+  background: #fff;
+  /* font-size:12px; */
+  font-size: 0.8125em;
+}
+
+.manpage {
+ font-family: Lucida Grande, Tahoma, Helvetica, Arial, sans-serif;
+ /* font-size:12px; */
+}
+
+H1.man {
+    font-family: Helvetica, Arial, sans-serif;
+    font-size: 2em;
+    font-weight:bold;
+    margin-left: 0;
+    border-style: none;
+}
+
+H2.man {
+   font-family: Lucida Grande, Verdana, Helvetica, Arial, sans-serif;
+    font-size:	1.3em;
+    font-weight:bold;
+    border-style: solid;
+    color:		#444444;
+    border-style:  solid;
+    border-color:	#ccc;
+    border-width:	1px 0px 1px 0px;
+    background-image: url('../images/shortfadeout_20px.png');
+    background-repeat: repeat-x;
+    padding:		3px 0px 2px 8px;
+    margin: 1.4em 0 0.8em 0;
+}
+
+H3.man  {
+ font-family: Lucida Grande, Verdana, Helvetica, Arial, sans-serif;
+ font-size: 1.1em;
+ font-weight:bold;
+ background:          #fff;  
+ color:		      #000;
+ border-style:        solid;
+ border-color:	#805362;
+ border-width:	0px 0px 0px 0px;
+ padding: 0;
+}
+
+.userdoc_hdr_left {
+  font-weight: bold;		   
+  float:left;
+}
+
+#man_leftmenu A {
+  color: #000;	      
+  text-decoration: none;
+}
+	      
+#man_leftmenu A:hover {
+  color: #805362;	      
+  text-decoration: underline;
+  font-weight:      bold;
+}
+
+.userdoc_hdr_right {
+  font-weight: bold;		   
+  text-align: right;
+}
+
+.abstract {
+  font-style: italic;
+}
+
+table.man {
+    border-width: 1px;
+    border-color: #666666;
+    border-collapse: collapse;
+}
+
+table table.man_inner {
+    border-style: hidden;
+    border-collapse: collapse;
+}
+
+table table.man_inner td {
+    border-style: hidden;
+    padding: 4px;
+}
+
+table.man th {
+    font-size:12px;
+    border-width: 1px;
+    padding: 6px;
+    border-style: solid;
+    border-color: #666666;
+    background-color: #fafff5;
+    color:		#444444;
+}
+
+table.man td {
+    border-width: 1px;
+    padding: 6px;
+    border-style: solid;
+    border-color: #666666;
+    background-color: #ffffff;
+}
diff --git a/docs/css/knopflerfish.css b/docs/css/knopflerfish.css
new file mode 100644
index 0000000..22c40d2
--- /dev/null
+++ b/docs/css/knopflerfish.css
@@ -0,0 +1,449 @@
+
+BODY  {
+  background: #ccc;
+  font-size: 16px;
+}
+
+#main {
+  width: 1000; 
+  background: #fff;
+  border:		1px solid #000;
+  margin: 0px auto;
+  font-family: Lucida Grande, Tahoma, Verdana, Helvetica, sans-serif;
+  font-size: 0.8125em;
+  padding: 0px 0px 0px 0px;
+}
+
+#mainblock {
+  margin-left: 210px; 
+  padding-right: 15px;
+  font-family: "Lucida Grande", Tahoma, Lucida Sans, Verdana, Helvetica, sans-serif;
+  /* font-size: 12.8px;
+  font-size: 10pt;
+  font-size: 0.8em; */
+}
+
+#mainblock_obr {
+  margin: 20px 10px 20px 10px;
+  font-family: Helvetica, sans-serif;
+  font-size: 12px;
+}
+
+#header {
+  background: #0B2229;
+  margin-bottom: 20px;
+  height: 90px;
+  margin: 0px;
+  padding: 0px;
+  border: 0px;
+}
+
+#header_logo {
+  /* padding: 7px 0px 0px 15px; */
+  padding: 7px 0 0 15px;
+  float:left;
+}
+
+#header_centerbox {
+    background: #0B2229;
+    height: 75px;
+    width: 400px;
+    float:left;
+    text-align: center;
+    margin: 0px;
+    border: 0px;
+}
+
+.header_centerinfo_top {
+    font-size: 1em;
+    color: #cccccc;
+    margin: 10px 0px 0px 40px;
+}
+
+.header_centerinfo_bottom {
+    font-size: 1.5em;
+    color: #cccccc;
+    margin: 7px 0px 0px 60px;
+    font-weight: bold;
+}
+    
+#header_rightinfo {
+    background: #0B2229;
+    font-size: 10px;
+    color: #cccccc;
+    padding-top: 10px;
+    padding-right: 20px;
+    text-align: right;
+    margin-left: 0px;
+    height: 65px;
+    border-style: none;
+    margin: 0px;
+    border: 0px;
+}
+
+#header_fade {
+  height: 15px;
+  border: 0px;
+  margin: 0px 0px -4px 0px;
+  margin: 0px;
+  padding:0px;
+  border-style: none;
+  background-image: url('../images/fadeout_15.png');
+  background-size: 15px;
+  background-repeat: repeat-x;
+  clear:both;
+  overflow: hidden; /* To prevent IE to add an extra 1px at the bottom */
+}
+
+
+#leftmenu {
+  margin-left: 10px;
+  width: 180px;
+  float:left;
+  margin-top: 12px;
+  /*  background: #f4d6ea; */
+}
+
+DL.leftmenu2,leftmenu2_last {
+  margin:	6px 0px 6px 0px;	     
+  padding:	6px 0px 6px 0px;
+  border-style: solid;
+  border-color: #802060;
+  border-width: 0px 0px 1px 0px;
+}
+
+DL.leftmenu2_last {
+  border-width: 0px 0px 0px 0px;
+}
+
+DT.leftmenu2 {
+  /* font-family:	Lucida Grande, Helvetica, sans-serif; */
+  /*font-size:	0.8em; */
+  font-weight:	bold;
+  padding:	0px 0px 0px 0px;
+  margin:	0px 0px 0px 0px;
+
+}  
+
+
+DD.leftmenu2  {
+    /* font-family:	 Lucida Grande, Tahoma, Helvetica, sans-serif; */
+  /* font-size:	0.8em; */
+  padding:	0px 0px 0px 12px;
+  margin:	0px 0px 0px 0px;
+  background-repeat: no-repeat;
+  background-position: 0 .5em;
+}
+
+DD.leftmenu3  {
+  font-family:	 Lucida Grande, Tahoma,Helvetica, sans-serif;
+  font-size:	12px;
+  padding:	0px 0px 0px 24px;
+  margin:	0px 0px 0px 0px;
+  background-image: url('/images/slash_small.jpg');
+  background-repeat: no-repeat;
+  background-position: 0 .5em;
+}
+
+DD.leftmenu4  {
+  font-family:	 Lucida Grande, Tahoma,Helvetica, sans-serif;
+  font-size:	12px;
+  padding:	0px 0px 0px 32px;
+  margin:	0px 0px 0px 0px;
+  background-image: url('/images/slash_small.jpg');
+  background-repeat: no-repeat;
+  background-position: 0 .5em;
+}
+
+#footer {
+  clear:both;
+  border-style: solid;
+  border-color: #802060;
+  border-width: 1px 0px 0px 0px;
+  margin:	20px 15px 15px 15px;
+}
+
+#copyright {
+  margin-left: 200px;
+  font-size:10px;
+  color: #000;
+  text-align: right;
+  padding: 5px 10px 0px 0px;
+}	  
+
+H1, H1.kf {
+    font-family: Helvetica Neue, Helvetica, Verdana, Arial, Helvetica, sans-serif;
+    font-size: 2em;
+    font-weight:bold;
+    border-style: solid;
+    border-color: #802060;
+    border-width: 0px 0px 1px 0px;
+    padding-bottom: 2px;
+    margin: 1.4em 0 0.6em 0;
+    color: #444444;
+}
+
+H2, H2.kf, H2.filled  {
+    font-family: Helvetica Neue; Helvetics, Lucida Grande, Verdana, Arial, Helvetica, sans-serif;
+    font-size:	1.6em;
+    font-weight:bold;
+    color: #444444;
+    padding: 0px;
+    margin: 1.4em 0 0.8em 0;
+    margin: 0.8em 0 0.2em 0;
+}
+
+H2.filled  {
+    background-image: url('../images/shortfadeout_20px.png');
+    border-style: solid;
+    border-color:	#ccc;
+    border-width:	1px 0px 1px 0px;
+    background-repeat: repeat-x;
+    padding:	3px 0px 3px 6px;
+}
+    
+/*
+H2 {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size:18px;
+    font-weight:bold;
+    border-style: solid;
+    border-color: #802060;
+    border-width: 0px 0px 2px 0px;
+    padding-bottom: 2px;
+}
+*/
+
+H3  {
+ font-family:  Lucida Grande, Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size:1.1em;
+ font-weight:bold;
+ background:          #805362;  
+ color:		      #ffffff;
+ border-style:        solid;
+ border-style: solid;
+ border-color: #000000;
+ border-width: 1px;
+ padding-top:         2px;
+ padding-bottom:      2px;
+ padding-left:        8px;
+}
+
+
+H3.kf  {
+    font-family: Verdana, Arial, Helvetica, sans-serif;
+    font-size:14px;
+    font-weight:bold;
+    background:          #805362;  
+    color:		      #ffffff;
+    border-style:        solid;
+    border-color: #000000;
+    border-width: 1px;
+    padding-top:         2px;
+    padding-bottom:      2px;
+    padding-left:        8px;
+    color:		#444444;
+    border-style:  solid;
+    border-color:	#ccc #fff #ccc #fff;
+    border-width:	1px;
+    border-width:	1px 0px 1px 0px;
+    background-image: url('../images/shortfadeout_20px.png');
+    background-repeat: repeat-x;
+}
+
+.navigation_enabled
+{
+ text-decoration:	none;
+ color:			#000000;	
+}
+
+.nav2_enabled
+{
+ text-decoration:	none;
+ color:			#ffffff;	
+}
+
+.navigation_enabled:hover {
+ text-decoration:  underline;
+ color:		   #cc3399;
+}
+
+.navigation_disabled
+{
+ text-decoration:  none;
+ font-weight:      bold;
+ color:		   #802060;
+
+}
+
+.navigation_disabled:visited {
+ text-decoration:  none;
+ font-weight:      bold;
+ color:		   #802060;
+}
+
+A.navigation_disabled:hover {
+ text-decoration:  none;
+}
+
+A {
+  color: #802060;
+}
+
+PRE {
+ font-family: Monaco, Courier New, Courier;
+ font-size:12px;
+ color:#000000;
+ text-align:left;
+ font-weight:normal;
+}
+
+PRE.code {
+    border-style: solid;
+    border-color: #ddddff;
+    border-width: 1px;
+    background-color: #f7F7FF;
+    padding: 5px 0px 5px 6px;
+}
+ 
+pre.shell {
+    border-style: solid;
+    border-color: #d0d0d0;
+    border-width: 1px;
+    background-color: #f7f7f7;
+    padding: 5px 0px 5px 6px;
+}
+
+TH {
+ text-align: left;
+ font-family:  Lucida Grande, Tahoma,Helvetica, sans-serif;
+ font-size: 14px;
+}
+
+TH.fancy {
+ text-align: center;
+ font-family:  Lucida Grande, Tahoma,Helvetica, sans-serif;
+ font-size: 12px;
+}
+
+TD {
+  font-family:  Lucida Grande, Tahoma,Helvetica, sans-serif;
+  font-size: 12px;
+  vertical-align: top;
+}
+
+TABLE.fancy {
+  border-collapse: collapse;
+}
+
+TR.fancy {
+  background: #C9C9C9;
+  border-bottom: 2px solid #A3A3A3;
+  border-top: 2px solid #A3A3A3;
+}
+
+TD.fancy {
+  padding: 2px 4px 2px 4px;
+}
+
+TD.fancy_row {
+  background: #C9C9C9;
+  border-bottom: 2px solid #A3A3A3;
+  border-top: 2px solid #A3A3A3;
+}
+
+
+#release_notes dt {
+  font-weight: bold;
+}
+
+#release_notes dd {
+  margin-bottom: 10px;
+}
+
+.release_notes dt {
+  font-weight: bold;
+}
+
+.release_notes dd {
+  margin-bottom: 10px;
+}
+
+.kf dt {
+  font-weight: bold;
+}
+
+.kf dd {
+    margin-bottom: 10px;
+}
+
+table.kf {
+    border-width: 1px;
+    border-color: #666666;
+    border-collapse: collapse;
+    background-color: #ffffff;
+    border-style: solid;
+}
+
+table.kf th {
+    font-weight: bold;
+    font-size:12px;
+    text-align:center;
+    border-width: 1px;
+    padding: 5px;
+    border-style: solid;
+    border-color: #999999;
+    background-color: #dedede;
+}
+
+
+table.kf td {
+    border-style: solid;
+    border-width: 1px;
+    padding: 5px;
+    border-color: #999999;
+    background-color: #ffffff;
+}
+
+table.kf td.subhead {
+    font-weight: bold;
+    background: #eeeeee;
+}
+
+table.kf td.kfpro {
+    color: #888888;
+    background-color: #ffffff;
+    /* background-image: url('../images/knopflerfish_pro.png');*/
+    background-repeat: no-repeat;
+    background-position: center center;
+}
+
+code {
+    font-family: Monaco, Courier;
+    font-size: 0.8125em;
+}
+
+tt {
+    font-family: Monaco, Courier;
+    font-size: 0.8125em;
+}
+
+
+.note_group {
+    margin: 1.5em 0 0.5em 0;
+}
+
+.note_name {
+    font-weight: bold;
+    color:#333333;
+}
+
+.note_item {
+    display: list-item;
+    margin: 0.5em 0 0.5em 2em;
+}
+
+p {
+    margin-top: 0.5em;
+    margin-bottom: 0.5em;
+}
\ No newline at end of file
diff --git a/docs/desktop.html b/docs/desktop.html
new file mode 100644
index 0000000..76ba22a
--- /dev/null
+++ b/docs/desktop.html
@@ -0,0 +1,243 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "The Knopflerfish OSGi Desktop"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  the famous KF Desktop bundle, visualizing the OSGi service platform"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  the famous KF Desktop bundle, visualizing the OSGi service platform</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">The Knopflerfish Desktop</h1>
+
+<div style="align:float;"><a href="images/desktop_info_manifest.gif"><img align=right src="images/desktop_info_manifest_200.png" border=0></a>
+</div>
+
+<p>
+The Knopflerfish OSGi Desktop displays a graphical overview of the OSGi
+framework. Most common operations as install, start, stop and update can
+be performed on bundles using the desktop. Additionally, bundle and service
+detail information is shown, and an experimental "Save deploy archive" is
+included.
+</p>
+
+<p>
+The desktop is a standard OSGi bundle, using Swing. The desktop is primarily
+designed to manage a locally running framework, but can be used to control a
+remote framework, using the optional <a href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles_opt/soap/readme.html">SOAP bundles</a>.
+Consult the description of <a href="remote_howto.html">how to activate the "Remote framework..." menu item</a>.
+</p>
+<p>
+Additionally, the <a href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/http/httpconsole/readme.html">HTTP console</a> or the <a href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/console/consoletelnet/readme.txt">Telnet console</a> bundle can always be used for remote control. Both are available in the <a href="http://www.knopflerfish.org/repo/">KF bundle repository</a>.
+</p>
+
+<p>
+The desktop can be customized using plugin services, see <a href="releases/5.1.0/javadoc/org/knopflerfish/service/desktop/SwingBundleDisplayer.html">SwingBundleDisplayer</a> for details.
+</p>
+
+<p>
+The Desktop bundle can be found in
+<pre>
+  knopflerfish/osgi/bundles/desktop
+</pre>
+
+<p>
+When started, it creates a window with four main areas:
+<dl>
+  <dt>Toolbar
+  <dd>The top toolbar provides quick access to common operations
+    as start/stop/update bundles.
+  <dt>Bundle view
+  <dd>The center bundle view area display all installed bundles
+    and their states. By clicking on bundles in this are,
+    detail information is displayed in the <b>Bundle detail area</b>
+    Four different views a supported internally (new can be installed):
+    <ul>
+      <li><a href="#view_icons">Icons</a> - each bundle is displayed as an icon.
+      <li><a href="#view_details">Details</a> - each bundle is displayed as a table row.
+      <li><a href="#view_spin">Spin</a> - each bundle is displayed in a really cool graphics view.
+      <li><a href="#view_timeline">Time line</a> - each bundle event is displayed in a zoomable time line view.
+    </ul>
+  <dt>Bundle detail area
+  <dd>The rightmost bundle detail area shows detailed
+    information on selected bundles such as:
+   <ul>
+    <li>manifest
+    <li>bundle closure
+    <li>imported/exported services
+    <li>imported/exported packages
+    <li>bundle logs.<br>
+   </ul>
+   New detail pages can be installed run-time using plug-ins.
+
+  <dt>Framework console
+  <dd>The bottom console area allows interaction with the
+    text console. This console acts exactly as the <tt>consoltty</tt> bundle, but does not require a shell or DOS window to run.
+</dl>
+
+
+<a name="#view_icons"></a>
+<h4>Icon view</h4>
+To view the installed bundles as icons, select
+<pre>
+View -> Large Icons
+</pre>
+<img src="images/desktop_icons.gif" border=1 align="left">
+
+<table>
+  <tr>
+    <td><img src="images/bundle_installed.gif"></td>
+    <td>Bundle which has a BundleActivator</td>
+  </tr>
+  <tr>
+    <td><img src="images/bundle_active.gif"></td>
+    <td>Active bundle</td>
+  </tr>
+  <tr>
+    <td><img src="images/lib_installed.gif"></td>
+    <td>"Library" bundle which has no BundleActivator</td>
+  </tr>
+</table>
+
+<br clear="all"/>
+
+<p>
+Bundles can be selected by clicking.
+</p>
+
+<a name="#view_details"></a>
+<h4>Detail list view</h4>
+To view the installed bundles as a detailed list, select
+<pre>
+View -> Details
+</pre>
+<img src="images/desktop_details.gif" border=1>
+<p>
+Bundles can be selected by clicking.
+</p>
+
+
+<a name="#view_spin"></a>
+<h4>Detail spin view</h4>
+To view the installed bundles as graphics, select
+<pre>
+View -> Spin
+</pre>
+<img src="images/desktop_spin.gif" border=1>
+<p>
+Dependencies between bundles and services are shown as connecting
+lines. Not how the console bundle depends on three other bundles
+in the image above.
+<p>
+Bundles can be selected by clicking.
+</p>
+
+<a name="#view_timeline"></a>
+<h4>Detail spin view</h4>
+To view the installed bundles as a time line, select
+<pre>
+View -> Time line
+</pre>
+<img src="images/desktop_timeline.gif" border=1>
+<p>
+Each bundle has a horizontal line, with bundle events marked for each bundle
+<p>
+Bundles can be selected by clicking.
+</p>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/examples/cpa/admin/build.xml b/docs/examples/cpa/admin/build.xml
new file mode 100644
index 0000000..48456ce
--- /dev/null
+++ b/docs/examples/cpa/admin/build.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="cpaexample_admin" default="all">
+
+  <dirname property="proj.dir" file="${ant.file.cpaexample_admin}"/>
+  <import file="${proj.dir}/../../examples_include.xml"/>
+  
+  <!-- Select the kind of bundle(s) to build. -->
+  <property name="bundle.build.api"  value="false"/>
+  <property name="bundle.build.impl" value="true"/>
+  <property name="bundle.build.lib"  value="false"/>
+  <property name="bundle.build.all"  value="false"/>
+
+  <!-- All private code to be included in the bundle must match this pattern.-->
+  <property name="impl.pattern"
+            value="org/knopflerfish/cpaexample/**"/>
+
+
+  <!-- Compile-time dependecies on other bundles in the distribution. -->
+  <!-- The bundle with the highest version that matches against those
+       included in this distribution will be used. -->
+  <path id="bundle.compile.path">
+  </path>
+
+  <import file="${ant.dir}/bundlebuild.xml"/>
+
+</project>
diff --git a/docs/examples/cpa/admin/bundle.manifest b/docs/examples/cpa/admin/bundle.manifest
new file mode 100644
index 0000000..74e51f4
--- /dev/null
+++ b/docs/examples/cpa/admin/bundle.manifest
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-Version: 1.0.0
+Bundle-Name: CPA admin example
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.knopflerfish.cpaexample.admin
+Bundle-Category: example
+Bundle-Description: Condition Permission Admin example
+Bundle-Vendor: Knopflerfish
+Bundle-ContactAddress: http://www.knopflerfish.org
+Bundle-DocURL: http://www.knopflerfish.org/releases/current/docs/bundledoc
+ /index.html
+Bundle-SubversionURL: https://www.knopflerfish.org/svn/knopflerfish.org/trunk
+ /osgi/bundles_examples/cpa/admin/
diff --git a/docs/examples/cpa/admin/src/org/knopflerfish/cpaexample/bundle/admin/AdminActivator.java b/docs/examples/cpa/admin/src/org/knopflerfish/cpaexample/bundle/admin/AdminActivator.java
new file mode 100644
index 0000000..a467ec8
--- /dev/null
+++ b/docs/examples/cpa/admin/src/org/knopflerfish/cpaexample/bundle/admin/AdminActivator.java
@@ -0,0 +1,61 @@
+package org.knopflerfish.cpaexample.bundle.admin;
+
+import java.util.List;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
+
+public class AdminActivator implements BundleActivator {
+  /*
+  // initial version, for tested bundles without local permission
+  private static final String[] ENCODED_PINFO = {
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \"file:jars/*\"] (java.security.AllPermission) } \"allToTrusted\"",
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \"file:/opt/kf/totest/*\"] (org.osgi.framework.PackagePermission \"*\" \"import\") } \"importToTested\""
+  };
+  */
+
+  // final version, for tested bundles that use local permissions
+  private static final String[] ENCODED_PINFO = {
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \"file:jars/*\"] (java.security.AllPermission) } \"allToTrusted\"",
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \"file:/opt/kf/totest/cpaexample_user*\"] (java.security.AllPermission) } \"allToUser\"",
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \"file:/opt/kf/totest/cpaexample_caller*\"] (java.security.AllPermission) } \"allToCaller\""
+  };
+
+  public void start(BundleContext bc) throws BundleException
+  {
+    ServiceReference sRef =
+      bc.getServiceReference(ConditionalPermissionAdmin.class.getName());
+    if (sRef != null) {
+      ConditionalPermissionAdmin cpa =
+        (ConditionalPermissionAdmin) bc.getService(sRef);
+     
+      installPolicies(cpa, ENCODED_PINFO);
+    } else {
+      throw new BundleException("Bundle CPA-test can not start, There is no "
+          + "ConditinalPermissionAdmin service");
+    }
+  }
+
+  public void stop(BundleContext context)
+  {
+  }
+    
+  void installPolicies(ConditionalPermissionAdmin cpa, String[] pInfos) {
+    ConditionalPermissionUpdate cpu = cpa.newConditionalPermissionUpdate();
+    List piList = cpu.getConditionalPermissionInfos();
+    
+    for (int i = 0; i < pInfos.length; i++) {
+      String pInfo = pInfos[i];
+      ConditionalPermissionInfo cpi = cpa.newConditionalPermissionInfo(pInfo);
+      piList.add(cpi);
+    }
+    
+    cpu.commit();
+  }
+  
+}
diff --git a/docs/examples/cpa/build.xml b/docs/examples/cpa/build.xml
new file mode 100644
index 0000000..8353fb4
--- /dev/null
+++ b/docs/examples/cpa/build.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+
+<project name="cpa" default="all">
+
+  <!-- Internal target that calls a specified target in all sub-dirs. -->
+  <target name="doAntBuild">
+    <ant target="${the.target}" dir="admin"/>
+    <ant target="${the.target}" dir="user"/>
+    <ant target="${the.target}" dir="caller"/>
+  </target>
+
+  <target name="all" 
+	  description="Builds all bundles">
+    <antcall target="doAntBuild">
+      <param name="the.target" value="all"/>
+    </antcall>
+
+  </target>
+
+  <target name="clean" 
+	  description="Cleans all bundles">
+    <antcall target="doAntBuild">
+      <param name="the.target" value="clean"/>
+    </antcall>
+  </target>
+  
+  <target name="bundle_doc" 
+	  description="Builds doc for all bundles">
+    <antcall target="doAntBuild">
+      <param name="the.target" value="bundle_doc"/>
+    </antcall>
+  </target>
+
+</project>
diff --git a/docs/examples/cpa/caller/build.xml b/docs/examples/cpa/caller/build.xml
new file mode 100644
index 0000000..9140a40
--- /dev/null
+++ b/docs/examples/cpa/caller/build.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="cpaexample_caller" default="all">
+
+  <dirname property="proj.dir" file="${ant.file.cpaexample_caller}"/>
+  <import file="${proj.dir}/../../examples_include.xml"/>
+  
+  <!-- Select the kind of bundle(s) to build. -->
+  <property name="bundle.build.api"  value="false"/>
+  <property name="bundle.build.impl" value="true"/>
+  <property name="bundle.build.lib"  value="false"/>
+  <property name="bundle.build.all"  value="false"/>
+
+
+  <!-- All private code to be included in the bundle must match this pattern.-->
+  <property name="impl.pattern"
+    value="org/knopflerfish/cpaexample/**"/>
+
+
+  <!-- Compile-time dependecies on other bundles in the distribution. -->
+  <!-- The bundle with the highest version that matches against those
+       included in this distribution will be used. -->
+  <path id="bundle.compile.path">
+    <pathelement location="cpaexample_user_all-N.N.N.jar"/>
+  </path>
+
+  <import file="${ant.dir}/bundlebuild.xml"/>
+
+</project>
diff --git a/docs/examples/cpa/caller/bundle.manifest b/docs/examples/cpa/caller/bundle.manifest
new file mode 100644
index 0000000..f51eb79
--- /dev/null
+++ b/docs/examples/cpa/caller/bundle.manifest
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-Version: 1.0.0
+Bundle-Name: CPA caller example
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.knopflerfish.cpaexample.caller
+Bundle-Category: example
+Bundle-Description: Condition Permission Admin caller example
+Bundle-Vendor: Knopflerfish
+Bundle-ContactAddress: http://www.knopflerfish.org
+Bundle-DocURL: http://www.knopflerfish.org/releases/current/docs/bundledoc
+ /index.html
+Bundle-SubversionURL: https://www.knopflerfish.org/svn/knopflerfish.org/trunk
+ /osgi/bundles_examples/cpa/caller/
diff --git a/docs/examples/cpa/caller/resources/OSGI-INF/permissions.perm b/docs/examples/cpa/caller/resources/OSGI-INF/permissions.perm
new file mode 100644
index 0000000..e75ae17
--- /dev/null
+++ b/docs/examples/cpa/caller/resources/OSGI-INF/permissions.perm
@@ -0,0 +1,3 @@
+(org.osgi.framework.PackagePermission "org.osgi.framework" "import")
+(org.osgi.framework.PackagePermission "com.makewave.cpaexample.service.user" "import")
+(org.osgi.framework.ServicePermission "com.makewave.cpaexample.service.user.UserService" "get")
diff --git a/docs/examples/cpa/caller/src/org/knopflerfish/cpaexample/bundle/caller/CallerActivator.java b/docs/examples/cpa/caller/src/org/knopflerfish/cpaexample/bundle/caller/CallerActivator.java
new file mode 100644
index 0000000..20725bd
--- /dev/null
+++ b/docs/examples/cpa/caller/src/org/knopflerfish/cpaexample/bundle/caller/CallerActivator.java
@@ -0,0 +1,38 @@
+package org.knopflerfish.cpaexample.bundle.caller;
+
+import java.io.IOException;
+
+import org.knopflerfish.cpaexample.service.user.UserService;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+
+public class CallerActivator implements BundleActivator {
+  public void start(BundleContext bc) throws IOException
+  {
+    ServiceReference sRef =
+      bc.getServiceReference(UserService.class.getName());
+    if (sRef != null) {
+      UserService us = (UserService) bc.getService(sRef);
+      if (us != null) {
+        us.login("joek");
+      }
+      bc.ungetService(sRef);
+    }
+  }
+
+  public void stop(BundleContext bc) throws IOException
+  {
+    ServiceReference sRef =
+      bc.getServiceReference(UserService.class.getName());
+    if (sRef != null) {
+      UserService us = (UserService) bc.getService(sRef);
+      if (us != null) {
+        us.logout();
+      }
+      bc.ungetService(sRef);
+    }
+  }
+
+}
diff --git a/docs/examples/cpa/init.xargs b/docs/examples/cpa/init.xargs
new file mode 100644
index 0000000..99c403a
--- /dev/null
+++ b/docs/examples/cpa/init.xargs
@@ -0,0 +1,33 @@
+#
+# Generated from bundles_examples/cpa/init.xargs.in
+# Knopflerfish release 5.1.0
+#
+
+# load common properties
+-xargs props.xargs
+
+# Semicolon seprated list of base URLs for searching (completing)
+# bundle URLs in "-install URL" command line options and in the console.
+-Forg.knopflerfish.gosg.jars=file:jars/;file:examples_jars/
+
+# CPA admin bundle, started before anything else
+-initlevel 1
+-istart cpaexample_admin/cpaexample_admin-1.0.0.jar
+
+-launch
+
+# basic KF bundles
+-initlevel 2
+-install cm/cm_api-5.0.1.jar
+-istart log/log_all-5.0.0.jar
+-istart console/console_all-4.0.1.jar
+-istart consoletty/consoletty-4.0.1.jar
+-istart frameworkcommands/frameworkcommands-4.0.1.jar
+-istart logcommands/logcommands-5.0.0.jar
+
+# bundle to test and test bundle
+-initlevel 3
+-install file:/opt/kf/totest/cpaexample_user/cpaexample_user_all-1.0.0.jar
+-install file:/opt/kf/totest/cpaexample_caller/cpaexample_caller-1.0.0.jar
+
+-startlevel 3
\ No newline at end of file
diff --git a/docs/examples/cpa/init.xargs.in b/docs/examples/cpa/init.xargs.in
new file mode 100644
index 0000000..029920f
--- /dev/null
+++ b/docs/examples/cpa/init.xargs.in
@@ -0,0 +1,33 @@
+#
+# Generated from bundles_examples/cpa/init.xargs.in
+# Knopflerfish release $(VERSION)
+#
+
+# load common properties
+-xargs props.xargs
+
+# Semicolon seprated list of base URLs for searching (completing)
+# bundle URLs in "-install URL" command line options and in the console.
+-Forg.knopflerfish.gosg.jars=file:jars/;file:examples_jars/
+
+# CPA admin bundle, started before anything else
+-initlevel 1
+-istart @cpaexample_admin-N.N.N.jar@
+
+-launch
+
+# basic KF bundles
+-initlevel 2
+-install @cm_api-N.N.N.jar@
+-istart @log_all-N.N.N.jar@
+-istart @console_all-N.N.N.jar@
+-istart @consoletty-N.N.N.jar@
+-istart @frameworkcommands-N.N.N.jar@
+-istart @logcommands-N.N.N.jar@
+
+# bundle to test and test bundle
+-initlevel 3
+-install file:/opt/kf/totest/@cpaexample_user_all-N.N.N.jar@
+-install file:/opt/kf/totest/@cpaexample_caller-N.N.N.jar@
+
+-startlevel 3
\ No newline at end of file
diff --git a/docs/examples/cpa/props.xargs b/docs/examples/cpa/props.xargs
new file mode 100644
index 0000000..bdc1d4e
--- /dev/null
+++ b/docs/examples/cpa/props.xargs
@@ -0,0 +1,13 @@
+# Initial startup verbosity, 0 is low verbosity
+#-Forg.knopflerfish.framework.main.verbosity=0
+
+# Log
+-Forg.knopflerfish.log.level=info
+
+# Security
+-Forg.osgi.framework.security=osgi
+-Forg.knopflerfish.framework.service.permissionadmin=false
+
+# Various debug flags
+-Forg.knopflerfish.framework.debug.errors=true
+-Forg.knopflerfish.framework.debug.permissions=true
diff --git a/docs/examples/cpa/user/build.xml b/docs/examples/cpa/user/build.xml
new file mode 100644
index 0000000..c64d1b3
--- /dev/null
+++ b/docs/examples/cpa/user/build.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="cpaexample_user" default="all">
+
+  <dirname property="proj.dir" file="${ant.file.cpaexample_user}"/>
+  <import file="${proj.dir}/../../examples_include.xml"/>
+  
+  <!-- Select the kind of bundle(s) to build. -->
+  <property name="bundle.build.api"  value="false"/>
+  <property name="bundle.build.impl" value="false"/>
+  <property name="bundle.build.lib"  value="false"/>
+  <property name="bundle.build.all"  value="true"/>
+
+
+  <!-- All private code to be included in the bundle must match this pattern.-->
+  <property name="impl.pattern" value="org/knopflerfish/cpaexample/**"/>
+  <property name="api.pattern"  value="org/knopflerfish/cpaexample/**"/>
+
+
+  <!-- Compile-time dependecies on other bundles in the distribution. -->
+  <!-- The bundle with the highest version that matches against those
+       included in this distribution will be used. -->
+  <path id="bundle.compile.path">
+    <pathelement location="log_api-N.N.N.jar"/>
+  </path>
+
+  <import file="${ant.dir}/bundlebuild.xml"/>
+
+</project>
diff --git a/docs/examples/cpa/user/bundle.manifest b/docs/examples/cpa/user/bundle.manifest
new file mode 100644
index 0000000..c3f6c3c
--- /dev/null
+++ b/docs/examples/cpa/user/bundle.manifest
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-Version: 1.0.0
+Bundle-Name: CPA service example
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.knopflerfish.cpaexample.user
+Bundle-Category: example
+Bundle-Description: Condition Permission Admin service example
+Bundle-Vendor: Knopflerfish
+Bundle-ContactAddress: http://www.knopflerfish.org
+Bundle-DocURL: http://www.knopflerfish.org/releases/current/docs/bundledoc
+ /index.html
+Bundle-SubversionURL: https://www.knopflerfish.org/svn/knopflerfish.org/trunk
+ /osgi/bundles_examples/cpa/user/
diff --git a/docs/examples/cpa/user/resources/OSGI-INF/permissions.perm b/docs/examples/cpa/user/resources/OSGI-INF/permissions.perm
new file mode 100644
index 0000000..74b5cc2
--- /dev/null
+++ b/docs/examples/cpa/user/resources/OSGI-INF/permissions.perm
@@ -0,0 +1,6 @@
+(org.osgi.framework.PackagePermission "org.osgi.framework" "import")
+(org.osgi.framework.PackagePermission "org.osgi.service.log" "import")
+(org.osgi.framework.ServicePermission "org.osgi.service.log.LogService" "get")
+(java.io.FilePermission "/tmp/osgiuser" "read,write,delete")
+(org.osgi.framework.PackagePermission "com.makewave.cpaexample.service.user" "exportonly")
+(org.osgi.framework.ServicePermission "com.makewave.cpaexample.service.user.UserService" "register")
diff --git a/docs/examples/cpa/user/src/org/knopflerfish/cpaexample/service/user/UserService.java b/docs/examples/cpa/user/src/org/knopflerfish/cpaexample/service/user/UserService.java
new file mode 100644
index 0000000..7643a5f
--- /dev/null
+++ b/docs/examples/cpa/user/src/org/knopflerfish/cpaexample/service/user/UserService.java
@@ -0,0 +1,85 @@
+package org.knopflerfish.cpaexample.service.user;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.service.log.LogService;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+
+// Separate activator, interface and implementation classes
+// should be used but to keep the number of source files
+// to a minimum, only one class is used in this example
+public class UserService implements BundleActivator {
+  private static String fileName = "/tmp/osgiuser";
+  
+  private BundleContext bc;
+  
+  public void start(BundleContext bc) throws BundleException
+  {
+    this.bc = bc;
+    bc.registerService(UserService.class.getName(), this, null);
+  }
+
+  public void stop(BundleContext context)
+  {
+  }
+    
+  public void login(final String name) {
+    final File f = new File(fileName);
+
+    AccessController.doPrivileged(new PrivilegedAction() {
+      public Object run() {
+        if (f.exists()) {
+          throw new IllegalStateException("User already logged in");
+        }
+
+        try {
+          OutputStream os = new FileOutputStream(f);
+          os.write(name.getBytes("UTF-8"));
+          os.close();
+          log(LogService.LOG_INFO, "User " + name + " logged in");
+        } catch (IOException ioe) {
+          log(LogService.LOG_WARNING, "Problem logging user in: " + ioe);
+        }
+        return null;
+      }
+    });
+  }
+  
+  public void logout() {
+    final File f = new File(fileName);
+
+    AccessController.doPrivileged(new PrivilegedAction() {
+      public Object run() {
+        if (!f.exists()) {
+          throw new IllegalStateException("No user logged in");
+        }
+    
+        f.delete();
+        log(LogService.LOG_INFO, "User logged out");
+        return null;
+      }
+    });
+  }
+
+  private void log(int level, String message)
+  {
+    ServiceReference sRef = 
+      bc.getServiceReference(LogService.class.getName());
+    if (sRef != null) {
+      LogService log = (LogService) bc.getService(sRef);
+      if (log != null) {
+        log.log(level, message);
+      }
+      bc.ungetService(sRef);
+    }
+  }
+
+}
diff --git a/docs/images/active_overlay.gif b/docs/images/active_overlay.gif
new file mode 100644
index 0000000..c0fc15a
Binary files /dev/null and b/docs/images/active_overlay.gif differ
diff --git a/docs/images/android_app.png b/docs/images/android_app.png
new file mode 100644
index 0000000..0a8c1b8
Binary files /dev/null and b/docs/images/android_app.png differ
diff --git a/docs/images/bundle_active.gif b/docs/images/bundle_active.gif
new file mode 100644
index 0000000..23d826d
Binary files /dev/null and b/docs/images/bundle_active.gif differ
diff --git a/docs/images/bundle_installed.gif b/docs/images/bundle_installed.gif
new file mode 100644
index 0000000..3004e3c
Binary files /dev/null and b/docs/images/bundle_installed.gif differ
diff --git a/docs/images/dalvik_httproot.png b/docs/images/dalvik_httproot.png
new file mode 100644
index 0000000..d6b6303
Binary files /dev/null and b/docs/images/dalvik_httproot.png differ
diff --git a/docs/images/desktop-clip.png b/docs/images/desktop-clip.png
new file mode 100644
index 0000000..d2e2786
Binary files /dev/null and b/docs/images/desktop-clip.png differ
diff --git a/docs/images/desktop1.gif b/docs/images/desktop1.gif
new file mode 100644
index 0000000..de18524
Binary files /dev/null and b/docs/images/desktop1.gif differ
diff --git a/docs/images/desktop1_200.gif b/docs/images/desktop1_200.gif
new file mode 100644
index 0000000..7eb256b
Binary files /dev/null and b/docs/images/desktop1_200.gif differ
diff --git a/docs/images/desktop1_small.gif b/docs/images/desktop1_small.gif
new file mode 100644
index 0000000..01955e5
Binary files /dev/null and b/docs/images/desktop1_small.gif differ
diff --git a/docs/images/desktop_details.gif b/docs/images/desktop_details.gif
new file mode 100644
index 0000000..3169e6d
Binary files /dev/null and b/docs/images/desktop_details.gif differ
diff --git a/docs/images/desktop_details.png b/docs/images/desktop_details.png
new file mode 100644
index 0000000..67731b6
Binary files /dev/null and b/docs/images/desktop_details.png differ
diff --git a/docs/images/desktop_drop_view.gif b/docs/images/desktop_drop_view.gif
new file mode 100644
index 0000000..8f1550b
Binary files /dev/null and b/docs/images/desktop_drop_view.gif differ
diff --git a/docs/images/desktop_drop_view.png b/docs/images/desktop_drop_view.png
new file mode 100644
index 0000000..7bb7ffe
Binary files /dev/null and b/docs/images/desktop_drop_view.png differ
diff --git a/docs/images/desktop_icons.gif b/docs/images/desktop_icons.gif
new file mode 100644
index 0000000..97ead7c
Binary files /dev/null and b/docs/images/desktop_icons.gif differ
diff --git a/docs/images/desktop_info_log.gif b/docs/images/desktop_info_log.gif
new file mode 100644
index 0000000..de0f431
Binary files /dev/null and b/docs/images/desktop_info_log.gif differ
diff --git a/docs/images/desktop_info_log.png b/docs/images/desktop_info_log.png
new file mode 100644
index 0000000..53cabff
Binary files /dev/null and b/docs/images/desktop_info_log.png differ
diff --git a/docs/images/desktop_info_manifest.gif b/docs/images/desktop_info_manifest.gif
new file mode 100644
index 0000000..8760837
Binary files /dev/null and b/docs/images/desktop_info_manifest.gif differ
diff --git a/docs/images/desktop_info_manifest.png b/docs/images/desktop_info_manifest.png
new file mode 100644
index 0000000..9462735
Binary files /dev/null and b/docs/images/desktop_info_manifest.png differ
diff --git a/docs/images/desktop_info_manifest_200.gif b/docs/images/desktop_info_manifest_200.gif
new file mode 100644
index 0000000..78ec019
Binary files /dev/null and b/docs/images/desktop_info_manifest_200.gif differ
diff --git a/docs/images/desktop_info_manifest_200.png b/docs/images/desktop_info_manifest_200.png
new file mode 100644
index 0000000..7657ec2
Binary files /dev/null and b/docs/images/desktop_info_manifest_200.png differ
diff --git a/docs/images/desktop_info_manifest_400.gif b/docs/images/desktop_info_manifest_400.gif
new file mode 100644
index 0000000..4d43d08
Binary files /dev/null and b/docs/images/desktop_info_manifest_400.gif differ
diff --git a/docs/images/desktop_info_manifest_400.png b/docs/images/desktop_info_manifest_400.png
new file mode 100644
index 0000000..bf0bcfa
Binary files /dev/null and b/docs/images/desktop_info_manifest_400.png differ
diff --git a/docs/images/desktop_info_packages.gif b/docs/images/desktop_info_packages.gif
new file mode 100644
index 0000000..e8c456c
Binary files /dev/null and b/docs/images/desktop_info_packages.gif differ
diff --git a/docs/images/desktop_info_packages.png b/docs/images/desktop_info_packages.png
new file mode 100644
index 0000000..626631b
Binary files /dev/null and b/docs/images/desktop_info_packages.png differ
diff --git a/docs/images/desktop_info_services.gif b/docs/images/desktop_info_services.gif
new file mode 100644
index 0000000..0871f39
Binary files /dev/null and b/docs/images/desktop_info_services.gif differ
diff --git a/docs/images/desktop_info_services.png b/docs/images/desktop_info_services.png
new file mode 100644
index 0000000..b6f7790
Binary files /dev/null and b/docs/images/desktop_info_services.png differ
diff --git a/docs/images/desktop_list.gif b/docs/images/desktop_list.gif
new file mode 100644
index 0000000..9c50b86
Binary files /dev/null and b/docs/images/desktop_list.gif differ
diff --git a/docs/images/desktop_on_eclipse.png b/docs/images/desktop_on_eclipse.png
new file mode 100644
index 0000000..c898073
Binary files /dev/null and b/docs/images/desktop_on_eclipse.png differ
diff --git a/docs/images/desktop_open_bundle.gif b/docs/images/desktop_open_bundle.gif
new file mode 100644
index 0000000..54d5eda
Binary files /dev/null and b/docs/images/desktop_open_bundle.gif differ
diff --git a/docs/images/desktop_open_bundle.png b/docs/images/desktop_open_bundle.png
new file mode 100644
index 0000000..20dfd93
Binary files /dev/null and b/docs/images/desktop_open_bundle.png differ
diff --git a/docs/images/desktop_set_startlevel.gif b/docs/images/desktop_set_startlevel.gif
new file mode 100644
index 0000000..812189b
Binary files /dev/null and b/docs/images/desktop_set_startlevel.gif differ
diff --git a/docs/images/desktop_set_startlevel.png b/docs/images/desktop_set_startlevel.png
new file mode 100644
index 0000000..b16c32c
Binary files /dev/null and b/docs/images/desktop_set_startlevel.png differ
diff --git a/docs/images/desktop_setbundle_startlevel.gif b/docs/images/desktop_setbundle_startlevel.gif
new file mode 100644
index 0000000..dc3ae2b
Binary files /dev/null and b/docs/images/desktop_setbundle_startlevel.gif differ
diff --git a/docs/images/desktop_setbundle_startlevel.png b/docs/images/desktop_setbundle_startlevel.png
new file mode 100644
index 0000000..a3782fd
Binary files /dev/null and b/docs/images/desktop_setbundle_startlevel.png differ
diff --git a/docs/images/desktop_spin.gif b/docs/images/desktop_spin.gif
new file mode 100644
index 0000000..28848c6
Binary files /dev/null and b/docs/images/desktop_spin.gif differ
diff --git a/docs/images/desktop_spin.png b/docs/images/desktop_spin.png
new file mode 100644
index 0000000..81f89c7
Binary files /dev/null and b/docs/images/desktop_spin.png differ
diff --git a/docs/images/desktop_timeline.gif b/docs/images/desktop_timeline.gif
new file mode 100644
index 0000000..50e5277
Binary files /dev/null and b/docs/images/desktop_timeline.gif differ
diff --git a/docs/images/desktop_timeline.png b/docs/images/desktop_timeline.png
new file mode 100644
index 0000000..ca55a75
Binary files /dev/null and b/docs/images/desktop_timeline.png differ
diff --git a/docs/images/fadeout_15.png b/docs/images/fadeout_15.png
new file mode 100644
index 0000000..969f69d
Binary files /dev/null and b/docs/images/fadeout_15.png differ
diff --git a/docs/images/install_options.png b/docs/images/install_options.png
new file mode 100644
index 0000000..9be9029
Binary files /dev/null and b/docs/images/install_options.png differ
diff --git a/docs/images/kf300_black.png b/docs/images/kf300_black.png
new file mode 100644
index 0000000..fcbe993
Binary files /dev/null and b/docs/images/kf300_black.png differ
diff --git a/docs/images/knopflerfish-bottom.jpg b/docs/images/knopflerfish-bottom.jpg
new file mode 100644
index 0000000..a6518d3
Binary files /dev/null and b/docs/images/knopflerfish-bottom.jpg differ
diff --git a/docs/images/knopflerfish-small.gif b/docs/images/knopflerfish-small.gif
new file mode 100644
index 0000000..0b45c70
Binary files /dev/null and b/docs/images/knopflerfish-small.gif differ
diff --git a/docs/images/knopflerfish-top.jpg b/docs/images/knopflerfish-top.jpg
new file mode 100644
index 0000000..0d581c2
Binary files /dev/null and b/docs/images/knopflerfish-top.jpg differ
diff --git a/docs/images/knopflerfish.jpg b/docs/images/knopflerfish.jpg
new file mode 100644
index 0000000..a4ccba4
Binary files /dev/null and b/docs/images/knopflerfish.jpg differ
diff --git a/docs/images/knopflerfish4_red400pxl.gif b/docs/images/knopflerfish4_red400pxl.gif
new file mode 100644
index 0000000..92ce872
Binary files /dev/null and b/docs/images/knopflerfish4_red400pxl.gif differ
diff --git a/docs/images/knopflerfish_red120pxl.gif b/docs/images/knopflerfish_red120pxl.gif
new file mode 100644
index 0000000..242095a
Binary files /dev/null and b/docs/images/knopflerfish_red120pxl.gif differ
diff --git a/docs/images/knopflerfish_red140pxl.gif b/docs/images/knopflerfish_red140pxl.gif
new file mode 100644
index 0000000..2148782
Binary files /dev/null and b/docs/images/knopflerfish_red140pxl.gif differ
diff --git a/docs/images/knopflerfish_red200pxl.gif b/docs/images/knopflerfish_red200pxl.gif
new file mode 100644
index 0000000..73b90eb
Binary files /dev/null and b/docs/images/knopflerfish_red200pxl.gif differ
diff --git a/docs/images/knopfleri.gif b/docs/images/knopfleri.gif
new file mode 100644
index 0000000..195ec60
Binary files /dev/null and b/docs/images/knopfleri.gif differ
diff --git a/docs/images/knopfleri.jpg b/docs/images/knopfleri.jpg
new file mode 100644
index 0000000..fdd3f2d
Binary files /dev/null and b/docs/images/knopfleri.jpg differ
diff --git a/docs/images/knopfleri_2.jpg b/docs/images/knopfleri_2.jpg
new file mode 100644
index 0000000..466007e
Binary files /dev/null and b/docs/images/knopfleri_2.jpg differ
diff --git a/docs/images/knopfleri_3.jpg b/docs/images/knopfleri_3.jpg
new file mode 100644
index 0000000..3c33ffc
Binary files /dev/null and b/docs/images/knopfleri_3.jpg differ
diff --git a/docs/images/legend.gif b/docs/images/legend.gif
new file mode 100644
index 0000000..17db139
Binary files /dev/null and b/docs/images/legend.gif differ
diff --git a/docs/images/lib_installed.gif b/docs/images/lib_installed.gif
new file mode 100644
index 0000000..56b90c2
Binary files /dev/null and b/docs/images/lib_installed.gif differ
diff --git a/docs/images/makewave_logo.png b/docs/images/makewave_logo.png
new file mode 100644
index 0000000..9e280f4
Binary files /dev/null and b/docs/images/makewave_logo.png differ
diff --git a/docs/images/makewave_logo_126x16.gif b/docs/images/makewave_logo_126x16.gif
new file mode 100644
index 0000000..b7e76f3
Binary files /dev/null and b/docs/images/makewave_logo_126x16.gif differ
diff --git a/docs/images/mem_256.gif b/docs/images/mem_256.gif
new file mode 100644
index 0000000..4953c0b
Binary files /dev/null and b/docs/images/mem_256.gif differ
diff --git a/docs/images/no_remote_framework.png b/docs/images/no_remote_framework.png
new file mode 100644
index 0000000..26b3a8d
Binary files /dev/null and b/docs/images/no_remote_framework.png differ
diff --git a/docs/images/osgi-fish.jpg b/docs/images/osgi-fish.jpg
new file mode 100644
index 0000000..43e5c62
Binary files /dev/null and b/docs/images/osgi-fish.jpg differ
diff --git a/docs/images/osgi-knopflerfish.gif b/docs/images/osgi-knopflerfish.gif
new file mode 100644
index 0000000..195ec60
Binary files /dev/null and b/docs/images/osgi-knopflerfish.gif differ
diff --git a/docs/images/remote_framework.png b/docs/images/remote_framework.png
new file mode 100644
index 0000000..b68ae67
Binary files /dev/null and b/docs/images/remote_framework.png differ
diff --git a/docs/images/shortfadeout_20px.png b/docs/images/shortfadeout_20px.png
new file mode 100644
index 0000000..52212a9
Binary files /dev/null and b/docs/images/shortfadeout_20px.png differ
diff --git a/docs/images/time_256.gif b/docs/images/time_256.gif
new file mode 100644
index 0000000..76d1eab
Binary files /dev/null and b/docs/images/time_256.gif differ
diff --git a/docs/images/tray.gif b/docs/images/tray.gif
new file mode 100644
index 0000000..6204447
Binary files /dev/null and b/docs/images/tray.gif differ
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..254b93b
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,166 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "The Knopflerfish OSGi, version 5.1.0 -  is an Open Source OSGi Service Platform designed to be compliant with the OSGi R5 specifications"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Open Source OSGi Serivce Platform"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Open Source OSGi Serivce Platform</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_disabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<a name="about_knopflerfish"></a>
+<h1 class="kf">Knopflerfish version 5.1.0 </h1>
+
+This is the documentation for version 5.1.0 of Knopflerfish - OSGi Service Platform. 
+<p>
+Knopflerfish 5 (KF5) is the first release of
+Knopflerfish which is implemented according to the <a
+href="http://www.osgi.org/osgi_technology/download_specs.asp?section=2">
+OSGi R5 specifications</a>.
+</p>
+
+<p>
+  The <a href="components.html">Contents</a> section
+  provides a summary of what is included in the release.
+</p>
+
+<p>
+  The <a href="release_notes.html">Release Notes</a> has the full
+  summary of all changes.
+</p>
+
+<h2 class="kf">About Knopflerfish</h2>
+<a href="http://www.makewave.com">Makewave</a>
+is the maintainer and sponsor of the 
+<a href="http://www.knopflerfish.org">Knopflerfish project</a> and has
+several developers assigned to develop and maintain the Knopflerfish
+OSGi distribution.  
+</p>
+<p>
+The Knopflerfish project's goal is to develop and distribute
+easy to use open source code, build tools and applications, related to
+the OSGi framework. See 
+<a href="http://www.knopflerfish.org/charter_se.html">charter</a>
+for details. 
+</p>
+
+<a name="about_osgi"></a>
+<h2 class="kf">The OSGi Service Platform</h2>
+The <a href="http://www.osgi.org">OSGi Alliance</a>
+specifies the <b>OSGi Service Platform</b>,
+an industry standard Java application platform, allowing multiple
+applications, to securely run in a 
+single JVM. These programs can share resources as data, functionality
+and threads.
+<p>
+  Knopflerfish OSGi is an implementation of the OSGi Specifications.
+</p>
+<p>
+Applications areas for OSGi ranges from use as a service platform on
+embedded devices, to plugin mechanisms for larger programs.
+The initial goal of OSGi was the embedded market, but other uses
+are certainly possible.
+</p>
+
+<p>
+For more information on the OSGi Alliance, see
+<a href="http://www.osgi.org">http://www.osgi.org</a>
+</p>
+
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/installing.html b/docs/installing.html
new file mode 100644
index 0000000..3af8c18
--- /dev/null
+++ b/docs/installing.html
@@ -0,0 +1,177 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Installing Knopflerfish OSGi"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Installing Knopflerfish"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Installing Knopflerfish</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Installing Knopflerfish</h1>
+
+<h2 class="kf">Installation instructions for the complete framework</h2>
+
+<p>
+You need at least <a
+href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java
+1.4</a> to install the framework.
+</p>
+
+The Knopflerfish OSGi framework should be installed by simply
+running the distribution jar file, either by double-clicking on the
+distribution file, or by the command:
+<pre class="shell">
+    > java -jar knopflerfish_osgi_sdk_<i><version></i>.jar
+</pre>
+
+This will open an installation wizard for selection installation
+directory and which components to install.
+<div class="kf">
+ <dl>
+   <dt>OSGi framework runtime files</dt>
+   <dd>The execution environment, including the Knopflerfish OSGi framework and bundles</dd>
+   <dt>Java sources and build environment</dt>
+   <dd>
+     Installs all java source code files and a 
+     <a href="building.html">
+       build system</a> for rebuilding Knopflerfish locally form the supplied source files.
+   </dd>
+   <dt>Knopflerfish Documentation</dt>
+   <dd>The Knopflerfish user and developer documentation.</dd>
+ </dl>
+</div>
+<img src="images/install_options.png">
+
+<p>
+If you don't need the wizard, installation can also be done in batch
+mode, by entering the command:
+
+<pre class="shell">
+    > java -jar knopflerfish_osgi_sdk_<i><version></i>.jar -batch -silent
+</pre>
+
+...or by simply unpacking the jar file manually.
+
+(WinZip is also capable of unpacking .jar files)
+
+<p>
+After successfully installing Knopflerfish you may move on to 
+<a href="running.html">
+  starting the framework.</a>
+
+<a name="download"></a>
+<h2 class="kf">Installation instructions for the tiny, remotely loading framework</h2>
+
+<ol>
+ <li>Unzip the distribution zip file
+ <li>Execute <tt>framework_compact.jar</tt>
+<pre class="shell">
+    > cd knopflerfish.org/osgi
+    > java -jar framework_compact.jar
+</pre>
+
+</ol>
+All bundles defined in <tt>remote-init.xargs</tt> will be loaded over the 
+net. 
+
+<p>
+Please see the <a href="running.html"> next section</a> for setting and configuring Knopflerfish run time options using <tt>.xargs</tt> files.
+</p>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/jars/applicationadmin/applicationadmin_api-4.0.0.html b/docs/jars/applicationadmin/applicationadmin_api-4.0.0.html
new file mode 100644
index 0000000..7296013
--- /dev/null
+++ b/docs/jars/applicationadmin/applicationadmin_api-4.0.0.html
@@ -0,0 +1,215 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>applicationadmin_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>applicationadmin_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/applicationadmin/applicationadmin_api-4.0.0.jar">download</a> (18166 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>applicationadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.applicationadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Application Admin API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/application/package-summary.html">org.osgi.service.application</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/application/package-summary.html">org.osgi.service.application</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td>*</td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:40</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/applicationadmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:applicationadmin:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../applicationadmin/applicationadmin_api-4.0.0.html">applicationadmin_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/application/package-summary.html">org.osgi.service.application</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../applicationadmin/applicationadmin_api-4.0.0.html">applicationadmin_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/application/package-summary.html">org.osgi.service.application</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/src/org/osgi/service/application/ApplicationAdminPermission.java">org/osgi/service/application/ApplicationAdminPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/src/org/osgi/service/application/ApplicationDescriptor.java">org/osgi/service/application/ApplicationDescriptor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/src/org/osgi/service/application/ApplicationException.java">org/osgi/service/application/ApplicationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/src/org/osgi/service/application/ApplicationHandle.java">org/osgi/service/application/ApplicationHandle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/src/org/osgi/service/application/ScheduledApplication.java">org/osgi/service/application/ScheduledApplication.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/applicationadmin/src/org/osgi/service/application/package-info.java">org/osgi/service/application/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/basicdriverlocator/basicdriverlocator-4.0.0.html b/docs/jars/basicdriverlocator/basicdriverlocator-4.0.0.html
new file mode 100644
index 0000000..a20427f
--- /dev/null
+++ b/docs/jars/basicdriverlocator/basicdriverlocator-4.0.0.html
@@ -0,0 +1,202 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>basicdriverlocator-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>basicdriverlocator-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/basicdriverlocator/basicdriverlocator-4.0.0.jar">download</a> (7094 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>basicdriverlocator-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.basicdriverlocator-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Basic device driver locator (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.basicdriverlocator.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:31</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/device/basicdriverlocator</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:basicdriverlocator:4.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/src/org/knopflerfish/bundle/basicdriverlocator/Activator.java">org/knopflerfish/bundle/basicdriverlocator/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/src/org/knopflerfish/bundle/basicdriverlocator/BasicDriverLocator.java">org/knopflerfish/bundle/basicdriverlocator/BasicDriverLocator.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/basicdriverlocator/basicdriverlocator_all-4.0.0.html b/docs/jars/basicdriverlocator/basicdriverlocator_all-4.0.0.html
new file mode 100644
index 0000000..334fff0
--- /dev/null
+++ b/docs/jars/basicdriverlocator/basicdriverlocator_all-4.0.0.html
@@ -0,0 +1,202 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>basicdriverlocator_all-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>basicdriverlocator_all-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/basicdriverlocator/basicdriverlocator_all-4.0.0.jar">download</a> (7077 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>basicdriverlocator</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.basicdriverlocator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Basic device driver locator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.basicdriverlocator.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:31</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/device/basicdriverlocator</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:basicdriverlocator:4.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/src/org/knopflerfish/bundle/basicdriverlocator/Activator.java">org/knopflerfish/bundle/basicdriverlocator/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/basicdriverlocator/src/org/knopflerfish/bundle/basicdriverlocator/BasicDriverLocator.java">org/knopflerfish/bundle/basicdriverlocator/BasicDriverLocator.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/blueprint/blueprint_api-5.0.0.html b/docs/jars/blueprint/blueprint_api-5.0.0.html
new file mode 100644
index 0000000..4e0f5d0
--- /dev/null
+++ b/docs/jars/blueprint/blueprint_api-5.0.0.html
@@ -0,0 +1,347 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>blueprint_api-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>blueprint_api-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/blueprint/blueprint_api-5.0.0.jar">download</a> (17923 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>blueprint-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.blueprint-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Blueprint Container API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/Apache-2.0;link="http://www.apache.org/licenses/LICENSE-2.0";description="Apache License, Version 2.0"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org">http://www.knopflerfish.org</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/container/package-summary.html">org.osgi.service.blueprint.container</a> 1.0.2<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/reflect/package-summary.html">org.osgi.service.blueprint.reflect</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/container/package-summary.html">org.osgi.service.blueprint.container</a> [1.0.2,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/reflect/package-summary.html">org.osgi.service.blueprint.reflect</a> [1.0.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:43</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/blueprint</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:blueprint:5.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/container/package-summary.html">org.osgi.service.blueprint.container</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/reflect/package-summary.html">org.osgi.service.blueprint.reflect</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/container/package-summary.html">org.osgi.service.blueprint.container</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/blueprint/reflect/package-summary.html">org.osgi.service.blueprint.reflect</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/BlueprintContainer.java">org/osgi/service/blueprint/container/BlueprintContainer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/BlueprintEvent.java">org/osgi/service/blueprint/container/BlueprintEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/BlueprintListener.java">org/osgi/service/blueprint/container/BlueprintListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/ComponentDefinitionException.java">org/osgi/service/blueprint/container/ComponentDefinitionException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/Converter.java">org/osgi/service/blueprint/container/Converter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/EventConstants.java">org/osgi/service/blueprint/container/EventConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/NoSuchComponentException.java">org/osgi/service/blueprint/container/NoSuchComponentException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/ReifiedType.java">org/osgi/service/blueprint/container/ReifiedType.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/ServiceUnavailableException.java">org/osgi/service/blueprint/container/ServiceUnavailableException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/container/package-info.java">org/osgi/service/blueprint/container/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/BeanArgument.java">org/osgi/service/blueprint/reflect/BeanArgument.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/BeanMetadata.java">org/osgi/service/blueprint/reflect/BeanMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/BeanProperty.java">org/osgi/service/blueprint/reflect/BeanProperty.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/CollectionMetadata.java">org/osgi/service/blueprint/reflect/CollectionMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ComponentMetadata.java">org/osgi/service/blueprint/reflect/ComponentMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/IdRefMetadata.java">org/osgi/service/blueprint/reflect/IdRefMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/MapEntry.java">org/osgi/service/blueprint/reflect/MapEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/MapMetadata.java">org/osgi/service/blueprint/reflect/MapMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/Metadata.java">org/osgi/service/blueprint/reflect/Metadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/NonNullMetadata.java">org/osgi/service/blueprint/reflect/NonNullMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/NullMetadata.java">org/osgi/service/blueprint/reflect/NullMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/PropsMetadata.java">org/osgi/service/blueprint/reflect/PropsMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/RefMetadata.java">org/osgi/service/blueprint/reflect/RefMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java">org/osgi/service/blueprint/reflect/ReferenceListMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ReferenceListener.java">org/osgi/service/blueprint/reflect/ReferenceListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ReferenceMetadata.java">org/osgi/service/blueprint/reflect/ReferenceMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/RegistrationListener.java">org/osgi/service/blueprint/reflect/RegistrationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ServiceMetadata.java">org/osgi/service/blueprint/reflect/ServiceMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java">org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/Target.java">org/osgi/service/blueprint/reflect/Target.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/ValueMetadata.java">org/osgi/service/blueprint/reflect/ValueMetadata.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/blueprint/src/org/osgi/service/blueprint/reflect/package-info.java">org/osgi/service/blueprint/reflect/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/classpatcher/classpatcher_all-5.0.0.html b/docs/jars/classpatcher/classpatcher_all-5.0.0.html
new file mode 100644
index 0000000..1c8b653
--- /dev/null
+++ b/docs/jars/classpatcher/classpatcher_all-5.0.0.html
@@ -0,0 +1,199 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>classpatcher_all-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>classpatcher_all-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/classpatcher/classpatcher_all-5.0.0.jar">download</a> (63488 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Class Patcher</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.classpatcher</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Implements a WeavingHook to allow patching of classes at load time using ASM</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org">http://www.knopflerfish.org</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.classpatcher.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,asm-3.2.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/hooks/weaving/package-summary.html">org.osgi.framework.hooks.weaving</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.framework.hooks.weaving.WeavingHook"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:32</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/classpatcher</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>framework</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/classpatcher/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/classpatcher/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:classpatcher:5.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/hooks/weaving/package-summary.html">org.osgi.framework.hooks.weaving</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/classpatcher/src/org/knopflerfish/bundle/classpatcher/Activator.java">org/knopflerfish/bundle/classpatcher/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/classpatcher/src/org/knopflerfish/bundle/classpatcher/ClassPatcher.java">org/knopflerfish/bundle/classpatcher/ClassPatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/classpatcher/src/org/knopflerfish/bundle/classpatcher/ClassPatcherWeavingHook.java">org/knopflerfish/bundle/classpatcher/ClassPatcherWeavingHook.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/classpatcher/src/org/knopflerfish/bundle/classpatcher/ClassPatcherWrappers.java">org/knopflerfish/bundle/classpatcher/ClassPatcherWrappers.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/cm/cm-5.0.1.html b/docs/jars/cm/cm-5.0.1.html
new file mode 100644
index 0000000..5e18376
--- /dev/null
+++ b/docs/jars/cm/cm-5.0.1.html
@@ -0,0 +1,332 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>cm-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>cm-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/cm/cm-5.0.1.jar">download</a> (72850 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>cm-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.cm-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Configuration Management Service (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.cm.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> [1.1.0,1.2.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,1.6.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.service.cm.ConfigurationAdmin"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:01</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/cm/cm</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:cm:5.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/Activator.java">org/knopflerfish/bundle/cm/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java">org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationDictionary.java">org/knopflerfish/bundle/cm/ConfigurationDictionary.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationDispatcher.java">org/knopflerfish/bundle/cm/ConfigurationDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationStore.java">org/knopflerfish/bundle/cm/ConfigurationStore.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ListenerEvent.java">org/knopflerfish/bundle/cm/ListenerEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ListenerEventQueue.java">org/knopflerfish/bundle/cm/ListenerEventQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/PluginManager.java">org/knopflerfish/bundle/cm/PluginManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/Update.java">org/knopflerfish/bundle/cm/Update.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/UpdateQueue.java">org/knopflerfish/bundle/cm/UpdateQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/CMDataReader.java">org/knopflerfish/shared/cm/CMDataReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/CMDataWriter.java">org/knopflerfish/shared/cm/CMDataWriter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/DictionaryUtils.java">org/knopflerfish/shared/cm/DictionaryUtils.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/XmlReader.java">org/knopflerfish/shared/cm/XmlReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/Configuration.java">org/osgi/service/cm/Configuration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationAdmin.java">org/osgi/service/cm/ConfigurationAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationEvent.java">org/osgi/service/cm/ConfigurationEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationException.java">org/osgi/service/cm/ConfigurationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationListener.java">org/osgi/service/cm/ConfigurationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationPermission.java">org/osgi/service/cm/ConfigurationPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationPlugin.java">org/osgi/service/cm/ConfigurationPlugin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ManagedService.java">org/osgi/service/cm/ManagedService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ManagedServiceFactory.java">org/osgi/service/cm/ManagedServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/SynchronousConfigurationListener.java">org/osgi/service/cm/SynchronousConfigurationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/package-info.java">org/osgi/service/cm/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/cm/cm_all-5.0.1.html b/docs/jars/cm/cm_all-5.0.1.html
new file mode 100644
index 0000000..04cc8a0
--- /dev/null
+++ b/docs/jars/cm/cm_all-5.0.1.html
@@ -0,0 +1,351 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>cm_all-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>cm_all-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/cm/cm_all-5.0.1.jar">download</a> (84205 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>cm</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.cm</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Configuration Management Service</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.cm.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> 1.1.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> 1.5.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> [1.1.0,1.2.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,1.6.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.service.cm.ConfigurationAdmin"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:01</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/cm/cm</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:cm:5.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/Activator.java">org/knopflerfish/bundle/cm/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java">org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationDictionary.java">org/knopflerfish/bundle/cm/ConfigurationDictionary.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationDispatcher.java">org/knopflerfish/bundle/cm/ConfigurationDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationStore.java">org/knopflerfish/bundle/cm/ConfigurationStore.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ListenerEvent.java">org/knopflerfish/bundle/cm/ListenerEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ListenerEventQueue.java">org/knopflerfish/bundle/cm/ListenerEventQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/PluginManager.java">org/knopflerfish/bundle/cm/PluginManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/Update.java">org/knopflerfish/bundle/cm/Update.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/UpdateQueue.java">org/knopflerfish/bundle/cm/UpdateQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/CMDataReader.java">org/knopflerfish/shared/cm/CMDataReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/CMDataWriter.java">org/knopflerfish/shared/cm/CMDataWriter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/DictionaryUtils.java">org/knopflerfish/shared/cm/DictionaryUtils.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/XmlReader.java">org/knopflerfish/shared/cm/XmlReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/Configuration.java">org/osgi/service/cm/Configuration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationAdmin.java">org/osgi/service/cm/ConfigurationAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationEvent.java">org/osgi/service/cm/ConfigurationEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationException.java">org/osgi/service/cm/ConfigurationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationListener.java">org/osgi/service/cm/ConfigurationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationPermission.java">org/osgi/service/cm/ConfigurationPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationPlugin.java">org/osgi/service/cm/ConfigurationPlugin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ManagedService.java">org/osgi/service/cm/ManagedService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ManagedServiceFactory.java">org/osgi/service/cm/ManagedServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/SynchronousConfigurationListener.java">org/osgi/service/cm/SynchronousConfigurationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/package-info.java">org/osgi/service/cm/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/cm/cm_api-5.0.1.html b/docs/jars/cm/cm_api-5.0.1.html
new file mode 100644
index 0000000..161bbff
--- /dev/null
+++ b/docs/jars/cm/cm_api-5.0.1.html
@@ -0,0 +1,339 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>cm_api-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>cm_api-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/cm/cm_api-5.0.1.jar">download</a> (12318 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>cm-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.cm-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Configuration Management Service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> 1.5.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:01</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/cm/cm</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:cm:5.0.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/Activator.java">org/knopflerfish/bundle/cm/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java">org/knopflerfish/bundle/cm/ConfigurationAdminFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationDictionary.java">org/knopflerfish/bundle/cm/ConfigurationDictionary.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationDispatcher.java">org/knopflerfish/bundle/cm/ConfigurationDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ConfigurationStore.java">org/knopflerfish/bundle/cm/ConfigurationStore.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ListenerEvent.java">org/knopflerfish/bundle/cm/ListenerEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/ListenerEventQueue.java">org/knopflerfish/bundle/cm/ListenerEventQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/PluginManager.java">org/knopflerfish/bundle/cm/PluginManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/Update.java">org/knopflerfish/bundle/cm/Update.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/bundle/cm/UpdateQueue.java">org/knopflerfish/bundle/cm/UpdateQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/CMDataReader.java">org/knopflerfish/shared/cm/CMDataReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/CMDataWriter.java">org/knopflerfish/shared/cm/CMDataWriter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/DictionaryUtils.java">org/knopflerfish/shared/cm/DictionaryUtils.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/knopflerfish/shared/cm/XmlReader.java">org/knopflerfish/shared/cm/XmlReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/Configuration.java">org/osgi/service/cm/Configuration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationAdmin.java">org/osgi/service/cm/ConfigurationAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationEvent.java">org/osgi/service/cm/ConfigurationEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationException.java">org/osgi/service/cm/ConfigurationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationListener.java">org/osgi/service/cm/ConfigurationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationPermission.java">org/osgi/service/cm/ConfigurationPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ConfigurationPlugin.java">org/osgi/service/cm/ConfigurationPlugin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ManagedService.java">org/osgi/service/cm/ManagedService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/ManagedServiceFactory.java">org/osgi/service/cm/ManagedServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/SynchronousConfigurationListener.java">org/osgi/service/cm/SynchronousConfigurationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm/src/org/osgi/service/cm/package-info.java">org/osgi/service/cm/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/cm_cmd/cm_cmd-5.0.1.html b/docs/jars/cm_cmd/cm_cmd-5.0.1.html
new file mode 100644
index 0000000..598a539
--- /dev/null
+++ b/docs/jars/cm_cmd/cm_cmd-5.0.1.html
@@ -0,0 +1,204 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>cm_cmd-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>cm_cmd-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/cm_cmd/cm_cmd-5.0.1.jar">download</a> (23385 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>CM-Commands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.cm_cmd-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Commands for the CM service (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm_cmd/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=cm_cmd/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.cm.commands.impl.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.knopflerfish.service.console.CommandGroup"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:09</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/cm/cm_cmd</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm_cmd/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm_cmd/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:cm_cmd:5.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm_cmd/src/org/knopflerfish/bundle/cm/commands/impl/Activator.java">org/knopflerfish/bundle/cm/commands/impl/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/cm/cm_cmd/src/org/knopflerfish/bundle/cm/commands/impl/CMCommands.java">org/knopflerfish/bundle/cm/commands/impl/CMCommands.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/cm_desktop/cm_desktop-5.0.2.html b/docs/jars/cm_desktop/cm_desktop-5.0.2.html
new file mode 100644
index 0000000..00442e8
--- /dev/null
+++ b/docs/jars/cm_desktop/cm_desktop-5.0.2.html
@@ -0,0 +1,281 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>cm_desktop-5.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>cm_desktop-5.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/cm_desktop/cm_desktop-5.0.2.jar">download</a> (77382 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>CM-Desktop-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.cm_desktop-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>CM desktop plugin (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/readme.html">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/readme.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.desktop.cm.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+javax.swing.event 0.0.0<br>
+javax.swing.filechooser 0.0.0<br>
+javax.swing.table 0.0.0<br>
+javax.swing.text 0.0.0<br>
+javax.swing.text.html 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> [2.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.osgi.service.cm.ConfigurationListener",osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))",osgi.service;objectClass:List<String>="org.osgi.service.metatype.MetaTypeService"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:37</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/metatype/cm_desktop</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:cm_desktop:5.0.2:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a></td></tr>
+<tr><td><a href="../metatype/metatype-4.0.0.html">metatype-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/Activator.java">org/knopflerfish/bundle/desktop/cm/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/CMDisplayer.java">org/knopflerfish/bundle/desktop/cm/CMDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/ControlPanel.java">org/knopflerfish/bundle/desktop/cm/ControlPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/cm/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/FileFilterImpl.java">org/knopflerfish/bundle/desktop/cm/FileFilterImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JCMInfo.java">org/knopflerfish/bundle/desktop/cm/JCMInfo.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JCMProp.java">org/knopflerfish/bundle/desktop/cm/JCMProp.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JCMService.java">org/knopflerfish/bundle/desktop/cm/JCMService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JLabelled.java">org/knopflerfish/bundle/desktop/cm/JLabelled.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JNumber.java">org/knopflerfish/bundle/desktop/cm/JNumber.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JVector.java">org/knopflerfish/bundle/desktop/cm/JVector.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/PropertiesPanel.java">org/knopflerfish/bundle/desktop/cm/PropertiesPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/SystemMetaTypeInformation.java">org/knopflerfish/bundle/desktop/cm/SystemMetaTypeInformation.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/TargetPanel.java">org/knopflerfish/bundle/desktop/cm/TargetPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/Util.java">org/knopflerfish/bundle/desktop/cm/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/cm_desktop/cm_desktop_all-5.0.2.html b/docs/jars/cm_desktop/cm_desktop_all-5.0.2.html
new file mode 100644
index 0000000..bbd92a2
--- /dev/null
+++ b/docs/jars/cm_desktop/cm_desktop_all-5.0.2.html
@@ -0,0 +1,288 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>cm_desktop_all-5.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>cm_desktop_all-5.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/cm_desktop/cm_desktop_all-5.0.2.jar">download</a> (94485 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>CM-Desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.cm_desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>CM desktop plugin</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/readme.html">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/metatype/cm_desktop/readme.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.desktop.cm.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+javax.swing.event 0.0.0<br>
+javax.swing.filechooser 0.0.0<br>
+javax.swing.table 0.0.0<br>
+javax.swing.text 0.0.0<br>
+javax.swing.text.html 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> [2.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.osgi.service.cm.ConfigurationListener",osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))",osgi.service;objectClass:List<String>="org.osgi.service.metatype.MetaTypeService"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:37</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/metatype/cm_desktop</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:cm_desktop:5.0.2</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a></td></tr>
+<tr><td><a href="../metatype/metatype-4.0.0.html">metatype-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/Activator.java">org/knopflerfish/bundle/desktop/cm/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/CMDisplayer.java">org/knopflerfish/bundle/desktop/cm/CMDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/ControlPanel.java">org/knopflerfish/bundle/desktop/cm/ControlPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/cm/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/FileFilterImpl.java">org/knopflerfish/bundle/desktop/cm/FileFilterImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JCMInfo.java">org/knopflerfish/bundle/desktop/cm/JCMInfo.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JCMProp.java">org/knopflerfish/bundle/desktop/cm/JCMProp.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JCMService.java">org/knopflerfish/bundle/desktop/cm/JCMService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JLabelled.java">org/knopflerfish/bundle/desktop/cm/JLabelled.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JNumber.java">org/knopflerfish/bundle/desktop/cm/JNumber.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/JVector.java">org/knopflerfish/bundle/desktop/cm/JVector.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/PropertiesPanel.java">org/knopflerfish/bundle/desktop/cm/PropertiesPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/SystemMetaTypeInformation.java">org/knopflerfish/bundle/desktop/cm/SystemMetaTypeInformation.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/TargetPanel.java">org/knopflerfish/bundle/desktop/cm/TargetPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/cm_desktop/src/org/knopflerfish/bundle/desktop/cm/Util.java">org/knopflerfish/bundle/desktop/cm/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/comm-linux/comm-linux_all-3.0.0.html b/docs/jars/comm-linux/comm-linux_all-3.0.0.html
new file mode 100644
index 0000000..dde29df
--- /dev/null
+++ b/docs/jars/comm-linux/comm-linux_all-3.0.0.html
@@ -0,0 +1,201 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>comm-linux_all-3.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>comm-linux_all-3.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/comm-linux/comm-linux_all-3.0.0.jar">download</a> (119718 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>comm-linux</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.comm-linux</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>3.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Native driver for linux javax.comm using the RXTX library. Note that this bundle is LGPL and contains full source to rxtx</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Piayda/RXTX</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>info.piayda.bundle.comm.linux.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,RXTXcomm.jar,comm.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a> 2.0.0<br>
+javax.comm 2.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a> 2.0.0<br>
+javax.comm 2.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:16</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/comm-linux</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Piayda/Sun</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-NativeCode</td>
+ <td>librxtxParallel.so; librxtxSerial.so ; processor = i386 ; osname = Linux, librxtxParallel.so; librxtxSerial.so ; processor = x86 ; osname = Linux, librxtxParallel.so; librxtxSerial.so ; processor = i386 ; osname = NetBSD</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/comm-linux/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/comm-linux/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:comm-linux:3.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a>, javax.comm</td></tr>
+<tr><td><a href="../comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../rxtxcomm/rxtxcomm_api-2.2.0.pre2.html">rxtxcomm_api-2.2.0.pre2</a></td><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a>, javax.comm</td></tr>
+<tr><td><a href="../comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td>javax.comm</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/comm-linux/src/info/piayda/bundle/comm/linux/Activator.java">info/piayda/bundle/comm/linux/Activator.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/comm-win32/comm-win32_all-3.0.0.html b/docs/jars/comm-win32/comm-win32_all-3.0.0.html
new file mode 100644
index 0000000..bf25900
--- /dev/null
+++ b/docs/jars/comm-win32/comm-win32_all-3.0.0.html
@@ -0,0 +1,198 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>comm-win32_all-3.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>comm-win32_all-3.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/comm-win32/comm-win32_all-3.0.0.jar">download</a> (38820 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>comm-win32</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.comm-win32</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>3.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Native driver for win32 javax.comm using Sun's COMM library</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Sun</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.comm.w32.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,comm.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.comm 2.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.comm 2.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:15</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/comm-win32</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish/Sun</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-NativeCode</td>
+ <td>win32com.dll ; processor = x86 ;osname = Windows NT ; osname = Windows 98 ; osname = Windows 95 ; osname = Windows 2000 ; osname = Windows XP ;osname = Windows Vista</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/comm-win32/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/comm-win32/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:comm-win32:3.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td>javax.comm</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/comm-win32/src/org/knopflerfish/bundle/comm/w32/Activator.java">org/knopflerfish/bundle/comm/w32/Activator.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/command/command_all-0.2.html b/docs/jars/command/command_all-0.2.html
new file mode 100644
index 0000000..a9f9b37
--- /dev/null
+++ b/docs/jars/command/command_all-0.2.html
@@ -0,0 +1,284 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>command_all-0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>command_all-0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/command/command_all-0.2.jar">download</a> (35977 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>command</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.command</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Command Service</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.command.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:21</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/command/command</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:command:0.2</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../command/command_api-0.2.html">command_api-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../command/command_api-0.2.html">command_api-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Activator.java">org/knopflerfish/bundle/command/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProcessorFactory.java">org/knopflerfish/bundle/command/CommandProcessorFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProcessorImpl.java">org/knopflerfish/bundle/command/CommandProcessorImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProviders.java">org/knopflerfish/bundle/command/CommandProviders.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProvidersService.java">org/knopflerfish/bundle/command/CommandProvidersService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProvidersTest.java">org/knopflerfish/bundle/command/CommandProvidersTest.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandSessionImpl.java">org/knopflerfish/bundle/command/CommandSessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/FrameworkConverter.java">org/knopflerfish/bundle/command/FrameworkConverter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/JavaLangConverter.java">org/knopflerfish/bundle/command/JavaLangConverter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Program.java">org/knopflerfish/bundle/command/Program.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Tokenizer.java">org/knopflerfish/bundle/command/Tokenizer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Util.java">org/knopflerfish/bundle/command/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/commands/CommandCommands.java">org/knopflerfish/bundle/command/commands/CommandCommands.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/commands/EchoCmd.java">org/knopflerfish/bundle/command/commands/EchoCmd.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/commands/FrameworkCommands.java">org/knopflerfish/bundle/command/commands/FrameworkCommands.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/CommandProcessor.java">org/osgi/service/command/CommandProcessor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/CommandSession.java">org/osgi/service/command/CommandSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/Converter.java">org/osgi/service/command/Converter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/Function.java">org/osgi/service/command/Function.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/command/command_api-0.2.html b/docs/jars/command/command_api-0.2.html
new file mode 100644
index 0000000..27d0a3d
--- /dev/null
+++ b/docs/jars/command/command_api-0.2.html
@@ -0,0 +1,278 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>command_api-0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>command_api-0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/command/command_api-0.2.jar">download</a> (3052 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>command-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.command-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Command Service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:21</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/command/command</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:command:0.2:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../command/command_api-0.2.html">command_api-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../command/command_api-0.2.html">command_api-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Activator.java">org/knopflerfish/bundle/command/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProcessorFactory.java">org/knopflerfish/bundle/command/CommandProcessorFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProcessorImpl.java">org/knopflerfish/bundle/command/CommandProcessorImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProviders.java">org/knopflerfish/bundle/command/CommandProviders.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProvidersService.java">org/knopflerfish/bundle/command/CommandProvidersService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandProvidersTest.java">org/knopflerfish/bundle/command/CommandProvidersTest.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/CommandSessionImpl.java">org/knopflerfish/bundle/command/CommandSessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/FrameworkConverter.java">org/knopflerfish/bundle/command/FrameworkConverter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/JavaLangConverter.java">org/knopflerfish/bundle/command/JavaLangConverter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Program.java">org/knopflerfish/bundle/command/Program.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Tokenizer.java">org/knopflerfish/bundle/command/Tokenizer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/Util.java">org/knopflerfish/bundle/command/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/commands/CommandCommands.java">org/knopflerfish/bundle/command/commands/CommandCommands.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/commands/EchoCmd.java">org/knopflerfish/bundle/command/commands/EchoCmd.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/knopflerfish/bundle/command/commands/FrameworkCommands.java">org/knopflerfish/bundle/command/commands/FrameworkCommands.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/CommandProcessor.java">org/osgi/service/command/CommandProcessor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/CommandSession.java">org/osgi/service/command/CommandSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/Converter.java">org/osgi/service/command/Converter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/command/src/org/osgi/service/command/Function.java">org/osgi/service/command/Function.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/commandtty/commandtty-4.0.1.html b/docs/jars/commandtty/commandtty-4.0.1.html
new file mode 100644
index 0000000..edee979
--- /dev/null
+++ b/docs/jars/commandtty/commandtty-4.0.1.html
@@ -0,0 +1,198 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>commandtty-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>commandtty-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/commandtty/commandtty-4.0.1.jar">download</a> (8047 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>TTY-Command-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.commandtty-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Command line system console (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.commandtty.CommandTty</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:25</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/command/commandtty</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/commandtty/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/commandtty/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:commandtty:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../command/command_api-0.2.html">command_api-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/command/commandtty/src/org/knopflerfish/bundle/commandtty/CommandTty.java">org/knopflerfish/bundle/commandtty/CommandTty.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/commons-logging/commons-logging_all-2.0.0.kf4-001.html b/docs/jars/commons-logging/commons-logging_all-2.0.0.kf4-001.html
new file mode 100644
index 0000000..b31b21c
--- /dev/null
+++ b/docs/jars/commons-logging/commons-logging_all-2.0.0.kf4-001.html
@@ -0,0 +1,284 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>commons-logging_all-2.0.0.kf4-001.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>commons-logging_all-2.0.0.kf4-001.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/commons-logging/commons-logging_all-2.0.0.kf4-001.jar">download</a> (37649 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Commons-Logging</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.commons-logging</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.0.0.kf4-001</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Apache Commons logging. Publishced under Apache License. See http://www.apache.org/licenses/LICENSE-2.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles_opt/commons-logging/readme.txt">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles_opt/commons-logging/readme.txt</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.commons.logging.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/commons/logging/package-summary.html">org.apache.commons.logging</a> 1.0.3<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> 1.3.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/commons/logging/package-summary.html">org.apache.commons.logging</a> [1.0.3,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:05</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/commons-logging</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish/Apache</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>lib</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:commons-logging:2.0.0.kf4-001</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/commons/logging/package-summary.html">org.apache.commons.logging</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service. [...]
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/commons/logging/package-summary.html">org.apache.commons.logging</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service. [...]
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/Log.java">org/apache/commons/logging/Log.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/LogConfigurationException.java">org/apache/commons/logging/LogConfigurationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/LogFactory.java">org/apache/commons/logging/LogFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/LogSource.java">org/apache/commons/logging/LogSource.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/impl/LogFactoryImpl.java">org/apache/commons/logging/impl/LogFactoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/impl/NoOpLog.java">org/apache/commons/logging/impl/NoOpLog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/apache/commons/logging/impl/SimpleLog.java">org/apache/commons/logging/impl/SimpleLog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/knopflerfish/bundle/commons/logging/Activator.java">org/knopflerfish/bundle/commons/logging/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/knopflerfish/bundle/commons/logging/LogFactoryOSGI.java">org/knopflerfish/bundle/commons/logging/LogFactoryOSGI.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/commons-logging/src/org/knopflerfish/bundle/commons/logging/LogOSGI.java">org/knopflerfish/bundle/commons/logging/LogOSGI.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/component/component_all-5.0.3.html b/docs/jars/component/component_all-5.0.3.html
new file mode 100644
index 0000000..28dfb30
--- /dev/null
+++ b/docs/jars/component/component_all-5.0.3.html
@@ -0,0 +1,343 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>component_all-5.0.3.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>component_all-5.0.3.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/component/component_all-5.0.3.jar">download</a> (78173 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>SCR</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.component</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.3</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Declarative Services SCR</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.component.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> 1.6.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> 1.2.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> [1.2.1,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+org.xmlpull.v1 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.apache.felix.scr.ScrService"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:03</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/component</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:component:5.0.3</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a>, <a target="_top" href="../../javadoc/index.html?o [...]
+<tr><td><a href="../kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td><td>org.xmlpull.v1</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a></td></tr>
+<tr><td><a href="../scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/apache/felix/scr/Component.java">org/apache/felix/scr/Component.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/apache/felix/scr/Reference.java">org/apache/felix/scr/Reference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/apache/felix/scr/ScrService.java">org/apache/felix/scr/ScrService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/Activator.java">org/knopflerfish/bundle/component/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/Component.java">org/knopflerfish/bundle/component/Component.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentConfiguration.java">org/knopflerfish/bundle/component/ComponentConfiguration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentContextImpl.java">org/knopflerfish/bundle/component/ComponentContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentDescription.java">org/knopflerfish/bundle/component/ComponentDescription.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentFactoryImpl.java">org/knopflerfish/bundle/component/ComponentFactoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentInstanceImpl.java">org/knopflerfish/bundle/component/ComponentInstanceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentMethod.java">org/knopflerfish/bundle/component/ComponentMethod.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/DelayedComponent.java">org/knopflerfish/bundle/component/DelayedComponent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/FactoryComponent.java">org/knopflerfish/bundle/component/FactoryComponent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/IllegalXMLException.java">org/knopflerfish/bundle/component/IllegalXMLException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ImmediateComponent.java">org/knopflerfish/bundle/component/ImmediateComponent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/PostponedBind.java">org/knopflerfish/bundle/component/PostponedBind.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/PropertyDictionary.java">org/knopflerfish/bundle/component/PropertyDictionary.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/Reference.java">org/knopflerfish/bundle/component/Reference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceDescription.java">org/knopflerfish/bundle/component/ReferenceDescription.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java">org/knopflerfish/bundle/component/ReferenceListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/SCR.java">org/knopflerfish/bundle/component/SCR.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ScrServiceImpl.java">org/knopflerfish/bundle/component/ScrServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentConstants.java">org/osgi/service/component/ComponentConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentContext.java">org/osgi/service/component/ComponentContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentException.java">org/osgi/service/component/ComponentException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentFactory.java">org/osgi/service/component/ComponentFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentInstance.java">org/osgi/service/component/ComponentInstance.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/package-info.java">org/osgi/service/component/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/component/component_api-5.0.3.html b/docs/jars/component/component_api-5.0.3.html
new file mode 100644
index 0000000..c3bffcd
--- /dev/null
+++ b/docs/jars/component/component_api-5.0.3.html
@@ -0,0 +1,333 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>component_api-5.0.3.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>component_api-5.0.3.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/component/component_api-5.0.3.jar">download</a> (6120 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>SCR-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.component-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.3</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Declarative Services SCR (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> 1.6.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> 1.2.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> [1.2.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:03</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/component</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:component:5.0.3:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a></td></tr>
+<tr><td><a href="../scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/apache/felix/scr/Component.java">org/apache/felix/scr/Component.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/apache/felix/scr/Reference.java">org/apache/felix/scr/Reference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/apache/felix/scr/ScrService.java">org/apache/felix/scr/ScrService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/Activator.java">org/knopflerfish/bundle/component/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/Component.java">org/knopflerfish/bundle/component/Component.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentConfiguration.java">org/knopflerfish/bundle/component/ComponentConfiguration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentContextImpl.java">org/knopflerfish/bundle/component/ComponentContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentDescription.java">org/knopflerfish/bundle/component/ComponentDescription.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentFactoryImpl.java">org/knopflerfish/bundle/component/ComponentFactoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentInstanceImpl.java">org/knopflerfish/bundle/component/ComponentInstanceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ComponentMethod.java">org/knopflerfish/bundle/component/ComponentMethod.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/DelayedComponent.java">org/knopflerfish/bundle/component/DelayedComponent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/FactoryComponent.java">org/knopflerfish/bundle/component/FactoryComponent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/IllegalXMLException.java">org/knopflerfish/bundle/component/IllegalXMLException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ImmediateComponent.java">org/knopflerfish/bundle/component/ImmediateComponent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/PostponedBind.java">org/knopflerfish/bundle/component/PostponedBind.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/PropertyDictionary.java">org/knopflerfish/bundle/component/PropertyDictionary.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/Reference.java">org/knopflerfish/bundle/component/Reference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceDescription.java">org/knopflerfish/bundle/component/ReferenceDescription.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ReferenceListener.java">org/knopflerfish/bundle/component/ReferenceListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/SCR.java">org/knopflerfish/bundle/component/SCR.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/knopflerfish/bundle/component/ScrServiceImpl.java">org/knopflerfish/bundle/component/ScrServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentConstants.java">org/osgi/service/component/ComponentConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentContext.java">org/osgi/service/component/ComponentContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentException.java">org/osgi/service/component/ComponentException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentFactory.java">org/osgi/service/component/ComponentFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/ComponentInstance.java">org/osgi/service/component/ComponentInstance.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/component/src/org/osgi/service/component/package-info.java">org/osgi/service/component/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/component_annotations/component_annotations_api-1.0.0.html b/docs/jars/component_annotations/component_annotations_api-1.0.0.html
new file mode 100644
index 0000000..d0a2026
--- /dev/null
+++ b/docs/jars/component_annotations/component_annotations_api-1.0.0.html
@@ -0,0 +1,233 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>component_annotations_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>component_annotations_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/component_annotations/component_annotations_api-1.0.0.jar">download</a> (7811 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Component Annotations-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.component_annotations-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi specified component annotations (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/component/annotations/package-summary.html">org.osgi.service.component.annotations</a> 1.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/component/annotations/package-summary.html">org.osgi.service.component.annotations</a> [1.2.0,1.3.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:38</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/annotations/component_api</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:component_annotations:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component_annotations/component_annotations_api-1.0.0.html">component_annotations_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/component/annotations/package-summary.html">org.osgi.service.component.annotations</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component_annotations/component_annotations_api-1.0.0.html">component_annotations_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/component/annotations/package-summary.html">org.osgi.service.component.annotations</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/Activate.java">org/osgi/service/component/annotations/Activate.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/Component.java">org/osgi/service/component/annotations/Component.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/ConfigurationPolicy.java">org/osgi/service/component/annotations/ConfigurationPolicy.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/Deactivate.java">org/osgi/service/component/annotations/Deactivate.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/Modified.java">org/osgi/service/component/annotations/Modified.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/Reference.java">org/osgi/service/component/annotations/Reference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/ReferenceCardinality.java">org/osgi/service/component/annotations/ReferenceCardinality.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/ReferencePolicy.java">org/osgi/service/component/annotations/ReferencePolicy.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/ReferencePolicyOption.java">org/osgi/service/component/annotations/ReferencePolicyOption.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/annotations/component_api/src/org/osgi/service/component/annotations/package-info.java">org/osgi/service/component/annotations/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/connectors/connectors-3.0.0.html b/docs/jars/connectors/connectors-3.0.0.html
new file mode 100644
index 0000000..a231c24
--- /dev/null
+++ b/docs/jars/connectors/connectors-3.0.0.html
@@ -0,0 +1,231 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>connectors-3.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>connectors-3.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/connectors/connectors-3.0.0.jar">download</a> (17965 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Connection-Factories-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.connectors-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>3.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi IO http, socket and datagram-receive Connectors (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.connectors.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.microedition.io 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:36</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/io/connectors</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:connectors:3.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../io/io_all-4.0.0.html">io_all-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_api-4.0.0.html">io_api-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/Activator.java">org/knopflerfish/bundle/connectors/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/BaseConnectionFactory.java">org/knopflerfish/bundle/connectors/BaseConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/datagram/DatagramConnectionAdapter.java">org/knopflerfish/bundle/connectors/datagram/DatagramConnectionAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/datagram/DatagramConnectionFactory.java">org/knopflerfish/bundle/connectors/datagram/DatagramConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/datagram/DatagramImpl.java">org/knopflerfish/bundle/connectors/datagram/DatagramImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/http/HttpConnectionAdapter.java">org/knopflerfish/bundle/connectors/http/HttpConnectionAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/http/HttpConnectionFactory.java">org/knopflerfish/bundle/connectors/http/HttpConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/socket/ServerSocketConnectionImpl.java">org/knopflerfish/bundle/connectors/socket/ServerSocketConnectionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/socket/SocketConnectionFactory.java">org/knopflerfish/bundle/connectors/socket/SocketConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/socket/SocketConnectionImpl.java">org/knopflerfish/bundle/connectors/socket/SocketConnectionImpl.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/connectors/connectors_all-3.0.0.html b/docs/jars/connectors/connectors_all-3.0.0.html
new file mode 100644
index 0000000..24aa9ea
--- /dev/null
+++ b/docs/jars/connectors/connectors_all-3.0.0.html
@@ -0,0 +1,231 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>connectors_all-3.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>connectors_all-3.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/connectors/connectors_all-3.0.0.jar">download</a> (17949 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Connection-Factories</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.connectors</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>3.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi IO http, socket and datagram-receive Connectors</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.connectors.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.microedition.io 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:36</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/io/connectors</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:connectors:3.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../io/io_all-4.0.0.html">io_all-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_api-4.0.0.html">io_api-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/Activator.java">org/knopflerfish/bundle/connectors/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/BaseConnectionFactory.java">org/knopflerfish/bundle/connectors/BaseConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/datagram/DatagramConnectionAdapter.java">org/knopflerfish/bundle/connectors/datagram/DatagramConnectionAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/datagram/DatagramConnectionFactory.java">org/knopflerfish/bundle/connectors/datagram/DatagramConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/datagram/DatagramImpl.java">org/knopflerfish/bundle/connectors/datagram/DatagramImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/http/HttpConnectionAdapter.java">org/knopflerfish/bundle/connectors/http/HttpConnectionAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/http/HttpConnectionFactory.java">org/knopflerfish/bundle/connectors/http/HttpConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/socket/ServerSocketConnectionImpl.java">org/knopflerfish/bundle/connectors/socket/ServerSocketConnectionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/socket/SocketConnectionFactory.java">org/knopflerfish/bundle/connectors/socket/SocketConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/connectors/src/org/knopflerfish/bundle/connectors/socket/SocketConnectionImpl.java">org/knopflerfish/bundle/connectors/socket/SocketConnectionImpl.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/console/console-4.0.1.html b/docs/jars/console/console-4.0.1.html
new file mode 100644
index 0000000..916c228
--- /dev/null
+++ b/docs/jars/console/console-4.0.1.html
@@ -0,0 +1,263 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>console-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>console-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/console/console-4.0.1.jar">download</a> (28126 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Console-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.console-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Knopflerfish Console Service (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=console/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=console/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.console.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.0.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:10</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/console</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:console:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Activator.java">org/knopflerfish/bundle/console/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Alias.java">org/knopflerfish/bundle/console/Alias.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Command.java">org/knopflerfish/bundle/console/Command.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/ConsoleServiceImpl.java">org/knopflerfish/bundle/console/ConsoleServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Pipe.java">org/knopflerfish/bundle/console/Pipe.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/ReadThread.java">org/knopflerfish/bundle/console/ReadThread.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/SessionCommandGroup.java">org/knopflerfish/bundle/console/SessionCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/SessionImpl.java">org/knopflerfish/bundle/console/SessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/CommandGroup.java">org/knopflerfish/service/console/CommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/CommandGroupAdapter.java">org/knopflerfish/service/console/CommandGroupAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/ConsoleService.java">org/knopflerfish/service/console/ConsoleService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/Session.java">org/knopflerfish/service/console/Session.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/SessionListener.java">org/knopflerfish/service/console/SessionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/Util.java">org/knopflerfish/service/console/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/console/console_all-4.0.1.html b/docs/jars/console/console_all-4.0.1.html
new file mode 100644
index 0000000..acbcb8e
--- /dev/null
+++ b/docs/jars/console/console_all-4.0.1.html
@@ -0,0 +1,282 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>console_all-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>console_all-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/console/console_all-4.0.1.jar">download</a> (41199 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Console</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.console</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Knopflerfish Console Service</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=console/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=console/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.console.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 2.1.2<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.0.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:10</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/console</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:console:4.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Activator.java">org/knopflerfish/bundle/console/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Alias.java">org/knopflerfish/bundle/console/Alias.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Command.java">org/knopflerfish/bundle/console/Command.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/ConsoleServiceImpl.java">org/knopflerfish/bundle/console/ConsoleServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Pipe.java">org/knopflerfish/bundle/console/Pipe.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/ReadThread.java">org/knopflerfish/bundle/console/ReadThread.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/SessionCommandGroup.java">org/knopflerfish/bundle/console/SessionCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/SessionImpl.java">org/knopflerfish/bundle/console/SessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/CommandGroup.java">org/knopflerfish/service/console/CommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/CommandGroupAdapter.java">org/knopflerfish/service/console/CommandGroupAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/ConsoleService.java">org/knopflerfish/service/console/ConsoleService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/Session.java">org/knopflerfish/service/console/Session.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/SessionListener.java">org/knopflerfish/service/console/SessionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/Util.java">org/knopflerfish/service/console/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/console/console_api-4.0.1.html b/docs/jars/console/console_api-4.0.1.html
new file mode 100644
index 0000000..31c09bf
--- /dev/null
+++ b/docs/jars/console/console_api-4.0.1.html
@@ -0,0 +1,278 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>console_api-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>console_api-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/console/console_api-4.0.1.jar">download</a> (14067 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Console-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.console-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Knopflerfish Console Service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=console/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=console/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 2.1.2<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.2,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:10</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/console</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:console:4.0.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Activator.java">org/knopflerfish/bundle/console/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Alias.java">org/knopflerfish/bundle/console/Alias.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Command.java">org/knopflerfish/bundle/console/Command.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/ConsoleServiceImpl.java">org/knopflerfish/bundle/console/ConsoleServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/Pipe.java">org/knopflerfish/bundle/console/Pipe.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/ReadThread.java">org/knopflerfish/bundle/console/ReadThread.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/SessionCommandGroup.java">org/knopflerfish/bundle/console/SessionCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/bundle/console/SessionImpl.java">org/knopflerfish/bundle/console/SessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/CommandGroup.java">org/knopflerfish/service/console/CommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/CommandGroupAdapter.java">org/knopflerfish/service/console/CommandGroupAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/ConsoleService.java">org/knopflerfish/service/console/ConsoleService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/Session.java">org/knopflerfish/service/console/Session.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/SessionListener.java">org/knopflerfish/service/console/SessionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console/src/org/knopflerfish/service/console/Util.java">org/knopflerfish/service/console/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/console2command/console2command-2.0.0.html b/docs/jars/console2command/console2command-2.0.0.html
new file mode 100644
index 0000000..e4e8aac
--- /dev/null
+++ b/docs/jars/console2command/console2command-2.0.0.html
@@ -0,0 +1,208 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>console2command-2.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>console2command-2.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/console2command/console2command-2.0.0.jar">download</a> (6842 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Console2Command-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.console2command-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Wrapper for KF console commands to RFC147 commands (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.console2command.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:18</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/console2command</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console2command/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console2command/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:console2command:2.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../command/command_api-0.2.html">command_api-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console2command/src/org/knopflerfish/bundle/console2command/Activator.java">org/knopflerfish/bundle/console2command/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console2command/src/org/knopflerfish/bundle/console2command/ConsoleWrapper.java">org/knopflerfish/bundle/console2command/ConsoleWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/console2command/src/org/knopflerfish/bundle/console2command/Dispatcher.java">org/knopflerfish/bundle/console2command/Dispatcher.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/consoletcp/consoletcp-5.0.0.html b/docs/jars/consoletcp/consoletcp-5.0.0.html
new file mode 100644
index 0000000..143c327
--- /dev/null
+++ b/docs/jars/consoletcp/consoletcp-5.0.0.html
@@ -0,0 +1,201 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>consoletcp-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>consoletcp-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/consoletcp/consoletcp-5.0.0.jar">download</a> (13882 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>TCP-Console-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.consoletcp-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Console Service Server accepting TCP connection. (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.consoletcp.ConsoleTcp</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.service.cm.ManagedService";service.pid="org.knopflerfish.bundle.consoletcp.ConsoleTcp"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:16</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/consoletcp</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletcp/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletcp/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:consoletcp:5.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletcp/src/org/knopflerfish/bundle/consoletcp/ConsoleTcp.java">org/knopflerfish/bundle/consoletcp/ConsoleTcp.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/consoletcp/consoletcp_all-5.0.0.html b/docs/jars/consoletcp/consoletcp_all-5.0.0.html
new file mode 100644
index 0000000..087226f
--- /dev/null
+++ b/docs/jars/consoletcp/consoletcp_all-5.0.0.html
@@ -0,0 +1,201 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>consoletcp_all-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>consoletcp_all-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/consoletcp/consoletcp_all-5.0.0.jar">download</a> (13865 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>TCP-Console</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.consoletcp</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Console Service Server accepting TCP connection.</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.consoletcp.ConsoleTcp</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.service.cm.ManagedService";service.pid="org.knopflerfish.bundle.consoletcp.ConsoleTcp"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:16</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/consoletcp</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletcp/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletcp/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:consoletcp:5.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletcp/src/org/knopflerfish/bundle/consoletcp/ConsoleTcp.java">org/knopflerfish/bundle/consoletcp/ConsoleTcp.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/consoletelnet/consoletelnet-4.0.1.html b/docs/jars/consoletelnet/consoletelnet-4.0.1.html
new file mode 100644
index 0000000..ce824de
--- /dev/null
+++ b/docs/jars/consoletelnet/consoletelnet-4.0.1.html
@@ -0,0 +1,273 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>consoletelnet-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>consoletelnet-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/consoletelnet/consoletelnet-4.0.1.jar">download</a> (33390 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Telnet-Console-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.consoletelnet-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Console service server accepting telnet connections. (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=consoletelnet/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=consoletelnet/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.consoletelnet.TelnetServer</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:17</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/consoletelnet</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:consoletelnet:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.userad [...]
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TCC.java">org/knopflerfish/bundle/consoletelnet/TCC.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetCommand.java">org/knopflerfish/bundle/consoletelnet/TelnetCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetCommandEcho.java">org/knopflerfish/bundle/consoletelnet/TelnetCommandEcho.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetCommandStatus.java">org/knopflerfish/bundle/consoletelnet/TelnetCommandStatus.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetCommandSupga.java">org/knopflerfish/bundle/consoletelnet/TelnetCommandSupga.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetConfig.java">org/knopflerfish/bundle/consoletelnet/TelnetConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetInputStream.java">org/knopflerfish/bundle/consoletelnet/TelnetInputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetLogin.java">org/knopflerfish/bundle/consoletelnet/TelnetLogin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetOutputStream.java">org/knopflerfish/bundle/consoletelnet/TelnetOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetPrintWriter.java">org/knopflerfish/bundle/consoletelnet/TelnetPrintWriter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetReader.java">org/knopflerfish/bundle/consoletelnet/TelnetReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetServer.java">org/knopflerfish/bundle/consoletelnet/TelnetServer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetSession.java">org/knopflerfish/bundle/consoletelnet/TelnetSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletelnet/src/org/knopflerfish/bundle/consoletelnet/TelnetStateMachine.java">org/knopflerfish/bundle/consoletelnet/TelnetStateMachine.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/consoletty/consoletty-4.0.1.html b/docs/jars/consoletty/consoletty-4.0.1.html
new file mode 100644
index 0000000..0255aec
--- /dev/null
+++ b/docs/jars/consoletty/consoletty-4.0.1.html
@@ -0,0 +1,202 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>consoletty-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>consoletty-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/consoletty/consoletty-4.0.1.jar">download</a> (8230 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>TTY-Console-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.consoletty-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Console Service Command Line Console (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.consoletty.ConsoleTty</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:15</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/console/consoletty</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/bundles/console/consoletty/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/bundles/console/consoletty/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:consoletty:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/console/consoletty/src/org/knopflerfish/bundle/consoletty/ConsoleTty.java">org/knopflerfish/bundle/consoletty/ConsoleTty.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/coordinator/coordinator_api-1.0.0.html b/docs/jars/coordinator/coordinator_api-1.0.0.html
new file mode 100644
index 0000000..2bae773
--- /dev/null
+++ b/docs/jars/coordinator/coordinator_api-1.0.0.html
@@ -0,0 +1,215 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>coordinator_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>coordinator_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/coordinator/coordinator_api-1.0.0.jar">download</a> (13214 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Coordinator-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.coordinator-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi specified coordinator service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/coordinator/package-summary.html">org.osgi.service.coordinator</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/coordinator/package-summary.html">org.osgi.service.coordinator</a> [1.0.1,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:47</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/coordinator</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:coordinator:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../coordinator/coordinator_api-1.0.0.html">coordinator_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/coordinator/package-summary.html">org.osgi.service.coordinator</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../coordinator/coordinator_api-1.0.0.html">coordinator_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/coordinator/package-summary.html">org.osgi.service.coordinator</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/src/org/osgi/service/coordinator/Coordination.java">org/osgi/service/coordinator/Coordination.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/src/org/osgi/service/coordinator/CoordinationException.java">org/osgi/service/coordinator/CoordinationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/src/org/osgi/service/coordinator/CoordinationPermission.java">org/osgi/service/coordinator/CoordinationPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/src/org/osgi/service/coordinator/Coordinator.java">org/osgi/service/coordinator/Coordinator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/src/org/osgi/service/coordinator/Participant.java">org/osgi/service/coordinator/Participant.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/coordinator/src/org/osgi/service/coordinator/package-info.java">org/osgi/service/coordinator/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/crimson/crimson-2.1.0.kf4-001.html b/docs/jars/crimson/crimson-2.1.0.kf4-001.html
new file mode 100644
index 0000000..7a57c73
--- /dev/null
+++ b/docs/jars/crimson/crimson-2.1.0.kf4-001.html
@@ -0,0 +1,205 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>crimson-2.1.0.kf4-001.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>crimson-2.1.0.kf4-001.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/crimson/crimson-2.1.0.kf4-001.jar">download</a> (196914 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Crimson-XML</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.crimson</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.1.0.kf4-001</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The Crimson XML parser</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Apache/Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=crimson/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=crimson/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.osgi.util.xml.XMLParserActivator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,crimson.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.xml.parsers 1.2.0<br>
+org.apache.crimson.jaxp 0.0.0<br>
+org.w3c.dom 2.0.0<br>
+org.xml.sax 2.0.0<br>
+org.xml.sax.ext 1.0.0<br>
+org.xml.sax.helpers 2.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.xml.parsers 0.0.0<br>
+org.apache.crimson.jaxp 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+org.w3c.dom 0.0.0<br>
+org.xml.sax 0.0.0<br>
+org.xml.sax.ext 0.0.0<br>
+org.xml.sax.helpers 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:06</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/xml/crimson</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>lib</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/crimson/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/crimson/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:crimson:2.1.0.kf4-001</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td>javax.xml.parsers, org.apache.crimson.jaxp, org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml.parsers, org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td>javax.xml.parsers, org.apache.crimson.jaxp, org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td>javax.xml.parsers, org.w3c.dom</td></tr>
+<tr><td><a href="../xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td>org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../xml/xml-4.0.0.html">xml-4.0.0</a></td><td>javax.xml.parsers</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/crimson/src/javax/xml/parsers/FactoryFinder.java">javax/xml/parsers/FactoryFinder.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/crimson/src/org/osgi/util/xml/XMLParserActivator.java">org/osgi/util/xml/XMLParserActivator.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/deploymentadmin/deploymentadmin_api-4.0.0.html b/docs/jars/deploymentadmin/deploymentadmin_api-4.0.0.html
new file mode 100644
index 0000000..5336bf3
--- /dev/null
+++ b/docs/jars/deploymentadmin/deploymentadmin_api-4.0.0.html
@@ -0,0 +1,242 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>deploymentadmin_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>deploymentadmin_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/deploymentadmin/deploymentadmin_api-4.0.0.jar">download</a> (11683 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>deploymentadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.deploymentadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Deployment Admin API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/package-summary.html">org.osgi.service.deploymentadmin</a> 1.1.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/spi/package-summary.html">org.osgi.service.deploymentadmin.spi</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/package-summary.html">org.osgi.service.deploymentadmin</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/spi/package-summary.html">org.osgi.service.deploymentadmin.spi</a> [1.0.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td>*</td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:49</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/deploymentadmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:deploymentadmin:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/package-summary.html">org.osgi.service.deploymentadmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/spi/package-summary.html">org.osgi.service.deploymentadmin.spi</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/package-summary.html">org.osgi.service.deploymentadmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/deploymentadmin/spi/package-summary.html">org.osgi.service.deploymentadmin.spi</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/BundleInfo.java">org/osgi/service/deploymentadmin/BundleInfo.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentAdmin.java">org/osgi/service/deploymentadmin/DeploymentAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java">org/osgi/service/deploymentadmin/DeploymentAdminPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentException.java">org/osgi/service/deploymentadmin/DeploymentException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentPackage.java">org/osgi/service/deploymentadmin/DeploymentPackage.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/package-info.java">org/osgi/service/deploymentadmin/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java">org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/spi/DeploymentSession.java">org/osgi/service/deploymentadmin/spi/DeploymentSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java">org/osgi/service/deploymentadmin/spi/ResourceProcessor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java">org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/deploymentadmin/src/org/osgi/service/deploymentadmin/spi/package-info.java">org/osgi/service/deploymentadmin/spi/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/desktop/desktop-5.0.1.html b/docs/jars/desktop/desktop-5.0.1.html
new file mode 100644
index 0000000..de0932f
--- /dev/null
+++ b/docs/jars/desktop/desktop-5.0.1.html
@@ -0,0 +1,825 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>desktop-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>desktop-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/desktop/desktop-5.0.1.jar">download</a> (782279 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Desktop-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.desktop-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Swing framework desktop (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=desktop/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=desktop/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.desktop.swing.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>com.apple.eawt 0.0.0<br>
+javax.accessibility 0.0.0<br>
+javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+javax.swing.event 0.0.0<br>
+javax.swing.filechooser 0.0.0<br>
+javax.swing.plaf 0.0.0<br>
+javax.swing.plaf.basic 0.0.0<br>
+javax.swing.plaf.metal 0.0.0<br>
+javax.swing.table 0.0.0<br>
+javax.swing.text 0.0.0<br>
+javax.swing.text.html 0.0.0<br>
+javax.swing.tree 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.2,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Graph,osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Closure,osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Manifest,osgi.service;  objectClas [...]
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:21</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/desktop</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Copyright</td>
+ <td>Copyright (c) 2003-2013, KNOPFLERFISH project. All rights reserved.</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>app.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:desktop:5.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target=" [...]
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../../javadoc/index.html?org/o [...]
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/DateCellRenderer.java">org/knopflerfish/bundle/desktop/event/DateCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/EventReaderDispatcher.java">org/knopflerfish/bundle/desktop/event/EventReaderDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/EventTableModel.java">org/knopflerfish/bundle/desktop/event/EventTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/FilterEventTableModel.java">org/knopflerfish/bundle/desktop/event/FilterEventTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JDetailFrame.java">org/knopflerfish/bundle/desktop/event/JDetailFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventEntryDetail.java">org/knopflerfish/bundle/desktop/event/JEventEntryDetail.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventPanel.java">org/knopflerfish/bundle/desktop/event/JEventPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventTable.java">org/knopflerfish/bundle/desktop/event/JEventTable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JSendEventPanel.java">org/knopflerfish/bundle/desktop/event/JSendEventPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/StringCellRenderer.java">org/knopflerfish/bundle/desktop/event/StringCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/TableMap.java">org/knopflerfish/bundle/desktop/event/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/TableSorter.java">org/knopflerfish/bundle/desktop/event/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/Util.java">org/knopflerfish/bundle/desktop/event/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/Colors.java">org/knopflerfish/bundle/desktop/prefs/Colors.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/ExtPreferences.java">org/knopflerfish/bundle/desktop/prefs/ExtPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsEditor.java">org/knopflerfish/bundle/desktop/prefs/JPrefsEditor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsPanel.java">org/knopflerfish/bundle/desktop/prefs/JPrefsPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsTree.java">org/knopflerfish/bundle/desktop/prefs/JPrefsTree.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValue.java">org/knopflerfish/bundle/desktop/prefs/JValue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueBoolean.java">org/knopflerfish/bundle/desktop/prefs/JValueBoolean.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueColor.java">org/knopflerfish/bundle/desktop/prefs/JValueColor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueDouble.java">org/knopflerfish/bundle/desktop/prefs/JValueDouble.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueFactory.java">org/knopflerfish/bundle/desktop/prefs/JValueFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueInteger.java">org/knopflerfish/bundle/desktop/prefs/JValueInteger.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueLong.java">org/knopflerfish/bundle/desktop/prefs/JValueLong.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueString.java">org/knopflerfish/bundle/desktop/prefs/JValueString.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/MountedPreferences.java">org/knopflerfish/bundle/desktop/prefs/MountedPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiBundlePreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiBundlePreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiBundlesPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiBundlesPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiUsersPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiUsersPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/PrefsTreeModel.java">org/knopflerfish/bundle/desktop/prefs/PrefsTreeModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/PrefsTreeNode.java">org/knopflerfish/bundle/desktop/prefs/PrefsTreeNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/TreeUtils.java">org/knopflerfish/bundle/desktop/prefs/TreeUtils.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Activator.java">org/knopflerfish/bundle/desktop/swing/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/BundleImageIcon.java">org/knopflerfish/bundle/desktop/swing/BundleImageIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ClosureHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ClosureHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Colors.java">org/knopflerfish/bundle/desktop/swing/Colors.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/swing/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Desktop.java">org/knopflerfish/bundle/desktop/swing/Desktop.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ErrorMessageDialog.java">org/knopflerfish/bundle/desktop/swing/ErrorMessageDialog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/EventDisplayer.java">org/knopflerfish/bundle/desktop/swing/EventDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/FileFilterImpl.java">org/knopflerfish/bundle/desktop/swing/FileFilterImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/GraphDisplayer.java">org/knopflerfish/bundle/desktop/swing/GraphDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JBundleHistory.java">org/knopflerfish/bundle/desktop/swing/JBundleHistory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JCardPane.java">org/knopflerfish/bundle/desktop/swing/JCardPane.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JFloatable.java">org/knopflerfish/bundle/desktop/swing/JFloatable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JHTMLBundle.java">org/knopflerfish/bundle/desktop/swing/JHTMLBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JHTMLBundleLinkHandler.java">org/knopflerfish/bundle/desktop/swing/JHTMLBundleLinkHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JPackageView.java">org/knopflerfish/bundle/desktop/swing/JPackageView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JServiceView.java">org/knopflerfish/bundle/desktop/swing/JServiceView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JSoftGraph.java">org/knopflerfish/bundle/desktop/swing/JSoftGraph.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JSoftGraphBundle.java">org/knopflerfish/bundle/desktop/swing/JSoftGraphBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JTips.java">org/knopflerfish/bundle/desktop/swing/JTips.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JToolbarButton.java">org/knopflerfish/bundle/desktop/swing/JToolbarButton.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/KnopflerfishLookAndFeel.java">org/knopflerfish/bundle/desktop/swing/KnopflerfishLookAndFeel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/KnopflerfishTheme.java">org/knopflerfish/bundle/desktop/swing/KnopflerfishTheme.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LFManager.java">org/knopflerfish/bundle/desktop/swing/LFManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LargeIconsDisplayer.java">org/knopflerfish/bundle/desktop/swing/LargeIconsDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LogDisplayer.java">org/knopflerfish/bundle/desktop/swing/LogDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LookAndFeelMenu.java">org/knopflerfish/bundle/desktop/swing/LookAndFeelMenu.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ManifestHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ManifestHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/OSXAdapter.java">org/knopflerfish/bundle/desktop/swing/OSXAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/OverlayImageIcon.java">org/knopflerfish/bundle/desktop/swing/OverlayImageIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PackageHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/PackageHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PackageManager.java">org/knopflerfish/bundle/desktop/swing/PackageManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PrefsDisplayer.java">org/knopflerfish/bundle/desktop/swing/PrefsDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SCRHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/SCRHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ServiceHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ServiceHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SizeSaver.java">org/knopflerfish/bundle/desktop/swing/SizeSaver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SpinDisplayer.java">org/knopflerfish/bundle/desktop/swing/SpinDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/StatusBar.java">org/knopflerfish/bundle/desktop/swing/StatusBar.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/StatusViewer.java">org/knopflerfish/bundle/desktop/swing/StatusViewer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Strings.java">org/knopflerfish/bundle/desktop/swing/Strings.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableDisplayer.java">org/knopflerfish/bundle/desktop/swing/TableDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableMap.java">org/knopflerfish/bundle/desktop/swing/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableSorter.java">org/knopflerfish/bundle/desktop/swing/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Util.java">org/knopflerfish/bundle/desktop/swing/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/WiringHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/WiringHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Config.java">org/knopflerfish/bundle/desktop/swing/console/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/ConsoleSwing.java">org/knopflerfish/bundle/desktop/swing/console/ConsoleSwing.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/PrefixPrintStream.java">org/knopflerfish/bundle/desktop/swing/console/PrefixPrintStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Queue.java">org/knopflerfish/bundle/desktop/swing/console/Queue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Strip.java">org/knopflerfish/bundle/desktop/swing/console/Strip.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/SwingIO.java">org/knopflerfish/bundle/desktop/swing/console/SwingIO.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/TextAreaOutputStream.java">org/knopflerfish/bundle/desktop/swing/console/TextAreaOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/TextReader.java">org/knopflerfish/bundle/desktop/swing/console/TextReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/Console.java">org/knopflerfish/bundle/desktop/swing/fwspin/Console.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/GameFrame.java">org/knopflerfish/bundle/desktop/swing/fwspin/GameFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/Spin.java">org/knopflerfish/bundle/desktop/swing/fwspin/Spin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/SpinItem.java">org/knopflerfish/bundle/desktop/swing/fwspin/SpinItem.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/BundleNode.java">org/knopflerfish/bundle/desktop/swing/graph/BundleNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/BundleServiceNode.java">org/knopflerfish/bundle/desktop/swing/graph/BundleServiceNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/DefaultLink.java">org/knopflerfish/bundle/desktop/swing/graph/DefaultLink.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/DefaultNode.java">org/knopflerfish/bundle/desktop/swing/graph/DefaultNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/EmptyNode.java">org/knopflerfish/bundle/desktop/swing/graph/EmptyNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/Link.java">org/knopflerfish/bundle/desktop/swing/graph/Link.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/Node.java">org/knopflerfish/bundle/desktop/swing/graph/Node.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/PackageNode.java">org/knopflerfish/bundle/desktop/swing/graph/PackageNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/ServiceLink.java">org/knopflerfish/bundle/desktop/swing/graph/ServiceLink.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/DateCellRenderer.java">org/knopflerfish/bundle/log/window/impl/DateCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/ExtLogEntry.java">org/knopflerfish/bundle/log/window/impl/ExtLogEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/FilterLogTableModel.java">org/knopflerfish/bundle/log/window/impl/FilterLogTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JDetailFrame.java">org/knopflerfish/bundle/log/window/impl/JDetailFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogEntryDetail.java">org/knopflerfish/bundle/log/window/impl/JLogEntryDetail.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogPanel.java">org/knopflerfish/bundle/log/window/impl/JLogPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogTable.java">org/knopflerfish/bundle/log/window/impl/JLogTable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/LogReaderDispatcher.java">org/knopflerfish/bundle/log/window/impl/LogReaderDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/LogTableModel.java">org/knopflerfish/bundle/log/window/impl/LogTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/TableMap.java">org/knopflerfish/bundle/log/window/impl/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/TableSorter.java">org/knopflerfish/bundle/log/window/impl/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/Util.java">org/knopflerfish/bundle/log/window/impl/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleFilter.java">org/knopflerfish/service/desktop/BundleFilter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleSelectionListener.java">org/knopflerfish/service/desktop/BundleSelectionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleSelectionModel.java">org/knopflerfish/service/desktop/BundleSelectionModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/DefaultBundleSelectionModel.java">org/knopflerfish/service/desktop/DefaultBundleSelectionModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/SelectionAware.java">org/knopflerfish/service/desktop/SelectionAware.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/SwingBundleDisplayer.java">org/knopflerfish/service/desktop/SwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/desktop/desktop_all-5.0.1.html b/docs/jars/desktop/desktop_all-5.0.1.html
new file mode 100644
index 0000000..57345d1
--- /dev/null
+++ b/docs/jars/desktop/desktop_all-5.0.1.html
@@ -0,0 +1,899 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>desktop_all-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>desktop_all-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/desktop/desktop_all-5.0.1.jar">download</a> (884818 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Swing framework desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=desktop/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=desktop/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.desktop.swing.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> 1.6.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 2.1.2<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 2.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> 1.1.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/workerthread/package-summary.html">org.knopflerfish.util.workerthread</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> 1.5.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> 1.2.1<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> 1.3.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> 1.3.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> 1.1.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>com.apple.eawt 0.0.0<br>
+javax.accessibility 0.0.0<br>
+javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+javax.swing.event 0.0.0<br>
+javax.swing.filechooser 0.0.0<br>
+javax.swing.plaf 0.0.0<br>
+javax.swing.plaf.basic 0.0.0<br>
+javax.swing.plaf.metal 0.0.0<br>
+javax.swing.table 0.0.0<br>
+javax.swing.text 0.0.0<br>
+javax.swing.text.html 0.0.0<br>
+javax.swing.tree 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.2,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/workerthread/package-summary.html">org.knopflerfish.util.workerthread</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.5.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> [1.2.1,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Graph,osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Closure,osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Manifest,osgi.service;  objectClas [...]
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:21</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/desktop</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Copyright</td>
+ <td>Copyright (c) 2003-2013, KNOPFLERFISH project. All rights reserved.</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>app.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:desktop:5.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target=" [...]
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a>, <a target="_top" href="../../javadoc/ind [...]
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../../javadoc/index.html?org/o [...]
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a>, <a target="_top" href="../../javadoc/index. [...]
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target=" [...]
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" hr [...]
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a>, <a target="_top" href="../../javadoc/index.html [...]
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../j [...]
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/i [...]
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">o [...]
+<tr><td><a href="../repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/DateCellRenderer.java">org/knopflerfish/bundle/desktop/event/DateCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/EventReaderDispatcher.java">org/knopflerfish/bundle/desktop/event/EventReaderDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/EventTableModel.java">org/knopflerfish/bundle/desktop/event/EventTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/FilterEventTableModel.java">org/knopflerfish/bundle/desktop/event/FilterEventTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JDetailFrame.java">org/knopflerfish/bundle/desktop/event/JDetailFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventEntryDetail.java">org/knopflerfish/bundle/desktop/event/JEventEntryDetail.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventPanel.java">org/knopflerfish/bundle/desktop/event/JEventPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventTable.java">org/knopflerfish/bundle/desktop/event/JEventTable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JSendEventPanel.java">org/knopflerfish/bundle/desktop/event/JSendEventPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/StringCellRenderer.java">org/knopflerfish/bundle/desktop/event/StringCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/TableMap.java">org/knopflerfish/bundle/desktop/event/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/TableSorter.java">org/knopflerfish/bundle/desktop/event/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/Util.java">org/knopflerfish/bundle/desktop/event/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/Colors.java">org/knopflerfish/bundle/desktop/prefs/Colors.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/ExtPreferences.java">org/knopflerfish/bundle/desktop/prefs/ExtPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsEditor.java">org/knopflerfish/bundle/desktop/prefs/JPrefsEditor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsPanel.java">org/knopflerfish/bundle/desktop/prefs/JPrefsPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsTree.java">org/knopflerfish/bundle/desktop/prefs/JPrefsTree.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValue.java">org/knopflerfish/bundle/desktop/prefs/JValue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueBoolean.java">org/knopflerfish/bundle/desktop/prefs/JValueBoolean.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueColor.java">org/knopflerfish/bundle/desktop/prefs/JValueColor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueDouble.java">org/knopflerfish/bundle/desktop/prefs/JValueDouble.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueFactory.java">org/knopflerfish/bundle/desktop/prefs/JValueFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueInteger.java">org/knopflerfish/bundle/desktop/prefs/JValueInteger.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueLong.java">org/knopflerfish/bundle/desktop/prefs/JValueLong.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueString.java">org/knopflerfish/bundle/desktop/prefs/JValueString.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/MountedPreferences.java">org/knopflerfish/bundle/desktop/prefs/MountedPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiBundlePreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiBundlePreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiBundlesPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiBundlesPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiUsersPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiUsersPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/PrefsTreeModel.java">org/knopflerfish/bundle/desktop/prefs/PrefsTreeModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/PrefsTreeNode.java">org/knopflerfish/bundle/desktop/prefs/PrefsTreeNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/TreeUtils.java">org/knopflerfish/bundle/desktop/prefs/TreeUtils.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Activator.java">org/knopflerfish/bundle/desktop/swing/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/BundleImageIcon.java">org/knopflerfish/bundle/desktop/swing/BundleImageIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ClosureHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ClosureHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Colors.java">org/knopflerfish/bundle/desktop/swing/Colors.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/swing/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Desktop.java">org/knopflerfish/bundle/desktop/swing/Desktop.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ErrorMessageDialog.java">org/knopflerfish/bundle/desktop/swing/ErrorMessageDialog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/EventDisplayer.java">org/knopflerfish/bundle/desktop/swing/EventDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/FileFilterImpl.java">org/knopflerfish/bundle/desktop/swing/FileFilterImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/GraphDisplayer.java">org/knopflerfish/bundle/desktop/swing/GraphDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JBundleHistory.java">org/knopflerfish/bundle/desktop/swing/JBundleHistory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JCardPane.java">org/knopflerfish/bundle/desktop/swing/JCardPane.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JFloatable.java">org/knopflerfish/bundle/desktop/swing/JFloatable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JHTMLBundle.java">org/knopflerfish/bundle/desktop/swing/JHTMLBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JHTMLBundleLinkHandler.java">org/knopflerfish/bundle/desktop/swing/JHTMLBundleLinkHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JPackageView.java">org/knopflerfish/bundle/desktop/swing/JPackageView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JServiceView.java">org/knopflerfish/bundle/desktop/swing/JServiceView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JSoftGraph.java">org/knopflerfish/bundle/desktop/swing/JSoftGraph.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JSoftGraphBundle.java">org/knopflerfish/bundle/desktop/swing/JSoftGraphBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JTips.java">org/knopflerfish/bundle/desktop/swing/JTips.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JToolbarButton.java">org/knopflerfish/bundle/desktop/swing/JToolbarButton.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/KnopflerfishLookAndFeel.java">org/knopflerfish/bundle/desktop/swing/KnopflerfishLookAndFeel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/KnopflerfishTheme.java">org/knopflerfish/bundle/desktop/swing/KnopflerfishTheme.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LFManager.java">org/knopflerfish/bundle/desktop/swing/LFManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LargeIconsDisplayer.java">org/knopflerfish/bundle/desktop/swing/LargeIconsDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LogDisplayer.java">org/knopflerfish/bundle/desktop/swing/LogDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LookAndFeelMenu.java">org/knopflerfish/bundle/desktop/swing/LookAndFeelMenu.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ManifestHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ManifestHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/OSXAdapter.java">org/knopflerfish/bundle/desktop/swing/OSXAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/OverlayImageIcon.java">org/knopflerfish/bundle/desktop/swing/OverlayImageIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PackageHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/PackageHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PackageManager.java">org/knopflerfish/bundle/desktop/swing/PackageManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PrefsDisplayer.java">org/knopflerfish/bundle/desktop/swing/PrefsDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SCRHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/SCRHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ServiceHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ServiceHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SizeSaver.java">org/knopflerfish/bundle/desktop/swing/SizeSaver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SpinDisplayer.java">org/knopflerfish/bundle/desktop/swing/SpinDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/StatusBar.java">org/knopflerfish/bundle/desktop/swing/StatusBar.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/StatusViewer.java">org/knopflerfish/bundle/desktop/swing/StatusViewer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Strings.java">org/knopflerfish/bundle/desktop/swing/Strings.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableDisplayer.java">org/knopflerfish/bundle/desktop/swing/TableDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableMap.java">org/knopflerfish/bundle/desktop/swing/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableSorter.java">org/knopflerfish/bundle/desktop/swing/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Util.java">org/knopflerfish/bundle/desktop/swing/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/WiringHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/WiringHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Config.java">org/knopflerfish/bundle/desktop/swing/console/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/ConsoleSwing.java">org/knopflerfish/bundle/desktop/swing/console/ConsoleSwing.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/PrefixPrintStream.java">org/knopflerfish/bundle/desktop/swing/console/PrefixPrintStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Queue.java">org/knopflerfish/bundle/desktop/swing/console/Queue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Strip.java">org/knopflerfish/bundle/desktop/swing/console/Strip.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/SwingIO.java">org/knopflerfish/bundle/desktop/swing/console/SwingIO.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/TextAreaOutputStream.java">org/knopflerfish/bundle/desktop/swing/console/TextAreaOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/TextReader.java">org/knopflerfish/bundle/desktop/swing/console/TextReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/Console.java">org/knopflerfish/bundle/desktop/swing/fwspin/Console.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/GameFrame.java">org/knopflerfish/bundle/desktop/swing/fwspin/GameFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/Spin.java">org/knopflerfish/bundle/desktop/swing/fwspin/Spin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/SpinItem.java">org/knopflerfish/bundle/desktop/swing/fwspin/SpinItem.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/BundleNode.java">org/knopflerfish/bundle/desktop/swing/graph/BundleNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/BundleServiceNode.java">org/knopflerfish/bundle/desktop/swing/graph/BundleServiceNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/DefaultLink.java">org/knopflerfish/bundle/desktop/swing/graph/DefaultLink.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/DefaultNode.java">org/knopflerfish/bundle/desktop/swing/graph/DefaultNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/EmptyNode.java">org/knopflerfish/bundle/desktop/swing/graph/EmptyNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/Link.java">org/knopflerfish/bundle/desktop/swing/graph/Link.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/Node.java">org/knopflerfish/bundle/desktop/swing/graph/Node.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/PackageNode.java">org/knopflerfish/bundle/desktop/swing/graph/PackageNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/ServiceLink.java">org/knopflerfish/bundle/desktop/swing/graph/ServiceLink.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/DateCellRenderer.java">org/knopflerfish/bundle/log/window/impl/DateCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/ExtLogEntry.java">org/knopflerfish/bundle/log/window/impl/ExtLogEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/FilterLogTableModel.java">org/knopflerfish/bundle/log/window/impl/FilterLogTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JDetailFrame.java">org/knopflerfish/bundle/log/window/impl/JDetailFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogEntryDetail.java">org/knopflerfish/bundle/log/window/impl/JLogEntryDetail.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogPanel.java">org/knopflerfish/bundle/log/window/impl/JLogPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogTable.java">org/knopflerfish/bundle/log/window/impl/JLogTable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/LogReaderDispatcher.java">org/knopflerfish/bundle/log/window/impl/LogReaderDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/LogTableModel.java">org/knopflerfish/bundle/log/window/impl/LogTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/TableMap.java">org/knopflerfish/bundle/log/window/impl/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/TableSorter.java">org/knopflerfish/bundle/log/window/impl/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/Util.java">org/knopflerfish/bundle/log/window/impl/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleFilter.java">org/knopflerfish/service/desktop/BundleFilter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleSelectionListener.java">org/knopflerfish/service/desktop/BundleSelectionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleSelectionModel.java">org/knopflerfish/service/desktop/BundleSelectionModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/DefaultBundleSelectionModel.java">org/knopflerfish/service/desktop/DefaultBundleSelectionModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/SelectionAware.java">org/knopflerfish/service/desktop/SelectionAware.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/SwingBundleDisplayer.java">org/knopflerfish/service/desktop/SwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/desktop/desktop_api-5.0.1.html b/docs/jars/desktop/desktop_api-5.0.1.html
new file mode 100644
index 0000000..5f6c837
--- /dev/null
+++ b/docs/jars/desktop/desktop_api-5.0.1.html
@@ -0,0 +1,794 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>desktop_api-5.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>desktop_api-5.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/desktop/desktop_api-5.0.1.jar">download</a> (5306 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Desktop-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.desktop-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Swing framework desktop (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=desktop/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=desktop/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 2.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>com.apple.eawt 0.0.0<br>
+javax.swing 0.0.0<br>
+javax.swing.plaf.basic 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> [2.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:21</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/desktop</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-Copyright</td>
+ <td>Copyright (c) 2003-2013, KNOPFLERFISH project. All rights reserved.</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>app.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:desktop:5.0.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/DateCellRenderer.java">org/knopflerfish/bundle/desktop/event/DateCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/EventReaderDispatcher.java">org/knopflerfish/bundle/desktop/event/EventReaderDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/EventTableModel.java">org/knopflerfish/bundle/desktop/event/EventTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/FilterEventTableModel.java">org/knopflerfish/bundle/desktop/event/FilterEventTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JDetailFrame.java">org/knopflerfish/bundle/desktop/event/JDetailFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventEntryDetail.java">org/knopflerfish/bundle/desktop/event/JEventEntryDetail.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventPanel.java">org/knopflerfish/bundle/desktop/event/JEventPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JEventTable.java">org/knopflerfish/bundle/desktop/event/JEventTable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/JSendEventPanel.java">org/knopflerfish/bundle/desktop/event/JSendEventPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/StringCellRenderer.java">org/knopflerfish/bundle/desktop/event/StringCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/TableMap.java">org/knopflerfish/bundle/desktop/event/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/TableSorter.java">org/knopflerfish/bundle/desktop/event/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/event/Util.java">org/knopflerfish/bundle/desktop/event/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/Colors.java">org/knopflerfish/bundle/desktop/prefs/Colors.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/ExtPreferences.java">org/knopflerfish/bundle/desktop/prefs/ExtPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsEditor.java">org/knopflerfish/bundle/desktop/prefs/JPrefsEditor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsPanel.java">org/knopflerfish/bundle/desktop/prefs/JPrefsPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JPrefsTree.java">org/knopflerfish/bundle/desktop/prefs/JPrefsTree.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValue.java">org/knopflerfish/bundle/desktop/prefs/JValue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueBoolean.java">org/knopflerfish/bundle/desktop/prefs/JValueBoolean.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueColor.java">org/knopflerfish/bundle/desktop/prefs/JValueColor.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueDouble.java">org/knopflerfish/bundle/desktop/prefs/JValueDouble.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueFactory.java">org/knopflerfish/bundle/desktop/prefs/JValueFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueInteger.java">org/knopflerfish/bundle/desktop/prefs/JValueInteger.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueLong.java">org/knopflerfish/bundle/desktop/prefs/JValueLong.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/JValueString.java">org/knopflerfish/bundle/desktop/prefs/JValueString.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/MountedPreferences.java">org/knopflerfish/bundle/desktop/prefs/MountedPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiBundlePreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiBundlePreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiBundlesPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiBundlesPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/OSGiUsersPreferences.java">org/knopflerfish/bundle/desktop/prefs/OSGiUsersPreferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/PrefsTreeModel.java">org/knopflerfish/bundle/desktop/prefs/PrefsTreeModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/PrefsTreeNode.java">org/knopflerfish/bundle/desktop/prefs/PrefsTreeNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/prefs/TreeUtils.java">org/knopflerfish/bundle/desktop/prefs/TreeUtils.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Activator.java">org/knopflerfish/bundle/desktop/swing/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/BundleImageIcon.java">org/knopflerfish/bundle/desktop/swing/BundleImageIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ClosureHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ClosureHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Colors.java">org/knopflerfish/bundle/desktop/swing/Colors.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/swing/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Desktop.java">org/knopflerfish/bundle/desktop/swing/Desktop.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ErrorMessageDialog.java">org/knopflerfish/bundle/desktop/swing/ErrorMessageDialog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/EventDisplayer.java">org/knopflerfish/bundle/desktop/swing/EventDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/FileFilterImpl.java">org/knopflerfish/bundle/desktop/swing/FileFilterImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/GraphDisplayer.java">org/knopflerfish/bundle/desktop/swing/GraphDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JBundleHistory.java">org/knopflerfish/bundle/desktop/swing/JBundleHistory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JCardPane.java">org/knopflerfish/bundle/desktop/swing/JCardPane.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JFloatable.java">org/knopflerfish/bundle/desktop/swing/JFloatable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JHTMLBundle.java">org/knopflerfish/bundle/desktop/swing/JHTMLBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JHTMLBundleLinkHandler.java">org/knopflerfish/bundle/desktop/swing/JHTMLBundleLinkHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JPackageView.java">org/knopflerfish/bundle/desktop/swing/JPackageView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JServiceView.java">org/knopflerfish/bundle/desktop/swing/JServiceView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JSoftGraph.java">org/knopflerfish/bundle/desktop/swing/JSoftGraph.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JSoftGraphBundle.java">org/knopflerfish/bundle/desktop/swing/JSoftGraphBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JTips.java">org/knopflerfish/bundle/desktop/swing/JTips.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/JToolbarButton.java">org/knopflerfish/bundle/desktop/swing/JToolbarButton.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/KnopflerfishLookAndFeel.java">org/knopflerfish/bundle/desktop/swing/KnopflerfishLookAndFeel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/KnopflerfishTheme.java">org/knopflerfish/bundle/desktop/swing/KnopflerfishTheme.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LFManager.java">org/knopflerfish/bundle/desktop/swing/LFManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LargeIconsDisplayer.java">org/knopflerfish/bundle/desktop/swing/LargeIconsDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LogDisplayer.java">org/knopflerfish/bundle/desktop/swing/LogDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/LookAndFeelMenu.java">org/knopflerfish/bundle/desktop/swing/LookAndFeelMenu.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ManifestHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ManifestHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/OSXAdapter.java">org/knopflerfish/bundle/desktop/swing/OSXAdapter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/OverlayImageIcon.java">org/knopflerfish/bundle/desktop/swing/OverlayImageIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PackageHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/PackageHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PackageManager.java">org/knopflerfish/bundle/desktop/swing/PackageManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/PrefsDisplayer.java">org/knopflerfish/bundle/desktop/swing/PrefsDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SCRHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/SCRHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/ServiceHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/ServiceHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SizeSaver.java">org/knopflerfish/bundle/desktop/swing/SizeSaver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/SpinDisplayer.java">org/knopflerfish/bundle/desktop/swing/SpinDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/StatusBar.java">org/knopflerfish/bundle/desktop/swing/StatusBar.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/StatusViewer.java">org/knopflerfish/bundle/desktop/swing/StatusViewer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Strings.java">org/knopflerfish/bundle/desktop/swing/Strings.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableDisplayer.java">org/knopflerfish/bundle/desktop/swing/TableDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableMap.java">org/knopflerfish/bundle/desktop/swing/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/TableSorter.java">org/knopflerfish/bundle/desktop/swing/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/Util.java">org/knopflerfish/bundle/desktop/swing/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/WiringHTMLDisplayer.java">org/knopflerfish/bundle/desktop/swing/WiringHTMLDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Config.java">org/knopflerfish/bundle/desktop/swing/console/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/ConsoleSwing.java">org/knopflerfish/bundle/desktop/swing/console/ConsoleSwing.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/PrefixPrintStream.java">org/knopflerfish/bundle/desktop/swing/console/PrefixPrintStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Queue.java">org/knopflerfish/bundle/desktop/swing/console/Queue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/Strip.java">org/knopflerfish/bundle/desktop/swing/console/Strip.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/SwingIO.java">org/knopflerfish/bundle/desktop/swing/console/SwingIO.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/TextAreaOutputStream.java">org/knopflerfish/bundle/desktop/swing/console/TextAreaOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/console/TextReader.java">org/knopflerfish/bundle/desktop/swing/console/TextReader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/Console.java">org/knopflerfish/bundle/desktop/swing/fwspin/Console.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/GameFrame.java">org/knopflerfish/bundle/desktop/swing/fwspin/GameFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/Spin.java">org/knopflerfish/bundle/desktop/swing/fwspin/Spin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/fwspin/SpinItem.java">org/knopflerfish/bundle/desktop/swing/fwspin/SpinItem.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/BundleNode.java">org/knopflerfish/bundle/desktop/swing/graph/BundleNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/BundleServiceNode.java">org/knopflerfish/bundle/desktop/swing/graph/BundleServiceNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/DefaultLink.java">org/knopflerfish/bundle/desktop/swing/graph/DefaultLink.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/DefaultNode.java">org/knopflerfish/bundle/desktop/swing/graph/DefaultNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/EmptyNode.java">org/knopflerfish/bundle/desktop/swing/graph/EmptyNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/Link.java">org/knopflerfish/bundle/desktop/swing/graph/Link.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/Node.java">org/knopflerfish/bundle/desktop/swing/graph/Node.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/PackageNode.java">org/knopflerfish/bundle/desktop/swing/graph/PackageNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/desktop/swing/graph/ServiceLink.java">org/knopflerfish/bundle/desktop/swing/graph/ServiceLink.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/DateCellRenderer.java">org/knopflerfish/bundle/log/window/impl/DateCellRenderer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/ExtLogEntry.java">org/knopflerfish/bundle/log/window/impl/ExtLogEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/FilterLogTableModel.java">org/knopflerfish/bundle/log/window/impl/FilterLogTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JDetailFrame.java">org/knopflerfish/bundle/log/window/impl/JDetailFrame.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogEntryDetail.java">org/knopflerfish/bundle/log/window/impl/JLogEntryDetail.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogPanel.java">org/knopflerfish/bundle/log/window/impl/JLogPanel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/JLogTable.java">org/knopflerfish/bundle/log/window/impl/JLogTable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/LogReaderDispatcher.java">org/knopflerfish/bundle/log/window/impl/LogReaderDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/LogTableModel.java">org/knopflerfish/bundle/log/window/impl/LogTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/TableMap.java">org/knopflerfish/bundle/log/window/impl/TableMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/TableSorter.java">org/knopflerfish/bundle/log/window/impl/TableSorter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/bundle/log/window/impl/Util.java">org/knopflerfish/bundle/log/window/impl/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleFilter.java">org/knopflerfish/service/desktop/BundleFilter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleSelectionListener.java">org/knopflerfish/service/desktop/BundleSelectionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/BundleSelectionModel.java">org/knopflerfish/service/desktop/BundleSelectionModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/DefaultBundleSelectionModel.java">org/knopflerfish/service/desktop/DefaultBundleSelectionModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/SelectionAware.java">org/knopflerfish/service/desktop/SelectionAware.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/desktop/src/org/knopflerfish/service/desktop/SwingBundleDisplayer.java">org/knopflerfish/service/desktop/SwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/desktop_jvm/desktop_jvm-1.0.0.html b/docs/jars/desktop_jvm/desktop_jvm-1.0.0.html
new file mode 100644
index 0000000..19f79e6
--- /dev/null
+++ b/docs/jars/desktop_jvm/desktop_jvm-1.0.0.html
@@ -0,0 +1,205 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>desktop_jvm-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>desktop_jvm-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/desktop_jvm/desktop_jvm-1.0.0.jar">download</a> (14486 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>desktop_jvm-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.desktop_jvm-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>JVM info desktop plugin (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org">http://www.knopflerfish.org</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.desktop.jvminfo.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:31</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/desktop_displayers/desktop_jvm</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:desktop_jvm:1.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/Activator.java">org/knopflerfish/bundle/desktop/jvminfo/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/jvminfo/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/JGraph.java">org/knopflerfish/bundle/desktop/jvminfo/JGraph.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/JVMDisplayer.java">org/knopflerfish/bundle/desktop/jvminfo/JVMDisplayer.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/desktop_jvm/desktop_jvm_all-1.0.0.html b/docs/jars/desktop_jvm/desktop_jvm_all-1.0.0.html
new file mode 100644
index 0000000..16e3fac
--- /dev/null
+++ b/docs/jars/desktop_jvm/desktop_jvm_all-1.0.0.html
@@ -0,0 +1,205 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>desktop_jvm_all-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>desktop_jvm_all-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/desktop_jvm/desktop_jvm_all-1.0.0.jar">download</a> (14473 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>desktop_jvm</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.desktop_jvm</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>JVM info desktop plugin</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org">http://www.knopflerfish.org</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.desktop.jvminfo.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:31</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/desktop_displayers/desktop_jvm</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:desktop_jvm:1.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/Activator.java">org/knopflerfish/bundle/desktop/jvminfo/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/desktop/jvminfo/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/JGraph.java">org/knopflerfish/bundle/desktop/jvminfo/JGraph.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/desktop_displayers/desktop_jvm/src/org/knopflerfish/bundle/desktop/jvminfo/JVMDisplayer.java">org/knopflerfish/bundle/desktop/jvminfo/JVMDisplayer.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/device/device-4.0.1.html b/docs/jars/device/device-4.0.1.html
new file mode 100644
index 0000000..da551b0
--- /dev/null
+++ b/docs/jars/device/device-4.0.1.html
@@ -0,0 +1,244 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>device-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>device-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/device/device-4.0.1.jar">download</a> (17731 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Device-Manager-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.device-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Device manager (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.device.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> [1.1.0,1.2.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.2.0,3.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:27</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/device/device</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:device:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/Activator.java">org/knopflerfish/bundle/device/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/DriverRef.java">org/knopflerfish/bundle/device/DriverRef.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/MatchImpl.java">org/knopflerfish/bundle/device/MatchImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/MatchValue.java">org/knopflerfish/bundle/device/MatchValue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Constants.java">org/osgi/service/device/Constants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Device.java">org/osgi/service/device/Device.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Driver.java">org/osgi/service/device/Driver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/DriverLocator.java">org/osgi/service/device/DriverLocator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/DriverSelector.java">org/osgi/service/device/DriverSelector.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Match.java">org/osgi/service/device/Match.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/package-info.java">org/osgi/service/device/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/device/device_all-4.0.1.html b/docs/jars/device/device_all-4.0.1.html
new file mode 100644
index 0000000..9c95e6d
--- /dev/null
+++ b/docs/jars/device/device_all-4.0.1.html
@@ -0,0 +1,252 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>device_all-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>device_all-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/device/device_all-4.0.1.jar">download</a> (20333 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Device-Manager</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.device</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Device manager</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.device.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> [1.1.0,1.2.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.2.0,3.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:27</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/device/device</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:device:4.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/Activator.java">org/knopflerfish/bundle/device/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/DriverRef.java">org/knopflerfish/bundle/device/DriverRef.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/MatchImpl.java">org/knopflerfish/bundle/device/MatchImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/MatchValue.java">org/knopflerfish/bundle/device/MatchValue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Constants.java">org/osgi/service/device/Constants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Device.java">org/osgi/service/device/Device.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Driver.java">org/osgi/service/device/Driver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/DriverLocator.java">org/osgi/service/device/DriverLocator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/DriverSelector.java">org/osgi/service/device/DriverSelector.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Match.java">org/osgi/service/device/Match.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/package-info.java">org/osgi/service/device/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/device/device_api-4.0.1.html b/docs/jars/device/device_api-4.0.1.html
new file mode 100644
index 0000000..966910b
--- /dev/null
+++ b/docs/jars/device/device_api-4.0.1.html
@@ -0,0 +1,247 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>device_api-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>device_api-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/device/device_api-4.0.1.jar">download</a> (3450 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Device-Manager-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.device-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Device manager (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:27</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/device/device</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:device:4.0.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/Activator.java">org/knopflerfish/bundle/device/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/DriverRef.java">org/knopflerfish/bundle/device/DriverRef.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/MatchImpl.java">org/knopflerfish/bundle/device/MatchImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/knopflerfish/bundle/device/MatchValue.java">org/knopflerfish/bundle/device/MatchValue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Constants.java">org/osgi/service/device/Constants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Device.java">org/osgi/service/device/Device.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Driver.java">org/osgi/service/device/Driver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/DriverLocator.java">org/osgi/service/device/DriverLocator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/DriverSelector.java">org/osgi/service/device/DriverSelector.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/Match.java">org/osgi/service/device/Match.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/device/device/src/org/osgi/service/device/package-info.java">org/osgi/service/device/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/dirdeployer/dirdeployer_all-4.0.1.html b/docs/jars/dirdeployer/dirdeployer_all-4.0.1.html
new file mode 100644
index 0000000..fe7a2e7
--- /dev/null
+++ b/docs/jars/dirdeployer/dirdeployer_all-4.0.1.html
@@ -0,0 +1,242 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>dirdeployer_all-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>dirdeployer_all-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/dirdeployer/dirdeployer_all-4.0.1.jar">download</a> (41921 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Directory Deployer</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.dirdeployer</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Monitors a set of file system directory for bundlesand configurations to deploy</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=dirdeployer/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=dirdeployer/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.dirdeployer.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a> [0.0.0,1.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:27</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/dirdeployer</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>example</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:dirdeployer:4.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/ut [...]
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/Activator.java">org/knopflerfish/bundle/dirdeployer/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/Config.java">org/knopflerfish/bundle/dirdeployer/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DeployedBundle.java">org/knopflerfish/bundle/dirdeployer/DeployedBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DeployedCMData.java">org/knopflerfish/bundle/dirdeployer/DeployedCMData.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DeployedFile.java">org/knopflerfish/bundle/dirdeployer/DeployedFile.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DirDeployerImpl.java">org/knopflerfish/bundle/dirdeployer/DirDeployerImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/service/dirdeployer/DirDeployerService.java">org/knopflerfish/service/dirdeployer/DirDeployerService.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/dirdeployer/dirdeployer_api-4.0.1.html b/docs/jars/dirdeployer/dirdeployer_api-4.0.1.html
new file mode 100644
index 0000000..a2a846c
--- /dev/null
+++ b/docs/jars/dirdeployer/dirdeployer_api-4.0.1.html
@@ -0,0 +1,220 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>dirdeployer_api-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>dirdeployer_api-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/dirdeployer/dirdeployer_api-4.0.1.jar">download</a> (1596 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Directory Deployer-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.dirdeployer-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Monitors a set of file system directory for bundlesand configurations to deploy (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=dirdeployer/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=dirdeployer/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a> [0.0.0,1.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:27</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/dirdeployer</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:dirdeployer:4.0.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/Activator.java">org/knopflerfish/bundle/dirdeployer/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/Config.java">org/knopflerfish/bundle/dirdeployer/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DeployedBundle.java">org/knopflerfish/bundle/dirdeployer/DeployedBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DeployedCMData.java">org/knopflerfish/bundle/dirdeployer/DeployedCMData.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DeployedFile.java">org/knopflerfish/bundle/dirdeployer/DeployedFile.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/bundle/dirdeployer/DirDeployerImpl.java">org/knopflerfish/bundle/dirdeployer/DirDeployerImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/dirdeployer/src/org/knopflerfish/service/dirdeployer/DirDeployerService.java">org/knopflerfish/service/dirdeployer/DirDeployerService.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/dmt/dmt_api-5.0.0.html b/docs/jars/dmt/dmt_api-5.0.0.html
new file mode 100644
index 0000000..3137fe0
--- /dev/null
+++ b/docs/jars/dmt/dmt_api-5.0.0.html
@@ -0,0 +1,336 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>dmt_api-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>dmt_api-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/dmt/dmt_api-5.0.0.jar">download</a> (37681 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>dmt-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.dmt-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>DMT (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/Apache-2.0;link="http://www.apache.org/licenses/LICENSE-2.0";description="Apache License, Version 2.0"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/package-summary.html">org.osgi.service.dmt</a> 2.0.1<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/package-summary.html">org.osgi.service.dmt.notification</a> 2.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/spi/package-summary.html">org.osgi.service.dmt.notification.spi</a> 2.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/security/package-summary.html">org.osgi.service.dmt.security</a> 2.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/spi/package-summary.html">org.osgi.service.dmt.spi</a> 2.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/package-summary.html">org.osgi.service.dmt</a> [2.0.1,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/package-summary.html">org.osgi.service.dmt.notification</a> [2.0.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/spi/package-summary.html">org.osgi.service.dmt.notification.spi</a> [2.0.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/security/package-summary.html">org.osgi.service.dmt.security</a> [2.0.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/spi/package-summary.html">org.osgi.service.dmt.spi</a> [2.0.0,3.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:52</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/dmt</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:dmt:5.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/package-summary.html">org.osgi.service.dmt</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/package-summary.html">org.osgi.service.dmt.notification</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/spi/package-summary.html">org.osgi.service.dmt.notification.spi</a>, <a target=" [...]
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/package-summary.html">org.osgi.service.dmt</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/package-summary.html">org.osgi.service.dmt.notification</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/dmt/notification/spi/package-summary.html">org.osgi.service.dmt.notification.spi</a>, <a target=" [...]
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/Acl.java">org/osgi/service/dmt/Acl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtAdmin.java">org/osgi/service/dmt/DmtAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtConstants.java">org/osgi/service/dmt/DmtConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtData.java">org/osgi/service/dmt/DmtData.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtEvent.java">org/osgi/service/dmt/DmtEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtEventListener.java">org/osgi/service/dmt/DmtEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtException.java">org/osgi/service/dmt/DmtException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtIllegalStateException.java">org/osgi/service/dmt/DmtIllegalStateException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/DmtSession.java">org/osgi/service/dmt/DmtSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/MetaNode.java">org/osgi/service/dmt/MetaNode.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/Uri.java">org/osgi/service/dmt/Uri.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/notification/AlertItem.java">org/osgi/service/dmt/notification/AlertItem.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/notification/NotificationService.java">org/osgi/service/dmt/notification/NotificationService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/notification/package-info.java">org/osgi/service/dmt/notification/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/notification/spi/RemoteAlertSender.java">org/osgi/service/dmt/notification/spi/RemoteAlertSender.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/notification/spi/package-info.java">org/osgi/service/dmt/notification/spi/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/package-info.java">org/osgi/service/dmt/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/security/AlertPermission.java">org/osgi/service/dmt/security/AlertPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/security/DmtPermission.java">org/osgi/service/dmt/security/DmtPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/security/DmtPrincipalPermission.java">org/osgi/service/dmt/security/DmtPrincipalPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/security/package-info.java">org/osgi/service/dmt/security/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/DataPlugin.java">org/osgi/service/dmt/spi/DataPlugin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/ExecPlugin.java">org/osgi/service/dmt/spi/ExecPlugin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/MountPlugin.java">org/osgi/service/dmt/spi/MountPlugin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/MountPoint.java">org/osgi/service/dmt/spi/MountPoint.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/ReadWriteDataSession.java">org/osgi/service/dmt/spi/ReadWriteDataSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/ReadableDataSession.java">org/osgi/service/dmt/spi/ReadableDataSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/TransactionalDataSession.java">org/osgi/service/dmt/spi/TransactionalDataSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/dmt/src/org/osgi/service/dmt/spi/package-info.java">org/osgi/service/dmt/spi/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/event/event_all-4.0.1.html b/docs/jars/event/event_all-4.0.1.html
new file mode 100644
index 0000000..8713cd4
--- /dev/null
+++ b/docs/jars/event/event_all-4.0.1.html
@@ -0,0 +1,284 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>event_all-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>event_all-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/event/event_all-4.0.1.jar">download</a> (40706 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Event-Admin</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.event</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Event Admin</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=event/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=event/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.event.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> 1.3.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)                                                (version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:11</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/event</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:event:4.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a>, <a target="_top" href="../../javadoc/inde [...]
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/Activator.java">org/knopflerfish/bundle/event/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/ConfigurationListenerImpl.java">org/knopflerfish/bundle/event/ConfigurationListenerImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/EventAdminService.java">org/knopflerfish/bundle/event/EventAdminService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/EventHandlerTracker.java">org/knopflerfish/bundle/event/EventHandlerTracker.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/InternalAdminEvent.java">org/knopflerfish/bundle/event/InternalAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/MultiListener.java">org/knopflerfish/bundle/event/MultiListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/QueueHandler.java">org/knopflerfish/bundle/event/QueueHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/TimeoutDeliver.java">org/knopflerfish/bundle/event/TimeoutDeliver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/TrackedEventHandler.java">org/knopflerfish/bundle/event/TrackedEventHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/Event.java">org/osgi/service/event/Event.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventAdmin.java">org/osgi/service/event/EventAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventConstants.java">org/osgi/service/event/EventConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventHandler.java">org/osgi/service/event/EventHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventProperties.java">org/osgi/service/event/EventProperties.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/TopicPermission.java">org/osgi/service/event/TopicPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/package-info.java">org/osgi/service/event/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/event/event_api-4.0.1.html b/docs/jars/event/event_api-4.0.1.html
new file mode 100644
index 0000000..ff2421f
--- /dev/null
+++ b/docs/jars/event/event_api-4.0.1.html
@@ -0,0 +1,272 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>event_api-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>event_api-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/event/event_api-4.0.1.jar">download</a> (13415 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Event-Admin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.event-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Event Admin (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=event/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=event/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> 1.3.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)                                                (version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:11</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/event</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:event:4.0.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/Activator.java">org/knopflerfish/bundle/event/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/ConfigurationListenerImpl.java">org/knopflerfish/bundle/event/ConfigurationListenerImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/EventAdminService.java">org/knopflerfish/bundle/event/EventAdminService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/EventHandlerTracker.java">org/knopflerfish/bundle/event/EventHandlerTracker.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/InternalAdminEvent.java">org/knopflerfish/bundle/event/InternalAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/MultiListener.java">org/knopflerfish/bundle/event/MultiListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/QueueHandler.java">org/knopflerfish/bundle/event/QueueHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/TimeoutDeliver.java">org/knopflerfish/bundle/event/TimeoutDeliver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/knopflerfish/bundle/event/TrackedEventHandler.java">org/knopflerfish/bundle/event/TrackedEventHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/Event.java">org/osgi/service/event/Event.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventAdmin.java">org/osgi/service/event/EventAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventConstants.java">org/osgi/service/event/EventConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventHandler.java">org/osgi/service/event/EventHandler.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/EventProperties.java">org/osgi/service/event/EventProperties.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/TopicPermission.java">org/osgi/service/event/TopicPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/event/src/org/osgi/service/event/package-info.java">org/osgi/service/event/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/foreignapplication/foreignapplication_api-4.0.0.html b/docs/jars/foreignapplication/foreignapplication_api-4.0.0.html
new file mode 100644
index 0000000..035baaa
--- /dev/null
+++ b/docs/jars/foreignapplication/foreignapplication_api-4.0.0.html
@@ -0,0 +1,210 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>foreignapplication_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>foreignapplication_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/foreignapplication/foreignapplication_api-4.0.0.jar">download</a> (3434 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Foreign application-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.foreignapplication-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Foreign Application Access API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/application/package-summary.html">org.osgi.application</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/application/package-summary.html">org.osgi.application</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:57</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/foreignapplication</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:foreignapplication:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../foreignapplication/foreignapplication_api-4.0.0.html">foreignapplication_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/application/package-summary.html">org.osgi.application</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../foreignapplication/foreignapplication_api-4.0.0.html">foreignapplication_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/application/package-summary.html">org.osgi.application</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/src/org/osgi/application/ApplicationContext.java">org/osgi/application/ApplicationContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/src/org/osgi/application/ApplicationServiceEvent.java">org/osgi/application/ApplicationServiceEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/src/org/osgi/application/ApplicationServiceListener.java">org/osgi/application/ApplicationServiceListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/src/org/osgi/application/Framework.java">org/osgi/application/Framework.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/foreignapplication/src/org/osgi/application/package-info.java">org/osgi/application/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/framework.html b/docs/jars/framework.html
new file mode 100644
index 0000000..7e26e71
--- /dev/null
+++ b/docs/jars/framework.html
@@ -0,0 +1,294 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="style.css" rel="stylesheet" type="text/css">
+  <title>framework.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>framework.jar</h2>
+
+<p>
+<a href="../../osgi/framework.jar">download</a> (620789 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>frameworkbundle</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.framework</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>7.1.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Knopflerfish OSGi framework system bundle</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>"http://www.knopflerfish.org/license.html";description=BSD;link="http://www.knopflerfish.org/license.html"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/current/docs/bundledoc/index.html?docpage=framework/index.html">http://www.knopflerfish.org/releases/current/docs/bundledoc/index.html?docpage=framework/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 1.7.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/bundle/package-summary.html">org.osgi.framework.hooks.bundle</a> 1.1.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/resolver/package-summary.html">org.osgi.framework.hooks.resolver</a> 1.0.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/service/package-summary.html">org.osgi.framework.hooks.service</a> 1.1.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/weaving/package-summary.html">org.osgi.framework.hooks.weaving</a> 1.0.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/launch/package-summary.html">org.osgi.framework.launch</a> 1.1.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a> 1.0.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> 1.0.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> 1.1.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 1.0.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/service/condpermadmin/package-summary.html">org.osgi.service.condpermadmin</a> 1.1.1<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a> 1.2.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/service/permissionadmin/package-summary.html">org.osgi.service.permissionadmin</a> 1.2.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/service/startlevel/package-summary.html">org.osgi.service.startlevel</a> 1.1.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/service/url/package-summary.html">org.osgi.service.url</a> 1.0.0<br>
+<a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> 1.5.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Build Fri June 13 2014, 08:25:43</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/framework/">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/framework/</a></td>
+</tr>
+<tr>
+ <td>Implementation-Title</td>
+ <td>Knopflerfish OSGi Framework</td>
+</tr>
+<tr>
+ <td>Implementation-Vendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Implementation-Version</td>
+ <td>7.1.2</td>
+</tr>
+<tr>
+ <td>Main-class</td>
+ <td>org.knopflerfish.framework.Main</td>
+</tr>
+<tr>
+ <td>Specification-Title</td>
+ <td>OSGi Framework API</td>
+</tr>
+<tr>
+ <td>Specification-Vendor</td>
+ <td>Open Service Gateway initiative</td>
+</tr>
+<tr>
+ <td>Specification-Version</td>
+ <td>1.7</td>
+</tr>
+<tr>
+ <td>SplashScreen-Image</td>
+ <td>kfsplash.gif</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="applicationadmin/applicationadmin_api-4.0.0.html">applicationadmin_api-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="classpatcher/classpatcher_all-5.0.0.html">classpatcher_all-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/weaving/package-summary.html">org.osgi.framework.hooks.weaving</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a></td></tr>
+<tr><td><a href="cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="connectors/connectors_all-3.0.0.html">connectors_all-3.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="connectors/connectors-3.0.0.html">connectors-3.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="coordinator/coordinator_api-1.0.0.html">coordinator_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../javadoc/index.h [...]
+<tr><td><a href="desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../javadoc/index.html?org/ [...]
+<tr><td><a href="desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a>, <a target="_top" href="../javadoc/i [...]
+<tr><td><a href="event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="foreignapplication/foreignapplication_api-4.0.0.html">foreignapplication_api-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a>, <a target="_top" href=".. [...]
+<tr><td><a href="http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="io/io_all-4.0.0.html">io_all-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="junit_runner/junit_runner_all-4.0.0.html">junit_runner_all-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="metatype/metatype-4.0.0.html">metatype-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+<tr><td><a href="prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="remoteserviceadmin/remoteserviceadmin_api-1.0.0.html">remoteserviceadmin_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+<tr><td><a href="repoindex_kf/repoindex_kf_all-1.0.1.html">repoindex_kf_all-1.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a>, <a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../javadoc/index.h [...]
+<tr><td><a href="repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+<tr><td><a href="resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+<tr><td><a href="scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="serviceloader/serviceloader_api-1.0.0.html">serviceloader_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+<tr><td><a href="sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="subsystem/subsystem_api-1.0.0.html">subsystem_api-1.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="threadio/threadio-0.2.0.html">threadio-0.2.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a></td></tr>
+<tr><td><a href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="wireadmin/wireadmin_api-5.0.0.html">wireadmin_api-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="xml/xml-4.0.0.html">xml-4.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+None found
+
+</body>
+</html>
+
+
diff --git a/docs/jars/frameworkcommands/frameworkcommands-4.0.1.html b/docs/jars/frameworkcommands/frameworkcommands-4.0.1.html
new file mode 100644
index 0000000..3d192ac
--- /dev/null
+++ b/docs/jars/frameworkcommands/frameworkcommands-4.0.1.html
@@ -0,0 +1,216 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>frameworkcommands-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>frameworkcommands-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/frameworkcommands/frameworkcommands-4.0.1.jar">download</a> (43187 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>FW-Commands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.frameworkcommands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Framework commands (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=frameworkcommands/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=frameworkcommands/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.frameworkcommands.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/condpermadmin/package-summary.html">org.osgi.service.condpermadmin</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/permissionadmin/package-summary.html">org.osgi.service.permissionadmin</a> [1.2.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:44</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/frameworkcommands</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/frameworkcommands/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/frameworkcommands/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:frameworkcommands:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Import-Service</td>
+ <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/ConsoleService.html">org.knopflerfish.service.console.ConsoleService</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/LogService.html">org.osgi.service.log.LogService</a> 0.0.0<br>
+</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/se [...]
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/frameworkcommands/src/org/knopflerfish/bundle/frameworkcommands/Activator.java">org/knopflerfish/bundle/frameworkcommands/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/frameworkcommands/src/org/knopflerfish/bundle/frameworkcommands/FrameworkCommandGroup.java">org/knopflerfish/bundle/frameworkcommands/FrameworkCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/frameworkcommands/src/org/knopflerfish/bundle/frameworkcommands/PermissionAdminHelper.java">org/knopflerfish/bundle/frameworkcommands/PermissionAdminHelper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/frameworkcommands/src/org/knopflerfish/bundle/frameworkcommands/PermissionAdminHelperImpl.java">org/knopflerfish/bundle/frameworkcommands/PermissionAdminHelperImpl.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/header.html b/docs/jars/header.html
new file mode 100644
index 0000000..c608d08
--- /dev/null
+++ b/docs/jars/header.html
@@ -0,0 +1,81 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <link href="../css/knopflerfish.css" rel="stylesheet" type="text/css">
+    <link href="../css/kf_man.css" rel="stylesheet" type="text/css">
+
+    <style type="text/css">
+
+    DIV.left_hdr {
+      width: 225px;
+      height: 100%;
+      background: #000;
+      margin: 0px;
+      padding-top: 10px;
+      padding-left: 15px;
+      color: #fff;
+      float:left;
+      font-weight: bold;
+    }
+
+    DIV.logo_hdr {
+      height: 100%;
+      background: #fb0b0c;
+      margin: 0px 0px 0px 225px;
+      padding-top: 10px;
+      padding-left: 50px;
+    }
+
+    DIV.header_fade {
+      height: 15px;
+      border: 0px;
+      margin: 0px;
+      padding:0px;
+      border-style: none;
+      background-image: url('../images/fadeout_15.png');
+      background-size: 15px;
+      background-repeat: repeat-x;
+      clear:both;
+      overflow: hidden; /* To prevent IE to add an extra 1px at the bottom */
+    }
+
+    BODY  {
+      background: #fff;
+      margin-top:   5px;
+      margin-left:  10px;
+      margin-right: 10px;
+      font-size: 0.8125em;
+    }
+  </style>
+    
+</head>
+
+<body>
+  <div id="header">
+    <div id="header_logo">
+      <a target="_top" href="../index.html" >
+        <img src="../images/kf300_black.png" border="0" alt="knopflerfish logo"/>
+      </a>
+    </div>
+    <div id="header_centerbox">
+      <div class="header_centerinfo_top">
+	Distribution Documentation
+      </div>
+      <div class="header_centerinfo_bottom">
+	Knopflerfish OSGi
+      </div>
+    </div>
+    <div id="header_rightinfo">
+      <div class="header_stylish">
+	Open Source OSGi Service Platform Maintained by
+      </div>
+      <a href="http://www.makewave.com">
+	<img border="0" alt="Makewave" src="../images/makewave_logo.png" border="0" style="margin-top: 4px;">
+      </a>
+    </div>
+    <!-- <div style="clear:both;"></div> -->
+    <div class="header_fade">
+    </div>
+  </div>
+</body>
+</html>
diff --git a/docs/jars/http/http-4.0.5.html b/docs/jars/http/http-4.0.5.html
new file mode 100644
index 0000000..eac317d
--- /dev/null
+++ b/docs/jars/http/http-4.0.5.html
@@ -0,0 +1,438 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>http-4.0.5.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>http-4.0.5.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/http/http-4.0.5.jar">download</a> (108383 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>HTTP-Server-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.http-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.5</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>HTTP/HTTPS Server (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=http/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=http/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.http.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.net.ssl 0.0.0<br>
+javax.servlet [2.5.0,2.6.0)<br>
+javax.servlet.http [2.5.0,2.6.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> [1.2.0,1.3.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:52</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/http/http</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:http:4.0.5:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href [...]
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Activator.java">org/knopflerfish/bundle/http/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Attributes.java">org/knopflerfish/bundle/http/Attributes.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/BodyOutputStream.java">org/knopflerfish/bundle/http/BodyOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/DefaultHttpContext.java">org/knopflerfish/bundle/http/DefaultHttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/GZIPServletOutputStreamImpl.java">org/knopflerfish/bundle/http/GZIPServletOutputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HeaderBase.java">org/knopflerfish/bundle/http/HeaderBase.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpConfig.java">org/knopflerfish/bundle/http/HttpConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpConfigWrapper.java">org/knopflerfish/bundle/http/HttpConfigWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpException.java">org/knopflerfish/bundle/http/HttpException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServer.java">org/knopflerfish/bundle/http/HttpServer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServerFactory.java">org/knopflerfish/bundle/http/HttpServerFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServiceFactory.java">org/knopflerfish/bundle/http/HttpServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServiceImpl.java">org/knopflerfish/bundle/http/HttpServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpSessionImpl.java">org/knopflerfish/bundle/http/HttpSessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpSessionManager.java">org/knopflerfish/bundle/http/HttpSessionManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpUtil.java">org/knopflerfish/bundle/http/HttpUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/LocaleToCharsetMap.java">org/knopflerfish/bundle/http/LocaleToCharsetMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ObjectPool.java">org/knopflerfish/bundle/http/ObjectPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/PoolableObject.java">org/knopflerfish/bundle/http/PoolableObject.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/PoolableServletWrapper.java">org/knopflerfish/bundle/http/PoolableServletWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Registration.java">org/knopflerfish/bundle/http/Registration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Registrations.java">org/knopflerfish/bundle/http/Registrations.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Request.java">org/knopflerfish/bundle/http/Request.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestBase.java">org/knopflerfish/bundle/http/RequestBase.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestDispatcherImpl.java">org/knopflerfish/bundle/http/RequestDispatcherImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java">org/knopflerfish/bundle/http/RequestImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestWrapper.java">org/knopflerfish/bundle/http/RequestWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResourceRegistration.java">org/knopflerfish/bundle/http/ResourceRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Response.java">org/knopflerfish/bundle/http/Response.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResponseImpl.java">org/knopflerfish/bundle/http/ResponseImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResponseWrapper.java">org/knopflerfish/bundle/http/ResponseWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletConfigImpl.java">org/knopflerfish/bundle/http/ServletConfigImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletContextImpl.java">org/knopflerfish/bundle/http/ServletContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletContextManager.java">org/knopflerfish/bundle/http/ServletContextManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletInputStreamImpl.java">org/knopflerfish/bundle/http/ServletInputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletOutputStreamImpl.java">org/knopflerfish/bundle/http/ServletOutputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletPool.java">org/knopflerfish/bundle/http/ServletPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletRegistration.java">org/knopflerfish/bundle/http/ServletRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/SimpleObjectPool.java">org/knopflerfish/bundle/http/SimpleObjectPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/SocketListener.java">org/knopflerfish/bundle/http/SocketListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Transaction.java">org/knopflerfish/bundle/http/Transaction.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/TransactionManager.java">org/knopflerfish/bundle/http/TransactionManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/console/HttpCommandGroup.java">org/knopflerfish/bundle/http/console/HttpCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/HttpContext.java">org/osgi/service/http/HttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/HttpService.java">org/osgi/service/http/HttpService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/NamespaceException.java">org/osgi/service/http/NamespaceException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/package-info.java">org/osgi/service/http/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/http/http_all-4.0.5.html b/docs/jars/http/http_all-4.0.5.html
new file mode 100644
index 0000000..f497f1c
--- /dev/null
+++ b/docs/jars/http/http_all-4.0.5.html
@@ -0,0 +1,471 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>http_all-4.0.5.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>http_all-4.0.5.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/http/http_all-4.0.5.jar">download</a> (116642 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>HTTP-Server</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.http</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.5</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>HTTP/HTTPS Server</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=http/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=http/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.http.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> 1.2.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.net.ssl 0.0.0<br>
+javax.servlet [2.5.0,2.6.0)<br>
+javax.servlet.http [2.5.0,2.6.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> [1.2.0,1.3.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:52</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/http/http</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:http:4.0.5</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href [...]
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Activator.java">org/knopflerfish/bundle/http/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Attributes.java">org/knopflerfish/bundle/http/Attributes.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/BodyOutputStream.java">org/knopflerfish/bundle/http/BodyOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/DefaultHttpContext.java">org/knopflerfish/bundle/http/DefaultHttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/GZIPServletOutputStreamImpl.java">org/knopflerfish/bundle/http/GZIPServletOutputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HeaderBase.java">org/knopflerfish/bundle/http/HeaderBase.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpConfig.java">org/knopflerfish/bundle/http/HttpConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpConfigWrapper.java">org/knopflerfish/bundle/http/HttpConfigWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpException.java">org/knopflerfish/bundle/http/HttpException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServer.java">org/knopflerfish/bundle/http/HttpServer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServerFactory.java">org/knopflerfish/bundle/http/HttpServerFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServiceFactory.java">org/knopflerfish/bundle/http/HttpServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServiceImpl.java">org/knopflerfish/bundle/http/HttpServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpSessionImpl.java">org/knopflerfish/bundle/http/HttpSessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpSessionManager.java">org/knopflerfish/bundle/http/HttpSessionManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpUtil.java">org/knopflerfish/bundle/http/HttpUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/LocaleToCharsetMap.java">org/knopflerfish/bundle/http/LocaleToCharsetMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ObjectPool.java">org/knopflerfish/bundle/http/ObjectPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/PoolableObject.java">org/knopflerfish/bundle/http/PoolableObject.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/PoolableServletWrapper.java">org/knopflerfish/bundle/http/PoolableServletWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Registration.java">org/knopflerfish/bundle/http/Registration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Registrations.java">org/knopflerfish/bundle/http/Registrations.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Request.java">org/knopflerfish/bundle/http/Request.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestBase.java">org/knopflerfish/bundle/http/RequestBase.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestDispatcherImpl.java">org/knopflerfish/bundle/http/RequestDispatcherImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java">org/knopflerfish/bundle/http/RequestImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestWrapper.java">org/knopflerfish/bundle/http/RequestWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResourceRegistration.java">org/knopflerfish/bundle/http/ResourceRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Response.java">org/knopflerfish/bundle/http/Response.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResponseImpl.java">org/knopflerfish/bundle/http/ResponseImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResponseWrapper.java">org/knopflerfish/bundle/http/ResponseWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletConfigImpl.java">org/knopflerfish/bundle/http/ServletConfigImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletContextImpl.java">org/knopflerfish/bundle/http/ServletContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletContextManager.java">org/knopflerfish/bundle/http/ServletContextManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletInputStreamImpl.java">org/knopflerfish/bundle/http/ServletInputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletOutputStreamImpl.java">org/knopflerfish/bundle/http/ServletOutputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletPool.java">org/knopflerfish/bundle/http/ServletPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletRegistration.java">org/knopflerfish/bundle/http/ServletRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/SimpleObjectPool.java">org/knopflerfish/bundle/http/SimpleObjectPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/SocketListener.java">org/knopflerfish/bundle/http/SocketListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Transaction.java">org/knopflerfish/bundle/http/Transaction.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/TransactionManager.java">org/knopflerfish/bundle/http/TransactionManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/console/HttpCommandGroup.java">org/knopflerfish/bundle/http/console/HttpCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/HttpContext.java">org/osgi/service/http/HttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/HttpService.java">org/osgi/service/http/HttpService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/NamespaceException.java">org/osgi/service/http/NamespaceException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/package-info.java">org/osgi/service/http/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/http/http_api-4.0.5.html b/docs/jars/http/http_api-4.0.5.html
new file mode 100644
index 0000000..e60572a
--- /dev/null
+++ b/docs/jars/http/http_api-4.0.5.html
@@ -0,0 +1,429 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>http_api-4.0.5.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>http_api-4.0.5.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/http/http_api-4.0.5.jar">download</a> (2992 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>HTTP-Server-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.http-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.5</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>HTTP/HTTPS Server (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=http/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=http/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> 1.2.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.net.ssl 0.0.0<br>
+javax.servlet 0.0.0<br>
+javax.servlet.http 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> [1.2.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:52</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/http/http</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:http:4.0.5:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Activator.java">org/knopflerfish/bundle/http/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Attributes.java">org/knopflerfish/bundle/http/Attributes.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/BodyOutputStream.java">org/knopflerfish/bundle/http/BodyOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/DefaultHttpContext.java">org/knopflerfish/bundle/http/DefaultHttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/GZIPServletOutputStreamImpl.java">org/knopflerfish/bundle/http/GZIPServletOutputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HeaderBase.java">org/knopflerfish/bundle/http/HeaderBase.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpConfig.java">org/knopflerfish/bundle/http/HttpConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpConfigWrapper.java">org/knopflerfish/bundle/http/HttpConfigWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpException.java">org/knopflerfish/bundle/http/HttpException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServer.java">org/knopflerfish/bundle/http/HttpServer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServerFactory.java">org/knopflerfish/bundle/http/HttpServerFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServiceFactory.java">org/knopflerfish/bundle/http/HttpServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpServiceImpl.java">org/knopflerfish/bundle/http/HttpServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpSessionImpl.java">org/knopflerfish/bundle/http/HttpSessionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpSessionManager.java">org/knopflerfish/bundle/http/HttpSessionManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/HttpUtil.java">org/knopflerfish/bundle/http/HttpUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/LocaleToCharsetMap.java">org/knopflerfish/bundle/http/LocaleToCharsetMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ObjectPool.java">org/knopflerfish/bundle/http/ObjectPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/PoolableObject.java">org/knopflerfish/bundle/http/PoolableObject.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/PoolableServletWrapper.java">org/knopflerfish/bundle/http/PoolableServletWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Registration.java">org/knopflerfish/bundle/http/Registration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Registrations.java">org/knopflerfish/bundle/http/Registrations.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Request.java">org/knopflerfish/bundle/http/Request.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestBase.java">org/knopflerfish/bundle/http/RequestBase.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestDispatcherImpl.java">org/knopflerfish/bundle/http/RequestDispatcherImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestImpl.java">org/knopflerfish/bundle/http/RequestImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/RequestWrapper.java">org/knopflerfish/bundle/http/RequestWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResourceRegistration.java">org/knopflerfish/bundle/http/ResourceRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Response.java">org/knopflerfish/bundle/http/Response.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResponseImpl.java">org/knopflerfish/bundle/http/ResponseImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ResponseWrapper.java">org/knopflerfish/bundle/http/ResponseWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletConfigImpl.java">org/knopflerfish/bundle/http/ServletConfigImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletContextImpl.java">org/knopflerfish/bundle/http/ServletContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletContextManager.java">org/knopflerfish/bundle/http/ServletContextManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletInputStreamImpl.java">org/knopflerfish/bundle/http/ServletInputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletOutputStreamImpl.java">org/knopflerfish/bundle/http/ServletOutputStreamImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletPool.java">org/knopflerfish/bundle/http/ServletPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/ServletRegistration.java">org/knopflerfish/bundle/http/ServletRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/SimpleObjectPool.java">org/knopflerfish/bundle/http/SimpleObjectPool.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/SocketListener.java">org/knopflerfish/bundle/http/SocketListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/Transaction.java">org/knopflerfish/bundle/http/Transaction.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/TransactionManager.java">org/knopflerfish/bundle/http/TransactionManager.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/knopflerfish/bundle/http/console/HttpCommandGroup.java">org/knopflerfish/bundle/http/console/HttpCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/HttpContext.java">org/osgi/service/http/HttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/HttpService.java">org/osgi/service/http/HttpService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/NamespaceException.java">org/osgi/service/http/NamespaceException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/http/src/org/osgi/service/http/package-info.java">org/osgi/service/http/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/httpconsole/httpconsole_all-4.0.1.html b/docs/jars/httpconsole/httpconsole_all-4.0.1.html
new file mode 100644
index 0000000..7d74ec4
--- /dev/null
+++ b/docs/jars/httpconsole/httpconsole_all-4.0.1.html
@@ -0,0 +1,312 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>httpconsole_all-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>httpconsole_all-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/httpconsole/httpconsole_all-4.0.1.jar">download</a> (70416 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>httpconsole</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.httpconsole</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=httpconsole/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=httpconsole/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.httpconsole.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.servlet [2.5.0,3.0.0)<br>
+javax.servlet.http [2.5.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)                                                (version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:59</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/http/httpconsole</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:httpconsole:4.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/Activator.java">org/knopflerfish/bundle/httpconsole/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/BundleView.java">org/knopflerfish/bundle/httpconsole/BundleView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/Command.java">org/knopflerfish/bundle/httpconsole/Command.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/ConsoleServlet.java">org/knopflerfish/bundle/httpconsole/ConsoleServlet.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/HTMLable.java">org/knopflerfish/bundle/httpconsole/HTMLable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/HelpCommand.java">org/knopflerfish/bundle/httpconsole/HelpCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/HttpWrapper.java">org/knopflerfish/bundle/httpconsole/HttpWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/IconCommand.java">org/knopflerfish/bundle/httpconsole/IconCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/IconDialogCommand.java">org/knopflerfish/bundle/httpconsole/IconDialogCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/IconView.java">org/knopflerfish/bundle/httpconsole/IconView.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/InfoCommand.java">org/knopflerfish/bundle/httpconsole/InfoCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/InstallFileCommand.java">org/knopflerfish/bundle/httpconsole/InstallFileCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/InstallFileCommand2.java">org/knopflerfish/bundle/httpconsole/InstallFileCommand2.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/InstallURLCommand.java">org/knopflerfish/bundle/httpconsole/InstallURLCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/Login.java">org/knopflerfish/bundle/httpconsole/Login.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/LogoutCommand.java">org/knopflerfish/bundle/httpconsole/LogoutCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/ReloadCommand.java">org/knopflerfish/bundle/httpconsole/ReloadCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/ServiceInfoCommand.java">org/knopflerfish/bundle/httpconsole/ServiceInfoCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/StartCommand.java">org/knopflerfish/bundle/httpconsole/StartCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/StatusCommand.java">org/knopflerfish/bundle/httpconsole/StatusCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/StopCommand.java">org/knopflerfish/bundle/httpconsole/StopCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/UninstallCommand.java">org/knopflerfish/bundle/httpconsole/UninstallCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/UpdateCommand.java">org/knopflerfish/bundle/httpconsole/UpdateCommand.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/Util.java">org/knopflerfish/bundle/httpconsole/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/httproot/httproot-4.0.0.html b/docs/jars/httproot/httproot-4.0.0.html
new file mode 100644
index 0000000..febce84
--- /dev/null
+++ b/docs/jars/httproot/httproot-4.0.0.html
@@ -0,0 +1,201 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>httproot-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>httproot-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/httproot/httproot-4.0.0.jar">download</a> (20492 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>HTTP-root-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.httproot-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Demo HTTP Service user that publishes on the root (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.httproot.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.servlet [2.5.0,3.0.0)<br>
+javax.servlet.http [2.5.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:58</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/http/httproot</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>example</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httproot/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httproot/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:httproot:4.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httproot/src/org/knopflerfish/bundle/httproot/Activator.java">org/knopflerfish/bundle/httproot/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/http/httproot/src/org/knopflerfish/bundle/httproot/InfoServlet.java">org/knopflerfish/bundle/httproot/InfoServlet.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/index.html b/docs/jars/index.html
new file mode 100644
index 0000000..37609a8
--- /dev/null
+++ b/docs/jars/index.html
@@ -0,0 +1,42 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    <title>Knopflerfish - Bundle Jar Documentation</title>
+    <script type="text/javascript" language="JavaScript">
+      <!--
+	  targetPage = "" + getPageId(window.location.search);
+
+	  function getPageId ( searchStr ) {
+	    var idStartPos = searchStr.indexOf('bundle=');
+	    if (-1==idStartPos) {
+	      return "main.html";
+	    }
+	    idStartPos += 7;
+	    var idEndPos = searchStr.indexOf('&',idStartPos);
+	    if (-1==idEndPos) {
+	      return searchStr.substr(idStartPos);
+	    } 
+	    return searchStr.substring(idStartPos,idEndPos);
+	  }
+
+	  function loadFrame() {
+	    top.bundle_main.location = top.targetPage;
+	  }
+
+          //-->
+    </script> 
+  </head>
+  <frameset rows="95px,*" onLoad="top.loadFrame()">
+    <frame name="bundle_header" src="header.html"
+           frameborder="0"      scrolling="no"
+           marginwidth="0"      marginheight="0">
+    <frameset cols="240,*">
+      <frame name="bundle_list" src="list.html"
+       frameborder="0"             scrolling="auto"
+       marginwidth="0"             marginheight="0">
+      <frame name="bundle_main" src="main.html"
+       frameborder="0"             scrolling="auto">
+    </frameset>
+  </frameset>
+</html>
+
diff --git a/docs/jars/io/io_all-4.0.0.html b/docs/jars/io/io_all-4.0.0.html
new file mode 100644
index 0000000..ba8f9c1
--- /dev/null
+++ b/docs/jars/io/io_all-4.0.0.html
@@ -0,0 +1,212 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>io_all-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>io_all-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/io/io_all-4.0.0.jar">download</a> (12863 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>io</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.io</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>IO</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.io.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,javax.microedition.io.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.microedition.io 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.microedition.io [0.0.0,1.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:32</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/io/io</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:io:4.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../io/io_all-4.0.0.html">io_all-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_api-4.0.0.html">io_api-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../connectors/connectors_all-3.0.0.html">connectors_all-3.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../connectors/connectors-3.0.0.html">connectors-3.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_all-4.0.0.html">io_all-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_api-4.0.0.html">io_api-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/knopflerfish/bundle/io/Activator.java">org/knopflerfish/bundle/io/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/knopflerfish/bundle/io/ConnectorServiceImpl.java">org/knopflerfish/bundle/io/ConnectorServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/osgi/service/io/ConnectionFactory.java">org/osgi/service/io/ConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/osgi/service/io/ConnectorService.java">org/osgi/service/io/ConnectorService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/osgi/service/io/package-info.java">org/osgi/service/io/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/io/io_api-4.0.0.html b/docs/jars/io/io_api-4.0.0.html
new file mode 100644
index 0000000..890ada4
--- /dev/null
+++ b/docs/jars/io/io_api-4.0.0.html
@@ -0,0 +1,210 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>io_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>io_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/io/io_api-4.0.0.jar">download</a> (2339 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>io-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.io-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>IO (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,javax.microedition.io.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.microedition.io 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.microedition.io [0.0.0,1.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:32</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/io/io</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:io:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../io/io_all-4.0.0.html">io_all-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_api-4.0.0.html">io_api-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../connectors/connectors_all-3.0.0.html">connectors_all-3.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../connectors/connectors-3.0.0.html">connectors-3.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_all-4.0.0.html">io_all-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+<tr><td><a href="../io/io_api-4.0.0.html">io_api-4.0.0</a></td><td>javax.microedition.io, <a target="_top" href="../../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/knopflerfish/bundle/io/Activator.java">org/knopflerfish/bundle/io/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/knopflerfish/bundle/io/ConnectorServiceImpl.java">org/knopflerfish/bundle/io/ConnectorServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/osgi/service/io/ConnectionFactory.java">org/osgi/service/io/ConnectionFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/osgi/service/io/ConnectorService.java">org/osgi/service/io/ConnectorService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/io/io/src/org/osgi/service/io/package-info.java">org/osgi/service/io/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/jinidriver/jinidriver_all-0.1.0.html b/docs/jars/jinidriver/jinidriver_all-0.1.0.html
new file mode 100644
index 0000000..cae9a9b
--- /dev/null
+++ b/docs/jars/jinidriver/jinidriver_all-0.1.0.html
@@ -0,0 +1,277 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>jinidriver_all-0.1.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>jinidriver_all-0.1.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/jinidriver/jinidriver_all-0.1.0.jar">download</a> (204969 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Jini-Driver</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.jinidriver</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>0.1.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Jini driver (experimental) using Sun's jini impl. jini-core.jar and jini-ext.jar, see http://wwws.sun.com/software/jini/licensing/SCSL3_JiniTSA1.html</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Nico Goeminne</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.jini.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,lib/jini-core.jar,lib/jini-ext.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>net.jini.admin 0.0.0<br>
+net.jini.core.discovery 0.0.0<br>
+net.jini.core.entry 0.0.0<br>
+net.jini.core.event 0.0.0<br>
+net.jini.core.lease 0.0.0<br>
+net.jini.core.lookup 0.0.0<br>
+net.jini.discovery 0.0.0<br>
+net.jini.lease 0.0.0<br>
+net.jini.lookup 0.0.0<br>
+net.jini.lookup.entry 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/jini/package-summary.html">org.osgi.service.jini</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.servlet 0.0.0<br>
+javax.servlet.http 0.0.0<br>
+net.jini.admin 0.0.0<br>
+net.jini.core.discovery 0.0.0<br>
+net.jini.core.entry 0.0.0<br>
+net.jini.core.event 0.0.0<br>
+net.jini.core.lease 0.0.0<br>
+net.jini.core.lookup 0.0.0<br>
+net.jini.discovery 0.0.0<br>
+net.jini.lease 0.0.0<br>
+net.jini.lookup 0.0.0<br>
+net.jini.lookup.entry 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/jini/package-summary.html">org.osgi.service.jini</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td>*</td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:24</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/jini/jinidriver</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:jinidriver:0.1.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td>net.jini.admin, net.jini.core.discovery, net.jini.core.entry, net.jini.core.event, net.jini.core.lease, net.jini.core.lookup, net.jini.discovery, net.jini.lease, net.jini.lookup, net.jini.lookup.entry, <a target="_top" href="../../javadoc/index.html?org/osgi/service/jini/package-summary.html">org.osgi.service.jini</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td>net.jini.admin, net.jini.core.discovery, net.jini.core.entry, net.jini.core.event, net.jini.core.lease, net.jini.core.lookup, net.jini.discovery, net.jini.lease, net.jini.lookup, net.jini.lookup.entry, <a target="_top" href="../../javadoc/index.html?org/osgi/service/jini/package-summary.html">org.osgi.service.jini</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/Activator.java">org/knopflerfish/bundle/jini/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/BundleHttpContext.java">org/knopflerfish/bundle/jini/BundleHttpContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/Debug.java">org/knopflerfish/bundle/jini/Debug.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/JiniDriverImpl.java">org/knopflerfish/bundle/jini/JiniDriverImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/JiniExportedService.java">org/knopflerfish/bundle/jini/JiniExportedService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/JiniExporter.java">org/knopflerfish/bundle/jini/JiniExporter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/JiniServiceFactory.java">org/knopflerfish/bundle/jini/JiniServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/Listener.java">org/knopflerfish/bundle/jini/Listener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/Osgi2Jini.java">org/knopflerfish/bundle/jini/Osgi2Jini.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/RMICodeBaseService.java">org/knopflerfish/bundle/jini/RMICodeBaseService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/knopflerfish/bundle/jini/Util.java">org/knopflerfish/bundle/jini/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/jini/jinidriver/src/org/osgi/service/jini/JiniDriver.java">org/osgi/service/jini/JiniDriver.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/jsdk/jsdk_api-2.5.0.kf3-2.html b/docs/jars/jsdk/jsdk_api-2.5.0.kf3-2.html
new file mode 100644
index 0000000..a35af23
--- /dev/null
+++ b/docs/jars/jsdk/jsdk_api-2.5.0.kf3-2.html
@@ -0,0 +1,392 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>jsdk_api-2.5.0.kf3-2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>jsdk_api-2.5.0.kf3-2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/jsdk/jsdk_api-2.5.0.kf3-2.jar">download</a> (42999 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>JSDK-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.jsdk-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.5.0.kf3-2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The servlet API classes (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Sun/Apache</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/Apache-2.0;link="http://www.apache.org/licenses/LICENSE-2.0";description="Apache License, Version 2.0"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.servlet 2.5.0<br>
+javax.servlet.http 2.5.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.servlet [2.5.0,3.0.0)<br>
+javax.servlet.http [2.5.0,3.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:46</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/jsdk</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Sun</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:jsdk:2.5.0.kf3-2:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/Filter.java">javax/servlet/Filter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/FilterChain.java">javax/servlet/FilterChain.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/FilterConfig.java">javax/servlet/FilterConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/GenericServlet.java">javax/servlet/GenericServlet.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/RequestDispatcher.java">javax/servlet/RequestDispatcher.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/Servlet.java">javax/servlet/Servlet.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletConfig.java">javax/servlet/ServletConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletContext.java">javax/servlet/ServletContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletContextAttributeEvent.java">javax/servlet/ServletContextAttributeEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletContextAttributeListener.java">javax/servlet/ServletContextAttributeListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletContextEvent.java">javax/servlet/ServletContextEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletContextListener.java">javax/servlet/ServletContextListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletException.java">javax/servlet/ServletException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletInputStream.java">javax/servlet/ServletInputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletOutputStream.java">javax/servlet/ServletOutputStream.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletRequest.java">javax/servlet/ServletRequest.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletRequestAttributeEvent.java">javax/servlet/ServletRequestAttributeEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletRequestAttributeListener.java">javax/servlet/ServletRequestAttributeListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletRequestEvent.java">javax/servlet/ServletRequestEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletRequestListener.java">javax/servlet/ServletRequestListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletRequestWrapper.java">javax/servlet/ServletRequestWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletResponse.java">javax/servlet/ServletResponse.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/ServletResponseWrapper.java">javax/servlet/ServletResponseWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/SingleThreadModel.java">javax/servlet/SingleThreadModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/UnavailableException.java">javax/servlet/UnavailableException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/Cookie.java">javax/servlet/http/Cookie.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpServlet.java">javax/servlet/http/HttpServlet.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpServletRequest.java">javax/servlet/http/HttpServletRequest.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpServletRequestWrapper.java">javax/servlet/http/HttpServletRequestWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpServletResponse.java">javax/servlet/http/HttpServletResponse.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpServletResponseWrapper.java">javax/servlet/http/HttpServletResponseWrapper.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSession.java">javax/servlet/http/HttpSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionActivationListener.java">javax/servlet/http/HttpSessionActivationListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionAttributeListener.java">javax/servlet/http/HttpSessionAttributeListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionBindingEvent.java">javax/servlet/http/HttpSessionBindingEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionBindingListener.java">javax/servlet/http/HttpSessionBindingListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionContext.java">javax/servlet/http/HttpSessionContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionEvent.java">javax/servlet/http/HttpSessionEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpSessionListener.java">javax/servlet/http/HttpSessionListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/jsdk/src/javax/servlet/http/HttpUtils.java">javax/servlet/http/HttpUtils.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/junit/junit_all-3.8.1.kf4-001.html b/docs/jars/junit/junit_all-3.8.1.kf4-001.html
new file mode 100644
index 0000000..f7c0a89
--- /dev/null
+++ b/docs/jars/junit/junit_all-3.8.1.kf4-001.html
@@ -0,0 +1,243 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>junit_all-3.8.1.kf4-001.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>junit_all-3.8.1.kf4-001.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/junit/junit_all-3.8.1.kf4-001.jar">download</a> (146393 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>JUnit</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.junit</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>3.8.1.kf4-001</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>JUnit support</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>JUnit/Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=junit">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=junit</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.junit.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,junit.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>junit.framework 3.8.1<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.servlet 0.0.0<br>
+javax.servlet.http 0.0.0<br>
+javax.swing 0.0.0<br>
+javax.swing.border 0.0.0<br>
+javax.swing.event 0.0.0<br>
+javax.swing.text 0.0.0<br>
+javax.swing.tree 0.0.0<br>
+javax.xml.parsers 0.0.0<br>
+junit.framework 3.8.1<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+org.w3c.dom 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:08</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/junit/junit</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>JUnit</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>testing</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:junit:3.8.1.kf4-001</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td>javax.xml.parsers, org.w3c.dom</td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a></td></tr>
+<tr><td><a href="../jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td>javax.servlet, javax.servlet.http</td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td>junit.framework, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a></td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml.parsers, org.w3c.dom</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td>junit.framework, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a></td></tr>
+<tr><td><a href="../junit_runner/junit_runner_all-4.0.0.html">junit_runner_all-4.0.0</a></td><td>junit.framework, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/bundle/junit/Activator.java">org/knopflerfish/bundle/junit/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/bundle/junit/HttpExporter.java">org/knopflerfish/bundle/junit/HttpExporter.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/bundle/junit/JUnitCommandGroup.java">org/knopflerfish/bundle/junit/JUnitCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/bundle/junit/JUnitServiceImpl.java">org/knopflerfish/bundle/junit/JUnitServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/bundle/junit/JUnitServlet.java">org/knopflerfish/bundle/junit/JUnitServlet.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/service/junit/JUnitService.java">org/knopflerfish/service/junit/JUnitService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit/src/org/knopflerfish/service/junit/client/JUnitClient.java">org/knopflerfish/service/junit/client/JUnitClient.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/junit_runner/junit_runner_all-4.0.0.html b/docs/jars/junit_runner/junit_runner_all-4.0.0.html
new file mode 100644
index 0000000..82a568a
--- /dev/null
+++ b/docs/jars/junit_runner/junit_runner_all-4.0.0.html
@@ -0,0 +1,190 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>junit_runner_all-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>junit_runner_all-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/junit_runner/junit_runner_all-4.0.0.jar">download</a> (12273 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>JUnitRunner</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.junit_runner</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Grunt, the JUnit test runner. Runs JUnit tests registered in the framework and dumps results to XML files.</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles_opt/junit/junit_runner/readme.txt">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles_opt/junit/junit_runner/readme.txt</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.junit_runner.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>junit.framework 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:11</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/junit/junit_runner</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>testing</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit_runner/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit_runner/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:junit_runner:4.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td>junit.framework, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit_runner/src/org/knopflerfish/bundle/junit_runner/Activator.java">org/knopflerfish/bundle/junit_runner/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/junit/junit_runner/src/org/knopflerfish/bundle/junit_runner/Grunt.java">org/knopflerfish/bundle/junit_runner/Grunt.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/kf_metatype/kf_metatype_all-5.0.2.html b/docs/jars/kf_metatype/kf_metatype_all-5.0.2.html
new file mode 100644
index 0000000..c79f58c
--- /dev/null
+++ b/docs/jars/kf_metatype/kf_metatype_all-5.0.2.html
@@ -0,0 +1,263 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>kf_metatype_all-5.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>kf_metatype_all-5.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/kf_metatype/kf_metatype_all-5.0.2.jar">download</a> (123656 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>KF-XML-Metatype</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.kf_metatype</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>XML format support for CM and Metatype</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish,nanoxml</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.metatype.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,nanoxml-2.2.1.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>net.n3.nanoxml 2.2.1<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>net.n3.nanoxml [2.2.1,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+org.xmlpull.v1 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.osgi.service.metatype.MetaTypeService",osgi.service;  objectClass:List<String>="org.knopflerfish.util.metatype.SystemMetatypeProvider",osgi.service;  objectClass:List<String>="org.osgi.service.cm.ManagedService";  service.pid:String="org.knopflerfish.util.metatype.SystemMetatypeProvider",osgi.service;  objectClass:List<String>="org.osgi.service.cm.ManagedService";  service.pid:String="java.system.properties"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:32</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/metatype/kf_metatype</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:kf_metatype:5.0.2</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td>net.n3.nanoxml, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a></td></tr>
+<tr><td><a href="../kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a>, org.xmlpull.v1</td></tr>
+<tr><td><a href="../metatype/metatype-4.0.0.html">metatype-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td>net.n3.nanoxml, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/bundle/metatype/Activator.java">org/knopflerfish/bundle/metatype/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/AD.java">org/knopflerfish/util/metatype/AD.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/AE.java">org/knopflerfish/util/metatype/AE.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/BundleMetaTypeInformationSnapshot.java">org/knopflerfish/util/metatype/BundleMetaTypeInformationSnapshot.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/BundleMetaTypeResource.java">org/knopflerfish/util/metatype/BundleMetaTypeResource.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/KFLegacyMetaTypeParser.java">org/knopflerfish/util/metatype/KFLegacyMetaTypeParser.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/Loader.java">org/knopflerfish/util/metatype/Loader.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/MTP.java">org/knopflerfish/util/metatype/MTP.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/OCD.java">org/knopflerfish/util/metatype/OCD.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/OsgiMetaTypeXmlParser.java">org/knopflerfish/util/metatype/OsgiMetaTypeXmlParser.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/kf_metatype/src/org/knopflerfish/util/metatype/SystemMetatypeProvider.java">org/knopflerfish/util/metatype/SystemMetatypeProvider.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/kxml/kxml-2.3.0.kf4-001.html b/docs/jars/kxml/kxml-2.3.0.kf4-001.html
new file mode 100644
index 0000000..b2b7477
--- /dev/null
+++ b/docs/jars/kxml/kxml-2.3.0.kf4-001.html
@@ -0,0 +1,240 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>kxml-2.3.0.kf4-001.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>kxml-2.3.0.kf4-001.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/kxml/kxml-2.3.0.kf4-001.jar">download</a> (56795 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>kXML 2-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.kxml-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.3.0.kf4-001</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Packing of kXML 2 as a bundle (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>kXML.org  http://kxml.sourceforge.net/</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://kxml.sourceforge.net/</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=kmxl/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=kmxl/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/kdom/package-summary.html">org.kxml2.kdom</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/wap/package-summary.html">org.kxml2.wap</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/wap/syncml/package-summary.html">org.kxml2.wap.syncml</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/wap/wml/package-summary.html">org.kxml2.wap.wml</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/wap/wv/package-summary.html">org.kxml2.wap.wv</a> 0.0.0<br>
+org.xmlpull.v1 1.1.3.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:02</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/xml/kxml</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>lib</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:kxml:2.3.0.kf4-001:lib</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td>org.xmlpull.v1</td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a>, org.xmlpull.v1</td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a>, org.xmlpull.v1</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/io/KXmlParser.java">org/kxml2/io/KXmlParser.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/io/KXmlSerializer.java">org/kxml2/io/KXmlSerializer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/kdom/Document.java">org/kxml2/kdom/Document.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/kdom/Element.java">org/kxml2/kdom/Element.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/kdom/Node.java">org/kxml2/kdom/Node.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/wap/Wbxml.java">org/kxml2/wap/Wbxml.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/wap/WbxmlParser.java">org/kxml2/wap/WbxmlParser.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/wap/WbxmlSerializer.java">org/kxml2/wap/WbxmlSerializer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/wap/syncml/SyncML.java">org/kxml2/wap/syncml/SyncML.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/wap/wml/Wml.java">org/kxml2/wap/wml/Wml.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/kxml/src/org/kxml2/wap/wv/WV.java">org/kxml2/wap/wv/WV.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/list.html b/docs/jars/list.html
new file mode 100644
index 0000000..e2582c8
--- /dev/null
+++ b/docs/jars/list.html
@@ -0,0 +1,158 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="style.css" rel="stylesheet" type="text/css">
+  <style type="text/css"> 
+      BODY {
+      background: #fff;
+      margin-top:    5px;
+      margin-left:  15px;
+      margin-right: 10px;
+      }
+
+      H2 {
+        color:#802060;
+        font-size:13px;
+        font-weight:bold;
+        margin:6px 0px 6px 0px;	     
+        padding:6px 0px 6px 0px;
+      }
+
+      #bundle_list {
+        margin-left: 8px;
+      }
+
+      #bundle_list A {
+        color: #000;
+        text-decoration: none;
+      }
+	      
+      #bundle_list A:hover {
+        color: #805362;	      
+        text-decoration: underline;
+        font-weight:      bold;
+      }
+  </style>
+</head>
+
+<body>
+<h2>Knopflerfish OSGi 5.1.0 Bundles</h2>
+<a target="_top" href="../index.html">Knopflerfish Documentation</a><br>
+<a target="bundle_main" href="main.html">Bundle Jar Documentation</a><br>
+<a target="bundle_main" href="package_list.html">Bundle Packages</a><br>
+<p></p>
+<div id="bundle_list">
+<a target="bundle_main" href="applicationadmin/applicationadmin_api-4.0.0.html">applicationadmin_api-4.0.0</a><br>
+<a target="bundle_main" href="basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a><br>
+<a target="bundle_main" href="basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a><br>
+<a target="bundle_main" href="blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a><br>
+<a target="bundle_main" href="classpatcher/classpatcher_all-5.0.0.html">classpatcher_all-5.0.0</a><br>
+<a target="bundle_main" href="cm/cm-5.0.1.html">cm-5.0.1</a><br>
+<a target="bundle_main" href="cm/cm_all-5.0.1.html">cm_all-5.0.1</a><br>
+<a target="bundle_main" href="cm/cm_api-5.0.1.html">cm_api-5.0.1</a><br>
+<a target="bundle_main" href="cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a><br>
+<a target="bundle_main" href="cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a><br>
+<a target="bundle_main" href="cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a><br>
+<a target="bundle_main" href="comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a><br>
+<a target="bundle_main" href="comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a><br>
+<a target="bundle_main" href="command/command_all-0.2.html">command_all-0.2</a><br>
+<a target="bundle_main" href="command/command_api-0.2.html">command_api-0.2</a><br>
+<a target="bundle_main" href="commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a><br>
+<a target="bundle_main" href="commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a><br>
+<a target="bundle_main" href="component/component_all-5.0.3.html">component_all-5.0.3</a><br>
+<a target="bundle_main" href="component_annotations/component_annotations_api-1.0.0.html">component_annotations_api-1.0.0</a><br>
+<a target="bundle_main" href="component/component_api-5.0.3.html">component_api-5.0.3</a><br>
+<a target="bundle_main" href="connectors/connectors-3.0.0.html">connectors-3.0.0</a><br>
+<a target="bundle_main" href="connectors/connectors_all-3.0.0.html">connectors_all-3.0.0</a><br>
+<a target="bundle_main" href="console/console-4.0.1.html">console-4.0.1</a><br>
+<a target="bundle_main" href="console2command/console2command-2.0.0.html">console2command-2.0.0</a><br>
+<a target="bundle_main" href="console/console_all-4.0.1.html">console_all-4.0.1</a><br>
+<a target="bundle_main" href="console/console_api-4.0.1.html">console_api-4.0.1</a><br>
+<a target="bundle_main" href="consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a><br>
+<a target="bundle_main" href="consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a><br>
+<a target="bundle_main" href="consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a><br>
+<a target="bundle_main" href="consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a><br>
+<a target="bundle_main" href="coordinator/coordinator_api-1.0.0.html">coordinator_api-1.0.0</a><br>
+<a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+<a target="bundle_main" href="deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a><br>
+<a target="bundle_main" href="desktop/desktop-5.0.1.html">desktop-5.0.1</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a><br>
+<a target="bundle_main" href="desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a><br>
+<a target="bundle_main" href="desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a><br>
+<a target="bundle_main" href="device/device-4.0.1.html">device-4.0.1</a><br>
+<a target="bundle_main" href="device/device_all-4.0.1.html">device_all-4.0.1</a><br>
+<a target="bundle_main" href="device/device_api-4.0.1.html">device_api-4.0.1</a><br>
+<a target="bundle_main" href="dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a><br>
+<a target="bundle_main" href="dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a><br>
+<a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a><br>
+<a target="bundle_main" href="event/event_all-4.0.1.html">event_all-4.0.1</a><br>
+<a target="bundle_main" href="event/event_api-4.0.1.html">event_api-4.0.1</a><br>
+<a target="bundle_main" href="foreignapplication/foreignapplication_api-4.0.0.html">foreignapplication_api-4.0.0</a><br>
+<a target="bundle_main" href="framework.html">framework</a><br>
+<a target="bundle_main" href="frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a><br>
+<a target="bundle_main" href="http/http-4.0.5.html">http-4.0.5</a><br>
+<a target="bundle_main" href="http/http_all-4.0.5.html">http_all-4.0.5</a><br>
+<a target="bundle_main" href="http/http_api-4.0.5.html">http_api-4.0.5</a><br>
+<a target="bundle_main" href="httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a><br>
+<a target="bundle_main" href="httproot/httproot-4.0.0.html">httproot-4.0.0</a><br>
+<a target="bundle_main" href="io/io_all-4.0.0.html">io_all-4.0.0</a><br>
+<a target="bundle_main" href="io/io_api-4.0.0.html">io_api-4.0.0</a><br>
+<a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+<a target="bundle_main" href="jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a><br>
+<a target="bundle_main" href="junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a><br>
+<a target="bundle_main" href="junit_runner/junit_runner_all-4.0.0.html">junit_runner_all-4.0.0</a><br>
+<a target="bundle_main" href="kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a><br>
+<a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+<a target="bundle_main" href="log/log-5.0.0.html">log-5.0.0</a><br>
+<a target="bundle_main" href="log/log_all-5.0.0.html">log_all-5.0.0</a><br>
+<a target="bundle_main" href="log/log_api-5.0.0.html">log_api-5.0.0</a><br>
+<a target="bundle_main" href="logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a><br>
+<a target="bundle_main" href="measurement/measurement-4.0.0.html">measurement-4.0.0</a><br>
+<a target="bundle_main" href="metatype/metatype-4.0.0.html">metatype-4.0.0</a><br>
+<a target="bundle_main" href="monitor/monitor_api-4.0.0.html">monitor_api-4.0.0</a><br>
+<a target="bundle_main" href="namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a><br>
+<a target="bundle_main" href="position/position-4.0.0.html">position-4.0.0</a><br>
+<a target="bundle_main" href="prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a><br>
+<a target="bundle_main" href="prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a><br>
+<a target="bundle_main" href="provisioning/provisioning_api-4.0.0.html">provisioning_api-4.0.0</a><br>
+<a target="bundle_main" href="remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a><br>
+<a target="bundle_main" href="remoteserviceadmin/remoteserviceadmin_api-1.0.0.html">remoteserviceadmin_api-1.0.0</a><br>
+<a target="bundle_main" href="repoindex_kf/repoindex_kf_all-1.0.1.html">repoindex_kf_all-1.0.1</a><br>
+<a target="bundle_main" href="repository/repository_api-1.0.0.html">repository_api-1.0.0</a><br>
+<a target="bundle_main" href="repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a><br>
+<a target="bundle_main" href="repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a><br>
+<a target="bundle_main" href="repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a><br>
+<a target="bundle_main" href="repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a><br>
+<a target="bundle_main" href="repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a><br>
+<a target="bundle_main" href="repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a><br>
+<a target="bundle_main" href="resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a><br>
+<a target="bundle_main" href="rxtxcomm-linux-arm/rxtxcomm-linux-arm-2.1.7.1.html">rxtxcomm-linux-arm-2.1.7.1</a><br>
+<a target="bundle_main" href="rxtxcomm-linux-x86/rxtxcomm-linux-x86-2.2.0.pre2.html">rxtxcomm-linux-x86-2.2.0.pre2</a><br>
+<a target="bundle_main" href="rxtxcomm/rxtxcomm_api-2.2.0.pre2.html">rxtxcomm_api-2.2.0.pre2</a><br>
+<a target="bundle_main" href="scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a><br>
+<a target="bundle_main" href="serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a><br>
+<a target="bundle_main" href="serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a><br>
+<a target="bundle_main" href="serviceloader/serviceloader_api-1.0.0.html">serviceloader_api-1.0.0</a><br>
+<a target="bundle_main" href="sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a><br>
+<a target="bundle_main" href="subsystem/subsystem_api-1.0.0.html">subsystem_api-1.0.0</a><br>
+<a target="bundle_main" href="threadio/threadio-0.2.0.html">threadio-0.2.0</a><br>
+<a target="bundle_main" href="threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a><br>
+<a target="bundle_main" href="threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a><br>
+<a target="bundle_main" href="trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a><br>
+<a target="bundle_main" href="upnp/upnp_api-4.0.0.html">upnp_api-4.0.0</a><br>
+<a target="bundle_main" href="useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a><br>
+<a target="bundle_main" href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a><br>
+<a target="bundle_main" href="useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a><br>
+<a target="bundle_main" href="util/util-4.1.0.html">util-4.1.0</a><br>
+<a target="bundle_main" href="wireadmin/wireadmin_api-5.0.0.html">wireadmin_api-5.0.0</a><br>
+<a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+<a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+<a target="bundle_main" href="xml/xml-4.0.0.html">xml-4.0.0</a><br>
+
+</div>
+</body>
+
+</html>
+
diff --git a/docs/jars/log/log-5.0.0.html b/docs/jars/log/log-5.0.0.html
new file mode 100644
index 0000000..5cab65c
--- /dev/null
+++ b/docs/jars/log/log-5.0.0.html
@@ -0,0 +1,287 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>log-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>log-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/log/log-5.0.0.jar">download</a> (34626 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Log Service-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.log-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The Knopflerfish OSGi log service (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=log/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=log/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.log.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.osgi.service.cm.ManagedService,                            org.knopflerfish.service.log.LogConfig";  service.pid=org.knopflerfish.bundle.log.LogConfig,osgi.service;  objectClass:List<String>="org.osgi.service.log.LogReaderService",osgi.service;  objectClass:List<String>="org.osgi.service.log.LogService,                            org.knopflerfish.service.log.LogService"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:38</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/log</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi/Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:log:5.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/Activator.java">org/knopflerfish/bundle/log/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/FileLog.java">org/knopflerfish/bundle/log/FileLog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogConfigImpl.java">org/knopflerfish/bundle/log/LogConfigImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogEntryImpl.java">org/knopflerfish/bundle/log/LogEntryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogFrameworkListener.java">org/knopflerfish/bundle/log/LogFrameworkListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogReaderServiceFactory.java">org/knopflerfish/bundle/log/LogReaderServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogReaderServiceImpl.java">org/knopflerfish/bundle/log/LogReaderServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogServiceFactory.java">org/knopflerfish/bundle/log/LogServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogServiceImpl.java">org/knopflerfish/bundle/log/LogServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogConfig.java">org/knopflerfish/service/log/LogConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogRef.java">org/knopflerfish/service/log/LogRef.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogService.java">org/knopflerfish/service/log/LogService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogUtil.java">org/knopflerfish/service/log/LogUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogEntry.java">org/osgi/service/log/LogEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogListener.java">org/osgi/service/log/LogListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogReaderService.java">org/osgi/service/log/LogReaderService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogService.java">org/osgi/service/log/LogService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/package-info.java">org/osgi/service/log/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/log/log_all-5.0.0.html b/docs/jars/log/log_all-5.0.0.html
new file mode 100644
index 0000000..71ecfa9
--- /dev/null
+++ b/docs/jars/log/log_all-5.0.0.html
@@ -0,0 +1,329 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>log_all-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>log_all-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/log/log_all-5.0.0.jar">download</a> (42745 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Log Service</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.log</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The Knopflerfish OSGi log service</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=log/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=log/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.log.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> 1.3.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.osgi.service.cm.ManagedService,                            org.knopflerfish.service.log.LogConfig";  service.pid=org.knopflerfish.bundle.log.LogConfig,osgi.service;  objectClass:List<String>="org.osgi.service.log.LogReaderService",osgi.service;  objectClass:List<String>="org.osgi.service.log.LogService,                            org.knopflerfish.service.log.LogService"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:38</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/log</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi/Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:log:5.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/Activator.java">org/knopflerfish/bundle/log/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/FileLog.java">org/knopflerfish/bundle/log/FileLog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogConfigImpl.java">org/knopflerfish/bundle/log/LogConfigImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogEntryImpl.java">org/knopflerfish/bundle/log/LogEntryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogFrameworkListener.java">org/knopflerfish/bundle/log/LogFrameworkListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogReaderServiceFactory.java">org/knopflerfish/bundle/log/LogReaderServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogReaderServiceImpl.java">org/knopflerfish/bundle/log/LogReaderServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogServiceFactory.java">org/knopflerfish/bundle/log/LogServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogServiceImpl.java">org/knopflerfish/bundle/log/LogServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogConfig.java">org/knopflerfish/service/log/LogConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogRef.java">org/knopflerfish/service/log/LogRef.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogService.java">org/knopflerfish/service/log/LogService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogUtil.java">org/knopflerfish/service/log/LogUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogEntry.java">org/osgi/service/log/LogEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogListener.java">org/osgi/service/log/LogListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogReaderService.java">org/osgi/service/log/LogReaderService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogService.java">org/osgi/service/log/LogService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/package-info.java">org/osgi/service/log/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/log/log_api-5.0.0.html b/docs/jars/log/log_api-5.0.0.html
new file mode 100644
index 0000000..175f6f4
--- /dev/null
+++ b/docs/jars/log/log_api-5.0.0.html
@@ -0,0 +1,326 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>log_api-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>log_api-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/log/log_api-5.0.0.jar">download</a> (9179 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Log Service-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.log-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The Knopflerfish OSGi log service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=log/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=log/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> 1.3.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:38</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/log</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi/Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:log:5.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console-4.0.1.html">console-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../device/device-4.0.1.html">device-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/Activator.java">org/knopflerfish/bundle/log/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/FileLog.java">org/knopflerfish/bundle/log/FileLog.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogConfigImpl.java">org/knopflerfish/bundle/log/LogConfigImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogEntryImpl.java">org/knopflerfish/bundle/log/LogEntryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogFrameworkListener.java">org/knopflerfish/bundle/log/LogFrameworkListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogReaderServiceFactory.java">org/knopflerfish/bundle/log/LogReaderServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogReaderServiceImpl.java">org/knopflerfish/bundle/log/LogReaderServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogServiceFactory.java">org/knopflerfish/bundle/log/LogServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/bundle/log/LogServiceImpl.java">org/knopflerfish/bundle/log/LogServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogConfig.java">org/knopflerfish/service/log/LogConfig.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogRef.java">org/knopflerfish/service/log/LogRef.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogService.java">org/knopflerfish/service/log/LogService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/knopflerfish/service/log/LogUtil.java">org/knopflerfish/service/log/LogUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogEntry.java">org/osgi/service/log/LogEntry.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogListener.java">org/osgi/service/log/LogListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogReaderService.java">org/osgi/service/log/LogReaderService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/LogService.java">org/osgi/service/log/LogService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/log/src/org/osgi/service/log/package-info.java">org/osgi/service/log/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/logcommands/logcommands-5.0.0.html b/docs/jars/logcommands/logcommands-5.0.0.html
new file mode 100644
index 0000000..424f5a4
--- /dev/null
+++ b/docs/jars/logcommands/logcommands-5.0.0.html
@@ -0,0 +1,209 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>logcommands-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>logcommands-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/logcommands/logcommands-5.0.0.jar">download</a> (16772 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>LogCommands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.logcommands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Provides log commands for the Knopflerfish console (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=logcommands/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=logcommands/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.logcommands.LogCommands</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.knopflerfish.service.console.CommandGroup";  groupName=log,osgi.service;  objectClass:List<String>="org.knopflerfish.service.console.CommandGroup";  groupName=logconfig</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:46</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/logcommands</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/logcommands/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/logcommands/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:logcommands:5.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/logcommands/src/org/knopflerfish/bundle/logcommands/LogCommandGroup.java">org/knopflerfish/bundle/logcommands/LogCommandGroup.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/logcommands/src/org/knopflerfish/bundle/logcommands/LogCommands.java">org/knopflerfish/bundle/logcommands/LogCommands.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/logcommands/src/org/knopflerfish/bundle/logcommands/LogConfigCommandGroup.java">org/knopflerfish/bundle/logcommands/LogConfigCommandGroup.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/main.html b/docs/jars/main.html
new file mode 100644
index 0000000..dd7eae2
--- /dev/null
+++ b/docs/jars/main.html
@@ -0,0 +1,154 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link type="text/css" href="../css/knopflerfish.css" rel="stylesheet">
+  <link type="text/css" href="style.css" rel="stylesheet">
+  <title>Knopflerfish - Bundle Jar Documentation</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+  <h1 class="kf">Bundle Jar Documentation</h1>
+
+  <p>This section contains information on all bundle jar files
+  included in this distribution of Knopflerfish.</p>
+
+  <p>Select the bundles from the bundle list to the left to view
+  detailed bundle information, including manifest headers, bundle
+  dependencies and derived javadoc links based on imported and
+  exported packages.</p>
+
+  <p>
+<table>
+ <tr><td colspan=2 class="mfheader">Unresolved packages</td></tr>
+ <tr><td>xerces-2.10.1.kf5</td>
+  <td>sun.io 0.0.0 <em>optional</em></td></tr>
+
+</table>
+
+  </p>
+
+  <h2 class="filled">Bundle Jars Listing</h2>
+  <p>
+    <table>
+      <tr><td><a target="bundle_main" href="applicationadmin/applicationadmin_api-4.0.0.html">applicationadmin_api-4.0.0</a></td><td><td>Application Admin API (API)</td></tr>
+<tr><td><a target="bundle_main" href="basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><td>Basic device driver locator (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><td>Basic device driver locator</td></tr>
+<tr><td><a target="bundle_main" href="blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a></td><td><td>Blueprint Container API (API)</td></tr>
+<tr><td><a target="bundle_main" href="classpatcher/classpatcher_all-5.0.0.html">classpatcher_all-5.0.0</a></td><td><td>Implements a WeavingHook to allow patching of classes at load time using ASM</td></tr>
+<tr><td><a target="bundle_main" href="cm/cm-5.0.1.html">cm-5.0.1</a></td><td><td>Configuration Management Service (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><td>Configuration Management Service</td></tr>
+<tr><td><a target="bundle_main" href="cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><td>Configuration Management Service (API)</td></tr>
+<tr><td><a target="bundle_main" href="cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><td>Commands for the CM service (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><td>CM desktop plugin (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><td>CM desktop plugin</td></tr>
+<tr><td><a target="bundle_main" href="comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td><td>Native driver for linux javax.comm using the RXTX library. Note that this bundle is LGPL and contains full source to rxtx</td></tr>
+<tr><td><a target="bundle_main" href="comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td><td>Native driver for win32 javax.comm using Sun's COMM library</td></tr>
+<tr><td><a target="bundle_main" href="command/command_all-0.2.html">command_all-0.2</a></td><td><td>Command Service</td></tr>
+<tr><td><a target="bundle_main" href="command/command_api-0.2.html">command_api-0.2</a></td><td><td>Command Service (API)</td></tr>
+<tr><td><a target="bundle_main" href="commandtty/commandtty-4.0.1.html">commandtty-4.0.1</a></td><td><td>Command line system console (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><td>Apache Commons logging. Publishced under Apache License. See http://www.apache.org/licenses/LICENSE-2.0</td></tr>
+<tr><td><a target="bundle_main" href="component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><td>Declarative Services SCR</td></tr>
+<tr><td><a target="bundle_main" href="component_annotations/component_annotations_api-1.0.0.html">component_annotations_api-1.0.0</a></td><td><td>OSGi specified component annotations (API)</td></tr>
+<tr><td><a target="bundle_main" href="component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><td>Declarative Services SCR (API)</td></tr>
+<tr><td><a target="bundle_main" href="connectors/connectors-3.0.0.html">connectors-3.0.0</a></td><td><td>OSGi IO http, socket and datagram-receive Connectors (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="connectors/connectors_all-3.0.0.html">connectors_all-3.0.0</a></td><td><td>OSGi IO http, socket and datagram-receive Connectors</td></tr>
+<tr><td><a target="bundle_main" href="console/console-4.0.1.html">console-4.0.1</a></td><td><td>Knopflerfish Console Service (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="console2command/console2command-2.0.0.html">console2command-2.0.0</a></td><td><td>Wrapper for KF console commands to RFC147 commands (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><td>Knopflerfish Console Service</td></tr>
+<tr><td><a target="bundle_main" href="console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><td>Knopflerfish Console Service (API)</td></tr>
+<tr><td><a target="bundle_main" href="consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><td>Console Service Server accepting TCP connection. (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><td>Console Service Server accepting TCP connection.</td></tr>
+<tr><td><a target="bundle_main" href="consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><td>Console service server accepting telnet connections. (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="consoletty/consoletty-4.0.1.html">consoletty-4.0.1</a></td><td><td>Console Service Command Line Console (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="coordinator/coordinator_api-1.0.0.html">coordinator_api-1.0.0</a></td><td><td>OSGi specified coordinator service (API)</td></tr>
+<tr><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td><td>The Crimson XML parser</td></tr>
+<tr><td><a target="bundle_main" href="deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a></td><td><td>Deployment Admin API (API)</td></tr>
+<tr><td><a target="bundle_main" href="desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><td>Swing framework desktop (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><td>Swing framework desktop</td></tr>
+<tr><td><a target="bundle_main" href="desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><td>Swing framework desktop (API)</td></tr>
+<tr><td><a target="bundle_main" href="desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><td>JVM info desktop plugin (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><td>JVM info desktop plugin</td></tr>
+<tr><td><a target="bundle_main" href="device/device-4.0.1.html">device-4.0.1</a></td><td><td>Device manager (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><td>Device manager</td></tr>
+<tr><td><a target="bundle_main" href="device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><td>Device manager (API)</td></tr>
+<tr><td><a target="bundle_main" href="dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a></td><td><td>Monitors a set of file system directory for bundlesand configurations to deploy</td></tr>
+<tr><td><a target="bundle_main" href="dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a></td><td><td>Monitors a set of file system directory for bundlesand configurations to deploy (API)</td></tr>
+<tr><td><a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a></td><td><td>DMT (API)</td></tr>
+<tr><td><a target="bundle_main" href="event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><td>Event Admin</td></tr>
+<tr><td><a target="bundle_main" href="event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><td>Event Admin (API)</td></tr>
+<tr><td><a target="bundle_main" href="foreignapplication/foreignapplication_api-4.0.0.html">foreignapplication_api-4.0.0</a></td><td><td>Foreign Application Access API (API)</td></tr>
+<tr><td><a target="bundle_main" href="framework.html">framework</a></td><td><td>Knopflerfish OSGi framework system bundle</td></tr>
+<tr><td><a target="bundle_main" href="frameworkcommands/frameworkcommands-4.0.1.html">frameworkcommands-4.0.1</a></td><td><td>Framework commands (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="http/http-4.0.5.html">http-4.0.5</a></td><td><td>HTTP/HTTPS Server (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><td>HTTP/HTTPS Server</td></tr>
+<tr><td><a target="bundle_main" href="http/http_api-4.0.5.html">http_api-4.0.5</a></td><td><td>HTTP/HTTPS Server (API)</td></tr>
+<tr><td><a target="bundle_main" href="httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><td></td></tr>
+<tr><td><a target="bundle_main" href="httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><td>Demo HTTP Service user that publishes on the root (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="io/io_all-4.0.0.html">io_all-4.0.0</a></td><td><td>IO</td></tr>
+<tr><td><a target="bundle_main" href="io/io_api-4.0.0.html">io_api-4.0.0</a></td><td><td>IO (API)</td></tr>
+<tr><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a></td><td><td>Jini driver (experimental) using Sun's jini impl. jini-core.jar and jini-ext.jar, see http://wwws.sun.com/software/jini/licensing/SCSL3_JiniTSA1.html</td></tr>
+<tr><td><a target="bundle_main" href="jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a></td><td><td>The servlet API classes (API)</td></tr>
+<tr><td><a target="bundle_main" href="junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td><td>JUnit support</td></tr>
+<tr><td><a target="bundle_main" href="junit_runner/junit_runner_all-4.0.0.html">junit_runner_all-4.0.0</a></td><td><td>Grunt, the JUnit test runner. Runs JUnit tests registered in the framework and dumps results to XML files.</td></tr>
+<tr><td><a target="bundle_main" href="kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><td>XML format support for CM and Metatype</td></tr>
+<tr><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td><td><td>Packing of kXML 2 as a bundle (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="log/log-5.0.0.html">log-5.0.0</a></td><td><td>The Knopflerfish OSGi log service (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><td>The Knopflerfish OSGi log service</td></tr>
+<tr><td><a target="bundle_main" href="log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><td>The Knopflerfish OSGi log service (API)</td></tr>
+<tr><td><a target="bundle_main" href="logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><td>Provides log commands for the Knopflerfish console (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="measurement/measurement-4.0.0.html">measurement-4.0.0</a></td><td><td>Measurement API (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="metatype/metatype-4.0.0.html">metatype-4.0.0</a></td><td><td>Metatype API (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="monitor/monitor_api-4.0.0.html">monitor_api-4.0.0</a></td><td><td>Monitor Admin API (API)</td></tr>
+<tr><td><a target="bundle_main" href="namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a></td><td><td>OSGi Namespace (API)</td></tr>
+<tr><td><a target="bundle_main" href="position/position-4.0.0.html">position-4.0.0</a></td><td><td>Position API (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><td>Preferences</td></tr>
+<tr><td><a target="bundle_main" href="prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><td>Preferences (API)</td></tr>
+<tr><td><a target="bundle_main" href="provisioning/provisioning_api-4.0.0.html">provisioning_api-4.0.0</a></td><td><td>Initial Provisioning (API)</td></tr>
+<tr><td><a target="bundle_main" href="remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><td>Remote Framework (API)</td></tr>
+<tr><td><a target="bundle_main" href="remoteserviceadmin/remoteserviceadmin_api-1.0.0.html">remoteserviceadmin_api-1.0.0</a></td><td><td>OSGi specified remote service admin service (API)</td></tr>
+<tr><td><a target="bundle_main" href="repoindex_kf/repoindex_kf_all-1.0.1.html">repoindex_kf_all-1.0.1</a></td><td><td>KF Resource Analyzer Extensions</td></tr>
+<tr><td><a target="bundle_main" href="repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><td>Repository API (API)</td></tr>
+<tr><td><a target="bundle_main" href="repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><td>Knopflerfish desktop plugin visualizing OSGi Repository contents.</td></tr>
+<tr><td><a target="bundle_main" href="repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><td>Xml Backed Repository</td></tr>
+<tr><td><a target="bundle_main" href="repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><td>Xml Backed Repository (API)</td></tr>
+<tr><td><a target="bundle_main" href="repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><td>Repository commands (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><td>Repository Manager</td></tr>
+<tr><td><a target="bundle_main" href="repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><td>Repository Manager (API)</td></tr>
+<tr><td><a target="bundle_main" href="resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a></td><td><td>Resolver API (API)</td></tr>
+<tr><td><a target="bundle_main" href="rxtxcomm-linux-arm/rxtxcomm-linux-arm-2.1.7.1.html">rxtxcomm-linux-arm-2.1.7.1</a></td><td><td>RXTX comm native driver for Linux/arm_le (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="rxtxcomm-linux-x86/rxtxcomm-linux-x86-2.2.0.pre2.html">rxtxcomm-linux-x86-2.2.0.pre2</a></td><td><td>RXTX comm native driver for Linux/x86 (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="rxtxcomm/rxtxcomm_api-2.2.0.pre2.html">rxtxcomm_api-2.2.0.pre2</a></td><td><td>RXTX comm java library, requires native driver fragment (API)</td></tr>
+<tr><td><a target="bundle_main" href="scrcommands/scrcommands-4.0.1.html">scrcommands-4.0.1</a></td><td><td>Provides SCR admin commands for the Knopflerfish console (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><td>Serial port device</td></tr>
+<tr><td><a target="bundle_main" href="serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><td>Serial port device (API)</td></tr>
+<tr><td><a target="bundle_main" href="serviceloader/serviceloader_api-1.0.0.html">serviceloader_api-1.0.0</a></td><td><td>OSGi specified serviceloader service (API)</td></tr>
+<tr><td><a target="bundle_main" href="sslj2sp/sslj2sp-4.0.0.html">sslj2sp-4.0.0</a></td><td><td>SSL Provider using the Java 2 security architecture. (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="subsystem/subsystem_api-1.0.0.html">subsystem_api-1.0.0</a></td><td><td>OSGi specified subsytem service (API)</td></tr>
+<tr><td><a target="bundle_main" href="threadio/threadio-0.2.0.html">threadio-0.2.0</a></td><td><td>ThreadIO Service (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><td>ThreadIO Service</td></tr>
+<tr><td><a target="bundle_main" href="threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><td>ThreadIO Service (API)</td></tr>
+<tr><td><a target="bundle_main" href="trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><td>Framework tray icon. Allows basic control of the framework using the windows system tray.</td></tr>
+<tr><td><a target="bundle_main" href="upnp/upnp_api-4.0.0.html">upnp_api-4.0.0</a></td><td><td>UPnP (API)</td></tr>
+<tr><td><a target="bundle_main" href="useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><td>User Administration Service (IMPL)</td></tr>
+<tr><td><a target="bundle_main" href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><td>User Administration Service</td></tr>
+<tr><td><a target="bundle_main" href="useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><td>User Administration Service (API)</td></tr>
+<tr><td><a target="bundle_main" href="util/util-4.1.0.html">util-4.1.0</a></td><td><td>Misc utilities (LIB)</td></tr>
+<tr><td><a target="bundle_main" href="wireadmin/wireadmin_api-5.0.0.html">wireadmin_api-5.0.0</a></td><td><td>WireAdmin (API)</td></tr>
+<tr><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td><td>The Apache Xalan-Java XML transformer</td></tr>
+<tr><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td><td>The Apache Xerces2 Java XML parser</td></tr>
+<tr><td><a target="bundle_main" href="xml/xml-4.0.0.html">xml-4.0.0</a></td><td><td>XML (LIB)</td></tr>
+
+    </table>
+  </p>
+
+</body>
+</html>
+
diff --git a/docs/jars/measurement/measurement-4.0.0.html b/docs/jars/measurement/measurement-4.0.0.html
new file mode 100644
index 0000000..049b83b
--- /dev/null
+++ b/docs/jars/measurement/measurement-4.0.0.html
@@ -0,0 +1,204 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>measurement-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>measurement-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/measurement/measurement-4.0.0.jar">download</a> (9239 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>measurement-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.measurement-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Measurement API (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a> [1.0.0,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:11</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/measurement</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/measurement/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/measurement/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:measurement:4.0.0:lib</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../measurement/measurement-4.0.0.html">measurement-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../measurement/measurement-4.0.0.html">measurement-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a></td></tr>
+<tr><td><a href="../position/position-4.0.0.html">position-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/measurement/src/org/osgi/util/measurement/Measurement.java">org/osgi/util/measurement/Measurement.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/measurement/src/org/osgi/util/measurement/State.java">org/osgi/util/measurement/State.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/measurement/src/org/osgi/util/measurement/Unit.java">org/osgi/util/measurement/Unit.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/measurement/src/org/osgi/util/measurement/package-info.java">org/osgi/util/measurement/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/metatype/metatype-4.0.0.html b/docs/jars/metatype/metatype-4.0.0.html
new file mode 100644
index 0000000..1fc1657
--- /dev/null
+++ b/docs/jars/metatype/metatype-4.0.0.html
@@ -0,0 +1,215 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>metatype-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>metatype-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/metatype/metatype-4.0.0.jar">download</a> (5291 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>metatype-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.metatype-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Metatype API (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a> 1.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:17</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/metatype/metatype_api</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:metatype:4.0.0:lib</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/src/org/osgi/service/metatype/AttributeDefinition.java">org/osgi/service/metatype/AttributeDefinition.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/src/org/osgi/service/metatype/MetaTypeInformation.java">org/osgi/service/metatype/MetaTypeInformation.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/src/org/osgi/service/metatype/MetaTypeProvider.java">org/osgi/service/metatype/MetaTypeProvider.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/src/org/osgi/service/metatype/MetaTypeService.java">org/osgi/service/metatype/MetaTypeService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/src/org/osgi/service/metatype/ObjectClassDefinition.java">org/osgi/service/metatype/ObjectClassDefinition.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/metatype/metatype_api/src/org/osgi/service/metatype/package-info.java">org/osgi/service/metatype/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/monitor/monitor_api-4.0.0.html b/docs/jars/monitor/monitor_api-4.0.0.html
new file mode 100644
index 0000000..133c15a
--- /dev/null
+++ b/docs/jars/monitor/monitor_api-4.0.0.html
@@ -0,0 +1,218 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>monitor_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>monitor_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/monitor/monitor_api-4.0.0.jar">download</a> (9454 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>monitor-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.monitor-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Monitor Admin API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/monitor/package-summary.html">org.osgi.service.monitor</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/monitor/package-summary.html">org.osgi.service.monitor</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:59</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/monitor</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:monitor:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../monitor/monitor_api-4.0.0.html">monitor_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/monitor/package-summary.html">org.osgi.service.monitor</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../monitor/monitor_api-4.0.0.html">monitor_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/monitor/package-summary.html">org.osgi.service.monitor</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/MonitorAdmin.java">org/osgi/service/monitor/MonitorAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/MonitorListener.java">org/osgi/service/monitor/MonitorListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/MonitorPermission.java">org/osgi/service/monitor/MonitorPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/Monitorable.java">org/osgi/service/monitor/Monitorable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/MonitoringJob.java">org/osgi/service/monitor/MonitoringJob.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/StatusVariable.java">org/osgi/service/monitor/StatusVariable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/monitor/src/org/osgi/service/monitor/package-info.java">org/osgi/service/monitor/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/namespace/namespace_api-1.0.0.html b/docs/jars/namespace/namespace_api-1.0.0.html
new file mode 100644
index 0000000..dac8ce9
--- /dev/null
+++ b/docs/jars/namespace/namespace_api-1.0.0.html
@@ -0,0 +1,219 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>namespace_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>namespace_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/namespace/namespace_api-1.0.0.jar">download</a> (3654 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Namespace-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.namespace-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi Namespace (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/namespace/contract/package-summary.html">org.osgi.namespace.contract</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/namespace/extender/package-summary.html">org.osgi.namespace.extender</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/namespace/service/package-summary.html">org.osgi.namespace.service</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/namespace/contract/package-summary.html">org.osgi.namespace.contract</a> [1.0.0,1.1.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/namespace/extender/package-summary.html">org.osgi.namespace.extender</a> [1.0.0,1.1.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/namespace/service/package-summary.html">org.osgi.namespace.service</a> [1.0.0,1.1.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:25:53</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/namespace</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:namespace:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/namespace/contract/package-summary.html">org.osgi.namespace.contract</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/namespace/extender/package-summary.html">org.osgi.namespace.extender</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/namespace/service/package-summary.html">org.osgi.namespace.service</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/namespace/contract/package-summary.html">org.osgi.namespace.contract</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/namespace/extender/package-summary.html">org.osgi.namespace.extender</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/namespace/service/package-summary.html">org.osgi.namespace.service</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/src/org/osgi/namespace/contract/ContractNamespace.java">org/osgi/namespace/contract/ContractNamespace.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/src/org/osgi/namespace/contract/package-info.java">org/osgi/namespace/contract/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/src/org/osgi/namespace/extender/ExtenderNamespace.java">org/osgi/namespace/extender/ExtenderNamespace.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/src/org/osgi/namespace/extender/package-info.java">org/osgi/namespace/extender/package-info.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/src/org/osgi/namespace/service/ServiceNamespace.java">org/osgi/namespace/service/ServiceNamespace.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/namespace/src/org/osgi/namespace/service/package-info.java">org/osgi/namespace/service/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/package_list.html b/docs/jars/package_list.html
new file mode 100644
index 0000000..1aab2f2
--- /dev/null
+++ b/docs/jars/package_list.html
@@ -0,0 +1,424 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="style.css" rel="stylesheet" type="text/css">
+  <style type="text/css"> 
+      BODY {
+      background: #fff;
+      margin-top:    5px;
+      margin-left:  15px;
+      margin-right: 10px;
+      }
+
+      #package_list {
+        margin-left: 8px;
+      }
+
+      #package_list A {
+        color: #000;
+        text-decoration: none;
+      }
+	      
+      #package_list A:hover {
+        color: #805362;	      
+        text-decoration: underline;
+        font-weight:     bold;
+      }
+  </style>
+  <title>Knopflerfish Bundle Packages</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+  <div id="package_list">
+    <table>
+      <tr><th>Package</th><th>Provider(s)</th></tr>
+      <tr><td><a target="_top" href="../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a> 2.0.0</td><td><a target="bundle_main" href="comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a> 2.2.0</td><td><a target="bundle_main" href="rxtxcomm/rxtxcomm_api-2.2.0.pre2.html">rxtxcomm_api-2.2.0.pre2</a><br>
+</td></tr>
+<tr><td>javax.comm 2.0.0</td><td><a target="bundle_main" href="comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a><br>
+<a target="bundle_main" href="comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a><br>
+</td></tr>
+<tr><td>javax.microedition.io 0.0.0</td><td><a target="bundle_main" href="io/io_all-4.0.0.html">io_all-4.0.0</a><br>
+<a target="bundle_main" href="io/io_api-4.0.0.html">io_api-4.0.0</a><br>
+</td></tr>
+<tr><td>javax.servlet 2.5.0</td><td><a target="bundle_main" href="jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a><br>
+</td></tr>
+<tr><td>javax.servlet.http 2.5.0</td><td><a target="bundle_main" href="jsdk/jsdk_api-2.5.0.kf3-2.html">jsdk_api-2.5.0.kf3-2</a><br>
+</td></tr>
+<tr><td>javax.xml 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.datatype 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.namespace 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.parsers 1.2.0</td><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+</td></tr>
+<tr><td>javax.xml.parsers 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.transform 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.transform 1.3.0.selectFirst</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td>javax.xml.transform.dom 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.transform.dom 1.3.0.selectFirst</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td>javax.xml.transform.sax 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.transform.sax 1.3.0.selectFirst</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td>javax.xml.transform.stream 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.transform.stream 1.3.0.selectFirst</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td>javax.xml.validation 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>javax.xml.xpath 1.3.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>junit.framework 3.8.1</td><td><a target="bundle_main" href="junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a><br>
+</td></tr>
+<tr><td>net.jini.admin 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.core.discovery 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.core.entry 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.core.event 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.core.lease 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.core.lookup 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.discovery 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.lease 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.lookup 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.jini.lookup.entry 0.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td>net.n3.nanoxml 2.2.1</td><td><a target="bundle_main" href="kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/apache/commons/logging/package-summary.html">org.apache.commons.logging</a> 1.0.3</td><td><a target="bundle_main" href="commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a><br>
+</td></tr>
+<tr><td>org.apache.crimson.jaxp 0.0.0</td><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> 1.6.0</td><td><a target="bundle_main" href="component/component_all-5.0.3.html">component_all-5.0.3</a><br>
+<a target="bundle_main" href="component/component_api-5.0.3.html">component_api-5.0.3</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+</td></tr>
+<tr><td>org.apache.html.dom 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.wml 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.wml.dom 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xalan 0.0.0</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td>org.apache.xalan.processor 0.0.0</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.dom 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.dom.events 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.dom3.as 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.jaxp 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.jaxp.datatype 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.jaxp.validation 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.parsers 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.util 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xinclude 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xni 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xni.grammars 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xni.parser 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xpointer 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xs 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xerces.xs.datatypes 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.resolver 1.2.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.resolver.apps 1.2.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.resolver.helpers 1.2.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.resolver.readers 1.2.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.resolver.tools 1.2.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.serialize 0.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xml.serializer 1.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.apache.xpath.jaxp 0.0.0</td><td><a target="bundle_main" href="xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> 2.1.2</td><td><a target="bundle_main" href="console/console_all-4.0.1.html">console_all-4.0.1</a><br>
+<a target="bundle_main" href="console/console_api-4.0.1.html">console_api-4.0.1</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> 2.2.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/dirdeployer/package-summary.html">org.knopflerfish.service.dirdeployer</a> 0.0.0</td><td><a target="bundle_main" href="dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a><br>
+<a target="bundle_main" href="dirdeployer/dirdeployer_api-4.0.1.html">dirdeployer_api-4.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/junit/package-summary.html">org.knopflerfish.service.junit</a> 1.0.0</td><td><a target="bundle_main" href="junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0</td><td><a target="bundle_main" href="commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="http/http_all-4.0.5.html">http_all-4.0.5</a><br>
+<a target="bundle_main" href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a><br>
+<a target="bundle_main" href="useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a><br>
+<a target="bundle_main" href="log/log_all-5.0.0.html">log_all-5.0.0</a><br>
+<a target="bundle_main" href="log/log_api-5.0.0.html">log_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a> 0.0.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a> 1.0.0</td><td><a target="bundle_main" href="repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a><br>
+<a target="bundle_main" href="repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> 1.2.0</td><td><a target="bundle_main" href="repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a><br>
+<a target="bundle_main" href="repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a> 0.0.0</td><td><a target="bundle_main" href="serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a><br>
+<a target="bundle_main" href="serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a> 1.0.0</td><td><a target="bundle_main" href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a><br>
+<a target="bundle_main" href="useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> 1.0.0</td><td><a target="bundle_main" href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a><br>
+<a target="bundle_main" href="useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/shared/cm/package-summary.html">org.knopflerfish.shared.cm</a> 1.1.0</td><td><a target="bundle_main" href="cm/cm_all-5.0.1.html">cm_all-5.0.1</a><br>
+<a target="bundle_main" href="cm/cm-5.0.1.html">cm-5.0.1</a><br>
+<a target="bundle_main" href="cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a><br>
+<a target="bundle_main" href="dirdeployer/dirdeployer_all-4.0.1.html">dirdeployer_all-4.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> 1.1.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="util/util-4.1.0.html">util-4.1.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a> 1.0.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="util/util-4.1.0.html">util-4.1.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/util/metatype/package-summary.html">org.knopflerfish.util.metatype</a> 0.0.0</td><td><a target="bundle_main" href="kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a> 1.0.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="util/util-4.1.0.html">util-4.1.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/knopflerfish/util/workerthread/package-summary.html">org.knopflerfish.util.workerthread</a> 1.0.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="util/util-4.1.0.html">util-4.1.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a> 0.0.0</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/kxml2/kdom/package-summary.html">org.kxml2.kdom</a> 0.0.0</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/kxml2/wap/package-summary.html">org.kxml2.wap</a> 0.0.0</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/kxml2/wap/syncml/package-summary.html">org.kxml2.wap.syncml</a> 0.0.0</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/kxml2/wap/wml/package-summary.html">org.kxml2.wap.wml</a> 0.0.0</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/kxml2/wap/wv/package-summary.html">org.kxml2.wap.wv</a> 0.0.0</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/application/package-summary.html">org.osgi.application</a> 1.0.0</td><td><a target="bundle_main" href="foreignapplication/foreignapplication_api-4.0.0.html">foreignapplication_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 1.7.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/bundle/package-summary.html">org.osgi.framework.hooks.bundle</a> 1.1.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/resolver/package-summary.html">org.osgi.framework.hooks.resolver</a> 1.0.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/service/package-summary.html">org.osgi.framework.hooks.service</a> 1.1.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/hooks/weaving/package-summary.html">org.osgi.framework.hooks.weaving</a> 1.0.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/launch/package-summary.html">org.osgi.framework.launch</a> 1.1.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/namespace/package-summary.html">org.osgi.framework.namespace</a> 1.0.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> 1.0.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> 1.1.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/namespace/contract/package-summary.html">org.osgi.namespace.contract</a> 1.0.0</td><td><a target="bundle_main" href="namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/namespace/extender/package-summary.html">org.osgi.namespace.extender</a> 1.0.0</td><td><a target="bundle_main" href="namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/namespace/service/package-summary.html">org.osgi.namespace.service</a> 1.0.0</td><td><a target="bundle_main" href="namespace/namespace_api-1.0.0.html">namespace_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 1.0.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/application/package-summary.html">org.osgi.service.application</a> 1.1.0</td><td><a target="bundle_main" href="applicationadmin/applicationadmin_api-4.0.0.html">applicationadmin_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/blueprint/container/package-summary.html">org.osgi.service.blueprint.container</a> 1.0.2</td><td><a target="bundle_main" href="blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/blueprint/reflect/package-summary.html">org.osgi.service.blueprint.reflect</a> 1.0.1</td><td><a target="bundle_main" href="blueprint/blueprint_api-5.0.0.html">blueprint_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> 1.5.0</td><td><a target="bundle_main" href="cm/cm_all-5.0.1.html">cm_all-5.0.1</a><br>
+<a target="bundle_main" href="cm/cm_api-5.0.1.html">cm_api-5.0.1</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/command/package-summary.html">org.osgi.service.command</a> 1.0.0</td><td><a target="bundle_main" href="command/command_all-0.2.html">command_all-0.2</a><br>
+<a target="bundle_main" href="command/command_api-0.2.html">command_api-0.2</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> 1.2.1</td><td><a target="bundle_main" href="component/component_all-5.0.3.html">component_all-5.0.3</a><br>
+<a target="bundle_main" href="component/component_api-5.0.3.html">component_api-5.0.3</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/component/annotations/package-summary.html">org.osgi.service.component.annotations</a> 1.2.0</td><td><a target="bundle_main" href="component_annotations/component_annotations_api-1.0.0.html">component_annotations_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/condpermadmin/package-summary.html">org.osgi.service.condpermadmin</a> 1.1.1</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/coordinator/package-summary.html">org.osgi.service.coordinator</a> 1.0.1</td><td><a target="bundle_main" href="coordinator/coordinator_api-1.0.0.html">coordinator_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/deploymentadmin/package-summary.html">org.osgi.service.deploymentadmin</a> 1.1.0</td><td><a target="bundle_main" href="deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/deploymentadmin/spi/package-summary.html">org.osgi.service.deploymentadmin.spi</a> 1.0.1</td><td><a target="bundle_main" href="deploymentadmin/deploymentadmin_api-4.0.0.html">deploymentadmin_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> 1.1.0</td><td><a target="bundle_main" href="device/device_all-4.0.1.html">device_all-4.0.1</a><br>
+<a target="bundle_main" href="device/device_api-4.0.1.html">device_api-4.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/dmt/package-summary.html">org.osgi.service.dmt</a> 2.0.1</td><td><a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/dmt/notification/package-summary.html">org.osgi.service.dmt.notification</a> 2.0.0</td><td><a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/dmt/notification/spi/package-summary.html">org.osgi.service.dmt.notification.spi</a> 2.0.0</td><td><a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/dmt/security/package-summary.html">org.osgi.service.dmt.security</a> 2.0.0</td><td><a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/dmt/spi/package-summary.html">org.osgi.service.dmt.spi</a> 2.0.0</td><td><a target="bundle_main" href="dmt/dmt_api-5.0.0.html">dmt_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> 1.3.0</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="event/event_all-4.0.1.html">event_all-4.0.1</a><br>
+<a target="bundle_main" href="event/event_api-4.0.1.html">event_api-4.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/http/package-summary.html">org.osgi.service.http</a> 1.2.1</td><td><a target="bundle_main" href="http/http_all-4.0.5.html">http_all-4.0.5</a><br>
+<a target="bundle_main" href="http/http_api-4.0.5.html">http_api-4.0.5</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/indexer/package-summary.html">org.osgi.service.indexer</a> 1.0.2</td><td><a target="bundle_main" href="repoindex_kf/repoindex_kf_all-1.0.1.html">repoindex_kf_all-1.0.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/io/package-summary.html">org.osgi.service.io</a> 1.0.0</td><td><a target="bundle_main" href="io/io_all-4.0.0.html">io_all-4.0.0</a><br>
+<a target="bundle_main" href="io/io_api-4.0.0.html">io_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/jini/package-summary.html">org.osgi.service.jini</a> 1.0.0</td><td><a target="bundle_main" href="jinidriver/jinidriver_all-0.1.0.html">jinidriver_all-0.1.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> 1.3.0</td><td><a target="bundle_main" href="commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a><br>
+<a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="log/log_all-5.0.0.html">log_all-5.0.0</a><br>
+<a target="bundle_main" href="log/log_api-5.0.0.html">log_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/metatype/package-summary.html">org.osgi.service.metatype</a> 1.2.0</td><td><a target="bundle_main" href="metatype/metatype-4.0.0.html">metatype-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/monitor/package-summary.html">org.osgi.service.monitor</a> 1.0.0</td><td><a target="bundle_main" href="monitor/monitor_api-4.0.0.html">monitor_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/packageadmin/package-summary.html">org.osgi.service.packageadmin</a> 1.2.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/permissionadmin/package-summary.html">org.osgi.service.permissionadmin</a> 1.2.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> 1.1.1</td><td><a target="bundle_main" href="desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a><br>
+<a target="bundle_main" href="prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a><br>
+<a target="bundle_main" href="prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/provisioning/package-summary.html">org.osgi.service.provisioning</a> 1.2.0</td><td><a target="bundle_main" href="provisioning/provisioning_api-4.0.0.html">provisioning_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/remoteserviceadmin/package-summary.html">org.osgi.service.remoteserviceadmin</a> 1.0.1</td><td><a target="bundle_main" href="remoteserviceadmin/remoteserviceadmin_api-1.0.0.html">remoteserviceadmin_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> 1.0.0</td><td><a target="bundle_main" href="repository/repository_api-1.0.0.html">repository_api-1.0.0</a><br>
+<a target="bundle_main" href="repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a> 1.0.1</td><td><a target="bundle_main" href="repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a><br>
+<a target="bundle_main" href="resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/serviceloader/package-summary.html">org.osgi.service.serviceloader</a> 1.0.0</td><td><a target="bundle_main" href="serviceloader/serviceloader_api-1.0.0.html">serviceloader_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/startlevel/package-summary.html">org.osgi.service.startlevel</a> 1.1.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/subsystem/package-summary.html">org.osgi.service.subsystem</a> 1.0.0</td><td><a target="bundle_main" href="subsystem/subsystem_api-1.0.0.html">subsystem_api-1.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> 1.0.0</td><td><a target="bundle_main" href="threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a><br>
+<a target="bundle_main" href="threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/upnp/package-summary.html">org.osgi.service.upnp</a> 1.2.0</td><td><a target="bundle_main" href="upnp/upnp_api-4.0.0.html">upnp_api-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/url/package-summary.html">org.osgi.service.url</a> 1.0.0</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> 1.1.0</td><td><a target="bundle_main" href="useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a><br>
+<a target="bundle_main" href="useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/service/wireadmin/package-summary.html">org.osgi.service.wireadmin</a> 1.0.1</td><td><a target="bundle_main" href="wireadmin/wireadmin_api-5.0.0.html">wireadmin_api-5.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a> 1.0.1</td><td><a target="bundle_main" href="measurement/measurement-4.0.0.html">measurement-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/util/position/package-summary.html">org.osgi.util.position</a> 1.0.1</td><td><a target="bundle_main" href="position/position-4.0.0.html">position-4.0.0</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> 1.5.1</td><td><a target="bundle_main" href="framework.html">framework</a><br>
+</td></tr>
+<tr><td><a target="_top" href="../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a> 1.0.1</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+<a target="bundle_main" href="xml/xml-4.0.0.html">xml-4.0.0</a><br>
+</td></tr>
+<tr><td>org.w3c.dom 2.0.0</td><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+</td></tr>
+<tr><td>org.w3c.dom 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.bootstrap 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.css 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.events 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.html 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.ls 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.ranges 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.stylesheets 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.traversal 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.views 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.w3c.dom.xpath 3.0.0</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.xml.sax 2.0.0</td><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+</td></tr>
+<tr><td>org.xml.sax 2.0.2</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.xml.sax.ext 1.0.0</td><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+</td></tr>
+<tr><td>org.xml.sax.ext 2.0.2</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.xml.sax.helpers 2.0.0</td><td><a target="bundle_main" href="crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a><br>
+</td></tr>
+<tr><td>org.xml.sax.helpers 2.0.2</td><td><a target="bundle_main" href="xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a><br>
+</td></tr>
+<tr><td>org.xmlpull.v1 1.1.3.1</td><td><a target="bundle_main" href="kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a><br>
+</td></tr>
+
+    </table>
+  </div>
+</body>
+
+</html>
+
diff --git a/docs/jars/position/position-4.0.0.html b/docs/jars/position/position-4.0.0.html
new file mode 100644
index 0000000..ca68404
--- /dev/null
+++ b/docs/jars/position/position-4.0.0.html
@@ -0,0 +1,195 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>position-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>position-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/position/position-4.0.0.jar">download</a> (4350 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>position-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.position-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Position API (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/util/position/package-summary.html">org.osgi.util.position</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/position/package-summary.html">org.osgi.util.position</a> [1.0.0,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:15</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/position</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/position/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/position/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:position:4.0.0:lib</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../measurement/measurement-4.0.0.html">measurement-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/measurement/package-summary.html">org.osgi.util.measurement</a></td></tr>
+<tr><td><a href="../position/position-4.0.0.html">position-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/position/package-summary.html">org.osgi.util.position</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../position/position-4.0.0.html">position-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/position/package-summary.html">org.osgi.util.position</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/position/src/org/osgi/util/position/Position.java">org/osgi/util/position/Position.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/position/src/org/osgi/util/position/package-info.java">org/osgi/util/position/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/prefs/prefs_all-4.0.2.html b/docs/jars/prefs/prefs_all-4.0.2.html
new file mode 100644
index 0000000..e380099
--- /dev/null
+++ b/docs/jars/prefs/prefs_all-4.0.2.html
@@ -0,0 +1,253 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>prefs_all-4.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>prefs_all-4.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/prefs/prefs_all-4.0.2.jar">download</a> (26716 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Prefs</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.prefs</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Preferences</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=prefs/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=prefs/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.prefs.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> 1.1.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> [1.1.0,1.2.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:32</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/prefs</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:prefs:4.0.2</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/Activator.java">org/knopflerfish/bundle/prefs/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PreferencesImpl.java">org/knopflerfish/bundle/prefs/PreferencesImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PreferencesServiceFactory.java">org/knopflerfish/bundle/prefs/PreferencesServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PreferencesServiceImpl.java">org/knopflerfish/bundle/prefs/PreferencesServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PrefsStorage.java">org/knopflerfish/bundle/prefs/PrefsStorage.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PrefsStorageFile.java">org/knopflerfish/bundle/prefs/PrefsStorageFile.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/BackingStoreException.java">org/osgi/service/prefs/BackingStoreException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/Preferences.java">org/osgi/service/prefs/Preferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/PreferencesService.java">org/osgi/service/prefs/PreferencesService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/package-info.java">org/osgi/service/prefs/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/prefs/prefs_api-4.0.2.html b/docs/jars/prefs/prefs_api-4.0.2.html
new file mode 100644
index 0000000..27b7308
--- /dev/null
+++ b/docs/jars/prefs/prefs_api-4.0.2.html
@@ -0,0 +1,242 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>prefs_api-4.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>prefs_api-4.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/prefs/prefs_api-4.0.2.jar">download</a> (3019 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Prefs-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.prefs-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Preferences (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=prefs/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=prefs/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> 1.1.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a> [1.1.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:32</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/prefs</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:prefs:4.0.2:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+<tr><td><a href="../prefs/prefs_api-4.0.2.html">prefs_api-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/prefs/package-summary.html">org.osgi.service.prefs</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/Activator.java">org/knopflerfish/bundle/prefs/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PreferencesImpl.java">org/knopflerfish/bundle/prefs/PreferencesImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PreferencesServiceFactory.java">org/knopflerfish/bundle/prefs/PreferencesServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PreferencesServiceImpl.java">org/knopflerfish/bundle/prefs/PreferencesServiceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PrefsStorage.java">org/knopflerfish/bundle/prefs/PrefsStorage.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/knopflerfish/bundle/prefs/PrefsStorageFile.java">org/knopflerfish/bundle/prefs/PrefsStorageFile.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/BackingStoreException.java">org/osgi/service/prefs/BackingStoreException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/Preferences.java">org/osgi/service/prefs/Preferences.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/PreferencesService.java">org/osgi/service/prefs/PreferencesService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/prefs/src/org/osgi/service/prefs/package-info.java">org/osgi/service/prefs/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/provisioning/provisioning_api-4.0.0.html b/docs/jars/provisioning/provisioning_api-4.0.0.html
new file mode 100644
index 0000000..afb33b6
--- /dev/null
+++ b/docs/jars/provisioning/provisioning_api-4.0.0.html
@@ -0,0 +1,193 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>provisioning_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>provisioning_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/provisioning/provisioning_api-4.0.0.jar">download</a> (2190 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>provisioning-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.provisioning-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Initial Provisioning (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/provisioning/package-summary.html">org.osgi.service.provisioning</a> 1.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/provisioning/package-summary.html">org.osgi.service.provisioning</a> [1.2.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:43</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/provisioning</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/provisioning/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/provisioning/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:provisioning:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../provisioning/provisioning_api-4.0.0.html">provisioning_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/provisioning/package-summary.html">org.osgi.service.provisioning</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../provisioning/provisioning_api-4.0.0.html">provisioning_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/provisioning/package-summary.html">org.osgi.service.provisioning</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/provisioning/src/org/osgi/service/provisioning/ProvisioningService.java">org/osgi/service/provisioning/ProvisioningService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/provisioning/src/org/osgi/service/provisioning/package-info.java">org/osgi/service/provisioning/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/remotefw/remotefw_api-4.0.0.html b/docs/jars/remotefw/remotefw_api-4.0.0.html
new file mode 100644
index 0000000..871f067
--- /dev/null
+++ b/docs/jars/remotefw/remotefw_api-4.0.0.html
@@ -0,0 +1,189 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>remotefw_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>remotefw_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/remotefw/remotefw_api-4.0.0.jar">download</a> (1696 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>RemoteFW-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.remotefw-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Remote Framework (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=remotefw/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=remotefw/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a> [0.0.0,1.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:19</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/remotefw</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remotefw/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remotefw/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:remotefw:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+<tr><td><a href="../remotefw/remotefw_api-4.0.0.html">remotefw_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/remotefw/package-summary.html">org.knopflerfish.service.remotefw</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remotefw/src/org/knopflerfish/service/remotefw/RemoteFramework.java">org/knopflerfish/service/remotefw/RemoteFramework.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/remoteserviceadmin/remoteserviceadmin_api-1.0.0.html b/docs/jars/remoteserviceadmin/remoteserviceadmin_api-1.0.0.html
new file mode 100644
index 0000000..3d62900
--- /dev/null
+++ b/docs/jars/remoteserviceadmin/remoteserviceadmin_api-1.0.0.html
@@ -0,0 +1,245 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>remoteserviceadmin_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>remoteserviceadmin_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/remoteserviceadmin/remoteserviceadmin_api-1.0.0.jar">download</a> (20605 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Remote Service Admin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.remoteserviceadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi specified remote service admin service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/remoteserviceadmin/package-summary.html">org.osgi.service.remoteserviceadmin</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/remoteserviceadmin/package-summary.html">org.osgi.service.remoteserviceadmin</a> [1.0.1,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:02</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/remoteserviceadmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:remoteserviceadmin:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../remoteserviceadmin/remoteserviceadmin_api-1.0.0.html">remoteserviceadmin_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/remoteserviceadmin/package-summary.html">org.osgi.service.remoteserviceadmin</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../remoteserviceadmin/remoteserviceadmin_api-1.0.0.html">remoteserviceadmin_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/remoteserviceadmin/package-summary.html">org.osgi.service.remoteserviceadmin</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointDescription.java">org/osgi/service/remoteserviceadmin/EndpointDescription.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointListener.java">org/osgi/service/remoteserviceadmin/EndpointListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointPermission.java">org/osgi/service/remoteserviceadmin/EndpointPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportReference.java">org/osgi/service/remoteserviceadmin/ExportReference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportRegistration.java">org/osgi/service/remoteserviceadmin/ExportRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportReference.java">org/osgi/service/remoteserviceadmin/ImportReference.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportRegistration.java">org/osgi/service/remoteserviceadmin/ImportRegistration.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteConstants.java">org/osgi/service/remoteserviceadmin/RemoteConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.java">org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.java">org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.java">org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/package-info.java">org/osgi/service/remoteserviceadmin/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repoindex_kf/repoindex_kf_all-1.0.1.html b/docs/jars/repoindex_kf/repoindex_kf_all-1.0.1.html
new file mode 100644
index 0000000..ba8a8f4
--- /dev/null
+++ b/docs/jars/repoindex_kf/repoindex_kf_all-1.0.1.html
@@ -0,0 +1,231 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repoindex_kf_all-1.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repoindex_kf_all-1.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repoindex_kf/repoindex_kf_all-1.0.1.jar">download</a> (19638 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>KF Resource Analyzer Extensions</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repository.index</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>KF Resource Analyzer Extensions</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.repository.index.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/indexer/package-summary.html">org.osgi.service.indexer</a> 1.0.2<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/indexer/package-summary.html">org.osgi.service.indexer</a> [1.0.2,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:00</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repoindex_kf</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repoindex_kf:1.0.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repoindex_kf/repoindex_kf_all-1.0.1.html">repoindex_kf_all-1.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/indexer/package-summary.html">org.osgi.service.indexer</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repoindex_kf/repoindex_kf_all-1.0.1.html">repoindex_kf_all-1.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/indexer/package-summary.html">org.osgi.service.indexer</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/Activator.java">org/knopflerfish/bundle/repository/index/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/KnopflerfishExtentions.java">org/knopflerfish/bundle/repository/index/KnopflerfishExtentions.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/knopflerfish/bundle/repository/index/Util.java">org/knopflerfish/bundle/repository/index/Util.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/Builder.java">org/osgi/service/indexer/Builder.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/Capability.java">org/osgi/service/indexer/Capability.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/Namespaces.java">org/osgi/service/indexer/Namespaces.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/Requirement.java">org/osgi/service/indexer/Requirement.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/Resource.java">org/osgi/service/indexer/Resource.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/ResourceAnalyzer.java">org/osgi/service/indexer/ResourceAnalyzer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repoindex_kf/src/org/osgi/service/indexer/ResourceIndexer.java">org/osgi/service/indexer/ResourceIndexer.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repository/repository_api-1.0.0.html b/docs/jars/repository/repository_api-1.0.0.html
new file mode 100644
index 0000000..4874eab
--- /dev/null
+++ b/docs/jars/repository/repository_api-1.0.0.html
@@ -0,0 +1,210 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repository_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repository_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repository/repository_api-1.0.0.jar">download</a> (2728 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Repository-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repository-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Repository API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> [1.0.0,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:47</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repository_api</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_api">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_api</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repository:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_api/src/org/osgi/service/repository/ContentNamespace.java">org/osgi/service/repository/ContentNamespace.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_api/src/org/osgi/service/repository/Repository.java">org/osgi/service/repository/Repository.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_api/src/org/osgi/service/repository/RepositoryContent.java">org/osgi/service/repository/RepositoryContent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_api/src/org/osgi/service/repository/package-info.java">org/osgi/service/repository/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repository_desktop/repository_desktop_all-1.1.1.html b/docs/jars/repository_desktop/repository_desktop_all-1.1.1.html
new file mode 100644
index 0000000..4e8c574
--- /dev/null
+++ b/docs/jars/repository_desktop/repository_desktop_all-1.1.1.html
@@ -0,0 +1,273 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repository_desktop_all-1.1.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repository_desktop_all-1.1.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repository_desktop/repository_desktop_all-1.1.1.jar">download</a> (75221 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Repository Desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repository_desktop</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.1.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Knopflerfish desktop plugin visualizing OSGi Repository contents.</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/">http://www.knopflerfish.org/</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.repository_desktop.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.swing 0.0.0<br>
+javax.swing.event 0.0.0<br>
+javax.swing.table 0.0.0<br>
+javax.swing.tree 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a> [2.2.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;  objectClass:List<String>="org.knopflerfish.service.desktop.SwingBundleDisplayer";  org.knopflerfish.service.desktop.displayer.name=Repository</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:59</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repository_desktop</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Copyright</td>
+ <td>Copyright (c) 2003-2013, KNOPFLERFISH project. All rights reserved.</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repository_desktop:1.1.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a [...]
+<tr><td><a href="../desktop/desktop_api-5.0.1.html">desktop_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/desktop/package-summary.html">org.knopflerfish.service.desktop</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../util/util-4.1.0.html">util-4.1.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/Activator.java">org/knopflerfish/bundle/repository_desktop/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/DefaultSwingBundleDisplayer.java">org/knopflerfish/bundle/repository_desktop/DefaultSwingBundleDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/DownloadableBundleRequirement.java">org/knopflerfish/bundle/repository_desktop/DownloadableBundleRequirement.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtml.java">org/knopflerfish/bundle/repository_desktop/NsToHtml.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtmlBundle.java">org/knopflerfish/bundle/repository_desktop/NsToHtmlBundle.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtmlContent.java">org/knopflerfish/bundle/repository_desktop/NsToHtmlContent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtmlEE.java">org/knopflerfish/bundle/repository_desktop/NsToHtmlEE.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtmlGeneric.java">org/knopflerfish/bundle/repository_desktop/NsToHtmlGeneric.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtmlHost.java">org/knopflerfish/bundle/repository_desktop/NsToHtmlHost.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/NsToHtmlPackage.java">org/knopflerfish/bundle/repository_desktop/NsToHtmlPackage.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoriesTableModel.java">org/knopflerfish/bundle/repository_desktop/RepositoriesTableModel.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java">org/knopflerfish/bundle/repository_desktop/RepositoryDisplayer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_desktop/src/org/knopflerfish/bundle/repository_desktop/Util.java">org/knopflerfish/bundle/repository_desktop/Util.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repository_xml/repository_xml_all-1.0.2.html b/docs/jars/repository_xml/repository_xml_all-1.0.2.html
new file mode 100644
index 0000000..14af942
--- /dev/null
+++ b/docs/jars/repository_xml/repository_xml_all-1.0.2.html
@@ -0,0 +1,246 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repository_xml_all-1.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repository_xml_all-1.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repository_xml/repository_xml_all-1.0.2.jar">download</a> (24041 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>repository xml</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repository.xml</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Xml Backed Repository</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.repository.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> 0.0.0<br>
+org.xmlpull.v1 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.service.Repository",osgi.service;objectClass:List<String>="org.knopflerfish.service.repository.XmlBackedRepositoryFactory"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:50</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repository_xml</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repository_xml:1.0.2</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../kxml/kxml-2.3.0.kf4-001.html">kxml-2.3.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/kxml2/io/package-summary.html">org.kxml2.io</a>, org.xmlpull.v1</td></tr>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/Activator.java">org/knopflerfish/bundle/repository/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/FactoryImpl.java">org/knopflerfish/bundle/repository/FactoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/RepositoryImpl.java">org/knopflerfish/bundle/repository/RepositoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/CapabilityImpl.java">org/knopflerfish/bundle/repository/xml/CapabilityImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/Data.java">org/knopflerfish/bundle/repository/xml/Data.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/RepositoryXmlParser.java">org/knopflerfish/bundle/repository/xml/RepositoryXmlParser.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/RequirementImpl.java">org/knopflerfish/bundle/repository/xml/RequirementImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/ResourceImpl.java">org/knopflerfish/bundle/repository/xml/ResourceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/service/repository/XmlBackedRepositoryFactory.java">org/knopflerfish/service/repository/XmlBackedRepositoryFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/service/repository/package-info.java">org/knopflerfish/service/repository/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repository_xml/repository_xml_api-1.0.2.html b/docs/jars/repository_xml/repository_xml_api-1.0.2.html
new file mode 100644
index 0000000..348b667
--- /dev/null
+++ b/docs/jars/repository_xml/repository_xml_api-1.0.2.html
@@ -0,0 +1,234 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repository_xml_api-1.0.2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repository_xml_api-1.0.2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repository_xml/repository_xml_api-1.0.2.jar">download</a> (2056 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>repository xml-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repository.xml-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Xml Backed Repository (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.osgi.service.Repository",osgi.service;objectClass:List<String>="org.knopflerfish.service.repository.XmlBackedRepositoryFactory"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:50</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repository_xml</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repository_xml:1.0.2:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/Activator.java">org/knopflerfish/bundle/repository/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/FactoryImpl.java">org/knopflerfish/bundle/repository/FactoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/RepositoryImpl.java">org/knopflerfish/bundle/repository/RepositoryImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/CapabilityImpl.java">org/knopflerfish/bundle/repository/xml/CapabilityImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/Data.java">org/knopflerfish/bundle/repository/xml/Data.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/RepositoryXmlParser.java">org/knopflerfish/bundle/repository/xml/RepositoryXmlParser.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/RequirementImpl.java">org/knopflerfish/bundle/repository/xml/RequirementImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/bundle/repository/xml/ResourceImpl.java">org/knopflerfish/bundle/repository/xml/ResourceImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/service/repository/XmlBackedRepositoryFactory.java">org/knopflerfish/service/repository/XmlBackedRepositoryFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repository_xml/src/org/knopflerfish/service/repository/package-info.java">org/knopflerfish/service/repository/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repositorycommands/repositorycommands-1.1.1.html b/docs/jars/repositorycommands/repositorycommands-1.1.1.html
new file mode 100644
index 0000000..8f96029
--- /dev/null
+++ b/docs/jars/repositorycommands/repositorycommands-1.1.1.html
@@ -0,0 +1,202 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repositorycommands-1.1.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repositorycommands-1.1.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repositorycommands/repositorycommands-1.1.1.jar">download</a> (15643 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Repository-Commands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repositorycommands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.1.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Repository commands (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=repositorycommands/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=repositorycommands/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.repositorycommands.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.0.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> [1.1.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.knopflerfish.service.console.CommandGroup"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:58</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repositorycommands</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repositorycommands/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repositorycommands/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repositorycommands:1.1.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/Activator.java">org/knopflerfish/bundle/repositorycommands/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorycommands/src/org/knopflerfish/bundle/repositorycommands/RepositoryCommandGroup.java">org/knopflerfish/bundle/repositorycommands/RepositoryCommandGroup.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repositorymanager/repositorymanager_all-1.2.0.html b/docs/jars/repositorymanager/repositorymanager_all-1.2.0.html
new file mode 100644
index 0000000..57389b3
--- /dev/null
+++ b/docs/jars/repositorymanager/repositorymanager_all-1.2.0.html
@@ -0,0 +1,240 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repositorymanager_all-1.2.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repositorymanager_all-1.2.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repositorymanager/repositorymanager_all-1.2.0.jar">download</a> (24908 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Repository-Manager</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repositorymanager</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.2.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Repository Manager</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org/index.html?docpage=repositorycommands/index.html</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org">http://www.knopflerfish.org</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.repositorymanager.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.knopflerfish.service.repositorymanager.RepositoryManager"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:53</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repositorymanager</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repositorymanager/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repositorymanager/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repositorymanager:1.2.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_api-1.0.2.html">repository_xml_api-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repository/package-summary.html">org.knopflerfish.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summar [...]
+<tr><td><a href="../repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/wiring/package-summary.html">org.osgi.framework.wiring</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summa [...]
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository/repository_api-1.0.0.html">repository_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repository_xml/repository_xml_all-1.0.2.html">repository_xml_all-1.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/repository/package-summary.html">org.osgi.service.repository</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summar [...]
+<tr><td><a href="../repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/Activator.java">org/knopflerfish/bundle/repositorymanager/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/Repositories.java">org/knopflerfish/bundle/repositorymanager/Repositories.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryListener.java">org/knopflerfish/bundle/repositorymanager/RepositoryListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java">org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/ResolveContextImpl.java">org/knopflerfish/bundle/repositorymanager/ResolveContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/BasicRequirement.java">org/knopflerfish/service/repositorymanager/BasicRequirement.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryInfo.java">org/knopflerfish/service/repositorymanager/RepositoryInfo.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryManager.java">org/knopflerfish/service/repositorymanager/RepositoryManager.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/repositorymanager/repositorymanager_api-1.2.0.html b/docs/jars/repositorymanager/repositorymanager_api-1.2.0.html
new file mode 100644
index 0000000..8dc99a7
--- /dev/null
+++ b/docs/jars/repositorymanager/repositorymanager_api-1.2.0.html
@@ -0,0 +1,226 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>repositorymanager_api-1.2.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>repositorymanager_api-1.2.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/repositorymanager/repositorymanager_api-1.2.0.jar">download</a> (6850 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Repository-Manager-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.repositorymanager-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.2.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Repository Manager (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org/index.html?docpage=repositorycommands/index.html</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org">http://www.knopflerfish.org</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> 1.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td>osgi.service;objectClass:List<String>="org.knopflerfish.service.repositorymanager.RepositoryManager"</td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:53</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/repository/repositorymanager</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repositorymanager/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repositorymanager/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:repositorymanager:1.2.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../repositorycommands/repositorycommands-1.1.1.html">repositorycommands-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+<tr><td><a href="../repositorymanager/repositorymanager_api-1.2.0.html">repositorymanager_api-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/repositorymanager/package-summary.html">org.knopflerfish.service.repositorymanager</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/Activator.java">org/knopflerfish/bundle/repositorymanager/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/Repositories.java">org/knopflerfish/bundle/repositorymanager/Repositories.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryListener.java">org/knopflerfish/bundle/repositorymanager/RepositoryListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java">org/knopflerfish/bundle/repositorymanager/RepositoryManagerImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/bundle/repositorymanager/ResolveContextImpl.java">org/knopflerfish/bundle/repositorymanager/ResolveContextImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/BasicRequirement.java">org/knopflerfish/service/repositorymanager/BasicRequirement.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryInfo.java">org/knopflerfish/service/repositorymanager/RepositoryInfo.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/repository/repositorymanager/src/org/knopflerfish/service/repositorymanager/RepositoryManager.java">org/knopflerfish/service/repositorymanager/RepositoryManager.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/resolver/resolver_api-1.0.0.html b/docs/jars/resolver/resolver_api-1.0.0.html
new file mode 100644
index 0000000..d811990
--- /dev/null
+++ b/docs/jars/resolver/resolver_api-1.0.0.html
@@ -0,0 +1,212 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>resolver_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>resolver_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/resolver/resolver_api-1.0.0.jar">download</a> (3846 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>resolver-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.resolver-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Resolver API (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a> [1.0.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:45</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/resolver/resolver_api</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:resolver:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a></td></tr>
+<tr><td><a href="../resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../repositorymanager/repositorymanager_all-1.2.0.html">repositorymanager_all-1.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a></td></tr>
+<tr><td><a href="../resolver/resolver_api-1.0.0.html">resolver_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/resolver/package-summary.html">org.osgi.service.resolver</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/resolver_api/src/org/osgi/service/resolver/HostedCapability.java">org/osgi/service/resolver/HostedCapability.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/resolver_api/src/org/osgi/service/resolver/ResolutionException.java">org/osgi/service/resolver/ResolutionException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/resolver_api/src/org/osgi/service/resolver/ResolveContext.java">org/osgi/service/resolver/ResolveContext.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/resolver_api/src/org/osgi/service/resolver/Resolver.java">org/osgi/service/resolver/Resolver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/resolver/resolver_api/src/org/osgi/service/resolver/package-info.java">org/osgi/service/resolver/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/rxtxcomm-linux-arm/rxtxcomm-linux-arm-2.1.7.1.html b/docs/jars/rxtxcomm-linux-arm/rxtxcomm-linux-arm-2.1.7.1.html
new file mode 100644
index 0000000..8b08688
--- /dev/null
+++ b/docs/jars/rxtxcomm-linux-arm/rxtxcomm-linux-arm-2.1.7.1.html
@@ -0,0 +1,183 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>rxtxcomm-linux-arm-2.1.7.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>rxtxcomm-linux-arm-2.1.7.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/rxtxcomm-linux-arm/rxtxcomm-linux-arm-2.1.7.1.jar">download</a> (167000 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>RXTXcomm-linux-arm-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.rxtxcomm-linux-arm-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.1.7.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>RXTX comm native driver for Linux/arm_le (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Piayda/RXTX</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:21</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/rxtxcomm-linux-arm</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-NativeCode</td>
+ <td>librxtxI2C.so; librxtxParallel.so; librxtxRS485.so;librxtxRaw.so; librxtxSerial.so ;osname = Linux ;processor = arm_le; processor = armv4tl</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm-linux-arm/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm-linux-arm/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:rxtxcomm-linux-arm:2.1.7.1:lib</td>
+</tr>
+<tr>
+ <td>Fragment-Host</td>
+ <td>org.knopflerfish.bundle.rxtxcomm-API</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+None found
+
+</body>
+</html>
+
+
diff --git a/docs/jars/rxtxcomm-linux-x86/rxtxcomm-linux-x86-2.2.0.pre2.html b/docs/jars/rxtxcomm-linux-x86/rxtxcomm-linux-x86-2.2.0.pre2.html
new file mode 100644
index 0000000..e2948e2
--- /dev/null
+++ b/docs/jars/rxtxcomm-linux-x86/rxtxcomm-linux-x86-2.2.0.pre2.html
@@ -0,0 +1,183 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>rxtxcomm-linux-x86-2.2.0.pre2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>rxtxcomm-linux-x86-2.2.0.pre2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/rxtxcomm-linux-x86/rxtxcomm-linux-x86-2.2.0.pre2.jar">download</a> (91325 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>RXTXcomm-linux-x86-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.rxtxcomm-linux-x86-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.2.0.pre2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>RXTX comm native driver for Linux/x86 (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Piayda/RXTX</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:22</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/rxtxcomm-linux-x86</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-NativeCode</td>
+ <td>librxtxParallel.so; librxtxSerial.so ;osname = Linux ;processor = x86</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm-linux-arm/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm-linux-arm/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:rxtxcomm-linux-x86:2.2.0.pre2:lib</td>
+</tr>
+<tr>
+ <td>Fragment-Host</td>
+ <td>org.knopflerfish.bundle.rxtxcomm-API</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+None found
+
+</body>
+</html>
+
+
diff --git a/docs/jars/rxtxcomm/rxtxcomm_api-2.2.0.pre2.html b/docs/jars/rxtxcomm/rxtxcomm_api-2.2.0.pre2.html
new file mode 100644
index 0000000..365e205
--- /dev/null
+++ b/docs/jars/rxtxcomm/rxtxcomm_api-2.2.0.pre2.html
@@ -0,0 +1,345 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>rxtxcomm_api-2.2.0.pre2.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>rxtxcomm_api-2.2.0.pre2.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/rxtxcomm/rxtxcomm_api-2.2.0.pre2.jar">download</a> (66938 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>RXTXcomm-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.rxtxcomm-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.2.0.pre2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>RXTX comm java library, requires native driver fragment (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Piayda/RXTX</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a> 2.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a> [2.2.0,3.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:17</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/rxtxcomm</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:rxtxcomm:2.2.0.pre2:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../rxtxcomm/rxtxcomm_api-2.2.0.pre2.html">rxtxcomm_api-2.2.0.pre2</a></td><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a></td></tr>
+<tr><td><a href="../rxtxcomm/rxtxcomm_api-2.2.0.pre2.html">rxtxcomm_api-2.2.0.pre2</a></td><td><a target="_top" href="../../javadoc/index.html?gnu/io/package-summary.html">gnu.io</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/CommDriver.java">gnu/io/CommDriver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/CommPort.java">gnu/io/CommPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/CommPortEnumerator.java">gnu/io/CommPortEnumerator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/CommPortIdentifier.java">gnu/io/CommPortIdentifier.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/CommPortOwnershipListener.java">gnu/io/CommPortOwnershipListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/Configure.java">gnu/io/Configure.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/I2C.java">gnu/io/I2C.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/I2CPort.java">gnu/io/I2CPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/I2CPortEvent.java">gnu/io/I2CPortEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/I2CPortEventListener.java">gnu/io/I2CPortEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/LPRPort.java">gnu/io/LPRPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/NoSuchPortException.java">gnu/io/NoSuchPortException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/ParallelPort.java">gnu/io/ParallelPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/ParallelPortEvent.java">gnu/io/ParallelPortEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/ParallelPortEventListener.java">gnu/io/ParallelPortEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/PortInUseException.java">gnu/io/PortInUseException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RS485.java">gnu/io/RS485.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RS485Port.java">gnu/io/RS485Port.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RS485PortEvent.java">gnu/io/RS485PortEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RS485PortEventListener.java">gnu/io/RS485PortEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RXTXCommDriver.java">gnu/io/RXTXCommDriver.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RXTXPort.java">gnu/io/RXTXPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RXTXVersion.java">gnu/io/RXTXVersion.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/Raw.java">gnu/io/Raw.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RawPort.java">gnu/io/RawPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RawPortEvent.java">gnu/io/RawPortEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/RawPortEventListener.java">gnu/io/RawPortEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/SerialPort.java">gnu/io/SerialPort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/SerialPortEvent.java">gnu/io/SerialPortEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/SerialPortEventListener.java">gnu/io/SerialPortEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/UnSupportedLoggerException.java">gnu/io/UnSupportedLoggerException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/UnsupportedCommOperationException.java">gnu/io/UnsupportedCommOperationException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/rxtxcomm/src/gnu/io/Zystem.java">gnu/io/Zystem.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/scrcommands/scrcommands-4.0.1.html b/docs/jars/scrcommands/scrcommands-4.0.1.html
new file mode 100644
index 0000000..a2aac11
--- /dev/null
+++ b/docs/jars/scrcommands/scrcommands-4.0.1.html
@@ -0,0 +1,198 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>scrcommands-4.0.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>scrcommands-4.0.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/scrcommands/scrcommands-4.0.1.jar">download</a> (14583 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>ScrCommands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.scrcommands-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Provides SCR admin commands for the Knopflerfish console (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=scrcommands/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=scrcommands/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a> [2.1.0,3.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a> [1.2.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:37</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/scrcommands</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/scrcommands/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/scrcommands/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:scrcommands:4.0.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+<tr>
+ <td>Service-Component</td>
+ <td>OSGI-INF/service.xml</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../component/component_all-5.0.3.html">component_all-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../component/component_api-5.0.3.html">component_api-5.0.3</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../console/console_all-4.0.1.html">console_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../console/console_api-4.0.1.html">console_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/apache/felix/scr/package-summary.html">org.apache.felix.scr</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/console/package-summary.html">org.knopflerfish.service.console</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/component/package-summary.html">org.osgi.service.component</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/scrcommands/src/org/knopflerfish/bundle/scrcommands/ScrCommandGroup.java">org/knopflerfish/bundle/scrcommands/ScrCommandGroup.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/serialportdevice/serialportdevice_all-4.0.0.html b/docs/jars/serialportdevice/serialportdevice_all-4.0.0.html
new file mode 100644
index 0000000..27a5e94
--- /dev/null
+++ b/docs/jars/serialportdevice/serialportdevice_all-4.0.0.html
@@ -0,0 +1,224 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>serialportdevice_all-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>serialportdevice_all-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/serialportdevice/serialportdevice_all-4.0.0.jar">download</a> (7658 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>serialportdevice</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.serialportdevice</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Serial port device</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.serial.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.comm 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:11</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/serialportdevice</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>device</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:serialportdevice:4.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/bundle/serial/Activator.java">org/knopflerfish/bundle/serial/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/bundle/serial/Config.java">org/knopflerfish/bundle/serial/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/bundle/serial/SPD.java">org/knopflerfish/bundle/serial/SPD.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/service/serial/SerialPortDevice.java">org/knopflerfish/service/serial/SerialPortDevice.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/serialportdevice/serialportdevice_api-4.0.0.html b/docs/jars/serialportdevice/serialportdevice_api-4.0.0.html
new file mode 100644
index 0000000..e8f3add
--- /dev/null
+++ b/docs/jars/serialportdevice/serialportdevice_api-4.0.0.html
@@ -0,0 +1,211 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>serialportdevice_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>serialportdevice_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/serialportdevice/serialportdevice_api-4.0.0.jar">download</a> (1738 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>serialportdevice-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.serialportdevice-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Serial port device (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=serial</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.comm 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a> [0.0.0,1.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a> 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:30:11</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles_opt/serial/serialportdevice</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:serialportdevice:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../comm-linux/comm-linux_all-3.0.0.html">comm-linux_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../comm-win32/comm-win32_all-3.0.0.html">comm-win32_all-3.0.0</a></td><td>javax.comm</td></tr>
+<tr><td><a href="../device/device_all-4.0.1.html">device_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../device/device_api-4.0.1.html">device_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/device/package-summary.html">org.osgi.service.device</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_api-4.0.0.html">serialportdevice_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/serial/package-summary.html">org.knopflerfish.service.serial</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/bundle/serial/Activator.java">org/knopflerfish/bundle/serial/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/bundle/serial/Config.java">org/knopflerfish/bundle/serial/Config.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/bundle/serial/SPD.java">org/knopflerfish/bundle/serial/SPD.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles_opt/serial/serialportdevice/src/org/knopflerfish/service/serial/SerialPortDevice.java">org/knopflerfish/service/serial/SerialPortDevice.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/serviceloader/serviceloader_api-1.0.0.html b/docs/jars/serviceloader/serviceloader_api-1.0.0.html
new file mode 100644
index 0000000..e4b24cb
--- /dev/null
+++ b/docs/jars/serviceloader/serviceloader_api-1.0.0.html
@@ -0,0 +1,195 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>serviceloader_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>serviceloader_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/serviceloader/serviceloader_api-1.0.0.jar">download</a> (1977 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Service Loader-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.serviceloader-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi specified serviceloader service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/serviceloader/package-summary.html">org.osgi.service.serviceloader</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/serviceloader/package-summary.html">org.osgi.service.serviceloader</a> [1.0.0,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:05</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/serviceloader</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/serviceloader/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/serviceloader/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:serviceloader:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../serviceloader/serviceloader_api-1.0.0.html">serviceloader_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/serviceloader/package-summary.html">org.osgi.service.serviceloader</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/resource/package-summary.html">org.osgi.resource</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../serviceloader/serviceloader_api-1.0.0.html">serviceloader_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/serviceloader/package-summary.html">org.osgi.service.serviceloader</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/serviceloader/src/org/osgi/service/serviceloader/ServiceLoaderNamespace.java">org/osgi/service/serviceloader/ServiceLoaderNamespace.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/serviceloader/src/org/osgi/service/serviceloader/package-info.java">org/osgi/service/serviceloader/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/sslj2sp/sslj2sp-4.0.0.html b/docs/jars/sslj2sp/sslj2sp-4.0.0.html
new file mode 100644
index 0000000..bbea6ee
--- /dev/null
+++ b/docs/jars/sslj2sp/sslj2sp-4.0.0.html
@@ -0,0 +1,206 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>sslj2sp-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>sslj2sp-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/sslj2sp/sslj2sp-4.0.0.jar">download</a> (17994 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>sslj2sp-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.sslj2sp-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>SSL Provider using the Java 2 security architecture. (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish/Oscar</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/sslj2sp/readme.txt">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/sslj2sp/readme.txt</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.ssl.j2sp.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.net.ssl 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a> [1.4.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.4))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:51</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/sslj2sp</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>service</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/sslj2sp/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/sslj2sp/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:sslj2sp:4.0.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../cm/cm_api-5.0.1.html">cm_api-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/cm/package-summary.html">org.osgi.service.cm</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/sslj2sp/src/org/knopflerfish/bundle/ssl/j2sp/Activator.java">org/knopflerfish/bundle/ssl/j2sp/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/sslj2sp/src/org/knopflerfish/bundle/ssl/j2sp/ConstsIf.java">org/knopflerfish/bundle/ssl/j2sp/ConstsIf.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/sslj2sp/src/org/knopflerfish/bundle/ssl/j2sp/SslServiceFactory.java">org/knopflerfish/bundle/ssl/j2sp/SslServiceFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/sslj2sp/src/org/knopflerfish/bundle/ssl/j2sp/SslServiceWrapper.java">org/knopflerfish/bundle/ssl/j2sp/SslServiceWrapper.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/style.css b/docs/jars/style.css
new file mode 100644
index 0000000..05f36a5
--- /dev/null
+++ b/docs/jars/style.css
@@ -0,0 +1,205 @@
+BODY  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:11px;
+ color:000000;
+ text-align:left;
+ font-weight:normal;
+ background:#fff;
+}
+
+
+
+
+TD  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ text-align:left;
+ vertical-align:top;
+ font-size:11px;
+}
+
+TD A  {
+ color:000000;
+ text-decoration:none
+ font-size:11px;
+}
+
+.mfheader  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ text-align:left;
+ vertical-align:top;
+ font-size:11px;
+ font-weight:bold;
+ /* background:   #805362; */
+ color: #fff;
+ padding-top:         4px;
+ padding-bottom:      4px;
+ /* text-align: center; */
+    border-style: solid;
+    border-color: #999999;
+    background-color: #dedede;
+    border-width: 1px;
+    color: #444444;
+    padding-left: 10px;
+
+}
+
+TH  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:11px;
+ color:000000;
+ text-align:left;
+ vertical-align:top;
+ font-weight:bold
+}
+
+TD A  {
+ color:000000;
+ text-decoration:none
+ font-size:11px;
+}
+
+PRE {
+ font-family: Courier New, Courier;
+ font-size:11px;
+ color:000000;
+ text-align:left;
+ font-weight:normal;
+}
+
+
+H1  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:19px;
+ font-weight:bold;
+ /* background: #dddddd; */
+}
+
+
+H3  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:13px;
+ font-weight:bold;
+ background:	#805362;
+ color:		#fff;
+ padding:	2px 0px 2px 3px;
+}
+
+H4  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:11px;
+ font-weight:bold;
+ background:	#805362;
+ color:		#fff;
+ padding:	2px 0px 2px 10px;
+    border-style: solid;
+    border-color: #999999;
+    background-color: #dedede;
+    border-width: 1px;
+    color: #444444;
+}
+
+H5  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:9px;
+ font-weight:bold;
+ background:	#805362;
+ color:		#fff;
+ padding:	2px 0px 2px 3px;
+}
+
+H6  {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size:7px;
+ font-weight:bold
+}
+
+TD.menu {
+ color: #ffffff;
+ font-size:9px;
+ font-weight:bold;
+ text-align:left;
+}
+
+A.top {
+  float: right;
+  text-decoration:  none;
+  font-weight:      bold;
+}
+
+A, A:visited, A:selected, A:active {
+ color:000000;
+ text-decoration:  none;
+ font-weight:      bold;
+}
+
+A:hover {
+ text-decoration:  underline;
+}
+
+li.A:visited, li.A:selected, li.A:active {
+ text-decoration:  none;
+ font-weight:      bold;
+}
+
+li.A:hover {
+ text-decoration:  underline;
+}
+
+.small  {
+ font-size:9px;
+}
+
+.medium  {
+ font-size:13px;
+}
+
+.big  {
+ font-size:17px;
+}
+
+.ghosted  {
+  color: #888888;
+}
+
+.framed  {
+ border-type: solid;
+ border-top: 1px solid;
+ border-left: 1px solid;
+ border-bottom: 1px solid;
+ border-right: 1px solid;
+ background:#eeeeee;
+ border-color:#000000;
+ padding-left: 2;
+ padding-top: 2;
+ padding-bottom: 2;
+ padding-right: 2;
+ text-decoration:none;
+ font-size: 11px;
+}
+
+.boxed  {
+ border-type: solid;
+ border-top: 1px solid;
+ border-left: 1px solid;
+ border-bottom: 1px solid;
+ border-right: 1px solid;
+ background:#E7DBAD;
+ border-color:#000000;
+ padding-left: 2;
+ padding-top: 1;
+ padding-bottom: 2;
+ padding-right: 2;
+ text-decoration:none;
+ float: left;
+}
+
+dt {
+ font-weight:bold;
+  margin-bottom: 5px;
+}
+
+dd {
+  margin-bottom: 5px;
+}
+
+
diff --git a/docs/jars/subsystem/subsystem_api-1.0.0.html b/docs/jars/subsystem/subsystem_api-1.0.0.html
new file mode 100644
index 0000000..79ce2b9
--- /dev/null
+++ b/docs/jars/subsystem/subsystem_api-1.0.0.html
@@ -0,0 +1,210 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>subsystem_api-1.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>subsystem_api-1.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/subsystem/subsystem_api-1.0.0.jar">download</a> (12485 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Subsystem-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.subsystem-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>1.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>OSGi specified subsytem service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/BSD-3-Clause;description="BSD 3-clause";link="http://www.knopflerfish.org/licenses/knopflerfish-1.txt"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/subsystem/package-summary.html">org.osgi.service.subsystem</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.7.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/subsystem/package-summary.html">org.osgi.service.subsystem</a> [1.0.0,1.1.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.5))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:07</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/subsystem</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:subsystem:1.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../subsystem/subsystem_api-1.0.0.html">subsystem_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/subsystem/package-summary.html">org.osgi.service.subsystem</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../subsystem/subsystem_api-1.0.0.html">subsystem_api-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/subsystem/package-summary.html">org.osgi.service.subsystem</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/src/org/osgi/service/subsystem/Subsystem.java">org/osgi/service/subsystem/Subsystem.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/src/org/osgi/service/subsystem/SubsystemConstants.java">org/osgi/service/subsystem/SubsystemConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/src/org/osgi/service/subsystem/SubsystemException.java">org/osgi/service/subsystem/SubsystemException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/src/org/osgi/service/subsystem/SubsystemPermission.java">org/osgi/service/subsystem/SubsystemPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/subsystem/src/org/osgi/service/subsystem/package-info.java">org/osgi/service/subsystem/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/threadio/threadio-0.2.0.html b/docs/jars/threadio/threadio-0.2.0.html
new file mode 100644
index 0000000..1f4898b
--- /dev/null
+++ b/docs/jars/threadio/threadio-0.2.0.html
@@ -0,0 +1,209 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>threadio-0.2.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>threadio-0.2.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/threadio/threadio-0.2.0.jar">download</a> (6211 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>threadio-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.threadio-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>0.2.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>ThreadIO Service (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.threadio.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:17</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/threadio</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:threadio:0.2.0:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/Activator.java">org/knopflerfish/bundle/threadio/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/Streams.java">org/knopflerfish/bundle/threadio/Streams.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/ThreadIOFactory.java">org/knopflerfish/bundle/threadio/ThreadIOFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/ThreadIOImpl.java">org/knopflerfish/bundle/threadio/ThreadIOImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/osgi/service/threadio/ThreadIO.java">org/osgi/service/threadio/ThreadIO.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/threadio/threadio_all-0.2.0.html b/docs/jars/threadio/threadio_all-0.2.0.html
new file mode 100644
index 0000000..bd76bbd
--- /dev/null
+++ b/docs/jars/threadio/threadio_all-0.2.0.html
@@ -0,0 +1,214 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>threadio_all-0.2.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>threadio_all-0.2.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/threadio/threadio_all-0.2.0.jar">download</a> (7027 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>threadio</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.threadio</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>0.2.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>ThreadIO Service</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.threadio.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:17</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/threadio</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:threadio:0.2.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio-0.2.0.html">threadio-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/Activator.java">org/knopflerfish/bundle/threadio/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/Streams.java">org/knopflerfish/bundle/threadio/Streams.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/ThreadIOFactory.java">org/knopflerfish/bundle/threadio/ThreadIOFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/ThreadIOImpl.java">org/knopflerfish/bundle/threadio/ThreadIOImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/osgi/service/threadio/ThreadIO.java">org/osgi/service/threadio/ThreadIO.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/threadio/threadio_api-0.2.0.html b/docs/jars/threadio/threadio_api-0.2.0.html
new file mode 100644
index 0000000..24eed83
--- /dev/null
+++ b/docs/jars/threadio/threadio_api-0.2.0.html
@@ -0,0 +1,212 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>threadio_api-0.2.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>threadio_api-0.2.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/threadio/threadio_api-0.2.0.jar">download</a> (1653 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>threadio-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.threadio-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>0.2.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>ThreadIO Service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:26:17</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/threadio</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:threadio:0.2.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../command/command_all-0.2.html">command_all-0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_all-0.2.0.html">threadio_all-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio_api-0.2.0.html">threadio_api-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+<tr><td><a href="../threadio/threadio-0.2.0.html">threadio-0.2.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/threadio/package-summary.html">org.osgi.service.threadio</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/Activator.java">org/knopflerfish/bundle/threadio/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/Streams.java">org/knopflerfish/bundle/threadio/Streams.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/ThreadIOFactory.java">org/knopflerfish/bundle/threadio/ThreadIOFactory.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/knopflerfish/bundle/threadio/ThreadIOImpl.java">org/knopflerfish/bundle/threadio/ThreadIOImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/threadio/src/org/osgi/service/threadio/ThreadIO.java">org/osgi/service/threadio/ThreadIO.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/trayicon_fw/trayicon_fw-4.0.0.html b/docs/jars/trayicon_fw/trayicon_fw-4.0.0.html
new file mode 100644
index 0000000..dab31a0
--- /dev/null
+++ b/docs/jars/trayicon_fw/trayicon_fw-4.0.0.html
@@ -0,0 +1,196 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>trayicon_fw-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>trayicon_fw-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/trayicon_fw/trayicon_fw-4.0.0.jar">download</a> (13109 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>FW-Tray</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.trayicon_fw</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Framework tray icon. Allows basic control of the framework using the windows system tray.</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/trayicon/trayicon_fw/readme.txt">https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/trayicon/trayicon_fw/readme.txt</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.bundle.trayicons.framework.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a> [1.0.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.6))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:39</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/trayicon/trayicon_fw</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>management</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/trayicon/trayicon_fw/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/trayicon/trayicon_fw/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:trayicon_fw:4.0.0</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/framework/startlevel/package-summary.html">org.osgi.framework.startlevel</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+None found
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/trayicon/trayicon_fw/src/org/knopflerfish/bundle/trayicons/framework/Activator.java">org/knopflerfish/bundle/trayicons/framework/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/trayicon/trayicon_fw/src/org/knopflerfish/bundle/trayicons/framework/FrameworkTrayIcon.java">org/knopflerfish/bundle/trayicons/framework/FrameworkTrayIcon.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/upnp/upnp_api-4.0.0.html b/docs/jars/upnp/upnp_api-4.0.0.html
new file mode 100644
index 0000000..77a457a
--- /dev/null
+++ b/docs/jars/upnp/upnp_api-4.0.0.html
@@ -0,0 +1,228 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>upnp_api-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>upnp_api-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/upnp/upnp_api-4.0.0.jar">download</a> (5849 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>upnp-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.upnp-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>UPnP (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/upnp/package-summary.html">org.osgi.service.upnp</a> 1.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/upnp/package-summary.html">org.osgi.service.upnp</a> [1.2.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:29:40</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/upnp</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:upnp:4.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../upnp/upnp_api-4.0.0.html">upnp_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/upnp/package-summary.html">org.osgi.service.upnp</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../upnp/upnp_api-4.0.0.html">upnp_api-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/upnp/package-summary.html">org.osgi.service.upnp</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPAction.java">org/osgi/service/upnp/UPnPAction.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPDevice.java">org/osgi/service/upnp/UPnPDevice.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPEventListener.java">org/osgi/service/upnp/UPnPEventListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPException.java">org/osgi/service/upnp/UPnPException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPIcon.java">org/osgi/service/upnp/UPnPIcon.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPLocalStateVariable.java">org/osgi/service/upnp/UPnPLocalStateVariable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPService.java">org/osgi/service/upnp/UPnPService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/UPnPStateVariable.java">org/osgi/service/upnp/UPnPStateVariable.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/upnp/src/org/osgi/service/upnp/package-info.java">org/osgi/service/upnp/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/useradmin/useradmin-4.1.1.html b/docs/jars/useradmin/useradmin-4.1.1.html
new file mode 100644
index 0000000..3c576ae
--- /dev/null
+++ b/docs/jars/useradmin/useradmin-4.1.1.html
@@ -0,0 +1,381 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>useradmin-4.1.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>useradmin-4.1.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/useradmin/useradmin-4.1.1.jar">download</a> (36390 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>UserAdmin-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.useradmin-IMPL</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.1.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>User Administration Service (IMPL)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.service.um.useradmin.impl.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> [1.1.0,1.2.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:56</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/useradmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:useradmin:4.1.1:impl</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.servi [...]
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/ipam/IPAMValuationService.java">org/knopflerfish/service/um/ipam/IPAMValuationService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/ipam/Levels.java">org/knopflerfish/service/um/ipam/Levels.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/BackEndControl.java">org/knopflerfish/service/um/useradmin/BackEndControl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/BackEndException.java">org/knopflerfish/service/um/useradmin/BackEndException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/Condition.java">org/knopflerfish/service/um/useradmin/Condition.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/ContextualAuthorization.java">org/knopflerfish/service/um/useradmin/ContextualAuthorization.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdAuthenticator.java">org/knopflerfish/service/um/useradmin/PasswdAuthenticator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdSession.java">org/knopflerfish/service/um/useradmin/PasswdSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdUtil.java">org/knopflerfish/service/um/useradmin/PasswdUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/Activator.java">org/knopflerfish/service/um/useradmin/impl/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/AuthorizationImpl.java">org/knopflerfish/service/um/useradmin/impl/AuthorizationImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/ConditionImpl.java">org/knopflerfish/service/um/useradmin/impl/ConditionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/EventQueue.java">org/knopflerfish/service/um/useradmin/impl/EventQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/GroupImpl.java">org/knopflerfish/service/um/useradmin/impl/GroupImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/LDAPQuery.java">org/knopflerfish/service/um/useradmin/impl/LDAPQuery.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/RoleImpl.java">org/knopflerfish/service/um/useradmin/impl/RoleImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/SendUserAdminEventJob.java">org/knopflerfish/service/um/useradmin/impl/SendUserAdminEventJob.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UACredentials.java">org/knopflerfish/service/um/useradmin/impl/UACredentials.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UAProperties.java">org/knopflerfish/service/um/useradmin/impl/UAProperties.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UserAdminImpl.java">org/knopflerfish/service/um/useradmin/impl/UserAdminImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UserImpl.java">org/knopflerfish/service/um/useradmin/impl/UserImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Authorization.java">org/osgi/service/useradmin/Authorization.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Group.java">org/osgi/service/useradmin/Group.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Role.java">org/osgi/service/useradmin/Role.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/User.java">org/osgi/service/useradmin/User.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdmin.java">org/osgi/service/useradmin/UserAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java">org/osgi/service/useradmin/UserAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminListener.java">org/osgi/service/useradmin/UserAdminListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java">org/osgi/service/useradmin/UserAdminPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/package-info.java">org/osgi/service/useradmin/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/useradmin/useradmin_all-4.1.1.html b/docs/jars/useradmin/useradmin_all-4.1.1.html
new file mode 100644
index 0000000..6d37ba5
--- /dev/null
+++ b/docs/jars/useradmin/useradmin_all-4.1.1.html
@@ -0,0 +1,387 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>useradmin_all-4.1.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>useradmin_all-4.1.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/useradmin/useradmin_all-4.1.1.jar">download</a> (50025 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>UserAdmin</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.useradmin</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.1.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>User Administration Service</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.knopflerfish.service.um.useradmin.impl.Activator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> 1.2.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a> [1.2.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a> [1.3.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> [1.1.0,1.2.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a> [1.5.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:56</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/useradmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:useradmin:4.1.1</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../event/event_api-4.0.1.html">event_api-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/event/package-summary.html">org.osgi.service.event</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.servi [...]
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/util/tracker/package-summary.html">org.osgi.util.tracker</a></td></tr>
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/log/package-summary.html">org.osgi.service.log</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator_all-4.0.0.html">basicdriverlocator_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../basicdriverlocator/basicdriverlocator-4.0.0.html">basicdriverlocator-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm_all-5.0.1.html">cm_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm/cm-5.0.1.html">cm-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop_all-5.0.2.html">cm_desktop_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../cm_desktop/cm_desktop-5.0.2.html">cm_desktop-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../commons-logging/commons-logging_all-2.0.0.kf4-001.html">commons-logging_all-2.0.0.kf4-001</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.us [...]
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm_all-1.0.0.html">desktop_jvm_all-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../desktop_jvm/desktop_jvm-1.0.0.html">desktop_jvm-1.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../event/event_all-4.0.1.html">event_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http_all-4.0.5.html">http_all-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../http/http-4.0.5.html">http-4.0.5</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../httproot/httproot-4.0.0.html">httproot-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../logcommands/logcommands-5.0.0.html">logcommands-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../serialportdevice/serialportdevice_all-4.0.0.html">serialportdevice_all-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../trayicon_fw/trayicon_fw-4.0.0.html">trayicon_fw-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.servi [...]
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.us [...]
+<tr><td><a href="../log/log_all-5.0.0.html">log_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log_api-5.0.0.html">log_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+<tr><td><a href="../log/log-5.0.0.html">log-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/log/package-summary.html">org.knopflerfish.service.log</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/ipam/IPAMValuationService.java">org/knopflerfish/service/um/ipam/IPAMValuationService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/ipam/Levels.java">org/knopflerfish/service/um/ipam/Levels.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/BackEndControl.java">org/knopflerfish/service/um/useradmin/BackEndControl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/BackEndException.java">org/knopflerfish/service/um/useradmin/BackEndException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/Condition.java">org/knopflerfish/service/um/useradmin/Condition.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/ContextualAuthorization.java">org/knopflerfish/service/um/useradmin/ContextualAuthorization.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdAuthenticator.java">org/knopflerfish/service/um/useradmin/PasswdAuthenticator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdSession.java">org/knopflerfish/service/um/useradmin/PasswdSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdUtil.java">org/knopflerfish/service/um/useradmin/PasswdUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/Activator.java">org/knopflerfish/service/um/useradmin/impl/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/AuthorizationImpl.java">org/knopflerfish/service/um/useradmin/impl/AuthorizationImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/ConditionImpl.java">org/knopflerfish/service/um/useradmin/impl/ConditionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/EventQueue.java">org/knopflerfish/service/um/useradmin/impl/EventQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/GroupImpl.java">org/knopflerfish/service/um/useradmin/impl/GroupImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/LDAPQuery.java">org/knopflerfish/service/um/useradmin/impl/LDAPQuery.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/RoleImpl.java">org/knopflerfish/service/um/useradmin/impl/RoleImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/SendUserAdminEventJob.java">org/knopflerfish/service/um/useradmin/impl/SendUserAdminEventJob.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UACredentials.java">org/knopflerfish/service/um/useradmin/impl/UACredentials.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UAProperties.java">org/knopflerfish/service/um/useradmin/impl/UAProperties.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UserAdminImpl.java">org/knopflerfish/service/um/useradmin/impl/UserAdminImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UserImpl.java">org/knopflerfish/service/um/useradmin/impl/UserImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Authorization.java">org/osgi/service/useradmin/Authorization.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Group.java">org/osgi/service/useradmin/Group.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Role.java">org/osgi/service/useradmin/Role.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/User.java">org/osgi/service/useradmin/User.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdmin.java">org/osgi/service/useradmin/UserAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java">org/osgi/service/useradmin/UserAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminListener.java">org/osgi/service/useradmin/UserAdminListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java">org/osgi/service/useradmin/UserAdminPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/package-info.java">org/osgi/service/useradmin/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/useradmin/useradmin_api-4.1.1.html b/docs/jars/useradmin/useradmin_api-4.1.1.html
new file mode 100644
index 0000000..22a896f
--- /dev/null
+++ b/docs/jars/useradmin/useradmin_api-4.1.1.html
@@ -0,0 +1,349 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>useradmin_api-4.1.1.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>useradmin_api-4.1.1.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/useradmin/useradmin_api-4.1.1.jar">download</a> (15225 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>UserAdmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.useradmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.1.1</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>User Administration Service (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> 1.1.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a> [1.0.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a> [1.1.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:56</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/useradmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-Icon</td>
+ <td>icon.png;size=32</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:useradmin:4.1.1:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../consoletcp/consoletcp_all-5.0.0.html">consoletcp_all-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../consoletcp/consoletcp-5.0.0.html">consoletcp-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../consoletelnet/consoletelnet-4.0.1.html">consoletelnet-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.useradmin</a></td></tr>
+<tr><td><a href="../useradmin/useradmin_all-4.1.1.html">useradmin_all-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../useradmin/useradmin_api-4.1.1.html">useradmin_api-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.servic [...]
+<tr><td><a href="../useradmin/useradmin-4.1.1.html">useradmin-4.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/ipam/package-summary.html">org.knopflerfish.service.um.ipam</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/service/um/useradmin/package-summary.html">org.knopflerfish.service.um.useradmin</a>, <a target="_top" href="../../javadoc/index.html?org/osgi/service/useradmin/package-summary.html">org.osgi.service.userad [...]
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/ipam/IPAMValuationService.java">org/knopflerfish/service/um/ipam/IPAMValuationService.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/ipam/Levels.java">org/knopflerfish/service/um/ipam/Levels.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/BackEndControl.java">org/knopflerfish/service/um/useradmin/BackEndControl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/BackEndException.java">org/knopflerfish/service/um/useradmin/BackEndException.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/Condition.java">org/knopflerfish/service/um/useradmin/Condition.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/ContextualAuthorization.java">org/knopflerfish/service/um/useradmin/ContextualAuthorization.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdAuthenticator.java">org/knopflerfish/service/um/useradmin/PasswdAuthenticator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdSession.java">org/knopflerfish/service/um/useradmin/PasswdSession.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/PasswdUtil.java">org/knopflerfish/service/um/useradmin/PasswdUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/Activator.java">org/knopflerfish/service/um/useradmin/impl/Activator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/AuthorizationImpl.java">org/knopflerfish/service/um/useradmin/impl/AuthorizationImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/ConditionImpl.java">org/knopflerfish/service/um/useradmin/impl/ConditionImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/EventQueue.java">org/knopflerfish/service/um/useradmin/impl/EventQueue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/GroupImpl.java">org/knopflerfish/service/um/useradmin/impl/GroupImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/LDAPQuery.java">org/knopflerfish/service/um/useradmin/impl/LDAPQuery.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/RoleImpl.java">org/knopflerfish/service/um/useradmin/impl/RoleImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/SendUserAdminEventJob.java">org/knopflerfish/service/um/useradmin/impl/SendUserAdminEventJob.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UACredentials.java">org/knopflerfish/service/um/useradmin/impl/UACredentials.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UAProperties.java">org/knopflerfish/service/um/useradmin/impl/UAProperties.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UserAdminImpl.java">org/knopflerfish/service/um/useradmin/impl/UserAdminImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/knopflerfish/service/um/useradmin/impl/UserImpl.java">org/knopflerfish/service/um/useradmin/impl/UserImpl.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Authorization.java">org/osgi/service/useradmin/Authorization.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Group.java">org/osgi/service/useradmin/Group.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/Role.java">org/osgi/service/useradmin/Role.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/User.java">org/osgi/service/useradmin/User.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdmin.java">org/osgi/service/useradmin/UserAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java">org/osgi/service/useradmin/UserAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminListener.java">org/osgi/service/useradmin/UserAdminListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java">org/osgi/service/useradmin/UserAdminPermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/useradmin/src/org/osgi/service/useradmin/package-info.java">org/osgi/service/useradmin/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/util/util-4.1.0.html b/docs/jars/util/util-4.1.0.html
new file mode 100644
index 0000000..d251d76
--- /dev/null
+++ b/docs/jars/util/util-4.1.0.html
@@ -0,0 +1,297 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>util-4.1.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>util-4.1.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/util/util-4.1.0.jar">download</a> (47278 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>util-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.util-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.1.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>Misc utilities (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a> 1.1.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a> 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/workerthread/package-summary.html">org.knopflerfish.util.workerthread</a> 1.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:25:56</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/util</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>Knopflerfish</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>utility</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:util:4.1.0:lib</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../cm_cmd/cm_cmd-5.0.1.html">cm_cmd-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a></td></tr>
+<tr><td><a href="../desktop/desktop_all-5.0.1.html">desktop_all-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/sort/package-summary.html">org.knopflerfish.util.sort</a>, <a target="_top" href=" [...]
+<tr><td><a href="../desktop/desktop-5.0.1.html">desktop-5.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a>, <a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a></td></tr>
+<tr><td><a href="../httpconsole/httpconsole_all-4.0.1.html">httpconsole_all-4.0.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../kf_metatype/kf_metatype_all-5.0.2.html">kf_metatype_all-5.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../prefs/prefs_all-4.0.2.html">prefs_all-4.0.2</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/package-summary.html">org.knopflerfish.util</a></td></tr>
+<tr><td><a href="../repository_desktop/repository_desktop_all-1.1.1.html">repository_desktop_all-1.1.1</a></td><td><a target="_top" href="../../javadoc/index.html?org/knopflerfish/util/framework/package-summary.html">org.knopflerfish.util.framework</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Base64.java">org/knopflerfish/util/Base64.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/ByteArray.java">org/knopflerfish/util/ByteArray.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/CacheMap.java">org/knopflerfish/util/CacheMap.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/CachedObject.java">org/knopflerfish/util/CachedObject.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/ClassLoaderUtil.java">org/knopflerfish/util/ClassLoaderUtil.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Compare.java">org/knopflerfish/util/Compare.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Dict.java">org/knopflerfish/util/Dict.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Lists.java">org/knopflerfish/util/Lists.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Queue.java">org/knopflerfish/util/Queue.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Semaphore.java">org/knopflerfish/util/Semaphore.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Text.java">org/knopflerfish/util/Text.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/Timer.java">org/knopflerfish/util/Timer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/framework/Alias.java">org/knopflerfish/util/framework/Alias.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/framework/ExecutableBundleActivator.java">org/knopflerfish/util/framework/ExecutableBundleActivator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/framework/VersionRange.java">org/knopflerfish/util/framework/VersionRange.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/sort/CompareFunc.java">org/knopflerfish/util/sort/CompareFunc.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/sort/QSort.java">org/knopflerfish/util/sort/QSort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/sort/Sort.java">org/knopflerfish/util/sort/Sort.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/workerthread/Job.java">org/knopflerfish/util/workerthread/Job.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/workerthread/RepeatingJob.java">org/knopflerfish/util/workerthread/RepeatingJob.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/util/src/org/knopflerfish/util/workerthread/WorkerThread.java">org/knopflerfish/util/workerthread/WorkerThread.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/wireadmin/wireadmin_api-5.0.0.html b/docs/jars/wireadmin/wireadmin_api-5.0.0.html
new file mode 100644
index 0000000..00b1edd
--- /dev/null
+++ b/docs/jars/wireadmin/wireadmin_api-5.0.0.html
@@ -0,0 +1,240 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>wireadmin_api-5.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>wireadmin_api-5.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/wireadmin/wireadmin_api-5.0.0.jar">download</a> (10209 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>wireadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.wireadmin-API</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>5.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>WireAdmin (API)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td>http://opensource.org/licenses/Apache-2.0;link="http://www.apache.org/licenses/LICENSE-2.0";description="Apache License, Version 2.0"</td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/service/wireadmin/package-summary.html">org.osgi.service.wireadmin</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/service/wireadmin/package-summary.html">org.osgi.service.wireadmin</a> [1.0.1,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:28:24</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/wireadmin</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>API</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:wireadmin:5.0.0:api</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../wireadmin/wireadmin_api-5.0.0.html">wireadmin_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/wireadmin/package-summary.html">org.osgi.service.wireadmin</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../wireadmin/wireadmin_api-5.0.0.html">wireadmin_api-5.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/service/wireadmin/package-summary.html">org.osgi.service.wireadmin</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/BasicEnvelope.java">org/osgi/service/wireadmin/BasicEnvelope.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/Consumer.java">org/osgi/service/wireadmin/Consumer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/Envelope.java">org/osgi/service/wireadmin/Envelope.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/Producer.java">org/osgi/service/wireadmin/Producer.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/Wire.java">org/osgi/service/wireadmin/Wire.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/WireAdmin.java">org/osgi/service/wireadmin/WireAdmin.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/WireAdminEvent.java">org/osgi/service/wireadmin/WireAdminEvent.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/WireAdminListener.java">org/osgi/service/wireadmin/WireAdminListener.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/WireConstants.java">org/osgi/service/wireadmin/WireConstants.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/WirePermission.java">org/osgi/service/wireadmin/WirePermission.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/wireadmin/src/org/osgi/service/wireadmin/package-info.java">org/osgi/service/wireadmin/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/xalan/xalan-2.7.1.kf3_01.html b/docs/jars/xalan/xalan-2.7.1.kf3_01.html
new file mode 100644
index 0000000..35dc4d5
--- /dev/null
+++ b/docs/jars/xalan/xalan-2.7.1.kf3_01.html
@@ -0,0 +1,219 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>xalan-2.7.1.kf3_01.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>xalan-2.7.1.kf3_01.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/xalan/xalan-2.7.1.kf3_01.jar">download</a> (1804820 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Xalan</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.xalan</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.7.1.kf3_01</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The Apache Xalan-Java XML transformer</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Apache/Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=xalan/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=xalan/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.osgi.util.xml.XMLTransformerActivator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,xml-apis.jar,xalan.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.xml.transform 1.3.0.selectFirst<br>
+javax.xml.transform.dom 1.3.0.selectFirst<br>
+javax.xml.transform.sax 1.3.0.selectFirst<br>
+javax.xml.transform.stream 1.3.0.selectFirst<br>
+org.apache.xalan 0.0.0<br>
+org.apache.xalan.processor 0.0.0<br>
+org.apache.xpath.jaxp 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.naming 0.0.0<br>
+javax.xml.namespace 1.3.0<br>
+javax.xml.parsers 1.3.0<br>
+javax.xml.transform 1.3.0<br>
+javax.xml.transform.dom 1.3.0<br>
+javax.xml.transform.sax 1.3.0<br>
+javax.xml.transform.stream 1.3.0<br>
+javax.xml.xpath 1.3.0<br>
+org.apache.xalan 0.0.0<br>
+org.apache.xalan.processor 0.0.0<br>
+org.apache.xerces.parsers 0.0.0<br>
+org.apache.xml.serialize 0.0.0<br>
+org.apache.xml.serializer 0.0.0<br>
+org.apache.xpath.jaxp 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+org.w3c.dom 0.0.0<br>
+org.w3c.dom.events 0.0.0<br>
+org.w3c.dom.traversal 0.0.0<br>
+org.w3c.dom.xpath 0.0.0<br>
+org.xml.sax 0.0.0<br>
+org.xml.sax.ext 0.0.0<br>
+org.xml.sax.helpers 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:37</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/xml/xalan</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>lib</td>
+</tr>
+<tr>
+ <td>Bundle-Copyright</td>
+ <td><a target="_top" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a></td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xalan/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xalan/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:xalan:2.7.1.kf3_01</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td>org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td>javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, org.apache.xalan, org.apache.xalan.processor, org.apache.xpath.jaxp</td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml.namespace, javax.xml.parsers, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, javax.xml.xpath, org.apache.xerces.parsers, org.apache.xml.serialize, org.apache.xml.serializer, org.w3c.dom, org.w3c.dom.events, org.w3c.dom.traversal, org.w3c.dom.xpath, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td>javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, org.apache.xalan, org.apache.xalan.processor, org.apache.xpath.jaxp</td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xalan/src/org/osgi/util/xml/XMLTransformerActivator.java">org/osgi/util/xml/XMLTransformerActivator.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/jars/xerces/xerces-2.10.1.kf5.html b/docs/jars/xerces/xerces-2.10.1.kf5.html
new file mode 100644
index 0000000..0a4c0f8
--- /dev/null
+++ b/docs/jars/xerces/xerces-2.10.1.kf5.html
@@ -0,0 +1,292 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>xerces-2.10.1.kf5.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>xerces-2.10.1.kf5.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/xerces/xerces-2.10.1.kf5.jar">download</a> (1619502 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>Xerces-J</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.xerces</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>2.10.1.kf5</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>The Apache Xerces2 Java XML parser</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Apache/Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=xerces/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=xerces/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td>org.osgi.util.xml.XMLParserActivator</td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.,xercesImpl.jar,xml-apis.jar,resolver.jar,serializer.jar</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td>javax.xml 1.3.0<br>
+javax.xml.datatype 1.3.0<br>
+javax.xml.namespace 1.3.0<br>
+javax.xml.parsers 1.3.0<br>
+javax.xml.transform 1.3.0<br>
+javax.xml.transform.dom 1.3.0<br>
+javax.xml.transform.sax 1.3.0<br>
+javax.xml.transform.stream 1.3.0<br>
+javax.xml.validation 1.3.0<br>
+javax.xml.xpath 1.3.0<br>
+org.apache.html.dom 0.0.0<br>
+org.apache.wml 0.0.0<br>
+org.apache.wml.dom 0.0.0<br>
+org.apache.xerces.dom 0.0.0<br>
+org.apache.xerces.dom.events 0.0.0<br>
+org.apache.xerces.dom3.as 0.0.0<br>
+org.apache.xerces.jaxp 0.0.0<br>
+org.apache.xerces.jaxp.datatype 0.0.0<br>
+org.apache.xerces.jaxp.validation 0.0.0<br>
+org.apache.xerces.parsers 0.0.0<br>
+org.apache.xerces.util 0.0.0<br>
+org.apache.xerces.xinclude 0.0.0<br>
+org.apache.xerces.xni 0.0.0<br>
+org.apache.xerces.xni.grammars 0.0.0<br>
+org.apache.xerces.xni.parser 0.0.0<br>
+org.apache.xerces.xpointer 0.0.0<br>
+org.apache.xerces.xs 0.0.0<br>
+org.apache.xerces.xs.datatypes 0.0.0<br>
+org.apache.xml.resolver 1.2.0<br>
+org.apache.xml.resolver.apps 1.2.0<br>
+org.apache.xml.resolver.helpers 1.2.0<br>
+org.apache.xml.resolver.readers 1.2.0<br>
+org.apache.xml.resolver.tools 1.2.0<br>
+org.apache.xml.serialize 0.0.0<br>
+org.apache.xml.serializer 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a> 1.0.1<br>
+org.w3c.dom 3.0.0<br>
+org.w3c.dom.bootstrap 3.0.0<br>
+org.w3c.dom.css 3.0.0<br>
+org.w3c.dom.events 3.0.0<br>
+org.w3c.dom.html 3.0.0<br>
+org.w3c.dom.ls 3.0.0<br>
+org.w3c.dom.ranges 3.0.0<br>
+org.w3c.dom.stylesheets 3.0.0<br>
+org.w3c.dom.traversal 3.0.0<br>
+org.w3c.dom.views 3.0.0<br>
+org.w3c.dom.xpath 3.0.0<br>
+org.xml.sax 2.0.2<br>
+org.xml.sax.ext 2.0.2<br>
+org.xml.sax.helpers 2.0.2<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.xml 1.3.0<br>
+javax.xml.datatype 1.3.0<br>
+javax.xml.namespace 1.3.0<br>
+javax.xml.parsers 1.3.0<br>
+javax.xml.transform 1.3.0<br>
+javax.xml.transform.dom 1.3.0<br>
+javax.xml.transform.sax 1.3.0<br>
+javax.xml.transform.stream 1.3.0<br>
+javax.xml.validation 1.3.0<br>
+javax.xml.xpath 1.3.0<br>
+org.apache.html.dom 0.0.0<br>
+org.apache.wml 0.0.0<br>
+org.apache.wml.dom 0.0.0<br>
+org.apache.xerces.dom 0.0.0<br>
+org.apache.xerces.dom.events 0.0.0<br>
+org.apache.xerces.dom3.as 0.0.0<br>
+org.apache.xerces.jaxp 0.0.0<br>
+org.apache.xerces.jaxp.datatype 0.0.0<br>
+org.apache.xerces.jaxp.validation 0.0.0<br>
+org.apache.xerces.parsers 0.0.0<br>
+org.apache.xerces.util 0.0.0<br>
+org.apache.xerces.xinclude 0.0.0<br>
+org.apache.xerces.xni 0.0.0<br>
+org.apache.xerces.xni.grammars 0.0.0<br>
+org.apache.xerces.xni.parser 0.0.0<br>
+org.apache.xerces.xpointer 0.0.0<br>
+org.apache.xerces.xs 0.0.0<br>
+org.apache.xerces.xs.datatypes 0.0.0<br>
+org.apache.xml.resolver 1.2.0<br>
+org.apache.xml.resolver.apps 1.2.0<br>
+org.apache.xml.resolver.helpers 1.2.0<br>
+org.apache.xml.resolver.readers 1.2.0<br>
+org.apache.xml.resolver.tools 1.2.0<br>
+org.apache.xml.serialize [0.0.0,1.0.0)<br>
+org.apache.xml.serializer 1.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a> [1.0.1,2.0.0)<br>
+org.w3c.dom 3.0.0<br>
+org.w3c.dom.bootstrap 3.0.0<br>
+org.w3c.dom.css 3.0.0<br>
+org.w3c.dom.events 3.0.0<br>
+org.w3c.dom.html 3.0.0<br>
+org.w3c.dom.ls 3.0.0<br>
+org.w3c.dom.ranges 3.0.0<br>
+org.w3c.dom.stylesheets 3.0.0<br>
+org.w3c.dom.traversal 3.0.0<br>
+org.w3c.dom.views 3.0.0<br>
+org.w3c.dom.xpath 3.0.0<br>
+org.xml.sax 2.0.2<br>
+org.xml.sax.ext 2.0.2<br>
+org.xml.sax.helpers 2.0.2<br>
+sun.io 0.0.0<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td></td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:10</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/xml/xerces</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>lib</td>
+</tr>
+<tr>
+ <td>Bundle-Copyright</td>
+ <td><a target="_top" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a></td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xerces/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xerces/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:xerces:2.10.1.kf5</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td>javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream</td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml, javax.xml.datatype, javax.xml.namespace, javax.xml.parsers, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, javax.xml.validation, javax.xml.xpath, org.apache.html.dom, org.apache.wml, org.apache.wml.dom, org.apache.xerces.dom, org.apache.xerces.dom.events, org.apache.xerces.dom3.as, org.apache.xerces.jaxp, org.apache.xerces.jaxp.datatype, org.apac [...]
+<tr><td><a href="../xml/xml-4.0.0.html">xml-4.0.0</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a></td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+<tr><td><b>Unresolved</b></td><td></td></tr>
+<tr><td>sun.io</td><td>0.0.0</td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td>javax.xml.parsers, org.w3c.dom, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../junit/junit_all-3.8.1.kf4-001.html">junit_all-3.8.1.kf4-001</a></td><td>javax.xml.parsers, org.w3c.dom</td></tr>
+<tr><td><a href="../xalan/xalan-2.7.1.kf3_01.html">xalan-2.7.1.kf3_01</a></td><td>javax.xml.namespace, javax.xml.parsers, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, javax.xml.xpath, org.apache.xerces.parsers, org.apache.xml.serialize, org.apache.xml.serializer, org.w3c.dom, org.w3c.dom.events, org.w3c.dom.traversal, org.w3c.dom.xpath, org.xml.sax, org.xml.sax.ext, org.xml.sax.helpers</td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml, javax.xml.datatype, javax.xml.namespace, javax.xml.parsers, javax.xml.transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, javax.xml.validation, javax.xml.xpath, org.apache.html.dom, org.apache.wml, org.apache.wml.dom, org.apache.xerces.dom, org.apache.xerces.dom.events, org.apache.xerces.dom3.as, org.apache.xerces.jaxp, org.apache.xerces.jaxp.datatype, org.apac [...]
+<tr><td><a href="../xml/xml-4.0.0.html">xml-4.0.0</a></td><td>javax.xml.parsers</td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+None found
+
+</body>
+</html>
+
+
diff --git a/docs/jars/xml/xml-4.0.0.html b/docs/jars/xml/xml-4.0.0.html
new file mode 100644
index 0000000..5545cda
--- /dev/null
+++ b/docs/jars/xml/xml-4.0.0.html
@@ -0,0 +1,196 @@
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+  <link href="../style.css" rel="stylesheet" type="text/css">
+  <title>xml-4.0.0.jar</title>
+  <script type="text/javascript">
+    function windowTitle() {
+      if (location.href.indexOf('is-external=true') == -1) {
+        parent.document.title=document.title;
+      }
+    }
+  </script>
+</head>
+
+<body onload="windowTitle();">
+
+<h2>xml-4.0.0.jar</h2>
+
+<p>
+<a href="../../../osgi/jars/xml/xml-4.0.0.jar">download</a> (4789 bytes)
+</p>
+
+<table width="100%">
+ <tr>
+  <td class="mfheader" colspan=2>OSGi manifest attributes</td>
+ </tr>
+
+ <tr>
+  <td>Bundle-Name</td>
+  <td>xml-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-SymbolicName</td>
+  <td>org.knopflerfish.bundle.xml-LIB</td>
+ </tr>
+ <tr>
+  <td>Bundle-Version</td>
+  <td>4.0.0</td>
+ </tr>
+ <tr>
+  <td>Bundle-Description</td>
+  <td>XML (LIB)</td>
+ </tr>
+ <tr>
+  <td>Bundle-Vendor</td>
+  <td>Knopflerfish</td>
+ </tr>
+ <tr>
+  <td>Bundle-ContactAddress</td>
+  <td>http://www.knopflerfish.org</td>
+ </tr>
+ <tr>
+  <td>Bundle-License</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-DocURL</td>
+  <td><a target="_top" href="http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=xml/index.html">http://www.knopflerfish.org/releases/5.1.0/docs/bundledoc/index.html?docpage=xml/index.html</a></td>
+ </tr>
+ <tr>
+  <td>Bundle-ManifestVersion</td>
+  <td>2</td>
+ </tr>
+ <tr>
+  <td>Bundle-Activator</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Bundle-Classpath</td>
+  <td>.</td>
+ </tr>
+
+ <tr>
+  <td>Export-Package</td>
+  <td><a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a> 1.0.1<br>
+</td>
+ </tr>
+ <tr>
+  <td>Import-Package</td>
+  <td>javax.xml.parsers 0.0.0<br>
+<a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a> [1.6.0,2.0.0)<br>
+</td>
+ </tr>
+ <tr>
+  <td>Dynamic-ImportPackage</td>
+  <td></td>
+ </tr>
+
+ <tr>
+  <td>Provide-Capability</td>
+  <td></td>
+ </tr>
+ <tr>
+  <td>Require-Capability</td>
+  <td>osgi.ee;filter:="(&(osgi.ee=OSGi/Minimum)(version>=1.2))"</td>
+ </tr>
+
+
+ <tr>
+  <td  class="mfheader" colspan=2>Other manifest attributes</td>
+ </tr>
+
+ <tr>
+ <td>Build-Date</td>
+ <td>Fri June 13 2014, 08:27:00</td>
+</tr>
+<tr>
+ <td>Built-From</td>
+ <td>/Users/jan/work/release/knopflerfish.org/osgi/bundles/xml/xml</td>
+</tr>
+<tr>
+ <td>Bundle-APIVendor</td>
+ <td>OSGi</td>
+</tr>
+<tr>
+ <td>Bundle-Category</td>
+ <td>osgi</td>
+</tr>
+<tr>
+ <td>Bundle-SubversionURL</td>
+ <td><a target="_top" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xml/">https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xml/</a></td>
+</tr>
+<tr>
+ <td>Bundle-UUID</td>
+ <td>org.knopflerfish:xml:4.0.0:lib</td>
+</tr>
+<tr>
+ <td>Knopflerfish-Version</td>
+ <td>5.1.0</td>
+</tr>
+
+
+</table>
+
+
+<h4>Depends on (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that can provide one or more of the
+capabilities that is required in the <tt>osgi.wiring.package</tt>
+namespace. Only one provider of each capability is required.
+
+<p>
+
+The first column is the providing bundle and the second column lists
+the sub-set of its provided packages that are required by this bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../crimson/crimson-2.1.0.kf4-001.html">crimson-2.1.0.kf4-001</a></td><td>javax.xml.parsers</td></tr>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td>javax.xml.parsers</td></tr>
+<tr><td><a href="../framework.html">framework</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/framework/package-summary.html">org.osgi.framework</a></td></tr>
+
+</table>
+
+<h4>Other bundles depending on this bundle (<tt>osgi.wiring.package</tt>)</h4>
+
+This section lists bundles that requires one or more of the
+capabilities that is provided in the namespace
+<tt>osgi.wiring.package</tt> by the current bundle.
+
+<p>
+
+The first column is the requiring bundle and the second column lists
+the sub-set of capabilities that this bundle may provide to the
+requiring bundle.
+
+<p>
+
+<table>
+<tr><td><a href="../xerces/xerces-2.10.1.kf5.html">xerces-2.10.1.kf5</a></td><td><a target="_top" href="../../javadoc/index.html?org/osgi/util/xml/package-summary.html">org.osgi.util.xml</a></td></tr>
+
+</table>
+
+
+<a name="source"></a>
+<h4>Bundle source</h4>
+
+Here are links to the source files of this bundle.
+
+<table> <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xml/src/org/osgi/util/xml/XMLParserActivator.java">org/osgi/util/xml/XMLParserActivator.java<a>
+  </td>
+ </tr>
+ <tr>
+  <td>
+    <a href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0/osgi/bundles/xml/xml/src/org/osgi/util/xml/package-info.java">org/osgi/util/xml/package-info.java<a>
+  </td>
+ </tr>
+</table>
+
+</body>
+</html>
+
+
diff --git a/docs/license.html b/docs/license.html
new file mode 100644
index 0000000..706b6ae
--- /dev/null
+++ b/docs/license.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  - BSD 3-style open source license"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Knopflerfish Open Source License"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Knopflerfish Open Source License</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Knopflerfish License</h1>
+The Knopflerfish OSGi service platform is available under a 
+<a href="http://www.opensource.org/licenses/BSD-3-Clause">BSD 3-Clause License</a>
+<p>
+A notice with third party licenses is available in a separate <a
+href="../NOTICE.txt">NOTICE.txt</a> file.
+<p>
+
+<h2 class="kf">Knopflerfish License</h2>
+<pre class="shell">
+Copyright (c) 2003-2014, 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.
+
+</pre>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/osgi_service_tutorial.html b/docs/osgi_service_tutorial.html
new file mode 100644
index 0000000..2ee75bd
--- /dev/null
+++ b/docs/osgi_service_tutorial.html
@@ -0,0 +1,626 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "The OSGi Service Tutorial"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  OSGi Service Tutorial"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  OSGi Service Tutorial</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">OSGi Service Tutorial</h1>
+
+<h2 class="kf">Contents</h2>
+<ol>
+ <li><a href="#what_is">What is a service?</a>
+ <li><a href="#what_isfactory">What is a service factory?</a>
+ <li><a href="#what_for">What can services be used for?</a>
+ <li><a href="#accessing">How are services accessed??</a>
+ <li><a href="#release">Releasing services</a>
+ <li><a href="#best">Best practices for accessing services</a>
+ <li><a href="#white">The white-board model</a>
+</ol>
+
+
+
+<a name="what_is"></a>
+<h2 class="kf">What is a service?</h2>
+
+<div class="intro" style="width: 300px;">
+An OSGi service is a java object instance, <i>registered</i> into
+an OSGi framework with a set of <i>properties</i>. Any java object can be registered as a service, but typically it implements a well-known interface.
+</div>
+
+<p>
+The OSGi <a href="http://www.osgi.org/osgi_technology/download_specs.asp?section=2">R3 specification</a>, chapter 4.10 is highly recommended reading. Also, the javadoc for <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html">BundleContext</a> contains lot of information.
+</p>
+
+<p>
+The client of a service is always an OSGi bundle, i.e. a piece of java
+code possible to start via the <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleActivator.html">BundleActivator</a> interface.
+</p>
+
+<p>
+Each bundle may register zero or more services. Each bundle may also use
+zero or more services. There exists no limit on the number of services, more 
+than the ones given by memory limits or java security permissions.
+</p>
+
+<p>
+Both publishing/registering and usage of services can be restricted by using java security permissions.
+</p>
+
+<pre class="code">
+<div class="head">Registering a very simple object as a service</div>
+Long      i     = new Long(20);
+Hashtable props = new Hashtable();
+props.put("description", "This an long value");
+bc.<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)">registerService</a>(Long.class.getName(), i, props);
+</pre>
+
+<p>
+<b>Note</b>: a service can also be registered as several interfaces. In this case, the object <i>must</i> implement all of the interfaces.
+</p>
+
+<a name="what_isfactory"></a>
+<h2 class="kf">What is a service factory?</h2>
+
+<div class="intro">
+An OSGi service factory is a special class <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceFactory.html">ServiceFactory</a>, which
+can create individual instances of service objects for <i>different</i> bundles.</div>
+
+<p>
+Sometimes a service needs to be differently configured depending on which 
+bundle uses the service. For example, the log service needs to be able to
+print the logging bundle's id, otherwise the log would be hard to read.
+</p>
+<p>
+A service factory is registered in exactly the same way as a normal service, using <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)">registerService</a>, the only difference is an indirection step before the actual service object is handed out.
+</p>
+
+<p>
+The client using the service need not, and should not, care if a service is 
+generated by a factory or by a plain object.
+</p>
+
+<pre class="code">
+<div class="head">A simple service factory example</div>
+  class LongFactory implements ServiceFactory {
+    public Object getService(Bundle bundle, ServiceRegistration reg) { 
+       // each bundle gets a Long with it's own id
+       return new Long(bundle.getBundleId());
+    }
+    void ungetService(Bundle bundle, ServiceRegistration reg, Object service) {
+       // nothing needed in this case
+    }
+  }
+  
+  ServiceFactory factory = new LongFactory();
+  bc.registerService(Long.class.getName(), factory, new Hashtable()); 
+</pre>
+
+<p>
+<b>Note</b>: The framework will cache generated service objects. Thus, 
+at most one service can be generated per client bundle.
+</p>
+
+<a name="what_for"></a>
+<h2 class="kf">What can services be used for?</h2>
+
+<p>
+The service concept is a very general-purpose tool, but some examples are:
+</p>
+<ul>
+ <li>Export functionality from a bundle to other bundles<br>
+ <li>Import functionality from other bundles<br>
+ <li>Register listeners for events from other bundles<br>
+ <li>Expose external devices, such as UPnP devices or even hardware,
+     to other OSGi bundles. See the <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/service/device/package-summary.html">Device</a> and <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/service/upnp/package-summary.html">UPnP</a> APIs
+ <li>Expose java code running in OSGI to an external network, e.g. via the 
+   UPnP or <a href="bundledoc/index.html?docpage=soap/index.html">SOAP</a> protocols. 
+ <li>Bundle configuration, using the <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/service/cm/package-summary.html">Configuration Manager</a>
+</ul>
+
+<p>
+Generally, services is the preferred method bundles should use to communicate 
+between each other.
+</p>
+
+<a name="accessing"></a>
+<h2 class="kf">How are services accessed?</h2>
+
+<div class="intro">
+Services are always accessed via <i>ServiceReferences</i>, which uniquely
+points to a <i>service object</i>.
+</div>
+
+To access a service, the following procedure must always be used (possibly wrapped by utility code):
+<ol>
+ <li>Get a <tt><a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceReference.html">ServiceReference</a></tt>
+ <li>Get the service object from the reference, using <tt><a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#getService(org.osgi.framework.ServiceReference)">BundleContext.getService()</a></tt>
+</ol>
+
+<tt>ServiceReference</tt> are typically retrieved by:
+<ol>
+ <li>Explicit usage of <tt><a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#getServiceReferences(java.lang.String, java.lang.String)">BundleContext.getService()</a></tt><br/>
+     This returns either the highest ranked service of the given class, or 
+     <tt>null</tt>
+
+ <li>Explicit usage of <tt><a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#getServiceReference(java.lang.String)">BundleContext.getServices()</a></tt><br/>
+    This return the complete set of matching services, or <tt>null</tt>
+ <li>Callback from a <tt><a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceListener.html">ServiceListener</a></tt>
+ <li>Using the utility class <tt><a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/util/tracker/ServiceTracker.html">ServiceTracker</a></tt>
+</ol>
+
+<p>
+All cases, except the first, allow the client to specify a set of properties
+that the service must fulfill. These properties are specified using LDAP <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/Filter.html">filters</a>. Zero or more service
+references can match a given filter. 
+</p>
+<p>
+A typical filter contains a class name and a set of properties. The example below matches a Http service having a "port" property equal to 80.
+</p>
+<pre class="code">
+<div class="head">An LDAP filter string</div>
+(&(objectclass=org.osgi.service.http.HttpService)(port=80))
+</pre>
+
+<p>
+As soon as a ServiceReference is available, the service object can be accessed
+using a cast:
+</p>
+<pre class="code">
+  HttpService http = (HttpService)bc.getService(sr);
+</pre>
+
+<p>
+After this, the service object can be accessed as any other java object. Actually, it <b>is</b> a fully normal java object, more exact, it is the same object as the bundle registering the service created.
+</p>
+
+
+<a name="release"></a>
+<h2 class="kf">Releasing services</h2>
+<p>
+As soon as the service isn't needed anymore, the client should <b>release</b>
+the service by calling the <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#ungetService(org.osgi.framework.ServiceReference)">BundleContext.ungetService()</a> method.
+</p>
+
+<pre class="code">
+  bc.ungetService(sr);
+</pre>
+
+<p>
+All services are <b>automatically</b> released when the client bundles stops. 
+No special service cleanup is needed in BundleActivator.stop().
+</p>
+
+<p>
+Note that service should only be released when <b>really</b> unused. Some
+services may keep a state for each using bundle, and releasing the service
+will release this state, which may, or may not, be the intention. Each service
+documentation must be consulted. An example of this is the <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/service/http/HttpService.html">HttpService</a>, which
+will remove all servlets and resources from itself when a client releases
+the HttpService.
+</p>
+
+<p>
+Some special words are needed when using service listeners. A listener
+will get a <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceEvent.html#UNREGISTERING">ServiceEvent.UNREGISTERING</a> event when a service is in the process
+of being unregistering from the framework.
+</p>
+
+<p>
+While in this UNREGISTERING listener, the <tt>getService()</tt> call should
+<b>not</b> be expected to return a valid service object. In fact, the expected value
+is <tt>null</tt>, even if the spec is a bit vague on this. The OSGi reference
+implementation does however return <tt>null</tt> in this case.
+</p>
+
+<p>
+<b>Note</b>: It's fully possible for a client to hold on to a service object
+via a variable, even after the exporting bundle has been stopped. The client shouldn't expect the service to work in this case and this also blocks any garbage collection. Thus, don't forget to null variables holding services when the
+service is released. 
+</p>
+
+<a name="best"></a>
+<h2 class="kf">Best practices for accessing OSGi services</h2>
+
+<div class="intro">
+OSGi services must always be considered volatile, and may disappear or become
+unusable at <t>any time</t>.
+</div>
+
+<p>
+Suggested practices:
+</p>
+<ul>
+ <li>Always <b>expect RuntimeException</b> when calling a service<br>
+     A service may fail at any time, similar to RMI based code. The recommended
+     exception an unusable service should throw is <tt>IllegalStateException</tt>
+     This
+     does <b>not</b> mean that a try/catch block should be made on each
+     service call, rather that the code must be prepared to handle such
+     exceptions on a higher level.
+
+ <li>Use the <b><a href="#white">white-board model</a></b><br>
+     If possible, construct your code so users of your bundle functionality
+     can participate by registering services, instead of getting services.
+     It's much easier to register a service, than to get it. Thus, if you 
+     want to make life easier for clients, go for the white-board model.
+
+ <li>Use <b>listeners</b><br>
+     <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceListener.html">ServiceListener</a> and <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/util/tracker/ServiceTracker.html">ServiceTracker</a> provide various levels of automation for getting services.
+
+ <li>Use the declarative <b>ServiceBinder</b><br>
+     The <a href="http://gravity.sourceforge.net/servicebinder/">ServiceBinder</a> by Cervantes/Hall provide a framework for cases where it's possible
+     to declare service dependencies in XML.
+
+</ul>
+
+
+Consider the bad-styled, but common, code:
+<pre class="code">
+<div class="head"><a name="ex_bad"></a>Bad code example</div>
+01: ServiceReference sr  =  bc.<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#getServiceReference(java.lang.String)">getServiceReference</a>(HttpService.class.getName());
+02: HttpService http     = (HttpService)bc.<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#getService(org.osgi.framework.ServiceReference)">getService</a>(sr);
+03: http.registerServlet(....)
+</pre>
+
+Three things can fail, one for each line!<br>
+<ol>
+ <li>The ServiceReference can be <tt>null</tt> if no HttpService is registered,
+     resulting in <tt>NullPointerException</tt> on line 2.
+ <li>The http service object cannot be get, due to missing permissions,
+     possible timing issues if the http unregisters between lines 1 and 2, 
+     causing <tt>NullPointerException</tt> on line 3.
+ <li>The http service may have become unusable, resulting in any 
+     <tt>RuntimeException</tt> subclass, most likely <tt>IllegalStateException</tt> on
+    line 3.
+</ol>
+
+<p>
+Additionally, the code above does not handle the case where more than one service is registered and actions should be taken on each of them.
+</p>
+
+<p>
+The NPE problems can be naively avoided by adding conditionals:
+</p>
+
+<pre class="code">
+01: ServiceReference sr  =  bc.getServiceReference(HttpService.class.getName());
+02: if(sr != null) {
+03:   HttpService http = (HttpService)bc.getService(sr);
+04:   if(http != null) {
+05:     http.registerServlet(....)
+06:   }
+07: }
+</pre>
+
+<p>
+This approach quickly becomes very cumbersome, and also creates an undesirable
+start order problem, since the HttpService must be available when the code is
+run.
+</p>
+
+<p>
+By using a service listener, the code can avoid the first ServiceReference 
+<tt>null</tt> problem:
+</p>
+<pre class="code">
+<div class="head"><a name="ex_listener"></a>Using a service listener</div>
+01: ServiceListener sl = new <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceListener.html">ServiceListener</a>() {
+02:   public void ServiceChanged(<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceEvent.html">ServiceEvent</a> ev) {
+03:      ServiceReference sr = ev.getServiceReference();
+04:      switch(ev.getType()) {
+05:        case <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/ServiceEvent.html#REGISTERED">ServiceEvent.REGISTERED</a>:
+06:          {
+07:             HttpService http = (HttpService)bc.getService(sr);
+08:             http.registerServlet(...);
+09:          }
+10:          break;
+11:        default:
+12:          break;
+13:      }
+14:   }
+15: };
+16:
+17: String filter = "(objectclass=" + HttpService.class.getName() + ")";
+18: try {
+19:   bc.<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#addServiceListener(org.osgi.framework.ServiceListener)">addServiceListener</a>(sl, filter);
+20: } catch (<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/InvalidSyntaxException.html">InvalidSyntaxException</a> e) { 
+21:   e.printStackTrace(); 
+22: }
+</pre>
+<p>
+The possible RuntimeException when actually calling the service (line 8) is handled by the framework event delivery code, so if no special handling is needed in the client code, nothing needs to be done.
+</p>
+
+<p>
+There's still one problem -- if all HttpServices already had been registered, the listener above would not be called until the HttpServices were restarted. A small trick solves this: Manually construct REGISTERED ServiceEvents and call the
+listener:
+</p>
+<pre class="code">
+<div class="head"><a name="ex_manualevents"></a>Construct ServiceEvents - contd. from above</div>
+18: try {
+19:   bc.<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#addServiceListener(org.osgi.framework.ServiceListener)">addServiceListener</a>(sl, filter);
+20:   ServiceReference[] srl = bc.<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/BundleContext.html#getServiceReferences(java.lang.String, java.lang.String)">getServiceReferences</a>(null, filter);
+21:   for(int i = 0; srl != null && i < srl.length; i++) {
+22:     sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTRED,
+23:                                      srl[i]));
+24:   }
+25: } catch (<a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/framework/InvalidSyntaxException.html">InvalidSyntaxException</a> e) { 
+26:   e.printStackTrace(); 
+27: }
+</pre>
+
+<p>
+Now the number of lines has grown from three to 25+. Which may be OK if this
+is a one-time operation. But if continuous use of a service is intended, it's easier to use a ServiceTracker:
+</p>
+
+<pre class="code">
+<div class="head"><a name="ex_tracker"></a>ServiceTracker example</div>
+01: <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/util/tracker/ServiceTracker.html">ServiceTracker</a> logTracker = new ServiceTracker(bc, <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/service/log/LogService.html">LogService</a>.class.getName(), null);
+02: logTracker.open();
+03: ((LogService)logTracker.getService()).doLog(...); 
+</pre>
+
+<p>
+The tracker guarantees to hold all currently available services, but may naturally return <tt>null</tt> if no services are available. This is often OK, since
+the code need to be prepared for RuntimeException anyway.
+</p>
+<p>
+The down-side of this approach is the continuous and annoying usage of casting to get the desired object. Wrapping this in a single utility method can ease 
+usage a bit:
+</p>
+
+<pre class="code">
+01: ServiceTracker logTracker;
+02:
+03: void init() {
+04:   logTracker = new ServiceTracker(bc, <a href="http://www.knopflerfish.org/releases/5.1.0/docs/javadoc/org/osgi/service/log/LogService.html">LogService</a>.class.getName(), null);
+05: }
+06:
+07: LogService getLog() {
+08:   return (LogService)logTracker.getService();
+09: }
+10: 
+11: void test() {
+12:   getLog().doLog(...);
+13: }
+</pre>
+
+<a name="white"></a>
+<h2 class="kf">The white-board model</h2>
+
+<div class="intro">
+"Don't call getService(), call registerService() instead!"
+</div>
+
+<p>
+Consider the HttpService case. All clients must constantly monitor the
+framework in some way to add its servlet(s) to the web server. 
+This requires at least the amount of code exemplified above, and even this
+doesn't completely guard against timing problems.
+</p>
+<p>
+Additionally, the Http service must provide special methods for 
+adding and removing servlets, and maintain an internal list of added servlets.
+This adds complexity both to the API and to the internal server code.
+</p>
+
+<p>
+This is a very common scenario -- some kind of callbacks/listeners are needed
+and the server needs to keep track of all available listeners.
+</p>
+<p>
+<i>The OSGi framework already provides exactly this functionality.</i>
+<p>
+
+<p>
+Thus, an alternative and better approach is to let the client <b>register its 
+servlets into the framework</b>, and let the http server use this list
+instead.
+</p>
+
+
+<pre class="code">
+<div class="head">Servlet client</div>
+01: class MyServlet extends HttpServlet {
+02:  ...
+03: }
+04: 
+05: HttpServlet servlet = new MyServlet();
+06: Hashtable   props   = new Hashtable();
+07: props.put("alias",  "/servlets/foo"); // desired http alias
+08: ServiceRegistration reg = 
+09:   bc.registerService(HttpServlet.class.getName(), servlet, props);
+</pre>
+
+<p>
+The client needn't do anything more. If the servlet should be removed, 
+it is simply unregistered from the framework.
+</p>
+<pre class="code">
+10: reg.unregister();
+</pre>
+<p>
+The new, improved http server would monitor the framework for all services 
+being HttpServlets, and use the "alias" property to set the alias.
+</p>
+
+<p>
+Below is a minimalistic wrapper for the existing http service: (a complete class doing this can be found in the <a href="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/bundles/http/httpconsole/src/org/knopflerfish/bundle/httpconsole/HttpWrapper.java">Http Console</a> example code.
+</p>
+
+<pre class="code">
+<div class="head">HttpService wrapper</div>
+  void open() {
+    httpTracker = new ServiceTracker(bc, HttpService.class.getName(), null);
+    httpTracker.open();
+
+    ServiceListener sl = new ServiceListener() {
+	public void serviceChanged(ServiceEvent ev) {
+	  ServiceReference sr = ev.getServiceReference();
+	  switch(ev.getType()) {
+	  case ServiceEvent.REGISTERED:
+	    {
+              registerServlet(sr);
+	    }
+	    break;
+	  case ServiceEvent.UNREGISTERING:
+	    {
+              unregisterServlet(sr);
+	    }
+	    break;
+	  }
+	}
+      };
+    
+    String filter = "(objectclass=" + HttpServlet.class.getName() + ")";
+    try {
+      bc.addServiceListener(sl, filter);
+      ServiceReference[] srl = bc.getServiceReferences(null, filter);
+      for(int i = 0; srl != null && i < srl.length; i++) {
+	sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED,
+					   srl[i]));
+      }
+    } catch (InvalidSyntaxException e) { 
+      e.printStackTrace(); 
+    }
+  }
+  
+  void registerServlet(ServiceReference sr) {
+    HttpServlet servlet = (HttpServlet)bc.getService(sr);
+    String alias        = (String)sr.getProperty("alias");
+    
+    Object[] httplist = httpTracker.getServices();
+    
+    for(int i = 0; httplist != null && i < httplist.length; i++) {
+      HttpService http = (HttpService)httplist[i];
+      try {
+	Hashtable props = new Hashtable();
+	http.registerServlet(alias, servlet, props, null);
+      } catch (Exception e) {
+	e.printStackTrace();
+      }
+    }
+  }
+  
+  void unregisterServlet(ServiceReference sr) {
+    String alias        = (String)sr.getProperty("alias");
+    
+    Object[] httplist = httpTracker.getServices();
+    
+    for(int i = 0; httplist != null && i < httplist.length; i++) {
+      HttpService http = (HttpService)httplist[i];
+      try {
+	http.unregister(alias);
+      } catch (Exception e) {
+	e.printStackTrace();
+      }
+      bc.ungetService(sr);
+    }
+  }
+
+</pre>
+
+<hr>
+<i>$Rev: 3482 $, $Author: cl $</i>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/osgi_with_security.html b/docs/osgi_with_security.html
new file mode 100644
index 0000000..662228d
--- /dev/null
+++ b/docs/osgi_with_security.html
@@ -0,0 +1,549 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Running OSGi with Security"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  OSGi with Security"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  OSGi with Security</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Running Knopflerfish OSGi with Security</h1>
+
+<h2 class="kf">Contents</h2>
+<ol>
+ <li><a href="#why">Why Security?</a>
+ <li><a href="#choose">Choose your Security</a>
+ <li><a href="#turn_it_on">Turn it On</a>
+ <li><a href="#easy">An Easy Set-up</a>
+ <li><a href="#console">Using the Console</a>
+ <li><a href="#cpa">Using Conditional Permission Admin</a>
+ <li><a href="#tested_bundle">The Tested Bundle</a>
+ <li><a href="#calling_bundle">A Calling Bundle</a>
+ <li><a href="#references">References</a>
+</ol>
+
+
+
+<a name="why"></a>
+<h2 class="kf">Why Security?</h2>
+
+<div class="intro">
+For most of us, the normal way is to run our OSGi frameworks with
+security off. When we have absolute control of the set of installed
+bundles, turning on security only gives us a set-up hassle and a
+performance hit. 
+</div>
+
+<p>
+But even if your framework is not exposed to bundles from unknown
+sources, you might have to run with security on in order to properly
+test bundles that need to do security right, in case someone else
+decides to run their framework with security on.
+</p>
+
+<p>
+The scenario for this tutorial is that we are developing a bundle and
+it is now time to test how it behaves in a framework with security on.
+</p>
+
+<a name="choose"></a>
+<h2 class="kf">Choose your Security</h2>
+
+<div class="intro">
+To complicate things, there is more than one way to set up security.
+</div>
+
+<p>
+The OSGi core specification contains both the Permission Admin and the
+Conditional Permission Admin that supersedes the former one. On top of
+that, it is also possible to specify a Java 2 policy file that grants
+permissions to code from specified code sources (based on location or
+signature).
+</p>
+
+<p>
+It is preferred to use Conditional Permission Admin (CPA) in favor of
+the old Permission Admin (as it is newer, but also more powerful).
+The Java 2 policy file is a lot less flexible than using CPA since it
+is not really possible to change permissions dynamically that way.
+This tutorial will use CPA, the policy file will only be used to grant
+the framework sufficient permission.
+</p>
+
+<p>
+A few final words about the policy file. It can be useful to know
+that the Knopflerfish framework will by default use a Java 2 policy
+file that is included in the framework jar file. But if the system
+property <code>java.security.policy</code> is set, the specified
+policy file will be used instead. The KF default policy file grants
+AllPermission to everyone, which is likely to be what you want; the
+framework needs AllPermission and since CPA will be used to control
+permissions for the bundles, you want the policy file to have -- no
+policy at all.
+</p>
+
+<a name="turn_it_on"></a>
+<h2 class="kf">Turn it On</h2>
+
+<div class="intro">
+Turning security on in Knopflerfish is easy, just a framework
+property that needs to be set.
+</div>
+
+<p>
+To set a security manager and thus turn on security, set the framework
+environment property <code>org.osgi.framework.security</code> to
+<code>osgi</code>. For Knopflerfish this will set the
+KFSecurityManager as security manager.
+</p>
+
+<p>
+With a security manager set (either using
+<code>-Djava.security.manager</code> or
+<code>-Forg.osgi.framework.security=osgi</code>) the KF system bundle
+will publish services PermissionAdmin and ConditionalPermissionAdmin.
+If you know that PermissionAdmin is not going to be used, you can turn
+it off by setting
+<code>-Forg.knopflerfish.framework.service.permissionadmin=false</code>.
+</p>
+
+<p>
+As you can see, turning security on is easy. Unfortunately, just
+turning it on will not do much since the default (as long as no
+permission has been set with CPA) is to grant everyone AllPermission.
+All we have accomplished so far is to slow thing down a little bit by
+installing a security manager. 
+</p>
+
+<a name="easy"></a>
+<h2 class="kf">An Easy Set-up</h2>
+
+<div class="intro">
+An easy set-up for permissions is to continue to grant AllPermission
+for bundles that you have control over/are not security testing.
+</div>
+
+<p>
+In this tutorial we are supposed to be testing a bundle under
+development. We do not really care about other bundles that might be
+installed and running, like the KF log, cm, http, event, etc bundles.
+To keep these working like before, we will grant them AllPermission by
+adding a policy that allow AllPermission under the condition that the
+bundle location matches the location where the KF bundles are stored
+in the local file system:
+<pre class="code">
+ALLOW {
+  [org.osgi.service.condpermadmin.BundleLocationCondition "file:jars/*"]
+  (java.security.AllPermission)
+}
+</pre>
+</p>
+
+<p>
+A bundle that we do not trust/are testing should be given less
+permission. A good starting point is to give them permission to import
+any package. If we give no permissions at all, the bundle will not
+even be allowed to resolve and will be difficult to test. An even more
+restricted starting point is to only allow import of the
+org.osgi.framework package.
+</p>
+
+<p>
+In this tutorial the bundle that we are testing is stored in the local
+file system at <code>/opt/kf/totest</code>, and to give all bundles
+located here permission to import any package we need:
+<pre class="code">
+ALLOW {
+  [org.osgi.service.condpermadmin.BundleLocationCondition "file:/opt/kf/totest/*"]
+  (org.osgi.framework.PackagePermission "*" "import")
+}
+</pre>
+</p>
+
+<p>
+A note to all Windows users out there: watch your backslashes. For
+example if the path to your bundles to test is <code>c:\kf\totest</code>,
+you might think that <code>file:c:\\kf\\totest\\*</code> will do fine as
+location argument. But in this argument the last backslash is not
+interpreted as a file separator, but as an escape character for the
+wildcard star, meaning that it is not going to be treated as a wildcard!
+<code>file:c:\\kf\\totest*</code> will work much better. This is
+documented in the javadoc for BundleLocationCondition but this little
+feature is easy to miss. 
+</p>
+
+<p>
+Both of the policies above use a bundle location condition. It is
+also possible to use a bundle signer condition to grant permission to
+bundles that are signed by a particular signature, or to use no
+condition at all if a permission should be granted to all bundles.  
+</p>
+
+<p>
+When we start to test our bundle, we will probably need to give it
+more permission. For example, if it is using the Log service, it will
+need a ServicePermisson for that.
+</p>
+
+<p>
+One way to add these policies is to use the setcondpermission command
+in the KF framework command group. Another way is to write a bundle
+that uses the ConditionalPermissinAdmin service to programmatically
+add conditional permissions.
+</p>
+
+<a name="console"></a>
+<h2 class="kf">Using the Console</h2>
+
+<div class="intro">
+Make sure that the bundle frameworkcommands is installed.  
+</div>
+
+<p>
+In the console, type
+<pre class="code">
+  > framework setcondpermission \
+  '[org.osgi.service.condpermadmin.BundleLocationCondition "file:jars/*"]' \
+  (java.security.AllPermission)
+</pre>
+and 
+<pre class="code">
+  > fr setcond '[org.osgi.service.condpermadmin.BundleLocationCondition \
+  "file:/opt/kf/totest/*"]' \
+  '(org.osgi.framework.PackagePermission "*" "import")'
+</pre>
+</p>
+<p>
+The policies will be part of the framework state, they will survive
+a restart as long as you do not use the <code>-init</code> flag to
+clear the state.
+</p>
+
+<a name="cpa"></a>
+<h2 class="kf">Using the Conditional Permission Admin</h2>
+
+<div class="intro">
+Let us write a bundle (the admin bundle) that will set up the polices for
+us using the CPA service that is published by the framework.
+</div>
+
+<p>
+The admin bundle will be our policy administration bundle so it will need
+permission to set polices using the CPA service. This means that
+it is in full control of the CPA and thereby able to grant itself or
+another bundle any kind of permission. It is easily realized that
+the admin bundle will have to be a trusted bundle. We could let it set the
+required CPA permissions for itself but to keep thing simple in this
+tutorial we will just treat it as trusted bundle and make sure it
+is loaded from the same location as the rest of the trusted KF bundles.
+</p>
+
+<p>
+Here is the <a href="examples/cpa/admin/src/org/knopflerfish/cpaexample/bundle/admin/AdminActivator.java">source code</a> and
+<a href="../osgi/example_jars/cpaexample_admin/cpaexample_admin-1.0.0.jar">jar f
+ile</a> for the admin bundle.
+We have a method, installPolicies that is called when the bundle starts:
+
+<pre class="code">
+01: void installPolicies(ConditionalPermissionAdmin cpa, String[] pInfos) {
+02:   ConditionalPermissionUpdate cpu = cpa.newConditionalPermissionUpdate();
+03:   List piList = cpu.getConditionalPermissionInfos();
+04:
+05:   for (int i = 0; i < pInfos.length; i++) {
+06:     String pInfo = pInfos[i];
+07:     ConditionalPermissionInfo cpi = cpa.newConditionalPermissionInfo(pInfo);
+08:     piList.add(cpi);
+09:   }
+10:    
+11:   cpu.commit();
+12: }
+</pre> 
+
+On line 02 and 03 we use the CPA to create a permission update object and
+get the list that our permissions will be added to. An instance of
+ConditionalPermissionInfo is created for each permission. The CPA service
+is used to create an instance from an encoded string. The string syntax is
+specified in the CPA chapter of the OSGi core specification. The policies
+that we defined in <a href="#easy">An Easy Set-up</a> would look like this:
+ 
+<pre class="code">
+  private static final String[] ENCODED_PINFO = {
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \
+    	\"file:jars/*\"] (java.security.AllPermission) } \"allToTrusted\"",
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \
+    	\"file:/opt/kf/totest/*\"] (org.osgi.framework.PackagePermission \
+    	\"*\" \"import\") } \"importToTested\""
+  };
+</pre> 
+</p>
+
+<p>
+Each ConditionalPermissionInfo instance is added to the update list and
+then the update is committed to the CPA service on line 11.
+</p>
+
+<p>
+Our version of the admin bundle uses hard coded policy strings to keep it
+simple. A more realistic version would probably read the policy data from
+a file or some other source.
+</p>
+
+<p>
+In a real world system, the functionality of the admin bundle could be
+integrated into a management agent. It would set the CPA policies and
+then it would take care of installing and starting the rest of the
+bundles that should be included in the system. We can follow this
+strategy without writing a complex management agent by using the xargs
+functionality in KF. Here is a <a href="examples/cpa/props.xargs">props.xargs</a> and
+an <a href="examples/cpa/init.xargs">init.xargs</a> that will:
+<ol>
+ <li>Install the admin bundle, schedule it for start.
+ <li>Launch the framework. This will start the admin bundle.
+ <li>Install and start the rest of the bundles, in this case a minimal
+     set of KF bundles that includes the log and some console bundles
+     for the TTY console, plus our bundle to test and a test bundle.
+ </ol>
+This way we make sure that no bundle can 'sneak in' and do something
+without being subjected to the CPA policies we want to be in effect.
+</p>
+
+<p>
+Debug output for permissions is enabled in props.xargs. A lot of output is
+produced but it can be useful to have it enabled when you are working with
+a security enabled framework.
+</p>
+<a name="tested_bundle"></a>
+<h2 class="kf">The Tested Bundle</h2>
+
+<div class="intro">
+This section is about the bundle that we are developing and that we want
+to verify is working correctly when running in a framework with security
+on.
+</div>
+
+<p>
+The to-test bundle is called user. It will publish a fake service
+(UserService) that we pretend is used to notify native components about
+the currently logged in OSGi user. Notification is done using the file
+system.
+</p>
+
+<p>
+The bundle will be using the framework and the LogService so we are going
+to need permission for that. We also need permission to read and write to
+the file system. Finally, we need permission to export a package and
+publish a service for other bundles to import and use. The policy for
+these permissions could look like:
+
+<pre class="code">
+ALLOW {
+  [org.osgi.service.condpermadmin.BundleLocationCondition "file:/opt/kf/totest/cpaexample_user*"]
+  (org.osgi.framework.PackagePermission "org.osgi.framework.*" "import")
+  (org.osgi.framework.PackagePermission "org.osgi.service.log" "import")
+  (org.osgi.framework.ServicePermission "org.osgi.service.log.LogService" "get")
+  (java.io.FilePermission "/tmp/osgiuser" "read,write,delete")
+  (org.osgi.framework.PackagePermission "com.acme.resource" "exportonly")
+  (org.osgi.framework.ServicePermission "com.acme.resource.ResourceService" "register")
+}
+</pre>
+While it is not mandatory, it is recommended that a bundle lists the
+permissions that it requires. The listed permissions are called local
+permissions. If defined, a bundle can never get more permissions than
+its local permissions. This feature makes it possible for a deployer
+to audit the permission requirements for a bundle. If the list of
+required permissions is acceptable, there is no need for the deployer
+to set up permissions in detail, the bundle can be given AllPermission.
+</p>
+
+<p>
+Local permissions for a bundle are defined in the resource file
+<code>OSGI_INF/permissions.perm</code>. Each permission is listed on
+its own line in this file, in the encoded form describes in
+<a href="#cpa"> Using Conditional Permission Admin</a>.
+</p>
+
+When we add local permissions to our user bundle, it is all right to
+use a policy in the admin bundle that grants the user bundle
+AllPermission. The hard coded policies in the admin bundle will now
+be:
+
+<pre class="code">
+  private static final String[] ENCODED_PINFO = {
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \
+    	\"file:jars/*\"] (java.security.AllPermission) } \"allToTrusted\"",
+    "allow { [org.osgi.service.condpermadmin.BundleLocationCondition \
+    	\"file:/opt/kf/totest/cpaexample_user*\"] \
+    	(java.security.AllPermission) } \"allToUser\""
+  };
+</pre> 
+
+<p>
+The source code for the user bundle is <a
+href="examples/cpa/user/src/org/knopflerfish/cpaexample/service/user/UserService.java">here</a>,
+the jar including local permission definition is <a
+href="../osgi/example_jars/cpaexample_user/cpaexample_user_all-1.0.0.jar">here</a>. The
+interesting parts for this security tutorial can be found in the login
+and logout methods of UserService. Here is the login method:
+
+<pre class="code">
+01: public void login(final String name) {
+02:   final File f = new File(fileName);
+03:
+04:   AccessController.doPrivileged(new PrivilegedAction() {
+05:     public Object run() {
+06:       if (f.exists()) {
+07:         throw new IllegalStateException("User already logged in");
+08:       }
+09:
+10:       try {
+11:         OutputStream os = new FileOutputStream(f);
+12:         os.write(name.getBytes("UTF-8"));
+13:         os.close();
+14:         log(LogService.LOG_INFO, "User " + name + " logged in");
+15:       } catch (IOException ioe) {
+16:         log(LogService.LOG_WARNING, "Problem logging user in: " + ioe);
+17:       }
+18:       return null;
+19:     }
+20:   });
+21: }
+</pre> 
+
+When doing method calls that will lead to permission checks (lines 06, 11,
+14 and 16) we need to mark us as privileged. When marked as privileged,
+the permission check will check that we have the required permissions but
+it will not continue to check that our caller (the bundle that is calling
+the login method in our service) also have the required permissions.
+Without the doPrivileged wrapper construction on line 04, it would be
+required for a bundle that is using our service to have the same
+permissions that we have.</p>
+
+<a name="calling_bundle"></a>
+<h2 class="kf">A Calling Bundle</h2>
+
+<div class="intro">
+To proper test our resource bundle we also need to write a bundle that
+uses our UserService.
+</div>
+
+<p>
+We have to make sure that permissions required by the user bundle is not
+also required by any user of its registered service. A user should only
+be required to have permission to import the package from the user bundle
+and to get the UserService.
+</p>
+
+This third bundle, called caller, is nothing special. All it does is
+getting the UserService and logging in a user in the start method and
+then logging out in the stop method. Here is the
+<a href="examples/cpa/caller/src/org/knopflerfish/cpaexample/bundle/caller/CallerActivator.java">source</a> and
+<a href="../osgi/example_jars/cpaexample_caller/cpaexample_caller-1.0.0.jar">jar file</a>.
+
+<a name="references"></a>
+<h2 class="kf">References</h2>
+
+<p>
+Chapter 9 of OSGi Service Platform Core Specification, Conditional
+Permission Admin Specification, contains a lot of information about
+the CPA service and security in OSGi in general. The specification
+can be downloaded from
+<a href=http://www.osgi.org/Specifications/HomePage>here</a>.
+</p>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/programming.html b/docs/programming.html
new file mode 100644
index 0000000..d6c333c
--- /dev/null
+++ b/docs/programming.html
@@ -0,0 +1,1531 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Information, tips and recommendations for developing OSGi bundles"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Develop OSGi bundles"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Develop OSGi bundles</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<div style="margin-left: 5px; margin-top: 5px; margin-bottom: 5px;">
+
+<h1 class="kf">Programming Knopflerfish</h1>
+
+<h2 class="kf">Contents</h2>
+<ol>
+  <li><a href="#eclipse_create">Using Eclipse to create bundles</a>
+  <li><a href="#ant_create">Using Ant to create bundles</a>
+  <li><a href="#maven_build">Using Maven to build bundles</a>
+  <li><a href="#activator">The BundleActivator</a>
+  <li><a href="osgi_service_tutorial.html">OSGi Service tutorial</a>
+  <li><a href="#dataaccess">Bundle data access</a>
+  <li><a href="#win32">Win32 tips</a>
+  <li><a href="#optimizing">Optimizing startup time, memory or disk usage</a>
+  <li><a href="#custom">Details on the included ant build system</a>
+  <li><a href="svn_info.html">Using the Subversion repository</a>
+  <!-- <li><a href="perf.html">Performance test</a> I don't think this is up-to-date ? [CL] -->
+</ol>
+
+<a name="eclipse_create"></a>
+<h2 class="kf">Using Eclipse to create bundles</h2>
+See the <a href="http://www.knopflerfish.org/eclipse_plugin.html">
+  Knopflerfish  Eclipse Plugin</a> documentation on the Knopferfish web site.  
+
+<a name="ant_create"></a>
+<h2 class="kf">Using Ant to create bundles</h2>
+<h3 class="kf">Prerequisites</h3>
+<ul>
+  <li><a href="http://en.wikipedia.org/wiki/Java_Development_Kit"><i>Java Development Kit (JDK)</i></a>
+  <li><i>Ant 1.8 or later</i>, available from <a href="http://ant.apache.org/">ant.apache.org</a>
+</ul>
+
+
+<h3 class="kf">Creating a new bundle</h3>
+New bundles can be created using the included ant build
+system. Naturally, you can create bundles manually, but this requires
+some knowledge about the OSGi manifest format.
+<p>
+<tt><i>knopflerfish</i></tt> refers to the unpacked knopflerfish directory, typically <tt>knopflerfish.org</tt>
+</p>
+
+<h3 class="kf">Using the included ant build system to create a new bundle</h3>
+<table>
+  <tr>
+    <td><b>1. Create a directory</b> for the new bundle</td>
+    <td>
+      <pre class="shell">
+> cd <i>knopflerfish</i>/osgi/bundles
+> mkdir mybundle
+      </pre>
+    </td>
+  </tr>
+
+  <tr>
+    <td><b>2. Copy</b> the ant bundle build <a
+      href="../ant/build_example.xml">template</a>
+    </td>
+    <td>
+      <pre class="shell">
+> cp <i>knopflerfish</i>/ant/build_example.xml build.xml
+      </pre>
+    </td>
+  </tr>
+
+  <tr>
+    <td><b>3. Change</b> the project name in the <tt>build.xml</tt> file
+
+      <p>Set the <tt><b>impl.pattern</b></tt> and
+      <tt><b>api.pattern</b></tt> properties to the packages that
+      contains implementation and API code.</p>
+
+      <p>Depending on where you have put your new bundle, you might
+      have to modify the path to <tt><b>bundlebuild.xml</b></tt> in
+      the <tt><import
+      file="${proj.dir}/../../../ant/bundlebuild.xml"/></tt> element
+      at the end of the build-file.</p>
+
+      <p> For details on bundle generation, see
+      <tt><i>knopflerfish</i>/ant/bundlebuild.xml</tt> </p>
+
+    </td>
+    <td>
+      <pre class="code">
+<project name="<b>mybundle</b>" default="all">
+...
+<property name  = "impl.pattern"
+          value = "example/mybundle/impl/**"/>
+..
+<property name  = "api.pattern"
+          value = "example/mybundle/*"/>
+
+      </pre>
+    </td>
+  </tr>
+
+  <tr>
+    <td><b>4. Create the java source code</b> in <tt>src</tt>
+      directory.
+    </td>
+    <td>
+      <pre class="shell">
+> mkdir -p src/example/mybundle/impl
+      </pre>
+
+      <b>Example BundleActivator:</b> src/examples/mybundle/impl/Activator.java
+      <pre class="code">
+package example.mybundle.impl;
+
+import org.osgi.framework.BundleActivator;
+
+public class Activator implements BundleActivator {
+  ...
+  public void start(BundleContext bc) {
+    ...
+  }
+  public void stop(BundleContext bc) {
+    ...
+  }
+      </pre>
+    </td>
+  </tr>
+
+  <tr>
+    <td><p><b>5. Compile</b> the bundle.</p>
+
+      <p>The ant build system will <b>automatically</b> find the
+      BundleActivator, imports and exports and generate a <b>bundle
+      manifest</b> file.</p>
+
+      <p>The resulting file will be generated to <font size="-1">
+      <tt><i>knopflerfish</i>/osgi/jars/mybundle/mybundle.jar</tt></font></p>
+
+      <p>Intermediate build results will be placed in <font size="-1">
+      <tt><i>knopflerfish</i>/osgi/out/mybundle</tt></font></p>
+
+    </td>
+    <td>
+      <pre class="shell">
+> ant
+      </pre>
+    </td>
+  </tr>
+
+  <tr>
+    <td><p><b>6. Install</b> the bundle.</p>
+
+      <p>This can be done either by using the <b>text console</b>,
+      dragging the bundle using the Swing <b>desktop</b> UI or by
+      modifying the framework startup file
+      <tt><b>init.xargs</b></tt></p>
+
+    </td>
+    <td>
+      <b>Using the console to install and start the bundle.
+      <pre class="shell">
+> install file:jars/mybundle/mybundle.jar
+> start mybundle.jar
+      </pre>
+      <b>Drag a bundle into the Desktop UI to install and start the bundle.<br>
+      <img src="images/desktop-clip.png">
+    </td>
+  </tr>
+
+  <tr>
+    <td><b>7. Using ant commands and telnet</b> console to install/start/stop/update bundles.
+  <p>
+   The ant build has support for communicating to a running framework and
+   install, start, stop, update and uninstall bundles.
+  </p>
+
+  <p>Given that the <tt>consoletelnet</tt> bundle is running, you can
+  simply use these built-in targets to handle the life cycle of the
+  bundle.</p>
+
+  <p>The properties <tt>console.host</tt>, <tt>console.port</tt>,
+  <tt>console.user</tt> and <tt>console.pwd</tt> controls the details
+  of the console connection.</p>
+
+  <p><b>Note</b>: requires netcomponents.jar in $ANT_HOME/lib. Needs
+  to be separately downloaded from <a
+  href="http://www.savarese.org/oro/downloads">http://www.savarese.org/oro/downloads</a></p>
+
+</td>
+
+<td>
+<pre class="shell">
+> ant install
+</pre>
+to install the compiled bundle. Similarly, type
+<pre class="shell">
+> ant start
+</pre>
+to start the bundle. Type
+<pre class="shell">
+> ant -projecthelp
+</pre>
+to see all available targets.
+   </td>
+
+  </tr>
+</table>
+
+<a class=top href="#top">top</a>
+
+<a name="maven_build"></a>
+<h2 class="kf">Using Maven to build bundles</h2>
+<h3 class="kf">Prerequisites</h3>
+<ul>
+  <li><a href="http://en.wikipedia.org/wiki/Java_Development_Kit"><i>Java Development Kit (JDK)</i></a>
+  <li><a href="http://maven.apache.org/"><i>Maven 2 or later.</i></a>
+</ul>
+
+
+<h3 class="kf">Knopflerfish Releases Repository</h3>
+
+To simplify building bundles that depends on OSGi or Knopflerfish APIs
+with Maven Knopflerfish offers a Maven 2 repository with all released
+artifacts (framework and bundles).
+
+This Maven2 repository id called "Knopflerfish Releases Repository"
+and can be found at<br/>
+
+<a
+href="http://www.knopflerfish.org/maven2/"><code>http://www.knopflerfish.org/maven2/</code></a><br/>
+
+It contains all artifacts from Knopflerfish release builds starting with
+2.3.3, 2.4, 3.0, 3.1, ...
+
+<p/>
+
+To make it easy to find artifacts that belongs to the same
+Knopflerfish release the repository contains an xml-document for each
+release that lists all artifacts with group id, artifact id and
+version. These documents are located in<br/>
+
+<a href="http://www.knopflerfish.org./maven2/org/knopflerfish/"><code>http://www.knopflerfish.org/maven2/org/knopflerfish/</code><br/></a>
+
+and are named like
+<code>KF-<i>VERSION</i>_dependencyManagement.xml</code>.<br/>
+
+E.g., the file with URL <a
+href="http://www.knopflerfish.org/maven2/org/knopflerfish/KF-3.1.0_dependencyManagement.xml"><code>http://www.knopflerfish.org/maven2/org/knopflerfish/KF-3.1.0_dependencyManagement.xml</code></a>
+will list all artifacts from the Knopflerfish 3.1 release.
+
+<p/>
+
+Each nightly build and release build (as of Knopflerfish 3.2) will also
+have a build specific Maven2 repository that contains exactly those
+artifacts that belongs to the build. The URL of these repositories are
+on the form<br/>
+
+<a
+href="http://www.knopflerfish.org/snapshots/current_trunk/maven2/"><code>http://www.knopflerfish.org/snapshots/current_trunk/maven2/</code></a></br>
+
+<a
+href="http://www.knopflerfish.org/releases/3.2.0/maven2/"><code>http://www.knopflerfish.org/releases/3.2.0/maven2/</code></a>
+
+
+<h3 class="kf">A sample POM file for building a simple bundle</h3>
+
+Here is a sample POM-file that may be used to build a simple
+bundle. Following Maven conventions the source code of the bundle
+should be in the subdirectory named <code>src/main/java</code>,
+resources should be in <code>src/main/resources</code>.
+
+<pre class="code">
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.knopflerfish.examples</groupId> 
+  <artifactId>example1</artifactId> 
+  <version>1.0</version> 
+  <packaging>bundle</packaging>
+
+  <name>Example 1</name>
+  <description>A bundle that exports a package.</description>
+
+  <properties>
+    <bundle.namespace>${pom.groupId}.${pom.artifactId}</bundle.namespace>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>${bundle.namespace}</Export-Package>
+            <Private-Package>!${bundle.namespace}</Private-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <repositories>
+    <b><repository>
+      <releases>
+        <enabled>true</enabled>
+        <updatePolicy>never</updatePolicy>
+        <checksumPolicy>fail</checksumPolicy>
+      </releases>
+      <snapshots>
+        <enabled>false</enabled>
+        <updatePolicy>never</updatePolicy>
+        <checksumPolicy>fail</checksumPolicy>
+      </snapshots>
+      <id>Knopflerfish</id>
+      <name>Knopflerfish Releases Repository</name>
+      <url><i>http://www.knopflerfish.org/maven2</i></url>
+      <layout>default</layout>
+    </repository></b>
+  </repositories>
+  <dependencyManagement>
+    <dependencies> 
+      <!-- KF 3.1.0 -->
+
+      <!--framework.jar-->
+      <b><dependency>
+        <groupId>org.knopflerfish</groupId>
+        <artifactId>framework</artifactId>
+        <version>5.1.6</version>
+      </dependency></b>
+
+      <!--log/log_api-3.0.5.jar-->
+      <dependency>
+        <groupId>org.knopflerfish</groupId>
+        <artifactId>log-API</artifactId>
+        <version>3.0.5</version>
+      </dependency>
+
+      <!--cm/cm_api-3.0.1.jar-->
+      <dependency>
+        <groupId>org.knopflerfish.bundle</groupId>
+        <artifactId>cm-API</artifactId>
+        <version>3.0.1</version>
+      </dependency>
+
+    </dependencies> 
+  </dependencyManagement>
+</project>
+</pre>
+
+Note: The <b><code><repository></code></b>-element is normally
+placed in the top-level parent POM or in the
+<code>settings</code>-file. In this example it has been added to the
+bundles POM-file to keep it all in one file. The same applies to the
+<b><code><dependencyManagement></code></b>-element.
+
+
+
+<h2 class="kf">Coding Style guides</h2>
+
+When writing OSGi bundles, all normal java guidelines apply, but some things
+might be worth noting. The list below is intended to give some hints on
+writing stable bundles, but feel free to use your own judgment.
+
+<p>
+
+<a name="activator"></a>
+<h2 class="kf">The BundleActivator</h2>
+
+The BundleActivator can be considered your application's main class. A bundle
+which is expected to start, register or use other service, <b>must</b>
+have a BundleActivator implementation and a reference to the BundleActivator's
+class name in its manifest file.
+
+<table border=0>
+
+<tr>
+<td class="tableheader" colspan=2>Naming the BundleActivator</td>
+</tr>
+
+  <tr>
+    <td valign=top>
+      Preferably name the <code>BundleActivator</code> class <b>Activator</b>.
+This makes it easy to find for other developers.
+    </td>
+    <td valign=top>
+      <pre class="code">
+public class <b>Activator</b> implements BundleActivator {
+  ...
+}
+</pre>
+
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Use package names</td>
+</tr>
+
+  <tr>
+    <td valign=top>
+<p>
+<b>Do</b> use normal package name conventions. One convention is to suffix
+the implementation parts of bundle with <tt>.impl</tt>
+</p>
+
+<p>
+However, the implementation parts can theoretically
+have any package name you want, since the framework keeps separate
+name spaces for separate bundles.
+</p>
+    </td>
+    <td valign=top>
+      <pre class="code">
+// This is the not exported implementation part of a bundle
+package com.acme.osgi.test.impl;
+
+// from the bundle's API part
+import com.acme.osgi.test.TestService;
+
+public class <b>Activator</b> implements BundleActivator {
+  TestService testService = ...
+  ...
+}
+</pre>
+
+    </td>
+  </tr>
+
+
+<tr>
+<td class="tableheader" colspan=2>Store the BundleContext</td>
+</tr>
+
+  <tr>
+    <td valign=top>
+      You can use a <b>static</b> <code>BundleContext</code> in the
+      <code>Activator</code> class.<br>
+      There is really no need for passing around <code>bc</code> by
+      parameter to all internal classes. The same trick should be used for
+      other <b>singular</b> common objects as the log service tracker.
+    </td>
+    <td valign=top>
+      <pre class="code">
+// Static bundle context
+public class <b>Activator</b> implements BundleActivator {
+
+   <b>static</b> BundleContext bc;
+
+   public void start(BundleContext bc) {
+     Activator.bc = bc;
+     ...
+   }
+
+   public void stop(BundleContext bc) {
+     Activator.bc = null; // allow for garbage collection
+     ...
+   }
+}
+</pre>
+
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Automatic cleanup of services</td>
+</tr>
+  <tr>
+    <td valign=top>There is <b>no need to unregister
+      services in the stop()</b> method. This
+      is done automatically by the framework.<br>
+      However, static variables <b>should</b> be nulled to allow
+      for garbage collection.
+    </td>
+    <td valign=top>
+      <pre class="code">
+public void stop(BundleContext bc) {
+  Activator.bc = null;
+}
+</pre>
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>No automatic cleanup of memory, threads, windows etc</td>
+</tr>
+  <tr>
+    <td valign=top>
+      <b>Do</b> deallocate
+      any other resources as threads or (gah!) Swing windows.
+      They are <b>not</b> stopped or closed automatically.
+    </td>
+    <td valign=top>
+      <pre class="code">
+// Cleanup up resources in stop method
+public void stop(BundleContext bc) {
+  Activator.bc = null;
+  if(window != null) {
+    window.setVisible(false);
+    window = null;
+  }
+}
+</pre>
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Beware of re-using service object</td>
+</tr>
+
+  <tr>
+    <td valign=top>Beware of re-using an object for
+      multiple service registrations.<br>
+      If you register a <b>public</b> class with one or
+      more <b>public</b> methods, these public methods
+      <b>will</b> become available to
+      all other bundles if they have <code>get</code>
+      permission on the service. Instead, make sure you
+      only implement public methods which are members of
+      the registered service's
+      interface.
+      <p>
+      A more compact method than multiple interfaces,
+      is to use anonymous inner classes.
+      </p>
+    </td>
+
+    <td valign=top>
+      <b>Common mistake of re-using the activator as service implementation:</b>
+      <pre class="code">
+import org.osgi.framework.BundleActivator;
+import org.osgi.service.cm.ManagesService;
+
+public class Activator
+       implements BundleActivator, <b>ManagedService</b> {
+
+  // implements BundleActivator
+  public void start(BundleContext bc) {
+
+    Hashtable props = new Hashtable();
+    props.put("service.pid", "myfantasticpid");
+
+    // We can register ourselves as a ManagedService,
+    // This is formally OK, but a service
+    // that can get this service (as a ManagedService),
+    // can also call start() and stop() using
+    // reflection trickery or casting. Which hardly
+    // was the intention of the bundle programmer.
+    bc.registerService(ManagedService.class.getName(),
+                       this, props);
+
+  }
+
+  // implements BundleActivator
+  public void stop(BundleContext bc) {
+    ...
+  }
+
+  // implements ManagedService
+  // should be avoided.
+  public void updated(Dictionary conf) {
+    ...
+  }
+}
+</pre>
+
+      <b>Better variant, using anonymous inner class:</b>
+      <pre class="code">
+public class Activator implements BundleActivator {
+
+  public void start(BundleContext bc) {
+
+    Hashtable props = new Hashtable();
+    props.put("service.pid", "myfantasticpid");
+
+    ManagedService mg = new <b>ManagedService</b>() {
+      public void updated(Dictionary conf) {
+        ...
+      }
+    };
+
+    // BundleActivator methods now hidden
+    // from outside access.
+    bc.registerService(ManagedService.class.getName(),
+                       mg, props);
+
+  }
+  ...
+}
+
+
+</pre>
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Spawning a startup thread</td>
+</tr>
+
+  <tr>
+    <td>
+      Do <b>not hang</b> in the Activator. Spawn a new thread if
+      the bundle is not completely event-driven.
+<p>
+      Nothing about threads is really specified or forbidden in the
+      OSGi spec, so there is currently no need for any special, external
+      thread service.
+</p>
+    </td>
+    <td>
+      <pre class="code">
+  public void start(BundleContext bc) {
+    new Thread("longTaskName") {
+      { start(); } // I like instance initializer blocks ;)
+      public void run() {
+         ...long operation
+      }
+    };
+  }
+</pre>
+
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Setting the context classloader</td>
+</tr>
+
+<tr>
+<td>
+<p>
+Many external libraries, like most JNDI lookup services requires a correctly
+set <b>thread context classloader</b>. If this is not set,
+ClassNotFoundException, or similar might be thrown even if you have
+included all necessary libs.
+</p>
+
+<p>
+To fix this, simple spawn a new thread in the activator and do the work
+from that thread. If you use the lib in any callback methods from the
+framework, as <tt>ServiceListener</tt> or <tt>BundleListener</tt> you should
+do a similar trick inside of these listeners.
+</p>
+
+<p>It is <b>not</b> recommended to set the context class loader
+persistently on the startup thread, since that thread might not be
+unique for your bundle.  Effects might vary depending on OSGi
+vendor. If you don't spawn a new thread, you <b>must</b> reset the
+context class loader before returning.</p>
+
+</td>
+<td>
+<pre class="code">
+public class Activator implements BundleActivator {
+   public void start(BundleContext bc) {
+
+     final ClassLoader classLoader =
+        getClass().getClassLoader();
+
+     Thread thread = new Thread() {
+       public void run() {
+         Thread.currentThread()
+           .setContextClassLoader(classLoader);
+         ...
+         // do any work that uses the context
+         // class loader, like :
+         context.lookup("QueueConnectionFactory");
+       }
+     };
+
+     thread.start();
+   }
+</pre>
+Thanks to Rob Evans for this example.
+
+</td>
+</tr>
+
+
+</table>
+
+<a class=top href="#top">top</a>
+
+<a name="services"></a>
+<h2 class="kf">Using services</h2>
+<table>
+
+  <tr>
+    <td class="tableheader" colspan=2>
+      This is short introduction to service usage, to learn more about
+      it read the 
+      <a href="osgi_service_tutorial.html">service tutorial</a>.
+      <p/>
+      <b>Track all services!</b>
+    </td>
+  </tr>
+
+  <tr>
+    <td valign=top>Be prepared that services might not exists, or suddenly
+      disappear.<p>
+      Use the <tt>ServiceTracker</tt> if you are interested in using a single
+      service.
+    <td valign=top>
+      <pre class="code">
+  ServiceTracker logTracker =
+    new ServiceTracker(bc,
+                       LogService.class.getName(),
+                       null);
+  logTracker.open();
+
+  // this might throw a NullPointerException
+  // if the log is not available
+  (LogService)logTracker
+    .getService().log(LogService.LOG_INFO,
+                      "Hello log");
+
+</pre>
+    </td>
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Track service using <tt>ServiceListener</tt></td>
+</tr>
+
+  <tr>
+    <td valign=top>
+      If you really need to act on multiple service appearing and
+      disappearing, a <tt>ServiceListener</tt> is preferred.
+      <p>
+    </td>
+    <td valign=top>
+      <b>Act on every http service that appears and disappears.</b>
+      <pre class="code">
+  ...
+  ServiceListener listener = new ServiceListener() {
+    public void serviceChanged(ServiceEvent ev) {
+     ServiceReference sr = ev.getServiceReference();
+
+      switch(ev.getType()) {
+        case ServiceEvent.REGISTERED:
+          ...
+          break;
+        case ServiceEvent.UNREGISTERING:
+          ...
+         break;
+      }
+    }
+  };
+
+  String filter =
+   "(objectclass=" + HttpService.class.getName() + ")";
+
+  try {
+    bc.addServiceListener(listener, filter);
+
+    // get all already registered services.
+    ServiceReference[] srl =
+      bc.getServiceReferences(null, filter);
+
+    for(int i = 0; srl != null && i < srl.length; i++) {
+      listener.serviceChanged(
+          new ServiceEvent(ServiceEvent.REGISTERED,
+          srl[i]));
+    }
+  } catch (Exception e) {
+     log.error("Failed to set up listener for http",
+               e);
+  }
+</pre>
+    </td>
+  </tr>
+</table>
+
+
+<a class=top href="#top">top</a>
+
+<a name="dataaccess"></a>
+<h2 class="kf">Bundle data access</h2>
+
+<table>
+
+<tr>
+<td class="tableheader" colspan=2>Access bundle data as streams</td>
+</tr>
+
+  <tr>
+    <td valign=top>You can access bundle data using
+      the <b>getResourceAsStream</b> method
+    </td>
+    <td valign=top>
+      <pre class="code">
+// Get the bundle's manifest file using the
+// bundle class loader
+InputStream in =
+  getClass()
+   .getResourceAsStream("/META-INF/MANIFEST.MF");
+..
+</pre>
+    </td>
+
+  </tr>
+
+<tr>
+<td class="tableheader" colspan=2>Access bundle data as URLs</td>
+</tr>
+
+  <tr>
+    <td valign=top>You can access bundle data using the <b>bundle: URL</b>
+      syntax.
+    </td>
+    <td valign=top>
+      <pre class="code">
+ // Get the bundle's raw manifest file using an URL
+ // Syntax: (jar number represents internal jars,
+ // where 0 is the top level jar)
+ //  "bundle://<bundle id>:<jar number><path>"
+ String s =
+   "bundle://" + bc.getBundle().getBundleId() + ":0" +
+   "/META-INF/MANIFEST.MF";
+
+ URL url = new URL(s);
+
+ InputStream in = url.openStream();
+
+ ..
+</pre>
+    </td>
+  </tr>
+
+
+<!--- #refreshing -->
+<tr>
+<td class="tableheader" colspan=2>
+<a name="refreshing"></a>
+Bundles must be refreshed after an update</td>
+</tr>
+  <tr>
+    <td valign=top>
+
+    Bundle update does <b>not</b> automatically release all wired
+    capabilities (exported packages).
+
+    <p>
+    This means that a bundle that has a wire from a provided
+    capability (e.g., exported package) to another bundle requiring
+    that capability needs to be explicitly <b>refreshed</b> before
+    that capability (e.g., classes in the exported package) is
+    released.
+    </p>
+
+    <p>
+    If you happen to have exported the package that your
+    BundleActivator resides in, this could mean that the "old" class
+    will be used and not the newly installed one.
+    </p>
+
+    </td>
+    <td valign=top>
+
+    Both the console and desktop provides means of calling refresh:
+
+    <p>
+    Console:
+<pre class="shell">
+ > /framework refresh
+</pre>
+    </p>
+
+    <p>
+    Desktop: <br>
+    Bundles -> Refresh bundle packages<br>
+    or CTRL + R<br>
+    or press the refresh link in the wiring displayer on a capability
+    that is pending removal on refresh.
+    </p>
+
+    <p>
+    Both of these methods uses the
+    <tt>org.osgi.wiring.FrameworkWiring</tt> API to refresh bundles:
+<pre class="code">
+  // refresh all bundles
+  frameworkWiring.refreshBundles(null)
+</pre>
+
+    </td>
+  </tr>
+<!--- /#refreshing -->
+
+</table>
+
+<a class=top href="#top">top</a>
+
+<a name="win32"></a>
+<h2 class="kf">Win32 tips</h2>
+
+<table>
+<tr>
+<td class="tableheader" colspan=2>Using the Java Media framework</td>
+</tr>
+
+  <tr>
+    <td valign=top>The <b>Java Media Framework</b> 2.1 is tricky
+      to install. If you fail to install properly it may still
+      work, but start very slowly.
+    </td>
+    <td valign=top>
+      <ol>
+  <li>Install all the .dlls and jars in the
+  <b>JRE runtime</b> <code>ext/</code> directory. <br>
+  Common installation directory:
+  <pre class="shell">
+C:\Program Files\JavaSoft\JRE\1.3\lib\ext\
+    </pre>
+  <li>This is not enough, copy the file <code>jmutils.dll</code> to the
+  JRE runtime <code>bin/</code> directory. <br>
+  Common installation directory:
+  <pre class="shell">
+C:\Program Files\JavaSoft\JRE\1.3\bin\
+    </pre>
+
+      </ol>
+    </td>
+  </tr>
+
+</table>
+
+<a name="custom"></a>
+<h2>Details on the included ant build system</h2>
+
+<b>Properties and elements used in <tt>bundlebuild_include.xml</tt></b>
+<table>
+
+ <tr>
+   <td class="tableheader"><b>Name</b>
+   <td class="tableheader"><b>Description</b>
+ </tr>
+
+ <tr>
+  <td class="tableheader" colspan="2">Files and directories</td>
+ </tr>
+
+ <tr>
+  <td>topdir</td>
+  <td>Must be set to the top directory of build. This should be the same
+     directory where framework.jar is located.
+  </td>
+ </tr>
+
+ <tr>
+  <td>ant.dir</td>
+  <td>Directory containing ant build files.
+      <br>Default is "${topdir}/../ant"
+  </td>
+ </tr>
+
+ <tr>
+  <td>src.dir</td>
+  <td>Directory where all bundle source is located.
+      <br>Default is "src"
+  </td>
+ </tr>
+
+ <tr>
+  <td>resources.dir</td>
+  <td>Directory where all bundle data is located. This directory will
+      be copied into the root of the bundle jar file, without the directory
+      name itself.
+      <br>Default is "resources"
+  </td>
+ </tr>
+
+<tr>
+  <td>bundle.build.api</td>
+  <td>If "true", build ${jar.api} bundle jar.<br>Default is "true"</td>
+ </tr>
+
+ <tr>
+  <td>bundle.build.lib</td>
+  <td>If "true", build ${jar.lib} bundle jar.<br>Default is "false"</td>
+ </tr>
+
+ <tr>
+  <td>bundle.build.impl</td>
+  <td>If "true", build ${jar.impl} bundle jar.<br>Default is "true"</td>
+ </tr>
+
+ <tr>
+  <td>bundle.build.all</td>
+  <td>If "true", build ${jar.all} bundle jar.<br>Default is "true"</td>
+ </tr>
+
+ <tr>
+  <td>jar.all</td>
+  <td>Location and name of jar file containing both API and implementation code<br/>
+Default is <tt>${jardir}/${ant.project.name}${all.suffix}.jar</tt>
+</td>
+ </tr>
+
+ <tr>
+  <td>api.all</td>
+  <td>Location of jar file containing API code</td>
+ </tr>
+
+ <tr>
+  <td>impl.all</td>
+  <td>Location of jar file containing implementation code</td>
+ </tr>
+
+ <tr>
+  <td>all.suffix</td>
+  <td>Suffix string for the ${all.jar} output file<br/>
+Default is <tt>_all-${bundle.version}</tt>
+</td>
+ </tr>
+
+ <tr>
+  <td class="tableheader" colspan="2">Bundle manifest attributes</td>
+ </tr>
+
+
+ <tr>
+  <td>bundle.name</td>
+  <td>Name of bundle. Will be stored in manifest as "Bundle-Name".
+      <br>Default value is ${ant.project.name}
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.version</td>
+  <td>Version of bundle. Will be stored in manifest as "Bundle-Version".
+      <br>Default value is "current"
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.vendor</td>
+  <td>Vendor of bundle. Will be stored in manifest as "Bundle-Vendor".
+  <br>Default value is "Knopflerfish"
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.apivendor</td>
+  <td>Vendor of a bundle's API. Will be stored in manifest as "Bundle-APIVendor".
+  <br>Default value is "[bundle.emptystring]"
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.description</td>
+  <td>Description of bundle. Will be stored in manifest as "Bundle-Description"
+      <br>Default value is empty
+ </td>
+ </tr>
+
+
+ <tr>
+  <td>bundle.icon</td>
+  <td>Optional URL to bundle icon, used by the desktop. Will be stored
+      in manifest as "Application-Icon". <br>Default value is empty</td>
+ </tr>
+
+ <tr>
+  <td>bundle.classpath</td>
+  <td>Bundle classpath. Will be stored in manifest as "Bundle-Classpath".
+      <br>Default value is "."</td>
+ </tr>
+
+ <tr>
+  <td>bundle.docurl</td>
+  <td>Bundle doc URL. Will be stored in manifest as "Bundle-DocURL".
+      <br>Default value is "http://www.knopflerfish.org"
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.contactaddress</td>
+  <td>Bundle contact address. Will be stored in manifest as "Bundle-ContactAddress".
+  <br>Default value is "http://www.knopflerfish.org"
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.activator</td>
+  <td>Class name of bundle activator. Will be stored in manifest as "Bundle-Activator".
+  <br>Default value is automatically derived from bundle classes in impl code.
+  </td>
+ </tr>
+
+ <tr>
+  <td>import.package</td>
+  <td>Comma-separated list of packages. Will be stored in manifest as "Import-Package".
+  <br>Default value is automatically derived from bundle classes in impl code
+  </td>
+ </tr>
+
+ <tr>
+  <td>export.package</td>
+  <td>Comma-separated list of packages. Will be stored in manifest as "Export-Package".
+  <br>Default value is automatically derived from bundle classes in API code
+  </td>
+ </tr>
+
+ <tr>
+  <td>dynamicimport.package</td>
+  <td>Comma-separated list of dynamic import packages. Will be stored in
+  manifest as "DynamicImport-Package".
+  <br>Default value is empty
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.nativecode</td>
+  <td>Comma-separated list of native code specifications. Will be stored in
+  manifest as "Bundle-NativeCode".
+  <br>Default value is empty
+  </td>
+ </tr>
+
+ <tr>
+  <td>import.service</td>
+  <td>Optional comma-separated list of service class names. Will be stored in manifest as "Import-Service".
+  </td>
+ </tr>
+
+ <tr>
+  <td>export.service</td>
+  <td>Optional comma-separated list of service class names. Will be stored in manifest as "Import-Package".
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.uuid</td>
+  <td>Optional "Universally Unique ID" for a bundle. Will be stored in manifest as "Bundle-UUID".<br/>
+Default is <tt>org.knopflerfish:${bundle.name}:${bundle.version}</tt>
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.symbolicname</td>
+  <td>Optional ID used by the Eclipse OSGi framework. Will be stored in manifest as "Bundle-SymbolicName".<br/>
+Default is <tt>${bundle.uuid}</tt>
+  </td>
+
+ <tr>
+  <td colspan=2><b>Note</b>: If any of the manifest attributes above are set to the
+   special value <tt>"[bundle.emptystring]"</tt>, that attribute will not
+be present at all in the manifest, not even as a zero-length string.
+ </td>
+ </tr>
+
+ </tr>
+
+
+ <tr>
+  <td class="tableheader" colspan="2">Flow control</td>
+ </tr>
+
+ <tr>
+  <td>do.bundle.custom.pre</td>
+  <td>If set, run the target <tt>bundle.custom.pre</tt>. Default is unset</td>
+ </tr>
+ <tr>
+  <td>do.bundle.custom.post</td>
+  <td>If set, run the target <tt>bundle.custom.post</tt>. Default is unset</td>
+ </tr>
+
+ <tr>
+  <td class="tableheader" colspan="2">Build control</td>
+ </tr>
+
+ <tr>
+  <td>api.pattern</td>
+  <td>
+      Path pattern string that must match all Java packages that are
+      part of the bundle's API (i.e., that shall be exported). Note
+      that this pattern must not only match all packages in the source
+      tree, but also all packages that shall be exported from the
+      bundle class path (i.e., in nested jars).
+
+      <p/>
+
+      The "API"-variant of the bundle will only contain classes that
+      is the result of compiling those java-source files that matches
+      this pattern from the source tree.
+  </td>
+ </tr>
+
+ <tr>
+  <td>impl.pattern</td>
+  <td>
+      Path pattern string that must match all private (implementation
+      specific) Java packages in the source tree that shall be
+      included in the bundle but not exported.
+
+      <p/>
+
+      The "IMPL"-variant of the bundle will contain classes that
+      is the result of compiling those java-source files that matches
+      any of the impl.pattern and impl-api.pattern.
+  </td>
+ </tr>
+
+ <tr>
+  <td>impl-api.pattern</td>
+  <td>
+      Path pattern string that must match all Java packages in the
+      source tree and on the bundle class path that shall be included
+      in and exported from the "IMPL" variant of the the bundle but
+      not in the "API"-variant of the bundle. Typically used when the
+      implementation part of the bundle needs to export implementation
+      specific Java packages that is not part of the bundles API.
+  </td>
+ </tr>
+
+ <tr>
+  <td>all.pattern</td>
+  <td>
+
+      Path pattern string that must match additional private
+      (implementation specific) Java packages in the source tree that
+      shall be included in the all-variant of the bundle but not
+      exported.
+
+      <p/>
+
+      The "ALL"-variant of the bundle will contain classes that
+      matches any of the api.pattern, impl.pattern, impl-api.pattern,
+      all.pattern and all-api.pattern.
+
+  </td>
+ </tr>
+
+ <tr>
+  <td>all-api.pattern</td>
+  <td>
+
+      Path pattern string that must match additional Java packages
+      that shall be included in and exported from the "ALL" variant of
+      the the bundle but not in the "API"-variant or "IMPL"-variant of
+      the bundle. Typically used to make a self contained
+      "ALL"-variant of the bundle that exports all Java-packages that
+      the "IMPL"-variant needs.
+
+      <p/>
+
+      The "ALL"-variant of the bundle will export classes in packages
+      that are matched by one of api.pattern, impl-api.pattern and
+      all-api.pattern. It will contain all classes that are matched by
+      any of api.pattern, impl-api.pattern, impl-pattern,
+      all-api.pattern and all.pattern.
+
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundle.compile.EE</td>
+  <td>
+    The bundle Execution Environment to use when compiling.  The value
+    is the id of a path that will be used as boot class path during
+    the compilation.
+
+    <p/>
+
+    Predefined values: <tt>ee.minimum</tt>, <tt>ee.foundation</tt>.
+    <br>Default is unset.
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundleinfo.failOnExports</td>
+  <td>If set, verify that the given <code>Export-Package</code>
+      manifest header is valid. If not valid the build will fail.
+      <br>Default is <code>true</code>.
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundleinfo.failOnImports</td>
+  <td>If set, verify that the given <code>Import-Package</code>
+      manifest header is valid. If not valid the build will fail.
+      <br>Default is <code>true</code>.
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundleinfo.failOnActivator</td>
+  <td>If set, verify that the given <code>Bundle-Activator</code>
+      manifest header is valid. E.g., that the class is included in
+      the bundle archive and that it implements
+      <code>org.osgi.framework.BundleActivator</code>. If not valid the
+      build will fail. 
+      <br>Default is <code>true</code>.
+  </td>
+ </tr>
+
+ <tr>
+  <td>bundleinfo.failOnClassPath</td>
+  <td>If set, verify that the given <code>Bundle-Classpath</code>
+      manifest header is valid. E.g., that all files, directories in
+      it existis inside the bundle archive. If not valid the build
+      will fail.
+      <br>Default is <code>true</code>.
+  </td>
+ </tr>
+
+ <tr>
+  <td class="tableheader" colspan="2">Other elements</td>
+ </tr>
+
+ <tr>
+  <td>Path element <tt>bundle.compile.path</tt></td>
+  <td><p>This path is used to make other bundles and JAR-files that the
+  bundle depends on availble to the compiler during the compilation of
+  the bundle.</p>
+
+  <p>Example - make the log API available during compilation:</p>
+<pre class="code">
+ <path id = "bundle.compile.path">
+   <pathelement location="log_api-N.N.N.jar"/>
+ </path>
+</pre>
+
+  <p>The <tt>N.N.N</tt> notation in the file name tells the build
+  system to look for and use the highest version available in the
+  directory tree starting at <tt>${jars.dir}</tt>. It is possible to
+  ask for the highest version available with a fixed major revision by
+  writing a pathelement like <tt>log_api-2.N.N.jar</tt>.</p>
+
+</td>
+ </tr>
+
+
+ <tr>
+  <td></td>
+  <td></td>
+ </tr>
+ <tr>
+  <td></td>
+  <td></td>
+ </tr>
+
+</table>
+
+<h2 class="kf">Special pre and post target</h2>
+
+If you need special handling of the bundle build process, you can
+add the special targets <tt>bundle.custom.pre</tt> or
+<tt>bundle.custom.post</tt>. These will be run just before and just after
+the standard bundle build.
+
+<br>
+<b>Example of pre target - copying a file</b>
+
+<pre class="shell">
+<!-- set do.bundle.custom.pre to anything to trigger pre target -->
+<property name="do.bundle.custom.pre" value=""/>
+<target name="bundle.custom.pre">
+   <copy file  = "myfile"  todir = "resources"/>
+  </target>
+
+</pre>
+
+<b>Example of post target - a custom manifest attribute</b>
+
+<pre class="code">
+<!-- set do.bundle.custom.post to anything to trigger post target -->
+<property name="do.bundle.custom.post" value=""/>
+
+<target name="bundle.custom.post">
+  <jar jarfile  = "${impl.jar}"  update   = "true">
+   <manifest>
+    <attribute name = "myattribyte"       value = "myvalue"/>
+   </manifest>
+  </jar>
+</target>
+</pre>
+
+<a name="optimizing"></a>
+<h2 class="kf">Optimizing startup time, memory or disk usage</h2>
+
+<p>
+The Knopflerfish framework can be started in either disk-optimizing or
+memory-optimizing modes. This is useful for systems with lower memory or
+small or slow disks. It also affects the startup time for the framework.
+</p>
+
+<!-- 
+<p>
+See <a href="perf.html">Knopflerfish performance test</a> for actual performance data
+with different methods.
+</p>
+-->
+
+The following apply:
+
+<ol>
+ <li>If you need quick startup, remember that initial startup is always
+     much slower than a restart, so
+     a avoid deleting the <tt>fwdir</tt> bundle storage directory, if
+     possible.
+
+ <li> Jar unpacking to disk costs time and disk space. When you
+    have a slow write-disk (as flash mem) this is really
+    notable.
+
+<p>
+    As a solution, memory can be used as bundle storage
+    instead of disk. Just start with
+</p>
+<pre class="shell">
+     -Dorg.knopflerfish.framework.bundlestorage=memory
+</pre>
+<p>
+    This has the side-effect of not making the bundles persistent,
+    so the 1) case does no longer apply. Also, this means that
+    the one part of OSGi compliance is lost.
+</p>
+
+ <li> Jar-files inside of bundles tend to take longer time than
+    unpacked class files. This is related to 2) since they must
+    be extracted from the bundle to be accessed.
+<p>
+    A work-around is to manually unpack a lib jar file and add it
+    to a bundle (instead of referencing the .jar from <tt>Bundle-Classpath</tt>)
+</p>
+</ol>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/release_notes.html b/docs/release_notes.html
new file mode 100644
index 0000000..10bd597
--- /dev/null
+++ b/docs/release_notes.html
@@ -0,0 +1,367 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Release notes for this release of Knopflerfish OSGi, version 5.1.0 - "/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Release Notes"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Release Notes</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<!-- The first line in this file is used by the desktop to check -->
+<!-- for new releases, i.e., do not change its format.           -->
+<!-- It must contain the word "Knopflerfish" followed by a space -->
+<!-- and then the version followed by another space.             -->
+
+<h1 class="kf">Release Notes Knopflerfish 5.1.0 (OSGi R5)</h1>
+<p>
+
+  Maintenance release of Knopflerfish 5 available from
+  http://www.knopflerfish.org/releases/5.1.0. Released 2014-06-13.
+
+</p>
+<p>
+
+  Knopflerfish 5 is an implementation of the "OSGi Service Platform
+  Release 5". It contains all services specified in the "Core
+  Specification" and most of the non Enterprise Edition related
+  services specified in the "Compendium Specification".
+
+</p>
+
+<p>
+
+  The Release Notes include all new features & changes for
+  Knopflerfish 5.1.0 compared to the release of Knopflerfish
+  5.0.0.
+
+</p>
+
+<h2 class="filled">Knopflerfish Framework - OSGi Core Specification</h2>
+<div class="release_notes">
+
+  <div class="note_group">
+    <div class="note_name">Framework 7.1.2</div>
+    <div class="note_item">
+    Fixed framework restart problem introduced in 7.1.0.
+    </div>
+    <div class="note_item">
+    Relaxed "org.knopflerfish.framework.validator.date" parsing, so that
+    it tries short US locale pattern if default locale parsing fails.
+    </div>
+
+    <div class="note_name">Framework 7.1.1</div>
+    <div class="note_item">
+    Fixed exception when doing BundleWiring.listResources on root directory.
+    </div>
+
+    <div class="note_name">Framework 7.1.0</div>
+    <div class="note_item">
+    Added new URL protocol "fwresource" to access resources from the framework
+    classloader.
+    </div>
+    <div class="note_item">
+    The start class org.knopflerfish.framework.Main now tries to load xargs as a
+    framework resource if the file is not found. This means that we together
+    with the new fwresource protocol can create a single jar that contains the
+    framework, all jars and xargs files that needs to start a complete application.
+    </div>
+    <div class="note_item">
+    Added property "org.knopflerfish.framework.readonly", that puts framework
+    in a read only mode. This means that framework will not write any files
+    in "fwdir". This means that if we are running with the default "file"
+    bundle storage then new bundles must be installed as a referenced file URL.
+    This also implies that no data storage will be available to bundles.
+    </div>
+
+    <div class="note_name">Framework 7.0.2</div>
+    <div class="note_item">
+    Fixed bug that caused IndexOutOfBoundsException when updating large
+    collections of ConditionalPermissionInfos using ConditionalPermissionUpdate.
+    </div>
+    <div class="note_item">
+    Added property "org.knopflerfish.framework.validator.date" to framework
+    for testing certification validation with different dates.
+    </div>
+  </div>
+
+</div>
+
+
+<h2 class="filled">OSGi Compendium Specification</h2>
+<div class="release_notes">
+
+  <div class="note_group">
+    <div class="note_name">UserAdmin 4.1.1</div>
+    <div class="note_item">
+    Now contains and imports/exports org.knopflerfish.service.log
+    in order to be self-contained.
+    </div>
+    <div class="note_item">
+      Changed to use the OSGi defined Bundle-Icon instead of
+      Application-Icon.
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">KF-XML-Metatype 5.0.1</div>
+    <div class="note_item">
+    Fixed bug in handling of designate-element that could cause
+    configurations to be created, deleted or overwritten
+    unintentionally.
+    Refactored handling of standardized OSGi metatype xml and
+    legacy proprietary meta type xml into separate classes.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">CM 5.0.1</div>
+    <div class="note_item">
+    Improved the persistent storage of CM data,
+    made it more robust and fault resilient. 
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">HTTP-Server 4.0.5</div>
+    <div class="note_item">
+    Fixed another bug in the handling of chunked transfer encoding in the
+    Request implementation. The last chunk (with size 0) is not followed
+    by any chunk-data and thus there is no CRLF to consume.
+    </div>
+
+    <div class="note_name">HTTP-Server 4.0.4</div>
+    <div class="note_item">
+    Fixed another bug in the handling of chunked transfer encoding in the
+    Request implementation. A chunk contianing a charter followed by a
+    new line char was not correctly un-chunked.
+    </div>
+
+    <div class="note_name">HTTP-Server 4.0.3</div>
+    <div class="note_item">
+    Fixed a bug in the handling of chunked transfer encoding in the
+    Request implementation. An extra CR-LF was incorrectly added to
+    the end of the decoded data, causing problems when transfering
+    binary data like a zip-file.
+    </div>
+  </div>  
+  
+  <div class="note_group">
+    <div class="note_name">Prefs 4.0.2</div>
+    <div class="note_item">
+      Added bundle icon.
+    </div>
+  </div>
+
+  <div class="note_group">
+    <div class="note_name">Repository XML 1.0.2</div>
+    <div class="note_item">
+    Fixed a bug in RequirementImpl and did some clean up.
+    </div>
+
+    <div class="note_name">Repository XML 1.0.1</div>
+    <div class="note_item">
+    Fixed a bug in CapabilityImpl.
+    </div>
+  </div>
+
+  <div class="note_group">
+    <div class="note_name">SCR(component) 5.0.3</div>
+    <div class="note_item">
+    Fixed missed factory component check in previous version. This miss caused
+    following error:<p/>
+    java.lang.IllegalStateException: Internal error! Factory component only created with newInstance
+    </div>
+
+    <div class="note_name">SCR(component) 5.0.2</div>
+    <div class="note_item">
+    Fixed a bug that caused factory components to be falsely created or
+    missed being created when we use target filters.
+    </div>
+
+    <div class="note_name">SCR(component) 5.0.1</div>
+    <div class="note_item">
+    Fixed a bug that caused problems when adding a CM configuration with
+    a target filter to an unsatisfied component.
+    </div>
+  </div>
+  
+</div>
+
+<h2 class="filled">Knopflerfish Services</h2>
+<div class="release_notes">
+
+   <div class="note_group">
+    <div class="note_name">CM Desktop 5.0.2</div>
+    <div class="note_item">
+    Add requirement for the Meta Type Service.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">KF Resource Analyzer Extensions 1.0.1</div>
+    <div class="note_item">
+    Added proper handling of Bundle-License according to osgi.identity
+    namepsace.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">Repository Commands 1.1.1</div>
+    <div class="note_item">
+    Bug fixes and some refactorings.
+    </div>
+
+    <div class="note_name">Repository Commands 1.1.0</div>
+    <div class="note_item">
+    Added [-r] flag to install command that tries to automatically find and
+    install dependencies along with the specified bundle by using new
+    methods in Repository Manager.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">Repository Desktop 1.1.1</div>
+    <div class="note_item">
+    The dialogue now gives information about exactly what will be installed when asking if a
+    Resolver should be used.
+    </div>
+
+    <div class="note_name">Repository Desktop 1.1.0</div>
+    <div class="note_item">
+    Added support for new methods in Repository Manager to use a Resolver
+    service when available.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">Repository Manager 1.2.0</div>
+    <div class="note_item">
+    Added install and resolverAvailable methods to RepositoryManager interface.
+    Embedded Resolver and Repository APIs.
+    </div>
+
+    <div class="note_name">Repository Manager 1.1.0</div>
+    <div class="note_item">
+    Added support for Resolver services and added RepositoryManager.findResolution method.
+    </div>
+  </div>
+
+  <div class="note_group">
+    <div class="note_name">KF-XML-Metatype 5.0.2</div>
+    <div class="note_item">
+    Only build an "all" variant. This makes it possible to correctly install
+    CM-Desktop using the Repository Desktop with the Felix resolver.
+    </div>
+  </div>
+
+</div>
+
+
+<h2 class="filled">Misc, start scripts, build system etc </h2>
+<div class="release_notes">
+
+   <div class="note_group">
+    <div class="note_name">init.xargs</div>
+    <div class="note_item">Added commented out line to install Resolver
+    reference implementation.
+    </div>
+  </div>
+
+</div>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/running.html b/docs/running.html
new file mode 100644
index 0000000..c5827a5
--- /dev/null
+++ b/docs/running.html
@@ -0,0 +1,308 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Running Knopflerfish OSGi"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Running Knopflerfish"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Running Knopflerfish</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	
+<h1 class="kf">Running Knopflerfish</h1>
+
+<h2 class="kf">Starting Knopflerfish</h2>
+The Knopflerfish OSGi framework is distributed as an executable jar
+file and is started by running java on the
+framework.jar file in the osgi directory. 
+<pre class="shell">
+    > cd osgi
+    > java -jar framework.jar
+</pre>
+<p>
+  The framework can also be started by double-clicking on the
+  framework.jar file from Finder/Explorer or similar tools, depending on
+  operating system used.
+</p>
+<p>
+  The compact version of the framework is started the same way, but instead of 
+  framework.jar the framework_compact.jar file must be used, e.g.
+<pre class="shell">
+    > cd osgi
+    > java -jar framework_compact.jar
+</pre>
+</p>
+
+<p>
+  It is also possible to start Knopflerfish from the 
+  <a href="building.html">
+    ant build environment.
+  </a>
+  This is typically done when running the 
+  <a href="testing.html">
+    Knopflerfish test suite.
+  </a>
+</p>
+<p>
+  The SDK installation starts a default set of bundles, including the 
+  <a href="bundledoc/index.html?docpage=desktop/index.html">
+    Knopflerfish OSGi Desktop bundle
+  </a> and other utilities. 
+</p>
+The Knopflerfish framework can be further controlled by:
+<ul>
+  <li><a href="#options">Supplying command line options</a></li>
+  <li><a href="#xargs">Creating xargs file</a></li>
+  <li><a href="#props">Setting framework and system properties</a></li>
+</ul>
+
+For a complete description of all framework feature please refer to
+the 
+<a href="bundledoc/index.html?docpage=framework/index.html">
+  framework bundle documentation
+</a>.
+
+<a name="options"></a>
+<h2 class="kf">Knopflerfish command line options</h2>
+To control the behavior of Knopflerfish OSGi command line options can
+be supplied. To get help on the framework options, run the framework with the help option.
+<pre class="shell">
+    java -jar framework.jar -help
+</pre>
+This prints a help screen (exact contents is version dependent).
+
+<pre class="shell">
+java -jar framework.jar -help
+Knopflerfish OSGi framework launcher, version 6.0.0.0001
+Copyright 2003-2013 Knopflerfish. All Rights Reserved.
+See http://www.knopflerfish.org for more information.
+
+ Usage:  java [properties] org.knopflerfish.framework.Main [options]
+      or java [properties] -jar framework.jar [options]
+      or ./kf2 [options] [-- [properties]]  [--- [extra]] (*)
+
+ Options:
+   -exit          Exit the JVM process
+   -help          Print this text and exit
+   -version       Print version and exit
+   -jvminfo       Print system and framework properties and exit
+   -sleep SEC     Sleep a while before next command.
+   -xargs file    Load more command line arguments from file, exit if file
+                  cannot be loaded.
+   --xargs file   Load more command line arguments from file, continue 
+                  if file cannot be loaded (but print error)
+
+   -create        Create and initialize a new framework instance
+                  after a shutdown. The default is to reuse the old
+                  framework instance.
+   -ff FF         Specify the name of the FrameworkFactory to use when
+                  creating the framework instance.
+   -init          Start an empty platform (i.e., clear old presistent data).
+   -launch        Launch framework (i.e., start it).
+   -shutdown mSEC Shutdown framework, timeout in milliseconds.
+
+   -install URL   Install a bundle
+   -istart URL    Install and start bundle according to activation policy.
+   -start ID      Start bundle (according to its activation policy)
+   -start_e ID    Start bundle eagerly (i.e., ignore its activation policy)
+   -start_et ID   Start bundle eagerly and transiently
+   -start_pt ID   Start bundle transiently according to policy
+   -stop ID       Stop bundle
+   -stop_t ID     Stop bundle transiently (i.e, non-persistent stop)
+   -uninstall ID  Uninstall a bundle
+   -update ID     Update a bundle
+
+   -initlevel N   Set initial start level for installed bundles
+   -startlevel N  Set the beginning start level of the Start Level service
+
+ Extra: (Only applicable when using ./kf2)
+   -java PATH	  Use this JVM (Default=java)
+
+
+ The default directory used for storing bundle data is  "fwdir".
+
+ (*) Fully R4 compatible, enables support for bootclasspath extension bundles.
+
+ For extended help and list of all available system properties, see online
+ documentation or visit:
+
+ http://www.knopflerfish.org/releases/current/docs/bundledoc/framework/index.html
+</pre>
+
+<a name="xargs"></a>
+<h2 class="kf">xargs files</h2>
+<p>
+The xargs file are Knopflerfish command line options specified in a
+text file, typically ending in .xargs. This is a convenient method for
+specifying which bundles to start as well as setting framework
+properties.
+</p>
+<p>
+The Knopflerfish SDK includes the following .xargs files by default
+<div class="kf">
+  <dl>
+    <dt>init.xargs</dt>
+    <dd>
+      Initial or bootstrap start. Also used as default if no other
+      xargs argument is given. See also 
+      <a href="bundledoc/index.html?docpage=framework/index.html#init_restart">
+	Initial start vs restart
+      </a>.
+      <p>
+	Generated from template.xargs.in (only present in a full
+	source file installation).
+      </p>
+    </dd>
+    <dt>headless.xargs</dt>
+    <dd>
+      Initial or bootstrap start to use when running the JVM is
+      running in headless mode. Same set of bundles as in init.xargs
+      except that bundles requiring AWT has been commented out.
+      <p>
+	Generated from template.xargs.in (only present in a full
+	source file installation) with "$(AWT)" set to '#'.
+      </p>
+    </dd>
+    <dt>minimal.xargs</dt>
+    <dd>
+      Starts the framework and a minimal set of bundles.
+    </dd>
+    <dt>props.xargs</dt>
+    <dd>
+      One common xargs file that only set properties. Is used, or sourced, by
+      other xargs files.
+    </dd>
+    <dt>remote-init.xargs</dt>
+    <dd>
+      Initial and bootstrap start with bundles loaded from an HTTP
+      URL from a release specific bundle repository, located on www.knopflerfish.org,
+      instead of loading from a file URL from the installation.
+    </dd>
+    <dt>init-tests.xargs</dt>
+    <dd>
+      xargs file for the Knopflerfish test suite. Normally invoked
+      via an ant target.
+    </dd>
+    <dt>test-restart1.xargs</dt>
+    <dd>
+      xargs file for the Knopflerfish test suite. Normally invoked
+      via an ant target.
+    </dd>
+    <dt>test-restart2.xargs</dt>
+    <dd>
+      xargs file for the Knopflerfish test suite. Normally invoked
+      via an ant target.
+    </dd>
+  </dl>    
+</div>
+
+<a name="props"></a>
+<h2 class="kf">Framework and System Properties</h2>
+<p>
+  The behavior of Knopflerfish can be further controlled by specifying
+  framework and system properties that are either specified by OSGi or
+  Knopflerfish specific. The framework and system properties are
+  described in detail in the <a
+  href="bundledoc/index.html?docpage=framework/index.html">
+  framework bundle documentation </a>.
+</p>
+<p>
+  There is a default properties setting in the <code>props.xargs</code> file.
+</p>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/testing.html b/docs/testing.html
new file mode 100644
index 0000000..0d349b7
--- /dev/null
+++ b/docs/testing.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Testing Knopflerfish OSGi"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Testing"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Testing</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Testing Knopflerfish</h1>
+
+<p>
+  Knopflerfish includes a Junit based test suite that tests the
+  framework and bundles. Developers can use this test suite to test and
+  verify Knopflerfish on specific target environments, e.g. some
+  combination of processor, operating system, and JVM. 
+</p>
+
+<p>
+  The easiest way to run the test suite is to run one of the two
+  test suite targets from the top level ant build file located in
+  the <tt>osgi</tt> directory. E.g.
+  <pre class="shell">
+> cd osgi
+> ant run-kf-tests
+  </pre>
+</p>
+
+The two test targets available are:
+<div class="kf">
+  <dl>
+    <dt> run-kf-tests</dt>
+    <dd>Builds then executes the KF test suite.</dd>
+    <dt>run-kf-tests-secure</dt>
+    <dd>Builds then executes the KF test suite with security enabled.</dd>
+  </dl>
+</div>
+
+<p>
+A developer may add new test bundles to the test suite, or defined
+their own stand-alone test suites. The bundle documentation for the 
+<a href="bundledoc/index.html?docpage=junit/index.html">
+  JUnit bundle
+</a>
+describes this in detail.
+</p>
+
+<p>
+  Please note that passing the Knopflerfish test suite is no claim for
+  OSGi compliance. It is a Knopflerfish specific test suite only.
+</p>
+  
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/tutorials.html b/docs/tutorials.html
new file mode 100644
index 0000000..aa894b5
--- /dev/null
+++ b/docs/tutorials.html
@@ -0,0 +1,144 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "The tutorials shipped with KF"/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Tutorials"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Tutorials</title>
+
+    <LINK href="./css/knopflerfish.css" rel="stylesheet" type="text/css">
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <a name="top"></a>
+      <div id="header">
+	<div id="header_logo">
+	  <a href="index.html"><img src="images/kf300_black.png" border="0" alt="knopflerfish logo"/></a>
+	</div>
+	<div id="header_centerbox">
+	  <div class="header_centerinfo_top">
+	    Distribution Documentation
+	  </div>
+	  <div class="header_centerinfo_bottom">
+	    Knopflerfish OSGi 5.1.0
+	  </div>
+	</div>
+	<div id="header_rightinfo">
+	  <div class="header_stylish">
+	    Open Source OSGi Service Platform Maintained by
+	  </div>
+	  <a href="http://www.makewave.com">
+	    <img border="0" alt="Makewave" src="./images/makewave_logo.png" border="0" style="margin-top: 4px;">
+	  </a>
+	</div>
+	<div id="header_fade">
+	</div>
+      </div>
+      <div id="leftmenu">
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="index.html">Knopflerfish 5.1.0</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="components.html">Contents</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="release_notes.html">Release Notes</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="license.html">License</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Getting Started</dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="installing.html">Installing</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="running.html">Running</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="building.html">Building</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="programming.html">Programming</a></dd> 
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="testing.html">Testing</a></dd>
+	</dl>
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2">Developer's Doc</dt>
+	  <dd class="leftmenu2"><a class="navigation_disabled" href="tutorials.html">Tutorials</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="javadoc/index.html">Java API docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="bundledoc/index.html">Framework and Bundle docs</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="jars/index.html">Bundle jar docs</a></dd>
+	</dl>
+
+	<dl class="leftmenu2">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/">www.knopflerfish.org</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://sourceforge.net/forum/forum.php?forum_id=328005">KF Forum</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://sourceforge.net/tracker/?atid=567241&group_id=82798&func=browse">Bug tracker</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="../osgi/jars/index.xml">Bundle repository</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="https://www.knopflerfish.org/svn/knopflerfish.org/tags/5.1.0">Source (subversion)</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.knopflerfish.org/eclipse_plugin.html">Eclipse plugin</a></dd>
+	</dl>
+
+	<dl class="leftmenu2_last">
+	  <dt class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/">Maintained by Makewave</a></dt>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/knopflerfish_pro_osgi.shtml">Knopflerfish Pro</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_expert.shtml">Professional Services</a></dd>
+	  <dd class="leftmenu2"><a class="navigation_enabled" href="http://www.makewave.com/site.en/products/osgi_training.shtml">Training</a></dd>
+	  <dd class="leftmenu2"> </dd>
+	  <dd class="leftmenu2" style="margin-top: 10px;"><a class="navigation_enabled" href="http://www.makewave.com"><img src="./images/makewave_logo_126x16.gif" border="0"></a><br>
+	  <dd><div style="font-size: 0.75em; color: #444444; font-family: Helvetica, Sans-Serif; margin-left: -10px;">
+	      <em>OSGi for Business Use</em></div>
+	  </dd>
+	</dl>
+      </div>
+      <div id="mainblock">
+	<h1 class="kf">Knopflerfish OSGi Tutorials</h1>
+
+<p>
+  This page contains links to tutorials and guides on how to use OSGi frameworks 
+  and the KF OSGi distribution.
+</p>
+
+<dl class="kf">
+  <dt><a href="tutorials/kf_osgi_tutorial/kf_osgi_tutorial.pdf">OSGi tutorial v2</a></dt>
+  <dd>A Step by Step Introduction to OSGi Programming Based on the 
+    Knopflerfish OSGi Framework. 
+    <p>
+      The tutorial includes examples src code located at<br>
+      <code>docs/tutorials/kf_osgi_tutorial/example_source</code>
+    </p>
+  </dd>
+  <dt>
+    <a href="osgi_service_tutorial.html"> The OSGi Service Tutorial</a>
+  </dt>
+  <dd> The complete survival guide for handling OSGi services</dd>
+
+  <dt>
+    <a href="osgi_with_security.html">Running Knopflerfish OSGi with Security</a>
+  </dt>
+  <dd>
+    A very short tutorial to get started with OSGi security and
+    permissions using Knopflerfish.
+  </dd>
+  
+  <dt>
+    <a href="android_dalvik_tutorial.html">Running Knopflerfish on Android / Dalvik</a>
+  </dt>
+  <dd>
+    An introduction on how to run Knopflerfish on Android / Dalvik
+  </dd>
+
+</dl>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/build.xml
new file mode 100644
index 0000000..3767b0a
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/build.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<project name="tutorial" default="all">
+
+  <property name="kf.dir" location="../../../osgi"/>
+
+  <target name="doAntBuild">
+    <ant target="${the.target}" dir="simplebundle"/>
+    <ant target="${the.target}" dir="dateservice"/>
+    <ant target="${the.target}" dir="dateserviceuser_bad"/>
+    <ant target="${the.target}" dir="dateserviceuser_bad2"/>
+    <ant target="${the.target}" dir="dateserviceuser_listener"/>
+    <ant target="${the.target}" dir="dateserviceuser_tracker"/>
+    <ant target="${the.target}" dir="dateserviceuser_declarative"/>
+  </target>
+
+  <target name="all" 
+	  description="Builds all bundles">
+    <antcall target="doAntBuild">
+      <param name="the.target" value="all"/>
+    </antcall>
+  </target>
+
+  <target name="clean"
+	  description="Cleans all bundles">
+    <antcall target="doAntBuild">
+      <param name="the.target" value="clean"/>
+    </antcall>
+  </target>
+
+</project>
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/build.xml
new file mode 100644
index 0000000..c9df642
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/build.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?> 
+<project name="dateservice" default="all"> 
+  
+  <property name="kf.dir" location="../../../../osgi"/>
+  
+  <property name="framework.jar" 
+	    location="${kf.dir}/framework.jar"/>
+  
+  <target name="all" depends="init,compile,jar"/> 
+  
+  <target name="init"> 
+    <mkdir dir="out/classes"/> 
+  </target> 
+  
+  <target name="compile"> 
+    <javac destdir       = "out/classes" 
+	   debug         = "on" 
+	   srcdir        = "src" 
+	   > 
+      <classpath>
+	<pathelement location="${framework.jar}"/>
+      </classpath>      	  	  
+    </javac> 
+  </target> 
+  
+  <target name="jar"> 
+    <jar basedir  = "out/classes" 
+	 jarfile  = "out/${ant.project.name}.jar" 
+	 compress = "true" 
+	 includes = "**/*" 
+	 manifest = "manifest.mf">
+    </jar>
+  </target> 
+  
+  <target name="clean"> 
+    <delete dir = "out"/> 
+  </target> 
+  
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/manifest.mf
new file mode 100644
index 0000000..99a6a8c
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/manifest.mf
@@ -0,0 +1,10 @@
+Manifest-Version: 2.0
+Bundle-Name: dateservice
+Bundle-SymbolicName: org.knopflerfish.tutorial.dateservice
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Service Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Activator: org.knopflerfish.tutorial.dateservice.impl.Activator 
+Bundle-Category: example 
+Import-Package: org.osgi.framework
+Export-Package: org.knopflerfish.tutorial.dateservice
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/DateService.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/DateService.java
new file mode 100644
index 0000000..2216923
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/DateService.java
@@ -0,0 +1,7 @@
+package org.knopflerfish.tutorial.dateservice; 
+
+import java.util.Date; 
+
+public interface DateService {
+  public String getFormattedDate(Date date);
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/impl/Activator.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/impl/Activator.java
new file mode 100644
index 0000000..ccab8cb
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/impl/Activator.java
@@ -0,0 +1,32 @@
+package org.knopflerfish.tutorial.dateservice.impl; 
+
+import java.util.Hashtable; 
+import org.osgi.framework.BundleActivator; 
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants; 
+import org.osgi.framework.ServiceRegistration; 
+
+import org.knopflerfish.tutorial.dateservice.DateService; 
+
+
+public class Activator implements BundleActivator { 
+  public static BundleContext bc = null; 
+
+  public void start(BundleContext bc) throws Exception { 
+    System.out.println(bc.getBundle().getHeaders().get 
+                       (Constants.BUNDLE_NAME) + " starting..."); 
+    Activator.bc = bc; 
+
+    DateService         service       = new DateServiceImpl(); 
+    ServiceRegistration registration = 
+      bc.registerService(DateService.class.getName(), 
+                         service, 
+                         new Hashtable()); 
+    System.out.println("Service registered: DateService"); 
+  } 
+  public void stop(BundleContext bc) throws Exception { 
+    System.out.println(bc.getBundle().getHeaders().get 
+                       (Constants.BUNDLE_NAME) + " stopping..."); 
+    Activator.bc = null; 
+  } 
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/impl/DateServiceImpl.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/impl/DateServiceImpl.java
new file mode 100644
index 0000000..860c996
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateservice/src/org/knopflerfish/tutorial/dateservice/impl/DateServiceImpl.java
@@ -0,0 +1,13 @@
+package org.knopflerfish.tutorial.dateservice.impl; 
+
+import java.text.DateFormat; 
+import java.util.Date; 
+import org.knopflerfish.tutorial.dateservice.DateService;
+
+
+public class DateServiceImpl implements DateService { 
+  public String getFormattedDate(Date date) { 
+    return DateFormat.getDateInstance(DateFormat.SHORT)
+      .format(date); 
+  } 
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/build.xml
new file mode 100644
index 0000000..059e767
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/build.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?> 
+<project name="dateserviceuser_bad" default="all"> 
+
+  <property name="kf.dir" location="../../../../osgi"/>
+  
+  <property name="framework.jar" 
+	    location="${kf.dir}/framework.jar"/>
+  
+  <property name="dateservice.jar"
+	    location="../dateservice/out/dateservice.jar"/>
+  
+  <target name="all" depends="init,compile,jar"/> 
+  
+  <target name="init"> 
+    <mkdir dir="out/classes"/> 
+  </target> 
+  
+  <target name="compile"> 
+    <javac destdir       = "out/classes" 
+	   debug         = "on" 
+	   srcdir        = "src"> 
+      <classpath>
+	<pathelement location="${framework.jar}"/>
+	<pathelement location="${dateservice.jar}"/>
+      </classpath>      
+    </javac> 
+  </target> 
+  
+  <target name="jar"> 
+    <jar basedir  = "out/classes" 
+	 jarfile  = "out/${ant.project.name}.jar" 
+	 compress = "true" 
+	 includes = "**/*" 
+	 manifest = "manifest.mf">
+    </jar>
+  </target> 
+  
+  <target name="clean"> 
+    <delete dir = "out"/> 
+  </target> 
+  
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/manifest.mf
new file mode 100644
index 0000000..feb683b
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/manifest.mf
@@ -0,0 +1,9 @@
+Manifest-Version: 2.0
+Bundle-Name: dateserviceuser_bad
+Bundle-SymbolicName: org.knopflerfish.tutorial.dateserviceuserbad
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Date Service User Bad Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Activator: org.knopflerfish.tutorial.dateserviceuserbad.impl.Activator 
+Bundle-Category: example 
+Import-Package: org.osgi.framework,org.knopflerfish.tutorial.dateservice
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/src/org/knopflerfish/tutorial/dateserviceuserbad/impl/Activator.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/src/org/knopflerfish/tutorial/dateserviceuserbad/impl/Activator.java
new file mode 100644
index 0000000..a29ee8c
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad/src/org/knopflerfish/tutorial/dateserviceuserbad/impl/Activator.java
@@ -0,0 +1,35 @@
+package org.knopflerfish.tutorial.dateserviceuserbad.impl; 
+
+import java.util.Date;
+import org.osgi.framework.BundleActivator; 
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants; 
+import org.osgi.framework.ServiceReference; 
+
+import org.knopflerfish.tutorial.dateservice.DateService; 
+
+public class Activator implements BundleActivator { 
+  public static BundleContext bc = null; 
+
+  public void start(BundleContext bc) throws Exception { 
+    System.out.println(bc.getBundle().getHeaders()
+                       .get(Constants.BUNDLE_NAME) + 
+                       " starting..."); 
+    Activator.bc = bc; 
+    ServiceReference reference = 
+      bc.getServiceReference(DateService.class.getName()); 
+
+    DateService service = (DateService)bc.getService(reference); 
+    System.out.println("Using DateService: formatting date: " + 
+                       service.getFormattedDate(new Date())); 
+    bc.ungetService(reference); 
+  }
+
+  public void stop(BundleContext bc) throws Exception { 
+    System.out.println(bc.getBundle().getHeaders()
+                       .get(Constants.BUNDLE_NAME) + 
+                       " stopping..."); 
+    Activator.bc = null; 
+  }
+} 
+
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/build.xml
new file mode 100644
index 0000000..65f5572
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/build.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?> 
+<project name="dateserviceuser_bad2" default="all"> 
+  
+  <property name="kf.dir" location="../../../../osgi"/>
+  
+  <property name="framework.jar" 
+	    location="${kf.dir}/framework.jar"/>
+  
+  <property name="dateservice.jar"
+	    location="../dateservice/out/dateservice.jar"/>
+  
+  <target name="all" depends="init,compile,jar"/> 
+  
+  <target name="init"> 
+    <mkdir dir="out/classes"/> 
+  </target> 
+  
+  <target name="compile"> 
+    <javac destdir       = "out/classes" 
+	   debug         = "on" 
+	   srcdir        = "src"> 
+      <classpath>
+	<pathelement location="${framework.jar}"/>
+	<pathelement location="${dateservice.jar}"/>
+      </classpath>      
+    </javac> 
+  </target> 
+  
+  <target name="jar"> 
+    <jar basedir  = "out/classes" 
+	 jarfile  = "out/${ant.project.name}.jar" 
+	 compress = "true" 
+	 includes = "**/*" 
+	 manifest = "manifest.mf">
+    </jar>
+  </target> 
+
+  <target name="clean"> 
+    <delete dir = "out"/> 
+  </target> 
+
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/manifest.mf
new file mode 100644
index 0000000..f7cc118
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/manifest.mf
@@ -0,0 +1,9 @@
+Manifest-Version: 2.0
+Bundle-Name: dateserviceuser_bad2
+Bundle-SymbolicName: org.knopflerfish.tutorial.dateserviceuserbad2
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Date Service User Bad2 Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Activator: org.knopflerfish.tutorial.dateserviceuserbad2.impl.Activator 
+Bundle-Category: example 
+Import-Package: org.osgi.framework,org.knopflerfish.tutorial.dateservice
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/src/org/knopflerfish/tutorial/dateserviceuserbad2/impl/Activator.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/src/org/knopflerfish/tutorial/dateserviceuserbad2/impl/Activator.java
new file mode 100644
index 0000000..4f41d89
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_bad2/src/org/knopflerfish/tutorial/dateserviceuserbad2/impl/Activator.java
@@ -0,0 +1,39 @@
+package org.knopflerfish.tutorial.dateserviceuserbad2.impl; 
+
+import java.util.Date;
+import org.osgi.framework.BundleActivator; 
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants; 
+import org.osgi.framework.ServiceReference; 
+
+import org.knopflerfish.tutorial.dateservice.DateService; 
+
+public class Activator implements BundleActivator { 
+  public static BundleContext bc = null; 
+
+  public void start(BundleContext bc) throws Exception { 
+    System.out.println(bc.getBundle().getHeaders()
+                       .get(Constants.BUNDLE_NAME) + 
+                       " starting..."); 
+    Activator.bc = bc; 
+    ServiceReference reference = 
+      bc.getServiceReference(DateService.class.getName()); 
+
+    if(reference != null) {
+      DateService service = (DateService)bc.getService(reference); 
+      System.out.println("Using DateService: formatting date: " + 
+                         service.getFormattedDate(new Date())); 
+      bc.ungetService(reference); 
+    } else {
+      System.out.println("No Service available!"); 
+    }
+  }
+
+  public void stop(BundleContext bc) throws Exception { 
+    System.out.println(bc.getBundle().getHeaders()
+                       .get(Constants.BUNDLE_NAME) + 
+                       " stopping..."); 
+    Activator.bc = null; 
+  }
+} 
+
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/build.xml
new file mode 100644
index 0000000..7030b62
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/build.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?> 
+<project name="dateserviceuser_declarative" default="all"> 
+
+  <property name="kf.dir" location="../../../../osgi"/>
+
+  <property name="framework.jar" 
+	    location="${kf.dir}/framework.jar"/>
+  <property name="dateservice.jar"
+	    location="../dateservice/out/dateservice.jar"/>
+
+  
+  <target name="all" depends="init,compile,jar"/> 
+
+  <target name="init"> 
+    <mkdir dir="out/classes"/> 
+  </target> 
+  
+  <target name="compile"> 
+    <javac destdir       = "out/classes" 
+	   debug         = "on" 
+	   srcdir        = "src"> 
+      <classpath>
+	<pathelement location="${framework.jar}"/>
+	<pathelement location="${dateservice.jar}"/>
+      </classpath>      
+    </javac> 
+  </target> 
+  
+  <target name="jar"> 
+    <jar basedir  = "out/classes" 
+	 jarfile  = "out/${ant.project.name}.jar" 
+	 compress = "true" 
+	 includes = "**/*" 
+	 manifest = "manifest.mf">
+      <fileset dir="resources"/>
+    </jar>
+  </target> 
+  
+  <target name="clean"> 
+    <delete dir = "out"/> 
+  </target> 
+  
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/manifest.mf
new file mode 100644
index 0000000..45c34d9
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/manifest.mf
@@ -0,0 +1,9 @@
+Manifest-Version: 2.0
+Bundle-Name: dateserviceuser_declarative
+Bundle-SymbolicName: org.knopflerfish.tutorial.dateserviceuserdeclarative
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Date Service User Declarative Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Category: example 
+Import-Package: org.osgi.framework,org.knopflerfish.tutorial.dateservice
+Service-Component: OSGI-INF/component.xml
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/resources/OSGI-INF/component.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/resources/OSGI-INF/component.xml
new file mode 100644
index 0000000..c7eae41
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/resources/OSGI-INF/component.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<component 
+  xmlns = "http://www.osgi.org/xmlns/scr/v1.0.0"
+  name  = "kf.tutorial.datelisten">
+
+  <implementation 
+     class="org.knopflerfish.tutorial.dateserviceuserdeclarative.impl.Component"/>
+  <reference name = "DATESERVICE"
+	     interface = "org.knopflerfish.tutorial.dateservice.DateService"
+	     bind = "setDateService"
+	     unbind = "unsetDateService"
+	     />
+</component>
\ No newline at end of file
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/src/org/knopflerfish/tutorial/common/ServiceUserThread.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/src/org/knopflerfish/tutorial/common/ServiceUserThread.java
new file mode 100644
index 0000000..e386555
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/src/org/knopflerfish/tutorial/common/ServiceUserThread.java
@@ -0,0 +1,40 @@
+package org.knopflerfish.tutorial.common; 
+
+import java.util.Date;
+import org.knopflerfish.tutorial.dateservice.DateService; 
+
+public class ServiceUserThread extends Thread { 
+  private DateService  dateService = null; 
+  private boolean      running = true; 
+
+  public ServiceUserThread(DateService dateService, String threadName) { 
+    super(threadName);
+    this.dateService = dateService; 
+  }
+  
+  public void run() { 
+    String formattedDate = null; 
+    
+    while (running) { 
+      Date date = new Date(); 
+      try { 
+        formattedDate = dateService.getFormattedDate(date); 
+      } catch (RuntimeException e) { 
+        System.out.println("RuntimeException occured during service usage: " 
+                            + e); 
+      } 
+      System.out.println(getName() + ": converted date has value: " 
+                         + formattedDate); 
+      try { 
+        Thread.sleep(1000); 
+      } catch (InterruptedException e) { 
+        System.out.println("ServiceUserThread ERROR: " + e); 
+      } 
+    } 
+  }
+  
+  public void stopThread() { 
+    System.out.println("stopping " + this);
+    this.running = false; 
+  } 
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/src/org/knopflerfish/tutorial/dateserviceuserdeclarative/impl/Component.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/src/org/knopflerfish/tutorial/dateserviceuserdeclarative/impl/Component.java
new file mode 100644
index 0000000..89dec03
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_declarative/src/org/knopflerfish/tutorial/dateserviceuserdeclarative/impl/Component.java
@@ -0,0 +1,48 @@
+package org.knopflerfish.tutorial.dateserviceuserdeclarative.impl; 
+
+import org.knopflerfish.tutorial.dateservice.DateService; 
+import org.knopflerfish.tutorial.common.ServiceUserThread;
+
+public class Component {
+  DateService       dateService;
+  ServiceUserThread thread;
+
+  /**
+   * Called by the Declarative Service component finds
+   * a registered DateService as specified in the component.xml
+   */
+  protected void setDateService(DateService dateService) {
+    log("setDateService");
+    this.dateService = dateService;
+
+    if(thread == null) {
+      thread = new ServiceUserThread(dateService, "declarative example"); 
+      thread.start(); 
+    }
+  }
+  
+  /**
+   * Called by the Declarative Service component notices an
+   * unregistered DateService as specified in the component.xml
+   */
+  protected void unsetDateService(DateService dateService) { 
+    log("unsetDateService");
+    this.dateService = null;
+
+    if(thread != null) {
+      thread.stopThread(); 
+      try { 
+        thread.join(); 
+      } catch (InterruptedException e) { 
+        e.printStackTrace(); 
+      }
+      thread = null;
+    }
+  }
+  
+  private void log(String message) { 
+    System.out.println("dateservice component: " + message); 
+  } 
+  
+} 
+
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/build.xml
new file mode 100644
index 0000000..849d3e4
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/build.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?> 
+<project name="dateserviceuser_listener" default="all"> 
+  
+  <property name="kf.dir" location="../../../../osgi"/>
+  
+  <property name="framework.jar" 
+	    location="${kf.dir}/framework.jar"/>
+  
+  <property name="dateservice.jar"
+	    location="../dateservice/out/dateservice.jar"/>
+  
+  <target name="all" depends="init,compile,jar"/> 
+  
+  <target name="init"> 
+    <mkdir dir="out/classes"/> 
+  </target> 
+  
+  <target name="compile"> 
+    <javac destdir       = "out/classes" 
+	   debug         = "on" 
+	   srcdir        = "src"> 
+      <classpath>
+	<pathelement location="${framework.jar}"/>
+	<pathelement location="${dateservice.jar}"/>
+      </classpath>      
+    </javac> 
+  </target> 
+  
+  <target name="jar"> 
+    <jar basedir  = "out/classes" 
+	 jarfile  = "out/${ant.project.name}.jar" 
+	 compress = "true" 
+	 includes = "**/*" 
+	 manifest = "manifest.mf">
+    </jar>
+  </target> 
+  
+  <target name="clean"> 
+    <delete dir = "out"/> 
+  </target> 
+  
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/manifest.mf
new file mode 100644
index 0000000..9235a83
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/manifest.mf
@@ -0,0 +1,9 @@
+Manifest-Version: 2.0
+Bundle-Name: dateserviceuser_listener
+Bundle-SymbolicName: org.knopflerfish.tutorial.dateserviceuserlistener
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Date Service User Listener Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Activator: org.knopflerfish.tutorial.dateserviceuserlistener.impl.Activator 
+Bundle-Category: example 
+Import-Package: org.osgi.framework,org.knopflerfish.tutorial.dateservice
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/src/org/knopflerfish/tutorial/common/ServiceUserThread.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/src/org/knopflerfish/tutorial/common/ServiceUserThread.java
new file mode 100644
index 0000000..e386555
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/src/org/knopflerfish/tutorial/common/ServiceUserThread.java
@@ -0,0 +1,40 @@
+package org.knopflerfish.tutorial.common; 
+
+import java.util.Date;
+import org.knopflerfish.tutorial.dateservice.DateService; 
+
+public class ServiceUserThread extends Thread { 
+  private DateService  dateService = null; 
+  private boolean      running = true; 
+
+  public ServiceUserThread(DateService dateService, String threadName) { 
+    super(threadName);
+    this.dateService = dateService; 
+  }
+  
+  public void run() { 
+    String formattedDate = null; 
+    
+    while (running) { 
+      Date date = new Date(); 
+      try { 
+        formattedDate = dateService.getFormattedDate(date); 
+      } catch (RuntimeException e) { 
+        System.out.println("RuntimeException occured during service usage: " 
+                            + e); 
+      } 
+      System.out.println(getName() + ": converted date has value: " 
+                         + formattedDate); 
+      try { 
+        Thread.sleep(1000); 
+      } catch (InterruptedException e) { 
+        System.out.println("ServiceUserThread ERROR: " + e); 
+      } 
+    } 
+  }
+  
+  public void stopThread() { 
+    System.out.println("stopping " + this);
+    this.running = false; 
+  } 
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/src/org/knopflerfish/tutorial/dateserviceuserlistener/impl/Activator.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/src/org/knopflerfish/tutorial/dateserviceuserlistener/impl/Activator.java
new file mode 100644
index 0000000..0697e92
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_listener/src/org/knopflerfish/tutorial/dateserviceuserlistener/impl/Activator.java
@@ -0,0 +1,87 @@
+package org.knopflerfish.tutorial.dateserviceuserlistener.impl; 
+
+import java.util.Date;
+import org.osgi.framework.BundleActivator; 
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants; 
+import org.osgi.framework.ServiceReference; 
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+
+import org.knopflerfish.tutorial.dateservice.DateService; 
+import org.knopflerfish.tutorial.common.ServiceUserThread;
+
+public class Activator implements BundleActivator { 
+  public static BundleContext bc = null; 
+
+  DateService       dateService;
+  ServiceUserThread thread;
+
+  public void start(BundleContext bc) throws Exception  { 
+    Activator.bc = bc; 
+    log("starting");
+    
+    String filter = "(objectclass=" + DateService.class.getName() + ")"; 
+    bc.addServiceListener(listener, filter); 
+    
+    ServiceReference references[] = bc.getServiceReferences(null, filter); 
+    for (int i = 0; references != null && i < references.length; i++) 
+      { 
+        listener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, 
+                                                 references[i])); 
+      } 
+  } 
+
+  public void stop(BundleContext bc) throws Exception { 
+    log("stopping");
+    Activator.bc = null; 
+  }
+  
+  private void log(String message) { 
+    System.out.println(Activator.bc.getBundle().getHeaders()
+                       .get(Constants.BUNDLE_NAME) 
+                       + ": " + message); 
+  } 
+
+  ServiceListener listener = new ServiceListener() {      
+      public void serviceChanged(ServiceEvent event) { 
+        switch (event.getType()) { 
+        case ServiceEvent.REGISTERED: 
+          log("ServiceEvent.REGISTERED"); 
+          dateService = (DateService) Activator.bc.getService(event 
+                                                               .getServiceReference()); 
+          startUsingService(); 
+          break; 
+        case ServiceEvent.MODIFIED: 
+          log("ServiceEvent.MODIFIED received"); 
+          stopUsingService(); 
+          dateService = (DateService) Activator.bc.getService(event 
+                                                          .getServiceReference()); 
+          startUsingService(); 
+          break; 
+        case ServiceEvent.UNREGISTERING: 
+          log("ServiceEvent.UNREGISTERING"); 
+          stopUsingService(); 
+          break; 
+        } 
+      } 
+      private void stopUsingService() { 
+        thread.stopThread(); 
+        try { 
+          thread.join(); 
+        } catch (InterruptedException e) { 
+          e.printStackTrace(); 
+        } 
+        dateService = null; 
+      } 
+
+      private void startUsingService() { 
+        thread = new ServiceUserThread(dateService, "listener example"); 
+        thread.start(); 
+      } 
+      
+    };
+
+  
+} 
+
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/build.xml
new file mode 100644
index 0000000..ac544bb
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/build.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?> 
+<project name="dateserviceuser_tracker" default="all"> 
+  
+  <property name="kf.dir" location="../../../../osgi"/>
+  
+  <property name="framework.jar" 
+	    location="${kf.dir}/framework.jar"/>
+  
+  <property name="dateservice.jar"
+	    location="../dateservice/out/dateservice.jar"/>
+  
+  <target name="all" depends="init,compile,jar"/> 
+  
+  <target name="init"> 
+    <mkdir dir="out/classes"/> 
+  </target> 
+  
+  <target name="compile"> 
+    <javac destdir       = "out/classes" 
+	   debug         = "on" 
+	   srcdir        = "src"> 
+      <classpath>
+	<pathelement location="${framework.jar}"/>
+	<pathelement location="${dateservice.jar}"/>
+      </classpath>      
+    </javac> 
+  </target> 
+  
+  <target name="jar"> 
+    <jar basedir  = "out/classes" 
+	 jarfile  = "out/${ant.project.name}.jar" 
+	 compress = "true" 
+	 includes = "**/*" 
+	 manifest = "manifest.mf">
+    </jar>
+  </target> 
+  
+  <target name="clean"> 
+    <delete dir = "out"/> 
+  </target> 
+  
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/manifest.mf
new file mode 100644
index 0000000..8a2732d
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/manifest.mf
@@ -0,0 +1,9 @@
+Manifest-Version: 2.0
+Bundle-Name: dateserviceuser_tracker
+Bundle-SymbolicName: org.knopflerfish.tutorial.dateserviceusertracker
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Date Service User Tracker Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Activator: org.knopflerfish.tutorial.dateserviceusertracker.impl.Activator 
+Bundle-Category: example 
+Import-Package: org.osgi.framework,org.knopflerfish.tutorial.dateservice,org.osgi.util.tracker
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/src/org/knopflerfish/tutorial/common/ServiceUserThread.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/src/org/knopflerfish/tutorial/common/ServiceUserThread.java
new file mode 100644
index 0000000..e386555
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/src/org/knopflerfish/tutorial/common/ServiceUserThread.java
@@ -0,0 +1,40 @@
+package org.knopflerfish.tutorial.common; 
+
+import java.util.Date;
+import org.knopflerfish.tutorial.dateservice.DateService; 
+
+public class ServiceUserThread extends Thread { 
+  private DateService  dateService = null; 
+  private boolean      running = true; 
+
+  public ServiceUserThread(DateService dateService, String threadName) { 
+    super(threadName);
+    this.dateService = dateService; 
+  }
+  
+  public void run() { 
+    String formattedDate = null; 
+    
+    while (running) { 
+      Date date = new Date(); 
+      try { 
+        formattedDate = dateService.getFormattedDate(date); 
+      } catch (RuntimeException e) { 
+        System.out.println("RuntimeException occured during service usage: " 
+                            + e); 
+      } 
+      System.out.println(getName() + ": converted date has value: " 
+                         + formattedDate); 
+      try { 
+        Thread.sleep(1000); 
+      } catch (InterruptedException e) { 
+        System.out.println("ServiceUserThread ERROR: " + e); 
+      } 
+    } 
+  }
+  
+  public void stopThread() { 
+    System.out.println("stopping " + this);
+    this.running = false; 
+  } 
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/src/org/knopflerfish/tutorial/dateserviceusertracker/impl/Activator.java b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/src/org/knopflerfish/tutorial/dateserviceusertracker/impl/Activator.java
new file mode 100644
index 0000000..a322ede
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/dateserviceuser_tracker/src/org/knopflerfish/tutorial/dateserviceusertracker/impl/Activator.java
@@ -0,0 +1,83 @@
+package org.knopflerfish.tutorial.dateserviceusertracker.impl; 
+
+import java.util.Date;
+import org.osgi.framework.BundleActivator; 
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants; 
+import org.osgi.framework.ServiceReference; 
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import org.knopflerfish.tutorial.dateservice.DateService; 
+import org.knopflerfish.tutorial.common.ServiceUserThread;
+
+public class Activator implements BundleActivator { 
+  public static BundleContext bc = null; 
+
+  ServiceTracker    tracker;
+  ServiceUserThread thread;
+
+  public void start(BundleContext bc) throws Exception { 
+    Activator.bc = bc; 
+    log("starting");
+    tracker =  new ServiceTracker(bc,
+                                  DateService.class.getName(), 
+                                  customizer);
+    tracker.open(); 
+  } 
+
+  ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer() {
+      public Object addingService(ServiceReference reference) { 
+        log("addingService");
+        DateService service = (DateService) bc.getService(reference); 
+        if (thread == null) { 
+          thread = new ServiceUserThread(service, "tracker example"); 
+          thread.start(); 
+          return service; 
+        } else {
+          return service; 
+        } 
+      }
+
+      public void modifiedService(ServiceReference reference, Object 
+                                  serviceObject) { 
+        thread.stopThread(); 
+        try { 
+          thread.join(); 
+        } catch (InterruptedException e) { 
+          e.printStackTrace(); 
+        } 
+        DateService service = (DateService) bc.getService(reference); 
+        thread = new ServiceUserThread(service, "tracker example"); 
+        thread.start(); 
+      } 
+      public void removedService(ServiceReference reference, Object 
+                                 serviceObject) {
+        log("removedService");
+        thread.stopThread(); 
+        try { 
+          thread.join(); 
+        } catch (InterruptedException e) { 
+          e.printStackTrace(); 
+        } 
+        thread = null; 
+      } 
+    };
+  
+  
+  public void stop(BundleContext bc) throws Exception { 
+    log("stopping");
+    tracker.close();
+    Activator.bc = null; 
+  }
+  
+  private void log(String message) { 
+    System.out.println(Activator.bc.getBundle().getHeaders()
+                       .get(Constants.BUNDLE_NAME) 
+                       + ": " + message); 
+  } 
+  
+} 
+
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/build.xml b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/build.xml
new file mode 100644
index 0000000..c9ab5c8
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/build.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?> 
+<project name="simplebundle" default="all"> 
+
+  <property name="kf.dir" location="../../../../osgi"/>
+  
+  <property name="framework.jar" 
+            location="${kf.dir}/framework.jar"/>
+  
+  <target name="all" depends="init,compile,jar"/> 
+
+  <target name="init"> 
+	<mkdir dir="out/classes"/> 
+  </target> 
+
+  <target name="compile"> 
+	<javac destdir       = "out/classes" 
+		   debug         = "on" 
+		   srcdir        = "src" 
+		   > 
+      <classpath>
+		<pathelement location="${framework.jar}"/>
+	  </classpath>      	  
+	</javac> 
+  </target> 
+
+  <target name="jar"> 
+	<jar basedir  = "out/classes" 
+		 jarfile  = "out/${ant.project.name}.jar" 
+		 compress = "true" 
+		 includes = "**/*" 
+		 manifest = "manifest.mf" 
+		 /> 
+  </target> 
+
+  <target name="clean"> 
+	<delete dir = "out"/> 
+  </target> 
+
+</project> 
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/manifest.mf b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/manifest.mf
new file mode 100644
index 0000000..84182b5
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/manifest.mf
@@ -0,0 +1,9 @@
+Manifest-Version: 2.0
+Bundle-Name: simplebundle 
+Bundle-SymbolicName: simplebundle 
+Bundle-Version: 1.0.0 
+Bundle-Description: Demo Bundle for the KF OSGi tutorial 
+Bundle-Vendor: Knopflerfish
+Bundle-Activator: org.knopflerfish.tutorial.simplebundle.impl.Activator 
+Bundle-Category: example 
+Import-Package: org.osgi.framework
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/src/org/knopflerfish/tutorial/simplebundle/impl/Activator.java b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/src/org/knopflerfish/tutorial/simplebundle/impl/Activator.java
new file mode 100644
index 0000000..2a8ac64
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/src/org/knopflerfish/tutorial/simplebundle/impl/Activator.java
@@ -0,0 +1,27 @@
+package org.knopflerfish.tutorial.simplebundle.impl; 
+
+import org.osgi.framework.BundleActivator; 
+import org.osgi.framework.BundleContext; 
+
+/** 
+ * @author Sven Haiges | sven.haiges at vodafone.com 
+ */ 
+public class Activator implements BundleActivator { 
+  public static BundleContext bc = null; 
+  
+  
+  private HelloWorldThread thread = null; 
+
+  public void start(BundleContext bc) throws Exception { 
+    System.out.println("SimpleBundle starting..."); 
+    Activator.bc = bc; 
+    thread = new HelloWorldThread(); 
+    thread.start(); 
+  } 
+  
+  public void stop(BundleContext bc) throws Exception { 
+    System.out.println("SimpleBundle stopping..."); 
+    thread.stopThread(); 
+    thread.join(); 
+  } 
+}
diff --git a/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/src/org/knopflerfish/tutorial/simplebundle/impl/HelloWorldThread.java b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/src/org/knopflerfish/tutorial/simplebundle/impl/HelloWorldThread.java
new file mode 100644
index 0000000..56fe77b
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/example_source/simplebundle/src/org/knopflerfish/tutorial/simplebundle/impl/HelloWorldThread.java
@@ -0,0 +1,29 @@
+package org.knopflerfish.tutorial.simplebundle.impl; 
+/** 
+ * @author Sven Haiges | sven.haiges at vodafone.com
+ * @author Erik Wistrand
+ */ 
+public class HelloWorldThread extends Thread { 
+  private boolean running = true; 
+
+  public HelloWorldThread() { 
+    super("Hello World thread");
+  } 
+
+  public void run() { 
+    while (running) { 
+      System.out.println("Hello World!"); 
+      try { 
+        Thread.sleep(5000); 
+      } catch (InterruptedException e) { 
+        System.out.println("HelloWorldThread ERROR: " + e); 
+      } 
+    } 
+    System.out.println("thread stopped"); 
+  }
+ 
+  public void stopThread() { 
+    System.out.println("stopping thread"); 
+    this.running = false; 
+  } 
+} 
diff --git a/docs/tutorials/kf_osgi_tutorial/kf_osgi_tutorial.odt b/docs/tutorials/kf_osgi_tutorial/kf_osgi_tutorial.odt
new file mode 100644
index 0000000..ff40332
Binary files /dev/null and b/docs/tutorials/kf_osgi_tutorial/kf_osgi_tutorial.odt differ
diff --git a/docs/tutorials/kf_osgi_tutorial/kf_osgi_tutorial.pdf b/docs/tutorials/kf_osgi_tutorial/kf_osgi_tutorial.pdf
new file mode 100644
index 0000000..3176ea7
Binary files /dev/null and b/docs/tutorials/kf_osgi_tutorial/kf_osgi_tutorial.pdf differ
diff --git a/docs/tutorials/kf_osgi_tutorial/readme.txt b/docs/tutorials/kf_osgi_tutorial/readme.txt
new file mode 100644
index 0000000..60abf21
--- /dev/null
+++ b/docs/tutorials/kf_osgi_tutorial/readme.txt
@@ -0,0 +1,6 @@
+
+This directory contains the OSGi Tutorial (in OpenOffice Writer format) 
+originally by Sven Haiges and updated by Erik wistrand.
+
+The example_source directory contains the source code used in the 
+tutorial. These examples depend on ${kf.dir/framework.jar}
diff --git a/fish16x16.gif b/fish16x16.gif
new file mode 100644
index 0000000..1e3f70e
Binary files /dev/null and b/fish16x16.gif differ
diff --git a/fish200x300.gif b/fish200x300.gif
new file mode 100644
index 0000000..d98ae8e
Binary files /dev/null and b/fish200x300.gif differ
diff --git a/fish32x32.gif b/fish32x32.gif
new file mode 100644
index 0000000..684295f
Binary files /dev/null and b/fish32x32.gif differ
diff --git a/kf_16x16.gif b/kf_16x16.gif
new file mode 100644
index 0000000..1e3f70e
Binary files /dev/null and b/kf_16x16.gif differ
diff --git a/kf_32x32.gif b/kf_32x32.gif
new file mode 100644
index 0000000..684295f
Binary files /dev/null and b/kf_32x32.gif differ
diff --git a/knopflerfish_red400pxl.gif b/knopflerfish_red400pxl.gif
new file mode 100644
index 0000000..dda1ffa
Binary files /dev/null and b/knopflerfish_red400pxl.gif differ
diff --git a/osgi/build.xml b/osgi/build.xml
new file mode 100644
index 0000000..223d96c
--- /dev/null
+++ b/osgi/build.xml
@@ -0,0 +1,496 @@
+<?xml version="1.0"?>
+
+<project name="osgi" default="default">
+
+  <!-- build properties -->
+
+  <property name="topdir"          location="."/>
+  <property name="osgi.dir"        location="."/>
+  <property name="ant.dir"         location="${topdir}/../ant"/>
+  <property name="jars.dir"        location="jars"/>
+  <property name="gosg.jars"       value="file:jars/"/>
+
+  <property name="repository.current.release"
+	    value="http://www.knopflerfish.org/releases/current/osgi/jars/index.xml"/>
+  <property name="repository.local"
+	    value="file:jars/index.xml"/>
+  <property name="repository.xml.urls"
+	    value="${repository.local},
+		   ${repository.current.release}"/>
+
+  <!-- Properties controling javadoc generation -->
+  <property name="root.out.dir"    location="out"/>
+  <property name="javadoc.out.dir" location="${root.out.dir}/javadoc"/>
+  <property name="exported.file"   location="${root.out.dir}/exported.txt"/>
+  <property name="sources.file"    location="${root.out.dir}/sources.txt"/>
+
+  <!-- The initial part of the URL to use for the default jars -->
+  <!-- location in the remote xargs files.  -->
+  <property name="base.url" value="http://www.knopflerfish.org/releases"/>
+
+  <!-- Test target related properties. -->
+  <property name="run.test.dir"   location="."/>
+  <property name="xargs.out.dir"  location="."/>
+  <property name="xargs.base.dir" location="."/>
+  <property name="junit.out.dir"  location="junit_grunt"/>
+  <property name="test.dir"
+            location="${osgi.dir}/bundles_test/regression_tests"/>
+  <property name="test_jars"      value="$$$${user.dir}/test_jars"/>
+  <property name="test.gosg.jars" value="file:jars/;file:test_jars/"/>
+
+
+  <import file="${ant.dir}/bundletasks.xml"/>
+  <import file="${ant.dir}/xargs.xml"/>
+
+  <!-- targets -->
+  <target name="init">
+    <mkdir dir="${root.out.dir}"/>
+    <available property="dir.bundles_test.present" file="bundles_test"/>
+    <available property="dir.bundles_examples.present" file="bundles_examples"/>
+  </target>
+
+  <target name="default"
+          description="Builds the framework and all non test bundles"
+          depends="init,bundle_tasks">
+    <delete file="${exported.file}"/>
+    <delete file="${sources.file}"/>
+    <property name="generate.javadoc.data" value="true"/>
+
+    <ant dir="framework" target="all"/>
+    <ant dir="bundles"          target="all"/>
+    <ant dir="bundles_opt"      target="all"/>
+    <ant dir="bundles_examples" target="all"/>
+    <antcall target="xargs"/>
+    <antcall target="repoindex"/>
+  </target>
+
+  <target name="all"
+          description="Builds the framework and all bundles including test bundles"
+          depends="default,bundles_test">
+    <antcall target="xargs"/>
+  </target>
+
+  <target name="bundles_test"
+          depends="init,bundles_test_missing,bundles_test_present" />
+  <target name="bundles_test_present" if="dir.bundles_test.present">
+    <ant dir="bundles_test" target="all"
+         inheritAll="false" inheritRefs="false">
+      <!-- No need to build the bundles tasks in this case. -->
+      <property name="bundle_tasks.built" value="true"/>
+    </ant>
+    <antcall target="xargs"/>
+  </target>
+  <target name="bundles_test_missing" unless="dir.bundles_test.present">
+   <echo level="warning"
+         message="The directory for regression test bundles, bundles_test, is missing, skipping test bundles. To build test bundles use subversion to check out the complete knopflerfish.org tree."/>
+  </target>
+
+  <target name="repoindex"
+	  description="Generates the repository index file."
+	  depends="init,bundle_tasks,install_repoindex">
+    <local name="version.repoindex"/>
+    <condition property="version.repoindex"
+               value="${version} "
+               else="">
+      <isset property="version"/>
+    </condition>
+    <repoindex name="Knopflerfish ${version.repoindex}Repository" dir="${jars.dir}"/>
+  </target>
+
+
+  <target name="xargs" depends="init,bundle_tasks">
+    <antcall target="headless_xargs"/>
+    <antcall target="minimal_xargs"/>
+    <antcall target="init_xargs"/>
+    <antcall target="remote_xargs"/>
+    <antcall target="remotefw_xargs"/>
+    <antcall target="examples_cpa_xargs"/>
+  </target>
+
+  <target name="minimal_xargs">
+    <xargs template="minimal.xargs.in"
+           xargs="${xargs.out.dir}/minimal.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${gosg.jars}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+  </target>
+
+  <target name="headless_xargs">
+    <xargs template="template.xargs.in"
+           xargs="${xargs.out.dir}/headless.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${gosg.jars}"
+           testJars="${test_jars}"
+           headless="true"
+           outDir="${root.out.dir}/xargs"/>
+  </target>
+
+  <target name="remote_xargs">
+    <xargs template="template.xargs.in"
+           xargs="${xargs.out.dir}/remote-init.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${base.url}/${version}/osgi/jars/"
+           testJars="${test_jars}"
+           repositoryXmlUrls="${repository.xml.urls}"
+           outDir="${root.out.dir}/xargs">
+      <bundles>
+        <fileset dir="${jars.dir}"
+                 excludes="**/*-source.jar,**/*-javadoc.jar"
+                 includes="**/*.jar"/>
+      </bundles>
+    </xargs>
+  </target>
+
+  <target name="remotefw_xargs">
+    <!-- xargs files that are part of the remote-framework documentation.-->
+    <xargs template="${osgi.dir}/bundles/remotefw/doc/server.xargs.in"
+           xargs="${osgi.dir}/bundles/remotefw/doc/server.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${gosg.jars}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+
+    <xargs template="${osgi.dir}/bundles/remotefw/doc/client.xargs.in"
+           xargs="${osgi.dir}/bundles/remotefw/doc/client.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${gosg.jars}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+  </target>
+
+  <target name="examples_cpa_xargs">
+    <!-- xargs files that are part of the CPA example.-->
+    <xargs template="${osgi.dir}/bundles_examples/cpa/init.xargs.in"
+           xargs="${osgi.dir}/bundles_examples/cpa/init.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${gosg.jars};file:example_jars/"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+  </target>
+
+  <target name="init_xargs">
+    <xargs template="template.xargs.in"
+           xargs="${xargs.out.dir}/init.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${gosg.jars}"
+           repositoryXmlUrls="${repository.xml.urls}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+  </target>
+
+  <target name="test_xargs" depends="check_openssl">
+    <xargs template="init-tests.xargs.in"
+           xargs="${xargs.out.dir}/init-tests.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${test.gosg.jars}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+
+    <xargs template="${test.dir}/restart_test/test-restart1.xargs.in"
+           xargs="${xargs.out.dir}/test-restart1.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${test.gosg.jars}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+
+    <xargs template="${test.dir}/restart_test/test-restart2.xargs.in"
+           xargs="${xargs.out.dir}/test-restart2.xargs"
+           baseDir="${xargs.base.dir}"
+           gosgJars="${test.gosg.jars}"
+           testJars="${test_jars}"
+           outDir="${root.out.dir}/xargs"/>
+  </target>
+
+  <target name="javadoc"
+          description="Create javadoc for all exported packages"
+          depends="bundle_tasks">
+    <fail message="You must build the 'default' or 'all' targets to create the list of exported package before you can generate javadoc.">
+      <condition>
+        <not>
+          <and>
+            <available file="${sources.file}"/>
+            <available file="${exported.file}"/>
+          </and>
+        </not>
+      </condition>
+    </fail>
+
+    <mkdir dir="${javadoc.out.dir}"/>
+
+    <!-- Explicit list of non-bundle source tree roots. -->
+    <path id="sources.path">
+      <pathelement location="${ant.dir}/src"/>
+    </path>
+    <!-- Add in source roots for the framework and all compiled bundles. -->
+    <bundle_javadoc_helper srcRootsFile="${sources.file}"
+                           srcPathId="sources.path"/>
+
+    <!-- Explicit list of non-bundle exported packages to include. -->
+    <property name="javadoc.packages"
+              value="org.knopflerfish.ant.taskdefs.bundle"/>
+    <!-- Add all packages exported by the framework and compiled bundles. -->
+    <bundle_javadoc_helper exportPkgsFile="${exported.file}"
+                           pkgPropertyName="javadoc.packages"/>
+
+    <property name="javadoc.header"
+              value="Knopflerfish OSGi ${version}"/>
+
+    <property name="javadoc.footer"
+              value="${javadoc.header}"/>
+
+    <property name="javadoc.windowtitle"
+              value="${javadoc.header} javadoc"/>
+
+    <property name="javadoc.doctitle"
+              value="${javadoc.header} API documentation"/>
+
+    <javadoc header="${javadoc.header}"
+             footer="${javadoc.footer}"
+             windowtitle="${javadoc.windowtitle}"
+             doctitle="${javadoc.doctitle}"
+             destdir="${javadoc.out.dir}"
+             packagenames="${javadoc.packages}"
+             sourcepathref="sources.path">
+      <!-- Custome tags used by OSGi -->
+      <tag name="ThreadSafe"    scope="all" description="ThreadSafe"/>
+      <tag name="NotThreadSafe" scope="all" description="NotThreadSafe"/>
+      <tag name="Immutable"     scope="all" description="Immutable"/>
+      <tag name="security"      scope="all" description="Required Permissions"/>
+      <tag name="noimplement"   scope="all"
+           description="Consumers of this API must not implement this interface"/>
+      <classpath>
+        <fileset dir="${ant.home}/lib/">
+          <include name="**/*.jar"/>
+          <exclude name="bindex.jar"/>
+        </fileset>
+        <fileset dir="${ant.dir}/lib/">
+          <include name="**/*.jar"/>
+          <exclude name="bindex.jar"/>
+        </fileset>
+        <!-- Make embedded jars available -->
+        <pathelement location="${osgi.dir}/bundles/io/io/resources/javax.microedition.io.jar"/>
+        <pathelement location="${osgi.dir}/bundles/metatype/kf_metatype/resources/nanoxml-2.2.1.jar"/>
+        <pathelement location="${osgi.dir}/bundles/xml/kxml/lib/xmlpull_1_1_3_1.jar"/>
+        <pathelement location="${osgi.dir}/bundles_opt/jini/jinidriver/resources/lib/jini-core.jar"/>
+        <pathelement location="${osgi.dir}/bundles_opt/jini/jinidriver/resources/lib/jini-ext.jar"/>
+        <pathelement location="${osgi.dir}/bundles_opt/junit/junit/resources/junit.jar"/>
+        <pathelement location="${osgi.dir}/bundles_opt/serial/comm-win32/resources/comm.jar"/>
+      </classpath>
+    </javadoc>
+
+    <!-- KF documentation uses links to javadoc with a seach-part that -->
+    <!-- points to a java package or file. Check that the generated    -->
+    <!-- top-level index.html supports this; if not add script.        -->
+    <condition property="javadoc.seach.support">
+      <resourcecontains
+         resource="${javadoc.out.dir}/index.html"
+         substring="SCRIPT"/>
+    </condition>
+    <antcall target="javadocSearchFix"/>
+  </target>
+
+  <target name="javadocSearchFix" unless="javadoc.seach.support">
+    <replace file="${javadoc.out.dir}/index.html">
+      <replacetoken></HEAD></replacetoken>
+      <replacevalue><![CDATA[<SCRIPT type="text/javascript">
+    targetPage = "" + window.location.search;
+    if (targetPage != "" && targetPage != "undefined")
+        targetPage = targetPage.substring(1);
+    if (targetPage.indexOf(":") != -1)
+        targetPage = "undefined";
+    function loadFrames() {
+        if (targetPage != "" && targetPage != "undefined")
+             top.classFrame.location = top.targetPage;
+    }
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+</HEAD>
+]]></replacevalue>
+      <replacefilter token='FRAMESET cols="20%,80%"'
+                     value='FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()"'/>
+      <replacefilter token='FRAMESET rows="30%,70%"'
+                     value='FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()"'/>
+    </replace>
+  </target>
+
+ <target name="run"
+         description="(Re)start the framework.">
+  <java fork="true"
+        jar="framework.jar">
+  </java>
+ </target>
+
+ <target name="run-secure"
+         description="(Re)start framework with security enabled.">
+  <java fork="true"
+        jar="framework.jar">
+    <arg value="-Forg.osgi.framework.security=osgi"/>
+  </java>
+ </target>
+
+ <target name="run-init"
+         description="Initial start with default set of bundles.">
+   <java fork="true"
+         jar="framework.jar" >
+     <arg value="-init"/>
+   </java>
+ </target>
+
+ <target name="run-secure-init"
+         description="Initial start with security enabled and default set of bundles.">
+   <java fork="true"
+         jar="framework.jar">
+     <arg value="-Forg.osgi.framework.security=osgi"/>
+     <arg value="-init"/>
+   </java>
+ </target>
+
+ <target name="run-kf-tests"
+         description="Builds then executes the KF testsuite."
+         depends="clean,all">
+   <antcall target="run-kf-tests-bare"/>
+ </target>
+
+ <target name="run-kf-tests-bare" depends="bundle_tasks">
+   <delete dir="${junit.out.dir}"/>
+
+   <antcall target="test_xargs"/>
+   <antcall target="run-kf-tests-bare-main"/>
+   <antcall target="run-kf-tests-bare-restart"/>
+   <echo message="Test output is available in ${junit.out.dir}/out.txt."/>
+   <echo message="Test results are available in ${junit.out.dir}/index.xml"/>
+ </target>
+
+ <target name="run-kf-tests-secure"
+         description="Builds then executes the KF testsuite with security enabled."
+         depends="clean,all">
+   <antcall target="run-kf-tests-secure-bare"/>
+ </target>
+
+ <target name="run-kf-tests-secure-bare">
+   <antcall target="run-kf-tests-bare">
+     <param name="run.test.secure" value="true"/>
+   </antcall>
+ </target>
+
+
+ <!-- Start the framework with output redirected to ${junit.out.dir}/out.txt -->
+ <!-- Parameters: -->
+ <!--  run.test.secure If set execute tests with security enabled -->
+ <!--  run.test.msg    The message (heading) to print             -->
+ <!--  run.test.append Append output to log file or start new log -->
+ <!--  run.test.xargs  The xargs file to load                     -->
+ <target name="run-test">
+   <antcall target="run-test-default"/>
+   <antcall target="run-test-secure"/>
+ </target>
+ <target name="run-test-default" unless="run.test.secure">
+   <echo message="${run.test.msg}"/>
+   <mkdir dir="${junit.out.dir}"/>
+   <java fork="true"
+         dir="${run.test.dir}"
+         output="${junit.out.dir}/out.txt"
+         append="${run.test.append}"
+         jar="${run.test.dir}/framework.jar">
+     <arg value="-Forg.osgi.framework.storage=${junit.out.dir}/test_fwdir"/>
+     <arg value="-Forg.knopflerfish.junit_runner.outdir=${junit.out.dir}"/>
+     <arg value="-xargs"/>
+     <arg value="${run.test.xargs}"/>
+     <arg value="-Forg.knopflerfish.prefs.dir=${junit.out.dir}/prefs"/>
+   </java>
+ </target>
+ <target name="run-test-secure" if="run.test.secure">
+   <echo message="${run.test.msg}"/>
+   <mkdir dir="${junit.out.dir}"/>
+   <java fork="true"
+         dir="${run.test.dir}"
+         output="${junit.out.dir}/out.txt"
+         append="${run.test.append}"
+         jar="${run.test.dir}/framework.jar">
+     <arg value="-Forg.osgi.framework.security=osgi"/>
+     <arg value="-Forg.osgi.framework.storage=${junit.out.dir}/test_fwdir"/>
+     <arg value="-Forg.knopflerfish.junit_runner.outdir=${junit.out.dir}"/>
+     <arg value="-xargs"/>
+     <arg value="${run.test.xargs}"/>
+     <arg value="-Forg.knopflerfish.prefs.dir=${junit.out.dir}/prefs"/>
+   </java>
+ </target>
+
+ <target name="run-kf-tests-bare-main">
+   <antcall target="run-test">
+     <param name="run.test.msg"    value="Running the main test suite..."/>
+     <param name="run.test.append" value="false"/>
+     <param name="run.test.xargs"  value="init-tests.xargs"/>
+   </antcall>
+ </target>
+
+ <target name="run-kf-tests-bare-restart">
+   <antcall target="run-test">
+     <param name="run.test.msg"    value="Running the restart test suite, part 1..."/>
+     <param name="run.test.append" value="true"/>
+     <param name="run.test.xargs"  value="test-restart1.xargs"/>
+   </antcall>
+   <antcall target="run-test">
+     <param name="run.test.msg"    value="Running the restart test suite, part 2..."/>
+     <param name="run.test.append" value="true"/>
+     <param name="run.test.xargs"  value="test-restart2.xargs"/>
+   </antcall>
+ </target>
+
+
+ <target name="clean"
+         description="Removes all generated files and directories."
+         depends="init,clean_ant,clean_bundles_test">
+  <delete file="framework.jar"/>
+  <delete dir="${root.out.dir}"/>
+  <delete dir="jars"/>
+  <delete dir="${ant.dir}/classes"/>
+  <delete file="headless.xargs"/>
+  <delete file="minimal.xargs"/>
+  <delete file="remote-init.xargs"/>
+  <delete file="init.xargs"/>
+  <delete file="init_Windows2000.xargs"/>
+  <delete file="init_WindowsXP.xargs"/>
+  <delete file="init-tests.xargs"/>
+  <delete file="${exported.file}"/>
+  <delete file="${sources.file}"/>
+  <delete dir="${junit.out.dir}"/>
+ </target>
+
+ <target name="clean_local"
+         description="Remove all bundles built by this build-file but keep all other bundles in the jars sub-directory.">
+    <ant dir="framework"    target="clean"
+         inheritAll="false" inheritRefs="false"/>
+    <ant dir="bundles"      target="clean"
+         inheritAll="false" inheritRefs="false"/>
+    <ant dir="bundles_opt"   target="clean"
+         inheritAll="false" inheritRefs="false"/>
+    <ant target="clean_bundles_test"/>
+ </target>
+ <target name="clean_ant">
+   <ant dir="${ant.dir}"   target="clean"
+        inheritAll="false" inheritRefs="false"/>
+ </target>
+ <target name="clean_bundles_test" if="dir.bundles_test.present">
+   <ant dir="bundles_test" target="clean"
+        inheritAll="false" inheritRefs="false"/>
+ </target>
+
+
+ <target name="rebuild"
+         description="Cleans then build build all">
+    <antcall target="clean"/>
+    <antcall target="all"/>
+ </target>
+
+
+ <target name="bundle_doc"
+         description="Builds bundle specific docs">
+   <ant dir="framework"    target="framework_doc"/>
+   <ant dir="bundles"      target="bundle_doc"/>
+   <ant dir="bundles_opt"  target="bundle_doc"/>
+ </target>
+
+</project>
diff --git a/osgi/framework/TODO b/osgi/framework/TODO
new file mode 100644
index 0000000..5ed777b
--- /dev/null
+++ b/osgi/framework/TODO
@@ -0,0 +1,11 @@
+-- I = Improvement  M = Missing --
+
+I Refactor Archive.java in bundlestorage when it come to searching for entries.
+
+I Refactor classloader to better handle recursive listEntries.
+
+I Check ResolveHooks and packages lock
+
+I More SystemBundle headers
+
+ 
diff --git a/osgi/framework/build.xml b/osgi/framework/build.xml
new file mode 100644
index 0000000..1897a14
--- /dev/null
+++ b/osgi/framework/build.xml
@@ -0,0 +1,435 @@
+<?xml version="1.0"?>
+
+<project name="framework" default="all">
+
+  <!-- build properties -->
+  <property name="topdir"       location=".."/>
+  <property name="osgi.dir"     location="${topdir}"/>
+  <property name="ant.dir"      location="${topdir}/../ant"/>
+
+  <property name="root.out.dir" location="${topdir}/out"/>
+  <property name="outdir"       location="${root.out.dir}/${ant.project.name}"/>
+  <property name="classout"     location="${outdir}/classes"/>
+  <property name="classout_compact" location="${outdir}/classes_compact"/>
+  <property name="javadoc.out.dir"  location="${outdir}/javadoc"/>
+  <property name="docs.dir"     location="${root.out.dir}/doc"/>
+  <property name="outdocdir"    location="${docs.dir}/${ant.project.name}"/>
+  <!-- Location of templates used by the framework_doc-target. -->
+  <property name="frameworkdoc_template"
+            location="${ant.dir}/html_template/frameworkdoc.html"/>
+
+  <property name="fw.impl.version"   value="7.1.2"/>
+
+  <property name="jarfile"
+            location="${topdir}/${ant.project.name}.jar"/>
+  <property name="jarfile_compact"
+            location="${topdir}/${ant.project.name}_compact.jar"/>
+  <property name="source.jarfile"
+            location="${topdir}/${ant.project.name}-source.jar"/>
+  <property name="javadoc.jarfile"
+            location="${topdir}/${ant.project.name}-javadoc.jar"/>
+
+  <import file="${ant.dir}/android.xml"/>
+
+  <available property="jdk1.7+" classname="java.lang.ClassValue"/> 
+  <condition property="javac.source" value="1.5" else="1.5">
+    <isset property="jdk1.7+"/>
+  </condition>
+  <condition property="javac.target" value="1.5" else="jsr14">
+    <isset property="jdk1.7+"/>
+  </condition>
+
+  <!-- When comipling with Java 7 we must use the Java 7 runtime -->
+  <!-- since ee.minimum does not contain java.lang.Iterable. -->
+  <condition property="javac.includeJavaRuntime" value="true" else="false">
+    <isset property="jdk1.7+"/>
+  </condition>
+
+  <!-- When comipling with Java 7 we use the Java 7 runtime -->
+  <!-- as libraryjar in proguard since ee.minimum does not contain -->
+  <!-- java.lang.StringBuilder which is used by the compiler for -->
+  <!-- string concatenation in the code. -->
+  <condition property="proguard.libraryjar"
+             value="${java.home}/lib/rt.jar"
+             else="${osgi.dir}/ee/ee.minimum.jar">
+    <isset property="jdk1.7+"/>
+  </condition>
+
+    
+  <property name="src.dir" location="src"/>
+
+  <property name="printClasses" location="true"/>
+
+  <!-- Optionally used classes that is outside the OSGi foundation EE -->
+  <!-- The value must be a valid includes/exludes expression.         -->
+  <!-- Currently this are classes that references:                    -->
+  <!--        java.security.cert                                      -->
+  <property name="nonFoundationSrcs"
+            value="org/knopflerfish/framework/validator/JKSValidator.java"/>
+
+  <path id="ee.minimum.path">
+    <pathelement location="${osgi.dir}/ee/ee.minimum.jar"/>
+    <!-- Outside EE, but usefull when compling -->
+    <pathelement location="${osgi.dir}/ee/src_annotations.jar"/>
+  </path>
+
+  <path id="ee.foundation.path">
+    <pathelement location="${osgi.dir}/ee/ee.foundation.jar"/>
+    <!-- Outside EE, but usefull when compling -->
+    <pathelement location="${osgi.dir}/ee/src_annotations.jar"/>
+  </path>
+
+  <path id="compile.path">
+    <pathelement location="${topdir}/framework/resources"/>
+    <pathelement location="libs/asm-3.2.jar"/>
+  </path>
+
+  <path id="empty.path">
+  </path>
+
+  <!-- Use the Java 7 runtime when compiling with Java 7 since -->
+  <!-- ee.minimum does not provide the required Iterable interface. --> 
+  <condition property="boot.class.path.name"
+             value="empty.path"
+             else="ee.minimum.path">
+    <isset property="jdk1.7+"/>
+  </condition>
+
+
+  <!-- targets -->
+  <target name="all"
+          depends="jar, source.jar, save_javadoc_data, javadoc.jar">
+  </target>
+
+  <target name="compile">
+    <antcall target="compile_full"/>
+    <antcall target="compile_compact"/>
+  </target>
+
+  <target name        = "compile_full"
+          unless      = "compact"
+          description = "compiles all java sources">
+    <mkdir dir="${classout}"/>
+
+    <javac destdir           = "${classout}"
+           srcdir            = "${src.dir}"
+           debug             = "on"
+           includeantruntime = "false"
+           includejavaruntime= "${javac.includeJavaRuntime}"
+           includes          = "**/*.java"
+           excludes          = "${nonFoundationSrcs},**/package-info.java"
+           target            = "${javac.target}"
+           source            = "${javac.source}"
+           bootclasspathref  = "${boot.class.path.name}"
+           classpathref      = "compile.path"
+           >
+    </javac>
+    <!-- Non foundation compliant part (uses java.security.cert) -->
+    <javac destdir           = "${classout}"
+           srcdir            = "${src.dir}"
+           debug             = "on"
+           includeantruntime = "false"
+           includejavaruntime= "${javac.includeJavaRuntime}"
+           includes          = "${nonFoundationSrcs}"
+           excludes          = "**/package-info.java"
+           target            = "${javac.target}"
+           source            = "${javac.source}"
+           classpathref      = "compile.path"
+           >
+    </javac>
+  </target>
+
+  <target name="compile_compact"
+          if="compact"
+          description="compiles with file storage only">
+    <mkdir dir="${classout_compact}"/>
+
+    <javac destdir           = "${classout_compact}"
+           srcdir            = "${src.dir}"
+           debug             = "on"
+           includeantruntime = "false"
+           includejavaruntime= "${javac.includeJavaRuntime}"
+           includes          = "**/*.java"
+           excludes          = "${nonFoundationSrcs},org/knopflerfish/framework/bundlestorage/memory/SelfSignedValidator.java,org/knopflerfish/framework/bundlestorage/memory/*.java,**/package-info.java,org/knopflerfish/framework/SecurePermissionOps.java,org/knopflerfish/framework/permissions/*.java"
+           target            = "${javac.target}"
+           source            = "${javac.source}"
+           bootclasspathref  = "${boot.class.path.name}"
+           classpathref      = "compile.path"
+           >
+    </javac>
+  </target>
+
+  <target name="jar" depends="compile,genexports" description="build jar">
+    <tstamp>
+      <format property="framework.tstamp"
+              pattern="'Build' EE MMMM d yyyy, HH:mm:ss"
+              locale="en"/>
+    </tstamp>
+
+    <!-- delete in case the file is read-only -->
+    <delete file="resources/version"/>
+    <echo message="${fw.impl.version}"  file="resources/version"/>
+    <delete file="resources/tstamp"/>
+    <echo message="${framework.tstamp}" file="resources/tstamp"/>
+
+    <condition property="version.isset">
+      <isset property="version"/>
+    </condition>
+
+    <antcall target="writerelease"/>
+
+    <delete file="${classout}/classes.dex"/>
+
+    <loadfile srcfile="${src.dir}/org/osgi/framework/packageinfo"
+              property="fw.spec.version">
+      <filterchain>
+        <striplinebreaks/>
+        <replacestring from="version " to=""/>
+      </filterchain>
+    </loadfile>
+
+    <antcall target="jar_file_full"/>
+    <antcall target="jar_file_compact"/>
+
+    <antcall target="add_dex"/>
+  </target>
+
+  <target name   = "jar_file_full"
+          unless = "compact">
+    <jar basedir="${classout}"
+         filesonly="true"
+         jarfile="${jarfile}">
+      <fileset dir="resources"/>
+      <manifest>
+        <attribute name="Main-class"             value="org.knopflerfish.framework.Main"/>
+        <attribute name="Specification-Title"    value="OSGi Framework API"/>
+        <attribute name="Specification-Version"  value="${fw.spec.version}"/>
+        <attribute name="Specification-Vendor"   value="Open Service Gateway initiative"/>
+        <attribute name="Implementation-Title"   value="Knopflerfish OSGi Framework"/>
+        <attribute name="Implementation-Version" value="${fw.impl.version}" />
+        <attribute name="Implementation-Vendor"  value="Knopflerfish"/>
+        <attribute name="Bundle-Vendor"          value="Knopflerfish"/>
+        <attribute name="Bundle-Version"         value="${fw.impl.version}"/>
+        <attribute name="Bundle-SymbolicName"    value="org.knopflerfish.framework"/>
+        <attribute name="Bundle-Name"            value="frameworkbundle"/>
+        <attribute name="Bundle-Description"     value="Knopflerfish OSGi framework system bundle"/>
+        <attribute name="Bundle-License"
+                   value=""http://www.knopflerfish.org/license.html";description=BSD;link="http://www.knopflerfish.org/license.html""/>
+        <attribute name="Export-Package"         value="${fw.export-package}"/>
+        <attribute name="Bundle-DocURL"          value="http://www.knopflerfish.org/releases/current/docs/bundledoc/index.html?docpage=framework/index.html"/>
+        <attribute name="Bundle-SubversionURL"   value="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/framework/"/>
+        <attribute name="Build-Date"             value="${framework.tstamp}"/>
+        <attribute name="SplashScreen-Image"     value="kfsplash.gif"/>
+      </manifest>
+    </jar>
+  </target>
+
+  <target name = "jar_file_compact"
+          if   = "compact">
+    <jar basedir="${classout_compact}"
+         filesonly="true"
+         jarfile="${jarfile_compact}">
+      <fileset dir="resources">
+        <exclude name="kfsplash.gif"/>
+      </fileset>
+      <manifest>
+        <attribute name="Main-class"             value="org.knopflerfish.framework.Main"/>
+        <attribute name="Specification-Title"    value="OSGi Framework API"/>
+        <attribute name="Specification-Version"  value="${fw.spec.version}"/>
+        <attribute name="Specification-Vendor"   value="Open Service Gateway initiative"/>
+        <attribute name="Implementation-Title"   value="Knopflerfish OSGi Framework"/>
+        <attribute name="Implementation-Version" value="${fw.impl.version}" />
+        <attribute name="Implementation-Vendor"  value="Knopflerfish"/>
+        <attribute name="Bundle-Vendor"          value="Knopflerfish"/>
+        <attribute name="Bundle-Version"         value="${fw.impl.version}"/>
+        <attribute name="Bundle-SymbolicName"    value="org.knopflerfish.framework"/>
+        <attribute name="Bundle-Name"            value="frameworkbundle"/>
+        <attribute name="Bundle-Description"     value="Knopflerfish OSGi framework system bundle"/>
+        <attribute name="Bundle-License"
+                   value=""http://www.knopflerfish.org/license.html";description=BSD;link="http://www.knopflerfish.org/license.html""/>
+        <attribute name="Export-Package"         value="${fw.export-package}"/>
+        <attribute name="Bundle-DocURL"          value="http://www.knopflerfish.org/releases/current/docs/bundledoc/index.html?docpage=framework/index.html"/>
+        <attribute name="Bundle-SubversionURL"   value="https://www.knopflerfish.org/svn/knopflerfish.org/trunk/osgi/framework/"/>
+        <attribute name="Build-Date"             value="${framework.tstamp}"/>
+      </manifest>
+    </jar>
+    <antcall target="proguard_compact"/>
+  </target>
+
+  <target name = "proguard_compact"
+	  depends="install_proguard">
+    <move file="${jarfile_compact}" tofile="${jarfile_compact}.tmp.jar"/>
+    <proguard note="false">
+      <!-- Specify the input jars, output jars, and library jars. -->
+      <injar  file="${jarfile_compact}.tmp.jar" />
+      <outjar file="${jarfile_compact}" />
+      <libraryjar file="${proguard.libraryjar}" />
+
+      <!-- Preserve Main. -->
+      <keepclasseswithmembers access="public">
+        <method access    ="public static"
+                type      ="void"
+                name      ="main"
+                parameters="java.lang.String[]" />
+      </keepclasseswithmembers>
+
+      <!-- Keep KF dynamic  -->
+      <keep name="org.knopflerfish.framework.FrameworkFactoryImpl"/>
+      <keep name="org.knopflerfish.framework.bundlestorage.file.BundleStorageImpl">
+      	<constructor/>
+      </keep>
+
+      <!-- Keep OSGi interface -->
+      <keep name="org.osgi.**" access="public">
+      	<field access="public,protected"/>
+      	<method access="public,protected"/>
+      	<constructor access="public,protected"/>
+      </keep>
+
+      <!-- Explicitly preserve all serialization members. The Serializable
+           interface is only a marker interface, so it wouldn't save them.
+           You can comment this out if your library doesn't use serialization.
+           If your code contains serializable classes that have to be backward
+           compatible, please refer to the manual. -->
+
+      <keepclassmembers implements="java.io.Serializable">
+        <field  access    ="static final"
+                type      ="long"
+                name      ="serialVersionUID" />
+        <field  access    ="static final"
+                type      ="java.io.ObjectStreamField[]"
+                name      ="serialPersistentFields" />
+        <method access    ="private"
+                type      ="void"
+                name      ="writeObject"
+                parameters="java.io.ObjectOutputStream" />
+        <method access    ="private"
+                type      ="void"
+                name      ="readObject"
+                parameters="java.io.ObjectInputStream" />
+        <method type      ="java.lang.Object"
+                name      ="writeReplace"
+                parameters="" />
+      	<method type      ="java.lang.Object"
+                name      ="readResolve"
+                parameters="" />
+      </keepclassmembers>
+
+    </proguard>
+  	<delete file="${jarfile_compact}.tmp.jar"/>
+  </target>
+
+  <target name="source.jar" if="bundle.build.source.jar">
+    <jar basedir="${src.dir}"
+         jarfile="${source.jarfile}"
+         includes="**/*.java"
+         excludes="**/package-info.java"
+         manifestencoding="UTF-8">
+    </jar>
+  </target>
+
+  <target name="save_javadoc_data" depends="genexports"
+          if="generate.javadoc.data">
+    <echo message="save_javadoc: to:${sources.file} src:${src.dir} "/>
+    <echo file="${sources.file}" append="true"
+          message="${src.dir}${line.separator}"/>
+    <echo file="${exported.file}" append="true"
+          message="${fw.export-package}${line.separator}"/>
+  </target>
+
+  <target name="javadoc.jar" if="bundle.build.javadoc.jar">
+    <mkdir dir="${javadoc.out.dir}"/>
+
+    <property name="javadoc.header"
+              value="Knopflerfish OSGi Framework ${fw.impl.version}"/>
+
+    <property name="javadoc.footer"
+              value="Knopflerfish OSGi ${version}"/>
+
+    <property name="javadoc.windowtitle"
+              value="${javadoc.header} javadoc"/>
+
+    <property name="javadoc.doctitle"
+              value="${javadoc.header} API documentation"/>
+
+    <javadoc header="${javadoc.header}"
+             footer="${javadoc.footer}"
+             windowtitle="${javadoc.windowtitle}"
+             doctitle="${javadoc.doctitle}"
+             destdir="${javadoc.out.dir}"
+             classpathref="compile.path">
+      <!-- Custome tags used by OSGi -->
+      <tag name="ThreadSafe"    scope="all" description="ThreadSafe"/>
+      <tag name="NotThreadSafe" scope="all" description="NotThreadSafe"/>
+      <tag name="Immutable"     scope="all" description="Immutable"/>
+      <tag name="security"      scope="all" description="Required Permissions"/>
+      <tag name="noimplement"   scope="all"
+           description="Consumers of this API must not implement this interface"/>
+      <packageset dir="${src.dir}">
+        <include name="org/osgi/**"/>
+        <exclude name="org/knopflerfish/**"/>
+      </packageset>
+
+    </javadoc>
+
+    <jar basedir="${javadoc.out.dir}"
+         jarfile="${javadoc.jarfile}"
+         includes="**"
+         manifestencoding="UTF-8">
+    </jar>
+  </target>
+
+
+  <!-- Helper taget that adds Android dex data to framework.jar. -->
+  <target name="add_dex" if="android.exists">
+    <echo message="add_dex ${jarfile}"/>
+    <add_dex jarfile="${jarfile}" outdir="${outdir}"/>
+  </target>
+
+  <target name="framework_doc"
+          depends="bundle_tasks,genexports">
+    <property name="bmfa.Bundle-Version" value="${fw.impl.version}"/>
+    <property name="bmfa.Export-Package" value="${fw.export-package}"/>
+    <makehtml template="${frameworkdoc_template}"
+              outdir="${outdocdir}"
+              manstyle="true">
+      <fileset dir="doc">
+        <include name="**/*.html"/>
+      </fileset>
+    </makehtml>
+
+    <copy todir="${outdocdir}">
+      <fileset dir="doc">
+        <exclude name="**/*.html"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="run">
+    <java fork="true"
+          jar="${outdir}/${ant.project.name}.jar"
+          />
+  </target>
+
+  <target name="writerelease" if="version.isset">
+    <delete file="resources/release"/>
+    <echo message="${version}" file="resources/release"/>
+  </target>
+
+  <target name="genexports" depends="bundle_tasks">
+    <delete file="resources/exports"/>
+    <bundleinfo  exports  = "fw.export-package"
+                 addPackageinfoPackages = "true" >
+     <exports dir="src" includes="org/osgi/**"/>
+    </bundleinfo>
+    <echo message="${fw.export-package}" file="resources/exports"/>
+  </target>
+
+  <target name="clean" description="removes all generated files">
+    <delete dir="${outdir}"/>
+    <delete file="${jarfile}"/>
+  </target>
+
+  <import file="${topdir}/../ant/bundletasks.xml"/>
+
+</project>
diff --git a/osgi/framework/doc/doc.properties b/osgi/framework/doc/doc.properties
new file mode 100644
index 0000000..e116a56
--- /dev/null
+++ b/osgi/framework/doc/doc.properties
@@ -0,0 +1,3 @@
+# Framwork user documentation properties
+category: framework
+title: Framework
diff --git a/osgi/framework/doc/index.html b/osgi/framework/doc/index.html
new file mode 100644
index 0000000..588b4c0
--- /dev/null
+++ b/osgi/framework/doc/index.html
@@ -0,0 +1,1177 @@
+<h1>Knopflerfish OSGi framework</h1>
+
+<div class="abstract">
+  This is the Knopflerfish framework. An OSGi Release 5
+  compliant framework. It supports all optional and deprecated
+  framework services, Package Admin, Start Level,
+  Conditional Permission Admin, Permission Admin, URL Handlers,
+  Bundle Hook, Resolver Hook, Service Hook and Weaving Hook.
+</div>
+
+<h2>Contents</h2>
+  <ol>
+    <li><a href="#startup">Knopflerfish framework.jar startup</a></li>
+    <li><a href="#init_restart">Initial start vs restart</a></li>
+    <li><a href="#framework">Starting the framework</a></li>
+    <li><a href="#framework_compact">Starting the compact framework</a></li>
+    <li><a href="#xargs">Default selection of .xargs</a></li>
+    <li><a href="#proxy">Using a HTTP proxy</a></li>
+    <li><a href="#props">Framework and System Properties</a></li>
+    <li><a href="#osgiprop">OSGi Specified Framework Properties</a></li>
+    <li><a href="#kfsysprop">Knopflerfish Specified System Properties</a></li>
+    <li><a href="#kffwprop">Knopflerfish Specified Framework Properties</a></li>
+  </ol>
+<a name="startup"></a>
+<h2>Knopflerfish framework.jar startup</h2>
+<p>
+This is a startup guide for the KF OSGi framework. Note that
+command-line startup of the framework is not specified by OSGi, and
+system integrators often need to create a wrapper script for FW
+startup.
+</p>
+<p>
+The KF Main startup class is primarily intended to be used in scenarios
+where current working directory is same as the one containing framework.jar,
+the framework storage directory and configuration files. In these cases
+</p>
+<p>
+<pre class="shell">java -jar framework.jar</pre>
+</p>
+<p>
+...is often enough. 
+</p>
+<p>
+To use features that requires JVM restart, e.g. extension bundles, 
+you can use our example shell start script "kf2". Open a terminal and type
+</p>
+<p>
+<pre class="shell">./kf2</pre>
+</p>
+<p>
+Note: the script requires a "sh" shell. 
+</p>
+<p>
+Other uses are possible, but require options and possibly some tweaking
+of the default startup files.
+</p>
+
+<a name="init_restart"></a>
+<h2>Initial start vs restart</h2>
+<p>
+Two cases of framework startup should be noted:
+</p>
+<ol>
+  <li>Initial, bootstrap, startup<br/>
+    An initial startup must contain enough options
+    to install bundles allowing further management, using 
+    -install options. If no bundles are installed, an empty 
+    framework will be started but nothing can be done with it..
+  </li>
+  <li>Restart of previously initialized framework<br/>
+    Any OSGi framework can remember its state from previous startup.
+    <br/>
+    In this case, startup options should only contains system properties
+    and a -launch option for restarting the bundles, but not any
+    -install options.
+  </li>
+ </ol>
+<p>
+ NB! Framework properties (-Fx=y) supplied at initial startup are saved as
+ part of the framework state, and need not to be supplied again at framework
+ restart. System properties (-Da=b) are not included in the framework state.
+ Since the two different startup cases probably will use separate startup
+ files, care must be taken so system properties are set correctly in both
+ files, when so required.
+</p>
+
+<p>
+</p>
+<p>
+It is up to a system integrator to decide when to use initial startup
+or restart. The Main KF class can help somewhat in doing this (see below)
+but might not be enough. In those cases, wrapper scripts, or modifications
+to Main.java are recommended.
+</p>
+
+<a name="framework"></a>
+<h2>Starting the framework</h2>
+<p>
+The framework can be started using the startup wrapper class
+</p>
+<p>
+<pre class="shell">org.knopflerfish.framework.Main</pre>
+</p>
+<p>
+This class is also set a Main-Class in framework.jar's manifest, meaning 
+framework.jar can be started using 
+</p>
+<p>
+<pre class="shell"> java -jar framework.jar [options] OR ./kf2 [options]</pre>
+</p>
+<p>
+The Main class supports a number of options, which can be displayed
+using:
+</p>
+<p>
+<pre class="shell">java -jar framework.jar -help OR ./kf2 -help</pre>
+</p>
+<p>
+Options can also be specified using the -xargs option, which specifies
+a .xargs text file containing lines of new options. Typically all
+options are specified in .xargs files. Combining .xargs files and
+command line options is possible. .xargs files can also use recursive
+.xargs files.
+</p>
+<p>
+When the framework is started, it uses a file system directory for
+storing the state of all installed bundles, "fwdir". The default
+directory used for this is:
+</p>
+<p>
+<pre class="shell">fwdir</pre>
+</p>
+<p>
+in the current directory. The "fwdir" directory can also be set
+specifically using the org.osgi.framework.storage property. Note that
+moving "fwdir" also changes the location for searching for default
+.xargs files.
+</p>
+<p>
+If no options are specified (any "-Fx=y", "-Da=b" or "-init" does not
+count as options in this case) an implicit
+</p>
+<p>
+<pre class="shell">-xargs "default"</pre>
+</p>
+<p>
+is added to the options. "default" means that the default .xargs (see
+below) is selected.
+</p>
+
+<a name="framework_compact"></a>
+<h2>Starting the compact framework</h2>
+<p>
+There is a compact version of the framework available for system that
+has limited amount of resources (memory and storage). This version
+doesn't contain any support for security and certificates. The internal
+classes has also been name mangled to save resources.
+</p>
+<p>
+The compact framework is started and controlled in the same way as the
+full version. The only difference is that the jar file is called
+<code>framework_compact.jar</code>.
+</p>
+
+<a name="xargs"></a>
+<h2>Default selection of .xargs</h2>
+<p>
+If _no_ args are supplied (arguments of the form "-Fx=y", "-Da=b" or
+"-init" does not count in this case), or a name of "default" is given
+as -xargs argument, a default .xargs file will be searched for, by the
+following algorithm:
+</p>
+<ol>
+  <li>If there exists a previous "fwdir" AND previous options
+      does not contain "-init", use a file in "fwdir" named:<br/>
+    <pre class="shell">fwprops.xargs</pre>
+  </li>
+  <li>If no fwdir exist, OR options contain an "-init", 
+       search for a file named:
+    <ol style="list-style-type:lower-latin">
+      <li>init_[osname].xargs</li>
+      <li>init.xargs</li>
+      <li>remote-init.xargs</li>
+    </ol>
+    The search is performed in the following directories:
+    <ol style="list-style-type:lower-latin">
+      <li>fwdir</li>
+      <li>The parent directory of fwdir (if any)</li>
+      <li>The current working directory</li>
+    </ol>
+    First match wins.<br/>
+    The [osname]-part of the file name is the unified OS name as
+    specified in Alias.java (see below). Case is important if the file
+    system is case sensitive.<br/>
+    OS aliases:
+    <ul>
+      <li>OS2</li>
+      <li>QNX</li>
+      <li>Windows95</li>
+      <li>Windows98</li>
+      <li>WindowsNT</li>
+      <li>WindowsCE</li>
+      <li>Windows2000</li>
+      <li>WindowsXP</li>
+    </ul>
+  </li>
+</ol>
+<p>
+The file fwdir/fwprops.xargs contains saved properties that is used
+when restarting a framework instance. It is written by the Knopflerfish
+framework on every startup (unless disabled by setting the property
+"org.knopflerfish.framework.write.restart.xargs" to false).
+</p>
+
+<a name="proxy"></a>
+<h2>Using a HTTP proxy</h2>
+<p>
+The standard JVM system properties
+</p>
+<ul>
+ <li>http.proxyHost</li>
+ <li>http.proxyPort</li>
+ <li>http.nonProxyHosts</li> 
+</ul>
+<p>
+should be used to set proxy information. This will be global to 
+all HTTP request from all bundles and the framework.
+</p>
+<p>
+Additionally, the KF-specific system property
+</p>
+<ul>
+ <li>http.proxyAuth</li>
+</ul>
+<p>
+can be set to a value on the form user:password
+</p>
+<p>
+If set to non-empty, this will add the 
+Proxy-Authorization header to bundle install http/https requests 
+made from the framework, However, bundles using the URL class internally
+must explicitly set this header themselves.
+</p>
+
+<a name="props"></a>
+<h2>Framework and System Properties</h2>
+<p>
+Both Framework and Java System properties are used to control the framework.
+</p>
+<p>
+Framework properties are the standard properties listed in the OSGi
+specification (section 4.5.3 in r4.core) and proprietary properties for
+the Knopflerfish framework. Framework properties are also used for
+configuration of Knopflerfish bundles. 
+</p>
+<p>
+Framework properties are specified on the command line or in .xarg files
+using "-F". If you have more than one framework instance, each instance
+has its own set of Framework properties.
+</p>
+<p>
+A framework property is accessed by using
+<pre class="shell">org.osgi.framework.BundleContext.getProperty(String)</pre>.
+</p>
+<p>
+Java System properties are specified on the command line or in .xargs
+files using "-D". System properties are accessed using
+<pre class="shell">java.lang.System.getProperty(String)</pre> but
+<pre class="shell">BundleContext.getProperty</pre> can also be used as it will look
+for a System property if there is no matching Framework property.
+</p>
+<p>
+Because of the different handling of Framework and System properties when
+the framework is <a href="#init_restart">restarted</a>, it is recommended
+to use only Framework properties in .xargs files. If you do, and use the
+default init.xargs/props.xargs files, initial starts and restarts become
+conveniently short on the command line:
+</p>
+<p>
+<pre class="shell">java -jar framework.jar -init  </pre> (initial start)
+</p>
+<p>
+<pre class="shell">java -jar framework.jar  </pre> (restart)
+</p>
+<p>
+Unfortunately, it is not always possible to avoid using Java System
+properties. For example, a bundle may include a class library that uses
+System properties for configuration. Also, properties that are read
+during start-up, before the framework has been initialized, need to be
+System properties, see <a href="#kfsysprop">KF System Properties</a>.
+</p>
+<a name="osgiprop"></a>
+<h2>OSGi Specified Framework Properties</h2>
+<p>
+OSGi Framework properties should be specified using "-F".
+</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.bootdelegation</td>
+    <td>
+      Set the boot delegation mask. A list of packages delegated from the
+      framework to the parent classloader. The package specified can contain
+      a wildcard at the end, which matches any sub-packages.
+    </td>
+    <td>String , ...</td>
+    <td></td>
+  </tr>
+  <tr>
+	<td>org.osgi.framework.bsnversion</td>
+	<td>
+	  Allow installation of multiple bundles with the same bundle symbolic
+	  name or restrict this. The property can have the following values:
+      <table class="man_inner">
+      <tr>
+	    <td class="man_inner"><b>single</b></td>
+        <td class="man_inner">
+          A combination of equal bundle symbolic name and equal version is
+          unique in the framework. Installing a second bundle with the same
+          bundle symbolic name and version is an error.
+        </td>
+      </tr>
+      <tr>
+        <td class="man_inner"><b>multiple</b></td>
+        <td class="man_inner">
+          The combination of bundle symbolic name and version is not unique
+          in the framework.
+        </td>
+      </tr>
+      <tr>
+	    <td class="man_inner"><b>managed</b></td>
+        <td class="man_inner">
+          Using a Bundle Collision Hook to filter any non-colliding bundles.
+        </td>
+      </tr>
+      </table>
+	</td>
+    <td>String</td>
+    <td>managed</td>	
+  <tr>
+    <td>org.osgi.framework.bundle.parent</td>
+    <td>
+      This property is used to specify what class loader is used for 
+      boot delegation. That is, java.* and the packages specified on 
+      the org.osgi.framework.bootdelegation.
+      This property can have the following values: boot, app, ext or
+      framework.
+    </td>
+    <td>String</td>
+    <td>boot</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.command.execpermission</td>
+    <td>
+      Specifies an optional OS specific command to set file permissions
+      on a bundle's native code. This is required on some operating
+      systems to use native libraries. For example, on a UNIX 
+      style OS you could have the following value: 
+      org.osgi.framework.command.execpermission="chmod +rx ${abspath}" 
+      The ${abspath} macro will be substituted for the actual file 
+      path. 
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.executionenvironment</td>
+    <td>
+      The current execution environment. There are no restriction on
+      the execution environment if this property isn't set.
+    </td>
+    <td>String</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.language</td>
+    <td>
+      The language used by the framework for the selection of 
+      native code.
+    </td>
+    <td>String</td>
+    <td>Set based on default locale</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.library.extensions</td>
+    <td>
+      A comma separated list of additional library file extensions that
+      must be used when searching for native code. If not set, then only
+      the library name returned by System.mapLibraryName(String) will be
+      used. This list of extensions is needed for certain operating
+      systems which allow more than one extension for native libraries.
+      For example, the AIX operating system allows library extensions of
+      .a and .so, but System.mapLibraryName(String) will only return
+      names with the .a extension.
+    </td>
+    <td>String , ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.os.name</td>
+    <td>
+      The name of the operating system as used in the native code clause.
+    </td>
+    <td>String</td>
+    <td>Set based on system property os.name</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.os.version</td>
+    <td>
+      The version of the operating system as used in the native code 
+      clause.
+    </td>
+    <td>String</td>
+    <td>Set based on system property os.version</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.os.processor</td>
+    <td>
+      The name of the processor as used in the native code clause.
+    </td>
+    <td></td>
+    <td>Set based on system property os.arch</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.security</td>
+    <td>
+      Specifies the type of security manager the framework must 
+      use. If not specified then the framework will not set the VM 
+      security manager. The following type is architected: 
+      <code>osgi</code> Enables a security manager that supports all 
+      security aspects of the OSGi Release 4 specifications 
+      (including postponed conditions). 
+      If specified, and there is a security manager that doesn't
+      match already installed, then a SecurityException is thrown
+      when the Framework is initialized. 
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.startlevel.beginning</td>
+    <td>
+      Specifies the beginning start level of the framework.
+    </td>
+    <td>Integer</td>
+    <td>1</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.storage</td>
+    <td>
+      Where we store persistent data.
+
+      On systems not supporting a current working directory,
+      as Pocket PC, this path should be set to an explicit
+      full path.
+
+      Note: Knopflerfish 1.x and 2.x used the name
+      "org.osgi.framework.dir" for this property.
+    </td>
+    <td>String</td>
+    <td>${currentWorkingDirectory}/fwdir</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.storage.clean</td>
+    <td>
+      Specifies if and when the storage area for the framework 
+      should be cleaned. If no value is specified, the framework storage
+      area will not be cleaned. The possible values is: 
+      <code>onFirstInit</code> - The framework storage area will be
+      cleaned  before the Framework bundle is initialized for the first 
+      time. Subsequent inits, starts or updates of the Framework bundle
+      will not result in cleaning the framework storage area.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.system.packages</td>
+    <td>
+      Complete list of packages exported by the system bundle.
+
+      If not set the framework will export all OSGi packages and all
+      standard Java packages according to the version of the running
+      JRE. See also "org.knopflerfish.framework.system.packages.base"
+      and "org.osgi.framework.system.packages.extra"
+    </td>
+    <td>String , ...</td>
+    <td>Default is based on other properties</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.system.packages.extra</td>
+    <td>
+      Packages to add to the default list of packages exported by the
+      system bundle.
+    </td>
+    <td>String , ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.trust.repositories</td>
+    <td>
+      This property is used to configure trust repositories for the 
+      framework. The value is path of files.The file paths are separated
+      by the pathSeparator defined in the File class. Each file path
+      should point to a JKS key store. The framework will use the key
+      stores as trust repositories to authenticate certificates of
+      trusted signers. The key stores must only be used as read-only
+      trust repositories to access public keys. The keystore must not
+      have a password.
+    </td>
+    <td>String : ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.osgi.framework.windowsystem</td>
+    <td>
+      Provide the name of the current window system. This can be used by
+      the native code clause.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+</table>
+
+
+<a name="kfsysprop"></a>
+<h2>Knopflerfish Specified System Properties</h2>
+<p>
+Knopflerfish System properties should be specified using "-D".
+</p>
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.verbosity</td>
+    <td>
+     Verbosity level of the Main class starting the framework. 0 means
+     few messages. Specify on the command line in order to see messages
+     from the very beginning.
+    </td>
+    <td>Integer</td>
+    <td>0</td>
+  </tr>
+</table>
+
+<a name="kffwprop"></a>
+<h2>Knopflerfish Specified Framework Properties</h2>
+<p>
+The recommendation is to use "-F" for Knopflerfish Framework properties
+but "-D" should also work. 
+</p>
+
+<table class="man">
+  <tr>
+    <th>Name</th>
+    <th>Description</th>
+    <th>Value type</th>
+    <th>Default value</th>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.all_signed</td>
+    <td>
+      If set to true, we require that all bundles that are installed are signed.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.automanifest</td>
+    <td>
+      Flag to enable automatic manifest generation. If true, bundle
+      manifest can be modified by a special configuration file. See
+      javadoc for org.knopflerfish.framework.AutoManifest class 
+      for details.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.automanifest.config</td>
+    <td>
+      Configuration URL for automatic manifest generation. Only
+      valid if org.knopflerfish.framework.automanifest=true.
+      An URL starting with "!!" followed by path is refer to a resource
+      on the classloader that have loaded the framework.
+    </td>
+    <td>String</td>
+    <td>!!/automanifest.props</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage</td>
+    <td>
+      Storage implementation for bundles
+      [file, memory]
+    </td>
+    <td>String</td>
+    <td>file</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.always_unpack</td>
+    <td>
+     When using file bundle storage, bundle jars can be unpacked
+     or copied as-is. Unpacking leads to faster restart and class loading
+     but takes longer for initial startup.
+
+     If set to true, unpack all bundle jars.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.jar_verifier_bug</td>
+    <td>
+     There is a bug when using file bundle storage, certificate and Oracle
+     JRE (Java 6). This bug causes the JarInputStream to miss picking up
+     certificates for files under the "META-INF" directory if they directly
+     follow the META-INF signature related files. This causes KF to mark
+     the bundle as not completly signed. To ignore problem set property
+     to true.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <a name="fileref"></a>
+    <td>org.knopflerfish.framework.bundlestorage.file.reference</td>
+    <td>
+     When using file bundle storage, file: URLs can optionally
+     be referenced only, not copied to the persistent area.
+
+     If set to true, file: URLs are referenced only.
+
+     Note: Individual bundles can be reference installed
+           by using URLs of the syntax:
+
+           reference:file:<path>
+
+           This works even if the global reference flag
+           is not enabled.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.trusted</td>
+    <td>
+     Are the bundles stored in the file bundle storage to be trusted, if not
+     signed bundles will be checked every time they are read.
+     Untrusted storage leads to slower restart and class loading.
+
+     If set to true, trust bundles in bundle storage.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlestorage.file.unpack</td>
+    <td>
+     Most JVM requires that we unpack the bundle to access internal jars
+     and native code. Setting this to true will unpack the jar if it contains
+     internal jars or native code.
+
+     If set to true, unpack needed bundle jars.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlethread.timeout</td>
+    <td>
+     Use this proprty to set a limit on how long the framework will wait for a
+     bundle's activator to complete and return from the start and stop methods.
+     If the time-out occurs, the framework will interrupt the BundleThread that
+     is executing the start or stop method and then optionally stop it or lower
+     its priority, see property org.knopflerfish.framework.bundlethread.abort.
+     A BundleException is thrown to indicate that start/stop of the bundle
+     failed.
+
+     If set to a positive integer, the value is used as time-out in seconds.
+     If set to 0, no time out is used and the framework will wait indefinitely
+     for the activator's start and stop methods to complete.
+    </td>
+    <td>Integer</td>
+    <td>0</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.bundlethread.abort</td>
+    <td>
+      If a bundle's start or stop method time-out (see property
+      org.knopflerfish.framework.bundlethread.timeout) or if the bundle gets
+      uninstalled before the method has returned, this property defines how to
+      manage the bundle's start/stop thread. Possible values are:
+      <table class="man_inner">
+	<tr>
+	  <td class="man_inner">"stop"</td>
+	  <td class="man_inner">Calls the stop() method of the bundle's thread</td>
+	</tr>
+	<tr>
+	  <td>"minprio"</td>
+	  <td>Sets a minium priority of the bundle's thred</td>
+	</tr>
+	<tr>
+	  <td>"ignore"</td>
+	  <td>Do nothing</td>
+	</tr>
+      </table>
+    </td>
+    <td>String</td>
+    <td>ignore</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.automanifest</td>
+    <td>
+      Print debug output for automatic manifest actions.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.bundle_resource</td>
+    <td>
+     When security is enabled, print information about resource
+     lookups that are rejected due to missing permissions for the
+     calling bundle.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.certficates</td>
+    <td>
+     Print debug information about certificate handling.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.classloader</td>
+    <td>
+     Print debug information from classloader
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.errors</td>
+    <td>
+     Print all FrameworkEvents of type ERROR
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.framework</td>
+    <td>
+     Print debug information about life-cycle events for the
+     current framework instance.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.hooks</td>
+    <td>
+     Print debug information about when service hooks are used
+     current framework instance.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.ldap</td>
+    <td>
+     Print debug information about LDAP filters
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.resolver</td>
+    <td>
+     Print debug information about resolver operation.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.patch</td>
+    <td>
+     Print debug information about class patching
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.permissions</td>
+    <td>
+     Print debug information about permission evaluation.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.print_with_do_privileged</td>
+    <td>
+     Surround all debug print-operations originating from
+     setting org.knopflerfish.debug.* properties with a
+     doPrivileged() wrapper.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.startlevel</td>
+    <td>
+     Print debug information about startlevel service
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.service_reference</td>
+    <td>
+     When security is enabled, print information about service
+     reference lookups that are rejected due to missing permissions
+     for calling bundle.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.debug.url</td>
+    <td>
+      Print debug information about URL services
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.is_doublechecked_locking_safe</td>
+    <td>
+     Is it safe to use double-checked locking or not.
+     It is safe if JSR 133 is included in the running JRE. I.e., for
+     Java SE if version is 1.5 or higher.
+    </td>
+    <td>Boolean</td>
+    <td>
+      True if value of the system property java.version ≥ 1.5,
+      False otherwise
+    </td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.ldap.nocache</td>
+    <td>
+     Disable LDAP caching for simple filters. LDAP caching
+     speeds up framework filters considerably, but uses
+     more memory.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.class.activation</td>
+    <td>
+      A comma-separated list of locations of bundles whose Main-Class
+      (set in manifest) should be used as activator if no
+      BundleActivator is specified. 
+      The Main-Class will be used as activator if and only if the jar
+      file does not specify a Bundle-Activator header and the bundle's
+      location(see Bundle.getLocation) is found in the comma-separated
+      list (case-sensitive). 
+<pre class="man">
+> java -jar framework.jar
+    -Forg.knopflerfish.framework.main.class.activation=\ 
+    file:/foo/bar.jar,http://foo.com/bar.jar ...
+</pre>
+      </pre>
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.verbosity</td>
+    <td>
+     Verbosity level of the Main class starting the framework. 0 means
+     few messages. Specify as a System property on the command line
+     in order to see messages from the very beginning.
+    </td>
+    <td>Integer</td>
+    <td>0</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.xargs.writesysprops</td>
+    <td>
+      Properties defined using -Fname=value in xargs-files are available
+      for bundles using BundleContext.getProperty(name).
+      This property controls weather such properties shall also be
+      exported as system properties or not.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.listener.n_threads</td>
+    <td>
+    Number of threads used to deliver events to asynchronous listeners.
+    If the value is 0 then we will revert to the old behaviour and call
+    all listeners synchronously.
+    </td>
+    <td>Integer</td>
+    <td>1</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch</td>
+    <td>
+      If true AND once the classpatcher_all-N.N.N.jar bundle is installed and started,
+      run time class patching will be enabled for all classes loaded afterwards. 
+
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch.configurl</td>
+    <td>
+     URL to class patch config file. Only used when class patching is enabled.
+     This is used as a fallback if a bundle does not specify a
+     Bundle-ClassPatcher-Config manifest header.
+
+     "!!" is used to read resources from the system class path
+     "!" can be used to read bundle resources.
+    </td>
+    <td>String</td>
+    <td>!!/patches.props</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch.dumpclasses</td>
+    <td>
+     If true and class patching is enabled, dump all modified classes
+     to a directory.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.patch.dumpclasses.dir</td>
+    <td>
+      If dumpclasses is enabled, specifies a directory where to dump
+      modified classes
+    </td>
+    <td>String</td>
+    <td>patchedclasses</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.readonly</td>
+    <td>
+      Controls if the framework should skip saving state changes
+      permantly under framework directory. This means that if we are
+      running with the default "file" bundle storage then new bundles
+      must be installed as a referenced file URL (see property
+      <a href="#fileref">org.knopflerfish.framework.bundlestorage.file.reference</a>).
+      This also implies that no data storage will be available to bundles.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.service.conditionalpermissionadmin</td>
+    <td>
+      Controls if the framework should register the Conditional Permission
+      Admin service.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.service.permissionadmin</td>
+    <td>
+      Controls if the framework should register the Permission
+      Admin service.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.strictbootclassloading</td>
+    <td>
+      If set to true, use strict rules for loading classes from the boot class loader.
+      If false, accept class loading from the boot class path from classes themselves
+      on the boot class, but which incorrectly assumes they may access all of the boot
+      classes on any class loader (such as the bundle class loader).
+      Setting this to true will, for example, result in broken serialization on the Sun 
+      JVM if bootdelegation does not exposes sun.* classes
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.system.packages.base</td>
+    <td>
+     An alternative to setting org.osgi.framework.system.packages.
+     When this property is used the list of packages given will be
+     appended with the default set of osgi-packages for the current
+     framework and then used as the exports of the system bundle.
+    </td>
+    <td>String , ...</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.system.packages.file</td>
+    <td>
+      File containing list of packages exported by the system bundle.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.system.packages.version</td>
+    <td>
+      Name for selected exporting profile of system packages.
+    </td>
+    <td>String</td>
+    <td>MAJOR.MINOR from system property "java.version"</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.usingwrapperscript</td>
+    <td>
+      If set to "true", KF will assume that it has been
+      started with the "kf2" shell script, and that it will be 
+      restarted if KF exits with exit code = 200. Required to be 
+      able to use new KF2 features such as extension bundles. 
+      This flag is set to "true" by the "kf2" shell script.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator</td>
+    <td>
+      A list of which certificate validators to use. Currently available are
+      JKSValidator and SelfSignedValidator. If no validator is to be used,
+      set to "null" or "none".
+    </td>
+    <td>String</td>
+    <td>JKSValidator if org.osgi.framework.trust.repositories Is set, otherwise none</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.date</td>
+    <td>
+      Date to use when validating certificates. The date is specifed
+      in the current locales short date format. If no date is specified
+      use the current date and time.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.jks.ca_certs</td>
+    <td>
+      File name of java keystore used by JKSValidator. Used if
+      org.osgi.framework.trust.repositories isn't set.
+    </td>
+    <td>String</td>
+    <td>$JAVA_HOME/lib/security/cacerts</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.jks.ca_certs_password</td>
+    <td>
+      Password to java keystore used by JKSValidator.
+    </td>
+    <td>String</td>
+    <td>changeit</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.validator.jks.cert_provider</td>
+    <td>
+      Provider for CertificateFactory to use.
+    </td>
+    <td>String</td>
+    <td>-</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.framework.main.write.fwprops.xargs</td>
+    <td>
+      Property that tells the Knopflerfish Main if it shall write a
+      fwprops.xargs file with all framework properties inside the
+      framework directory on startup or not.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.gosg.jars</td>
+    <td>
+     Semicolon separated list of base URLs for relative install commands
+    </td>
+    <td>URL;...</td>
+    <td>URLs to the "jars" folder and all its sub-folders and
+        fwresource:jars/</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.startlevel.compat</td>
+    <td>
+      Set to true indicates startlevel compatibility mode.
+      All bundles and current start level will be 1.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.startlevel.use</td>
+    <td>
+      Use the Start Level service. If start level is not used then
+      we do not create a non daemon thread that will keep a JVM
+      with only daemon threads alive.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.osgi.setcontextclassloader</td>
+    <td>
+     If set to "true", set the bundle startup thread's context class
+     loader to the bundle's class loader. This is useful for checking
+     if an external lib will work better with a wrapped startup. It
+     doesn't set the context classloader for event callbacks.
+
+     Note that setting the context classloader is not mandated
+     by OSGi, and might introduce dependencies on the KF framework,
+     so this flag should only be enabled for testing purposes.
+    </td>
+    <td>Boolean</td>
+    <td>False</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.servicereference.valid.during.unregistering</td>
+    <td>
+      If set to false, then the service reference can not be used to
+      fetch an instance of the service during delivery and handling of
+      the UNREGISTERING service event. The behaviour specified in the
+      OSGi R4 v4.0.1 specification (and later), according to a
+      clarification done by CPEG February 2008, is that it shall be
+      possible to obtain a service instance during delivery of
+      UNREGISTERING events thus this property now defaults to true.
+
+      <p>Note that independent of this setting the service reference
+      of an UNREGISTERING service will not be returned by any of the
+      methods searching for service references provided by the
+      BundleContext interface.
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+  <tr>
+    <td>org.knopflerfish.osgi.registerserviceurlhandler</td>
+    <td>
+      Flag for installing OSGi service based URL handlers. 
+      Since the URL handler can only be installed once, there
+      might be cased where some external entity (not OSGi)
+      sets this. In this case, the OSGi handler can be disabled
+      by setting 
+    </td>
+    <td>Boolean</td>
+    <td>True</td>
+  </tr>
+</table>
diff --git a/osgi/framework/libs/asm-license.txt b/osgi/framework/libs/asm-license.txt
new file mode 100644
index 0000000..a4ae90b
--- /dev/null
+++ b/osgi/framework/libs/asm-license.txt
@@ -0,0 +1,32 @@
+This is the Licence for the ASM library, from http://asm.ow2.org/
+----------------------------------------------------------------------
+
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the copyright holders 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.
diff --git a/osgi/framework/resources/META-INF/services/org.osgi.framework.launch.FrameworkFactory b/osgi/framework/resources/META-INF/services/org.osgi.framework.launch.FrameworkFactory
new file mode 100644
index 0000000..e980566
--- /dev/null
+++ b/osgi/framework/resources/META-INF/services/org.osgi.framework.launch.FrameworkFactory
@@ -0,0 +1 @@
+org.knopflerfish.framework.FrameworkFactoryImpl
diff --git a/osgi/framework/resources/automanifest.props b/osgi/framework/resources/automanifest.props
new file mode 100644
index 0000000..76b62bf
--- /dev/null
+++ b/osgi/framework/resources/automanifest.props
@@ -0,0 +1,17 @@
+#
+# Configuration file for automatic manifest generation. 
+#
+# See javadoc for org.knopflerfish.framework.AutoManifest for documentation
+#
+
+
+
+# Section that will set all bundles to export all of their
+# packages automatically, and dynamically import *
+
+0.match.filter=(location=*)
+0.export.filter=(pkg=*)
+0.export.file.filter=(file=*.class)
+0.header.DynamicImport-Package=*
+0.header.Import-Package=[remove]
+0.header.Export-Package=[autoexport]
diff --git a/osgi/framework/resources/exports b/osgi/framework/resources/exports
new file mode 100644
index 0000000..7530dfa
--- /dev/null
+++ b/osgi/framework/resources/exports
@@ -0,0 +1 @@
+org.osgi.framework;version=1.7.0,org.osgi.framework.hooks.bundle;version=1.1.0,org.osgi.framework.hooks.resolver;version=1.0.0,org.osgi.framework.hooks.service;version=1.1.0,org.osgi.framework.hooks.weaving;version=1.0.0,org.osgi.framework.launch;version=1.1.0,org.osgi.framework.namespace;version=1.0.0,org.osgi.framework.startlevel;version=1.0.0,org.osgi.framework.wiring;version=1.1.0,org.osgi.resource;version=1.0.0,org.osgi.service.condpermadmin;version=1.1.1,org.osgi.service.packageadm [...]
\ No newline at end of file
diff --git a/osgi/framework/resources/framework.policy b/osgi/framework/resources/framework.policy
new file mode 100644
index 0000000..dc85222
--- /dev/null
+++ b/osgi/framework/resources/framework.policy
@@ -0,0 +1,3 @@
+grant {
+  permission java.security.AllPermission;
+};
diff --git a/osgi/framework/resources/help.txt b/osgi/framework/resources/help.txt
new file mode 100644
index 0000000..d6782e6
--- /dev/null
+++ b/osgi/framework/resources/help.txt
@@ -0,0 +1,52 @@
+ Usage:  java [properties] org.knopflerfish.framework.Main [options]
+      or java [properties] -jar framework.jar [options]
+      or java [properties] -jar framework_compact.jar [options]
+      or ./kf2 [options] [-- [properties]]  [--- [extra]] (*)
+
+ Options:
+   -exit          Exit the JVM process
+   -help          Print this text and exit
+   -version       Print version and exit
+   -jvminfo       Print system and framework properties and exit
+   -sleep SEC     Sleep a while before next command.
+   -xargs file    Load more command line arguments from file, exit if file
+                  cannot be loaded.
+   --xargs file   Load more command line arguments from file, continue 
+                  if file cannot be loaded (but print error)
+
+   -create        Create and initialize a new framework instance
+                  after a shutdown. The default is to reuse the old
+                  framework instance.
+   -ff FF         Specify the name of the FrameworkFactory to use when
+                  creating the framework instance.
+   -init          Start an empty platform (i.e., clear old presistent data).
+   -launch        Launch framework (i.e., start it).
+   -shutdown mSEC Shutdown framework, timeout in milliseconds.
+
+   -install URL   Install a bundle
+   -istart URL    Install and start bundle according to activation policy.
+   -start ID      Start bundle (according to its activation policy)
+   -start_e ID    Start bundle eagerly (i.e., ignore its activation policy)
+   -start_et ID   Start bundle eagerly and transiently
+   -start_pt ID   Start bundle transiently according to policy
+   -stop ID       Stop bundle
+   -stop_t ID     Stop bundle transiently (i.e, non-persistent stop)
+   -uninstall ID  Uninstall a bundle
+   -update ID     Update a bundle
+
+   -initlevel N   Set initial start level for installed bundles
+   -startlevel N  Set the beginning start level of the Start Level service
+
+ Extra: (Only applicable when using ./kf2)
+   -java PATH	  Use this JVM (Default=java)
+
+
+ The default directory used for storing bundle data is  "fwdir".
+
+ (*) Fully R5 compatible, enables support for bootclasspath extension bundles.
+     Uses framwork.jar if available, otherwise framework_compact.jar.
+
+ For extended help and list of all available system properties, see online
+ documentation or visit:
+
+ http://www.knopflerfish.org/releases/current/docs/bundledoc/framework/index.html
diff --git a/osgi/framework/resources/icon.png b/osgi/framework/resources/icon.png
new file mode 100644
index 0000000..08d00b5
Binary files /dev/null and b/osgi/framework/resources/icon.png differ
diff --git a/osgi/framework/resources/icon64.png b/osgi/framework/resources/icon64.png
new file mode 100644
index 0000000..788b74e
Binary files /dev/null and b/osgi/framework/resources/icon64.png differ
diff --git a/osgi/framework/resources/kfsplash.gif b/osgi/framework/resources/kfsplash.gif
new file mode 100644
index 0000000..da2e5a6
Binary files /dev/null and b/osgi/framework/resources/kfsplash.gif differ
diff --git a/osgi/framework/resources/packages.txt b/osgi/framework/resources/packages.txt
new file mode 100644
index 0000000..7464bf6
--- /dev/null
+++ b/osgi/framework/resources/packages.txt
@@ -0,0 +1,255 @@
+com.apple.concurrent!1.7
+com.apple.eawt
+com.apple.eawt.event!1.7
+com.apple.eio
+com.apple.laf!1.7
+com.apple.laf.resources!1.7
+com.apple.resources!1.7
+com.sun.java.swing.plaf.gtk!1.7
+com.sun.java.swing.plaf.gtk.resources!1.7
+com.sun.java.swing.plaf.motif!1.6
+com.sun.java.swing.plaf.motif.resources!1.7
+com.sun.java.swing.plaf.nimbus!1.7
+com.sun.java.swing.plaf.windows!1.6
+com.sun.java.swing.plaf.windows.resources!1.7
+javafx.animation!1.7
+javafx.application!1.7
+javafx.beans!1.7
+javafx.beans.binding!1.7
+javafx.beans.property!1.7
+javafx.beans.property.adapter!1.7
+javafx.beans.value!1.7
+javafx.collections!1.7
+javafx.concurrent!1.7
+javafx.embed.swing!1.7
+javafx.embed.swt!1.7
+javafx.event!1.7
+javafx.fxml!1.7
+javafx.geometry!1.7
+javafx.scene!1.7
+javafx.scene.canvas!1.7
+javafx.scene.chart!1.7
+javafx.scene.control!1.7
+javafx.scene.control.cell!1.7
+javafx.scene.effect!1.7
+javafx.scene.image!1.7
+javafx.scene.input!1.7
+javafx.scene.layout!1.7
+javafx.scene.media!1.7
+javafx.scene.paint!1.7
+javafx.scene.shape!1.7
+javafx.scene.text!1.7
+javafx.scene.transform!1.7
+javafx.scene.web!1.7
+javafx.stage!1.7
+javafx.util!1.7
+javafx.util.converter!1.7
+javax.accessibility
+javax.activation!1.6
+javax.activity!1.6
+javax.annotation!1.6
+javax.annotation.processing!1.6
+javax.crypto
+javax.crypto.interfaces
+javax.crypto.spec
+javax.imageio
+javax.imageio.event
+javax.imageio.metadata
+javax.imageio.plugins.bmp!1.6
+javax.imageio.plugins.jpeg
+javax.imageio.spi
+javax.imageio.stream
+javax.jws!1.6
+javax.jws.soap!1.6
+javax.lang.model!1.6
+javax.lang.model.element!1.6
+javax.lang.model.type!1.6
+javax.lang.model.util!1.6
+javax.management!1.6
+javax.management.loading!1.6
+javax.management.modelmbean!1.6
+javax.management.monitor!1.6
+javax.management.openmbean!1.6
+javax.management.relation!1.6
+javax.management.remote!1.6
+javax.management.remote.rmi!1.6
+javax.management.timer!1.6
+javax.naming
+javax.naming.directory
+javax.naming.event
+javax.naming.ldap
+javax.naming.spi
+javax.net
+javax.net.ssl
+javax.print
+javax.print.attribute
+javax.print.attribute.standard
+javax.print.event
+javax.rmi
+javax.rmi.CORBA
+javax.rmi.ssl!1.6
+javax.script!1.6
+javax.security![1.4,1.6)
+javax.security.auth
+javax.security.auth.callback
+javax.security.auth.kerberos
+javax.security.auth.login
+javax.security.auth.spi
+javax.security.auth.x500
+javax.security.cert
+javax.security.sasl!1.6
+javax.smartcardio!1.6
+javax.sound.midi
+javax.sound.midi.spi
+javax.sound.sampled
+javax.sound.sampled.spi
+javax.sql
+javax.sql.rowset!1.6
+javax.sql.rowset.serial!1.6
+javax.sql.rowset.spi!1.6
+javax.swing
+javax.swing.beaninfo![1.4,1.6)
+javax.swing.beaninfo.images![1.4,1.6)
+javax.swing.border
+javax.swing.colorchooser
+javax.swing.event
+javax.swing.filechooser
+javax.swing.plaf
+javax.swing.plaf.basic
+javax.swing.plaf.basic.icons![1.5,1.6)
+javax.swing.plaf.metal
+javax.swing.plaf.metal.icons![1.4,1.6)
+javax.swing.plaf.metal.icons.ocean![1.5,1.6)
+javax.swing.plaf.metal.sounds![1.4,1.6)
+javax.swing.plaf.multi
+javax.swing.plaf.nimbus!1.7
+javax.swing.plaf.synth!1.6
+javax.swing.table
+javax.swing.text
+javax.swing.text.html
+javax.swing.text.html.icons![1.4,1.6)
+javax.swing.text.html.parser
+javax.swing.text.rtf
+javax.swing.text.rtf.charsets![1.4,1.6)
+javax.swing.tree
+javax.swing.undo
+javax.tools!1.6
+javax.transaction
+javax.transaction.xa
+javax.xml!1.6
+javax.xml.bind!1.6
+javax.xml.bind.annotation!1.6
+javax.xml.bind.annotation.adapters!1.6
+javax.xml.bind.attachment!1.6
+javax.xml.bind.helpers!1.6
+javax.xml.bind.util!1.6
+javax.xml.crypto!1.6
+javax.xml.crypto.dom!1.6
+javax.xml.crypto.dsig!1.6
+javax.xml.crypto.dsig.dom!1.6
+javax.xml.crypto.dsig.keyinfo!1.6
+javax.xml.crypto.dsig.spec!1.6
+javax.xml.datatype!1.6
+javax.xml.namespace!1.6
+javax.xml.parsers
+javax.xml.soap!1.6
+javax.xml.stream!1.6
+javax.xml.stream.events!1.6
+javax.xml.stream.util!1.6
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stax!1.6
+javax.xml.transform.stream
+javax.xml.validation!1.6
+javax.xml.ws!1.6
+javax.xml.ws.handler!1.6
+javax.xml.ws.handler.soap!1.6
+javax.xml.ws.http!1.6
+javax.xml.ws.soap!1.6
+javax.xml.ws.spi!1.6
+javax.xml.ws.spi.http!1.7
+javax.xml.ws.wsaddressing!1.7
+javax.xml.xpath!1.6
+netscape.javascript!1.7
+org.apache.crimson.jaxp![1.4,1.5)
+org.apache.crimson.parser![1.4,1.5)
+org.apache.crimson.parser.resources![1.4,1.5)
+org.apache.crimson.tree![1.4,1.5)
+org.apache.crimson.tree.resources![1.4,1.5)
+org.apache.crimson.util![1.4,1.5)
+org.apache.xalan![1.4,1.5)
+org.apache.xalan.client![1.4,1.5)
+org.apache.xalan.extensions![1.4,1.5)
+org.apache.xalan.lib![1.4,1.5)
+org.apache.xalan.lib.sql![1.4,1.5)
+org.apache.xalan.processor![1.4,1.5)
+org.apache.xalan.res![1.4,1.5)
+org.apache.xalan.serialize![1.4,1.5)
+org.apache.xalan.templates![1.4,1.5)
+org.apache.xalan.trace![1.4,1.5)
+org.apache.xalan.transformer![1.4,1.5)
+org.apache.xalan.xslt![1.4,1.5)
+org.apache.xml.dtm![1.4,1.5)
+org.apache.xml.dtm.ref![1.4,1.5)
+org.apache.xml.dtm.ref.dom2dtm![1.4,1.5)
+org.apache.xml.dtm.ref.sax2dtm![1.4,1.5)
+org.apache.xml.utils![1.4,1.5)
+org.apache.xml.utils.res![1.4,1.5)
+org.apache.xpath![1.4,1.5)
+org.apache.xpath.axes![1.4,1.5)
+org.apache.xpath.compiler![1.4,1.5)
+org.apache.xpath.functions![1.4,1.5)
+org.apache.xpath.objects![1.4,1.5)
+org.apache.xpath.operations![1.4,1.5)
+org.apache.xpath.patterns![1.4,1.5)
+org.apache.xpath.res![1.4,1.5)
+org.ietf.jgss
+org.jcp.xml.dsig.internal!1.7
+org.jcp.xml.dsig.internal.dom!1.7
+org.omg.CORBA
+org.omg.CORBA.DynAnyPackage
+org.omg.CORBA.ORBPackage
+org.omg.CORBA.TypeCodePackage
+org.omg.CORBA.portable
+org.omg.CORBA_2_3
+org.omg.CORBA_2_3.portable
+org.omg.CosNaming
+org.omg.CosNaming.NamingContextExtPackage
+org.omg.CosNaming.NamingContextPackage
+org.omg.Dynamic
+org.omg.DynamicAny
+org.omg.DynamicAny.DynAnyFactoryPackage
+org.omg.DynamicAny.DynAnyPackage
+org.omg.IOP
+org.omg.IOP.CodecFactoryPackage
+org.omg.IOP.CodecPackage
+org.omg.Messaging
+org.omg.PortableInterceptor
+org.omg.PortableInterceptor.ORBInitInfoPackage
+org.omg.PortableServer
+org.omg.PortableServer.CurrentPackage
+org.omg.PortableServer.POAManagerPackage
+org.omg.PortableServer.POAPackage
+org.omg.PortableServer.ServantLocatorPackage
+org.omg.PortableServer.portable
+org.omg.SendingContext
+org.omg.stub.java.rmi
+org.omg.stub.javax.management.remote.rmi!1.6
+org.w3c.dom
+org.w3c.dom.bootstrap!1.6
+org.w3c.dom.css
+org.w3c.dom.events
+org.w3c.dom.html
+org.w3c.dom.ls!1.6
+org.w3c.dom.ranges!1.6
+org.w3c.dom.stylesheets
+org.w3c.dom.traversal
+org.w3c.dom.views
+org.w3c.dom.xpath!1.6
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
+sun.awt.shell!1.6
+sunw.io
+sunw.util
diff --git a/osgi/framework/resources/release b/osgi/framework/resources/release
new file mode 100644
index 0000000..acf69b4
--- /dev/null
+++ b/osgi/framework/resources/release
@@ -0,0 +1 @@
+5.1.0
\ No newline at end of file
diff --git a/osgi/framework/resources/version b/osgi/framework/resources/version
new file mode 100644
index 0000000..0e7b60d
--- /dev/null
+++ b/osgi/framework/resources/version
@@ -0,0 +1 @@
+7.1.2
\ No newline at end of file
diff --git a/osgi/framework/src/org/knopflerfish/framework/Alias.java b/osgi/framework/src/org/knopflerfish/framework/Alias.java
new file mode 100644
index 0000000..c8d799d
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Alias.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2003-2011, 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.
+ */
+
+package org.knopflerfish.framework;
+
+/**
+ * This class contains aliases for system properties.
+ * 
+ * @author Jan Stein
+ */
+public class Alias {
+
+  /**
+   * List of processor aliases. The first entry is the true name. All matching
+   * aliases must be in lowercase.
+   */
+  final public static String[][] processorAliases = {
+      { "arm_le", "armv*l" },
+      { "arm_be", "armv*" },
+      { "Ignite", "psc1k" },
+      { "PowerPC", "power", "ppc", "ppcbe" },
+      { "x86", "pentium", "i386", "i486", "i586", "i686" },
+      { "x86-64", "amd64", "em64t", "x86_64" }
+  };
+
+  /**
+   * List of OS name aliases. The first entry is the true name. All matching
+   * aliases must be in lowercase.
+   */
+  final public static String[][] osNameAliases = {
+      { "Epoc32", "symbianos" },
+      { "HPUX", "hp-ux" },
+      { "MacOS", "mac os" },
+      { "MacOSX", "mac os x" },
+      { "OS2", "os/2" },
+      { "QNX", "procnto" },
+      { "Windows95", "win*95", "win32" },
+      { "Windows98", "win*98", "win32" },
+      { "WindowsNT", "win*nt", "win32" },
+      { "WindowsCE", "win*ce", "win32" },
+      { "Windows2000", "win*2000", "win32" },
+      { "WindowsXP", "win*xp", "win32" },
+      { "Windows2003", "win*2003", "win32" },
+      { "WindowsVista", "win*vista", "win32" },
+      { "Windows7", "win*7", "win32" },
+      { "WindowsServer2008", "win*2008", "win32" },
+      { "Windows8", "win*8", "win32" },
+      { "WindowsServer2012", "win*2012", "win32" }
+  };
+
+
+  /**
+   * Unify processor names.
+   * 
+   * @param name Processor name.
+   * @return The unified name.
+   */
+  static public String unifyProcessor(String name) {
+    String lname = name.toLowerCase();
+    for (int i = 0; i < processorAliases.length; i++) {
+      for (int j = 1; j < processorAliases[i].length; j++) {
+        if (Util.filterMatch(processorAliases[i][j], lname)) {
+          return processorAliases[i][0];
+        }
+      }
+    }
+    return name;
+  }
+
+
+  /**
+   * Unify OS names.
+   * 
+   * @param name OS name.
+   * @return The unified name.
+   */
+  static public String unifyOsName(String name) {
+    String lname = name.toLowerCase();
+    for (int i = 0; i < osNameAliases.length; i++) {
+      for (int j = 1; j < osNameAliases[i].length; j++) {
+        if (Util.filterMatch(osNameAliases[i][j], lname)) {
+          return osNameAliases[i][0];
+        }
+      }
+    }
+    return name;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/AutoManifest.java b/osgi/framework/src/org/knopflerfish/framework/AutoManifest.java
new file mode 100644
index 0000000..371af11
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/AutoManifest.java
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.osgi.framework.Constants;
+
+/**
+ * Manifest subclass which modifies some of the attributes automatically.
+ * This can be used to add or remove manifest headers to any loaded bundle. For example,
+ * adding package import/export headers.
+ *
+ * <p>
+ * To enable automatic manifest generation, set the system property
+ * </p>
+ * <pre>
+ *  org.knopflerfish.framework.automanifest=true
+ * </pre>
+ *
+ * <p>
+ * The automatic manifest config can be specified as an URL using
+ * the system property:
+ * </p>
+ * <pre>
+ *  org.knopflerfish.framework.automanifest.config=[URL]
+ * </pre>
+ *
+ * <p>
+ * Default is <code>"!!/automanifest.props"</code> The <code>"!!"</code> part is used to refer
+ * to a resource on the system classloader, but any URL can be used.
+ * </p>
+ *
+ * <p>
+ * The configuration file for automatic manifest generation is on java property
+ * file format with any number of sections as:
+ * <pre>
+ * [id].match.filter=[ldap filter]
+ * [id].export.filter=[ldap filter]
+ * [id].export.file.filter=[ldap filter]
+ * [id].header.[header-name]=[header-value]
+ * [id].header.[header-name]=[header-value]
+ * [id].header.[header-name]=[header-value]
+ * ...
+ * </pre>
+ *
+ * <p>
+ * The default config file only has one section, setting all installed
+ * bundles to automatically export all of their packages, and dynamically
+ * install every class. This is implemented by a single section:
+ * </p>
+ * <pre>
+ * 1.match.filter=(location=*)
+ * 1.export.filter=(pkg=*)
+ * 1.export.file.filter=(file=*.class)
+ * 1.header.DynamicImport-Package=*
+ * 1.header.Import-Package=[remove]
+ * 1.header.Export-Package=[autoexport]
+ * </pre>
+ *
+ * <p>
+ * <code>[id]</code> is any string. The <code>[id]</code> is also used for sorting the sections. Matching is
+ * done is this sort order.
+ * </p>
+ *
+ * </p>
+ * The <code>match.filter</code> value is an LDAP filter expression used to select
+ * which bundles the section applies to. Only the first matching section is applied to
+ * a bundle. All original bundle manifest attributes can be used in the matching, plus the
+ * special key "location" which represents the bundle location string.
+ * </p>
+ *
+ * <p>
+ * The <code>export.filter</code> value is an LDAP filter expression which selects
+ * which resources are valid for automatic package export. The special
+ * key "pkg" represents the export candidate. E.g. a filter of <code>"(pkg=*)"</code>
+ * exports all packages.
+ * </p>
+ *
+ * <p>
+ * The <code>export.file.filter</code> value is an optional LDAP filter expression which selects
+ * which files are considered for auto package generation. The special key
+ * key "file" represents the file candidate. E.g. a filter of <code>"(name=*)"</code>
+ * considers all files. Default is <code>"(file=*.class)</code>
+ * </p>
+ *
+ * <p>
+ * The <code>[header-name]</code> values are stored directly in the generated
+ * manifest. Any number of header names can be specified.
+ * </p>
+ *
+ * <p>
+ * Two special header values can be used:
+ * </p>
+ * <pre>
+ *  "[remove]"     -  Removes the header completely from the manifest
+ *  "[autoexport]" -  Uses the generated package names as value.
+ *                    Package names are only present if the passes
+ *                    the export.filter
+ * </pre>
+ * <p>
+ * <b>Note 1</b>: An extra attribute
+ *       <code>"Bundle-AutoManifest-config"</code>
+ *       is always added to the manifest. The value is the URL of the config file
+ * </p>
+ *
+ * <p>
+ * <b>Note 2</b>: Debug output of automatic manifest can be enabled by setting the system property
+ * </p>
+ * <pre>
+ * org.knopflerfish.framework.debug.automanifest=true
+ * </pre>
+ *
+ * @author Erik Wistrand
+ */
+public class AutoManifest extends Manifest {
+  FrameworkContext fwCtx;
+  Manifest   mf;
+  String     location;
+  AutoInfo   autoInfo;
+  Attributes mainAttrs;
+  Set<String> packages = new TreeSet<String>();
+
+  static String configSource = null;
+  static Map<String, AutoInfo>    configs      = null;
+
+  /**
+   * Create an AutoManifest instance based on an original manifest
+   * and a bundle location.
+   *
+   * <p>
+   * An AutoManifest instance is a proxy to the original manifest except in the
+   * case of getting the main attributes. In this case the result may be modified
+   * according the auto manifest configuration file.
+   * </p>
+   *
+   * <p>
+   * Note: The first time an AutoManifest instance is created, the configuration
+   * file is read.
+   * </p>
+   *
+   * @param mf original manifest. Must not be null.
+   * @param location bundle location. Must not be null.
+   */
+  public AutoManifest(FrameworkContext fwCtx, Manifest mf, String location) {
+    if(mf == null) {
+      throw new NullPointerException("Manifest cannot be null");
+    }
+
+    if(location == null) {
+      throw new NullPointerException("location cannot be null");
+    }
+
+    this.fwCtx = fwCtx;
+    this.mf       = mf;
+    this.location = location;
+
+    // just read the config once
+    if(configs == null) {
+      if(fwCtx.props.getBooleanProperty(FWProps.AUTOMANIFEST_PROP)) {
+        configSource = fwCtx.props.getProperty(FWProps.AUTOMANIFEST_CONFIG_PROP);
+        configs      = loadConfig(configSource);
+        if(fwCtx.debug.automanifest) {
+          fwCtx.debug.println("Loaded auto manifest config from " + configSource);
+        }
+      } else {
+        configs = new TreeMap<String, AutoInfo>();
+      }
+    }
+
+    autoInfo = findConfig();
+
+    if(isAuto() && fwCtx.debug.automanifest) {
+      fwCtx.debug.println("Using auto manifest for bundlelocation " + location);
+    }
+  }
+
+  /**
+   * Check if manifest generation is enabled for this instance.
+   */
+  public boolean isAuto() {
+    return autoInfo != null;
+  }
+
+
+  /**
+   * Delegate to original manifest.
+   */
+  @Override
+  public void 	clear() {
+    mf.clear();
+    mainAttrs = null;
+  }
+
+  /**
+   * Delegate to original manifest.
+   */
+  @Override
+  public  Attributes 	getAttributes(String name) {
+    return mf.getAttributes(name);
+  }
+
+  /**
+   * Delegate to original manifest.
+   */
+  @Override
+  public Map<String,Attributes> getEntries()
+  {
+    return mf.getEntries();
+  }
+
+  /**
+   * Delegate to original manifest.
+   */
+  @Override
+  public  void 	read(InputStream is) throws IOException {
+    mf.read(is);
+    mainAttrs = null;
+  }
+
+  /**
+   * Delegate to original manifest.
+   */
+  @Override
+  public  void 	write(OutputStream out) throws IOException {
+    mf.write(out);
+  }
+
+  /**
+   * Get the original manifest
+   */
+  public Manifest getManifest() {
+    return mf;
+  }
+
+  /**
+   * Get the bundle location
+   */
+  public String getLocation() {
+    return location;
+  }
+
+
+  /**
+   * AutoManifests are equal if both the original manifest
+   * and the bundle location are equal.
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if(obj == null || !(obj instanceof AutoManifest)) {
+      return false;
+    }
+    final AutoManifest af = (AutoManifest)obj;
+    return mf.equals(af.mf) && location.equals(af.location);
+  }
+
+  /**
+   * Hash code base on original manifest and loation
+   */
+  @Override
+  public int hashCode() {
+    return mf.hashCode() + 17 * location.hashCode();
+  }
+
+
+  /**
+   * Get the main manifest attributes, possibly modified.
+   */
+  @Override
+  public  Attributes 	getMainAttributes() {
+    if(mainAttrs == null) {
+
+      // Get the original attribs and modify them according to
+      // autoInfo config (if present)
+      mainAttrs = mf.getMainAttributes();
+
+
+      if(autoInfo != null) {
+        // store a flag for debug purposes
+        mainAttrs.putValue("Bundle-AutoManifest-config", configSource);
+
+        for (final String key : autoInfo.headers.keySet()) {
+          final String val = autoInfo.headers.get(key);
+
+          if("[remove]".equals(val)) {
+            mainAttrs.remove(new Attributes.Name(key));
+          } else if("[autoexport]".equals(val)) {
+            final String exports = getExports();
+
+            if(fwCtx.debug.automanifest) {
+              fwCtx.debug.println("Auto exports for " + location + ": " + exports);
+            }
+
+            if(exports.length() > 0) {
+              mainAttrs.putValue(Constants.EXPORT_PACKAGE, exports);
+            } else {
+              mainAttrs.remove(new Attributes.Name(Constants.EXPORT_PACKAGE));
+            }
+          } else {
+            mainAttrs.putValue(key, val);
+          }
+        }
+      }
+    }
+    return mainAttrs;
+  }
+
+  /**
+   * Add a File for automatic package export consideration.
+   */
+  public void addFile(File file) throws IOException {
+    addFile(file.getAbsolutePath(), file);
+  }
+
+  /**
+   * Add a File for automatic package export consideration.
+   */
+  public void addFile(String prefix, File file) throws IOException {
+    final String f = prefix.length() < file.getAbsolutePath().length()
+      ? file.getAbsolutePath().substring(prefix.length() + 1)
+      : file.getAbsolutePath();
+
+    if(f.endsWith(".jar")) {
+      addZipFile(new ZipFile(file));
+    } else if(isValidFileName(f)) {
+      addFileName(f);
+    } else if(file.isDirectory()) {
+      final String[] files = file.list();
+      for (final String file2 : files) {
+        addFile(prefix, new File(file.getAbsolutePath(), file2));
+      }
+    }
+  }
+
+  // used to avoid recreating a new hash table at each isValidFileName() call
+  private final Hashtable<String, String> fileProps = new Hashtable<String, String>();
+
+  private boolean isValidFileName(String f) {
+    if(autoInfo != null && autoInfo.fileNameFilter != null) {
+      fileProps.put("file", f);
+      return autoInfo.fileNameFilter.evaluate(fileProps, true);
+    } else {
+      return f.endsWith(".class");
+    }
+  }
+
+  /**
+   * Add contents of a ZipFile for automatic package export consideration.
+   */
+  public void addZipFile(ZipFile jar) {
+    for(final Enumeration<? extends ZipEntry> e = jar.entries(); e.hasMoreElements(); ) {
+      final ZipEntry ze = e.nextElement();
+      final String   f  = ze.getName();
+      if(isValidFileName(f)) {
+        addFileName(f);
+      }
+    }
+  }
+
+  /**
+   * Add a string file name for automatic package export consideration.
+   */
+  public void addFileName(String f) {
+
+    // transform file path to package name
+    f = f.replace('\\', '/');
+
+    // ..and strip last part
+    final int ix = f.lastIndexOf("/");
+    if(ix != -1) {
+      f = f.substring(0, ix);
+    }
+    f = f.replace('/', '.');
+
+    // check all export patterns if the file matches.
+    // If so, add to packages set
+    if(autoInfo != null) {
+      final Hashtable<String, String> props = new Hashtable<String, String>();
+      props.put("pkg", f);
+      if(autoInfo.exportFilter.evaluate(props, true)) {
+        if(!packages.contains(f)) {
+          packages.add(f);
+        }
+      }
+    }
+
+    // clearing mainAttrs will force rebuild of attribut set in getMainAttributes()
+    mainAttrs = null;
+  }
+
+
+
+
+  /***
+   * Create Export-Package string from package set
+   * The package set is created by addFileName() calls
+   */
+  String getExports() {
+    final StringBuffer sb = new StringBuffer();
+    for (final String pkg : packages) {
+      if(sb.length() > 0) {
+        sb.append(",");
+      }
+      sb.append(pkg);
+      if(autoInfo.version != null) {
+        sb.append(";");
+        sb.append(autoInfo.version);
+      }
+    }
+    return sb.toString();
+  }
+
+
+  private AutoInfo findConfig() {
+    final Hashtable<String, String> props = new Hashtable<String, String>();
+    props.put("location", location);
+
+    final Attributes attrs = mf.getMainAttributes();
+    for (final Object key : attrs.keySet()) {
+      final Object val = attrs.getValue(key.toString());
+      props.put(key.toString(), val.toString());
+    }
+
+    for (final String id : configs.keySet()) {
+      final AutoInfo ai = configs.get(id);
+
+      if(ai.filter.evaluate(props, true)) {
+        return ai;
+      }
+    }
+    return null;
+  }
+
+  private Map<String, AutoInfo> loadConfig(String urlS) {
+    if(urlS != null && !"".equals(urlS)) {
+      URL         url = null;
+      InputStream is  = null;
+      try {
+        if(urlS.startsWith("!!")) {
+          url = AutoManifest.class.getResource(urlS.substring(2));
+        } else {
+          url = new URL(urlS);
+        }
+        is = url.openStream();
+        return loadConfigFromInputStream(is);
+      } catch (final Exception e) {
+        fwCtx.debug.printStackTrace("Failed to load autoimportexport conf from " + url, e);
+      } finally {
+        try { is.close(); } catch (final Exception ignored) { }
+      }
+    }
+    return new HashMap<String, AutoInfo>();
+  }
+
+  private Map<String, AutoInfo> loadConfigFromInputStream(InputStream is)
+      throws IOException
+  {
+    final Properties props = new Properties();
+    props.load(is);
+
+    final Map<String, AutoInfo> configMap = new TreeMap<String, AutoInfo>();
+
+    for (final Object object : props.keySet()) {
+      final String key = (String) object;
+      final int ix = key.indexOf(".");
+      if(ix != -1) {
+        final String id = key.substring(0, ix);
+
+        final String pattern     = (String)props.get(id + ".match.filter");
+        final String export      = (String)props.get(id + ".export.filter");
+        String fileFilter  = (String)props.get(id + ".export.file.filter");
+        final Map<String, String>    headers     = new HashMap<String, String>();
+
+        if(fileFilter == null) {
+          fileFilter = "(file=*.class)";
+        }
+
+        final String headerPre = id + ".header.";
+        for (final Object object2 : props.keySet()) {
+          final String key2 = (String) object2;
+          final String val2 = (String) props.get(key2);
+          if(key2.startsWith(headerPre)) {
+            headers.put(key2.substring(headerPre.length()), val2);
+          }
+        }
+        final AutoInfo ai = new AutoInfo(pattern, export, fileFilter, headers);
+        ai.version = (String)props.get(id + ".export.version");
+        configMap.put(id, ai);
+      }
+    }
+    return configMap;
+  }
+
+
+  /**
+   * Helper structure to hold configuration info.
+   */
+  static class AutoInfo {
+    LDAPExpr filter;
+    LDAPExpr exportFilter;
+    LDAPExpr fileNameFilter;
+    Map<String, String>      headers;
+    String   version;
+
+    AutoInfo(String filter, String export, String nameFilter, Map<String, String> headers) {
+      try {
+        this.filter  = new LDAPExpr(filter);
+      } catch (final Exception e) {
+        throw new RuntimeException("Bad filter '" + filter + "': " +e);
+      }
+      try {
+        this.fileNameFilter  = new LDAPExpr(nameFilter);
+      } catch (final Exception e) {
+        throw new RuntimeException("Bad file name filter '" + nameFilter
+                                   + "': " +e);
+      }
+      try {
+        this.exportFilter  = new LDAPExpr(export);
+      } catch (final Exception e) {
+        throw new RuntimeException("Bad export filter '" + export + "': " +e);
+      }
+      this.headers = headers;
+    }
+
+    @Override
+    public String toString() {
+      return "AutoInfo[" +
+        "filter=" + filter +
+        ", exportFilter="+ exportFilter +
+        ", version=" + version +
+        ", headers=" + headers +
+        "]";
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleArchive.java b/osgi/framework/src/org/knopflerfish/framework/BundleArchive.java
new file mode 100644
index 0000000..4d504bd
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleArchive.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * Interface for managing bundle data.
+ *
+ * @author Jan Stein
+ * @author Philippe Laporte
+ * @author Mats-Ola Persson
+ * @author Gunnar Ekolin
+ */
+public interface BundleArchive {
+
+  /**
+   * Autostart setting stopped.
+   *
+   * @see BundleArchive#setAutostartSetting(String)
+   */
+  public String AUTOSTART_SETTING_STOPPED = "stopped";
+
+  /**
+   * Autostart setting eager.
+   *
+   * @see BundleArchive#setAutostartSetting(String)
+   */
+  public String AUTOSTART_SETTING_EAGER = "eager";
+
+  /**
+   * Autostart setting declared activation policy.
+   *
+   * @see BundleArchive#setAutostartSetting(String)
+   */
+  public String AUTOSTART_SETTING_ACTIVATION_POLICY = "activation_policy";
+
+
+  /**
+   * Get an attribute from the manifest of a bundle.
+   *
+   * Not localized
+   *
+   * @param key Name of attribute to get.
+   * @return A string with result or null if the entry doesn't exists.
+   */
+  String getAttribute(String key);
+
+
+  /**
+   * Get a FileArchive handle to a named Jar file or directory within this
+   * archive.
+   *
+   * @param path Name of Jar file or directory to get.
+   * @return A FileArchive object representing new archive, null if not found.
+   */
+  FileArchive getFileArchive(String path);
+
+
+  /**
+   * Gets all localization entries from this bundle. Will typically read the
+   * file OSGI-INF/bundle_<locale>.properties.
+   *
+   * @param localeFile Filename within archive for localization properties.
+   * @return null or a mapping of the entries.
+   */
+  Hashtable<String, String> getLocalizationEntries(String localeFile);
+
+
+  /**
+   * @returns the (raw/unlocalized) attributes
+   */
+  HeaderDictionary getUnlocalizedAttributes();
+
+
+  /**
+   * Get bundle generation associated with this bundle archive.
+   *
+   * @return BundleGeneration object.
+   */
+  BundleGeneration getBundleGeneration();
+
+
+  /**
+   * Set bundle generation associated with this bundle archive.
+   *
+   * @param BundleGeneration object.
+   */
+  void setBundleGeneration(BundleGeneration bg);
+
+
+  /**
+   * Get bundle identifier for this bundle archive.
+   *
+   * @return Bundle identifier.
+   */
+  long getBundleId();
+
+
+  /**
+   * Get bundle location for this bundle archive.
+   *
+   * @return Bundle location.
+   */
+  String getBundleLocation();
+
+
+  /**
+   * Get a BundleResourceStream to named entry inside a bundle. Leading '/' is
+   * stripped.
+   *
+   * @param component Entry to get reference to.
+   * @param ix index of sub archives. A postive number is the classpath entry
+   *          index. 0 means look in the main bundle.
+   * @return BundleResourceStream to entry or null if it doesn't exist.
+   */
+  BundleResourceStream getBundleResourceStream(String component, int ix);
+
+
+  /**
+   * Returns an Enumeration of all the paths (<code>String</code> objects) to
+   * entries within the bundle whose longest sub-path matches the supplied path
+   * argument.
+   *
+   * @param name
+   * @return
+   */
+  Enumeration<String> findResourcesPath(String path);
+
+
+  /**
+   * Get stored bundle start level.
+   */
+  int getStartLevel();
+
+
+  /**
+   * Set stored bundle start level.
+   */
+  void setStartLevel(int level) throws IOException;
+
+
+  /**
+   * Get last modified timestamp.
+   */
+  long getLastModified();
+
+
+  /**
+   * Set stored last modified timestamp.
+   */
+  void setLastModified(long timemillisecs) throws IOException;
+
+
+  /**
+   * Get auto-start setting.
+   *
+   * @return the autostart setting. "-1" if bundle not started.
+   */
+  int getAutostartSetting();
+
+
+  /**
+   * Set the auto-start setting.
+   *
+   * @param setting the autostart setting to use.
+   */
+  void setAutostartSetting(int setting) throws IOException;
+
+
+  /**
+   * @return the location of the cached bundle.
+   */
+  String getJarLocation();
+
+
+  /**
+   * Get certificate chains associated with with bundle archive.
+   *
+   * @param onlyTrusted Only return trusted certificates.
+   * @return All certificates or null if bundle is unsigned.
+   */
+  ArrayList<List<X509Certificate>> getCertificateChains(boolean onlyTrusted);
+
+
+  /**
+   * Mark certificate associated with with bundle archive as trusted.
+   *
+   */
+  void trustCertificateChain(List<X509Certificate> trustedChain);
+
+
+  /**
+   * Remove bundle archive from persistent storage.
+   */
+  void purge();
+
+
+  /**
+   * Close archive and all its open files.
+   */
+  void close();
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleCapabilityImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleCapabilityImpl.java
new file mode 100644
index 0000000..3066f4a
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleCapabilityImpl.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Constants;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * Implementation of bundle capability for generic capabilities specified in the
+ * Bundle-Capability header.
+ */
+public class BundleCapabilityImpl implements BundleCapability {
+  private final BundleGeneration gen;
+  private final BundleGeneration owner;
+  private final String nameSpace;
+  private final Map<String,Object> attributes;
+  private final Map<String,String> directives;
+  private Vector<BundleWireImpl> wires = new Vector<BundleWireImpl>(2);
+
+  /**
+   * Creates a {@link BundleCapability} from one entry of the Bundle-Capability
+   * header.
+   *
+   * @param gen
+   *          the owning bundle revision.
+   * @param he
+   *          the parsed bundle capability header entry.
+   */
+  public BundleCapabilityImpl(final BundleGeneration gen, final HeaderEntry he)
+  {
+    this.gen = gen;
+    owner = gen;
+    nameSpace = he.getKey();
+    for (final String ns : Arrays
+        .asList(new String[] { BundleRevision.BUNDLE_NAMESPACE,
+                               BundleRevision.HOST_NAMESPACE,
+                               BundleRevision.PACKAGE_NAMESPACE,
+                               IdentityNamespace.IDENTITY_NAMESPACE})) {
+      if (ns.equals(nameSpace)) {
+        throw new IllegalArgumentException("Capability with name-space '" + ns
+                                           + "' must not be provided in the "
+                                           + Constants.PROVIDE_CAPABILITY
+                                           + " manifest header.");
+      }
+    }
+
+    attributes = Collections.unmodifiableMap(he.getAttributes());
+    directives = Collections.unmodifiableMap(he.getDirectives());
+  }
+
+  public BundleCapabilityImpl(BundleCapability bc, BundleGeneration bg) {
+    gen = bg;
+    owner = ((BundleCapabilityImpl)bc).owner;
+    nameSpace = bc.getNamespace();
+    attributes = bc.getAttributes();
+    directives = bc.getDirectives();
+  }
+
+  public BundleCapabilityImpl(BundleGeneration bg) {
+    gen = bg;
+    owner = gen;
+    nameSpace = IdentityNamespace.IDENTITY_NAMESPACE;
+    Map<String,Object> attrs = new HashMap<String, Object>();
+    attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, gen.symbolicName);
+    attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE,
+              gen.fragment != null ? IdentityNamespace.TYPE_FRAGMENT : IdentityNamespace.TYPE_BUNDLE);
+    attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, gen.version);
+    if (gen.archive != null) {
+      String a = gen.archive.getAttribute(Constants.BUNDLE_COPYRIGHT);
+      if (a != null) {
+        attrs.put(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE, a);
+      }
+      a = gen.archive.getAttribute(Constants.BUNDLE_DESCRIPTION);
+      if (a != null) {
+        attrs.put(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE, a);
+      }
+      a = gen.archive.getAttribute(Constants.BUNDLE_DOCURL);
+      if (a != null) {
+        attrs.put(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE, a);
+      }
+      a = gen.archive.getAttribute("Bundle-License");
+      if (a != null) {
+        StringBuffer sb = new StringBuffer();
+        try {
+          List<HeaderEntry> lic = Util.parseManifestHeader("Bundle-License", a, true, true, false);
+          for (HeaderEntry he : lic) {
+            if (sb.length() > 0) {
+              sb.append(", ");
+            }
+            sb.append(he.getKey());
+          }
+        } catch (IllegalArgumentException iae) {
+          gen.bundle.fwCtx.frameworkInfo(gen.bundle, iae);
+          sb.append(a);
+        }
+        attrs.put(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE, sb.toString());
+      }
+    }
+    attributes = Collections.unmodifiableMap(attrs);
+    Map<String,String> dirs = new HashMap<String, String>();
+    dirs.put(Constants.SINGLETON_DIRECTIVE, gen.singleton ? "true" : "false");
+    // TODO, should we try to find classfiers?
+    directives = Collections.unmodifiableMap(dirs);
+  }
+
+  @Override
+  public String getNamespace() {
+    return nameSpace;
+  }
+
+  @Override
+  public Map<String, String> getDirectives() {
+    return Collections.unmodifiableMap(directives);
+  }
+
+  @Override
+  public Map<String, Object> getAttributes() {
+    return attributes;
+  }
+
+  @Override
+  public BundleRevision getRevision() {
+    return owner.bundleRevision;
+  }
+
+  @Override
+  public BundleRevision getResource() {
+	return owner.bundleRevision;
+  }
+
+  @Override
+  public String toString() {
+    return "BundleCapability[nameSpace=" + nameSpace + ", attributes=" + attributes +
+        ", directives=" + directives + ", revision=" + getRevision() + "]";
+  }
+
+  BundleGeneration getBundleGeneration() {
+    return gen;
+  }
+
+  boolean isEffectiveResolve() {
+    final String effective = directives.get(Constants.EFFECTIVE_DIRECTIVE);
+    return effective == null || effective.equals(Constants.EFFECTIVE_RESOLVE);
+  }
+
+  boolean isZombie() {
+    return !gen.isCurrent();
+  }
+
+  void addWire(BundleWireImpl bw) {
+    wires.add(bw);
+  }
+
+  void getWires(List<BundleWireImpl> res) {
+    synchronized (wires) {
+      res.addAll(wires);
+    }
+  }
+
+  void removeWire(BundleWireImpl wire) {
+    wires.remove(wire);
+  }
+
+  void removeWires() {
+    wires.clear();
+  }
+
+  boolean isWired() {
+    return !wires.isEmpty();
+  }
+
+  /**
+   * Check if we have provide permissions.
+   *
+   * @return true if we have provide permission
+   */
+  boolean checkPermission() {
+    return gen.bundle.fwCtx.perm.hasProvidePermission(this);
+  }
+
+  Set<String> getUses() {
+    try {
+      return Util.parseEnumeration(Constants.USES_DIRECTIVE,
+                                   directives.get(Constants.USES_DIRECTIVE));
+    } catch (IllegalArgumentException iae) {
+      final BundleImpl b = gen.bundle;
+      b.fwCtx.frameworkError(b, iae);
+    }
+    return null;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleClassLoader.java b/osgi/framework/src/org/knopflerfish/framework/BundleClassLoader.java
new file mode 100644
index 0000000..c12d80e
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleClassLoader.java
@@ -0,0 +1,1241 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleReference;
+
+/**
+ * Classloader for bundle JAR files.
+ * 
+ * @author Jan Stein, Philippe Laporte, Mats-Ola Persson, Gunna Ekolin
+ * @author Vilmos Nebehaj (Android application support)
+ */
+final public class BundleClassLoader extends ClassLoader implements BundleReference {
+
+  final static int ONLY_FIRST = 1;
+  final static int LIST = 2;
+  final static int ONLY_RECURSE = 4;
+  final static int RECURSE = 256;
+  final static int LOCAL = 512;
+
+  /**
+   * Framework class loader
+   */
+  final FrameworkContext fwCtx;
+
+  /**
+   * Handle to secure operations.
+   */
+  final PermissionOps secure;
+
+  /**
+   * Bundle classloader protect domain.
+   */
+  final ProtectionDomain protectionDomain;
+
+  /**
+   * Archive that we load code from.
+   */
+  BundleArchive archive;
+
+  /**
+   * Imported and Exported java packages.
+   */
+  BundlePackages bpkgs;
+
+  /**
+   * Bundle class path for this classloader.
+   */
+  final private BundleClassPath classPath;
+
+  // Array of bundles for which a classload is triggering activation.
+  private static ThreadLocal<ArrayList<BundleImpl>> tlBundlesToActivate = new ThreadLocal<ArrayList<BundleImpl>>();
+
+  // android/dalvik VM stuff
+  private static Method dexFileClassLoadDexMethod;
+  private static Method dexFileClassLoadClassMethod;
+
+  // bDalvik will be set to true if we're running on the android
+  // dalvik VM.
+  // package protected to enable other parts of framework to check
+  // for dalvik VM
+  static boolean bDalvik = false;
+
+  private ArrayList<Object> dexFile = null;
+
+  static {
+    try {
+      Class<?> dexFileClass = null;
+      try {
+        dexFileClass = Class.forName("android.dalvik.DexFile");
+      } catch (final Exception ex) {
+        dexFileClass = Class.forName("dalvik.system.DexFile");
+      }
+
+      dexFileClassLoadDexMethod = dexFileClass.getMethod("loadDex", new Class[] { String.class,
+                                                                                 String.class,
+                                                                                 Integer.TYPE });
+
+      dexFileClassLoadClassMethod = dexFileClass.getMethod("loadClass",
+                                                           new Class[] { String.class,
+                                                                        ClassLoader.class });
+
+      bDalvik = true;
+      // if(debug.classLoader) {
+      // debug.println("running on dalvik VM");
+      // }
+    } catch (final Exception e) {
+      dexFileClassLoadDexMethod = null;
+      dexFileClassLoadClassMethod = null;
+    }
+  }
+
+  Debug debug;
+
+  /**
+   * Create class loader for specified bundle.
+   */
+  BundleClassLoader(final BundleGeneration gen) throws BundleException {
+    // otherwise getResource will bypass OUR parent
+    super(gen.bundle.fwCtx.parentClassLoader);
+
+    fwCtx = gen.bundle.fwCtx;
+    debug = fwCtx.debug;
+    secure = fwCtx.perm;
+    protectionDomain = gen.getProtectionDomain();
+    bpkgs = gen.bpkgs;
+    archive = gen.archive;
+    classPath = new BundleClassPath(archive, gen.fragments, fwCtx);
+    fwCtx.bundleClassLoaderCreated(this);
+    if (debug.classLoader) {
+      debug.println(this + " Created new classloader");
+    }
+  }
+
+  /**
+   * Find bundle class to load. First check if this load comes from an imported
+   * package. Otherwise load class from our bundle.
+   * 
+   * @see java.lang.ClassLoader#findClass
+   */
+  @Override
+  protected Class<?> findClass(String name) throws ClassNotFoundException {
+    if (name.startsWith("java.")) {
+      return fwCtx.parentClassLoader.loadClass(name);
+    }
+    if (fwCtx.isBootDelegated(name)) {
+      try {
+        final Class<?> bootDelegationCls = fwCtx.parentClassLoader.loadClass(name);
+        if (debug.classLoader && bootDelegationCls != null) {
+          debug.println(this + " findClass: " + name + " boot delegation: " + bootDelegationCls);
+        }
+        return bootDelegationCls;
+      } catch (final ClassNotFoundException e) {
+      }
+    }
+    String path;
+    String pkg;
+    final int pos = name.lastIndexOf('.');
+    if (pos != -1) {
+      path = name.replace('.', '/');
+      pkg = name.substring(0, pos);
+    } else {
+      path = name;
+      pkg = null;
+    }
+    Class<?> res = (Class<?>) secure.callSearchFor(this, name, pkg, path + ".class",
+                                                   classSearch, ONLY_FIRST, this, null);
+    if (res != null) {
+      return res;
+    }
+
+    if (!fwCtx.props.STRICTBOOTCLASSLOADING) {
+      if (isBootClassContext(name)) {
+        if (debug.classLoader) {
+          debug.println(this + " trying parent loader for class=" + name
+                        + ", since it was loaded on the system loader itself");
+        }
+        res = fwCtx.parentClassLoader.loadClass(name);
+        if (res != null) {
+          if (debug.classLoader) {
+            debug.println(this + " loaded " + name + " from " + fwCtx.parentClassLoader);
+          }
+        }
+        return res;
+      }
+    }
+
+    throw new ClassNotFoundException(name);
+  }
+
+  /**
+   * Find native library code to load.
+   * 
+   * @see java.lang.ClassLoader#findLibrary
+   */
+  @Override
+  protected String findLibrary(String name) {
+    final String res = secure.callFindLibrary0(this, name);
+    if (debug.classLoader) {
+      debug.println(this + " Find library: " + name + (res != null ? " OK" : " FAIL"));
+    }
+    return res;
+  }
+
+  /**
+   * Returns an Enumeration of all the resources with the given name.
+   * 
+   * @see java.lang.ClassLoader#findResources
+   */
+  @Override
+  protected Enumeration<URL> findResources(String name) {
+    // Step 1 and 2 are done by getResources
+    return getBundleResources(name, false);
+  }
+
+  /**
+   * Finds the resource with the given name.
+   * 
+   * @see java.lang.ClassLoader#findResource
+   */
+  @Override
+  protected URL findResource(String name) {
+    final Enumeration<URL> res = getBundleResources(name, true);
+    if (res != null) {
+      return res.nextElement();
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Wrapper class around SecurityManager which exposes the getClassLoader()
+   * method.
+   */
+  static class SecurityManagerExposer extends SecurityManager {
+    @Override
+    public Class<?>[] getClassContext() {
+      return super.getClassContext();
+    }
+  }
+
+  static protected SecurityManagerExposer smex = new SecurityManagerExposer();
+
+  /**
+   * @return <code>true</code> if the given class is not loaded by a bundle
+   *         class loader, <code>false</false> otherwise.
+   */
+  private boolean isNonBundleClass(Class<?> cls) {
+    return (this.getClass().getClassLoader() != cls.getClassLoader())
+           && !ClassLoader.class.isAssignableFrom(cls) && !Class.class.equals(cls)
+           && !Proxy.class.equals(cls);
+  }
+
+  /**
+   * Check if the current call is made from a class loaded on the boot class
+   * path (or rather, on a class loaded from something else than a bundle class
+   * loader)
+   * 
+   * @param name
+   *          The name of the class to load.
+   */
+  public boolean isBootClassContext(String name) {
+    Class<?>[] classStack = smex.getClassContext();
+
+    if (classStack == null) { // Android 4.0 returns null
+      // TODO: Find a cheaper and better solution
+      try {
+        final StackTraceElement[] classNames = new Throwable().getStackTrace();
+        classStack = new Class[classNames.length];
+        for (int i = 1; i < classNames.length; i++)
+          classStack[i] = Class.forName(classNames[i].getClassName());
+      } catch (final ClassNotFoundException e) {
+        return false;
+      }
+    }
+
+    for (int i = 1; i < classStack.length; i++) {
+      final Class<?> currentCls = classStack[i];
+      if (isNonBundleClass(currentCls)) {
+        final ClassLoader currentCL = currentCls.getClassLoader();
+
+        // If any of the classloaders for the caller's class is
+        // a BundleClassLoader, we're not in a VM class context
+        // ANDROID FIX, android-7/8 unexpectedly returns
+        // java.lang.BootClassLoader as the ClassLoader for the
+        // BootClassLoader Class other jvm's return null
+        for (ClassLoader cl = currentCL; cl != null && cl != cl.getClass().getClassLoader(); cl = cl.getClass()
+                                                                                                    .getClassLoader()) {
+          if (BundleClassLoader.class.isInstance(cl)) {
+            return false;
+          }
+        }
+        return !Bundle.class.isInstance(classStack[i - 1]);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Find Class and load it. This function is abstract in PJava 1.2 so we define
+   * it here to work as closely as it can to Java 2. Should work okey if we
+   * don't use the Java 2 stuff.
+   * 
+   * @param name
+   *          the name of the class
+   * @param resolve
+   *          if <code>true</code> then resolve the class
+   * @return the resulting <code>Class</code> object
+   * @exception ClassNotFoundException
+   *              if the class could not be found
+   * @see java.lang.ClassLoader#loadClass
+   */
+  @Override
+  protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+    Class<?> c = findLoadedClass(name);
+    if (c == null) {
+      c = findClass(name);
+    } else if (secure.getClassLoaderOf(c) == this) {
+      // Handle bundles that are lazely started after having been
+      // stopped. In this case the triggering classes will already
+      // be loaded. Only consider classes loaded by this classloader
+      final BundleImpl b = (BundleImpl) getBundle();
+      if (b.triggersActivationCls(name)) {
+        if (debug.lazy_activation) {
+          debug.println(this + " lazy activation of #" + b.id + " triggered by loadClass("
+                        + name + ")");
+        }
+
+        final ArrayList<BundleImpl> bundlesToActivate = tlBundlesToActivate.get();
+        if (null == bundlesToActivate) {
+          // Not part of a load chain; activate bundle here.
+          if (debug.lazy_activation) {
+            debug.println(this + " requesting lazy activation of #" + b.id);
+          }
+          try {
+            secure.callFinalizeActivation(b);
+          } catch (final BundleException e) {
+            fwCtx.frameworkError(b, e);
+          }
+        } else {
+          // add bundle to list of bundles to activate when the
+          // initiator class has been loaded.
+          boolean bundlePresent = false;
+          for (int i = 0, size = bundlesToActivate.size(); i < size; i++) {
+            final BundleImpl tmp = bundlesToActivate.get(i);
+            if (tmp.id == b.id) {
+              bundlePresent = true;
+              break;
+            }
+          }
+          if (!bundlePresent) {
+            bundlesToActivate.add(b);
+            if (debug.lazy_activation) {
+              debug.println(this + " added #" + b.id + " to list of bundles to be activated.");
+            }
+          }
+        }
+      }
+    }
+
+    if (resolve) {
+      resolveClass(c);
+    }
+    return c;
+  }
+
+  /**
+   * Finds the resource with the given name. This is defined a little different
+   * in PJava 1.2 versus Java 2. So we first try to use the super() version and
+   * if it fails we try to find it in the local bundle.
+   * 
+   * @param name
+   *          resource name
+   * @return an URL to resource, or <code>null</code> if the resource could not
+   *         be found or the caller doesn't have adequate privileges to get the
+   *         resource.
+   * @see java.lang.ClassLoader#getResource
+   */
+  @Override
+  public URL getResource(String name) {
+    if (debug.classLoader) {
+      debug.println(this + " getResource: " + name);
+    }
+    URL res = null;
+    if (name.startsWith("java/")) {
+      res = fwCtx.parentClassLoader.getResource(name);
+      if (debug.classLoader) {
+        debug.println(this + " getResource: " + name + " file in java pkg: " + res);
+      }
+      return res;
+    }
+
+    if (fwCtx.isBootDelegatedResource(name)) {
+      res = fwCtx.parentClassLoader.getResource(name);
+      if (res != null) {
+        if (debug.classLoader) {
+          debug.println(this + " getResource: " + name + " boot delegation: " + res);
+        }
+        return res;
+      }
+    }
+
+    res = findResource(name);
+    if (debug.classLoader) {
+      debug.println(this + " getResource: " + name + " bundle space: " + res);
+    }
+    return res;
+  }
+
+  // We would like to use the following implementation of
+  // getResources() but that method is final in JDK 1.4
+  // thus we can not redefine it here.
+  /**
+   * Finds all the resources with the given name. A resource is some data
+   * (images, audio, text, etc) that can be accessed by class code in a way that
+   * is independent of the location of the code.
+   * 
+   * <p>
+   * The name of a resource is a <tt>/</tt>-separated path name that identifies
+   * the resource.
+   * 
+   * @param name
+   *          resource name
+   * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for the
+   *         resource. If no resources could be found, the enumeration will be
+   *         empty. Resources that the class loader doesn't have access to will
+   *         not be in the enumeration.
+   * 
+   * @see java.lang.ClassLoader#getResources
+   * @see org.osgi.framework.Bundle#getResources(String name)
+   * 
+   */
+  public Enumeration<URL> getResourcesOSGi(String name) throws IOException {
+    if (debug.classLoader) {
+      debug.println(this + " getResources: " + name);
+    }
+    final int start = name.startsWith("/") ? 1 : 0;
+    if (name.substring(start).startsWith("java/")) {
+      return fwCtx.parentClassLoader.getResources(name);
+    }
+
+    Enumeration<URL> res = null;
+    if (fwCtx.isBootDelegatedResource(name)) {
+      res = fwCtx.parentClassLoader.getResources(name);
+    }
+
+    if (res == null || !res.hasMoreElements()) {
+      res = findResources(name);
+    }
+    return res;
+  }
+
+  /**
+   * Finds the resource with the given name and returns the InputStream. The
+   * method is overridden to make sure it does the right thing.
+   * 
+   * @param name
+   *          resource name
+   * @return an InputStream to resource, or <code>null</code> if the resource
+   *         could not be found or the caller doesn't have adequate privileges
+   *         to get the resource.
+   * @see java.lang.ClassLoader#getResourceAsStream
+   */
+  @Override
+  public InputStream getResourceAsStream(String name) {
+    try {
+      final URL url = getResource(name);
+      if (url != null) {
+        return url.openStream();
+      }
+    } catch (final IOException ignore) {
+    }
+    return null;
+  }
+
+  /**
+   * Return a string representing this object
+   * 
+   * @return A message string.
+   */
+  @Override
+  public String toString() {
+    return "BundleClassLoader("
+    // +"fw=" +bpkgs.bundle.fwCtx.hashCode()
+           + "id=" + bpkgs.bg.bundle.id + ",gen=" + bpkgs.bg.generation + ")";
+  }
+
+  // Implements BundleReference
+  public Bundle getBundle() {
+    return bpkgs.bg.bundle;
+  }
+
+  //
+  // BundleClassLoader specific
+  //
+
+  /**
+   * Close down this classloader. We don't give out any new classes. Perhaps we
+   * should block all classloads.
+   */
+  void close() {
+    archive = null;
+    fwCtx.bundleClassLoaderClosed(this);
+    if (debug.classLoader) {
+      debug.println(this + " Cleared archives");
+    }
+  }
+
+  /**
+   * Get all the resources with the given name in this bundle.
+   * 
+   */
+  Enumeration<URL> getBundleResources(String name, boolean onlyFirst) {
+    // Removed this check pending outcome of OSGi bug 1489.
+    // if (secure.okResourceAdminPerm(bpkgs.bundle)) {
+    if (debug.classLoader) {
+      debug.println(this + " Find bundle resource" + (onlyFirst ? "" : "s") + ": " + name);
+    }
+    String pkg = null;
+    final int pos = name.lastIndexOf('/');
+    if (pos > 0) {
+      final int start = name.startsWith("/") ? 1 : 0;
+      pkg = name.substring(start, pos).replace('/', '.');
+    } else {
+      pkg = null;
+    }
+    @SuppressWarnings("unchecked")
+    final Enumeration<URL> res = (Enumeration<URL>) secure.callSearchFor(this, null, pkg, name,
+                                                                         resourceSearch,
+                                                                         onlyFirst ? ONLY_FIRST
+                                                                                  : 0, this,
+                                                                         null);
+    return res;
+    // } else {
+    // return null;
+    // }
+  }
+
+  /**
+   * Get bundle package handler.
+   * 
+   */
+  BundlePackages getBpkgs() {
+    return bpkgs;
+  }
+
+  /**
+   * Attach fragment to classloader.
+   * 
+   * @throws BundleException
+   * 
+   */
+  void attachFragment(BundleGeneration gen) throws BundleException {
+    if (debug.classLoader) {
+      debug.println(this + " fragment attached update classpath");
+    }
+    classPath.attachFragment(gen);
+  }
+
+  Collection<String> listResources(String path, String filePattern, int options) {
+    if (debug.classLoader) {
+      debug.println(this + " List bundle resources: " + path + ", pattern=" + filePattern);
+    }
+    if (path.startsWith("/")) {
+      path = path.substring(1);
+    }
+    if (path.endsWith("/")) {
+      path = path.substring(0, path.length() - 1);
+    }
+    // TODO handle . within path
+    String pkg = path.replace('/', '.');
+
+    @SuppressWarnings("unchecked")
+    final Set<String> res = (Set<String>)
+      secure.callSearchFor(this, filePattern, pkg, path, listSearch,
+                           (options << 8) | LIST, this, null);
+    return res;
+  }
+
+  //
+  // Private
+  //
+
+  /**
+   * Searches for and loads classes and resources according to OSGi search
+   * order. When lazy activation of bundles are used this method will detect and
+   * perform the activation. The actual searching and loading is done in
+   * {@link #searchFor0()}
+   * 
+   * @param name
+   *          Name of class or pattern we are looking for, null if we look for a
+   *          resource
+   * @param pkg
+   *          Package name for item
+   * @param path
+   *          File path to item searched ("/" separated)
+   * @param action
+   *          Action to be taken when item is found
+   * @param options
+   *          Options controlling what should be included in search result.
+   * 
+   * @return Object returned from action class.
+   */
+  Object searchFor(String name, String pkg, String path, SearchAction action, int options,
+                   BundleClassLoader requestor, HashSet<BundleClassLoader> visited) {
+    try {
+      final BundleImpl b = (BundleImpl) getBundle();
+      boolean initiator = false;
+      ArrayList<BundleImpl> bundlesToActivate = null;
+
+      if (action == classSearch) {
+        boolean bundlePresent = false;
+
+        bundlesToActivate = tlBundlesToActivate.get();
+        initiator = bundlesToActivate == null;
+        if (initiator) {
+          bundlesToActivate = new ArrayList<BundleImpl>();
+          tlBundlesToActivate.set(bundlesToActivate);
+        } else {
+          bundlePresent = bundlesToActivate.contains(b);
+        }
+        if (!bundlePresent && b.triggersActivationPkg(pkg)) {
+          bundlesToActivate.add(b);
+          if (debug.lazy_activation) {
+            debug.println(this + " lazy activation of #" + b.id + " triggered by searchFor("
+                          + name + ")");
+          }
+        }
+      }
+
+      final Object res = searchFor0(name, pkg, path, action, options, requestor, visited);
+
+      if (initiator) {
+        tlBundlesToActivate.set(null);
+        for (int i = bundlesToActivate.size() - 1; i >= 0; i--) {
+          final BundleImpl tmp = bundlesToActivate.get(i);
+          if (debug.lazy_activation) {
+            debug.println(this + " requesting lazy activation of #" + tmp.id);
+          }
+          try {
+            tmp.finalizeActivation();
+          } catch (final BundleException e) {
+            fwCtx.frameworkError(tmp, e);
+          }
+        }
+      }
+      return res;
+    } catch (final Error te) {
+      tlBundlesToActivate.set(null);
+      throw te;
+    }
+  }
+
+  /**
+   * Search for classloader to use according to OSGi search order.
+   * 
+   * 3 If the class or resource is in a package that is imported using
+   * Import-Package or was imported dynamically in a previous load, then the
+   * request is delegated to the exporting bundles class loader; otherwise the
+   * search continues with the next step. If the request is delegated to an
+   * exporting class loader and the class or resource is not found, then the
+   * search terminates and the request fails.
+   * 
+   * 4 If the class or resource is in a package that is imported from one or
+   * more other bundles using Require-Bundle, the request is delegated to the
+   * class loaders of the other bundles, in the order in which they are
+   * specified in this bundles manifest. If the class or resource is not found,
+   * then the search continues with the next step.
+   * 
+   * 5 The bundles own internal bundle class path is searched. If the class or
+   * resource is not found, then the search continues with the next step.
+   * 
+   * 6 Each attached fragment's internal bundle class path is searched. The
+   * fragments are searched in ascending bundle ID order. If the class or
+   * resource is not found, then the search continues with the next step.
+   * 
+   * 7 If the class or resource is in a package that is exported by the bundle
+   * or the package is imported by the bundle (using Import-Package or
+   * Require-Bundle), then the search ends and the class or resource is not
+   * found.
+   * 
+   * 8 Otherwise, if the class or resource is in a package that is imported
+   * using DynamicImport-Package, then a dynamic import of the package is now
+   * attempted. An exporter must conform to any implied package constraints. If
+   * an appropriate exporter is found, a wire is established so that future
+   * loads of the package are handled in Step 3. If a dynamic wire is not
+   * established, then the request fails.
+   * 
+   * 9 If the dynamic import of the package is established, the request is
+   * delegated to the exporting bundle's class loader. If the request is
+   * delegated to an exporting class loader and the class or resource is not
+   * found, then the search terminates and the request fails.
+   * 
+   * @param name
+   *          Name of class or null if we look for a resource
+   * @param pkg
+   *          Package name for item
+   * @param path
+   *          File path to item searched ("/" separated)
+   * @param action
+   *          Action to be taken when item is found
+   * @param onlyFirst
+   *          Stop search when first matching item is found.
+   * 
+   * @return Object returned from action class.
+   */
+  Object searchFor0(String name, String pkg, String path, SearchAction action, int options,
+                    BundleClassLoader requestor, HashSet<BundleClassLoader> visited) {
+    BundlePackages pbp;
+    Iterator<ExportPkg> ep;
+
+    // TODO, Should this be an action method
+    if (action == classSearch && requestor != this) {
+      final Class<?> c = findLoadedClass(name);
+      if (c != null) {
+        return c;
+      }
+    }
+    final boolean list = (options & LIST) != 0;
+    final boolean local = (options & LOCAL) != 0;
+    final boolean recurse = (options & RECURSE) != 0;
+    Object answer = null;
+    if (debug.classLoader) {
+      debug.println(this + " Search for: " + path);
+    }
+    /* 3 */
+    if (pkg != null) {
+      pbp = bpkgs.getProviderBundlePackages(pkg);
+      if (pbp != null) {
+        final ClassLoader cl = pbp.getClassLoader();
+        if (!local || cl == this) {
+          if (isSystemBundle(pbp.bg.bundle)) {
+            answer = frameworkSearchFor(cl, name, path, action);
+            if (!recurse) {
+              return answer;
+            }
+          } else {
+            final BundleClassLoader bcl = (BundleClassLoader) cl;
+            // Second check avoids a loop when a required bundle imports a
+            // package from its requiring host that it self should
+            // provide contents for to the requiring bundle.
+            if (bcl != this && (visited == null || (bcl != null && !visited.contains(bcl)))) {
+              if (bcl != null) {
+                if (debug.classLoader) {
+                  debug.println(this + " Import search: " + path + " from #" + pbp.bg.bundle.id);
+                }
+                answer = secure.callSearchFor(bcl, name, pkg, path, action, options & ~RECURSE,
+                                              requestor, visited);
+              } else {
+                if (debug.classLoader) {
+                  debug.println(this + " No import found: " + path);
+                }
+              }
+              if (!recurse) {
+                return answer;
+              }
+            }
+          }
+        }
+        if (cl != this) {
+          // Import checked we don't need to list any more in this directory.
+          options |= ONLY_RECURSE;
+        }
+      } else if (!local) {
+        /* 4 */
+        final ArrayList<BundleGeneration> pl = bpkgs.getRequiredBundleGenerations(pkg);
+        if (pl != null) {
+          if (visited == null) {
+            visited = new HashSet<BundleClassLoader>();
+          }
+          visited.add(this);
+          for (final BundleGeneration pbg : pl) {
+            final ClassLoader cl = pbg.getClassLoader();
+            if (cl instanceof BundleClassLoader) {
+              final BundleClassLoader bcl = (BundleClassLoader)cl;
+              if (bcl != null && !visited.contains(bcl)) {
+                if (debug.classLoader) {
+                  debug.println(this + " Required bundle search: " + path + " from #"
+                                + pbg.bundle.id);
+                }
+                answer = secure.callSearchFor(bcl, name, pkg, path, action, options,
+                                              requestor, visited);
+              }
+            } else {
+              answer = frameworkSearchFor(cl, name, path, action);
+            }
+            if (answer != null) {
+              if (list || recurse) {
+                break;
+              } else {
+                return answer;
+              }
+            }
+          }
+          if (debug.classLoader && answer == null) {
+            debug.println(this + " Required bundle search: "
+                          + "Not found, continuing with local search.");
+          }
+        }
+      }
+      ep = bpkgs.getExports(pkg);
+    } else {
+      ep = null;
+    }
+    /* 5 + 6 */
+    if (this != requestor && ep != null) {
+      // TODO should we block resources?
+      if (action == classSearch) {
+        boolean blocked = true;
+        while (ep.hasNext()) {
+          if (ep.next().checkFilter(name)) {
+            blocked = false;
+            break;
+          }
+        }
+        if (blocked) {
+          if (debug.classLoader) {
+            debug.println(this + " Filter check blocked search for: " + name);
+          }
+          return null;
+        }
+      }
+    }
+    final Vector<FileArchive> av = classPath.componentExists(path, (options & ONLY_FIRST) != 0,
+                                                             (options & LIST) != 0);
+    if (av != null || recurse) {
+      try {
+        Object res = action.get(av, path, name, pkg, options, requestor, this);
+        if (answer != null) {
+          if (res != null) {
+            @SuppressWarnings("unchecked")
+            Collection<Object> ca = (Collection<Object>) answer;
+            @SuppressWarnings("unchecked")
+            Collection<Object> cr = (Collection<Object>) res;
+            ca.addAll(cr);
+          }
+        } else {
+          answer = res;
+        }
+        return answer;
+      } catch (final ClassFormatError cfe) {
+        // TODO: OSGI43 WeavingHook CT has some specific demands that
+        // ClassFormatErrors are thrown that doesn't seem to be in the spec
+        throw cfe;
+      } catch (final IOException ioe) {
+        fwCtx.frameworkError(bpkgs.bg.bundle, ioe);
+        return null;
+      }
+    }
+
+    /* 7 */
+    if (ep != null || (options & LIST) != 0) {
+      return null;
+    }
+    /* 8 */
+    if (pkg != null) {
+      pbp = bpkgs.getDynamicProviderBundlePackages(pkg);
+      if (pbp != null) {
+        /* 9 */
+        if (isSystemBundle(pbp.bg.bundle)) {
+          try {
+            return fwCtx.systemBundle.getClassLoader().loadClass(name);
+          } catch (final ClassNotFoundException e) {
+            // continue
+          }
+        } else {
+          final BundleClassLoader cl = (BundleClassLoader) pbp.getClassLoader();
+          if (cl != null) {
+            if (debug.classLoader) {
+              debug.println(this + " Dynamic import search: " + path + " from #"
+                            + pbp.bg.bundle.id);
+            }
+            return secure.callSearchFor(cl, name, pkg, path, action, options, requestor,
+                                        visited);
+          }
+        }
+      }
+      if (debug.classLoader) {
+        debug.println(this + " No dynamic import: " + path);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Get resources/classes from the framework.
+   * Rewrite this since this solution will leak
+   * resources that aren't bootdelegated.
+   * 
+   * @param cl
+   * @param name
+   * @param path
+   * @param action
+   * @return
+   */
+  private Object frameworkSearchFor(final ClassLoader cl, String name, String path,
+                                    SearchAction action) {
+    if (action == classSearch) {
+      try {
+        return cl.loadClass(name);
+      } catch (final ClassNotFoundException e) {
+      }
+    } else if (action == resourceSearch) {
+      try {
+        return cl.getResources(path);
+      } catch (IOException e) {
+      }
+    } else if (action == listSearch) {
+      // TODO, listSearch
+      throw new UnsupportedOperationException("listResources not available on system bundle");
+    }
+    return null;
+  }
+
+  private static boolean isSystemBundle(BundleImpl bundle) {
+    return bundle == bundle.fwCtx.systemBundle;
+  }
+
+  /**
+   * Search action
+   */
+  interface SearchAction {
+    public abstract Object get(Vector<FileArchive> items, String path, String name, String pkg,
+                               int options, BundleClassLoader requestor, BundleClassLoader cl)
+                                                                                              throws IOException;
+  }
+
+  /**
+   * Search action for class searching
+   */
+  static final SearchAction classSearch = new SearchAction() {
+    public Object get(Vector<FileArchive> items, String path, String name, String pkg,
+                      int options, BundleClassLoader requestor, BundleClassLoader cl)
+                                                                                     throws IOException {
+      byte[] bytes = items.get(0).getClassBytes(path);
+      if (bytes != null) {
+        if (cl.debug.classLoader) {
+          cl.debug.println("classLoader(#" + cl.bpkgs.bg.bundle.id + ") - load class: " + name);
+        }
+        synchronized (cl) {
+          Class<?> c = cl.findLoadedClass(name);
+          if (c == null) {
+            if (pkg != null) {
+              if (cl.getPackage(pkg) == null) {
+                cl.definePackage(pkg, null, null, null, null, null, null, null);
+              }
+            }
+
+            // Use dalvik DexFile class loading when running
+            // on the dalvik VM
+            if (bDalvik) {
+              try {
+                c = cl.getDexFileClass(name);
+              } catch (final Exception e) {
+                throw new IOException("Failed to load dex class '" + name + "', " + e);
+              }
+            }
+
+            if (c == null) {
+
+              WeavingHooks.WovenClassImpl wc = null;
+              if (cl != null && cl.bpkgs != null && cl.bpkgs.bg != null
+                  && cl.bpkgs.bg.bundle != null) {
+                wc = new WeavingHooks.WovenClassImpl(cl.bpkgs.bg.bundle, name, bytes);
+                try {
+                  cl.fwCtx.weavingHooks.callHooks(wc);
+                  if (wc.hasAdditionalDynamicImports()) {
+                    cl.bpkgs.parseDynamicImports(wc.getDynamicImportsAsString());
+                  }
+                  bytes = wc.getBytes();
+                } catch (final ClassFormatError cfe) {
+                  throw cfe;
+                } catch (final Throwable t) {
+                  final ClassFormatError cfe = new ClassFormatError(
+                                                                    "Failed to call WeavingHooks for "
+                                                                        + name);
+                  cfe.initCause(t);
+                  throw cfe;
+                }
+              }
+              if (cl.protectionDomain == null) {
+                // Kaffe can't handle null protectiondomain
+                c = cl.defineClass(name, bytes, 0, bytes.length);
+              } else {
+                c = cl.defineClass(name, bytes, 0, bytes.length, cl.protectionDomain);
+              }
+
+              if (wc != null) {
+                wc.setDefinedClass(c);
+              }
+            }
+          }
+          return c;
+        }
+      }
+      return null;
+    }
+  };
+
+  private void walkAndAddJars(List<Object> dexlist, String path) throws Exception {
+    final File root = new File(path);
+    final File[] list = root.listFiles();
+
+    for (final File f : list) {
+      if (f.isDirectory()) {
+        walkAndAddJars(dexlist, f.getAbsolutePath());
+      } else {
+        if (f.getAbsolutePath().endsWith(".jar")) {
+          if (debug.classLoader) {
+            debug.println("creating DexFile from " + f.getAbsolutePath());
+          }
+          final Object dex = dexFileClassLoadDexMethod.invoke(null,
+                                                              new Object[] {
+                                                                            f.getAbsolutePath(),
+                                                                            f.getAbsolutePath()
+                                                                                + ".dexopt",
+                                                                            new Integer(0) });
+          dexlist.add(dex);
+        }
+      }
+    }
+  }
+
+  /**
+   * Load a class using the Dalvik DexFile API.
+   * <p>
+   * This relies in the bundle having a "classes.dex" in its root
+   * <p>
+   * TODO: We should create a specific bundle storage module for DEX files.
+   * <p>
+   * 
+   * To create such a bundle, do
+   * <ol>
+   * <li><code>dx --dex --output=classes.dex bundle.jar</code>
+   * <li><code>aapt add bundle.jar classes.dex</code>
+   * </ol>
+   */
+  private Class<?> getDexFileClass(String name) throws Exception {
+    if (debug.classLoader) {
+      debug.println("loading dex class " + name);
+    }
+
+    if (dexFile == null) {
+      dexFile = new ArrayList<Object>();
+      final File f = new File(archive.getJarLocation());
+      if (!f.isDirectory()) {
+        if (debug.classLoader) {
+          debug.println("creating DexFile from " + f);
+        }
+        final Object dex = dexFileClassLoadDexMethod.invoke(null,
+                                                            new Object[] {
+                                                                          f.getAbsolutePath(),
+                                                                          f.getAbsolutePath()
+                                                                              + ".dexopt",
+                                                                          new Integer(0) });
+        dexFile.add(dex);
+        if (debug.classLoader) {
+          debug.println("created DexFile from " + f);
+        }
+      } else {
+        // if it has an internal jar file then it was unpacked into a folder
+        if (debug.classLoader) {
+          System.err.println("creating DexFile from " + f + "/classes.dex");
+        }
+        final Object dex = dexFileClassLoadDexMethod.invoke(null,
+                                                            new Object[] {
+                                                                          f.getAbsolutePath()
+                                                                              + "/classes.dex",
+                                                                          f.getAbsolutePath()
+                                                                              + ".dexopt",
+                                                                          new Integer(0) });
+        dexFile.add(dex);
+        if (debug.classLoader) {
+          debug.println("created DexFile from " + f + File.pathSeparatorChar + "classes.dex");
+        }
+        // check for internal jar files
+        walkAndAddJars(dexFile, f.getAbsolutePath());
+      }
+    }
+
+    final String path = name.replace('.', '/');
+
+    final Iterator<Object> i = dexFile.iterator();
+    while (i.hasNext()) {
+      final Object dex = i.next();
+      if (debug.classLoader) {
+        debug.println("trying to load " + path + " from " + dex);
+      }
+      try {
+        final Class<?> clz = (Class<?>) dexFileClassLoadClassMethod.invoke(dex,
+                                                                           new Object[] { path,
+                                                                                         this });
+        if (clz != null) {
+          if (debug.classLoader) {
+            debug.println("loaded " + path + " from " + dex);
+          }
+          return clz;
+        }
+      } catch (final Exception e) {
+      }
+      if (debug.classLoader) {
+        debug.println("failed to load " + path + " from " + dex);
+      }
+    }
+
+    throw new ClassNotFoundException("could not find dex class " + path);
+  }
+
+  /**
+   * Search action for resource searching
+   */
+  static final SearchAction resourceSearch = new SearchAction() {
+    public Object get(Vector<FileArchive> items, String path, String name, String pkg,
+                      int options, BundleClassLoader requestor, BundleClassLoader cl)
+                                                                                     throws IOException {
+      final Vector<URL> answer = new Vector<URL>();
+      for (int i = 0; i < items.size(); i++) {
+        final FileArchive fa = items.elementAt(i);
+        final URL url = fa.getBundleGeneration().getURL(fa.getSubId(), path);
+        if (url != null) {
+          if (cl.debug.classLoader) {
+            cl.debug.println("classLoader(#" + cl.bpkgs.bg.bundle.id + ") - found: " + path
+                             + " -> " + url);
+          }
+          answer.addElement(url);
+        } else {
+          return null;
+        }
+      }
+      return answer.elements();
+    }
+  };
+
+  /**
+   * Search action for listResource searching
+   */
+  static final SearchAction listSearch = new SearchAction() {
+    public Object get(Vector<FileArchive> items, String path, String name, String pkg,
+                      int options, BundleClassLoader requestor, BundleClassLoader cl)
+      throws IOException
+    {
+      Set<String> answer = new HashSet<String>();
+      boolean onlyRecurse = (options & ONLY_RECURSE) != 0;
+      HashSet<String> scanned = new HashSet<String>();
+      for (String subPkg : cl.bpkgs.getSubProvider(pkg)) {
+        if ((options & RECURSE) != 0) {
+          String next = path.length() > 0 ? path + "/" + subPkg : subPkg;
+          @SuppressWarnings("unchecked")
+          Set<String> subAnswer = (Set<String>) cl.searchFor(name, next.replace('/', '.'),
+                                                             next, listSearch,
+                                                             options & ~ONLY_RECURSE,
+                                                             requestor, null);
+          if (subAnswer != null) {
+            answer.addAll(subAnswer);
+          }
+        }
+        if (!onlyRecurse && (name == null || Util.filterMatch(name, subPkg))) {
+          answer.add(path + "/" + subPkg);
+        }
+        scanned.add(subPkg + "/");
+      }
+      if (items != null) {
+        for (FileArchive fa : items) {
+          for (String e : fa.listDir(path)) {
+            if (scanned.contains(e)) {
+              if (cl.debug.classLoader) {
+                cl.debug.println("classLoader(#" + cl.bpkgs.bg.bundle.id + ") - list search skip: " + e);
+              }
+              continue;
+            } else if (cl.debug.classLoader) {
+              cl.debug.println("classLoader(#" + cl.bpkgs.bg.bundle.id +
+                  ") - list search check: " + e + (onlyRecurse ? " (scan)" : ""));
+            }
+            if (e.endsWith("/")) {
+              e = e.substring(0, e.length() - 1);
+              if ((options & RECURSE) != 0) {
+                String next = path.length() > 0 ? path + "/" + e : e;
+                @SuppressWarnings("unchecked")
+                Set<String> subAnswer = (Set<String>) cl.searchFor(name,
+                                                                   next.replace('/', '.'),
+                                                                   next, listSearch,
+                                                                   options & ~ONLY_RECURSE,
+                                                                   requestor, null);
+                if (subAnswer != null) {
+                  answer.addAll(subAnswer);
+                }
+              }
+            }
+            if (!onlyRecurse && (name == null || Util.filterMatch(name, e))) {
+              answer.add(path + "/" + e);
+              if (cl.debug.classLoader) {
+                cl.debug.println("classLoader(#" + cl.bpkgs.bg.bundle.id + ") - list search match: " + e);
+              }
+            }
+          }
+        }
+      }
+      return answer;
+    }
+  };
+
+  /**
+   * Find native library code to load. This method is called from
+   * findLibrary(name) within a doPriviledged-block via the secure object.
+   * 
+   */
+  String findLibrary0(final String name) {
+    return classPath.getNativeLibrary(name);
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleClassLoaderListener.java b/osgi/framework/src/org/knopflerfish/framework/BundleClassLoaderListener.java
new file mode 100644
index 0000000..bb58eea
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleClassLoaderListener.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package org.knopflerfish.framework;
+
+/**
+ * Bundle class loader life cycle listener interface.
+ *
+ * @author Makewave AB, Gunnar Ekolin
+ */
+public interface BundleClassLoaderListener {
+
+  /**
+   * Synchronously called when a new bundle class loader has been
+   * created.
+   *
+   * @param bcl the newly created bundle class loader.
+   */
+  void bundleClassLoaderCreated(BundleClassLoader bcl);
+
+  /**
+   * Synchronously called when a bundle class loader has been
+   * closed.
+   *
+   * @param bcl the closed down bundle class loader.
+   */
+  void bundleClassLoaderClosed(BundleClassLoader bcl);
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleClassPath.java b/osgi/framework/src/org/knopflerfish/framework/BundleClassPath.java
new file mode 100644
index 0000000..a87a51f
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleClassPath.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+/**
+ * Bundle Class Path handler.
+ *
+ * @author Jan Stein
+ */
+public class BundleClassPath {
+  /**
+   * Framework context.
+   */
+  final private FrameworkContext fwCtx;
+
+  /**
+   * Archives that we load code from.
+   */
+  private final ArrayList<FileArchive> archives = new ArrayList<FileArchive>(4);
+
+  /**
+   *
+   */
+  private Map<String, FileArchive> nativeLibs;
+
+  /**
+   *
+   */
+  private final Debug debug;
+
+  /**
+   *
+   */
+  private final long bid;
+
+
+  /**
+   * Create class loader for specified bundle.
+   *
+   * @throws BundleException if native code resolve failed.
+   */
+  BundleClassPath(BundleArchive ba, List<BundleGeneration> frags, FrameworkContext fwCtx)
+      throws BundleException {
+    this.fwCtx = fwCtx;
+    debug = fwCtx.debug;
+    bid = ba.getBundleId();
+    checkBundleArchive(ba, frags);
+    if (frags != null) {
+      for (final BundleGeneration bundleGeneration : frags) {
+        checkBundleArchive(bundleGeneration.archive, null);
+      }
+    }
+    resolveNativeCode(ba, false);
+    if (frags != null) {
+      for (final BundleGeneration bundleGeneration : frags) {
+        resolveNativeCode(bundleGeneration.archive, true);
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  BundleClassPath(BundleArchive ba, FrameworkContext fwCtx) {
+    this.fwCtx = fwCtx;
+    debug = fwCtx.debug;
+    bid = ba.getBundleId();
+    checkBundleArchive(ba, null);
+  }
+
+
+  /**
+   * @throws BundleException
+   *
+   */
+  void attachFragment(BundleGeneration gen) throws BundleException {
+    checkBundleArchive(gen.archive, null);
+    resolveNativeCode(gen.archive, true);
+  }
+
+
+  /**
+   * Check if named entry exist in bundle class path. Leading '/' is stripped.
+   *
+   * @param component Entry to get reference to.
+   * @param onlyFirst End search when we find first entry if this is true.
+   * @return Vector or entry numbers, or null if it doesn't exist.
+   */
+  Vector<FileArchive> componentExists(String component, boolean onlyFirst, boolean dirs) {
+    Vector<FileArchive> v = null;
+    if (component.startsWith("/")) {
+      component = component.substring(1);
+    }
+    if (debug.classLoader) {
+      debug.println(this + "compentExists: " + component);
+    }
+    if (0 == component.length()) {
+      // The special case asking for "/"
+      if (onlyFirst) {
+        v = new Vector<FileArchive>(1);
+        v.addElement(archives.get(0));
+        if (debug.classLoader) {
+          debug.println(this + "compentExists added first top in classpath.");
+        }
+      } else {
+        v = new Vector<FileArchive>(archives);
+        if (debug.classLoader) {
+          debug.println(this + "compentExists added all tops in classpath.");
+        }
+      }
+    } else {
+      for (final FileArchive fa : archives) {
+        if (fa.exists(component, dirs)) {
+          if (v == null) {
+            v = new Vector<FileArchive>();
+          }
+          v.addElement(fa);
+          if (debug.classLoader) {
+            debug.println(this + "compentExists added: " + fa);
+          }
+          if (onlyFirst) {
+            break;
+          }
+        }
+      }
+    }
+    return v;
+  }
+
+
+  /**
+   * Get an specific InputStream to named entry inside a bundle. Leading '/' is
+   * stripped.
+   *
+   * @param component Entry to get reference to.
+   * @param ix index of sub archives. A positive number is the classpath entry
+   *          index. 0 means look in the main bundle.
+   * @return InputStream to entry or null if it doesn't exist.
+   */
+  InputStream getInputStream(String component, int ix) {
+    if (component.startsWith("/")) {
+      component = component.substring(1);
+    }
+    return archives.get(ix).getBundleResourceStream(component);
+  }
+
+
+  /**
+   * Get native library from class path.
+   *
+   * @param libName Name of Jar file to get.
+   * @return A string with the path to the native library.
+   */
+  String getNativeLibrary(String libName) {
+    if (debug.classLoader) {
+      debug.println(this + "getNativeLibrary: lib=" + libName);
+    }
+    if (nativeLibs != null) {
+      String [] keys = new String [] { System.mapLibraryName(libName), libName };
+      FileArchive fa = null;
+      String key = null;
+      for (String k : keys) {
+        key = k;
+        if (debug.classLoader) {
+          debug.println(this + "getNativeLibrary: try, " + key);
+        }
+        fa = nativeLibs.get(key);
+        if (fa == null) {
+          // Try other non-default lib-extensions
+          final String libExtensions = fwCtx.props
+              .getProperty(Constants.FRAMEWORK_LIBRARY_EXTENSIONS);
+          final int pos = key.lastIndexOf(".");
+          if (libExtensions.length() > 0 && pos > -1) {
+            final String baseKey = key.substring(0, pos + 1);
+            final String[] exts = Util.splitwords(libExtensions, ", \t");
+            for (final String ext : exts) {
+              key = baseKey + ext;
+              if (debug.classLoader) {
+                debug.println(this + "getNativeLibrary: try, " + key);
+              }
+              fa = nativeLibs.get(key);
+              if (fa != null) {
+                break;
+              }
+            }
+          }
+        }
+        if (fa != null) {
+          break;
+        }
+      }
+      if (fa == null) {
+        return null;
+      }
+      if (debug.classLoader) {
+        debug.println(this + "getNativeLibrary: got, " + fa);
+      }
+      return fa.getNativeLibrary(key);
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public String toString() {
+    return "BundleClassPath(#" + bid + ").";
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   *
+   */
+  private void checkBundleArchive(BundleArchive ba, List<BundleGeneration> frags) {
+    final String bcp = ba.getAttribute(Constants.BUNDLE_CLASSPATH);
+
+    if (bcp != null) {
+      final StringTokenizer st = new StringTokenizer(bcp, ",");
+      while (st.hasMoreTokens()) {
+        final String path = st.nextToken().trim();
+        FileArchive a = ba.getFileArchive(path);
+        if (a == null && frags != null) {
+          for (final BundleGeneration bundleGeneration : frags) {
+            a = bundleGeneration.archive.getFileArchive(path);
+            if (a != null) {
+              break;
+            }
+          }
+        }
+        if (a != null) {
+          archives.add(a);
+          if (debug.classLoader) {
+            debug.println(this + "- Added path entry: " + a);
+          }
+        } else {
+          fwCtx.frameworkWarning(ba.getBundleGeneration().bundle,
+              new IllegalArgumentException(Constants.BUNDLE_CLASSPATH + " entry " + path
+                  + " not found in bundle"));
+          if (debug.classLoader) {
+            debug.println(this + "- Failed to find class path entry: " + path);
+          }
+        }
+      }
+    } else {
+      archives.add(ba.getFileArchive("."));
+    }
+  }
+
+
+  /**
+   * Resolve native code libraries.
+   *
+   * @throws BundleException if native code resolve failed.
+   */
+  private void resolveNativeCode(BundleArchive ba, boolean isFrag) throws BundleException {
+    final String bnc = ba.getAttribute(Constants.BUNDLE_NATIVECODE);
+    if (bnc != null) {
+      final ArrayList<String> proc = new ArrayList<String>(3);
+      final String procP = fwCtx.props.getProperty(Constants.FRAMEWORK_PROCESSOR).toLowerCase();
+      proc.add(procP);
+      final String procS = System.getProperty("os.arch").toLowerCase();
+      if (!procP.equals(procS)) {
+        proc.add(procS);
+      }
+      // Handle deprecated value "arm"
+      if (procP.startsWith("arm_")) {
+        proc.add("arm");
+      }
+      for (int i = 0; i < Alias.processorAliases.length; i++) {
+        if (procP.equalsIgnoreCase(Alias.processorAliases[i][0])) {
+          for (int j = 1; j < Alias.processorAliases[i].length; j++) {
+            if (!procS.equals(Alias.processorAliases[i][j])) {
+              proc.add(Alias.processorAliases[i][j]);
+            }
+          }
+          break;
+        }
+      }
+      final ArrayList<String> os = new ArrayList<String>();
+      final String osP = fwCtx.props.getProperty(Constants.FRAMEWORK_OS_NAME).toLowerCase();
+      os.add(osP);
+      final String osS = System.getProperty("os.name").toLowerCase();
+      if (!osS.equals(osP)) {
+        os.add(osS);
+      }
+      for (int i = 0; i < Alias.osNameAliases.length; i++) {
+        if (osP.equalsIgnoreCase(Alias.osNameAliases[i][0])) {
+          for (int j = 1; j < Alias.osNameAliases[i].length; j++) {
+            if (!osS.equals(Alias.osNameAliases[i][j])) {
+              os.add(Alias.osNameAliases[i][j]);
+            }
+          }
+          break;
+        }
+      }
+      final Version osVer = new Version(fwCtx.props.getProperty(Constants.FRAMEWORK_OS_VERSION));
+      final String osLang = fwCtx.props.getProperty(Constants.FRAMEWORK_LANGUAGE);
+      boolean optional = false;
+      List<String> best = null;
+      VersionRange bestVer = null;
+      boolean bestLang = false;
+
+      final List<HeaderEntry> hes = Util
+          .parseManifestHeader(Constants.BUNDLE_NATIVECODE, bnc, false, false,
+                               false);
+      for (final Iterator<HeaderEntry> heIt = hes.iterator(); heIt.hasNext();) {
+        final HeaderEntry he = heIt.next();
+        VersionRange matchVer = null;
+        boolean matchLang = false;
+
+        final
+        List<String> keys = he.getKeys();
+        if (keys.size() == 1 && "*".equals(keys.get(0)) && !heIt.hasNext()) {
+          optional = true;
+          break;
+        }
+
+        @SuppressWarnings("unchecked")
+        final
+        List<String> pl = (List<String>) he.getAttributes().get(Constants.BUNDLE_NATIVECODE_PROCESSOR);
+        if (pl != null) {
+          if (!containsIgnoreCase(proc, pl)) {
+            continue;
+          }
+        } else {
+          // NYI! Handle null
+          continue;
+        }
+
+        @SuppressWarnings("unchecked")
+        final
+        List<String> ol = (List<String>) he.getAttributes().get(Constants.BUNDLE_NATIVECODE_OSNAME);
+        if (ol != null) {
+          if (!containsIgnoreCase(os, ol)) {
+            continue;
+          }
+        } else {
+          // NYI! Handle null
+          continue;
+        }
+
+        @SuppressWarnings("unchecked")
+        final
+        List<String> ver = (List<String>) he.getAttributes().get(Constants.BUNDLE_NATIVECODE_OSVERSION);
+        if (ver != null) {
+          boolean okVer = false;
+          for (final String string : ver) {
+            // TODO! Handle format Exception
+            matchVer = new VersionRange(string);
+            if (matchVer.includes(osVer)) {
+              okVer = true;
+              break;
+            }
+          }
+          if (!okVer) {
+            continue;
+          }
+        }
+
+        @SuppressWarnings("unchecked")
+        final
+        List<String> lang = (List<String>) he.getAttributes().get(Constants.BUNDLE_NATIVECODE_LANGUAGE);
+        if (lang != null) {
+          for (final String string : lang) {
+            if (osLang.equalsIgnoreCase(string)) {
+              // Found specified language version, search no more
+              matchLang = true;
+              break;
+            }
+          }
+          if (!matchLang) {
+            continue;
+          }
+        }
+
+        @SuppressWarnings("unchecked")
+        final
+        List<String> sf = (List<String>) he.getAttributes().get(Constants.SELECTION_FILTER_ATTRIBUTE);
+        if (sf != null) {
+          final String sfs = sf.get(0);
+          if (sf.size() == 1) {
+            try {
+              if (!(FrameworkUtil.createFilter(sfs)).match(fwCtx.props.getProperties())) {
+                continue;
+              }
+            } catch (final InvalidSyntaxException ise) {
+              throw new BundleException("Bundle#" + bid +
+                                        ", Invalid syntax for native code selection filter: "
+                                        + sfs, BundleException.NATIVECODE_ERROR, ise);
+            }
+          } else {
+            throw new BundleException("Bundle#" + bid +
+                                      ", Invalid character after native code selection filter: "
+                                      + sfs, BundleException.NATIVECODE_ERROR);
+          }
+        }
+
+        // Compare to previous best
+        if (best != null) {
+          boolean verEqual = false;
+          if (bestVer != null) {
+            if (matchVer == null) {
+              continue;
+            }
+            final int d = bestVer.getLeft().compareTo(matchVer.getLeft());
+            if (d == 0) {
+              verEqual = true;
+            } else if (d > 0) {
+              continue;
+            }
+          } else if (matchVer == null) {
+            verEqual = true;
+          }
+          if (verEqual && (!matchLang || bestLang)) {
+            continue;
+          }
+        }
+        best = keys;
+        bestVer = matchVer;
+        bestLang = matchLang;
+      }
+      if (best == null) {
+        if (optional) {
+          return;
+        } else {
+          throw new BundleException("Bundle#" + bid +
+                                    ", no matching native code libraries found for os="
+                                    + os + " version=" + osVer + ", processor="
+                                    + proc + " and language=" + osLang + ".",
+                                    BundleException.NATIVECODE_ERROR);
+        }
+      }
+      nativeLibs = new HashMap<String, FileArchive>();
+      bloop: for (final String name : best) {
+        for (final FileArchive fa : archives) {
+          if (!isFrag || fa.getBundleGeneration().archive == ba) {
+            final String key = fa.checkNativeLibrary(name);
+            if (key != null) {
+              nativeLibs.put(key, fa);
+              if (debug.classLoader) {
+                debug.println(this + "- Registered native library: " + key + " -> " + fa);
+              }
+              continue bloop;
+            }
+          }
+        }
+        throw new BundleException("Bundle#" + bid + ", failed to resolve native code: "
+                                  + name, BundleException.NATIVECODE_ERROR);
+      }
+    } else {
+      // No native code in this bundle
+      nativeLibs = null;
+    }
+  }
+
+
+  /**
+   * Check if a string exists in a list. Ignore case when comparing.
+   */
+  private boolean containsIgnoreCase(List<String> fl, List<String> l) {
+    for (final String string : l) {
+      final String s = string.toLowerCase();
+      for (final String string2 : fl) {
+        if (Util.filterMatch(string2, s)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleContextImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleContextImpl.java
new file mode 100644
index 0000000..782ddf2
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleContextImpl.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Implementation of the BundleContext object.
+ *
+ * @see org.osgi.framework.BundleContext
+ * @author Jan Stein
+ * @author Philippe Laporte
+ */
+public class BundleContextImpl
+  implements BundleContext
+{
+
+  /**
+   * Reference to bundleImpl for this context.
+   */
+  final BundleImpl bundle;
+
+
+  /**
+   * Is bundle context valid.
+   */
+  private boolean valid = true;
+
+
+  /**
+   * Create a BundleContext for specified bundle.
+   */
+  public BundleContextImpl(BundleImpl bundle) {
+    this.bundle = bundle;
+  }
+
+  //
+  // BundleContext interface
+  //
+
+  /**
+   * Retrieve the value of the named environment property.
+   *
+   * @see org.osgi.framework.BundleContext#getProperty
+   */
+  public String getProperty(String key) {
+    checkValid();
+    return bundle.fwCtx.props.getProperty(key);
+  }
+
+
+  /**
+   * Install a bundle from location.
+   *
+   * @see org.osgi.framework.BundleContext#installBundle
+   */
+  public Bundle installBundle(String location) throws BundleException {
+    checkValid();
+    return bundle.fwCtx.bundles.install(location, null, bundle);
+  }
+
+
+  /**
+   * Install a bundle from an InputStream.
+   *
+   * @see org.osgi.framework.BundleContext#installBundle
+   */
+  public Bundle installBundle(String location, InputStream in)
+    throws BundleException
+  {
+    try {
+      checkValid();
+      return bundle.fwCtx.bundles.install(location, in, bundle);
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) {}
+      }
+    }
+  }
+
+
+  /**
+   * Retrieve the Bundle object for the calling bundle.
+   *
+   * @see org.osgi.framework.BundleContext#getBundle
+   */
+  public Bundle getBundle() {
+    checkValid();
+    return bundle;
+  }
+
+
+  /**
+   * Retrieve the bundle that has the given unique identifier.
+   *
+   * @see org.osgi.framework.BundleContext#getBundle
+   */
+  public Bundle getBundle(long id) {
+    return bundle.fwCtx.bundleHooks.filterBundle(this, bundle.fwCtx.bundles.getBundle(id));
+  }
+
+
+  /**
+   * Retrieve a list of all installed bundles.
+   *
+   * @see org.osgi.framework.BundleContext#getBundles
+   */
+  public Bundle[] getBundles() {
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    final
+    List<Bundle> bl = (List) bundle.fwCtx.bundles.getBundles();
+    bundle.fwCtx.bundleHooks.filterBundles(this, bl);
+    return bl.toArray(new Bundle [bl.size()]);
+  }
+
+
+  /**
+   * Add a service listener with a filter.
+   *
+   * @see org.osgi.framework.BundleContext#addServiceListener
+   */
+  public void addServiceListener(ServiceListener listener, String filter)
+    throws InvalidSyntaxException {
+    checkValid();
+    bundle.fwCtx.listeners.addServiceListener(this, listener, filter);
+  }
+
+
+  /**
+   * Add a service listener.
+   *
+   * @see org.osgi.framework.BundleContext#addServiceListener
+   */
+  public void addServiceListener(ServiceListener listener) {
+    checkValid();
+    try {
+      bundle.fwCtx.listeners.addServiceListener(this, listener, null);
+    } catch (final InvalidSyntaxException neverHappens) { }
+  }
+
+
+  /**
+   * Remove a service listener.
+   *
+   * @see org.osgi.framework.BundleContext#removeServiceListener
+   */
+  public void removeServiceListener(ServiceListener listener) {
+    checkValid();
+    bundle.fwCtx.listeners.removeServiceListener(this, listener);
+  }
+
+
+  /**
+   * Add a bundle listener.
+   *
+   * @see org.osgi.framework.BundleContext#addBundleListener
+   */
+  public void addBundleListener(BundleListener listener) {
+    checkValid();
+    bundle.fwCtx.listeners.addBundleListener(this, listener);
+  }
+
+
+  /**
+   * Remove a bundle listener.
+   *
+   * @see org.osgi.framework.BundleContext#removeBundleListener
+   */
+  public void removeBundleListener(BundleListener listener) {
+    checkValid();
+    bundle.fwCtx.listeners.removeBundleListener(this, listener);
+  }
+
+
+  /**
+   * Add a framework listener.
+   *
+   * @see org.osgi.framework.BundleContext#addFrameworkListener
+   */
+  public void addFrameworkListener(FrameworkListener listener) {
+    checkValid();
+    bundle.fwCtx.listeners.addFrameworkListener(this, listener);
+  }
+
+
+  /**
+   * Remove a framework listener.
+   *
+   * @see org.osgi.framework.BundleContext#removeFrameworkListener
+   */
+  public void removeFrameworkListener(FrameworkListener listener) {
+    checkValid();
+    bundle.fwCtx.listeners.removeFrameworkListener(this, listener);
+  }
+
+
+  /**
+   * Register a service with multiple names.
+   *
+   * @see org.osgi.framework.BundleContext#registerService
+   */
+  public ServiceRegistration<?> registerService(String[] clazzes,
+                                                Object service,
+                                                Dictionary<String, ?> properties)
+  {
+    checkValid();
+    final String [] classes = clazzes.clone();
+    return bundle.fwCtx.services.register(bundle, classes, service, properties);
+  }
+
+
+  /**
+   * Register a service with a single name.
+   *
+   * @see org.osgi.framework.BundleContext#registerService
+   */
+  public ServiceRegistration<?> registerService(String clazz,
+                                                Object service,
+                                                Dictionary<String, ?> properties)
+  {
+    checkValid();
+    final String [] classes =  new String [] { clazz };
+    return bundle.fwCtx.services.register(bundle, classes, service, properties);
+  }
+
+
+  /**
+   * Get a list of service references.
+   *
+   * @see org.osgi.framework.BundleContext#getServiceReferences
+   */
+  public ServiceReference<?>[] getServiceReferences(String clazz, String filter)
+      throws InvalidSyntaxException
+  {
+    checkValid();
+    return bundle.fwCtx.services.get(clazz, filter, bundle);
+  }
+
+  /**
+   * Get a list of service references.
+   *
+   * @see org.osgi.framework.BundleContext#getAllServiceReferences
+   */
+  public ServiceReference<?>[] getAllServiceReferences(String clazz,
+                                                       String filter)
+      throws InvalidSyntaxException
+  {
+    checkValid();
+    return bundle.fwCtx.services.get(clazz, filter, null);
+  }
+
+
+  /**
+   * Get a service reference.
+   *
+   * @see org.osgi.framework.BundleContext#getServiceReference
+   */
+  public ServiceReference<?> getServiceReference(String clazz)
+  {
+    checkValid();
+    return bundle.fwCtx.services.get(bundle, clazz);
+  }
+
+
+  /**
+   * Get the service object.
+   *
+   * @see org.osgi.framework.BundleContext#getService
+   */
+  public <S> S getService(ServiceReference<S> reference) {
+    checkValid();
+
+    if(reference == null) {
+      // Throw an NPE with a message to be really clear we do it
+      // intentionally.
+      // A better solution would be to throw IllegalArgumentException,
+      // but the OSGi ref impl throws NPE, and we want to keep as
+      // close as possible
+      throw new NullPointerException("null ServiceReference is not valid input to getService()");
+    }
+
+    final ServiceReferenceImpl<S> sri = (ServiceReferenceImpl<S>) reference;
+    return sri.getService(bundle);
+  }
+
+
+  /**
+   * Unget the service object.
+   *
+   * @see org.osgi.framework.BundleContext#ungetService
+   */
+  public boolean ungetService(ServiceReference<?> reference) {
+    checkValid();
+
+    if(reference == null) {
+      // Throw an NPE with a message to be really clear we do it
+      // intentionally.
+      // A better solution would be to throw IllegalArgumentException,
+      // but the OSGi ref impl throws NPE, and we want to keep as
+      // close as possible
+      throw new NullPointerException("null ServiceReference is not valid input to ungetService()");
+    }
+
+    return ((ServiceReferenceImpl<?>)reference).ungetService(bundle);
+  }
+
+
+  /**
+   * Creates a File object for a file in the persistent storage
+   * area provided for the bundle.
+   *
+   * @see org.osgi.framework.BundleContext#getDataFile
+   */
+  public File getDataFile(String filename) {
+    checkValid();
+    final File dataRoot = bundle.getDataRoot();
+    if (dataRoot != null) {
+      if (!dataRoot.exists()) {
+        dataRoot.mkdirs();
+      }
+      return new File(dataRoot, filename);
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Constructs a Filter object. This filter object may be used
+   * to match a {@link ServiceReference} or a Dictionary.
+   *
+   * @param filter the filter string.
+   * @return the Filter object encapsulating the filter string.
+   * @exception InvalidSyntaxException If the filter parameter contains
+   * an invalid filter string which cannot be parsed.
+   *
+   * @since 1.1
+   */
+  public Filter createFilter(String filter) throws InvalidSyntaxException {
+    checkValid();
+    return FrameworkUtil.createFilter(filter);
+  }
+
+
+  public <S> ServiceRegistration<S>
+    registerService(Class<S> clazz,
+                    S service,
+                    Dictionary<String, ?> properties)
+  {
+    @SuppressWarnings("unchecked")
+    final ServiceRegistration<S> res = (ServiceRegistration<S>)
+        registerService(clazz == null ? null
+                                      : clazz.getName(),service,properties);
+    return res;
+  }
+
+
+  public <S> ServiceReference<S> getServiceReference(Class<S> clazz)
+  {
+    @SuppressWarnings("unchecked")
+    final ServiceReference<S> res = (ServiceReference<S>)
+        getServiceReference(clazz == null ? null : clazz.getName());
+    return res;
+  }
+
+  public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz,
+                                                                  String filter)
+      throws InvalidSyntaxException
+  {
+    @SuppressWarnings("unchecked")
+    final ServiceReference<S>[] srs = (ServiceReference[])
+      getServiceReferences(clazz == null ? null : clazz.getName(), filter);
+
+    if(srs == null) {
+      @SuppressWarnings("unchecked")
+      final Collection<ServiceReference<S>> res =
+          Collections.EMPTY_LIST;
+      return res;
+    } else {
+      return Arrays.asList(srs);
+    }
+  }
+
+  public Bundle getBundle(String location) {
+    return bundle.fwCtx.bundles.getBundle(location);
+  }
+
+
+  //
+  // Package methods
+  //
+
+  /**
+   * Invalidate this BundleContext.
+   */
+  void invalidate() {
+    valid = false;
+  }
+
+
+  /**
+   * Is bundle still valid.
+   *
+   * @return true if valid.
+   * @exception IllegalStateException, if bundle isn't active.
+   */
+  boolean isValid() {
+    return valid;
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Check that the bundle is still valid.
+   *
+   * @return true if valid.
+   * @exception IllegalStateException, if bundle isn't active.
+   */
+  private void checkValid() {
+    if (!valid) {
+      throw new IllegalStateException("This bundle context is no longer valid");
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleGeneration.java b/osgi/framework/src/org/knopflerfish/framework/BundleGeneration.java
new file mode 100644
index 0000000..5355c7e
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleGeneration.java
@@ -0,0 +1,1260 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Vector;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.hooks.bundle.CollisionHook;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * Bundle generation specific data.
+ *
+ * @see org.osgi.framework.Bundle
+ * @author Jan Stein
+ */
+
+public class BundleGeneration implements Comparable<BundleGeneration> {
+
+  /**
+   * Symbolic name system bundle.
+   */
+  final static String KNOPFLERFISH_SYMBOLICNAME = "org.knopflerfish.framework";
+
+  /**
+   * Bundle
+   */
+  final BundleImpl bundle;
+
+  /**
+   * Packages that the bundle wants to export and import.
+   */
+  final BundlePackages bpkgs;
+
+  /**
+   * Bundle JAR data.
+   */
+  final BundleArchive archive;
+
+  /**
+   * Generation of BundlePackages.
+   */
+  final int generation;
+
+  /**
+   * Does bundle have a version 2 manifest.
+   */
+  final boolean v2Manifest;
+
+  /**
+   * Bundle symbolic name.
+   */
+  final String symbolicName;
+
+  /**
+   * Symbolic name parameters
+   */
+  final HeaderEntry symbolicNameParameters;
+
+  /**
+   * Bundle is a singleton.
+   */
+  final boolean singleton;
+
+  /**
+   * Bundle version.
+   */
+  final Version version;
+
+  /**
+   * This bundle's fragment attach policy.
+   */
+  final String attachPolicy;
+
+  /**
+   * Fragment description. This is null when the bundle isn't a fragment bundle.
+   */
+  final Fragment fragment;
+
+  /**
+   * The bundle requirements from the Require-Capability header.
+   */
+  final Map<String, List<BundleRequirementImpl>> requirements
+    = new HashMap<String, List<BundleRequirementImpl>>();
+
+  /**
+   * The bundle capabilities from the Provide-Capability header.
+   */
+  final Map<String, List<BundleCapabilityImpl>> capabilities
+    = new HashMap<String, List<BundleCapabilityImpl>>();
+
+  /**
+   * True when this bundle has its activation policy set to "lazy"
+   */
+  final boolean lazyActivation;
+  final private Set<String> lazyIncludes;
+  final private Set<String> lazyExcludes;
+
+  /**
+   * Time when bundle was last created.
+   *
+   */
+  final long timeStamp;
+
+  /**
+   * All fragment bundles this bundle hosts.
+   */
+  Vector<BundleGeneration> fragments = null;
+
+  /**
+   * Stores the raw manifest headers.
+   */
+  private volatile HeaderDictionary cachedRawHeaders = null;
+
+  /**
+   * Classloader for bundle.
+   */
+  private volatile ClassLoader classLoader;
+
+  /**
+   * Bundle protect domain. Will always be <tt>null</tt> for the system bundle,
+   * methods requiring access to it must be overridden in the SystemBundle
+   * class.
+   */
+  private ProtectionDomain protectionDomain;
+
+  private BundleClassPath unresolvedBundleClassPath = null;
+
+  final BundleRevisionImpl bundleRevision;
+
+  final private BundleCapability identity;
+
+  /**
+   * Construct a new BundleGeneration for the System Bundle.
+   *
+   * @param b BundleImpl this bundle data.
+   * @param exportStr The value of the Export-Package header.
+   * @param capabilityStr The value of the Provide-Capability header.
+   */
+  BundleGeneration(BundleImpl b, String exportStr, String capabilityStr) {
+    bundle = b;
+    archive = null;
+    generation = 0;
+    v2Manifest = true;
+    symbolicName = KNOPFLERFISH_SYMBOLICNAME;
+    symbolicNameParameters = null;
+    singleton = false;
+    version = new Version(Util.readFrameworkVersion());
+    attachPolicy = Constants.FRAGMENT_ATTACHMENT_ALWAYS;
+    fragment = null;
+    protectionDomain = null;
+    lazyActivation = false;
+    lazyIncludes = null;
+    lazyExcludes = null;
+    timeStamp = System.currentTimeMillis();
+    bpkgs = new BundlePackages(this, exportStr);
+    bundleRevision = new BundleRevisionImpl(this);
+    classLoader = b.getClassLoader();
+    processCapabilities(capabilityStr);
+    identity = new BundleCapabilityImpl(this);
+  }
+
+
+  /**
+   * Construct a new BundleGeneration.
+   *
+   * Construct a new Bundle based on a BundleArchive.
+   *
+   * @param b BundleImpl this bundle data.
+   * @param ba Bundle archive with holding the contents of the bundle.
+   * @param prev the previous generation of this bundle.
+   *
+   * @throws BundleException If we have duplicate symbolicname and version.
+   *
+   * @exception IOException If we fail to read and store our JAR bundle or if
+   *              the input data is corrupted.
+   * @exception SecurityException If we don't have permission to install
+   *              extension.
+   * @exception IllegalArgumentException Faulty manifest for bundle
+   */
+  BundleGeneration(BundleImpl b, BundleArchive ba, BundleGeneration prev, Bundle caller) throws BundleException {
+    bundle = b;
+    generation = (prev != null ? prev.generation : -1) + 1;
+    archive = ba;
+    checkCertificates();
+    // TODO, v2Manifest unnecessary to cache?
+    final String mv = archive.getAttribute(Constants.BUNDLE_MANIFESTVERSION);
+    v2Manifest = mv != null && mv.trim().equals("2");
+    
+    final String mbv = archive.getAttribute(Constants.BUNDLE_VERSION);
+    Version newVer = Version.emptyVersion;
+    if (mbv != null) {
+      try {
+        newVer = new Version(mbv);
+      } catch (final Exception ee) {
+        if (v2Manifest) {
+          throw new IllegalArgumentException("Bundle does not specify a valid "
+              + Constants.BUNDLE_VERSION + " header. Got exception: " + ee.getMessage());
+        }
+      }
+    }
+    version = newVer;
+
+    List<HeaderEntry> hes = Util.parseManifestHeader(Constants.FRAGMENT_HOST, archive
+        .getAttribute(Constants.FRAGMENT_HOST), true, true, true);
+    if (!hes.isEmpty()) {
+      fragment = new Fragment(this, hes.get(0));
+    } else {
+      fragment = null;
+    }
+
+    hes = Util.parseManifestHeader(Constants.BUNDLE_ACTIVATIONPOLICY, archive
+        .getAttribute(Constants.BUNDLE_ACTIVATIONPOLICY), true, true, true);
+    if (!hes.isEmpty()) {
+      HeaderEntry he = hes.get(0);
+      lazyActivation = Constants.ACTIVATION_LAZY.equals(he.getKey());
+      if (lazyActivation) {
+        if (he.getDirectives().containsKey(Constants.INCLUDE_DIRECTIVE)) {
+          lazyIncludes = Util.parseEnumeration(Constants.INCLUDE_DIRECTIVE,
+              he.getDirectives().get(Constants.INCLUDE_DIRECTIVE));
+        } else {
+          lazyIncludes = null;
+        }
+        if (he.getDirectives().containsKey(Constants.EXCLUDE_DIRECTIVE)) {
+          lazyExcludes = Util.parseEnumeration(Constants.EXCLUDE_DIRECTIVE,
+              he.getDirectives().get(Constants.EXCLUDE_DIRECTIVE));
+
+          if (lazyIncludes != null) {
+            for (final String entry : lazyExcludes) {
+              if (lazyIncludes.contains(entry)) {
+                throw new IllegalArgumentException("Conflicting "
+                    + Constants.INCLUDE_DIRECTIVE
+                    + "/" + Constants.EXCLUDE_DIRECTIVE + " entries in "
+                    + Constants.BUNDLE_ACTIVATIONPOLICY + ": '" + entry
+                    + "' both included and excluded");
+              }
+            }
+          }
+        } else {
+          lazyExcludes = null;
+        }
+      } else {
+        lazyIncludes = null;
+        lazyExcludes = null;
+      }
+    } else {
+      lazyActivation = false;
+      lazyIncludes = null;
+      lazyExcludes = null;
+    }
+
+    hes = Util.parseManifestHeader(Constants.REQUIRE_CAPABILITY, archive
+        .getAttribute(Constants.REQUIRE_CAPABILITY), true, true, false);
+    for (final HeaderEntry e : hes) {
+      final BundleRequirementImpl bri = new BundleRequirementImpl(this, e);
+      final String ns = bri.getNamespace();
+      List<BundleRequirementImpl> nsReqs = requirements.get(ns);
+      if (null == nsReqs) {
+        if (isExtension() && !ns.equals(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE)) {
+          throw new IllegalArgumentException("An extension bundle can only specify capability requirements in the " +
+              ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + " namespace. Not in " + ns);
+        }
+        nsReqs = new ArrayList<BundleRequirementImpl>();
+        requirements.put(ns, nsReqs);
+      }
+      nsReqs.add(bri);
+    }
+
+    @SuppressWarnings("deprecation")
+    String ee = archive.getAttribute(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+    if (ee != null) {
+      final BundleRequirementImpl bri = new BundleRequirementImpl(this, ee);
+      List<BundleRequirementImpl> nsReqs = requirements.get(bri.getNamespace());
+      if (null == nsReqs) {
+        nsReqs = new ArrayList<BundleRequirementImpl>();
+        requirements.put(bri.getNamespace(), nsReqs);
+      }
+      nsReqs.add(bri);
+    }
+
+    processCapabilities(archive.getAttribute(Constants.PROVIDE_CAPABILITY));
+
+    bpkgs = new BundlePackages(this);
+    try {
+      if (b.fwCtx.startLevelController == null) {
+        archive.setStartLevel(0);
+      } else {
+        if (archive.getStartLevel() == -1) {
+          archive.setStartLevel(b.fwCtx.startLevelController.getInitialBundleStartLevel());
+        }
+      }
+    } catch (final Exception exc) {
+      b.fwCtx.frameworkError(b, exc);
+    }
+    archive.setBundleGeneration(this);
+    long lastModified = prev != null ? 0 : archive.getLastModified();
+    if (lastModified == 0) {
+      lastModified = System.currentTimeMillis();
+    }
+    bundleRevision = new BundleRevisionImpl(this);
+    timeStamp = lastModified;
+
+    hes = Util
+        .parseManifestHeader(Constants.BUNDLE_SYMBOLICNAME, archive
+            .getAttribute(Constants.BUNDLE_SYMBOLICNAME), true, true, true);
+    HeaderEntry he = null;
+    if (!hes.isEmpty()) {
+      he = hes.get(0);
+      symbolicName = he.getKey();
+    } else {
+      if (v2Manifest) {
+        throw new IllegalArgumentException("Bundle has no symbolic name, location="
+            + bundle.location);
+      } else {
+        symbolicName = null;
+      }
+    }
+    if (he != null) {
+      singleton = "true".equals(he.getDirectives().get(Constants.SINGLETON_DIRECTIVE));
+      final String tmp = he.getDirectives().get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
+      attachPolicy = tmp == null ? Constants.FRAGMENT_ATTACHMENT_ALWAYS : tmp;
+      symbolicNameParameters = he;
+      if (!bundle.fwCtx.bsnversionMode.equals(Constants.FRAMEWORK_BSNVERSION_MULTIPLE)) {
+        final Collection<Bundle> snbl = b.fwCtx.bundles.getBundles(symbolicName, version);
+        if (!snbl.isEmpty() && (snbl.size() > 1 || !snbl.contains(bundle))) {
+          boolean fail;
+          if (bundle.fwCtx.bsnversionMode.equals(Constants.FRAMEWORK_BSNVERSION_MANAGED)) {
+            bundle.fwCtx.bundleHooks.filterCollisions(prev != null ? CollisionHook.UPDATING : CollisionHook.INSTALLING, caller, snbl);
+            fail = !snbl.isEmpty() && (snbl.size() > 1 || !snbl.contains(bundle));
+          } else {
+            fail = true;
+          }
+          if (fail) {
+            throw new BundleException("Bundle#" + b.id +
+                                      ", a bundle with same symbolic name and version "
+                                      + "is already installed (" + symbolicName + ", "
+                                      + version, BundleException.DUPLICATE_BUNDLE_ERROR);
+          }
+        }
+      }
+    } else {
+      attachPolicy = Constants.FRAGMENT_ATTACHMENT_ALWAYS;
+      singleton = false;
+      symbolicNameParameters = null;
+    }
+    identity = symbolicName != null ? new BundleCapabilityImpl(this) : null;
+  }
+
+
+  /**
+   * Construct a new BundleGeneration for an uninstalled bundle.
+   *
+   * @param prev Previous BundleGeneration.
+   */
+  BundleGeneration(BundleGeneration prev) {
+    bundle = prev.bundle;
+    archive = null;
+    generation = prev.generation + 1;
+    v2Manifest = prev.v2Manifest;
+    symbolicName = prev.symbolicName;
+    symbolicNameParameters = prev.symbolicNameParameters;
+    singleton = prev.singleton;
+    version = prev.version;
+    attachPolicy = Constants.FRAGMENT_ATTACHMENT_NEVER;
+    fragment = prev.fragment;
+    protectionDomain = null;
+    lazyActivation = false;
+    lazyIncludes = null;
+    lazyExcludes = null;
+    timeStamp = System.currentTimeMillis();
+    bpkgs = null;
+    cachedRawHeaders = prev.cachedRawHeaders;
+    classLoader = null;
+    bundleRevision = null;
+    identity = null;
+  }
+
+
+  private void processCapabilities(String capabilityStr)
+  {
+    if (capabilityStr != null && capabilityStr.length() > 0) {
+      for (final HeaderEntry he : Util
+          .parseManifestHeader(Constants.PROVIDE_CAPABILITY, capabilityStr,
+                               true, true, false)) {
+        final BundleCapabilityImpl bci = new BundleCapabilityImpl(this, he);
+        List<BundleCapabilityImpl> nsCaps = capabilities.get(bci.getNamespace());
+        if (null == nsCaps) {
+          nsCaps = new ArrayList<BundleCapabilityImpl>();
+          capabilities.put(bci.getNamespace(), nsCaps);
+        }
+        nsCaps.add(bci);
+      }
+    }
+  }
+
+  /**
+   * Compares this {@code BundleGeneration} object to another
+   * {@code BundleGeneration}. It compares the bundle identifier value.
+   *
+   * @param bg the other object to compare this one to.
+   */
+  public int compareTo(BundleGeneration bg) {
+    final long diff = bundle.id - bg.bundle.id;
+    if (diff < 0) {
+      return -1;
+    } else if (diff == 0) {
+      return 0;
+    } else {
+      return 1;
+    }
+  }
+
+
+  public String toString() {
+    return "BundleGeneration[bid=" + bundle.id + ", gen=" + generation + "]";
+  }
+
+  //
+  // Package methods
+  //
+
+  /**
+   * Finish construction by doing protectDomain creation and permission checks.
+   *
+   * @return Bundles classloader.
+   */
+  void checkPermissions(Object checkContext) {
+    protectionDomain = bundle.secure.getProtectionDomain(this);
+    try {
+      bundle.secure.checkExtensionLifecycleAdminPerm(bundle, checkContext);
+      if (isExtension() && !bundle.secure.okAllPerm(bundle)) {
+        throw new IllegalArgumentException("An extension bundle must have AllPermission");
+      }
+    } catch (final RuntimeException re) {
+      purgeProtectionDomain();
+      throw re;
+    }
+    // Bundle ok save timeStamp
+    if (archive.getLastModified() != timeStamp) {
+      try {
+        archive.setLastModified(timeStamp);
+      } catch (final IOException ioe) {
+        bundle.fwCtx.frameworkError(bundle, ioe);
+      }
+    }
+  }
+
+
+  /**
+   * Get capabilities specified by this bundle generation.
+   *
+   * Returns capabilities declared in the Bundle-Capability manifest header.
+   * <p/>
+   * The key in the map is the {@code name-space} of the capability.
+   */
+  Map<String, List<BundleCapabilityImpl>> getDeclaredCapabilities()
+  {
+    return capabilities;
+  }
+
+
+  /**
+   * Get requirements specified by this bundle generation.
+   *
+   * Returns all requirements declared in the Bundle-Requirement manifest header.
+   * <p/>
+   * The key in the map is the {@code name-space} of the bundle requirement.
+   */
+  Map<String, List<BundleRequirementImpl>> getDeclaredRequirements()
+  {
+    return requirements;
+  }
+
+
+  /**
+   *
+   */
+  boolean resolvePackages(BundleImpl[] triggers) throws BundleException {
+    ArrayList<BundleGeneration> detached = null;
+    attachFragments();
+    while (true) {
+      if (bpkgs.resolvePackages(triggers)) {
+        if (detached != null) {
+          // TODO should we report fragment that failed to attach
+          for (int i = detached.size() - 2; i >= 0; i--) {
+            final BundleGeneration bg = detached.get(i);
+            if (bg.bundle.attachToFragmentHost(this)) {
+              fragments.add(bg);
+            }
+          }
+        }
+        classLoader = bundle.secure.newBundleClassLoader(this);
+
+        return true;
+      }
+      if (isFragmentHost()) {
+        if (bundle.fwCtx.debug.resolver) {
+          bundle.fwCtx.debug.println("Resolve failed, remove last fragment and retry");
+        }
+        if (detached == null) {
+          detached = new ArrayList<BundleGeneration>();
+        }
+        detached.add(detachLastFragment(true));
+      } else {
+        break;
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * @param packageName
+   * @return true if this package name should trigger activation of a lazyBundle
+   */
+  boolean isPkgActivationTrigger(String packageName) {
+    return lazyActivation
+        && ((lazyIncludes == null && lazyExcludes == null)
+            || (lazyIncludes != null && lazyIncludes.contains(packageName)) || (lazyExcludes != null && !lazyExcludes
+            .contains(packageName)));
+  }
+
+
+  /**
+   * Get class loader for this bundle generation.
+   *
+   * @return Bundles classloader.
+   */
+  ClassLoader getClassLoader() {
+    return classLoader;
+  }
+
+
+  /**
+   * Get protection domain for this bundle generation.
+   *
+   * @return ProtectionDomain
+   */
+  ProtectionDomain getProtectionDomain() {
+    return protectionDomain;
+  }
+
+
+  /**
+   * Attaches all relevant fragments to this bundle.
+   * @throws BundleException Resolve hook throw an exception.
+   */
+  private void attachFragments() throws BundleException {
+    if (!attachPolicy.equals(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
+      final Collection<BundleGeneration> hosting = bundle.fwCtx.bundles.getFragmentBundles(this);
+      if (hosting.size() > 0 && bundle.secure.okHostBundlePerm(bundle)) {
+        // retrieve all fragments this bundle host
+        for (final BundleGeneration fbg : hosting) {
+          // TODO, do we need to clean in case of BundleException?
+          fbg.bundle.attachToFragmentHost(this);
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Attaches a fragment to this bundle generation.
+   * @throws BundleException 
+   */
+  void attachFragment(BundleGeneration fragmentBundle) throws BundleException {
+    if (attachPolicy.equals(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
+      throw new IllegalStateException("Bundle does not allow fragments to attach");
+    }
+    if (attachPolicy.equals(Constants.FRAGMENT_ATTACHMENT_RESOLVETIME)
+        && bundle.isResolved()) {
+      throw new IllegalStateException("Bundle does not allow fragments to attach dynamically");
+    }
+    if (!bundle.fwCtx.resolverHooks.filterMatches(fragmentBundle.fragment,
+                                                  new BundleNameVersionCapability(this, BundleRevision.HOST_NAMESPACE))) {
+      throw new IllegalStateException("Resolver hooks vetoed attach to: " + this);      
+    }
+    final String failReason = bpkgs.attachFragment(fragmentBundle.bpkgs);
+    if (failReason != null) {
+      throw new IllegalStateException("Failed to attach: " + failReason);
+    }
+    if (classLoader != null && classLoader instanceof BundleClassLoader) {
+      try {
+        ((BundleClassLoader)classLoader).attachFragment(fragmentBundle);
+      } catch (final BundleException be) {
+        // TODO, should we unregister fragment packaaes
+        throw new IllegalStateException(be.getMessage());
+      }
+    }
+    if (bundle.fwCtx.debug.resolver) {
+      bundle.fwCtx.debug.println("Fragment(" + fragmentBundle.bundle + ") attached to host(id="
+          + bundle.id + ",gen=" + generation + ")");
+    }
+    if (fragments == null) {
+      fragments = new Vector<BundleGeneration>();
+    }
+    int i = 0;
+    // TODO: use sorted list!?
+    for (; i < fragments.size(); i++) {
+      final BundleGeneration b = fragments.get(i);
+      if (b.bundle.id > fragmentBundle.bundle.id) {
+        break;
+      }
+    }
+    fragments.add(i, fragmentBundle);
+  }
+
+
+  /**
+   * Detach last fragment from this bundle.
+   *
+   * @return BundleGeneration for fragment removed, otherwise null.
+   */
+  private BundleGeneration detachLastFragment(boolean unregister) {
+    // TODO, handle extensions
+    final int last = fragments.size() - 1;
+    if (last >= 0) {
+      final BundleGeneration fbg = fragments.remove(last);
+      bpkgs.detachFragmentSynchronized(fbg, unregister);
+      if (bundle.fwCtx.debug.resolver) {
+        bundle.fwCtx.debug.println("Fragment(id=" + fbg.bundle.id + ") detached from host(id="
+            + bundle.id + ",gen=" + generation + ")");
+      }
+      if (fbg.bundle.state != Bundle.UNINSTALLED) {
+        fbg.fragment.removeHost(this);
+        if (!fbg.fragment.hasHosts()) {
+          if (fbg.isCurrent()) {
+            fbg.bundle.setStateInstalled(true);
+          } else {
+            // ... NYI zombie detach
+          }
+        }
+      }
+      return fbg;
+    }
+    return null;
+  }
+
+
+  void updateStateFragments() {
+    if (fragments != null) {
+      @SuppressWarnings("unchecked")
+      final Vector<BundleGeneration> fix = (Vector<BundleGeneration>)fragments.clone();
+      for (final BundleGeneration bundleGeneration : fix) {
+        final BundleImpl fb = bundleGeneration.bundle;
+        fb.getUpdatedState(null);
+      }
+    }
+  }
+
+
+  /**
+   * Get hosts if this bundle is a fragment.
+   * Return null if not a fragment.
+   */
+  Vector<BundleGeneration> getHosts() {
+    return fragment != null ? fragment.getHosts() : null;
+  }
+
+
+  /**
+   * Checks if this bundle is a fragment
+   */
+  boolean isFragment() {
+    return fragment != null;
+  }
+
+
+  /**
+   * Determines whether this bundle is a fragment host or not.
+   */
+  boolean isFragmentHost() {
+    return fragments != null && !fragments.isEmpty();
+  }
+
+
+  /**
+   * Checks if this bundle is a boot class path extension bundle
+   */
+  boolean isBootClassPathExtension() {
+    return fragment != null && fragment.extension != null
+        && fragment.extension.equals(Constants.EXTENSION_BOOTCLASSPATH);
+  }
+
+
+  /**
+   * Checks if this bundle is an extension bundle
+   */
+  boolean isExtension() {
+    return fragment != null && fragment.extension != null;
+  }
+
+
+  /**
+   * Get locale dictionary for this bundle.
+   */
+  private Dictionary<String, String> getLocaleDictionary(String locale, String baseName) {
+    final String defaultLocale = Locale.getDefault().toString();
+
+    if (locale == null) {
+      locale = defaultLocale;
+    } else if (locale.equals("")) {
+      return null;
+    }
+    final Hashtable<String, String> localization_entries = new Hashtable<String, String>();
+    // TODO, should we do like this and allow mixed locales?
+    if (baseName == null) {
+      baseName = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+    }
+    final Vector<BundleGeneration> h = getHosts();
+    if (h != null) {
+      BundleGeneration best;
+      while (true) {
+        try {
+          best = null;
+          for (final BundleGeneration bundleGeneration : h) {
+            final BundleGeneration bg = bundleGeneration;
+            if (best == null || bg.version.compareTo(best.version) > 0) {
+              best = bg;
+            }
+          }
+          break;
+        } catch (final ConcurrentModificationException ignore) {
+        }
+      }
+      if (best == bundle.fwCtx.systemBundle.current()) {
+        bundle.fwCtx.systemBundle.readLocalization("", localization_entries, baseName);
+        bundle.fwCtx.systemBundle.readLocalization(defaultLocale, localization_entries,
+            baseName);
+        if (!locale.equals(defaultLocale)) {
+          bundle.fwCtx.systemBundle.readLocalization(locale, localization_entries, baseName);
+        }
+        return localization_entries;
+      } else if (best != null) {
+        return best.getLocaleDictionary(locale, baseName);
+      }
+      // Didn't find a host, fall through.
+    }
+
+    readLocalization("", localization_entries, baseName);
+    readLocalization(defaultLocale, localization_entries, baseName);
+    if (!locale.equals(defaultLocale)) {
+      readLocalization(locale, localization_entries, baseName);
+    }
+    return localization_entries;
+  }
+
+
+  /**
+   *
+   */
+  HeaderDictionary getHeaders0(String locale) {
+    if (cachedRawHeaders == null) {
+      cachedRawHeaders = archive.getUnlocalizedAttributes();
+    }
+    if ("".equals(locale)) {
+      return (HeaderDictionary)cachedRawHeaders.clone();
+    }
+    if (bundle.state != Bundle.UNINSTALLED) {
+      final String base = cachedRawHeaders.get(Constants.BUNDLE_LOCALIZATION);
+      try {
+        return localize(getLocaleDictionary(locale, base));
+      } catch (final RuntimeException e) {
+        // We assume that we got an exception because we got
+        // state change during the operation. Check!
+        // NYI
+        if (true) {
+          throw e;
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  void addResourceEntries(Vector<URL> res, String path, String pattern, boolean recurse) {
+    if (archive == null) {
+      // We are not called as systembundle
+      throw new IllegalStateException("Bundle is in UNINSTALLED state");
+    }
+    final Enumeration<String> e = archive.findResourcesPath(path);
+    if (e != null) {
+      while (e.hasMoreElements()) {
+        final String fp = e.nextElement();
+        final boolean isDirectory = fp.endsWith("/");
+        int searchBackwardFrom = fp.length() - 1;
+        if (isDirectory) {
+          // Skip last / in case of directories
+          searchBackwardFrom = searchBackwardFrom - 1;
+        }
+        final int l = fp.lastIndexOf('/', searchBackwardFrom);
+        final String lastComponentOfPath = fp.substring(l + 1, searchBackwardFrom + 1);
+        if (pattern == null || Util.filterMatch(pattern, lastComponentOfPath)) {
+          final URL url = getURL(0, fp);
+          if (url != null) {
+            res.add(url);
+          }
+        }
+        if (isDirectory && recurse) {
+          addResourceEntries(res, fp, pattern, recurse);
+        }
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  Vector<URL> findEntries(String path, String filePattern, boolean recurse) {
+    final Vector<URL> res = new Vector<URL>();
+    addResourceEntries(res, path, filePattern, recurse);
+    if (isFragmentHost()) {
+      @SuppressWarnings("unchecked")
+      final Vector<BundleGeneration> fix = (Vector<BundleGeneration>)fragments.clone();
+      for (final BundleGeneration fbg : fix) {
+        fbg.addResourceEntries(res, path, filePattern, recurse);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Construct URL to bundle resource
+   */
+  URL getURL(int subId, String path) {
+    try {
+      final StringBuffer u = new StringBuffer(BundleURLStreamHandler.PROTOCOL);
+      u.append("://");
+      u.append(bundle.id);
+      if (generation > 0) {
+        u.append('.').append(generation);
+      }
+      if (bundle.fwCtx.id > 0) {
+        u.append('!').append(bundle.fwCtx.id);
+      }
+      if (subId > 0) {
+        u.append(':').append(subId);
+      }
+      if (!path.startsWith("/")) {
+        u.append('/');
+      }
+      u.append(path);
+      return bundle.secure.getBundleURL(bundle.fwCtx, u.toString());
+    } catch (final MalformedURLException e) {
+      return null;
+    }
+  }
+
+
+  /**
+   * Purge classloader resources connected to object.
+   *
+   */
+  void closeClassLoader() {
+    if (bundle.fwCtx.debug.classLoader) {
+      bundle.fwCtx.debug.println("closeClassLoader: " + bundle + " gen = " + generation);
+    }
+    final BundleClassLoader tmp = (BundleClassLoader)classLoader;
+    if (tmp != null) {
+      classLoader = null;
+      tmp.close();
+    }
+  }
+
+
+  /**
+   * Purge classloader resources connected to object.
+   *
+   */
+  void purge(boolean unregister) {
+    if (bundle.fwCtx.debug.classLoader) {
+      bundle.fwCtx.debug.println("BundleGeneration.purge: " + bundle + " gen = " + generation);
+    }
+    if (unregister) {
+      unregisterPackages(true);
+    }
+    closeClassLoader();
+    purgeProtectionDomain();
+    if (archive != null) {
+      archive.purge();
+    }
+    clearWiring();
+  }
+
+
+  /**
+   *
+   *
+   */
+  boolean unregisterPackages(boolean force) {
+    final boolean res = bpkgs.unregisterPackages(force);
+    if (res && isFragmentHost()) {
+      while (detachLastFragment(false) != null)
+        ;
+    }
+    return res;
+  }
+
+
+  /**
+   * Purge permission resources connected to object.
+   *
+   */
+  void purgeProtectionDomain() {
+    bundle.secure.purge(bundle, protectionDomain);
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Check bundle certificates
+   */
+  private void checkCertificates() {
+    ArrayList<List<X509Certificate>> cs = archive.getCertificateChains(false);
+    if (cs != null) {
+      if (bundle.fwCtx.validator != null) {
+        if (bundle.fwCtx.debug.certificates) {
+          bundle.fwCtx.debug.println("Validate certs for bundle #" + archive.getBundleId());
+        }
+        cs = new ArrayList<List<X509Certificate>>(cs);
+        for (final Iterator<Validator> vi = bundle.fwCtx.validator.iterator(); !cs.isEmpty() && vi.hasNext();) {
+          final Validator v = vi.next();
+          for (final Iterator<List<X509Certificate>> ci = cs.iterator(); ci.hasNext();) {
+            final List<X509Certificate> c = ci.next();
+            if (v.validateCertificateChain(c)) {
+              archive.trustCertificateChain(c);
+              ci.remove();
+              if (bundle.fwCtx.debug.certificates) {
+                bundle.fwCtx.debug.println("Validated cert: " + c.get(0));
+              }
+            } else {
+              if (bundle.fwCtx.debug.certificates) {
+                bundle.fwCtx.debug.println("Failed to validate cert: " + c.get(0));
+              }
+            }
+          }
+        }
+        if (cs.isEmpty()) {
+          // Ok, bundle is signed and validated!
+          return;
+        }
+      }
+    }
+    if (bundle.fwCtx.props.getBooleanProperty(FWProps.ALL_SIGNED_PROP)) {
+      throw new IllegalArgumentException("All installed bundles must be signed!");
+    }
+  }
+
+
+  /**
+   * "Localizes" this bundle's headers
+   *
+   * @param localization_entries A mapping of localization variables to values.
+   * @returns a new localized dictionary.
+   */
+  private HeaderDictionary localize(final Dictionary<String, String> localization_entries) {
+    final HeaderDictionary localized = (HeaderDictionary)cachedRawHeaders.clone();
+    if (localization_entries != null) {
+      for (final Enumeration<String> e = localized.keys(); e.hasMoreElements();) {
+        final String key = e.nextElement();
+        final String unlocalizedEntry = localized.get(key);
+
+        if (unlocalizedEntry.startsWith("%")) {
+          final String k = unlocalizedEntry.substring(1);
+          final String val = localization_entries.get(k);
+
+          if (val == null) {
+            localized.put(key, k);
+          } else {
+            localized.put(key, val);
+          }
+        }
+      }
+    }
+    return localized;
+  }
+
+
+  /**
+   * Reads all localization entries that affects this bundle (including its
+   * host/fragments)
+   *
+   * @param locale locale == "" the bundle.properties will be read o/w it will
+   *          read the files as described in the spec.
+   * @param localization_entries will append the new entries to this dictionary
+   * @param baseName the basename for localization properties, <code>null</code>
+   *          will choose OSGi default
+   */
+  private void readLocalization(String locale, Hashtable<String, String> localization_entries, String baseName) {
+    if (!locale.equals("")) {
+      locale = "_" + locale;
+    }
+    while (true) {
+      final String l = baseName + locale + ".properties";
+      final Hashtable<String, String> res = getLocalizationEntries(l);
+      if (res != null) {
+        localization_entries.putAll(res);
+        break;
+      }
+      final int pos = locale.lastIndexOf('_');
+      if (pos == -1) {
+        break;
+      }
+      locale = locale.substring(0, pos);
+    }
+  }
+
+
+  /**
+   * Find localization files and load.
+   *
+   */
+  private Hashtable<String, String> getLocalizationEntries(String name) {
+    Hashtable<String, String> res = archive.getLocalizationEntries(name);
+    if (res == null && isFragmentHost()) {
+      @SuppressWarnings("unchecked")
+      final Vector<BundleGeneration> fix = (Vector<BundleGeneration>)fragments.clone();
+      for (final BundleGeneration bg : fix) {
+        if (bg.archive != null) {
+          res = bg.archive.getLocalizationEntries(name);
+          if (res != null) {
+            break;
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+
+  boolean isUninstalled() {
+    return bpkgs == null;
+  }
+
+
+  BundleCapability getHostCapability()
+  {
+    if (v2Manifest
+        && !attachPolicy.equals(Constants.FRAGMENT_ATTACHMENT_NEVER) && fragment == null) {
+      return new BundleNameVersionCapability(this,
+                                             BundleRevision.HOST_NAMESPACE);
+    }
+    return null;
+  }
+
+  BundleNameVersionCapability getBundleCapability() {
+    if (v2Manifest && fragment==null) {
+      return new BundleNameVersionCapability(this, BundleRevision.BUNDLE_NAMESPACE);
+    }
+    return null;
+  }
+
+
+  Vector<URL> getBundleClassPathEntries(final String name, final boolean onlyFirst) {
+    BundleClassPath bcp = unresolvedBundleClassPath;
+    if (bcp == null) {
+      bcp = new BundleClassPath(archive, bundle.fwCtx);
+      unresolvedBundleClassPath = bcp;
+    }
+    final Vector<FileArchive> fas = bcp.componentExists(name, onlyFirst, false);
+    if (fas != null) {
+      final Vector<URL> res = new Vector<URL>();
+      for (final FileArchive fa : fas)  {
+        final URL url = fa.getBundleGeneration().getURL(fa.getSubId(), name);
+        if (url != null) {
+          res.addElement(url);
+        } else {
+          // Internal error
+          return null;
+        }
+      }
+      return res;
+    }
+    return null;
+  }
+
+
+  List<BundleWireImpl> getCapabilityWires() {
+    if (bpkgs != null) {
+      List<BundleWireImpl> res = new ArrayList<BundleWireImpl>();
+      for (List<BundleCapabilityImpl> lbc : bpkgs.getOtherCapabilities().values()) {
+        for (BundleCapabilityImpl bc : lbc) {
+          bc.getWires(res);
+        }
+      }
+      return res;
+    } else {
+      return null;
+    }
+  }
+
+
+  List<BundleWireImpl> getRequirementWires() {
+    List<BundleWireImpl> res = new ArrayList<BundleWireImpl>();
+    for (List<BundleRequirementImpl> lbr : getOtherRequirements().values()) {
+      for (BundleRequirementImpl br : lbr) {
+        final BundleWireImpl wire = br.getWire();
+        if (wire != null) {
+          res.add(wire);
+        }
+      }
+    }
+    return res;
+  }
+
+
+  Map<String, List<BundleRequirementImpl>> getOtherRequirements() {
+    Map<String, List<BundleRequirementImpl>> res = getDeclaredRequirements();
+    if (isFragmentHost()) {
+      boolean copied = false;
+      @SuppressWarnings("unchecked")
+      final Vector<BundleGeneration> fix = (Vector<BundleGeneration>)fragments.clone();
+      for (final BundleGeneration fbg : fix) {
+        Map<String, List<BundleRequirementImpl>> frm = fbg.getDeclaredRequirements();
+        if (!frm.isEmpty()) {
+          if (!copied) {
+            res = new HashMap<String, List<BundleRequirementImpl>>(res);
+            copied = true;
+          }
+          for (Entry<String, List<BundleRequirementImpl>> e : frm.entrySet()) {
+            String ns = e.getKey();
+            List<BundleRequirementImpl> p = res.get(ns);
+            if (p != null) {
+              p = new ArrayList<BundleRequirementImpl>(p);
+              p.addAll(e.getValue());
+            } else {
+              p = e.getValue();
+            }
+            res.put(ns, p);
+          }
+        }
+      }
+    }
+    // TODO filter optional
+    return res;
+  }
+
+
+  boolean isCurrent() {
+    return this == bundle.current();
+  }
+
+
+  boolean bsnAttrMatch(Map<String, Object> attributes) {
+    if (symbolicNameParameters != null) {
+      final Map<String, Object> attr = symbolicNameParameters.getAttributes();
+      final String mandatory = symbolicNameParameters.getDirectives().get(Constants.MANDATORY_DIRECTIVE);
+      HashSet<String> mAttr = new HashSet<String>();
+      if (mandatory != null) {
+        String [] split = Util.splitwords(mandatory, ",");
+        for (String e : split) {
+          mAttr.add(e.trim());
+        }
+      }
+      for (Entry<String, Object> e : attributes.entrySet()) {
+        final String key = e.getKey();
+        if (e.getValue().equals(attr.get(key))) {
+          mAttr.remove(key);
+        } else {
+          return false;
+        }
+      }
+      return mAttr.isEmpty();
+    }
+    return true;
+  }
+
+
+  void setWired() {
+    bundleRevision.setWired();
+  }
+
+
+  void clearWiring() {
+    bundleRevision.clearWiring();
+  }
+
+
+  Set<BundleImpl> getResolvedHosts() {
+    Set<BundleImpl> res = new HashSet<BundleImpl>();
+    List<BundleGeneration> tgts = fragment.targets();
+    for (BundleGeneration t : tgts) {
+      if (t.bundle.isResolved()) {
+        res.add(t.bundle);
+      }
+    }
+    return res;
+  }
+
+
+  BundleCapability getIdentityCapability() {
+    return identity;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleHooks.java b/osgi/framework/src/org/knopflerfish/framework/BundleHooks.java
new file mode 100644
index 0000000..13b176a
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleHooks.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.hooks.bundle.CollisionHook;
+import org.osgi.framework.hooks.bundle.EventHook;
+import org.osgi.framework.hooks.bundle.FindHook;
+
+class BundleHooks {
+
+  final private FrameworkContext fwCtx;
+
+  BundleHooks(FrameworkContext fwCtx) {
+    this.fwCtx = fwCtx;
+  }
+
+  Bundle filterBundle(BundleContextImpl bc,
+                      Bundle bundle) {
+    if(bundle == null) {
+      return bundle;
+    }
+    final List<ServiceRegistrationImpl<?>> srl = fwCtx.services.get(FindHook.class.getName());
+    if (srl == null || srl.isEmpty()) {
+      return bundle;
+    } else {
+      final ArrayList<Bundle> bl = new ArrayList<Bundle>();
+      bl.add(bundle);
+      filterBundles(bc, bl);
+      return bl.isEmpty() ? null : bundle;
+    }
+  }
+
+  void filterBundles(BundleContextImpl bc,
+                     Collection<Bundle> bundles) {
+    final List<ServiceRegistrationImpl<?>> srl = fwCtx.services.get(FindHook.class.getName());
+    if (srl != null) {
+      final RemoveOnlyCollection<Bundle> filtered
+        = new RemoveOnlyCollection<Bundle>(bundles);
+
+      for (final ServiceRegistrationImpl<?> serviceRegistrationImpl : srl) {
+        final ServiceReferenceImpl<?> sr = serviceRegistrationImpl.reference;
+        final FindHook fh = (FindHook) sr.getService(fwCtx.systemBundle);
+        if (fh != null) {
+          try {
+            fh.find(bc, filtered);
+          } catch (final Exception e) {
+            fwCtx.frameworkError(bc,
+                new BundleException("Failed to call Bundle FindHook  #" +
+                                    sr.getProperty(Constants.SERVICE_ID), e));
+          }
+        }
+      }
+    }
+  }
+
+  void filterBundleEventReceivers(final BundleEvent evt,
+                                   final HashSet<ListenerEntry> syncBundleListeners,
+                                   final HashSet<ListenerEntry> bundleListeners) {
+
+    final List<ServiceRegistrationImpl<?>> eventHooks
+      = fwCtx.services.get(EventHook.class.getName());
+
+    synchronized (fwCtx.listeners.syncBundleListeners) {
+      syncBundleListeners.addAll(fwCtx.listeners.syncBundleListeners);
+    }
+
+    synchronized (fwCtx.listeners.bundleListeners) {
+      if(bundleListeners != null) {
+        bundleListeners.addAll(fwCtx.listeners.bundleListeners);
+      }
+    }
+
+    if(eventHooks != null) {
+      final HashSet<BundleContext> bundleContexts = new HashSet<BundleContext>();
+      for (final ListenerEntry le : syncBundleListeners) {
+        bundleContexts.add(le.bc);
+      }
+      if(bundleListeners != null) {
+        for (final ListenerEntry le : bundleListeners) {
+          bundleContexts.add(le.bc);
+        }
+      }
+
+      final int unfilteredSize = bundleContexts.size();
+      final RemoveOnlyCollection<BundleContext> filtered
+        = new RemoveOnlyCollection<BundleContext>(bundleContexts);
+
+      for (final ServiceRegistrationImpl<?> serviceRegistrationImpl : eventHooks) {
+        final ServiceReferenceImpl<?> sr = serviceRegistrationImpl.reference;
+        final EventHook eh = (EventHook)sr.getService(fwCtx.systemBundle);
+        if (eh != null) {
+          try {
+            eh.event(evt, filtered);
+          } catch (final Exception e) {
+            fwCtx.frameworkError(fwCtx.systemBundle,
+                                 new BundleException("Failed to call Bundle EventHook #" +
+                                     sr.getProperty(Constants.SERVICE_ID), e));
+          }
+        }
+      }
+
+      if (unfilteredSize != bundleContexts.size()) {
+        for (final ListenerEntry le : syncBundleListeners) {
+          if(!bundleContexts.contains(le.bc)) {
+            syncBundleListeners.remove(le);
+          }
+        }
+        if(bundleListeners != null) {
+          for (final ListenerEntry le : bundleListeners) {
+            if(!bundleContexts.contains(le.bc)) {
+              bundleListeners.remove(le);
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  void filterCollisions(int mode,
+                        Bundle b,
+                        Collection<Bundle> bundles) {
+    final List<ServiceRegistrationImpl<?>> srl = fwCtx.services.get(CollisionHook.class.getName());
+    if (srl != null) {
+      final RemoveOnlyCollection<Bundle> filtered
+        = new RemoveOnlyCollection<Bundle>(bundles);
+
+      for (final ServiceRegistrationImpl<?> serviceRegistrationImpl : srl) {
+        final ServiceReferenceImpl<?> sr = serviceRegistrationImpl.reference;
+        final CollisionHook ch = (CollisionHook) sr.getService(fwCtx.systemBundle);
+        if (ch != null) {
+          try {
+            ch.filterCollisions(mode, b, filtered);
+          } catch (final Exception e) {
+            fwCtx.frameworkError(b,
+                new BundleException("Failed to call Bundle CollisionHook #" +
+                                    sr.getProperty(Constants.SERVICE_ID), e));
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleImpl.java
new file mode 100644
index 0000000..17b8612
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleImpl.java
@@ -0,0 +1,1923 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
+import org.osgi.framework.wiring.BundleWiring;
+
+/**
+ * Implementation of the Bundle object.
+ *
+ * @see org.osgi.framework.Bundle
+ * @author Jan Stein
+ * @author Philippe Laporte
+ * @author Mats-Ola Persson
+ */
+
+public class BundleImpl implements Bundle {
+
+  /**
+   * Framework for bundle.
+   */
+  final FrameworkContext fwCtx;
+
+  /**
+   * Bundle identifier.
+   */
+  final long id;
+
+  /**
+   * Bundle location identifier.
+   */
+  final String location;
+
+  /**
+   * Handle to secure operations.
+   */
+  PermissionOps secure;
+
+  /**
+   * State of bundle.
+   */
+  volatile int state;
+
+  /**
+   * Bundle generation data.
+   */
+  protected final Vector<BundleGeneration> generations;
+
+  /**
+   * Directory for bundle data.
+   */
+  protected FileTree bundleDir = null;
+
+  /**
+   * BundleContext for bundle.
+   */
+  protected BundleContextImpl bundleContext = null;
+
+  /**
+   * BundleActivator for bundle.
+   */
+  protected BundleActivator bactivator = null;
+
+  /**
+   * Stores the default locale entries when uninstalled.
+   */
+  volatile private HeaderDictionary cachedHeaders = null;
+
+  /**
+   * Type of operation in progress. Blocks bundle calls during activator and
+   * listener calls
+   */
+  volatile protected int operation;
+  final static int IDLE = 0;
+  final static int ACTIVATING = 1;
+  final static int DEACTIVATING = 2;
+  final static int RESOLVING = 3;
+  final static int UNINSTALLING = 4;
+  final static int UNRESOLVING = 5;
+  final static int UPDATING = 6;
+
+  /** Saved exception of resolve failure. */
+  private BundleException resolveFailException;
+
+  /** Remember if bundle was started */
+  private boolean wasStarted;
+
+  /** start/stop time-out/uninstall flag, see BundleThread */
+  volatile Boolean aborted;
+
+  /** current bundle thread */
+  private BundleThread bundleThread;
+  
+  /**
+   * Construct a new Bundle empty.
+   *
+   * Only called for system bundle
+   *
+   * @param fw Framework for this bundle.
+   */
+  BundleImpl(FrameworkContext fw) {
+    fwCtx = fw;
+    secure = fwCtx.perm;
+    id = 0;
+    generations = new Vector<BundleGeneration>(1);
+    location = Constants.SYSTEM_BUNDLE_LOCATION;
+    state = INSTALLED;
+    bundleDir = fwCtx.getDataStorage(id);
+  }
+
+
+  /**
+   * Construct a new Bundle based on a BundleArchive.
+   *
+   * @param fw FrameworkContext for this bundle.
+   * @param ba Bundle archive with holding the contents of the bundle.
+   * @param checkContext AccessConrolContext to do permission checks against.
+   * @throws BundleException If we have duplicate symbolicname and version.
+   * @exception IOException If we fail to read and store our JAR bundle or if
+   *              the input data is corrupted.
+   * @exception SecurityException If we don't have permission to install
+   *              extension.
+   * @exception IllegalArgumentException Faulty manifest for bundle
+   */
+  BundleImpl(FrameworkContext fw, BundleArchive ba, Object checkContext, Bundle caller) throws BundleException {
+    fwCtx = fw;
+    secure = fwCtx.perm;
+    id = ba.getBundleId();
+    location = ba.getBundleLocation();
+    state = INSTALLED;
+    generations = new Vector<BundleGeneration>(2);
+    final BundleGeneration gen = new BundleGeneration(this, ba, null, caller);
+    generations.add(gen);
+    gen.checkPermissions(checkContext);
+    doExportImport();
+    bundleDir = fwCtx.getDataStorage(id);
+
+    // Activate extension as soon as they are installed so that
+    // they get added in bundle id order.
+    if (gen.isExtension() && attachToFragmentHost(fwCtx.systemBundle.current())) {
+      gen.setWired();
+      state = RESOLVED;
+    }
+  }
+
+
+  //
+  // Bundle interface
+  //
+
+  /**
+   * Get bundle state.
+   *
+   * @see org.osgi.framework.Bundle#getState
+   */
+  public int getState() {
+    return state;
+  }
+
+
+  public void start() throws BundleException {
+    start(0);
+  }
+
+
+  /**
+   * Start this bundle.
+   *
+   * @see org.osgi.framework.Bundle#start
+   */
+  public void start(int options) throws BundleException {
+    secure.checkExecuteAdminPerm(this);
+
+    synchronized (fwCtx.resolver) {
+      final BundleGeneration current = current();
+      if (current.isFragment()) {
+        throw new BundleException("Bundle#" + id +
+                                  ", cannot start a fragment bundle",
+                                  BundleException.INVALID_OPERATION);
+      }
+      if (state == UNINSTALLED) {
+        throw new IllegalStateException("Bundle is uninstalled");
+      }
+      fwCtx.resolverHooks.checkResolveBlocked();
+
+      // The value -1 is used by this implementation to indicate a bundle
+      // that has not been started, thus ensure that options is != -1.
+      options &= 0xFF;
+
+      if (fwCtx.startLevelController != null) {
+        if (getStartLevel() > fwCtx.startLevelController.getStartLevel()) {
+          if ((options & START_TRANSIENT) != 0) {
+            throw new BundleException("Bundle#" + id +
+                                      ", can not transiently activate bundle with start level "
+                                      + getStartLevel() + " when running on start level "
+                                      + fwCtx.startLevelController.getStartLevel(),
+                                      BundleException.START_TRANSIENT_ERROR);
+          } else {
+            setAutostartSetting(options);
+            return;
+          }
+        }
+      }
+
+      // Initialize the activation; checks initialization of lazy
+      // activation.
+
+      // 1: If an operation is in progress, wait a little
+      waitOnOperation(fwCtx.resolver, "Bundle.start", false);
+
+      // 2: start() is idempotent, i.e., nothing to do when already started
+      if (state == ACTIVE) {
+        return;
+      }
+
+      // 3: Record non-transient start requests.
+      if ((options & START_TRANSIENT) == 0) {
+        setAutostartSetting(options);
+      }
+
+      // 5: Lazy?
+      if ((options & START_ACTIVATION_POLICY) != 0 && current.lazyActivation) {
+        // 4: Resolve bundle (if needed)
+        if (INSTALLED == getUpdatedState(new BundleImpl [] { this })) {
+          throw resolveFailException;
+        }
+        if (STARTING == state)
+          return;
+        state = STARTING;
+        bundleContext = new BundleContextImpl(this);
+        operation = ACTIVATING;
+      } else {
+        secure.callFinalizeActivation(this);
+        return;
+      }
+    }
+    // Last step of lazy activation
+    secure.callBundleChanged(fwCtx, new BundleEvent(BundleEvent.LAZY_ACTIVATION, this));
+    synchronized (fwCtx.resolver) {
+      operation = IDLE;
+      fwCtx.resolver.notifyAll();
+    }
+  }
+
+
+  // Performs the actual activation.
+  void finalizeActivation() throws BundleException {
+    synchronized (fwCtx.resolver) {
+      // 4: Resolve bundle (if needed)
+      switch (getUpdatedState(new BundleImpl [] { this })) {
+      case INSTALLED:
+        throw resolveFailException;
+      case STARTING:
+        if (operation == ACTIVATING) {
+          // finalization already in progress.
+          return;
+        }
+        // Lazy activation; fall through to RESOLVED.
+      case RESOLVED:
+        // 6:
+        state = STARTING;
+        operation = ACTIVATING;
+        if (fwCtx.debug.lazy_activation) {
+          fwCtx.debug.println("activating #" + getBundleId());
+        }
+        // 7:
+        if (null == bundleContext) {
+          bundleContext = new BundleContextImpl(this);
+        }
+        final BundleException e = bundleThread().callStart0(this);
+        operation = IDLE;
+        fwCtx.resolver.notifyAll();
+        if (e != null) {
+          throw e;
+        }
+        break;
+      case ACTIVE:
+        break;
+      case STOPPING:
+        // This happens if call start from inside the BundleActivator.stop
+        // method.
+        // Don't allow it.
+        throw new BundleException("Bundle#" + id +
+                                  ", start called from BundleActivator.stop",
+                                  BundleException.ACTIVATOR_ERROR);
+      case UNINSTALLED:
+        throw new IllegalStateException("Bundle is in UNINSTALLED state");
+      }
+    }
+  }
+
+
+  /**
+   * Start code that is executed in the bundleThread without holding the
+   * packages lock.
+   */
+  BundleException start0() {
+    final BundleArchive archive = current().archive;
+    final String ba = archive.getAttribute(Constants.BUNDLE_ACTIVATOR);
+    boolean bStarted = false;
+    // res is used to signal that start did not complete in a normal way
+    BundleException res = null;
+
+    fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.STARTING, this));
+
+    // If SETCONTEXTCLASSLOADER, set the thread's context
+    // class loader to the bundle class loader. This
+    // is useful for debugging external libs using
+    // the context class loader.
+    ClassLoader oldLoader = null;
+    if (fwCtx.props.SETCONTEXTCLASSLOADER) {
+      oldLoader = Thread.currentThread().getContextClassLoader();
+      Thread.currentThread().setContextClassLoader(getClassLoader());
+    }
+
+    int error_type = BundleException.MANIFEST_ERROR;
+    try {
+      if (ba != null) {
+        @SuppressWarnings("unchecked")
+        final Class<BundleActivator> c =
+            (Class<BundleActivator>) getClassLoader().loadClass(ba.trim());
+        error_type = BundleException.ACTIVATOR_ERROR;
+        bactivator = c.newInstance();
+
+        bactivator.start(bundleContext);
+        bStarted = true;
+      } else {
+        final String locations = fwCtx.props.getProperty(FWProps.MAIN_CLASS_ACTIVATION_PROP);
+        if (locations.length() > 0) {
+          final String mc = archive.getAttribute("Main-Class");
+
+          if (mc != null) {
+            final String[] locs = Util.splitwords(locations, ",");
+            for (final String loc : locs) {
+              if (loc.equals(location)) {
+                if (fwCtx.debug.resolver) {
+                  fwCtx.debug.println("starting main class " + mc);
+                }
+                error_type = BundleException.ACTIVATOR_ERROR;
+                final Class<?> mainClass = getClassLoader().loadClass(mc.trim());
+                bactivator = new MainClassBundleActivator(mainClass);
+                bactivator.start(bundleContext);
+                bStarted = true;
+                break;
+              }
+            }
+          }
+        }
+      }
+
+      if (!bStarted) {
+        // Even bundles without an activator are marked as
+        // ACTIVE.
+        // Should we possible log an information message to
+        // make sure users are aware of the missing activator?
+      }
+
+    } catch (Throwable t) {
+      res = new BundleException("Bundle#" + id + " start failed", error_type, t);
+    }
+    
+    // activator.start() done
+    // - normal -> state = active, started event
+    // - exception from start() -> res = ex, start-failed clean-up
+    // - unexpected state change (uninstall, refresh?):
+    //   -> res = new exception
+    // - start time-out -> res = new exception (not used?)    
+
+    // if start was aborted (uninstall or timeout), make sure
+    // finalizeActivation() has finished before checking aborted/state
+    synchronized (fwCtx.resolver) {
+      if (!isBundleThread(Thread.currentThread())) {
+        // newer BundleThread instance has been active for this BundleImpl,
+        // end thread execution 
+        throw new RuntimeException("Aborted bundle thread ending execution");
+      }
+      
+      Exception cause = null;
+      if (aborted == Boolean.TRUE) {
+        if (UNINSTALLED == state) {
+          cause = new Exception("Bundle uninstalled during start()");
+        } else {
+          cause = new Exception("Bundle activator start() time-out");
+        }
+      } else {
+        aborted = Boolean.FALSE; // signal to other thread that BundleThread
+                                 // concludes start/stop
+        if (STARTING != state) {
+          cause = new Exception("Bundle changed state because of refresh during start()");
+        }
+      }
+      if (cause != null) {
+        res = new BundleException("Bundle#" + id + " start failed",
+                                BundleException.STATECHANGE_ERROR, cause);
+      }
+    }
+    
+    if (fwCtx.debug.lazy_activation) {
+      fwCtx.debug.println("activating #" + getBundleId() + " completed.");
+    }
+    if (fwCtx.props.SETCONTEXTCLASSLOADER) {
+      Thread.currentThread().setContextClassLoader(oldLoader);
+    }
+
+    if (res == null) {
+      // 10:
+      state = ACTIVE;
+      fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.STARTED, this));
+    } else if (operation == ACTIVATING) {
+      // 8:
+      startFailed();
+    }
+    return res;
+  }
+
+  void startFailed()
+  {
+    // 8:
+    state = STOPPING;
+    fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.STOPPING, this));
+    removeBundleResources();
+    bundleContext.invalidate();
+    bundleContext = null;
+    state = RESOLVED;
+    fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.STOPPED, this));
+  }
+
+  /**
+   * Stop this bundle.
+   *
+   * @see org.osgi.framework.Bundle#stop
+   */
+  public void stop() throws BundleException {
+    stop(0);
+  }
+
+
+  /**
+   * Stop this bundle.
+   *
+   * @see org.osgi.framework.Bundle#stop
+   */
+  public void stop(int options) throws BundleException {
+    Exception savedException = null;
+
+    secure.checkExecuteAdminPerm(this);
+
+    synchronized (fwCtx.resolver) {
+      if (current().isFragment()) {
+        throw new BundleException("Bundle#" + id + ", can not stop a fragment",
+                                  BundleException.INVALID_OPERATION);
+      }
+
+      // 1:
+      if (state == UNINSTALLED) {
+        throw new IllegalStateException("Bundle is uninstalled");
+      }
+
+      // 2: If an operation is in progress, wait a little
+      waitOnOperation(fwCtx.resolver, "Bundle.stop", false);
+
+      // 3:
+      if ((options & STOP_TRANSIENT) == 0) {
+        setAutostartSetting(-1);
+      }
+      switch (state) {
+      case INSTALLED:
+      case RESOLVED:
+      case STOPPING:
+      case UNINSTALLED:
+        // 4:
+        return;
+
+      case ACTIVE:
+      case STARTING: // Lazy start...
+        savedException = stop0();
+        break;
+      }
+    }
+    if (savedException != null) {
+      if (savedException instanceof BundleException) {
+        throw (BundleException)savedException;
+      } else {
+        throw (RuntimeException)savedException;
+      }
+    }
+  }
+
+
+  Exception stop0() {
+    wasStarted = state == ACTIVE;
+    // 5:
+    state = STOPPING;
+    operation = DEACTIVATING;
+    // 6-13:
+    final Exception savedException = bundleThread().callStop1(this);
+    if (state != UNINSTALLED) {
+      state = RESOLVED;
+      bundleThread().bundleChanged(new BundleEvent(BundleEvent.STOPPED, this));
+      fwCtx.resolver.notifyAll();
+      operation = IDLE;
+    }
+    return savedException;
+  }
+
+
+  /**
+   * Stop code that is executed in the bundleThread without holding the packages
+   * lock.
+   */
+  Exception stop1() {
+    BundleException res = null;
+
+    // 6:
+    fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.STOPPING, this));
+
+    // 7:
+    if (wasStarted && bactivator != null) {
+      try {
+        bactivator.stop(bundleContext);
+      } catch (final Throwable e) {
+        res = new BundleException("Bundle#" + id + ", BundleActivator.stop() failed",
+                                  BundleException.ACTIVATOR_ERROR, e);
+      }
+
+      // if stop was aborted (uninstall or timeout), make sure
+      // finalizeActivation() has finished before checking aborted/state
+      synchronized (fwCtx.resolver) {
+        Exception cause = null;
+        if (aborted == Boolean.TRUE) {
+          if (UNINSTALLED == state) {
+            cause = new Exception("Bundle uninstalled during stop()");
+          } else {
+            cause = new Exception("Bundle activator stop() time-out");
+          }
+        } else {
+          aborted = Boolean.FALSE; // signal to other thread that BundleThread
+                                   // concludes stop
+          if (STOPPING != state) {
+            cause = new Exception("Bundle changed state because of refresh during stop()");
+          }
+        }
+        if (cause != null) {
+          res = new BundleException("Bundle stop failed",
+                                  BundleException.STATECHANGE_ERROR, cause);
+        }
+      }
+      bactivator = null;
+    }
+
+    if (operation == DEACTIVATING) {
+      stop2();
+    }
+
+    return res;
+  }
+
+  void stop2()
+  {
+    // Call hooks after we've called Activator.stop(), but before we've
+    // cleared all resources
+    if (null != bundleContext) {
+      fwCtx.listeners.serviceListeners.hooksBundleStopped(bundleContext);
+      // 8-10:
+      removeBundleResources();
+      bundleContext.invalidate();
+      bundleContext = null;
+    }
+  }
+
+
+  /**
+   * Wait for an ongoing operation to finish.
+   *
+   * @param lock Object used for locking.
+   * @param src Caller to include in exception message.
+   * @param longWait True, if we should wait extra long before aborting.
+   * @throws BundleException if the ongoing (de-)activation does not finish
+   *           within reasonable time.
+   */
+  void waitOnOperation(Object lock, final String src, boolean longWait) throws BundleException {
+    if (operation != IDLE) {
+      long left = longWait ? 20000 : 500;
+      final long waitUntil = Util.timeMillis() + left;
+      do {
+        try {
+          lock.wait(left);
+          if (operation == IDLE) {
+            return;
+          }
+        } catch (final InterruptedException _ie) {
+        }
+        left = waitUntil - Util.timeMillis();
+      } while (left > 0);
+      String op;
+      switch (operation) {
+      case IDLE:
+        // Should not happen!
+        return;
+      case ACTIVATING:
+        op = "start";
+        break;
+      case DEACTIVATING:
+        op = "stop";
+        break;
+      case RESOLVING:
+        op = "resolve";
+        break;
+      case UNINSTALLING:
+        op = "uninstall";
+        break;
+      case UNRESOLVING:
+        op = "unresolve";
+        break;
+      case UPDATING:
+        op = "update";
+        break;
+      default:
+        op = "unknown operation";
+        break;
+      }
+      throw new BundleException(src + " called during " + op + " of Bundle#"
+                                + id, BundleException.STATECHANGE_ERROR);
+    }
+  }
+
+
+  /**
+   * Update this bundle.
+   *
+   * @see org.osgi.framework.Bundle#update
+   */
+  public void update() throws BundleException {
+    update(null);
+  }
+
+
+  /**
+   * Update this bundle.
+   *
+   * @see org.osgi.framework.Bundle#update
+   */
+  public void update(final InputStream in) throws BundleException {
+    try {
+      secure.checkLifecycleAdminPerm(this);
+      if (current().isExtension()) {
+        secure.checkExtensionLifecycleAdminPerm(this);
+      }
+      synchronized (fwCtx.resolver) {
+        final boolean wasActive = state == ACTIVE;
+
+        switch (getState()) {
+        case ACTIVE:
+          stop(STOP_TRANSIENT);
+          // Fall through
+        case RESOLVED:
+        case INSTALLED:
+          // Load new bundle
+          secure.callUpdate0(this, in, wasActive);
+          break;
+        case STARTING:
+          // Wait for RUNNING state, this doesn't happen now
+          // since we are synchronized.
+          throw new IllegalStateException("Bundle is in STARTING state");
+        case STOPPING:
+          // Wait for RESOLVED state, this doesn't happen now
+          // since we are synchronized.
+          throw new IllegalStateException("Bundle is in STOPPING state");
+        case UNINSTALLED:
+          throw new IllegalStateException("Bundle is in UNINSTALLED state");
+        }
+      }
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) {
+        }
+      }
+
+    }
+  }
+
+
+  void update0(InputStream in, boolean wasActive, Object checkContext) throws BundleException {
+    final boolean wasResolved = state == RESOLVED;
+    final BundleGeneration current = current();
+    final Fragment oldFragment = current.fragment;
+    final int oldStartLevel = getStartLevel();
+    BundleArchive newArchive = null;
+    BundleGeneration newGeneration = null;
+
+    operation = UPDATING;
+    try {
+      // New bundle as stream supplied?
+      InputStream bin;
+      final BundleArchive archive = current.archive;
+      if (in == null) {
+        // Try Bundle-UpdateLocation
+        String update = archive != null ? archive
+            .getAttribute(Constants.BUNDLE_UPDATELOCATION) : null;
+        if (update == null) {
+          // Take original location
+          update = location;
+        }
+        final URL url = new URL(update);
+
+        // Handle case where bundle location is a reference and/or a directory
+        // URL. In these cases, send a NULL input stream to the archive
+        // indicating that is should re-use the old bundle location
+        String fname = url.getFile(); // if reference URL, the getFile() result
+                                      // may be a file: string
+        if (fname.startsWith("file:")) {
+          fname = fname.substring(5);
+        }
+        final File file = new File(fname);
+        if (file.isDirectory()) {
+          bin = null;
+        } else {
+          bin = url.openStream();
+        }
+      } else {
+        bin = in;
+      }
+
+      newArchive = fwCtx.storage.updateBundleArchive(archive, bin);
+      newGeneration = new BundleGeneration(this, newArchive, current, this);
+      newGeneration.checkPermissions(checkContext);
+      newArchive.setStartLevel(oldStartLevel);
+      fwCtx.storage.replaceBundleArchive(archive, newGeneration.archive);
+    } catch (final Exception e) {
+      if (newArchive != null) {
+        newArchive.purge();
+      }
+      operation = IDLE;
+      if (wasActive) {
+        try {
+          start();
+        } catch (final BundleException be) {
+          fwCtx.frameworkError(this, be);
+        }
+      }
+      if (e instanceof BundleException) {
+        throw (BundleException)e;
+      } else {
+        throw new BundleException("Failed to get update Bundle#" + id , BundleException.UNSPECIFIED, e);
+      }
+    }
+
+    boolean saveZombie;
+    if (oldFragment != null) {
+      saveZombie = oldFragment.hasHosts();
+      if (saveZombie) {
+        if (oldFragment.extension != null) {
+          if (oldFragment.extension.equals(Constants.EXTENSION_BOOTCLASSPATH)) {
+            fwCtx.systemBundle.bootClassPathHasChanged = true;
+          }
+        } else {
+          for (final BundleGeneration bundleGeneration : oldFragment.getHosts()) {
+            bundleGeneration.bpkgs.fragmentIsZombie(this);
+          }
+        }
+      }
+    } else {
+      // Remove this bundle's packages
+      saveZombie = !current.unregisterPackages(false);
+
+      // Loose old bundle if no exporting packages left
+      if (!saveZombie) {
+        current.closeClassLoader();
+      }
+    }
+
+    // Activate new bundle generation
+    final BundleGeneration oldGen = current;
+    state = INSTALLED;
+    if (saveZombie) {
+      generations.add(0, newGeneration);
+      fwCtx.bundles.addZombie(this);
+    } else {
+      generations.set(0, newGeneration);
+    }
+    doExportImport();
+
+    // Purge old archive
+    if (!saveZombie) {
+      oldGen.purge(false);
+    }
+
+    // Broadcast events
+    if (wasResolved) {
+      bundleThread().bundleChanged(new BundleEvent(BundleEvent.UNRESOLVED, this));
+    }
+    bundleThread().bundleChanged(new BundleEvent(BundleEvent.UPDATED, this));
+    operation = IDLE;
+
+    // Restart bundles previously stopped in the operation
+    if (wasActive) {
+      try {
+        start();
+      } catch (final BundleException be) {
+        fwCtx.frameworkError(this, be);
+      }
+    }
+  }
+
+
+  /**
+   * Uninstall this bundle.
+   *
+   * @see org.osgi.framework.Bundle#uninstall
+   */
+  public void uninstall() throws BundleException {
+    secure.checkLifecycleAdminPerm(this);
+    if (current().isExtension()) {
+      secure.checkExtensionLifecycleAdminPerm(this);
+    }
+    secure.callUninstall0(this);
+  }
+
+
+  void uninstall0() {
+    synchronized (fwCtx.resolver) {
+      final BundleGeneration current = current();
+      if (!current.isUninstalled()) {
+        try {
+          current.archive.setStartLevel(-2); // Mark as uninstalled
+        } catch (final Exception ignored) {
+        }
+      }
+
+      boolean doPurge = false;
+      switch (state) {
+      case UNINSTALLED:
+        throw new IllegalStateException("Bundle is in UNINSTALLED state");
+      case STARTING: // Lazy start
+      case ACTIVE:
+      case STOPPING:
+        Exception exception;
+        try {
+          waitOnOperation(fwCtx.resolver, "Bundle.uninstall", true);
+          exception = (state & (ACTIVE | STARTING)) != 0 ? stop0() : null;
+        } catch (final Exception se) {
+          // Force to install
+          setStateInstalled(false);
+          fwCtx.resolver.notifyAll();
+          exception = se;
+        }
+        operation = UNINSTALLING;
+        if (exception != null) {
+          fwCtx.frameworkError(this, exception);
+        }
+        // Fall through
+      case RESOLVED:
+      case INSTALLED:
+        fwCtx.bundles.remove(location);
+        if (operation != UNINSTALLING) {
+          try {
+            waitOnOperation(fwCtx.resolver, "Bundle.uninstall", true);
+            operation = UNINSTALLING;
+          } catch (final BundleException be) {
+            // Make sure that bundleContext is invalid
+            if (bundleContext != null) {
+              bundleContext.invalidate();
+              bundleContext = null;
+            }
+            operation = UNINSTALLING;
+            fwCtx.frameworkError(this, be);
+          }
+        }
+        if (state == UNINSTALLED) {
+          operation = IDLE;
+          throw new IllegalStateException("Bundle is in UNINSTALLED state");
+        }
+        boolean saveZombie = false;
+        if (current.isFragment()) {
+          if (isAttached()) {
+            if (current.isExtension()) {
+              if (current.isBootClassPathExtension()) {
+                fwCtx.systemBundle.bootClassPathHasChanged = true;
+              }
+            } else {
+              for (final BundleGeneration hbg : current.getHosts()) {
+                if (hbg.bpkgs != null) {
+                  hbg.bpkgs.fragmentIsZombie(this);
+                }
+              }
+            }
+            // Fragment in use, save as zombie generation
+            saveZombie = true;
+          } else {
+            doPurge = true;
+          }
+        } else { // Non-fragment bundle
+          // Try to unregister this bundle's packages
+          final boolean pkgsUnregistered = current.unregisterPackages(false);
+
+          if (pkgsUnregistered) {
+            // No exports in use, clean up.
+            current.closeClassLoader();
+            doPurge = true;
+          } else {
+            // Exports are in use, save as zombie generation
+            saveZombie = true;
+          }
+        }
+
+        state = INSTALLED;
+        bundleThread().bundleChanged(new BundleEvent(BundleEvent.UNRESOLVED, this));
+        cachedHeaders = current.getHeaders0(null);
+        bactivator = null;
+        state = UNINSTALLED;
+        // Purge old archive
+        final BundleGeneration oldGen = current;
+        if (saveZombie) {
+          generations.add(0, new BundleGeneration(oldGen));
+          fwCtx.bundles.addZombie(this);
+        } else {
+          generations.set(0, new BundleGeneration(oldGen));
+        }
+        if (doPurge) {
+          oldGen.purge(false);
+        }
+        operation = IDLE;
+        if (bundleDir != null) {
+          if (bundleDir.exists() && !bundleDir.delete()) {
+            fwCtx.frameworkError(this,
+                new IOException("Failed to delete bundle data"));
+          }
+          bundleDir = null;
+        }
+        // id, location and headers survives after uninstall.
+
+        // There might be bundle threads that are running start or stop
+        // operation. This will wake them and give them an chance to terminate.
+        fwCtx.resolver.notifyAll();
+        break;
+      }
+    }
+    fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.UNINSTALLED, this));
+  }
+
+
+  /**
+   * Get header data. This is all entries in the bundles MANIFEST file.
+   *
+   * @see org.osgi.framework.Bundle#getHeaders
+   */
+  public Dictionary<String, String> getHeaders() {
+    return getHeaders(null);
+  }
+
+
+  /**
+   * Get bundle identifier.
+   *
+   * @see org.osgi.fwCtx.Bundle#getBundleId
+   */
+  public long getBundleId() {
+    return id;
+  }
+
+
+  /**
+   * Get bundle location.
+   *
+   * @see org.osgi.framework.Bundle#getLocation
+   */
+  public String getLocation() {
+    secure.checkMetadataAdminPerm(this);
+    return location;
+  }
+
+
+  /**
+   * Get services that this bundle has registrated.
+   *
+   * @see org.osgi.framework.Bundle#getRegisteredServices
+   */
+  public ServiceReference<?>[] getRegisteredServices() {
+    checkUninstalled();
+    final Set<ServiceRegistrationImpl<?>> sr = fwCtx.services.getRegisteredByBundle(this);
+    secure.filterGetServicePermission(sr);
+    if (sr.size() > 0) {
+      final ServiceReference<?>[] res = new ServiceReference[sr.size()];
+      int pos = 0;
+      for (final ServiceRegistrationImpl<?> serviceRegistrationImpl : sr) {
+        res[pos++] = serviceRegistrationImpl.getReference();
+      }
+      return res;
+    }
+    return null;
+  }
+
+
+  /**
+   * Get services that this bundle uses.
+   *
+   * @see org.osgi.framework.Bundle#getServicesInUse
+   */
+  public ServiceReference<?>[] getServicesInUse() {
+    checkUninstalled();
+    final Set<ServiceRegistrationImpl<?>> sr = fwCtx.services.getUsedByBundle(this);
+    secure.filterGetServicePermission(sr);
+    if (sr.size() > 0) {
+      final ServiceReference<?>[] res = new ServiceReference<?>[sr.size()];
+      int pos = 0;
+      for (final ServiceRegistrationImpl<?> serviceRegistrationImpl : sr) {
+        res[pos++] = serviceRegistrationImpl.getReference();
+      }
+      return res;
+    }
+    return null;
+  }
+
+
+  /**
+   * Determine whether the bundle has the requested permission.
+   *
+   * @see org.osgi.framework.Bundle#hasPermission
+   */
+  public boolean hasPermission(Object permission) {
+    final BundleGeneration fix = current();
+    checkUninstalled();
+    if (permission instanceof Permission) {
+      if (secure.checkPermissions()) {
+        // get the current status from permission admin
+        final PermissionCollection pc = fix.getProtectionDomain().getPermissions();
+        return pc != null ? pc.implies((Permission)permission) : false;
+      } else {
+        return true;
+      }
+    } else {
+      return false;
+    }
+  }
+
+
+  /**
+   * Returns this bundle's BundleContext.
+   *
+   * @see org.osgi.framework.Bundle#getBundleContext
+   * @since org.osgi.framework 1.4
+   */
+  public BundleContext getBundleContext() {
+    secure.checkContextAdminPerm(this);
+    return bundleContext;
+  }
+
+
+  /**
+   * @see org.osgi.framework.Bundle#getResource(String name)
+   */
+  public URL getResource(String name) {
+    checkUninstalled();
+    // NYI, sync BundleGeneration
+    if (secure.okResourceAdminPerm(this) && !current().isFragment()) {
+      if (getUpdatedState(new BundleImpl [] { this }) != INSTALLED) {
+        final ClassLoader cl0 = getClassLoader();
+        if (cl0 != null) {
+          return cl0.getResource(name);
+        }
+      } else {
+        final Vector<URL> uv = secure.getBundleClassPathEntries(current(), name, true);
+        if (uv != null) {
+          return uv.firstElement();
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * @see org.osgi.framework.Bundle#getSymbolicName()
+   */
+  public String getSymbolicName() {
+    return current().symbolicName;
+  }
+
+
+  /**
+   *
+   * @see org.osgi.framework.Bundle#getLastModified()
+   */
+  public long getLastModified() {
+    return current().timeStamp;
+  }
+
+
+  /**
+   *
+   * @see org.osgi.framework.Bundle#getSignerCertificates()
+   */
+  @SuppressWarnings("unchecked")
+  public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType) {
+    boolean onlyTrusted;
+    if (signersType == SIGNERS_ALL) {
+      onlyTrusted = false;
+    } else if (signersType == SIGNERS_TRUSTED) {
+      onlyTrusted = true;
+    } else {
+      throw new IllegalArgumentException("signersType not SIGNER_ALL or SIGNERS_TRUSTED");
+    }
+    final BundleArchive fix = current().archive;
+    if (fix != null) {
+      final List<List<X509Certificate>> cs = fix.getCertificateChains(onlyTrusted);
+      if (cs != null) {
+        final Map<X509Certificate, List<X509Certificate>> res = new HashMap<X509Certificate, List<X509Certificate>>();
+        for (final List<X509Certificate> chain : cs) {
+          final List<X509Certificate> copy = new ArrayList<X509Certificate>(chain);
+          res.put(chain.get(0), copy);
+        }
+        return res;
+      }
+    }
+    return Collections.EMPTY_MAP;
+  }
+
+
+  /**
+   *
+   * @see org.osgi.framework.Bundle#getVersion()
+   */
+  public Version getVersion() {
+    return current().version;
+  }
+
+
+  public <A> A adapt(Class<A> type) {
+    secure.checkAdaptPerm(this, type);
+    return adaptSecure(type);
+  }
+
+
+  public File getDataFile(String filename) {
+    return bundleContext.getDataFile(filename);
+  }
+
+
+  public int compareTo(Bundle bundle) {
+    return new Long(getBundleId()).compareTo(new Long(bundle.getBundleId()));
+  }
+
+  //
+  // Package methods
+  //
+
+  /**
+   * Get updated bundle state. That means check if an installed bundle has been
+   * resolved.
+   *
+   * @return Bundles state
+   */
+  int getUpdatedState(BundleImpl [] triggers) {
+    if (state == INSTALLED) {
+      try {
+        synchronized (fwCtx.resolver) {
+          waitOnOperation(fwCtx.resolver, "Bundle.resolve", true);
+          if (state == INSTALLED) {
+            final BundleGeneration current = current();
+            if (triggers != null) {
+              fwCtx.resolverHooks.beginResolve(triggers);
+            }
+            if (current.isFragment()) {
+              final List<BundleGeneration> hosts = current.fragment.targets();
+              if (!hosts.isEmpty()) {
+                for (final BundleGeneration host : hosts) {
+                  if (!host.bpkgs.isActive()) {
+                    // Try resolve our host
+                    // NYI! Detect circular attach
+                    host.bundle.getUpdatedState(null);
+                  } else {
+                    if (!current.fragment.isHost(host)) {
+                      attachToFragmentHost(host);
+                    }
+                  }
+                }
+                if (state == INSTALLED && current.fragment.hasHosts()) {
+                  current.setWired();
+                  state = RESOLVED;
+                  operation = RESOLVING;
+                  bundleThread().bundleChanged(new BundleEvent(BundleEvent.RESOLVED, this));
+                  operation = IDLE;
+                }
+              }
+            } else {
+              if (current.resolvePackages(triggers)) {
+                current.setWired();
+                state = RESOLVED;
+                operation = RESOLVING;
+                current.updateStateFragments();
+                bundleThread().bundleChanged(new BundleEvent(BundleEvent.RESOLVED, this));
+                operation = IDLE;
+              } else {
+                String reason = current.bpkgs.getResolveFailReason();
+                throw new BundleException("Bundle#" + id + ", unable to resolve: "
+                    + reason,
+                    reason == Resolver.RESOLVER_HOOK_VETO ?
+                                                           BundleException.REJECTED_BY_HOOK :
+                                                             BundleException.RESOLVE_ERROR);
+              }
+            }
+            if (triggers != null && triggers.length == 1) {
+              BundleImpl[] t = triggers;
+              triggers = null;
+              fwCtx.resolverHooks.endResolve(t);
+            }
+          }
+        }
+      } catch (final BundleException be) {
+        resolveFailException = be;
+        fwCtx.frameworkError(this, be);
+        if (triggers != null && triggers.length == 1) {
+          try {
+            fwCtx.resolverHooks.endResolve(triggers);
+          } catch (final BundleException be2) {
+            resolveFailException = be2;
+            fwCtx.frameworkError(this, be2);
+          }
+        }
+      }
+    }
+    return state;
+  }
+
+
+  /**
+   * Attach a fragment to host bundle
+   * @throws BundleException 
+   */
+  boolean attachToFragmentHost(BundleGeneration host) throws BundleException {
+    final BundleGeneration fix = current();
+    if (fix.isFragment() && secure.okFragmentBundlePerm(this)) {
+      try {
+        if (fix.isExtension()) {
+          fwCtx.systemBundle.attachExtension(fix);
+        } else {
+          host.attachFragment(fix);
+        }
+        fix.fragment.addHost(host);
+        return true;
+      } catch (final BundleException be) {
+        throw be;
+      } catch (final Exception e) {
+        fwCtx.frameworkWarning(this, e);
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * Get root for persistent storage area for this bundle.
+   *
+   * @return A File object representing the data root.
+   */
+  File getDataRoot() {
+    return bundleDir;
+  }
+
+
+  /**
+   * Get class loader for this bundle. Create the classloader if we haven't done
+   * this previously. This method can only be called when the bundle is
+   * resolved.
+   *
+   * @return Bundles classloader.
+   */
+  ClassLoader getClassLoader() {
+    return current().getClassLoader();
+  }
+
+  /**
+   * Set state to INSTALLED and throw away our classloader. Reset all package
+   * registration. We assume that the bundle is resolved when entering this
+   * method.
+   */
+  void setStateInstalled(boolean sendEvent) {
+    synchronized (fwCtx.resolver) {
+      // Make sure that bundleContext is invalid
+      if (bundleContext != null) {
+        bundleContext.invalidate();
+        bundleContext = null;
+      }
+      final BundleGeneration current = current();
+      if (current.isFragment()) {
+        current.fragment.removeHost(null);
+      } else {
+        current.closeClassLoader();
+        current.unregisterPackages(true);
+        current.bpkgs.registerPackages();
+      }
+      current.clearWiring();
+      state = INSTALLED;
+      if (sendEvent) {
+        operation = UNRESOLVING;
+        bundleThread().bundleChanged(new BundleEvent(BundleEvent.UNRESOLVED, this));
+      }
+      operation = IDLE;
+    }
+  }
+
+
+  /**
+   * Purge any old files and data associated with this bundle.
+   */
+  void purge() {
+    fwCtx.bundles.removeZombie(this);
+    Vector<BundleGeneration> old;
+    synchronized (generations) {
+      final List<BundleGeneration> sub = generations.subList(1, generations.size());
+      old = new Vector<BundleGeneration>(sub);
+      sub.clear();
+    }
+    for (final BundleGeneration bg : old) {
+      bg.purge(true);
+    }
+  }
+
+
+  /**
+   * Get bundle archive.
+   *
+   * @return BundleArchive object.
+   */
+  BundleArchive getBundleArchive(long generation) {
+    synchronized (generations) {
+      for (final BundleGeneration bg : generations) {
+        if (bg.generation == generation) {
+          return bg.archive;
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Get exported packages. Note! Can be called without packages lock held.
+   *
+   * @return Iterator of all exported packages as ExportPkg.
+   */
+  @SuppressWarnings("unchecked")
+  Iterator<ExportPkg> getExports() {
+    synchronized (generations) {
+      HashSet<ExportPkg> res;
+      if (generations.size() > 1) {
+        res = new HashSet<ExportPkg>();
+        for (final BundleGeneration bg : generations) {
+          final BundlePackages bp = bg.bpkgs;
+          if (bp != null) {
+            for (final Iterator<ExportPkg> j = bp.getExports(); j.hasNext();) {
+              res.add(j.next());
+            }
+          }
+        }
+        return res.iterator();
+      } else {
+        final BundlePackages bp = generations.get(0).bpkgs;
+        if (bp != null) {
+          return bp.getExports();
+        } else {
+          return Collections.EMPTY_LIST.iterator();
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Get Hosts for this bundle packages.
+   *
+   * @return Vector of all host bundles BundleGeneration.
+   */
+  Vector<BundleGeneration> getHosts(final boolean zombieHosts) {
+    Vector<BundleGeneration> res = null;
+    if (zombieHosts) {
+      synchronized (generations) {
+        for (final BundleGeneration bg : generations) {
+          final Vector<BundleGeneration> h = bg.getHosts();
+          if (h != null) {
+            if (res != null) {
+              res.addAll(h);
+            } else {
+              res = h;
+            }
+          }
+        }
+      }
+    } else {
+      res = current().getHosts();
+    }
+    return res;
+  }
+
+
+  /**
+   * Get a list of all BundlePackages that require the exported packages that
+   * comes from this bundle.
+   *
+   * @return List of all requiring bundles as BundlePackages.
+   */
+  @SuppressWarnings("unchecked")
+  List<BundlePackages> getRequiredBy() {
+    List<BundlePackages> res = null;
+    synchronized (generations) {
+      for (final BundleGeneration bg : generations) {
+        final BundlePackages bp = bg.bpkgs;
+        if (bp != null) {
+          final List<BundlePackages> rb = bp.getRequiredBy();
+          if (res != null) {
+            res.addAll(rb);
+          } else {
+            res = rb;
+          }
+        }
+      }
+    }
+    return res != null ? res : Collections.EMPTY_LIST;
+  }
+
+
+  /**
+   * Save the autostart setting to the persistent bundle storage.
+   *
+   * @param setting The autostart options to save.
+   */
+  void setAutostartSetting(int setting) {
+    secure.callSetAutostartSetting(this, setting);
+  }
+
+
+  /**
+   * Internal version; only to be used from inside PriviledgedActions running on
+   * the framework's security context.
+   *
+   * @param setting The autostart setting to store.
+   */
+  void setAutostartSetting0(int setting) {
+    try {
+      final BundleArchive ba = current().archive;
+      if (null != ba) {
+        ba.setAutostartSetting(setting);
+      }
+    } catch (final IOException e) {
+      fwCtx.frameworkError(this, e);
+    }
+  }
+
+
+  /**
+   * Get the autostart setting from the bundle storage.
+   *
+   * @return the current autostart setting, "-1" if bundle not started.
+   */
+  int getAutostartSetting() {
+    final BundleArchive ba = current().archive;
+    return ba != null ? ba.getAutostartSetting() : -1;
+  }
+
+
+  // Start level related
+
+  /**
+   *
+   */
+  int getStartLevel() {
+    final BundleArchive ba = current().archive;
+    if (ba != null) {
+      return ba.getStartLevel();
+    } else {
+      return 0;
+    }
+  }
+
+
+  /**
+   *
+   */
+  void setStartLevel(int n) {
+    // as soon as anoyone sets the start level explicitly
+    // the level becomes persistent
+    final BundleArchive ba = current().archive;
+    if (ba != null) {
+      try {
+        ba.setStartLevel(n);
+      } catch (final Exception e) {
+        fwCtx.frameworkError(this, new BundleException(
+            "Failed to set start level on #" + id, e));
+      }
+    }
+  }
+
+
+  // Misc other
+
+  /**
+   * Return a string representing this bundle. Only return identifier, since it
+   * requires AdminPermisson to get the location.
+   *
+   * @return a String representing this bundle.
+   */
+  public String toString() {
+    return toString(0); // 0 is lowest detail
+  }
+
+
+  String toString(int detail) {
+    final StringBuffer sb = new StringBuffer();
+
+    sb.append("BundleImpl[");
+    sb.append("id=" + getBundleId());
+    if (detail > 0) {
+      sb.append(", state=" + getState());
+    }
+
+    if (detail > 1) {
+      sb.append(", startlevel=" + getStartLevel());
+    }
+
+    if (detail > 3) {
+      try {
+        sb.append(", autostart setting=");
+        sb.append(getAutostartSetting());
+      } catch (final Exception e) {
+        sb.append(e.toString());
+      }
+    }
+    if (detail > 4) {
+      sb.append(", loc=" + location);
+    }
+
+    if (detail > 4) {
+      sb.append(", symName=" + getSymbolicName());
+    }
+
+    sb.append("]");
+
+    return sb.toString();
+  }
+
+
+  /**
+   * Get bundle data. Get resources from bundle or fragment jars.
+   *
+   * @see org.osgi.framework.Bundle#findEntries
+   */
+  public Enumeration<URL> findEntries(String path, String filePattern, boolean recurse) {
+    if (secure.okResourceAdminPerm(this)) {
+      // Try to resolve, so that fragments attach.
+      getUpdatedState(new BundleImpl [] { this });
+      final Vector<URL> res = secure.callFindEntries(current(), path, filePattern, recurse);
+      if (!res.isEmpty()) {
+        return res.elements();
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  public URL getEntry(String name) {
+    if (secure.okResourceAdminPerm(this)) {
+      checkUninstalled();
+      try {
+        final BundleGeneration fix = current();
+        if ("/".equals(name)) {
+          return fix.getURL(0, "/");
+        }
+        final InputStream is = secure.callGetBundleResourceStream(fix.archive, name, 0);
+        if (is != null) {
+          is.close();
+          return fix.getURL(0, name);
+        }
+      } catch (final IOException _ignore) {
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  public Enumeration<String> getEntryPaths(String path) {
+    if (secure.okResourceAdminPerm(this)) {
+      checkUninstalled();
+      return secure.callFindResourcesPath(current().archive, path);
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * @see org.osgi.framework.Bundle#getHeaders(String locale)
+   */
+  public Dictionary<String, String> getHeaders(String locale) {
+    secure.checkMetadataAdminPerm(this);
+    Dictionary<String, String> res = secure.callGetHeaders0(current(), locale);
+    if (res == null && cachedHeaders != null) {
+      res = cachedHeaders.cloneHD();
+      // If we went to uninstalled, then use saved value.
+      // Otherwise try again, NYI make sure we don't inf-loop.
+      if (cachedHeaders == null) {
+        return getHeaders(locale);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   *
+   * @see org.osgi.framework.Bundle#getResources(String name)
+   */
+  public Enumeration<URL> getResources(String name) throws IOException {
+    checkUninstalled();
+    final BundleGeneration current = current();
+    if (secure.okResourceAdminPerm(this) && !current.isFragment()) {
+      Enumeration<URL> e = null;
+      if (getUpdatedState(new BundleImpl [] { this }) != INSTALLED) {
+        if (this instanceof SystemBundle) {
+          e = getClassLoader().getResources(name);
+        } else {
+          final BundleClassLoader cl0 = (BundleClassLoader)current.getClassLoader();
+          if (cl0 != null) {
+            e = cl0.getResourcesOSGi(name);
+          }
+        }
+      } else {
+        final Vector<URL> uv = secure.getBundleClassPathEntries(current, name, false);
+        if (uv != null) {
+          e = uv.elements();
+        }
+      }
+      if (e != null && e.hasMoreElements()) {
+        return e;
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   * @see org.osgi.framework.Bundle#loadClass()
+   */
+  public Class<?> loadClass(final String name) throws ClassNotFoundException {
+    if (secure.okClassAdminPerm(this)) {
+      checkUninstalled();
+      final BundleGeneration current = current();
+      if (current.isFragment()) {
+        throw new ClassNotFoundException("Can not load classes from fragment/extension bundles");
+      }
+      // NYI! Fix BundleGeneration
+      if (getUpdatedState(new BundleImpl [] { this }) == INSTALLED) {
+        throw new ClassNotFoundException(resolveFailException.getMessage());
+      }
+
+      ClassLoader cl;
+      if (this instanceof SystemBundle) {
+        cl = ((SystemBundle)this).getClassLoader();
+      } else {
+        cl = current.getClassLoader();
+        if (cl == null) {
+          throw new IllegalStateException("state is uninstalled?");
+        }
+      }
+      return cl.loadClass(name);
+    } else {
+      throw new ClassNotFoundException("No AdminPermission to get class: " + name);
+    }
+  }
+
+  /**
+   * Get the current generation.
+   *
+   */
+  BundleGeneration current() {
+    return generations.get(0);
+  }
+
+  /**
+   * Checks if this bundle is an extension bundle that is updated/uninstalled
+   * and needs to be restarted.
+   */
+  boolean extensionNeedsRestart() {
+    return current().isExtension() && (state & (INSTALLED | UNINSTALLED)) != 0;
+  }
+
+
+  /**
+   * Checks if this bundle is attached to a fragment host.
+   */
+  boolean isAttached() {
+    final BundleGeneration fix = current();
+    return fix.fragment != null && fix.fragment.hasHosts();
+  }
+
+
+  /**
+   * Returns the name of the bundle's fragment host. Returns null if this is not
+   * a fragment.
+   */
+  String getFragmentHostName() {
+    final BundleGeneration fix = current();
+    if (fix.isFragment()) {
+      return fix.fragment.hostName;
+    } else {
+      return null;
+    }
+  }
+
+
+  // Lazy bundles in state STARTING must not be actiavted during shutdown
+  boolean triggersActivationPkg(String pkg) {
+    return Bundle.STOPPING != fwCtx.systemBundle.getState() && state == Bundle.STARTING
+        && operation != ACTIVATING && current().isPkgActivationTrigger(pkg);
+  }
+
+
+  // Lazy bundles in state STARTING must not be actiavted during shutdown
+  boolean triggersActivationCls(String name) {
+    if (Bundle.STOPPING != fwCtx.systemBundle.getState() && state == Bundle.STARTING
+        && operation != ACTIVATING) {
+      String pkg = "";
+      final int pos = name.lastIndexOf('.');
+      if (pos != -1) {
+        pkg = name.substring(0, pos);
+      }
+      return current().isPkgActivationTrigger(pkg);
+    }
+    return false;
+  }
+
+
+  /**
+   *
+   */
+  BundleThread bundleThread() {
+    synchronized (fwCtx.bundleThreads) {
+      if (fwCtx.bundleThreads.isEmpty()) {
+        bundleThread = secure.createBundleThread(fwCtx);
+      } else {
+        bundleThread = (BundleThread)fwCtx.bundleThreads.removeFirst();
+      }
+      return bundleThread;
+    }
+  }
+
+
+  @SuppressWarnings("unchecked")
+  <A> A adaptSecure(Class<A> type) {
+    Object res = null;
+    if (BundleRevision.class.equals(type)) {
+      res = current().bundleRevision;
+    } else if (BundleRevisions.class.equals(type)) {
+      res = new BundleRevisionsImpl(generations);
+    } else if (BundleWiring.class.equals(type)) {
+      BundleRevision bundleRevision = current().bundleRevision;
+      if (bundleRevision != null) {
+        res = bundleRevision.getWiring();
+      }
+    } else if (fwCtx.startLevelController != null &&
+	           BundleStartLevel.class.equals(type)) {
+      res = fwCtx.startLevelController.bundleStartLevel(this);
+    } else if (BundleContext.class.equals(type)) {
+      res = bundleContext;
+    } else if (AccessControlContext.class.equals(type)) {
+      res = secure.getAccessControlContext(this);
+    }
+    return (A) res;
+  }
+
+
+  boolean usesBundleGeneration(BundleGeneration check) {
+    return generations.contains(check);
+  }
+
+
+  boolean hasZombies() {
+    return generations.size() > 1;
+  }
+
+  boolean isBundleThread(Thread t) {
+    return bundleThread == t;
+  }
+
+
+  void resetBundleThread() {
+    bundleThread = null;
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Register all our import and export packages.
+   *
+   */
+  private void doExportImport() {
+    final BundleGeneration current = current();
+    if (!current.isFragment()) {
+      // fragments don't export anything themselves.
+      current.bpkgs.registerPackages();
+    }
+  }
+
+
+  /**
+   * Remove a bundles all registered listeners, registered services and used
+   * services.
+   *
+   */
+  private void removeBundleResources() {
+    fwCtx.listeners.removeAllListeners(bundleContext);
+    final Set<ServiceRegistrationImpl<?>> srs = fwCtx.services.getRegisteredByBundle(this);
+    for (final ServiceRegistrationImpl<?> serviceRegistrationImpl : srs) {
+      try {
+        serviceRegistrationImpl.unregister();
+      } catch (final IllegalStateException ignore) {
+        // Someone has unregistered the service after stop completed.
+        // This should not occur, but we don't want get stuck in
+        // an illegal state so we catch it.
+      }
+    }
+    final Set<ServiceRegistrationImpl<?>> s = fwCtx.services.getUsedByBundle(this);
+    for (final ServiceRegistrationImpl<?> sri : s) {
+      sri.ungetService(this, false);
+    }
+  }
+
+
+  /**
+   * Check if bundle is in state UNINSTALLED. If so, throw exception.
+   */
+  private void checkUninstalled() {
+    if (state == UNINSTALLED) {
+      throw new IllegalStateException("Bundle is in UNINSTALLED state");
+    }
+  }
+
+
+  /**
+   * State is resolved, allowing bundle package access.
+   * <p>
+   * State is
+   * <tt>Bundle.RESOLVED | Bundle.STARTING | Bundle.ACTIVE | Bundle.STOPPING</tt>
+   * </p>
+   */
+  boolean isResolved() {
+    return (state & (RESOLVED | STARTING | ACTIVE | STOPPING)) != 0;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleNameVersionCapability.java b/osgi/framework/src/org/knopflerfish/framework/BundleNameVersionCapability.java
new file mode 100644
index 0000000..6f466c3
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleNameVersionCapability.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+
+public class BundleNameVersionCapability implements BundleCapability {
+
+  final BundleGeneration gen;
+  final String namespace;
+
+  BundleNameVersionCapability(BundleGeneration bundleGeneration, String namespace) {
+    gen = bundleGeneration;
+    this.namespace = namespace;
+  }
+
+  @Override
+  public String getNamespace() {
+    return namespace;
+  }
+
+  @Override
+  public Map<String, String> getDirectives() {
+    if (gen.symbolicNameParameters != null) {
+      return Collections.unmodifiableMap(gen.symbolicNameParameters.getDirectives());
+    }
+    @SuppressWarnings("unchecked")
+    Map<String, String> res = Collections.EMPTY_MAP;
+    return res;
+  }
+
+  @Override
+  public Map<String, Object> getAttributes() {
+    final Map<String,Object> res = new HashMap<String, Object>();
+    if (gen.symbolicNameParameters != null) {
+      res.putAll(gen.symbolicNameParameters.getAttributes());
+    }
+    if (gen.symbolicName != null) {
+      res.put(namespace, gen.symbolicName);
+      res.put(Constants.BUNDLE_VERSION_ATTRIBUTE, gen.version);
+    }
+    return Collections.unmodifiableMap(res);
+  }
+
+  @Override
+  public BundleRevision getRevision() {
+    return gen.bundleRevision;
+  }
+
+  @Override
+  public BundleRevision getResource() {
+	return gen.bundleRevision;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((gen == null) ? 0 : gen.hashCode());
+    result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (getClass() != obj.getClass())
+      return false;
+    BundleNameVersionCapability other = (BundleNameVersionCapability) obj;
+    if (!gen.equals(other.gen))
+      return false;
+    if (!namespace.equals(other.namespace))
+      return false;
+    return true;
+  }
+
+  @Override
+  public String toString() {
+    return "BundleNameVersionCapability[nameSpace=" + namespace + ", attributes=" +
+        getAttributes() + ", directives=" + getDirectives() + ", revision=" +
+        getRevision() + "]";
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundlePackages.java b/osgi/framework/src/org/knopflerfish/framework/BundlePackages.java
new file mode 100644
index 0000000..65c128c
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundlePackages.java
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.knopflerfish.framework.Util.Comparator;
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleRequirement;
+
+/**
+ * Class representing all packages imported and exported.
+ *
+ * @author Jan Stein
+ * @author Mats-Ola Persson
+ * @author Gunnar Ekolin
+ */
+class BundlePackages {
+
+  final BundleGeneration bg;
+
+  /* Sorted list of exports */
+  private final ArrayList<ExportPkg> exports = new ArrayList<ExportPkg>(1);
+
+  /* Sorted list of declared imports */
+  private final ArrayList<ImportPkg> imports = new ArrayList<ImportPkg>(1);
+
+  /* Sorted list of declared dynamic imports */
+  private final ArrayList<ImportPkg> dImportPatterns = new ArrayList<ImportPkg>(1);
+
+  private final Map<String, List<BundleCapabilityImpl>> capabilities;
+
+  private TreeMap<BundleGeneration, BundlePackages> fragments = null;
+
+  private ArrayList<RequireBundle> require;
+
+  private ArrayList<BundlePackages> requiredBy = null;
+
+  /* Sorted list of active imports */
+  private ArrayList<ImportPkg> okImports = null;
+
+  /* Is our packages registered */
+  private boolean registered = false;
+
+  /* Reason we failed to resolve */
+  private String failReason = null;
+
+  /* Ordering of dynamic imports */
+  private int nextDynId = 0;
+
+  final static String EMPTY_STRING = "";
+
+
+  /**
+   * Create package entry.
+   */
+  BundlePackages(BundleGeneration bg) {
+    this.bg = bg;
+    final BundleArchive ba = bg.archive;
+
+    for (final HeaderEntry he : Util.parseManifestHeader(Constants.IMPORT_PACKAGE, ba
+        .getAttribute(Constants.IMPORT_PACKAGE), false, true, false)) {
+      final Iterator<String> pi = he.getKeys().iterator();
+      ImportPkg ip = new ImportPkg(pi.next(), he, this, false);
+      for (;;) {
+        final int ii = Util.binarySearch(imports, ipComp, ip);
+        if (ii < 0) {
+          imports.add(-ii - 1, ip);
+        } else {
+          throw new IllegalArgumentException("Duplicate import definitions for - " + ip.name);
+        }
+        if (pi.hasNext()) {
+          ip = new ImportPkg(ip, pi.next());
+        } else {
+          break;
+        }
+      }
+    }
+
+    for (final HeaderEntry he : Util
+        .parseManifestHeader(Constants.EXPORT_PACKAGE,
+                             ba.getAttribute(Constants.EXPORT_PACKAGE), false,
+                             true, false)) {
+      final List<String> keys = he.getKeys();
+      final Iterator<String> pi = keys.iterator();
+      ExportPkg ep = new ExportPkg(pi.next(), he, this);
+      for (;;) {
+        final int ei = Math.abs(Util.binarySearch(exports, epComp, ep) + 1);
+        exports.add(ei, ep);
+        if (!bg.v2Manifest) {
+          final ImportPkg ip = new ImportPkg(ep);
+          final int ii = Util.binarySearch(imports, ipComp, ip);
+          if (ii < 0) {
+            imports.add(-ii - 1, ip);
+          }
+        }
+        if (pi.hasNext()) {
+          ep = new ExportPkg(ep, pi.next());
+        } else {
+          break;
+        }
+      }
+    }
+
+    parseDynamicImports(ba.getAttribute(Constants.DYNAMICIMPORT_PACKAGE));
+
+    final List<HeaderEntry> hes = Util
+        .parseManifestHeader(Constants.REQUIRE_BUNDLE,
+                             ba.getAttribute(Constants.REQUIRE_BUNDLE), true,
+                             true, false);
+    if (!hes.isEmpty()) {
+      require = new ArrayList<RequireBundle>();
+      for (final HeaderEntry he : hes) {
+        require.add(new RequireBundle(this, he));
+      }
+    } else {
+      require = null;
+    }
+    capabilities = bg.getDeclaredCapabilities();
+  }
+
+
+  /**
+   * Create package entry used by system bundle.
+   */
+  BundlePackages(BundleGeneration bg, String exportString) {
+    this.bg = bg;
+
+    for (final HeaderEntry he : Util.parseManifestHeader(Constants.EXPORT_PACKAGE,
+                                                   exportString, false, true,
+                                                   false)) {
+      final List<String> keys = he.getKeys();
+      final Iterator<String> pi = keys.iterator();
+      ExportPkg ep = new ExportPkg(pi.next(), he, this);
+      for (;;) {
+        final int ei = Util.binarySearch(exports, epComp, ep);
+        if (ei >= 0) {
+          // Duplicate export entries from system bundle
+          // use the last one since it is configured by
+          // the user.
+          exports.set(ei, ep);
+        } else {
+          exports.add(-ei - 1, ep);
+        }
+        if (pi.hasNext()) {
+          ep = new ExportPkg(ep, pi.next());
+        } else {
+          break;
+        }
+      }
+    }
+    require = null;
+    capabilities = bg.getDeclaredCapabilities();
+  }
+
+
+  /**
+   * Create package entry used to clone fragment bundle.
+   */
+  BundlePackages(BundlePackages host, BundlePackages frag, boolean noNew) {
+    this.bg = host.bg;
+    /*
+     * make sure that the fragment's bundle does not conflict with this bundle's
+     * (see 3.1.4 r4-core)
+     */
+    for (final Iterator<ImportPkg> iiter = frag.getImports(); iiter.hasNext();) {
+      final ImportPkg fip = iiter.next();
+      final ImportPkg ip = host.getImport(fip.name);
+
+      if (ip != null) {
+        if (!fip.intersect(ip)) {
+          throw new IllegalStateException(
+              "Host bundle import package and fragment bundle " +
+                  "import package doesn't intersect, resolve isn't possible.");
+        }
+      } else if (noNew){
+        throw new IllegalStateException("Resolve host bundle package would " +
+                                        "be shadow by new fragment import.");
+      }
+      imports.add(new ImportPkg(fip, this));
+    }
+
+    if (frag.require != null) {
+      require = new ArrayList<RequireBundle>();
+      for (final RequireBundle fragReq : frag.require) {
+        boolean match = false;
+
+        if (host.require != null) {
+          // check for conflicts
+          for (final RequireBundle req : host.require) {
+            if (fragReq.name.equals(req.name)) {
+              if (fragReq.overlap(req)) {
+                match = true;
+              } else {
+                throw new IllegalStateException(
+                    "Fragment bundle required bundle doesn't completely " +
+                        "overlap required bundle in host bundle.");
+              }
+            }
+          }
+        }
+        if (!match) {
+          if (bg.bundle.state != Bundle.INSTALLED) {
+            throw new IllegalStateException("Can not attach a fragment with new required " +
+                                            "bundles to a resolved host");
+          }
+          require.add(new RequireBundle(fragReq, this));
+        }
+      }
+    } else {
+      require = null;
+    }
+    for (final Iterator<ExportPkg> eiter = frag.getExports(); eiter.hasNext();) {
+      final ExportPkg fep = eiter.next();
+      final ExportPkg hep = getExport(fep.name);
+      if (fep.pkgEquals(hep)) {
+        continue;
+      }
+      exports.add(new ExportPkg(fep, this));
+    }
+    capabilities = new HashMap<String, List<BundleCapabilityImpl>>();
+
+    for (Entry<String, List<BundleCapabilityImpl>> e : frag.bg.getDeclaredCapabilities().entrySet()) {
+      List<BundleCapabilityImpl> l = new ArrayList<BundleCapabilityImpl>();
+      for (BundleCapabilityImpl bc : e.getValue()) {
+        l.add(new BundleCapabilityImpl(bc, bg));
+      }
+      capabilities.put(e.getKey(), l);
+    }
+  }
+
+
+  /**
+   * Register bundle packages in framework.
+   *
+   */
+  void registerPackages() {
+    bg.bundle.fwCtx.resolver.registerCapabilities(capabilities, exports.iterator(), imports.iterator());
+    registered = true;
+  }
+
+
+  /**
+   * Unregister bundle packages in framework.
+   *
+   */
+  synchronized boolean unregisterPackages(boolean force) {
+    if (registered) {
+      if (bg.bundle.fwCtx.resolver.unregisterCapabilities(capabilities, getExports(), getImports(), force)) {
+        registered = false;
+        if (okImports != null) {
+          okImports = null;
+          for (List<BundleRequirementImpl> lbr : bg.getOtherRequirements().values()) {
+            for (BundleRequirementImpl br : lbr) {
+              br.resetWire();
+            }
+          }
+          unRequireBundles();
+          detachFragments();
+        }
+      } else {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  /**
+   * Resolve all the bundles' packages.
+   *
+   * @return true if we resolved all packages. If we failed return false. Reason
+   *         for fail can be fetched with getResolveFailReason().
+   * @throws BundleException Resolver hook complaint.
+   */
+  boolean resolvePackages(BundleImpl[] triggers) throws BundleException {
+    failReason = bg.bundle.fwCtx.resolver.resolve(bg, this, triggers);
+    if (failReason == null) {
+      okImports = new ArrayList<ImportPkg>(imports.size());
+      for (final Iterator<ImportPkg> i = getImports(); i.hasNext();) {
+        final ImportPkg ip = i.next();
+        if (ip.provider != null) { // <=> optional import with unresolved
+                                   // provider
+          okImports.add(ip);
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+
+  /**
+   * Return a string with a reason for why resolve failed.
+   *
+   * @return A error message string.
+   */
+  String getResolveFailReason() {
+    return failReason;
+  }
+
+
+  /**
+   * If bundle package has been resolved look for a BundlePackages that provides
+   * the requested package.
+   *
+   * @param pkg Package name
+   * @return BundlePackages exporting the pkg.
+   */
+  synchronized BundlePackages getProviderBundlePackages(String pkg) {
+    if (bg.bundle instanceof SystemBundle) {
+      return isExported(pkg) ? this : null;
+    }
+    if (okImports == null) {
+      return null;
+    }
+    final int ii = Util.binarySearch(okImports, ipFind, pkg);
+    if (ii >= 0) {
+      return okImports.get(ii).provider.bpkgs;
+    }
+    return null;
+  }
+
+
+  /**
+   * List available sub packages.
+   *
+   * @param pkg Package name
+   * @return .
+   */
+  synchronized Set<String> getSubProvider(String pkg) {
+    Set<String> res = new HashSet<String>();
+    if (pkg.length() > 0) {
+      pkg = pkg + ".";
+    }
+    if (okImports != null) {
+      for (ImportPkg ip : okImports) {
+        if (ip.provider != null && ip.name.startsWith(pkg)) {
+          String n = ip.name.substring(pkg.length());
+          if (n.indexOf('.') == -1) {
+            res.add(n);
+          }
+        }
+      }
+      for (Iterator<RequireBundle> irb = getRequire(); irb.hasNext(); ) {
+        RequireBundle rb = irb.next();
+        if (rb.bpkgs != null) {
+          for (Iterator<ExportPkg> iep = rb.bpkgs.getExports(); iep.hasNext(); ) {
+            ExportPkg ep = iep.next();
+            if (ep.name.startsWith(pkg)) {
+              String n = ep.name.substring(pkg.length());
+              if (n.indexOf('.') == -1) {
+                res.add(n);
+              }
+            }
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Check if we can dynamically import a package. Re-check that we haven't
+   * gotten a provider. (Do we need to do that?)
+   *
+   * @param pkg Package name
+   * @return Bundle exporting
+   */
+  synchronized BundlePackages getDynamicProviderBundlePackages(String pkg) {
+    if (okImports == null) {
+      return null;
+    }
+    final int ii = Util.binarySearch(okImports, ipFind, pkg);
+    if (ii >= 0) {
+      return okImports.get(ii).provider.bpkgs;
+    }
+    BundlePackages res = null;
+    BundleImpl [] trigger = null;
+    final FrameworkContext fwCtx = bg.bundle.fwCtx;
+    try {
+      for (final ImportPkg ip : dImportPatterns) {
+        if (ip.name == EMPTY_STRING ||
+            (ip.name.endsWith(".") && pkg.startsWith(ip.name)) ||
+            pkg.equals(ip.name)) {
+          if (trigger == null) {
+            trigger = new BundleImpl[] { bg.bundle };
+            fwCtx.resolverHooks.beginResolve(trigger);
+          }
+          final ImportPkg nip = new ImportPkg(ip, pkg);
+          final ExportPkg ep = fwCtx.resolver.registerDynamicImport(nip);
+          if (ep != null) {
+            nip.provider = ep;
+            nip.dynId = ++nextDynId;
+            okImports.add(-ii - 1, nip);
+            res = ep.bpkgs;
+            break;
+          }
+        }
+      }
+    } catch (BundleException be) {
+      fwCtx.frameworkError(bg.bundle, be);
+    }
+    if (trigger != null) {
+      try {
+        fwCtx.resolverHooks.endResolve(trigger);      
+      } catch (BundleException be) {
+        fwCtx.frameworkError(bg.bundle, be);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get all RequiredBundle for this BundlePackages.
+   *
+   * @return Iterator of RequireBundle.
+   */
+  Iterator<RequireBundle> getRequire() {
+    if (fragments != null) {
+      synchronized (fragments) {
+        final ArrayList<Iterator<RequireBundle>> iters = new ArrayList<Iterator<RequireBundle>>(fragments.size() + 1);
+        if (require != null) {
+          iters.add(require.iterator());
+        }
+        for (final BundlePackages bundlePackages : fragments.values()) {
+          iters.add(bundlePackages.getRequire());
+        }
+        return new IteratorIterator<RequireBundle>(iters);
+      }
+    } else if (require != null) {
+      return require.iterator();
+    } else {
+      @SuppressWarnings("unchecked")
+      final
+      Iterator<RequireBundle>res = Collections.EMPTY_LIST.iterator();
+      return res;
+    }
+  }
+
+
+  /**
+   * Get a list of all BundleGenerations that exports package
+   * <code>pkg</code> that comes from bundles that we have required,
+   * in correct order. Correct order is a depth first search order.
+   *
+   * @param pkg String with package name we are searching for, if null get all.
+   * @return List of required BundleGenerations or null if we don't
+   *         require any bundles.
+   */
+  ArrayList<BundleGeneration> getRequiredBundleGenerations(String pkg) {
+    ArrayList<BundleGeneration> res = null;
+    for (final Iterator<RequireBundle> i = getRequire(); i.hasNext(); ) {
+      final RequireBundle rb = i.next();
+      if (rb.bpkgs != null && rb.bpkgs.isExported(pkg)) {
+        if (res == null) {
+          res = new ArrayList<BundleGeneration>(2);
+        }
+        res.add(rb.bpkgs.bg);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Check if this BundlePackages is required by another Bundle.
+   *
+   * @return True if is required
+   */
+  void addRequiredBy(BundlePackages r) {
+    if (requiredBy == null) {
+      requiredBy = new ArrayList<BundlePackages>();
+    }
+    requiredBy.add(r);
+  }
+
+
+  /**
+   * Check if this BundlePackages is required by another Bundle.
+   *
+   * @return True if is required
+   */
+  boolean isRequired() {
+    return requiredBy != null && !requiredBy.isEmpty();
+  }
+
+
+  /**
+   * Check if this BundlePackages is required by another Bundle.
+   *
+   * @return True if is required
+   */
+  boolean isRequiredBy(BundlePackages cbp) {
+    return requiredBy != null && requiredBy.contains(cbp);
+  }
+
+
+  /**
+   * Get a list of all BundlePackages that requires the exported packages that
+   * comes from the bundle owning this object.
+   *
+   * @return List of required BundlePackages
+   */
+  List<BundlePackages> getRequiredBy() {
+    final List<BundlePackages> res = new ArrayList<BundlePackages>();
+    if (requiredBy != null) {
+      synchronized (requiredBy) {
+        res.addAll(requiredBy);
+      }
+      if (fragments != null) {
+        synchronized (fragments) {
+          for (final BundlePackages bundlePackages : fragments.values()) {
+            final List<BundlePackages> fl = bundlePackages.getRequiredBy();
+            if (fl != null) {
+              res.addAll(fl);
+            }
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Check if package needs to be added as re-exported package.
+   *
+   * @param ep ExportPkg to re-export.
+   */
+  void checkReExport(ExportPkg ep) {
+    // NYI. Rework this solution and include fragments
+    final int i = Util.binarySearch(exports, epFind, ep.name);
+    if (i < 0) {
+      final ExportPkg nep = new ExportPkg(ep, this);
+      exports.add(-i - 1, nep);
+      // Perhaps we should avoid this shortcut and go through Packages.
+      ep.pkg.addExporter(nep);
+    }
+  }
+
+
+  /**
+   * Get ExportPkg for exported package.
+   *
+   * @return ExportPkg entry or null if package is not exported.
+   */
+  private ExportPkg getExport(String pkg) {
+    final int i = Util.binarySearch(exports, epFind, pkg);
+    if (i >= 0) {
+      return exports.get(i);
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Get an iterator over all exported packages sorted
+   * according to epComp.
+   *
+   * @return An Iterator over ExportPkg.
+   */
+  Iterator<ExportPkg> getExports() {
+    if (fragments != null) {
+      synchronized (fragments) {
+        final ArrayList<Iterator<ExportPkg>> iters
+          = new ArrayList<Iterator<ExportPkg>>(fragments.size() + 1);
+        iters.add(exports.iterator());
+        for (final BundlePackages bundlePackages : fragments.values()) {
+          iters.add(bundlePackages.getExports());
+        }
+        return new IteratorIteratorSorted<ExportPkg>(iters, epComp);
+      }
+    } else {
+      return exports.iterator();
+    }
+  }
+
+
+  /**
+   * Get an iterator over all exported packages with specific name.
+   *
+   * @return An Iterator over ExportPkg.
+   */
+  Iterator<ExportPkg> getExports(String pkg) {
+    final ArrayList<ExportPkg> res = new ArrayList<ExportPkg>(2);
+    ExportPkg ep = getExport(pkg);
+    if (ep != null) {
+      res.add(ep);
+    }
+    if (fragments != null) {
+      synchronized (fragments) {
+        for (final BundlePackages bundlePackages : fragments.values()) {
+          ep = bundlePackages.getExport(pkg);
+          if (ep != null) {
+            res.add(ep);
+          }
+        }
+      }
+    }
+    return res.isEmpty() ? null : res.iterator();
+  }
+
+
+  /**
+   * Check if this packaged is exported
+   */
+  boolean isExported(String pkg) {
+    if (getExport(pkg) != null) {
+      return true;
+    }
+    if (fragments != null) {
+      synchronized (fragments) {
+        for (final BundlePackages bundlePackages : fragments.values()) {
+          if (bundlePackages.getExport(pkg) != null) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * Get an iterator over all static imported packages sorted
+   * according to ipComp.
+   *
+   * @return An Iterator over ImportPkg.
+   */
+  Iterator<ImportPkg> getImports() {
+    if (fragments != null) {
+      synchronized (fragments) {
+        final ArrayList<Iterator<ImportPkg>> iters = new ArrayList<Iterator<ImportPkg>>(fragments.size() + 1);
+        iters.add(imports.iterator());
+        for (final BundlePackages bundlePackages : fragments.values()) {
+          iters.add(bundlePackages.getImports());
+        }
+        return new IteratorIteratorSorted<ImportPkg>(iters, ipComp);
+      }
+    } else {
+      return imports.iterator();
+    }
+  }
+
+
+  /**
+   * Get an iterator over all active imported packages.
+   *
+   * @return An Iterator over ImportPkg.
+   */
+  Iterator<ImportPkg> getActiveImports() {
+    if (okImports != null) {
+      return okImports.iterator();
+    } else if (bg.isFragment()){
+      // This is fragment BP, use host
+      return bg.bpkgs.getActiveImports();
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Get the list of package capabilities derived from the Export-Package header.
+   *
+   * The bundle capability objects in the list has the same order as the packages
+   * in the Export-Package header.
+   *
+   * @return ordered list with bundle capabilities for packages.
+   */
+  SortedSet<ExportPkg> getDeclaredPackageCapabilities()
+  {
+    final TreeSet<ExportPkg> epCreationOrder = new TreeSet<ExportPkg>(exports);
+
+    return epCreationOrder;
+  }
+
+
+  /**
+   * Get the list package requirements derived from the Import-Package header.
+   * The bundle requirement objects for imported packages in the list has the
+   * same order as the packages in the Import-Package header.
+   *
+   * @return all defined import package requirements for this bundle revision.
+   */
+  SortedSet<ImportPkg> getDeclaredPackageRequirements() {
+    final TreeSet<ImportPkg> ipCreationOrder = new TreeSet<ImportPkg>(imports);
+    ipCreationOrder.addAll(dImportPatterns);
+    return ipCreationOrder;
+  }
+
+
+  /**
+   * Get the list of package capabilities available for export. Contains exports from fragments.
+   *
+   * The bundle capability objects in the list has the same order as the packages
+   * in the Export-Package header.
+   *
+   * @return ordered list with bundle capabilities for packages.
+   */
+  List<ExportPkg> getPackageCapabilities() {
+    List<ExportPkg> res = new ArrayList<ExportPkg>(getDeclaredPackageCapabilities());
+    if (fragments != null) {
+      synchronized (fragments) {
+        for (final BundlePackages bpkgs : fragments.values()) {
+          res.addAll(bpkgs.getDeclaredPackageCapabilities());
+        }
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get the list of package capabilities available for export. Contains exports from fragments.
+   *
+   * The bundle capability objects in the list has the same order as the packages
+   * in the Export-Package header.
+   *
+   * @return ordered list with bundle capabilities for packages.
+   */
+  List<ImportPkg> getPackageRequirements() {
+    List<ImportPkg> res = new ArrayList<ImportPkg>();
+    for (ImportPkg ip : getDeclaredPackageRequirements()) {
+      if (ip.provider != null || ip.isDynamic()) {
+        res.add(ip);
+      }      
+    }
+    if (fragments != null) {
+      HashSet<ImportPkg> parents = new HashSet<ImportPkg>();
+      synchronized (this) {
+        // Get fragment parents
+        for (ImportPkg oip : okImports) {
+          if (oip.parent != null && oip.parent.bpkgs != oip.bpkgs) {
+            parents.add(oip.parent);
+          }
+        }
+      }
+      synchronized (fragments) {
+        for (final BundlePackages bpkgs : fragments.values()) {
+          for (ImportPkg ip : bpkgs.getDeclaredPackageRequirements()) {
+            if (ip.isDynamic() || parents.contains(ip)) {
+              res.add(ip);
+            }
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+
+  synchronized List<ImportPkg> getActiveChildImports(ImportPkg ip) {
+    List<ImportPkg> res = new ArrayList<ImportPkg>();
+    for (ImportPkg oip : okImports) {
+      if (oip.parent == ip) {
+        res.add(oip);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get the list bundle requirements derived from the Require-Bundle header.
+   * The bundle requirement objects for required bundles in the list has the
+   * same order as the bundles in the Require-Bundle header.
+   *
+   * @return all defined require bundle requirements for this bundle revision.
+   */
+  List<BundleRequirement> getDeclaredBundleRequirements() {
+    final List<BundleRequirement> res = new ArrayList<BundleRequirement>();
+
+    if (require!=null) {
+      final TreeSet<RequireBundle> rbCreationOrder
+        = new TreeSet<RequireBundle>(require);
+      res.addAll(rbCreationOrder);
+    }
+    return res;
+  }
+
+  /**
+   * 
+   * @return
+   */
+  Map<String, List<BundleCapabilityImpl>> getOtherCapabilities() {
+    Map<String, List<BundleCapabilityImpl>> res = capabilities;
+    if (fragments != null) {
+      synchronized (fragments) {
+        boolean copied = false;
+        for (final BundlePackages bpkgs : fragments.values()) {
+          Map<String, List<BundleCapabilityImpl>> frm = bpkgs.getOtherCapabilities();
+          if (!frm.isEmpty()) {
+            if (!copied) {
+              res = new HashMap<String, List<BundleCapabilityImpl>>(res);
+              copied = true;
+            }
+            for (Entry<String, List<BundleCapabilityImpl>> e : frm.entrySet()) {
+              String ns = e.getKey();
+              List<BundleCapabilityImpl> p = res.get(ns);
+              if (p != null) {
+                p = new ArrayList<BundleCapabilityImpl>(p);
+                p.addAll(e.getValue());
+              } else {
+                p = e.getValue();
+              }
+              res.put(ns, p);
+            }
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+
+
+  /**
+   * Get class loader for these packages.
+   *
+   * @return ClassLoader handling these packages.
+   */
+  ClassLoader getClassLoader() {
+    return bg.getClassLoader();
+  }
+
+
+  /**
+   * Is these packages registered in the Packages object.
+   *
+   * @return True if packages are registered otherwise false.
+   */
+  boolean isRegistered() {
+    return registered;
+  }
+
+
+  /**
+   * Attach a fragment bundle packages.
+   *
+   * @param fbpkgs The BundlePackages of the fragment to be attached.
+   * @return null if okay, otherwise a String with fail reason.
+   * @throws BundleException Resolver hook complaint.
+   */
+  String attachFragment(BundlePackages fbpkgs) throws BundleException {
+    // TODO, should we lock this?!
+    final boolean resolvedHost = okImports != null;
+    final BundlePackages nfbpkgs = new BundlePackages(this, fbpkgs, resolvedHost);
+    nfbpkgs.registerPackages();
+    if (resolvedHost) {
+      try {
+        failReason = bg.bundle.fwCtx.resolver.resolve(bg, nfbpkgs, null);
+      } catch (BundleException be) {
+        nfbpkgs.unregisterPackages(true);
+        throw be;
+      }
+      if (failReason == null) {
+        for (final Iterator<ImportPkg> i = nfbpkgs.getImports(); i.hasNext();) {
+          final ImportPkg ip = i.next();
+          if (ip.provider != null) { // <=> optional import with unresolved
+                                     // provider
+            final int ii = Util.binarySearch(okImports, ipComp, ip);
+            if (ii < 0) {
+              okImports.add(-ii - 1, ip);
+            }
+          }
+        }
+      } else {
+        nfbpkgs.unregisterPackages(true);
+        return failReason;
+      }
+    }
+    if (fragments == null) {
+      fragments = new TreeMap<BundleGeneration, BundlePackages>();
+    }
+    fragments.put(fbpkgs.bg, nfbpkgs);
+    return null;
+  }
+
+
+  /**
+   * An attached fragment is now a zombie since it have been updated or
+   * uninstalled. Mark all packages exported by this host as zombies, since
+   * their contents may have changed.
+   *
+   * @param fb The fragment bundle that have been updated or uninstalled.
+   */
+  void fragmentIsZombie(BundleImpl fb) {
+    if (null != exports) {
+      if (bg.bundle.fwCtx.debug.resolver) {
+        bg.bundle.fwCtx.debug.println("Marking all packages exported by host bundle(id="
+                                      + bg.bundle.id + ",gen=" + bg.generation
+                                      + ") as zombies since the attached fragment (id="
+                                      + fb.getBundleId() + ") was updated/uninstalled.");
+      }
+      for (final ExportPkg exportPkg : exports) {
+        exportPkg.zombie = true;
+      }
+    }
+  }
+
+
+  /**
+   * Detach a fragment bundle's packages.
+   *
+   * I.e., unregister and remove the fragments import / exports from the set of
+   * packages that are imported / exported by this bundle packages.
+   *
+   * If this bundle packages is resolved, do nothing since in that case must not
+   * change the set of imports and exports.
+   *
+   * @param fb The fragment bundle to detach.
+   */
+  void detachFragmentSynchronized(BundleGeneration fbg, boolean unregister) {
+    if (fragments != null) {
+      synchronized (fragments) {
+        detachFragment(fbg, unregister);
+      }
+    }
+  }
+
+
+  /**
+   * Sets these packages registered in the Packages object.
+   *
+   * @return True if packages are registered otherwise false.
+   */
+  void unregister() {
+    registered = false;
+    unRequireBundles();
+  }
+
+
+  /**
+   * Return a string representing this object
+   *
+   * @return A message string.
+   */
+  @Override
+  public String toString() {
+    return "BundlePackages" + bundleGenInfo();
+  }
+
+
+  String bundleGenInfo() {
+    return "[id=" + bg.bundle.id + ",gen=" + bg.generation + "]";
+  }
+
+
+  boolean isActive() {
+    return okImports != null;
+  }
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Get a specific import
+   *
+   * @return an import
+   */
+  private ImportPkg getImport(String pkg) {
+    final int i = Util.binarySearch(imports, ipFind, pkg);
+    if (i >= 0) {
+      return imports.get(i);
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Remove this bundle packages from the requiredBy list in the wired required
+   * bundle package.
+   */
+  private void unRequireBundles() {
+    if (require != null) {
+      for (final RequireBundle req : require) {
+        if (null != req.bpkgs && null != req.bpkgs.requiredBy) {
+          req.bpkgs.requiredBy.remove(this);
+          // TODO check if we can reset bpkgs to make checking easier
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Detach all remaining fragments.
+   */
+  private void detachFragments() {
+    if (fragments != null) {
+      synchronized (fragments) {
+        while (!fragments.isEmpty()) {
+          detachFragment(fragments.lastKey(), false);
+        }
+        fragments = null;
+      }
+    }
+  }
+
+
+  /**
+   * Detach a fragment bundle's packages.
+   *
+   * I.e., unregister and remove the fragments import / exports from the set of
+   * packages that are imported / exported by this bundle packages.
+   *
+   * If this bundle packages is resolved, do nothing since in that case must not
+   * change the set of imports and exports.
+   *
+   * Note! Must be called with fragments locked.
+   *
+   * @param fb The fragment bundle to detach.
+   * @param unregisterPkg Unregister the imports and exports of the specified
+   *          fragment.
+   */
+  private void detachFragment(final BundleGeneration fbg, final boolean unregisterPkg) {
+    if (null == okImports) {
+      final BundlePackages fbpkgs = fragments.remove(fbg);
+      if (fbpkgs != null) {
+        if (unregisterPkg) {
+          fbpkgs.unregisterPackages(true);
+        } else {
+          fbpkgs.unregister();
+        }
+      }
+    }
+  }
+
+  /**
+   * Parse the dynamic import attribute
+   */
+
+  void parseDynamicImports(final String s) {
+    for (final HeaderEntry he : Util
+        .parseManifestHeader(Constants.DYNAMICIMPORT_PACKAGE, s, false, true,
+                             false)) {
+      if (he.getDirectives().containsKey(Constants.RESOLUTION_DIRECTIVE)) {
+        throw new IllegalArgumentException(Constants.DYNAMICIMPORT_PACKAGE +
+                                           " entry illegal contains a " +
+                                           Constants.RESOLUTION_DIRECTIVE +
+                                           " directive.");
+      }
+      ImportPkg tmpl = null;
+      for (String key : he.getKeys()) {
+        if (key.equals("*")) {
+          key = EMPTY_STRING;
+        } else if (key.endsWith(".*")) {
+          key = key.substring(0, key.length() - 1);
+        } else if (key.endsWith(".")) {
+          throw new IllegalArgumentException(Constants.DYNAMICIMPORT_PACKAGE +
+                                             " entry ends with '.': " + key);
+        } else if (key.indexOf("*") != -1) {
+          throw new IllegalArgumentException(Constants.DYNAMICIMPORT_PACKAGE +
+                                           " entry contains a '*': " + key);
+        }
+        if (tmpl != null) {
+          dImportPatterns.add(new ImportPkg(tmpl, key));
+        } else {
+          tmpl = new ImportPkg(key, he, this, true);
+          dImportPatterns.add(tmpl);
+        }
+      }
+    }
+  }
+
+  //
+  // Pkg Comparators
+  //
+
+  static final Comparator<ExportPkg, ExportPkg> epComp
+    = new Util.Comparator<ExportPkg, ExportPkg>() {
+    /**
+     * Compare two ExportPkg objects on package name.
+     *
+     * @param a Object to compare.
+     * @param b Object to compare.
+     * @return Return 0 if equals, negative if first object is less than second
+     *         object and positive if first object is larger then second object.
+     * @exception ClassCastException if object is not a ExportPkg object.
+     */
+    public int compare(ExportPkg a, ExportPkg b) throws ClassCastException {
+      return a.name.compareTo(b.name);
+    }
+  };
+
+  static final Util.Comparator<ExportPkg,String> epFind
+    = new Util.Comparator<ExportPkg,String>() {
+    /**
+     * Compare package name of ExportPkg object with String object.
+     *
+     * @param a ExportPkg object to compare.
+     * @param b String object to compare.
+     * @return Return 0 if equals, negative if first object is less than second
+     *         object and positive if first object is larger then second object.
+     * @exception ClassCastException if object is not a ExportPkg object.
+     */
+    public int compare(ExportPkg a, String b)
+    {
+      return a.name.compareTo(b);
+    }
+  };
+
+  static final Util.Comparator<ImportPkg,ImportPkg> ipComp
+    = new Util.Comparator<ImportPkg, ImportPkg>() {
+    /**
+     * Compare two ImportPkg objects by package name.
+     *
+     * @param a Object to compare.
+     * @param b Object to compare.
+     * @return Return 0 if equals, negative if first object is less than second
+     *         object and positive if first object is larger then second object.
+     * @exception ClassCastException if object is not a ImportPkg object.
+     */
+    public int compare(ImportPkg a, ImportPkg b) throws ClassCastException {
+      return a.name.compareTo(b.name);
+    }
+  };
+
+  static final Util.Comparator<ImportPkg,String> ipFind
+    = new Util.Comparator<ImportPkg,String>() {
+    /**
+     * Compare package name in ImportPkg object with a package name as a String.
+     *
+     * @param a Candidate ImportPkg object to compare.
+     * @param b Package name of the ImportPkg to find.
+     * @return Return 0 if equals, negative if first object is less than second
+     *         object and positive if first object is larger then second object.
+     */
+    public int compare(ImportPkg a, String b) {
+      return a.name.compareTo(b);
+    }
+  };
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleReferenceImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleReferenceImpl.java
new file mode 100644
index 0000000..3f10c2d
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleReferenceImpl.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+public class BundleReferenceImpl implements BundleReference {
+
+	final BundleImpl bundle;
+
+  BundleReferenceImpl(BundleImpl bundle) {
+	  this.bundle = bundle;
+	}
+
+  public Bundle getBundle() {
+		return bundle;
+	}
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleRequirementImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleRequirementImpl.java
new file mode 100644
index 0000000..1404a91
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleRequirementImpl.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+public class BundleRequirementImpl
+  implements BundleRequirement
+{
+
+  private final BundleGeneration gen;
+  private final String nameSpace;
+  private final Map<String, Object> attributes;
+  private final Map<String,String> directives;
+  private final Filter filter;
+  private BundleWireImpl wire = null;
+
+
+  /**
+   * Creates a {@link BundleRequirement} from one entry in the parsed
+   * "Require-Capability" manifest header.
+   *
+   * @param gen
+   *          the owning bundle revision.
+   * @param he
+   *          the parsed entry from the "Require-Capability" manifest header.
+   */
+  BundleRequirementImpl(final BundleGeneration gen, final HeaderEntry he)
+  {
+    this.gen = gen;
+    nameSpace = he.getKey();
+    for (final String ns : Arrays
+        .asList(new String[] { BundleRevision.BUNDLE_NAMESPACE,
+                               BundleRevision.HOST_NAMESPACE,
+                               BundleRevision.PACKAGE_NAMESPACE })) {
+      if (ns.equals(nameSpace)) {
+        throw new IllegalArgumentException("Capability with name-space '" + ns
+                                           + "' must not be required in the "
+                                           + Constants.REQUIRE_CAPABILITY
+                                           + " manifest header.");
+      }
+    }
+
+    final String filterStr = he.getDirectives().remove("filter");
+    if (null!=filterStr && filterStr.length()>0) {
+      try {
+        filter = FrameworkUtil.createFilter(filterStr);
+        he.getDirectives().put("filter", filter.toString());
+      } catch (final InvalidSyntaxException ise) {
+        final String msg = "Invalid filter '" + filterStr + "' in "
+                           + Constants.REQUIRE_CAPABILITY
+                           + " for name-space " + nameSpace + ": " + ise;
+        throw (IllegalArgumentException)
+          new IllegalArgumentException(msg).initCause(ise);
+      }
+    } else {
+      filter = null;
+    }
+    directives = Collections.unmodifiableMap(he.getDirectives());
+    attributes = Collections.unmodifiableMap(he.getAttributes());
+  }
+
+  /**
+   * Creates a {@link BundleRequirement} from a
+   * "Bundle-RequiredExecutionEnvironment" manifest header.
+   *
+   * @param gen
+   *          the owning bundle revision.
+   * @param ee
+   *          the entry from the "Bundle-RequiredExecutionEnvironment" manifest header.
+   */
+  @SuppressWarnings("unchecked")
+  BundleRequirementImpl(final BundleGeneration gen, final String ee)
+  {
+    this.gen = gen;
+    nameSpace = ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE;
+
+    final StringBuffer filterStrB = new StringBuffer();
+    final String[] l = Util.splitwords(ee, ",");
+    if (l.length > 1) {
+      filterStrB.append("(|");
+    }
+    for (final String e : l) {
+      final String[] es = Util.splitwords(e, "-");
+      try {
+        if (es.length == 2) {
+          final int si = es[1].indexOf('/');
+          new Version(si == -1 ? es[1] : es[1].substring(0, si));
+          filterStrB.append("(&(").append(nameSpace).append('=');
+          if (es[0].equalsIgnoreCase("J2SE")) {
+            es[0]="JavaSE";
+          }
+          filterStrB.append(es[0]);
+          if (si != -1) {
+            filterStrB.append(es[1].substring(si));
+          }
+          filterStrB.append(")(version=").append(es[1]).append("))");
+          continue;
+        } else if (es.length > 2) {
+          final StringBuffer esStrB = new StringBuffer(es[0]);
+          Version v = null;
+          for (int i = 1; i < es.length; i++) {
+            if (Character.isDigit(es[i].charAt(0))) {
+              if (v == null) {
+                final int si = es[i].indexOf('/');
+                v = new Version(si == -1 ? es[i] : es[i].substring(0, si));
+                if (si != -1) {
+                  esStrB.append(es[1].substring(si));
+                } else if (i != es.length - 1) {
+                  throw new IllegalArgumentException("Version not at end");                  
+                }
+              } else {
+                if (v.equals(new Version(es[i])) && i == es.length - 1) {
+                  break;
+                }
+                throw new IllegalArgumentException("Version mismatch");
+              }
+            } else {
+              esStrB.append('-').append(es[i]);
+            }
+          }
+          if (v != null) {
+            filterStrB.append("(&(").append(nameSpace).append('=');
+            filterStrB.append(esStrB).append(")(version=");
+            filterStrB.append(v).append("))");
+            continue;
+          }
+        }
+      } catch (IllegalArgumentException _ignore) { }
+      filterStrB.append('(').append(nameSpace).append('=');
+      filterStrB.append(e).append(')');
+    }
+    if (l.length > 1) {
+      filterStrB.append(')');
+    }
+    
+    try {
+      filter = FrameworkUtil.createFilter(filterStrB.toString());
+    } catch (final InvalidSyntaxException ise) {
+      throw new RuntimeException("Internal error");
+    }
+    directives = Collections.singletonMap("filter", filter.toString());
+    attributes = Collections.EMPTY_MAP;
+  }
+
+  @Override
+  public String getNamespace()
+  {
+    return nameSpace;
+  }
+
+  @Override
+  public Map<String, String> getDirectives()
+  {
+    return directives;
+  }
+
+  @Override
+  public Map<String, Object> getAttributes()
+  {
+    return attributes;
+  }
+
+  @Override
+  public BundleRevision getRevision()
+  {
+    return gen.bundleRevision;
+  }
+
+
+  @Override
+  public BundleRevision getResource() {
+	return gen.bundleRevision;
+  }
+
+
+  @Override
+  public boolean matches(BundleCapability capability) {
+    if (nameSpace.equals(capability.getNamespace())) {
+      return null==filter ? true : filter.matches(capability.getAttributes());
+    }
+    return false;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuffer sb = new StringBuffer(40);
+
+    sb.append("[")
+    .append(BundleRequirement.class.getName())
+    .append(": ")
+    .append(nameSpace)
+    .append(" directives: ")
+    .append(directives.toString())
+    .append("]");
+
+    return sb.toString();
+  }
+
+
+  BundleGeneration getBundleGeneration() {
+    return gen;
+  }
+
+
+  BundleWireImpl getWire() {
+    return wire;
+  }
+
+
+  void resetWire() {
+    if (wire != null) {
+      ((BundleCapabilityImpl)wire.getCapability()).removeWire(this.wire);
+      this.wire = null;
+    }
+  }
+
+
+  void setWire(BundleWireImpl wire) {
+    ((BundleCapabilityImpl)wire.getCapability()).addWire(wire);
+    this.wire = wire;
+  }
+
+
+  boolean isOptional() {
+    final String resolution = directives.get(Constants.RESOLUTION_DIRECTIVE);
+    return Constants.RESOLUTION_OPTIONAL.equals(resolution);
+  }
+
+
+  boolean shouldResolve() {
+    final String effective = directives.get(Constants.EFFECTIVE_DIRECTIVE);
+    return effective == null || effective.equals(Constants.EFFECTIVE_RESOLVE);
+  }
+
+
+  boolean isWired() {
+    return wire != null;
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleResourceStream.java b/osgi/framework/src/org/knopflerfish/framework/BundleResourceStream.java
new file mode 100644
index 0000000..117836c
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleResourceStream.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+
+/**
+ * InputStream for bundle content
+ *
+ * @author Jan Stein
+ */
+public class BundleResourceStream extends InputStream {
+
+  protected InputStream wis;
+
+  protected long contentLen;
+
+
+  /**
+   * BundleResourceStream
+   *
+   * @param is Underlying input stream.
+   * @parma length Length of content, -1 if unknown.
+   */
+  public BundleResourceStream(InputStream is, long length) {
+    wis = is;
+    contentLen = length;
+  }
+
+
+  /**
+   * Get length of resource stream.
+   *
+   * @return Length of resource stream. If length is unknown
+   *         -1 is returned.
+   */
+  public long getContentLength() {
+    return contentLen;
+  }
+
+
+  /**
+   * Read a byte from the input stream.
+   *
+   * @return Byte read
+   */
+  public int read() throws IOException {
+    return wis.read();
+  }
+
+  
+  /**
+   * Read bytes from the input stream.
+   *
+   * @param dest Byte array to read into
+   * @return Number of bytes actually read
+   */
+  public int read(byte[] dest) throws IOException {
+    return wis.read(dest);
+  }
+
+
+  /**
+   * Read a specified number of bytes from the input stream.
+   *
+   * @param dest  Byte array to read into
+   * @param off   Starting offset into the byte array
+   * @param len   Maximum number of bytes to read
+   * @return Number of bytes actually read
+   */
+  public int read(byte[] dest, int off, int len) throws IOException {
+    return wis.read(dest, off, len);
+  }
+
+
+  /**
+   * Skip over (and discard) a specified number of bytes in this input
+   * stream.
+   *
+   * @param len Number of bytes to be skipped
+   * @return Number of bytes skipped
+   */
+  public long skip(long len) throws IOException {
+    return wis.skip(len);
+  }
+
+
+  /**
+   * Return the number of bytes available for immediate read
+   *
+   * @return the number of bytes
+   */
+  public int available() throws IOException {
+    return wis.available();
+  }
+
+
+  /**
+   * Close input stream
+   */
+  public void close() throws IOException {
+    wis.close();
+  }
+
+
+  /**
+   * Mark current position in input stream
+   *
+   * @param readlimit Maximum of bytes when can save.
+   */
+  public void mark(int readlimit) {
+    wis.mark(readlimit);
+  }
+
+
+  /**
+   * Return to marked position.
+   */
+  public void reset() throws IOException {
+    wis.reset();
+  }
+
+
+  /**
+   * Check it mark/reset is supported.
+   *
+   * @return True if supported, otherwise false.
+   */
+  public boolean markSupported() {
+    return wis.markSupported();
+  }
+ 
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleRevisionImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleRevisionImpl.java
new file mode 100644
index 0000000..7962359
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleRevisionImpl.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+
+public class BundleRevisionImpl
+  extends BundleReferenceImpl
+  implements BundleRevision
+{
+
+  static final int NS_BUNDLE =    1;
+  static final int NS_HOST =      2;
+  static final int NS_IDENTITY =  4;
+  static final int NS_PACKAGE =   8;
+  static final int NS_OTHER =    16;
+
+  final BundleGeneration gen;
+  private BundleWiring bundleWiring = null;
+
+
+  BundleRevisionImpl(BundleGeneration gen) {
+    super(gen.bundle);
+    this.gen = gen;
+  }
+
+
+  @Override
+  public String getSymbolicName() {
+    return gen.symbolicName;
+  }
+
+
+  @Override
+  public Version getVersion() {
+    return gen.version;
+  }
+
+
+  @Override
+  public List<BundleCapability> getDeclaredCapabilities(String namespace) {
+    final ArrayList<BundleCapability> res = new ArrayList<BundleCapability>();
+    final int ns = whichNameSpaces(namespace);
+
+    if ((ns & NS_BUNDLE) != 0) {
+      final BundleCapability bc = gen.getBundleCapability();
+      if (bc!=null) {
+        res.add(bc);
+      }
+    }
+    if ((ns & NS_HOST) != 0) {
+      final BundleCapability bc = gen.getHostCapability();
+      if (bc!=null) {
+        res.add(bc);
+      }
+    }
+
+    if ((ns & NS_IDENTITY) != 0) {
+      final BundleCapability bc = gen.getIdentityCapability();
+      if (bc!=null) {
+        res.add(bc);
+      }
+    }
+
+    if ((ns & NS_PACKAGE) != 0) {
+      res.addAll(gen.bpkgs.getDeclaredPackageCapabilities());
+    }
+
+    if ((ns & NS_OTHER) != 0) {
+      final Map<String, List<BundleCapabilityImpl>> caps = gen.getDeclaredCapabilities();
+      if (null != namespace) {
+        final List<BundleCapabilityImpl> lcap = caps.get(namespace);
+        if (lcap != null) {
+          res.addAll(lcap);
+        }
+      } else {
+        for (final List<BundleCapabilityImpl> lcap : caps.values()) {
+          res.addAll(lcap);
+        }
+      }
+    }
+
+    return res;
+  }
+
+
+  @Override
+  public List<BundleRequirement> getDeclaredRequirements(String namespace) {
+    final ArrayList<BundleRequirement> res = new ArrayList<BundleRequirement>();
+    final int ns = whichNameSpaces(namespace);
+
+    if ((ns & NS_BUNDLE) != 0) {
+      res.addAll(gen.bpkgs.getDeclaredBundleRequirements());
+    }
+
+    if ((ns & NS_HOST) != 0) {
+      if (gen.isFragment()) {
+        res.add(gen.fragment);
+      }
+    }
+
+    if ((ns & NS_PACKAGE) != 0) {
+      res.addAll(gen.bpkgs.getDeclaredPackageRequirements());
+    }
+
+    if ((ns & (NS_IDENTITY|NS_OTHER)) != 0) {
+      final Map<String, List<BundleRequirementImpl>> reqs = gen.getDeclaredRequirements();
+      if (null != namespace) {
+        final List<BundleRequirementImpl> lbr = reqs.get(namespace);
+        if (lbr != null) {
+          res.addAll(lbr);
+        }
+      } else {
+        for (final List<BundleRequirementImpl> lbr : reqs.values()) {
+          res.addAll(lbr);
+        }
+      }
+    }
+
+    return res;
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Capability> getCapabilities(String namespace) {
+    return (List<Capability>)(List<?>)getDeclaredCapabilities(namespace);
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Requirement> getRequirements(String namespace) {
+    return (List<Requirement>)(List<?>)getDeclaredRequirements(namespace);
+  }
+
+
+  @Override
+  public int getTypes() {
+    return gen.isFragment() ? TYPE_FRAGMENT : 0;
+  }
+
+
+  @Override
+  public BundleWiring getWiring() {
+    return bundleWiring;
+  }
+
+
+  @Override
+  public String toString() {
+    return "BundleRevision[" + getSymbolicName() + ":" + getVersion() + "]";
+  }
+
+
+  BundleGeneration getBundleGeneration() {
+    return gen;
+  }
+  
+
+  void setWired() {
+    bundleWiring = new BundleWiringImpl(this);
+  }
+
+
+  void clearWiring() {
+    bundleWiring = null;
+  }
+
+
+  static int whichNameSpaces(String namespace) {
+    int ns;
+    if (namespace == null) {
+      ns = NS_BUNDLE|NS_HOST|NS_IDENTITY|NS_PACKAGE|NS_OTHER;
+    } else if (BundleRevision.BUNDLE_NAMESPACE.equals(namespace)) {
+      ns = NS_BUNDLE;
+    } else if (BundleRevision.HOST_NAMESPACE.equals(namespace)) {
+      ns = NS_HOST;
+    } else if (IdentityNamespace.IDENTITY_NAMESPACE.equals(namespace)) {
+      ns = NS_IDENTITY;
+    } else if (BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
+      ns = NS_PACKAGE;
+    } else {
+      ns = NS_OTHER;
+    }
+    return ns;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleRevisionsImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleRevisionsImpl.java
new file mode 100644
index 0000000..1660089
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleRevisionsImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
+
+public class BundleRevisionsImpl extends BundleReferenceImpl implements BundleRevisions {
+
+  private Vector<BundleGeneration> generations;
+
+  BundleRevisionsImpl(Vector<BundleGeneration> generations) {
+    super(generations.get(0).bundle);
+    this.generations = generations;
+  }
+
+  public List<BundleRevision> getRevisions() {
+    synchronized (generations) {
+      List<BundleRevision> res = new ArrayList<BundleRevision>(generations.size());
+      for (BundleGeneration bg : generations) {
+        if (!bg.isUninstalled()) {
+          res.add(bg.bundleRevision);
+        }
+      }
+      return res;
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleStorage.java b/osgi/framework/src/org/knopflerfish/framework/BundleStorage.java
new file mode 100644
index 0000000..3311341
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleStorage.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Interface for managing all bundles jar content.
+ *
+ * @author Jan Stein
+ */
+public interface BundleStorage {
+
+  /**
+   * Insert bundle into persistent storagedata.
+   *
+   * @param location Locaion of bundle to install.
+   * @param is Inputstream containing bundle.
+   * @return BundleArchive representing installed bundle.
+   */
+  BundleArchive insertBundleJar(String location, InputStream is)
+    throws Exception;
+
+
+  /**
+   * Insert a new jar file into persistent storagedata as an update
+   * to an existing bundle archive. To commit this data a call to
+   * <code>replaceBundleArchive</code> is needed.
+   *
+   * @param old BundleArchive to be replaced.
+   * @param is Input-stream with bundle content.
+   * @return Bundle archive object.
+   */
+  BundleArchive updateBundleArchive(BundleArchive old, InputStream is)
+    throws Exception;
+
+
+  /**
+   * Replace old bundle archive with a new updated bundle archive, that
+   * was created with updateBundleArchive.
+   *
+   * @param oldBA BundleArchive to be replaced.
+   * @param newBA BundleArchive with bundle content.
+   * @return New bundle archive object.
+   */
+  void replaceBundleArchive(BundleArchive oldBA, BundleArchive newBA)
+    throws Exception;
+
+
+  /**
+   * Get all bundle archive objects.
+   *
+   * @return Private copy of a List with bundle id's.
+   */
+  BundleArchive [] getAllBundleArchives();
+
+
+  /**
+   * Get all bundles tagged to start at next launch of framework.
+   * This list is sorted in suggest start order.
+   *
+   * @return Private copy of a List with bundle id's.
+   */
+  List<String> getStartOnLaunchBundles();
+
+
+  /**
+   * Close this bundle storage and all bundles in it.
+   */
+  void close();
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleThread.java b/osgi/framework/src/org/knopflerfish/framework/BundleThread.java
new file mode 100644
index 0000000..8d8fff9
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleThread.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.lang.reflect.Method;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+
+class BundleThread extends Thread {
+  final private static int OP_IDLE = 0;
+  final private static int OP_BUNDLE_EVENT = 1;
+  final private static int OP_START = 2;
+  final private static int OP_STOP = 3;
+
+  final private static int KEEP_ALIVE = 1000;
+
+  final static String ABORT_ACTION_STOP = "stop";
+  final static String ABORT_ACTION_MINPRIO = "minprio";
+  final static String ABORT_ACTION_IGNORE = "ignore";
+
+  final private FrameworkContext fwCtx;
+  private long startStopTimeout = 0;
+  final private Object lock = new Object();
+  volatile private BundleEvent be;
+  volatile private BundleImpl bundle;
+  volatile private int operation = OP_IDLE;
+  volatile private Object res;
+  volatile private boolean doRun;
+
+  // Thread.stop() is not available in all Execution Environments...
+  final static Method stopMethod  = initStopSupported();
+  private static Method initStopSupported()
+  {
+    try {
+      return Thread.class.getMethod("stop", (Class[]) null);
+    } catch (final Throwable _t) {
+      return null;
+    }
+  }
+
+  static void checkWarnStopActionNotSupported(FrameworkContext fc)
+  {
+    final String s = fc.props.getProperty(FWProps.BUNDLETHREAD_ABORT);
+    if (ABORT_ACTION_STOP.equals(s) && null==stopMethod) {
+      System.err.println("WARNING: Bundle thread abort action stop was "
+                         +"requested but is not supported on this execution "
+                         +"environment; using 'minprio' as abort action.");
+    }
+  }
+
+  BundleThread(FrameworkContext fc) {
+    super(fc.threadGroup, "BundleThread waiting");
+    setDaemon(true);
+    fwCtx = fc;
+    doRun = true;
+    
+    // get bundlethread timeout property value
+    String timeout = fwCtx.props.getProperty(FWProps.BUNDLETHREAD_TIMEOUT);
+    if (timeout != null) {
+      try {
+        startStopTimeout = 1000 * Integer.parseInt(timeout);
+      } catch (NumberFormatException nfe) {
+        fwCtx.debug.println("Property " + FWProps.BUNDLETHREAD_TIMEOUT
+                            + " has a non integer value, ignoring");
+      }
+    }
+    
+    start();
+  }
+
+
+  /**
+   *
+   */
+  void quit() {
+    doRun = false;
+    interrupt();
+  }
+
+
+  @Override
+  public void run() {
+    while (doRun) {
+      synchronized (lock) {
+        while (doRun && operation == OP_IDLE) {
+          try {
+            lock.wait(KEEP_ALIVE);
+            if (operation != OP_IDLE) {
+              break;
+            }
+            synchronized (fwCtx.bundleThreads) {
+              if (fwCtx.bundleThreads.remove(this)) {
+                return;
+              }
+            }
+          } catch (final InterruptedException ie) {
+          }
+        }
+        if (!doRun) {
+          break;
+        }
+        Object tmpres = null;
+        try {
+          switch (operation) {
+          case OP_BUNDLE_EVENT:
+            setName("BundleChanged #" + be.getBundle().getBundleId());
+            fwCtx.listeners.bundleChanged(be);
+            break;
+          case OP_START:
+            setName("BundleStart #" + bundle.getBundleId());
+            tmpres = bundle.start0();
+            break;
+          case OP_STOP:
+            setName("BundleStop #" + bundle.getBundleId());
+            tmpres = bundle.stop1();
+            break;
+          }
+        } catch (final Throwable t) {
+          fwCtx.frameworkError(bundle, t);
+        }
+        operation = OP_IDLE;
+        res = tmpres;
+      }
+      synchronized (fwCtx.resolver) {
+        fwCtx.resolver.notifyAll();
+      }
+    }
+  }
+
+
+  /**
+   * Note! Must be called while holding packages lock.
+   */
+  void bundleChanged(final BundleEvent be) {
+    this.be = be;
+    startAndWait((BundleImpl)be.getBundle(), OP_BUNDLE_EVENT);
+  }
+
+
+  /**
+   * Note! Must be called while holding packages lock.
+   */
+  BundleException callStart0(final BundleImpl b) {
+    return (BundleException)startAndWait(b, OP_START);
+  }
+
+
+  /**
+   * Note! Must be called while holding packages lock.
+   */
+  BundleException callStop1(final BundleImpl b) {
+    return (BundleException)startAndWait(b, OP_STOP);
+  }
+
+
+  /**
+   * Note! Must be called while holding packages lock.
+   */
+  private Object startAndWait(final BundleImpl b, final int op) {
+    synchronized (lock) {
+      res = Boolean.FALSE;
+      bundle = b;
+      operation = op;
+      lock.notifyAll();
+    }
+
+    // timeout for waiting on op to finish can be set for start/stop
+    long left = 0;
+    if (op == OP_START || op == OP_STOP) {
+      b.aborted = null; // clear aborted status
+      left = startStopTimeout;
+    }    
+    boolean timeout = false;
+    boolean uninstall = false;
+
+    long waitUntil = Util.timeMillis() + left;
+    do {
+      try {
+        fwCtx.resolver.wait(left);
+      } catch (InterruptedException ie) { }
+
+      // Abort start/stop operation if bundle has been uninstalled
+      if ((op == OP_START || op == OP_STOP) && b.getState() == Bundle.UNINSTALLED) {
+        uninstall = true;
+        res = null;
+      } else if (left > 0) { // we were waiting with a timeout
+        left = waitUntil - Util.timeMillis();
+        
+        // check time-out for Bundle.start and .stop
+        if (left <= 0 && ((op == OP_START && b.getState() == Bundle.STARTING)
+                       || (op == OP_STOP && b.getState() == Bundle.STOPPING))) {
+          timeout = true;
+          res = null;
+        }
+      }
+      
+    } while (res == Boolean.FALSE);
+
+    // if b.aborted is set, BundleThread has/will concluded start/stop
+    if (b.aborted == null && (timeout || uninstall)) {
+      // BundleThreda is still in BundleActivator.start/.stop, 
+
+      b.aborted = Boolean.TRUE; // signal to BundleThread that this
+                                // thread is acting on uninstall/time-out
+
+      String opType = op == OP_START ? "start" : "stop";
+      String reason = timeout ? "Time-out during bundle " + opType + "()"
+                              : "Bundle uninstalled during " + opType + "()";
+
+      String s = fwCtx.props.getProperty(FWProps.BUNDLETHREAD_ABORT);
+      if (s == null) {
+        s = ABORT_ACTION_IGNORE;
+      }
+      fwCtx.debug.println("bundle thread aborted during " + opType
+          + " of bundle #" + b.getBundleId() + ", abort action set to '"
+          + s + "'");
+
+      if (timeout) {
+        if (op == OP_START) {
+          // set state, send events, do clean-up like when Bundle.start()
+          // throws an exception
+          // TODO: startFailed() calls BundleListener.bundleChanged and
+          // should not be called with the packages lock as we do here
+          b.startFailed();
+          
+        } else {
+          // STOP, like when Bundle.stop() returns/throws an exception
+          b.bactivator = null;
+          b.stop2();
+        }
+      }
+      
+      quit();
+
+      // Check what abort action to use
+      if (ABORT_ACTION_STOP.equalsIgnoreCase(s)) {
+        if (null!=stopMethod) {
+          try {
+            stopMethod.invoke(this, (Object[]) null);
+          } catch (final Throwable t) {
+            fwCtx.debug.println("bundle thread abort action stop failed: "
+                                +t.getMessage());
+            setPriority(Thread.MIN_PRIORITY);
+          }
+        } else {
+          setPriority(Thread.MIN_PRIORITY);
+        }
+      } else if (ABORT_ACTION_MINPRIO.equalsIgnoreCase(s)) {
+        setPriority(Thread.MIN_PRIORITY);
+      }
+
+      res = new BundleException("Bundle#" + b.id + " " + opType + " failed",
+                                BundleException.STATECHANGE_ERROR,
+                                new Exception(reason));
+	    b.resetBundleThread();
+      return res;
+    } else {
+      synchronized (fwCtx.bundleThreads) {
+        fwCtx.bundleThreads.addFirst(this);
+        if (op != operation) {
+          // TODO! Handle when operation has changed.
+          // i.e. uninstall during operation?
+        }
+		    b.resetBundleThread();
+        return res;
+      }
+    }
+  }
+
+  boolean isExecutingBundleChanged() {
+    return operation == OP_BUNDLE_EVENT;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleURLConnection.java b/osgi/framework/src/org/knopflerfish/framework/BundleURLConnection.java
new file mode 100644
index 0000000..31fd902
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleURLConnection.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2003-2012, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.*;
+import java.net.*;
+import java.security.Permission;
+
+import org.osgi.framework.AdminPermission;
+
+
+/**
+ * Bundle URL handling.
+ *
+ * @author Jan Stein, Gunnar Ekolin
+ */
+class BundleURLConnection extends URLConnection {
+  // Should maybe only allow the bundle that fetched the URL to connect?
+  final static Permission ADMIN_PERMISSION
+    = new AdminPermission( (String)null, AdminPermission.RESOURCE);
+
+  private BundleResourceStream is = null;
+  /**
+   * Handle to the current framework instance used in the conversion
+   * from bundle id on string form in the URL to the actual bundle
+   * instance. */
+  private FrameworkContext fwCtx;
+  /** The bundle that provides the data for this URL. */
+  private BundleImpl bundle;
+  private int contentLength;
+  private String contentType;
+  private long lastModified;
+
+  BundleURLConnection(URL u, FrameworkContext fwCtx) {
+    super(u);
+    this.fwCtx = fwCtx;
+  }
+
+  /**
+   * Analyzes the URL to determine the bundle and which of its related
+   * bundle archives that actually provides the contents of this
+   * URL. The bundle is stored in the private member field
+   * <tt>bundle</tt> for later use, the bundle archive is returned.
+   *
+   * @return The bundle archive that provides the contents of this
+   *         bundle URL.
+   */
+  private BundleArchive getBundleArchive()
+  {
+    bundle = null;
+    long gen = 0;
+    try {
+      String s = url.getHost();
+      int i = s.indexOf('!');
+      if (i >= 0) {
+        s = s.substring(0,i);
+      }
+      i = s.indexOf('.');
+      if (i >= 0) {
+        gen = Long.parseLong(s.substring(i+1));
+        s = s.substring(0,i);
+      }
+      bundle = (BundleImpl) fwCtx.bundles.getBundle(Long.parseLong(s));
+    } catch (NumberFormatException _ignore) { }
+    if (bundle != null) {
+      return bundle.getBundleArchive(gen);
+    }
+    return null;
+  }
+
+  public void connect() throws IOException {
+    if (!connected) {
+      final BundleArchive a = getBundleArchive();
+      if (a != null) {
+        // Some storage kinds (e.g., expanded storage of sub-JARs)
+        // requieres the Framework's permisisons to allow access
+        // thus we must call bundleArchive.getInputStream()
+        // via doPrivileged().
+        int port = url.getPort();
+        is = bundle.secure.callGetBundleResourceStream(a, url.getFile(), port != -1 ? port : 0);
+      }
+      if (is != null) {
+        connected = true;
+        if(BundleClassLoader.bDalvik) {
+          contentLength = -1;
+        } else {
+          contentLength = (int)is.getContentLength();
+        }
+        contentType = URLConnection.guessContentTypeFromName(url.getFile());
+        lastModified = a.getLastModified();
+      } else {
+        throw new IOException("URL not found");
+      }
+    }
+  }
+
+  public InputStream getInputStream() throws IOException {
+    connect();
+    return is;
+  }
+
+  public String getContentType() {
+    try {
+      connect();
+      return contentType;
+    } catch (IOException e) {
+      return null;
+    }
+  }
+
+  public int getContentLength() {
+    try {
+      connect();
+      return contentLength;
+    } catch (IOException e) {
+      return -1;
+    }
+  }
+
+  public long getLastModified() {
+    try {
+      connect();
+      return lastModified;
+    } catch (IOException e) {
+      return 0;
+    }
+  }
+
+  public Permission getPermission() throws IOException {
+    return ADMIN_PERMISSION;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleURLStreamHandler.java b/osgi/framework/src/org/knopflerfish/framework/BundleURLStreamHandler.java
new file mode 100644
index 0000000..7adb917
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleURLStreamHandler.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * Bundle URL handling.
+ *
+ * @author Jan Stein, Gunnar Ekolin
+ */
+public class BundleURLStreamHandler extends URLStreamHandler {
+
+  final public static String PROTOCOL = "bundle";
+
+  final public static String PERM_OK = "P";
+
+  // Currently we only support a single framework instance in the same
+  // class-loader context!
+  private final ArrayList<FrameworkContext> framework
+    = new ArrayList<FrameworkContext>(2);
+
+
+  // TODO, we need a more efficient and cleaner solution here.
+
+
+  @Override
+  public URLConnection openConnection(URL u) throws IOException {
+    final String h = u.getHost();
+    final FrameworkContext fw = getFramework(h);
+    if (fw == null) {
+      throw new IOException("Framework associated with URL is not active");
+    }
+    if (u.getAuthority() != PERM_OK) {
+      fw.perm.checkResourceAdminPerm(fw.bundles.getBundle(getId(h)));
+      // NYI, set authority
+    }
+    return new BundleURLConnection(u, fw);
+  }
+
+
+  @Override
+  protected void parseURL(URL u, String s, int start, int limit)  {
+    String path = u.getPath();
+    String host = u.getHost();
+    long id = -1;
+    int cpElem = u.getPort();
+    if (limit > start) {
+      int len = limit - start;
+      char [] sc = new char[len];
+      s.getChars(start, limit, sc, 0);
+      int pos = 0;
+      if (len >= 2 && sc[0] == '/' && sc[1] == '/') {
+        for (pos = 2; pos < len; pos++) {
+          if (sc[pos] == ':' || sc[pos] == '/') {
+            break;
+          } else if (sc[pos] == '!' || sc[pos] == '.') {
+            if (id == -1) {
+              id = Long.parseLong(new String(sc, 2, pos - 2));
+            }
+          } else if (!Character.isDigit(sc[pos])) {
+            throw new IllegalArgumentException
+              ("Illegal chars in bundle id specification");
+          }
+        }
+        host = new String(sc, 2, pos - 2);
+        if (pos < len && sc[pos] == ':') {
+          ++pos;
+          cpElem = 0;
+          while (pos < len) {
+            if (sc[pos] == '/') {
+              break;
+            } else if (!Character.isDigit(sc[pos])) {
+              throw new IllegalArgumentException
+                ("Illegal chars in bundle port specification");
+            }
+            cpElem = 10 * cpElem + (sc[pos++] - '0');
+          }
+        } else {
+          cpElem = -1;
+        }
+      }
+      if (pos < len) {
+        int pstart;
+        if (sc[pos] != '/') {
+          if (path != null) {
+            final int dirend = path.lastIndexOf('/') + 1;
+            if (dirend > 0) {
+              final int plen = len - pos;
+              pstart = path.startsWith("/") ? 0 : 1;
+              len = dirend + plen + pstart;
+              if (len > sc.length) {
+                final char [] newsc = new char [len];
+                System.arraycopy(sc, pos, newsc, dirend + pstart, plen);
+                sc = newsc;
+              } else if (pos != dirend) {
+                System.arraycopy(sc, pos, sc, dirend + pstart, plen);
+              }
+              path.getChars(1 - pstart, dirend, sc, 1);
+            } else {
+              len = 1;
+            }
+          } else {
+            len = 1;
+          }
+          sc[0] = '/';
+          pstart = 0;
+          pos = 0;
+        } else {
+          pstart = pos;
+        }
+        int dots = 0;
+        int ipos = pstart - 1;
+        boolean slash = false;
+        for (; pos < len; pos++) {
+          if (sc[pos] == '/') {
+            if (slash) {
+              continue;
+            }
+            slash = true;
+            if (dots == 1) {
+              dots = 0;
+              continue;
+            } else if (dots == 2) {
+              if (ipos>pstart) { // There is a path-level to remove.
+                dots = 0;
+                while (ipos > pstart && sc[--ipos] != '/')
+                  ;
+                continue;
+              }
+            }
+          } else if (sc[pos] == '.') {
+            if (slash) {
+              dots = 1;
+              slash = false;
+              continue;
+            } else if (dots == 1) {
+              dots = 2;
+              continue;
+            }
+          } else {
+            slash = false;
+          }
+          while (dots-- > 0) {
+            sc[++ipos] = '.';
+          }
+          if (++ipos != pos) {
+            sc[ipos] = sc[pos];
+          }
+        }
+        if (dots == 2) {
+          if (ipos > pstart) { // There is a level to remove
+            while (ipos > pstart && sc[--ipos] != '/')
+              ;
+          } else { // On top level, keep the ".."
+            while (dots-- > 0) {
+              sc[++ipos] = '.';
+            }
+            // Add trailing '/' to ensure that a relative URL created
+            // with path ".." results in the same URL as one created
+            // using "../".
+            sc[++ipos] = '/';
+          }
+        }
+        path = new String(sc, pstart, ipos - pstart + 1);
+      }
+    }
+    if (id == -1) {
+      id = getId(host);
+    }
+    final FrameworkContext fw = getFramework(host);
+    if (fw == null) {
+      throw new IllegalArgumentException("Framework associated with URL is not active");
+    }
+    fw.perm.checkResourceAdminPerm(fw.bundles.getBundle(id));
+    setURL(u, PROTOCOL, host, cpElem, PERM_OK, null, path, null, null);
+  }
+
+
+  /**
+   * Equals calculation for bundle URLs.
+   * @return <tt>true</tt> if the two urls are
+   * considered equal, ie. they refer to the same
+   * fragment in the same file.
+   *
+   */
+  @Override
+  protected boolean equals(URL u1, URL u2) {
+    return sameFile(u1, u2);
+  }
+
+
+  /**
+   * Provides the hash calculation
+   * @return an <tt>int</tt> suitable for hash table indexing
+   */
+  @Override
+  protected int hashCode(URL u) {
+    int h = 0;
+
+    if (PROTOCOL.equals(u.getProtocol())) {
+      final String host = u.getHost();
+      if (host != null)
+        h = host.hashCode();
+
+      final String file = u.getFile();
+      if (file != null)
+        h += file.hashCode();
+
+      h += u.getPort();
+    } else {
+      h = u.hashCode();
+    }
+    return h;
+  }
+
+  /**
+   * Compare two urls to see whether they refer to the same file,
+   * i.e., having the same protocol, host, port, and path.
+   * @return true if u1 and u2 refer to the same file
+   */
+  @Override
+  protected boolean sameFile(URL u1, URL u2) {
+    final String p1 = u1.getProtocol();
+    if (PROTOCOL.equals(p1)) {
+      if (!p1.equals(u2.getProtocol()))
+        return false;
+
+      if (!hostsEqual(u1, u2))
+        return false;
+
+      if (!(u1.getFile() == u2.getFile() ||
+            (u1.getFile() != null && u1.getFile().equals(u2.getFile()))))
+        return false;
+
+      if (u1.getPort() != u2.getPort())
+        return false;
+
+      return true;
+    } else {
+      return u1.equals(u2);
+    }
+  }
+
+
+  /**
+   * Compares the host components of two URLs.
+   * @param u1 the URL of the first host to compare
+   * @param u2 the URL of the second host to compare
+   * @return    <tt>true</tt> if and only if they
+   * are equal, <tt>false</tt> otherwise.
+   */
+  @Override
+  protected boolean hostsEqual(URL u1, URL u2) {
+    final String s1 = u1.getHost();
+    final String s2 = u2.getHost();
+    return (s1 == s2) || (s1 != null && s1.equals(s2));
+  }
+
+
+  /**
+   * Converts a bundle URL to a String.
+   *
+   * @param   url   the URL.
+   * @return  a string representation of the URL.
+   */
+  @Override
+  protected String toExternalForm(URL url) {
+    final StringBuffer res = new StringBuffer(url.getProtocol());
+    res.append("://");
+    res.append(url.getHost());
+    final int port = url.getPort();
+    if (port >= 0) {
+      res.append(":").append(port);
+    }
+    res.append(url.getPath());
+    return res.toString();
+  }
+
+
+  @Override
+  protected synchronized InetAddress getHostAddress(URL url) {
+    return null;
+  }
+
+  //
+  // Package
+  //
+
+  /**
+   * Add framework that uses this URLStreamHandlerFactory.
+   *
+   * @param fw Framework context for framework to add.
+   */
+  void addFramework(FrameworkContext fw) {
+    framework.add(fw);
+  }
+
+
+  /**
+   * Remove framework that uses this URLStreamHandlerFactory.
+   *
+   * @param fw Framework context for framework to remove.
+   */
+  void removeFramework(FrameworkContext fw) {
+    framework.remove(fw);
+  }
+
+  //
+  // Private
+  //
+
+  private FrameworkContext getFramework(String host) {
+    final Iterator<FrameworkContext> i = framework.iterator();
+    final int e = host.indexOf("!");
+    int fwId;
+    if (e == -1) {
+      fwId = 0;
+    } else {
+      try {
+        fwId = Integer.parseInt(host.substring(e + 1));
+      } catch (final NumberFormatException _) {
+        return null;
+      }
+    }
+    while (i.hasNext()) {
+      final FrameworkContext fw = i.next();
+      if (fw.id == fwId) {
+        return fw;
+      }
+    }
+    return null;
+  }
+
+
+  public static long getId(String host) {
+    int e = host.indexOf(".");
+    if (e == -1) {
+      e = host.indexOf("!");
+    }
+    if (e >= 0) {
+      host = host.substring(0, e);
+    }
+    return Long.parseLong(host);
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleWireImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleWireImpl.java
new file mode 100644
index 0000000..d20fe12
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleWireImpl.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class BundleWireImpl implements BundleWire {
+  
+  private final BundleCapability capability;
+  private final BundleRequirement requirement;
+  private final BundleGeneration providerGen;
+  private final BundleGeneration requirerGen;
+
+  BundleWireImpl(BundleCapability capability, BundleGeneration provider,
+                 BundleRequirement requirement, BundleGeneration requirer) {
+    this.capability = capability;
+    this.providerGen = provider;
+    this.requirement = requirement;
+    this.requirerGen = requirer;
+  }
+
+
+  @Override
+  public BundleCapability getCapability() {
+    return capability;
+  }
+
+
+  @Override
+  public BundleRequirement getRequirement() {
+    return requirement;
+  }
+
+
+  @Override
+  public BundleWiring getProviderWiring() {
+    return providerGen.bundleRevision.getWiring();
+  }
+
+
+  @Override
+  public BundleWiring getRequirerWiring() {
+    return requirerGen.bundleRevision.getWiring();
+  }
+
+
+  @Override
+  public BundleRevision getProvider() {
+    // TODO What should we return if getWiring() is null
+    return providerGen.bundleRevision;
+  }
+
+
+  @Override
+  public BundleRevision getRequirer() {
+    // TODO What should we return if getWiring() is null
+    return requirerGen.bundleRevision;
+  }
+
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((capability == null) ? 0 : capability.hashCode());
+    result = prime * result + ((providerGen == null) ? 0 : providerGen.hashCode());
+    result = prime * result + ((requirement == null) ? 0 : requirement.hashCode());
+    result = prime * result + ((requirerGen == null) ? 0 : requirerGen.hashCode());
+    return result;
+  }
+
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (!(obj instanceof BundleWireImpl)) {
+      return false;
+    }
+    BundleWireImpl other = (BundleWireImpl) obj;
+    if (capability == null) {
+      if (other.capability != null) {
+        return false;
+      }
+    } else if (!capability.equals(other.capability)) {
+      return false;
+    }
+    if (providerGen == null) {
+      if (other.providerGen != null) {
+        return false;
+      }
+    } else if (!providerGen.equals(other.providerGen)) {
+      return false;
+    }
+    if (requirement == null) {
+      if (other.requirement != null) {
+        return false;
+      }
+    } else if (!requirement.equals(other.requirement)) {
+      return false;
+    }
+    if (requirerGen == null) {
+      if (other.requirerGen != null) {
+        return false;
+      }
+    } else if (!requirerGen.equals(other.requirerGen)) {
+      return false;
+    }
+    return true;
+  }
+
+ 
+  BundleGeneration getProviderGeneration() {
+    return providerGen;
+  }
+
+
+  BundleGeneration getRequirerGeneration() {
+    return requirerGen;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/BundleWiringImpl.java b/osgi/framework/src/org/knopflerfish/framework/BundleWiringImpl.java
new file mode 100644
index 0000000..934f208
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/BundleWiringImpl.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Wire;
+
+public class BundleWiringImpl implements BundleWiring {
+
+  final BundleRevisionImpl bundleRevision;
+
+  BundleWiringImpl(BundleRevisionImpl br) {
+    bundleRevision = br;
+  }
+
+
+  public Bundle getBundle() {
+    return bundleRevision.getBundle();
+  }
+
+
+  public boolean isCurrent() {
+    return this == bundleRevision.getWiring() &&
+           bundleRevision.bundle.current() == bundleRevision.gen;
+  }
+
+
+  public boolean isInUse() {
+    return this == bundleRevision.getWiring();
+  }
+
+
+  public List<BundleCapability> getCapabilities(String namespace) {
+    if (!isInUse()) {
+      return null;
+    }
+    BundleGeneration gen = bundleRevision.getBundleGeneration();
+    final int ns = BundleRevisionImpl.whichNameSpaces(namespace);
+    final ArrayList<BundleCapability> res = new ArrayList<BundleCapability>();
+    if ((ns & BundleRevisionImpl.NS_IDENTITY) != 0) {
+      final BundleCapability bc = gen.getIdentityCapability();
+      if (bc != null) {
+        res.add(bc);
+      }
+    }
+    if (!gen.isFragment()) {
+      if ((ns & BundleRevisionImpl.NS_BUNDLE) != 0) {
+        final BundleCapability bc = gen.getBundleCapability();
+        if (bc != null) {
+          res.add(bc);
+        }
+      }
+      if ((ns & BundleRevisionImpl.NS_HOST) != 0) {
+        final BundleCapability bc = gen.getHostCapability();
+        if (bc != null) {
+          res.add(bc);
+        }
+      }
+      if ((ns & BundleRevisionImpl.NS_PACKAGE) != 0) {
+        for (ExportPkg ep : gen.bpkgs.getPackageCapabilities()) {
+          if (ep.checkPermission()) {
+            res.add(ep);            
+          }
+        }
+      }
+      if ((ns & BundleRevisionImpl.NS_OTHER) != 0) {
+        final Map<String, List<BundleCapabilityImpl>> caps = gen.bpkgs.getOtherCapabilities();
+        Collection<List<BundleCapabilityImpl>> clbc = null;
+        if (null != namespace) {
+          final List<BundleCapabilityImpl> lbc = caps.get(namespace);
+          if (lbc != null) {
+            clbc  = Collections.singleton(lbc);
+          }
+        } else {
+          clbc = caps.values();
+        }
+        if (null != clbc) {
+          for (final List<BundleCapabilityImpl> lbc : clbc) {
+            for (final BundleCapabilityImpl bc : lbc) {
+              if (bc.isEffectiveResolve() && bc.checkPermission()) {
+                res.add(bc);
+              }
+            }
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+
+  public List<BundleRequirement> getRequirements(String namespace) {
+    if (!isInUse()) {
+      return null;
+    }
+    BundleGeneration gen = bundleRevision.getBundleGeneration();
+    final int ns = BundleRevisionImpl.whichNameSpaces(namespace);
+    final ArrayList<BundleRequirement> res = new ArrayList<BundleRequirement>();
+    if (gen.isFragment()) {
+      if ((ns & BundleRevisionImpl.NS_HOST) != 0) {
+        res.add(gen.fragment);
+      }
+    } else {
+      if ((ns & BundleRevisionImpl.NS_BUNDLE) != 0) {
+        for (final Iterator<RequireBundle> irb = gen.bpkgs.getRequire(); irb.hasNext(); ) {
+          final RequireBundle rb = irb.next();
+          if (null != rb.bpkgs && rb.bpkgs.isRequiredBy(gen.bpkgs)) {
+            res.add(rb);
+          }
+        }
+      }
+      if ((ns & BundleRevisionImpl.NS_PACKAGE) != 0) {
+        res.addAll(gen.bpkgs.getPackageRequirements());
+      }
+      if ((ns & (BundleRevisionImpl.NS_IDENTITY|BundleRevisionImpl.NS_OTHER)) != 0) {
+        final Map<String, List<BundleRequirementImpl>> reqs = gen.getOtherRequirements();
+        Collection<List<BundleRequirementImpl>> clbr = null;
+        if (null != namespace) {
+          final List<BundleRequirementImpl> lbr = reqs.get(namespace);
+          if (lbr != null) {
+            clbr = Collections.singleton(lbr);
+          }
+        } else {
+          clbr = reqs.values();
+        }
+        if (null != clbr) {
+          for (final List<BundleRequirementImpl> lbr : clbr) {
+            for (final BundleRequirementImpl br : lbr) {
+              if (br.isWired()) {
+                res.add(br);
+              }
+            }
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+  public List<BundleWire> getProvidedWires(String namespace) {
+    if (!isInUse()) {
+      return null;
+    }
+    BundleGeneration gen = bundleRevision.getBundleGeneration();
+    final int ns = BundleRevisionImpl.whichNameSpaces(namespace);
+    final ArrayList<BundleWire> res = new ArrayList<BundleWire>();
+    if ((ns & BundleRevisionImpl.NS_BUNDLE) != 0) {
+      final List<BundlePackages> reqBys = gen.bpkgs.getRequiredBy();
+      for (final BundlePackages bp : reqBys) {
+        for (final Iterator<RequireBundle> irb = bp.getRequire(); irb.hasNext(); ) {
+          final RequireBundle rb = irb.next();
+          if (rb.bpkgs == gen.bpkgs) {
+            res.add(new BundleWireImpl(gen.getBundleCapability(), gen, rb, bp.bg));
+          }
+        }
+      }
+    }
+    if ((ns & BundleRevisionImpl.NS_HOST) != 0) {
+      if (gen.isFragmentHost()) {
+        @SuppressWarnings("unchecked")
+        final Vector<BundleGeneration> fix = (Vector<BundleGeneration>)gen.fragments.clone();
+        for (final BundleGeneration fbg : fix) {
+          res.add(new BundleWireImpl(gen.getHostCapability(), gen, fbg.fragment, fbg));
+        }
+      }
+    }
+    if ((ns & BundleRevisionImpl.NS_PACKAGE) != 0) {
+      for (final BundleCapability bc : gen.bpkgs.getPackageCapabilities()) {
+        final ExportPkg ep = (ExportPkg)bc;
+        final List<ImportPkg> ips = ep.getPackageImporters();
+        if (ips != null) {
+          for (final ImportPkg ip : ips) {
+            // Fetch the original for dynamic and fragment imports
+            ImportPkg oip;
+            if (ip.parent != null && ip.parent.bpkgs != ip.bpkgs) {
+              oip = ip.parent;
+            } else {
+              oip = ip;
+            }
+            res.add(new BundleWireImpl(ep, gen, oip, ip.bpkgs.bg));
+          }
+        }
+      }
+    }
+    if ((ns & (BundleRevisionImpl.NS_IDENTITY|BundleRevisionImpl.NS_OTHER)) != 0) {
+      List<BundleWireImpl> other = gen.getCapabilityWires();
+      if (other != null) {
+        for (BundleWireImpl bw : other) {
+          if (namespace == null || namespace.equals(bw.getCapability().getNamespace())) {
+            res.add(bw);
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+  public List<BundleWire> getRequiredWires(String namespace) {
+    if (!isInUse()) {
+      return null;
+    }
+    BundleGeneration gen = bundleRevision.getBundleGeneration();
+    final int ns = BundleRevisionImpl.whichNameSpaces(namespace);
+    final ArrayList<BundleWire> res = new ArrayList<BundleWire>();
+    if ((ns & BundleRevisionImpl.NS_BUNDLE) != 0) {
+      for (final Iterator<RequireBundle> irb = gen.bpkgs.getRequire(); irb.hasNext(); ) {
+        final RequireBundle rb = irb.next();
+        if (null != rb.bpkgs && rb.bpkgs.isRequiredBy(gen.bpkgs)) {
+          res.add(new BundleWireImpl(rb.bpkgs.bg.getBundleCapability(), rb.bpkgs.bg, rb, gen));
+        }
+      }
+    }
+    if ((ns & BundleRevisionImpl.NS_HOST) != 0) {
+      if (gen.isFragment()) {
+        for (final BundleGeneration hbg : gen.getHosts()) {
+          res.add(new BundleWireImpl(hbg.getHostCapability(), hbg, gen.fragment, gen));
+        }
+      }
+    }
+    if ((ns & BundleRevisionImpl.NS_PACKAGE) != 0) {
+      TreeSet<ImportPkg> dynamic = new TreeSet<ImportPkg>(
+          new Comparator<ImportPkg>() {
+            @Override
+            public int compare(ImportPkg o1, ImportPkg o2) {
+              return o1.dynId - o2.dynId;
+            }
+          });
+     for (final ImportPkg ip : gen.bpkgs.getPackageRequirements()) {
+        ExportPkg ep = ip.provider;
+        if (ep != null) {
+          res.add(new BundleWireImpl(ep, ep.bpkgs.bg, ip, gen));
+        } else {
+          // Must be dynamic import or fragment
+          for (ImportPkg cip : gen.bpkgs.getActiveChildImports(ip)) {
+            // Add dynamic imports in bind order
+            if (ip.isDynamic()) {
+              dynamic.add(cip);
+            } else {
+              res.add(new BundleWireImpl(cip.provider, cip.provider.bpkgs.bg, ip, gen));
+            }
+          }
+        }
+      }
+      for (ImportPkg cip : dynamic) {
+        res.add(new BundleWireImpl(cip.provider, cip.provider.bpkgs.bg, cip.parent, gen));
+      }
+    }
+    if ((ns & (BundleRevisionImpl.NS_IDENTITY|BundleRevisionImpl.NS_OTHER)) != 0) {
+      List<BundleWireImpl> other = gen.getRequirementWires();
+      if (other != null) {
+        for (BundleWireImpl bw : other) {
+          if (namespace == null || namespace.equals(bw.getRequirement().getNamespace())) {
+            res.add(bw);
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+  public BundleRevision getRevision() {
+    return bundleRevision;
+  }
+
+  public ClassLoader getClassLoader() {
+    if (isInUse()) {
+      return bundleRevision.getBundleGeneration().getClassLoader();
+    }
+    return null;
+  }
+
+  public List<URL> findEntries(String path, String filePattern, int options) {
+    BundleGeneration gen = bundleRevision.getBundleGeneration();
+    if (isInUse()) {
+      return Collections.unmodifiableList(gen.bundle.secure.callFindEntries(gen, path, filePattern, (options & FINDENTRIES_RECURSE) != 0));
+    }
+    return null;
+  }
+
+  public Collection<String> listResources(String path, String filePattern, int options) {
+    BundleGeneration gen = bundleRevision.getBundleGeneration();
+    if (!isInUse()) {
+      return null;
+    }
+    @SuppressWarnings("unchecked")
+    Collection<String> res = Collections.EMPTY_SET;
+    ClassLoader cl = gen.getClassLoader();
+    if (cl != null && cl instanceof BundleClassLoader) {
+      BundleClassLoader bcl = (BundleClassLoader) gen.getClassLoader();
+      res = bcl.listResources(path, filePattern, options);
+    }
+    return res;
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Capability> getResourceCapabilities(String namespace) {
+    return (List<Capability>)(List<?>)getCapabilities(namespace);
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Requirement> getResourceRequirements(String namespace) {
+    return (List<Requirement>)(List<?>)getRequirements(namespace);
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Wire> getProvidedResourceWires(String namespace) {
+    return (List<Wire>)(List<?>)getProvidedWires(namespace);
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public List<Wire> getRequiredResourceWires(String namespace) {
+    return (List<Wire>)(List<?>)getRequiredWires(namespace);
+  }
+
+
+  @Override
+  public BundleRevision getResource() {
+    return bundleRevision;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Bundles.java b/osgi/framework/src/org/knopflerfish/framework/Bundles.java
new file mode 100644
index 0000000..0591358
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Bundles.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+/**
+ * Here we handle all the bundles that are installed in the framework.
+ * Also handles load and save of bundle states to file, so that we
+ * can restart the platform.
+ *
+ * @author Jan Stein, Mats-Ola Persson, Gunnar Ekolin
+ */
+public class Bundles {
+
+  /**
+   * Table of all installed bundles in this framework.
+   * Key is bundle location.
+   */
+  final private Hashtable<String, BundleImpl> bundles = new Hashtable<String, BundleImpl>();
+
+  final private HashSet<BundleImpl> zombies = new HashSet<BundleImpl>();
+
+  /**
+   * Link to framework object.
+   */
+  private FrameworkContext fwCtx;
+
+
+  /**
+   * Create a container for all bundles in this framework.
+   */
+  Bundles(FrameworkContext fw) {
+    fwCtx = fw;
+    bundles.put(fw.systemBundle.location, fw.systemBundle);
+  }
+
+
+  void clear()
+  {
+    bundles.clear();
+    fwCtx = null;
+  }
+
+
+  /**
+   * Install a new bundle.
+   *
+   * @param location The location to be installed
+   */
+  BundleImpl install(final String location, final InputStream in, final Bundle caller)
+    throws BundleException
+  {
+    checkIllegalState();
+    BundleImpl b;
+    synchronized (this) {
+      b = bundles.get(location);
+      if (b != null) {
+        b = (BundleImpl)b.fwCtx.bundleHooks.filterBundle(b.bundleContext, b);
+        if(b == null) {
+          throw new BundleException("Rejected by a bundle hook",
+                                    BundleException.REJECTED_BY_HOOK);
+        } else {
+          return b;
+        }
+      }
+      b = fwCtx.perm.callInstall0(this, location, in, caller);
+    }
+    return b;
+  }
+
+
+  BundleImpl install0(String location, InputStream in, Object checkContext, Bundle caller)
+    throws BundleException {
+    InputStream bin;
+    BundleArchive ba = null;
+    try {
+      if (in == null) {
+        // Do it the manual way to have a chance to
+        // set request properties
+        final URL url  = new URL(location);
+        final URLConnection conn = url.openConnection();
+
+        // Support for http proxy authentication
+        //TODO put in update as well
+        final String auth = fwCtx.props.getProperty("http.proxyAuth");
+        if (auth != null && !"".equals(auth)) {
+          if ("http".equals(url.getProtocol()) ||
+              "https".equals(url.getProtocol())) {
+            final String base64 = Util.base64Encode(auth);
+            conn.setRequestProperty("Proxy-Authorization",
+                                    "Basic " + base64);
+          }
+        }
+        // Support for http basic authentication
+        final String basicAuth = fwCtx.props.getProperty("http.basicAuth");
+        if (basicAuth != null && !"".equals(basicAuth)) {
+          if ("http".equals(url.getProtocol()) ||
+              "https".equals(url.getProtocol())) {
+            final String base64 = Util.base64Encode(basicAuth);
+            conn.setRequestProperty("Authorization",
+                                    "Basic " +base64);
+          }
+        }
+        bin = conn.getInputStream();
+      } else {
+        bin = in;
+      }
+      try {
+        ba = fwCtx.storage.insertBundleJar(location, bin);
+      } finally {
+        bin.close();
+      }
+      final BundleImpl res = new BundleImpl(fwCtx, ba, checkContext, caller);
+      bundles.put(location, res);
+      fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.INSTALLED, res, caller));
+      return res;
+    } catch (final Exception e) {
+      if (ba != null) {
+        ba.purge();
+      }
+      if (e instanceof SecurityException) {
+        throw (SecurityException)e;
+      } else if (e instanceof BundleException) {
+        throw (BundleException)e;
+      } else {
+        throw new BundleException("Failed to install bundle: " + e,
+                                  BundleException.UNSPECIFIED, e);
+      }
+    }
+  }
+
+
+  /**
+   * Remove bundle registration.
+   *
+   * @param location The location to be removed
+   */
+  void remove(String location) {
+    bundles.remove(location);
+  }
+
+  void addZombie(BundleImpl b) {
+    synchronized (bundles) {
+      zombies.add(b);
+    }
+  }
+
+  void removeZombie(BundleImpl b) {
+    synchronized (bundles) {
+      zombies.remove(b);
+    }
+  }
+
+  /**
+   * Get bundle that has specified bundle identifier.
+   *
+   * @param id The identifier of bundle to get.
+   * @return BundleImpl representing bundle or null
+   *         if bundle was not found.
+   */
+  Bundle getBundle(long id) {
+    checkIllegalState();
+    synchronized (bundles) {
+      for (final Enumeration<BundleImpl> e = bundles.elements(); e.hasMoreElements();) {
+        final BundleImpl b = e.nextElement();
+        if (b.id == id) {
+          return b;
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Get bundle that has specified bundle location.
+   *
+   * @param location The location of bundle to get.
+   * @return BundleImpl representing bundle or null
+   *         if bundle was not found.
+   */
+  Bundle getBundle(String location) {
+    checkIllegalState();
+    return bundles.get(location);
+  }
+
+
+  /**
+   * Get all bundles that has specified bundle symbolic name and version.
+   *
+   * @param name The symbolic name of bundle to get.
+   * @param version The bundle version of bundle to get.
+   * @return Collection of BundleImpls.
+   */
+  Collection<Bundle> getBundles(String name, Version version) {
+    checkIllegalState();
+    final ArrayList<Bundle> res = new ArrayList<Bundle>(bundles.size());    
+    if (Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(name)
+        && version.equals(fwCtx.systemBundle.getVersion())) {
+      res.add(fwCtx.systemBundle);
+    }
+    synchronized (bundles) {
+      for (final Enumeration<BundleImpl> e = bundles.elements(); e.hasMoreElements();) {
+        final BundleImpl b = e.nextElement();
+        if (name.equals(b.getSymbolicName()) && version.equals(b.getVersion())) {
+          res.add(b);
+        }
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get all installed bundles.
+   *
+   * @return A Bundle array with bundles.
+   */
+  List<BundleImpl> getBundles() {
+    final ArrayList<BundleImpl> res = new ArrayList<BundleImpl>(bundles.size());
+    synchronized (bundles) {
+      res.addAll(bundles.values());
+    }
+    return res;
+  }
+
+
+  /**
+   * Get all bundles that has specified bundle symbolic name.
+   *
+   * @param name The symbolic name of bundles to get, if null get all.
+   * @return A List of current BundleGenerations.
+   */
+  List<BundleGeneration> getBundleGenerations(String name) {
+    final ArrayList<BundleGeneration> res = new ArrayList<BundleGeneration>();
+    if (Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(name)) {
+      res.add(fwCtx.systemBundle.current());
+    }
+    synchronized (bundles) {
+      for (final BundleImpl b : bundles.values()) {
+        if (name == null || name.equals(b.getSymbolicName())) {
+          res.add(b.current());
+        }
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get all bundles that has specified bundle symbolic name and
+   * version range. Result is sorted in decreasing version order.
+   *
+   * @param name The symbolic name of bundles to get.
+   * @param range Version range of bundles to get.
+   * @return A List of current BundleGenerations.
+   */
+  List<BundleGeneration> getBundles(String name, VersionRange range) {
+    checkIllegalState();
+    final List<BundleGeneration> res = getBundleGenerations(name);
+    for (int i = 0; i < res.size(); ) {
+      final BundleGeneration bg = res.remove(i);
+      if (range == null || range.includes(bg.version)) {
+        int j = i;
+        while (--j >= 0) {
+          if (bg.version.compareTo(res.get(j).version) <= 0) {
+            break;
+          }
+        }
+        res.add(j + 1, bg);
+        i++;
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get all bundles currently in bundle state ACTIVE.
+   *
+   * @return A List of BundleImpl.
+   */
+  List<BundleImpl> getActiveBundles() {
+    checkIllegalState();
+    final ArrayList<BundleImpl> slist = new ArrayList<BundleImpl>();
+    synchronized (bundles) {
+      for (final Enumeration<BundleImpl> e = bundles.elements(); e.hasMoreElements();) {
+        final BundleImpl b = e.nextElement();
+        final int s = b.getState();
+        if (s == Bundle.ACTIVE || s == Bundle.STARTING) {
+          slist.add(b);
+        }
+      }
+    }
+    return slist;
+  }
+
+
+  /**
+   * Get removal pending bundles.
+   *
+   * @return A Bundle array with bundles.
+   */
+  void getRemovalPendingBundles(Collection<Bundle> res) {
+    synchronized (bundles) {
+      for (BundleImpl b : bundles.values()) {
+        if (b.hasZombies()) {
+          res.add(b);
+        }
+      }
+      res.addAll(zombies);
+    }
+  }
+
+
+  /**
+   * Get unattached fragments that has a resolved host.
+   *
+   * @return A Bundle array with bundles.
+   */
+  void getUnattachedBundles(Collection<Bundle> res) {
+    synchronized (bundles) {
+      for (BundleImpl b : bundles.values()) {
+        if (b.getState() == Bundle.INSTALLED) {
+          final BundleGeneration curr = b.current();
+          if (curr.isFragment() && curr.getResolvedHosts().size() > 0) {
+            res.add(b);
+          }
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Check if any extension bundle needs a framework restart.
+   *
+   * @return A Bundle array with bundles.
+   */
+  boolean checkExtensionBundleRestart() {
+    synchronized (bundles) {
+      for (BundleImpl b : zombies) {
+        if (b.extensionNeedsRestart()) {
+          return true;
+        }
+      }
+      for (BundleImpl b : bundles.values()) {
+        if (b.extensionNeedsRestart()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * Try to load any saved framework state.
+   * This is done by installing all saved bundles from the local archive
+   * copy, and restoring the saved state for each bundle. This is only
+   * intended to be executed during the start of the framework.
+   *
+   */
+  synchronized void load() {
+    final BundleArchive [] bas = fwCtx.storage.getAllBundleArchives();
+    for (final BundleArchive ba : bas) {
+      try {
+        final BundleImpl b = new BundleImpl(fwCtx, ba, null, fwCtx.systemBundle);
+        bundles.put(b.location, b);
+      } catch (final Exception e) {
+        try {
+          ba.setAutostartSetting(-1); // Do not start on launch
+          ba.setStartLevel(-2); // Mark as uninstalled
+        } catch (final IOException _ioe) {
+        }
+        System.err.println("Error: Failed to load bundle "
+                           +ba.getBundleId()
+                           +" (" +ba.getBundleLocation() +")"
+                           +" uninstalled it!" );
+        e.printStackTrace();
+      }
+    }
+  }
+
+
+  /**
+   * Returns all fragment bundles that is
+   * already attached and targets given bundle.
+   *
+   * @param target the targeted bundle
+   * @return a list of all matching fragment bundle generations.
+   */
+  Collection<BundleGeneration> getFragmentBundles(BundleGeneration target) {
+    final HashMap<String, BundleGeneration> res = new HashMap<String, BundleGeneration>();
+    for (final Enumeration<BundleImpl> e = bundles.elements(); e.hasMoreElements();) {
+      final BundleImpl b = e.nextElement();
+      final BundleGeneration bg = b.current();
+      if (bg.isFragment() &&
+          b.state != Bundle.UNINSTALLED &&
+          bg.fragment.isTarget(target)) {
+        final String sym = bg.symbolicName;
+        final BundleGeneration old = res.get(sym);
+        if (old != null && old.symbolicName.equals(sym)) {
+          if (old.version.compareTo(bg.version) > 0) {
+            continue;
+          }
+        }
+        res.put(sym, bg);
+      }
+    }
+    return res.values();
+  }
+
+
+  /**
+   * Check if this bundles object have been closed!
+   */
+  private void checkIllegalState() {
+    if (null == fwCtx) {
+      throw new IllegalStateException("This framework instance is not active.");
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Capabilities.java b/osgi/framework/src/org/knopflerfish/framework/Capabilities.java
new file mode 100644
index 0000000..4d89557
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Capabilities.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class Capabilities {
+
+  /**
+   * List of registered capabilities indexed by name space.
+   * The list is order in manifest order.
+   */
+  private HashMap<String, ArrayList<BundleCapabilityImpl>> namespaceCapabilties =
+      new HashMap<String, ArrayList<BundleCapabilityImpl>>();
+
+
+  List<BundleCapabilityImpl> getCapabilities(String namespace) {
+    return namespaceCapabilties.get(namespace);
+  }
+
+  void addCapabilities(Map<String, List<BundleCapabilityImpl>> capabilities) {
+    for (Entry<String, List<BundleCapabilityImpl>> e : capabilities.entrySet()) {
+      final String ns = e.getKey();
+      ArrayList<BundleCapabilityImpl> bcl = namespaceCapabilties.get(ns);
+      if (bcl == null) {
+        bcl = new ArrayList<BundleCapabilityImpl>();
+        namespaceCapabilties.put(ns, bcl);  
+      }
+      bcl.addAll(e.getValue());
+    }
+  }
+
+  void removeCapabilities(Map<String, List<BundleCapabilityImpl>> capabilities) {
+    for (Entry<String, List<BundleCapabilityImpl>> e : capabilities.entrySet()) {
+      final String ns = e.getKey();
+      ArrayList<BundleCapabilityImpl> bcl = namespaceCapabilties.get(ns);
+      if (bcl != null) {
+        int before = bcl.size();
+        bcl.removeAll(e.getValue());
+        if (bcl.isEmpty()) {
+          namespaceCapabilties.remove(ns);
+        }
+        if (before != bcl.size() + e.getValue().size()) {
+          throw new RuntimeException("Internal error, tried to remove unknown capabilities");          
+        }
+      } else {
+        throw new RuntimeException("Internal error, tried to remove unknown name space with capabilities");
+      }
+    }
+  }
+
+  Collection<ArrayList<BundleCapabilityImpl>> getAll() {
+    return namespaceCapabilties.values();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ContentHandlerWrapper.java b/osgi/framework/src/org/knopflerfish/framework/ContentHandlerWrapper.java
new file mode 100644
index 0000000..210b2bc
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ContentHandlerWrapper.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.net.ContentHandler;
+import java.net.URLConnection;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.url.URLConstants;
+
+
+/**
+ * Wrapper which delegates an MIME ContentHandlers
+ * OSGi registered ContentHandlers
+ *
+ * <p>
+ * Each instance of ContentHandlerWrapper  tracks ContentHandlers
+ * for a named MIME type and selects the best from all available services.
+ * </p>
+ */
+public class ContentHandlerWrapper
+  extends ContentHandler
+{
+
+  FrameworkContext       framework;
+  String                 mimetype;
+  String                 filter;
+  ServiceReference<ContentHandler> best;
+
+  ContentHandlerWrapper(FrameworkContext       framework,
+			String                 mimetype) {
+
+    this.framework = framework;
+    this.mimetype  = mimetype;
+
+    filter =
+      "(&" +
+      "(" + Constants.OBJECTCLASS + "=" +
+      ContentHandler.class.getName() + ")" +
+      "(" + URLConstants.URL_CONTENT_MIMETYPE + "=" + mimetype +
+      ")" +
+      ")";
+
+    final ServiceListener serviceListener =
+      new ServiceListener() {
+        public void serviceChanged(ServiceEvent evt) {
+          @SuppressWarnings("unchecked")
+          final
+          ServiceReference<ContentHandler> ref =
+              (ServiceReference<ContentHandler>) evt.getServiceReference();
+
+          switch (evt.getType()) {
+          case ServiceEvent.MODIFIED:
+            // fall through
+          case ServiceEvent.REGISTERED:
+            if (best == null) {
+              updateBest();
+              return ;
+            }
+
+            if (compare(best, ref) > 0) {
+              best = ref;
+            }
+            break;
+          case ServiceEvent.MODIFIED_ENDMATCH:
+            // fall through
+          case ServiceEvent.UNREGISTERING:
+            if (best.equals(ref)) {
+              best = null;
+            }
+          }
+        }
+      };
+
+    try {
+      framework.systemBundle.bundleContext.addServiceListener(serviceListener, filter);
+
+    } catch (final Exception e) {
+      throw new IllegalArgumentException("Could not register service listener for content handler: " + e);
+    }
+
+    if (framework.debug.url) {
+      framework.debug.println("created wrapper for " + mimetype + ", filter=" + filter);
+    }
+  }
+
+  private int compare(ServiceReference<?> ref1, ServiceReference<?> ref2) {
+    final Object tmp1 = ref1.getProperty(Constants.SERVICE_RANKING);
+    final Object tmp2 = ref2.getProperty(Constants.SERVICE_RANKING);
+
+    final int r1 = (tmp1 instanceof Integer) ? ((Integer)tmp1).intValue() : 0;
+    final int r2 = (tmp2 instanceof Integer) ? ((Integer)tmp2).intValue() : 0;
+
+    if (r2 == r1) {
+      final Long i1 = (Long)ref1.getProperty(Constants.SERVICE_ID);
+      final Long i2 = (Long)ref2.getProperty(Constants.SERVICE_ID);
+      return i1.compareTo(i2);
+
+    } else {
+      return r2 -r1;
+    }
+  }
+
+  private void updateBest() {
+    try {
+      @SuppressWarnings("unchecked")
+      final
+      ServiceReference<ContentHandler>[] refs
+        = (ServiceReference<ContentHandler>[]) framework.systemBundle.bundleContext
+          .getServiceReferences(ContentHandler.class.getName(), filter);
+      if (refs != null) {
+        best = refs[0];
+        for (int i = 1; i < refs.length; i++) {
+          if (compare(best, refs[i]) > 0) {
+            best = refs[i];
+          }
+        }
+      }
+    } catch (final Exception e) {
+      // TODO, handle differently!? this should not happen.
+      throw new IllegalArgumentException("Could not register url handler: " + e);
+    }
+  }
+
+
+  private ContentHandler getService() {
+    ContentHandler obj;
+
+    try {
+      if (best == null) {
+        updateBest();
+      }
+
+      if (best == null) {
+        throw new IllegalStateException("null: Lost service for protocol="+ mimetype);
+      }
+
+      obj = framework.systemBundle.bundleContext.getService(best);
+
+      if (obj == null) {
+        throw new IllegalStateException("null: Lost service for protocol=" + mimetype);
+      }
+
+    } catch (final Exception e) {
+      throw new IllegalStateException("null: Lost service for protocol=" + mimetype);
+    }
+
+    return obj;
+  }
+
+  @Override
+  public Object getContent(URLConnection urlc) throws IOException {
+    return getService().getContent(urlc);
+  }
+
+  @Override
+  public Object getContent(URLConnection urlc,
+                           @SuppressWarnings("rawtypes") Class[] classes)
+      throws IOException
+  {
+    return getService().getContent(urlc, classes);
+  }
+
+  @Override
+  public String toString() {
+    final StringBuffer sb = new StringBuffer();
+
+    sb.append("ContentHandlerWrapper[");
+
+    final ServiceReference<ContentHandler> ref = best;
+    sb.append("mimetype=" + mimetype);
+    if(ref != null) {
+      sb.append(", id=" + ref.getProperty(Constants.SERVICE_ID));
+      sb.append(", rank=" + ref.getProperty(Constants.SERVICE_RANKING));
+    } else {
+      sb.append(" no service tracked");
+    }
+
+    sb.append("]");
+
+    return sb.toString();
+  }
+}
+
+
diff --git a/osgi/framework/src/org/knopflerfish/framework/Debug.java b/osgi/framework/src/org/knopflerfish/framework/Debug.java
new file mode 100644
index 0000000..629dc31
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Debug.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.framework.BundleException;
+
+/**
+ * Variables that controls debugging of the framework code.
+ *
+ * @author Jan Stein
+ */
+public class Debug {
+
+  /**
+   * Thread local storage to prevent recursive debug message
+   * in permission checks
+   */
+  private ThreadLocal<Boolean> insideDebug;
+
+
+  /**
+   * Report Automanifest handling
+   */
+  public static String AUTOMANIFEST_PROP = "org.knopflerfish.framework.debug.automanifest";
+  boolean automanifest;
+
+  /**
+   * When security is enabled, print information about resource
+   * lookups that are rejected due to missing permissions for the
+   * calling bundle.
+   */
+  public static String BUNDLE_RESOURCE_PROP = "org.knopflerfish.framework.debug.bundle_resource";
+  boolean bundle_resource;
+
+  /**
+   * Report certificate matching
+   */
+  public static String CERTIFICATES_PROP = "org.knopflerfish.framework.debug.certificates";
+  public boolean certificates;
+
+  /**
+   * Report whenever the bundle classloader does something.
+   */
+  public static String CLASSLOADER_PROP = "org.knopflerfish.framework.debug.classloader";
+  boolean classLoader;
+
+  /**
+   * Report error handling events.
+   */
+  public static String ERRORS_PROP = "org.knopflerfish.framework.debug.errors";
+  boolean errors;
+
+  /**
+   * Report framework create, init, start, stop
+   */
+  public static String FRAMEWORK_PROP = "org.knopflerfish.framework.debug.framework";
+  boolean framework;
+
+  /**
+   * Report hooks handling
+   */
+  public static String HOOKS_PROP = "org.knopflerfish.framework.debug.hooks";
+  boolean hooks;
+
+  /**
+   * Report triggering of lazy activation
+   */
+  public static String LAZY_ACTIVATION_PROP = "org.knopflerfish.framework.debug.lazy_activation";
+  boolean lazy_activation;
+
+  /**
+   * Report LDAP handling
+   */
+  public static String LDAP_PROP = "org.knopflerfish.framework.debug.ldap";
+  boolean ldap;
+
+  /**
+   * Report resolver handling events.
+   */
+  public static String RESOLVER_PROP = "org.knopflerfish.framework.debug.resolver";
+  boolean resolver;
+
+  /**
+   * Report Class patching handling
+   */
+  public static String PATCH_PROP = "org.knopflerfish.framework.debug.patch";
+  public boolean patch;
+
+  /**
+   * Report permission handling
+   */
+  public static String PERMISSIONS_PROP = "org.knopflerfish.framework.debug.permissions";
+  public boolean permissions;
+
+  /**
+   * When security is enabled, print information about service
+   * reference lookups that are rejected due to missing permissions
+   * for calling bundle.
+   */
+  public static String SERVICE_REFERENCE_PROP = "org.knopflerfish.framework.debug.service_reference";
+  boolean service_reference;
+
+  /**
+   * Report startlevel.
+   */
+  public static String STARTLEVEL_PROP = "org.knopflerfish.framework.debug.startlevel";
+  boolean startlevel;
+
+  /**
+   * Report url
+   */
+  public static String URL_PROP = "org.knopflerfish.framework.debug.url";
+  boolean url;
+
+  /**
+   * Report warning handling events.
+   */
+  public static String WARNINGS_PROP = "org.knopflerfish.framework.debug.warnings";
+  boolean warnings;
+
+
+
+  public Debug(FWProps props) {
+    props.setPropertyDefault(AUTOMANIFEST_PROP, FWProps.FALSE);
+    props.setPropertyDefault(BUNDLE_RESOURCE_PROP, FWProps.FALSE);
+    props.setPropertyDefault(CERTIFICATES_PROP, FWProps.FALSE);
+    props.setPropertyDefault(CLASSLOADER_PROP, FWProps.FALSE);
+    props.setPropertyDefault(ERRORS_PROP, FWProps.FALSE);
+    props.setPropertyDefault(FRAMEWORK_PROP, FWProps.FALSE);
+    props.setPropertyDefault(HOOKS_PROP, FWProps.FALSE);
+    props.setPropertyDefault(LAZY_ACTIVATION_PROP, FWProps.FALSE);
+    props.setPropertyDefault(RESOLVER_PROP, FWProps.FALSE);
+    props.setPropertyDefault(PATCH_PROP, FWProps.FALSE);
+    props.setPropertyDefault(PERMISSIONS_PROP, FWProps.FALSE);
+    props.setPropertyDefault(SERVICE_REFERENCE_PROP, FWProps.FALSE);
+    props.setPropertyDefault(STARTLEVEL_PROP, FWProps.FALSE);
+    props.setPropertyDefault(URL_PROP, FWProps.FALSE);
+    automanifest = props.getBooleanProperty(AUTOMANIFEST_PROP);
+    bundle_resource = props.getBooleanProperty(BUNDLE_RESOURCE_PROP);
+    certificates = props.getBooleanProperty(CERTIFICATES_PROP);
+    classLoader = props.getBooleanProperty(CLASSLOADER_PROP);
+    errors = props.getBooleanProperty(ERRORS_PROP);
+    framework = props.getBooleanProperty(FRAMEWORK_PROP);
+    hooks = props.getBooleanProperty(HOOKS_PROP);
+    lazy_activation = props.getBooleanProperty(LAZY_ACTIVATION_PROP);
+    resolver = props.getBooleanProperty(RESOLVER_PROP);
+    patch = props.getBooleanProperty(PATCH_PROP);
+    permissions = props.getBooleanProperty(PERMISSIONS_PROP);
+    service_reference = props.getBooleanProperty(SERVICE_REFERENCE_PROP);
+    startlevel = props.getBooleanProperty(STARTLEVEL_PROP);
+    url = props.getBooleanProperty(URL_PROP);
+    warnings = props.getBooleanProperty(WARNINGS_PROP);
+  }
+
+
+  /**
+   * Check if we should use doPriviledged
+   */
+  private boolean useDoPrivileged() {
+    if (System.getSecurityManager() != null) {
+      if (insideDebug == null) {
+        insideDebug = new ThreadLocal<Boolean>() {
+            @Override
+            protected synchronized Boolean initialValue() {
+              return new Boolean(false);
+            }
+          };
+      }
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * Are we already inside a debug print?
+   */
+  private void inside(boolean b) {
+    insideDebug.set(new Boolean(b));
+  }
+
+
+  /**
+   * Are we already inside a debug print?
+   */
+  private boolean isInside() {
+    return (insideDebug.get()).booleanValue();
+  }
+
+
+  /**
+   * The actual println implementation.
+   *
+   * @param str the message to print.
+   */
+  private void println0(final String str) {
+    System.err.println("## DEBUG: " + str);
+  }
+
+  /**
+   * Common {@code println()} method for debug messages.
+   *
+   * @param str the message to print.
+   */
+  public void println(final String str) {
+    if(useDoPrivileged()) {
+      // The call to this method can be made from a the framework on
+      // behalf of a bundle that have no permissions at all assigned
+      // to it.
+      //
+      // Use doPrivileged() here to protect the Framework from
+      // PrintStream implementations that does not wrap calls needing
+      // permissions in their own doPrivileged().
+      if (!isInside()) {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+              inside(true);
+              println0(str);
+              inside(false);
+              return null;
+            }
+          });
+      }
+    } else {
+      println0(str);
+    }
+  }
+
+  /**
+   * The actual printStackTrace() implementation.
+   *
+   * @param str the message to print.
+   * @param t   the throwable to print a stack trace for.
+   */
+  private void printStackTrace0(final String str, final Throwable t) {
+    System.err.println("## DEBUG: " + str);
+    t.printStackTrace();
+    if (t instanceof BundleException) {
+      final Throwable n = ((BundleException)t).getNestedException();
+      if (n != null) {
+        System.err.println("Nested bundle exception:");
+        n.printStackTrace();
+      }
+    }
+  }
+
+  /**
+   * Common printStackTrace method for debug messages.
+   *
+   * @param str the message to print.
+   * @param t   the throwable to print a stack trace for.
+   */
+  public void printStackTrace(final String str, final Throwable t) {
+    if(useDoPrivileged()) {
+      // The call to this method can be made from a the framework on
+      // behalf of a bundle that have no permissions at all assigned
+      // to it.
+      //
+      // Use doPrivileged() here to protect the Framework from
+      // PrintStream implementations that does not wrap calls needing
+      // permissions in their own doPrivileged().
+      if (!isInside()) {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+              inside(true);
+              printStackTrace0(str,t);
+              inside(false);
+              return null;
+            }
+          });
+      }
+    } else {
+      printStackTrace0(str,t);
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ExportPkg.java b/osgi/framework/src/org/knopflerfish/framework/ExportPkg.java
new file mode 100644
index 0000000..50d9d1c
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ExportPkg.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2005-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+
+
+/**
+ * Data structure for export package definitions.
+ *
+ * @author Jan Stein, Gunnar Ekolin
+ */
+class ExportPkg
+  implements BundleCapability, Comparable<ExportPkg>
+{
+  // To maintain the creation order in the osgi.wiring.package name space.
+  static private int exportPkgCount = 0;
+  final int orderal = ++exportPkgCount;
+
+  final String name;
+  final BundlePackages bpkgs;
+  final Set<String> uses;
+  final Set<String> mandatory;
+  final Set <String> include;
+  final Set<String> exclude;
+  final Version version;
+  final Map<String,Object> attributes;
+  boolean zombie = false;
+
+  // Link to pkg entry
+  Pkg pkg = null;
+
+  /**
+   * Create an export package entry.
+   */
+  ExportPkg(final String name, final HeaderEntry he, final BundlePackages b)
+  {
+    this.bpkgs = b;
+    this.name = name;
+    if (name.startsWith("java.")) {
+      throw new IllegalArgumentException("You can not export a java.* package");
+    }
+    this.uses = Util.parseEnumeration(Constants.USES_DIRECTIVE, he
+        .getDirectives().get(Constants.USES_DIRECTIVE));
+    this.mandatory = Util.parseEnumeration(Constants.MANDATORY_DIRECTIVE, he
+        .getDirectives().get(Constants.MANDATORY_DIRECTIVE));
+    this.include = Util.parseEnumeration(Constants.INCLUDE_DIRECTIVE, he
+        .getDirectives().get(Constants.INCLUDE_DIRECTIVE));
+    this.exclude = Util.parseEnumeration(Constants.EXCLUDE_DIRECTIVE, he
+        .getDirectives().get(Constants.EXCLUDE_DIRECTIVE));
+    final String versionStr = (String) he.getAttributes()
+        .remove(Constants.VERSION_ATTRIBUTE);
+    @SuppressWarnings("deprecation")
+    final String SPEC_VERSION = Constants.PACKAGE_SPECIFICATION_VERSION;
+    final String specVersionStr = (String) he.getAttributes().remove(SPEC_VERSION);
+    if (specVersionStr != null) {
+      this.version = new Version(specVersionStr);
+      if (versionStr != null && !this.version.equals(new Version(versionStr))) {
+        throw new IllegalArgumentException("Both " + Constants.VERSION_ATTRIBUTE +
+                                           " and " + SPEC_VERSION  +
+                                           " are specified, and differs");
+      }
+    } else if (versionStr != null) {
+      this.version = new Version(versionStr);
+    } else {
+      this.version = Version.emptyVersion;
+    }
+    if (he.getAttributes().containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)) {
+      throw new IllegalArgumentException("Export definition illegally contains attribute, " +
+                                         Constants.BUNDLE_VERSION_ATTRIBUTE);
+    }
+    if (he.getAttributes().containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)) {
+      throw new IllegalArgumentException("Export definition illegally contains attribute, " +
+                                         Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+    }
+    this.attributes = Collections.unmodifiableMap(he.getAttributes());
+  }
+
+
+  /**
+   * Create an export package entry with a new name from an export template.
+   *
+   * @param ep The export template to create an export package entry for.
+   * @param name The name of the export package entry created from the template.
+   */
+  ExportPkg(ExportPkg ep, String name) {
+    this.name = name;
+    this.bpkgs = ep.bpkgs;
+    this.uses = ep.uses;
+    this.mandatory = ep.mandatory;
+    this.include = ep.include;
+    this.exclude = ep.exclude;
+    this.version = ep.version;
+    this.attributes = ep.attributes;
+  }
+
+
+  /**
+   * Create a re-export package entry with a new bundle owner from an
+   * existing export.
+   * @param ep The ExportPkg to create a re-export package entry for.
+   * @param b  The BundlePackages that owns this re-exprot entry.
+   */
+  ExportPkg(ExportPkg ep, BundlePackages b) {
+    this.name = ep.name;
+    this.bpkgs = b;
+    this.uses = ep.uses;
+    this.mandatory = ep.mandatory;
+    this.include = ep.include;
+    this.exclude = ep.exclude;
+    this.version = ep.version;
+    this.attributes = ep.attributes;
+  }
+
+
+  /**
+   * Attach this to a Pkg object which indicate that it is exported.
+   */
+  void attachPkg(Pkg p) {
+    pkg = p;
+  }
+
+
+  /**
+   * Detach this from a Pkg object which indicate that it is no longer exported.
+   */
+  void detachPkg() {
+    pkg = null;
+    zombie = false;
+  }
+
+
+  /**
+   * Checks if we are allowed to export this class according to
+   * the filter rules.
+   */
+  boolean checkFilter(String fullClassName) {
+    String clazz = null;
+    boolean ok = true;
+    if (fullClassName != null) {
+      if (include != null) {
+        // assert fullClassName.startsWith(name)
+        clazz = fullClassName.substring(name.length() + 1);
+        for (final Iterator<String> i = include.iterator(); i.hasNext(); ) {
+          if (Util.filterMatch(i.next(), clazz)) {
+            break;
+          }
+          if (!i.hasNext()) {
+            ok = false;
+          }
+        }
+      }
+      if (ok && exclude != null) {
+        if (clazz == null) {
+          // assert fullClassName.startsWith(name)
+          clazz = fullClassName.substring(name.length() + 1);
+        }
+        for (final String string : exclude) {
+          if (Util.filterMatch(string, clazz)) {
+            ok = false;
+            break;
+          }
+        }
+      }
+    }
+    return ok;
+  }
+
+
+  /**
+   * Check if ExportPkg is provider of a package.
+   *
+   * @return True if pkg exports the package.
+   */
+  boolean isProvider() {
+    final Pkg p = pkg;
+    if (p != null) {
+      synchronized (p) {
+        return p.providers.contains(this) || bpkgs.isRequired();
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * Check if ExportPkg is exported from its bundle. A package is deemed to
+   * be exported if its bundle is resolved and hasn't been replaced by a
+   * conflicting import (see resolving process chapter in core spec.).
+   * Bundle must also have export permission.
+   *
+   * @return True if pkg exports the package.
+   */
+  boolean isExported() {
+    final BundlePackages bp = bpkgs;
+    if (checkPermission() && pkg != null &&
+        (bp.bg.bundle.isResolved() || zombie)) {
+      final BundlePackages pbp = bp.getProviderBundlePackages(name);
+      return pbp == null || pbp.bg.bundle == bpkgs.bg.bundle;
+    }
+    return false;
+  }
+
+
+  /**
+   * Get active importers of a package.
+   *
+   * @param pkg Package.
+   * @return List of bundles importing, null export is not active.
+   */
+  List<ImportPkg> getPackageImporters() {
+    final Pkg p = pkg;
+    if (p != null) {
+      final List<ImportPkg> res = new ArrayList<ImportPkg>();
+      synchronized (p) {
+        for (final ImportPkg ip : p.importers) {
+          if (ip.provider == this && ip.bpkgs != bpkgs) {
+            res.add(ip);
+          }
+        }
+      }
+      return res;
+    }
+    return null;
+  }
+
+
+  /**
+   * Check if we have export permissions.
+   *
+   * @return true if we have export permission
+   */
+  boolean checkPermission() {
+    return bpkgs.bg.bundle.fwCtx.perm.hasExportPackagePermission(this);
+  }
+
+
+  /**
+   * Check if the name, version, attributes and directives are equal.
+   *
+   * @return true if all package information is equal, otherwise false.
+   */
+  boolean pkgEquals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (null == o) {
+      return false;
+    }
+    final ExportPkg ep = (ExportPkg)o;
+    return name.equals(ep.name) &&
+      version.equals(ep.version) &&
+      (uses == null ? ep.uses == null : uses.equals(ep.uses)) &&
+      (mandatory == null ? ep.mandatory == null : mandatory.equals(ep.mandatory)) &&
+      (include == null ? ep.include == null : include.equals(ep.include)) &&
+      (exclude == null ? ep.exclude == null : exclude.equals(ep.exclude)) &&
+      attributes.equals(ep.attributes);
+  }
+
+
+  /**
+   * String describing package name and specification version, if specified.
+   *
+   * @return String.
+   */
+  public String pkgString() {
+    if (version != Version.emptyVersion) {
+      return name + ";" + Constants.VERSION_ATTRIBUTE + "=" + version;
+    } else {
+      return name;
+    }
+  }
+
+
+  /**
+   * String describing this object.
+   *
+   * @return String.
+   */
+  @Override
+  public String toString() {
+    final StringBuffer sb = new StringBuffer(pkgString());
+    sb.append(' ');
+    if (zombie) {
+      sb.append("Zombie");
+    }
+    sb.append("Bundle");
+    sb.append(bpkgs.bundleGenInfo());
+    return sb.toString();
+  }
+
+
+  @Override
+  public String getNamespace() {
+    return BundleRevision.PACKAGE_NAMESPACE;
+  }
+
+
+  @Override
+  public Map<String, String> getDirectives() {
+    final Map<String,String> res = new HashMap<String, String>(1);
+
+    if (uses!=null) {
+      final StringBuffer sb = new StringBuffer(uses.size()*30);
+      for (final String pkg : uses) {
+        if (sb.length()>0) sb.append(',');
+        sb.append(pkg);
+      }
+      res.put(Constants.USES_DIRECTIVE, sb.toString());
+    }
+
+    return res;
+  }
+
+
+  @Override
+  public Map<String, Object> getAttributes() {
+    final Map<String,Object> res
+      = new HashMap<String, Object>(4+attributes.size());
+
+    res.put(BundleRevision.PACKAGE_NAMESPACE, name);
+    res.put(Constants.VERSION_ATTRIBUTE, version);
+
+    res.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bpkgs.bg.symbolicName);
+    res.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bpkgs.bg.version);
+
+    res.putAll(attributes);
+
+    return Collections.unmodifiableMap(res);
+  }
+
+
+  @Override
+  public BundleRevision getRevision() {
+    return bpkgs.bg.bundleRevision;
+  }
+
+
+  @Override
+  public BundleRevision getResource() {
+    return bpkgs.bg.bundleRevision;
+  }
+
+
+  /**
+   * The default ordering is the order in which the {@code ExportPkg}-objects
+   * has been created. I.e., the order they appeared in the {@code Export-Package}
+   * header.
+   *
+   * @param o other object to compare with.
+   * @return Less than zero, zero or greater than zero of this object is smaller
+   *  than, equals to or greater than {@code o}.
+   */
+  @Override
+  public int compareTo(ExportPkg o)
+  {
+    return this.orderal - o.orderal;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ExportedPackageImpl.java b/osgi/framework/src/org/knopflerfish/framework/ExportedPackageImpl.java
new file mode 100644
index 0000000..3efcd4f
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ExportedPackageImpl.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2003-2010, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.HashSet;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+
+/**
+ * An exported package.
+ *
+ * Instances implementing this interface are created by the
+ * {@link PackageAdmin} service.
+ * <p> Note that the information about an exported package provided by
+ * this class is valid only until the next time
+ * <tt>PackageAdmin.refreshPackages()</tt> is
+ * called.
+ * If an ExportedPackage becomes stale (that is, the package it references
+ * has been updated or removed as a result of calling
+ * PackageAdmin.refreshPackages()),
+ * its getName() and getSpecificationVersion() continue to return their
+ * old values, isRemovalPending() returns true, and getExportingBundle()
+ * and getImportingBundles() return null.
+ */
+ at SuppressWarnings("deprecation")
+public class ExportedPackageImpl implements ExportedPackage {
+
+  final private ExportPkg pkg;
+
+  ExportedPackageImpl(ExportPkg pkg) {
+    this.pkg = pkg;
+  }
+
+
+  /**
+   * Returns the name of this <tt>ExportedPackage</tt>.
+   *
+   * @return The name of this <tt>ExportedPackage</tt>.
+   */
+  public String getName() {
+    return pkg.name;
+  }
+
+
+  /**
+   * Returns the bundle that is exporting this <tt>ExportedPackage</tt>.
+   *
+   * @return The exporting bundle, or null if this <tt>ExportedPackage</tt>
+   *         has become stale.
+   */
+  public Bundle getExportingBundle() {
+    if (pkg.pkg != null) {
+      return pkg.bpkgs.bg.bundle;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Returns the resolved bundles that are currently importing this
+   * <tt>ExportedPackage</tt>.
+   *
+   * @return The array of resolved bundles currently importing this
+   * <tt>ExportedPackage</tt>, or null if this <tt>ExportedPackage</tt>
+   * has become stale.
+   */
+  public Bundle[] getImportingBundles() {
+    final List<ImportPkg> imps = pkg.getPackageImporters();
+    if (imps != null) {
+      final HashSet<Bundle> bs = new HashSet<Bundle>();
+      for (final ImportPkg ip : imps) {
+        bs.add(ip.bpkgs.bg.bundle);
+      }
+      final List<BundlePackages> rl = pkg.bpkgs.getRequiredBy();
+      for (final BundlePackages bp : rl) {
+        bs.add(bp.bg.bundle);
+      }
+      return bs.toArray(new Bundle[bs.size()]);
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Returns the specification version of this <tt>ExportedPackage</tt>, as
+   * specified in the exporting bundle's manifest file.
+   *
+   * @return The specification version of this <tt>ExportedPackage</tt>, or
+   *         <tt>null</tt> if no version information is available.
+   */
+  public String getSpecificationVersion() {
+    return pkg.version.toString();
+  }
+
+
+  /**
+   * Returns <tt>true</tt> if this <tt>ExportedPackage</tt> has been
+   * exported by a bundle that has been updated or uninstalled.
+   *
+   * @return <tt>true</tt> if this <tt>ExportedPackage</tt> is being
+   * exported by a bundle that has been updated or uninstalled;
+   * <tt>false</tt> otherwise.
+   */
+  public boolean isRemovalPending() {
+    if (pkg.isProvider()) {
+      return pkg.zombie;
+    } else {
+      return false;
+    }
+  }
+
+
+  public Version getVersion() {
+    return pkg.version;
+  }
+
+  @Override
+  public String toString() {
+    return pkg.name +"(" +pkg.version +")";
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ExtensionContext.java b/osgi/framework/src/org/knopflerfish/framework/ExtensionContext.java
new file mode 100644
index 0000000..9289a96
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ExtensionContext.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2012-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+
+
+/**
+ * Context that extension bundles are given to interact with the
+ * Knopflerfish framework implementation.
+ *
+ * @author Gunnar Ekolin
+ */
+
+public class ExtensionContext {
+
+  private final FrameworkContext fwCtx;
+  @SuppressWarnings("unused")
+  private final BundleGeneration ext;
+  private Object activator = null;
+
+  ExtensionContext(final FrameworkContext fwCtx,
+                   final BundleGeneration ext) {
+    this.fwCtx = fwCtx;
+    this.ext   = ext;
+
+    String extActivatorName =
+      ext.archive.getAttribute("Extension-Activator");
+    extActivatorName = null!=extActivatorName ? extActivatorName.trim() : null;
+
+    try {
+      // Extension bundles uses the framework class loader...
+      final Class<?> c = getClass().getClassLoader().loadClass(extActivatorName);
+      activator = c.newInstance();
+
+      final Method activateMethod
+        = c.getMethod("activate", new Class[] { ExtensionContext.class });
+      activateMethod.invoke(activator, new Object[] { this } );
+    } catch (final Exception e) {
+      activator = null;
+      final String msg = "Failed to activate framework extension "
+        +ext.symbolicName + ":" +ext.version;
+      fwCtx.log(msg, e);
+    }
+  }
+
+
+  /**
+   * Register a service possibly implementing multiple interfaces.
+   *
+   * @see org.osgi.framework.BundleContext#registerService
+   */
+  public ServiceRegistration<?> registerService(String[] clazzes,
+                                                Object service,
+                                                Dictionary<String, ?> properties)
+  {
+    return fwCtx.services.register(fwCtx.systemBundle, clazzes, service,
+                                   properties);
+  }
+
+  /**
+   * @return the current bundle class loader for a given bundle.
+   */
+  public ClassLoader getClassLoader(Bundle b) {
+    final BundleImpl bi = (BundleImpl) b;
+    return bi.getClassLoader();
+  }
+
+  /**
+   * @return the generation (bundle revision) that a given bundle
+   * class loader belongs to.
+   */
+  public int getGeneration(BundleClassLoader bcl) {
+    return bcl.bpkgs.bg.generation;
+  }
+
+
+
+  /**
+   * The list of bundle class loader listeners registered for this
+   * extension context.
+   */
+  private final List<BundleClassLoaderListener> bclls
+    = new ArrayList<BundleClassLoaderListener>();
+
+  /**
+   * Register a bundle class loader created listener.
+   *
+   * @param bcll the bundle class loader listener to register.
+   */
+  public void addBundleClassLoaderListener(BundleClassLoaderListener bcll)  {
+    bclls.add(bcll);
+  }
+
+  /**
+   * Called by the framework context when a bundle class
+   * loader has been created. Will notify all registered listeners.
+   *
+   * <p>This is a synchronous call.
+   *
+   * @param bcl the newly created bundle class loader.
+   */
+  void bundleClassLoaderCreated(final BundleClassLoader bcl) {
+    for (final BundleClassLoaderListener bcll : bclls) {
+      bcll.bundleClassLoaderCreated(bcl);
+    }
+  }
+
+  /**
+   * Called by the framework context when a bundle class loader has
+   * been closed down. Will notify all registered listeners.
+   *
+   * <p>This is a synchronous call.
+   *
+   * @param bcl the closed down bundle class loader.
+   */
+  void bundleClassLoaderClosed(final BundleClassLoader bcl) {
+    for (final BundleClassLoaderListener bcll : bclls) {
+      bcll.bundleClassLoaderClosed(bcl);
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/FWProps.java b/osgi/framework/src/org/knopflerfish/framework/FWProps.java
new file mode 100644
index 0000000..2e6021f
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FWProps.java
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 2009-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.net.URLClassLoader;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/**
+ * This class contains properties used by the framework
+ */
+public class FWProps {
+
+  /**
+   * Constants for knopflerfish framework properties
+   */
+  public final static String ALL_SIGNED_PROP = "org.knopflerfish.framework.all_signed";
+
+  public final static String AUTOMANIFEST_PROP = "org.knopflerfish.framework.automanifest";
+
+  public final static String AUTOMANIFEST_CONFIG_PROP = "org.knopflerfish.framework.automanifest.config";
+
+  public final static String BUNDLESTORAGE_PROP = "org.knopflerfish.framework.bundlestorage";
+
+  public final static String BUNDLESTORAGE_CHECKSIGNED_PROP = "org.knopflerfish.framework.bundlestorage.checksigned";
+
+  public final static String PATCH_PROP = "org.knopflerfish.framework.patch";
+
+  public final static String PATCH_CONFIGURL_PROP = "org.knopflerfish.framework.patch.configurl";
+
+  public final static String PATCH_DUMPCLASSES_PROP = "org.knopflerfish.framework.patch.dumpclasses";
+
+  public final static String PATCH_DUMPCLASSES_DIR_PROP = "org.knopflerfish.framework.patch.dumpclasses.dir";
+
+  public final static String SERVICE_CONDITIONALPERMISSIONADMIN_PROP = "org.knopflerfish.framework.service.conditionalpermissionadmin";
+
+  public final static String SERVICE_PERMISSIONADMIN_PROP = "org.knopflerfish.framework.service.permissionadmin";
+
+  /**
+   * Property specifying how bundle threads which are aborted should be handled.
+   * Possible values are {@link BundleThread#ABORT_ACTION_STOP},
+   * {@link BundleThread#ABORT_ACTION_MINPRIO},
+   * {@link BundleThread#ABORT_ACTION_IGNORE}. The default value is
+   * {@link BundleThread#ABORT_ACTION_IGNORE}.
+   */
+  public final static String BUNDLETHREAD_ABORT = "org.knopflerfish.framework.bundlethread.abort";
+
+  /**
+   * Property specifying the amount of time in seconds that the framework waits for a
+   * BundleActivator.start() or .stop() call to complete and return. The default value is 0 which
+   * means to wait indefinitely.
+   */
+  public final static String BUNDLETHREAD_TIMEOUT = "org.knopflerfish.framework.bundlethread.timeout";
+
+  /**
+   * Name of system property for basic system packages to be exported. The
+   * normal OSGi exports will be added to this list.
+   */
+  public final static String SYSTEM_PACKAGES_BASE_PROP = "org.knopflerfish.framework.system.packages.base";
+
+  /**
+   * Property name pointing to file listing of system-exported packages
+   */
+  public final static String SYSTEM_PACKAGES_FILE_PROP = "org.knopflerfish.framework.system.packages.file";
+
+  /**
+   * Property name for selecting exporting profile of system packages.
+   */
+  public final static String SYSTEM_PACKAGES_VERSION_PROP = "org.knopflerfish.framework.system.packages.version";
+
+  public final static String IS_DOUBLECHECKED_LOCKING_SAFE_PROP = "org.knopflerfish.framework.is_doublechecked_locking_safe";
+
+  public final static String LDAP_NOCACHE_PROP = "org.knopflerfish.framework.ldap.nocache";
+
+  public final static String LISTENER_N_THREADS_PROP = "org.knopflerfish.framework.listener.n_threads";
+
+  /**
+   * If the Main-Class manifest attribute is set and this bundles location is
+   * present in the value (comma separated list) of the Framework property named
+   * org.knopflerfish.framework.main.class.activation then setup up a bundle
+   * activator that calls the main-method of the Main-Class when the bundle is
+   * started, and if the Main-Class contains a method named stop() call that
+   * method when the bundle is stopped.
+   */
+  public final static String MAIN_CLASS_ACTIVATION_PROP = "org.knopflerfish.framework.main.class.activation";
+
+  public final static String STRICTBOOTCLASSLOADING_PROP = "org.knopflerfish.framework.strictbootclassloading";
+
+  public final static String VALIDATOR_PROP = "org.knopflerfish.framework.validator";
+
+  public final static String SETCONTEXTCLASSLOADER_PROP = "org.knopflerfish.osgi.setcontextclassloader";
+
+  public final static String REGISTERSERVICEURLHANDLER_PROP = "org.knopflerfish.osgi.registerserviceurlhandler";
+
+  public final static String STARTLEVEL_USE_PROP = "org.knopflerfish.startlevel.use";
+
+  /**
+   * Set to true indicates startlevel compatability mode. all bundles and
+   * current start level will be 1
+   */
+  public final static String STARTLEVEL_COMPAT_PROP = "org.knopflerfish.framework.startlevel.compat";
+
+  /**
+   * Set to true indicates that the framework shouldn't write any files.
+   */
+  public static final String READ_ONLY_PROP = "org.knopflerfish.framework.readonly";
+
+  /**
+   * Name of special property containing a comma-separated list of all other
+   * property names.
+   */
+  public static final String KEY_KEYS = "org.knopflerfish.framework.bundleprops.keys";
+
+  /**
+   * Common true string.
+   */
+  public final static String TRUE = "true";
+
+  /**
+   * Common false string.
+   */
+  public final static String FALSE = "false";
+
+  /**
+   * Common new line string.
+   */
+  public static final String NL = System.getProperty("line.separator");
+
+  // If set to true, use strict rules for loading classes from the
+  // boot class loader. If false, accept class loading from the boot
+  // class path from classes themselves on the boot class, but which
+  // incorrectly assumes they may access all of the boot classes on
+  // any class loader (such as the bundle class loader).
+  //
+  // Setting this to TRUE will, for example, result in broken
+  // serialization on the Sun JVM It's debatable what is the correct
+  // OSGi R4 behavior.
+  public boolean STRICTBOOTCLASSLOADING;
+
+  /**
+   * The properties for this framework instance.
+   */
+  protected Map<String, String> props = new Hashtable<String, String>();
+
+  /**
+   * The default properties for this framework instance. TBD, maybe we should
+   * make this JVM global!?
+   */
+  protected Map<String, String> props_default = new Hashtable<String, String>();
+
+  // If set to true, then during the UNREGISTERING event the Listener
+  // can use the ServiceReference to receive an instance of the service.
+  public boolean UNREGISTERSERVICE_VALID_DURING_UNREGISTERING = true;
+
+  // If set to true, set the bundle startup thread's context class
+  // loader to the bundle class loader. This is useful for tests
+  // but shouldn't really be used in production.
+  public boolean SETCONTEXTCLASSLOADER = false;
+
+  public boolean REGISTERSERVICEURLHANDLER = true;
+
+  public static int javaVersionMajor = -1;
+  public static int javaVersionMinor = -1;
+  public static int javaVersionMicro = -1;
+
+  static {
+    String javaVersion = System.getProperty("java.specification.version");
+    if (javaVersion == null || javaVersion.length()==0) {
+      javaVersion = System.getProperty("java.version");
+    }
+    // Value is on the form M.N.U_P[-xxx] where M,N,U,P are decimal integers
+    if (null != javaVersion) {
+      int startPos = 0;
+      int endPos = 0;
+      final int max = javaVersion.length();
+      while (endPos < max && Character.isDigit(javaVersion.charAt(endPos))) {
+        endPos++;
+      }
+      if (startPos < endPos) {
+        try {
+          javaVersionMajor = Integer.parseInt(javaVersion.substring(startPos, endPos));
+          startPos = endPos + 1;
+          endPos = startPos;
+          while (endPos < max && Character.isDigit(javaVersion.charAt(endPos))) {
+            endPos++;
+          }
+          if (startPos < endPos) {
+            javaVersionMinor = Integer.parseInt(javaVersion.substring(startPos, endPos));
+            startPos = endPos + 1;
+            endPos = startPos;
+            while (endPos < max && Character.isDigit(javaVersion.charAt(endPos))) {
+              endPos++;
+            }
+            if (startPos < endPos) {
+              javaVersionMicro = Integer.parseInt(javaVersion.substring(startPos, endPos));
+            }
+          }
+        } catch (final NumberFormatException _nfe) {
+        }
+      }
+    }
+  }
+
+  @SuppressWarnings("deprecation")
+  private static final String FRAMEWORK_EXECUTIONENVIRONMENT = Constants.FRAMEWORK_EXECUTIONENVIRONMENT;
+
+  /**
+   * Is it safe to use double-checked locking or not. It is safe if JSR 133 is
+   * included in the running JRE. I.e., for Java SE if version is 1.5 or higher.
+   */
+  public boolean isDoubleCheckedLockingSafe;
+
+
+  public FWProps(Map<String, String> initProps, FrameworkContext fwCtx) {
+    // Add explicitly given properties.
+    props.putAll(initProps);
+
+    // Setup Debug as early as possible.
+    fwCtx.debug = new Debug(this);
+
+    // Setup default (launch) OSGi properties, see OSGi R4 v4.2 sec 4.2.2
+    initProperties(fwCtx);
+
+    // Setup default KF framework properties
+    initKFProperties();
+
+    // Set up some instance variables that depends on the properties
+    SETCONTEXTCLASSLOADER = getBooleanProperty(SETCONTEXTCLASSLOADER_PROP);
+    REGISTERSERVICEURLHANDLER = getBooleanProperty(REGISTERSERVICEURLHANDLER_PROP);
+    STRICTBOOTCLASSLOADING = getBooleanProperty(STRICTBOOTCLASSLOADING_PROP);
+    isDoubleCheckedLockingSafe = getBooleanProperty(IS_DOUBLECHECKED_LOCKING_SAFE_PROP);
+  }
+
+
+  /**
+   * Retrieve boolean value of the named framework property, with a default
+   * value.
+   *
+   */
+  public boolean getBooleanProperty(String key) {
+    final String v = getProperty(key);
+    if (v != null) {
+      return TRUE.equalsIgnoreCase(v);
+    }
+    return false;
+  }
+
+
+  /**
+   * Retrieve the value of the named framework property, with a default value.
+   *
+   */
+  public String getProperty(String key) {
+    if (KEY_KEYS.equals(key)) {
+      return makeKeys();
+    }
+    String v = props.get(key);
+    if (v == null) {
+      v = System.getProperty(key);
+      if (v == null) {
+        // We know that we don't need to trim the result
+        return props_default.get(key);
+      }
+    }
+    return v.trim();
+  }
+
+
+  public void setPropertyDefault(String key, String val) {
+    // No need to save default if already have a value
+    if (!props.containsKey(key)) {
+      props_default.put(key, val);
+    }
+  }
+
+
+  /**
+   * Set property if not set to system property if it exists otherwise set to
+   * supplied value.
+   */
+  public void setPropertyIfNotSet(String key, String val) {
+    if (!props.containsKey(key)) {
+      props.put(key, System.getProperty(key, val));
+    }
+  }
+
+
+  public Dictionary<String, String> getProperties() {
+    final Hashtable<String, String> p = new Hashtable<String, String>(props_default);
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    final
+    Hashtable<String,String> sysProps = (Hashtable) System.getProperties();
+    p.putAll(sysProps);
+    p.putAll(props);
+    p.put(KEY_KEYS, makeKeys());
+    return p;
+  }
+
+
+  protected String makeKeys() {
+    final StringBuffer sb = new StringBuffer();
+    for (final String string : props.keySet()) {
+      if (sb.length() > 0) {
+        sb.append(',');
+      }
+      sb.append(string.toString());
+    }
+    for (final String string : props_default.keySet()) {
+      sb.append(',');
+      sb.append(string.toString());
+    }
+    return sb.toString();
+  }
+
+
+  /**
+   * Create the default set of framework (launch) properties.
+   */
+  protected void initProperties(FrameworkContext fwCtx) {
+    setPropertyIfNotSet(Constants.FRAMEWORK_BOOTDELEGATION, "");
+    setPropertyIfNotSet(Constants.FRAMEWORK_BSNVERSION,
+                        Constants.FRAMEWORK_BSNVERSION_MANAGED);
+    setPropertyIfNotSet(Constants.FRAMEWORK_BUNDLE_PARENT,
+                        Constants.FRAMEWORK_BUNDLE_PARENT_BOOT);
+    setPropertyIfNotSet(Constants.FRAMEWORK_EXECPERMISSION, "");
+
+    if (!props.containsKey(FRAMEWORK_EXECUTIONENVIRONMENT)) {
+      final StringBuffer ee = new StringBuffer();
+      // Always allow ee minimum
+      ee.append("OSGi/Minimum-1.0");
+      ee.append(",OSGi/Minimum-1.1");
+      ee.append(",OSGi/Minimum-1.2");
+      // Set up the default ExecutionEnvironment
+      if (1 == javaVersionMajor) {
+        for (int i = javaVersionMinor; i > 1; i--) {
+          ee.append((i > 5) ? ",JavaSE-1." : ",J2SE-1.");
+          ee.append(i);
+        }
+      }
+      props.put(FRAMEWORK_EXECUTIONENVIRONMENT, ee.toString());
+    }
+
+    // The actual value is created in SytemBundle.
+    setPropertyIfNotSet(Constants.FRAMEWORK_SYSTEMCAPABILITIES, "");
+    setPropertyIfNotSet(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA, "");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_LANGUAGE, Locale.getDefault().getLanguage());
+    setPropertyIfNotSet(Constants.FRAMEWORK_LIBRARY_EXTENSIONS, "");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_OS_NAME,
+        Alias.unifyOsName(System.getProperty("os.name")));
+
+    if (!props.containsKey(Constants.FRAMEWORK_OS_VERSION)) {
+      final String ver = System.getProperty("os.version");
+      int maj = 0;
+      int min = 0;
+      int mic = 0;
+      String qual = null;
+      if (ver != null) {
+        // Convert os.version to a reasonable default
+        try {
+          final StringTokenizer st = new StringTokenizer(ver.trim(), ".");
+          maj = Integer.parseInt(st.nextToken());
+          if (st.hasMoreTokens()) {
+            qual = st.nextToken();
+            min = Integer.parseInt(qual);
+            qual = null;
+            if (st.hasMoreTokens()) {
+              qual = st.nextToken();
+              mic = Integer.parseInt(qual);
+              qual = null;
+              if (st.hasMoreTokens()) {
+                qual = st.nextToken();
+              }
+            }
+          }
+        } catch (final Exception ignore) {
+        }
+      }
+      Version osVersion;
+      try {
+        osVersion = new Version(maj, min, mic, qual);
+      } catch (final IllegalArgumentException skip) {
+        osVersion = new Version(maj, min, mic, null);
+      }
+      props.put(Constants.FRAMEWORK_OS_VERSION, osVersion.toString());
+    }
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_PROCESSOR,
+        Alias.unifyProcessor(System.getProperty("os.arch")));
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_SECURITY, "");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, "1");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_STORAGE, "fwdir");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_STORAGE_CLEAN, "");
+
+    // The SystemBundle will fill in this later.
+    setPropertyIfNotSet(Constants.FRAMEWORK_SYSTEMPACKAGES, "");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "");
+
+    setPropertyIfNotSet(Constants.FRAMEWORK_TRUST_REPOSITORIES, "");
+
+    // NYI
+    setPropertyIfNotSet(Constants.FRAMEWORK_WINDOWSYSTEM, "");
+
+    // Impl. constants
+    props.put(Constants.FRAMEWORK_VERSION, Util.readFrameworkVersion());
+    props.put(Constants.FRAMEWORK_VENDOR, "Knopflerfish");
+    props.put(Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, TRUE);
+    props.put(Constants.SUPPORTS_FRAMEWORK_FRAGMENT, TRUE);
+    // Only first framework support framework extension
+    // TODO Improve this in the future
+    setPropertyIfNotSet(Constants.SUPPORTS_FRAMEWORK_EXTENSION,
+        getClass().getClassLoader() instanceof URLClassLoader && fwCtx.id == 0 ? TRUE : FALSE);
+    // Only first framework can support bootclasspath extension
+    // TODO Improve this in the future
+    setPropertyIfNotSet(Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, FALSE);
+    if (getBooleanProperty(Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION)
+        && !(getClass().getClassLoader() instanceof URLClassLoader && fwCtx.id == 1)) {
+      props.put(Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, FALSE);
+    }
+  }
+
+
+  /**
+   * Create the default set of KF specific framework properties.
+   */
+  protected void initKFProperties() {
+    setPropertyDefault(ALL_SIGNED_PROP, FALSE);
+    setPropertyDefault(AUTOMANIFEST_PROP, FALSE);
+    setPropertyDefault(AUTOMANIFEST_CONFIG_PROP, "!!/automanifest.props");
+    setPropertyDefault(BUNDLESTORAGE_PROP, "file");
+    setPropertyDefault(BUNDLESTORAGE_CHECKSIGNED_PROP, TRUE);
+    setPropertyDefault(PATCH_PROP, FALSE);
+    setPropertyDefault(PATCH_CONFIGURL_PROP, "!!/patches.props");
+    setPropertyDefault(PATCH_DUMPCLASSES_PROP, FALSE);
+    setPropertyDefault(PATCH_DUMPCLASSES_DIR_PROP, "patchedclasses");
+    setPropertyDefault(SERVICE_CONDITIONALPERMISSIONADMIN_PROP, TRUE);
+    setPropertyDefault(SERVICE_PERMISSIONADMIN_PROP, TRUE);
+    setPropertyDefault(SYSTEM_PACKAGES_BASE_PROP, "");
+    setPropertyDefault(SYSTEM_PACKAGES_FILE_PROP, "");
+    setPropertyDefault(SYSTEM_PACKAGES_VERSION_PROP, Integer.toString(javaVersionMajor) + "."
+        + javaVersionMinor);
+    setPropertyDefault(IS_DOUBLECHECKED_LOCKING_SAFE_PROP, javaVersionMajor >= 1
+        && javaVersionMinor >= 5 ? TRUE : FALSE);
+    setPropertyDefault(LDAP_NOCACHE_PROP, FALSE);
+    setPropertyDefault(MAIN_CLASS_ACTIVATION_PROP, "");
+    setPropertyDefault(STRICTBOOTCLASSLOADING_PROP, FALSE);
+    setPropertyDefault(VALIDATOR_PROP, getProperty(Constants.FRAMEWORK_TRUST_REPOSITORIES)
+        .length() > 0 ? "JKSValidator" : "none");
+    setPropertyDefault(SETCONTEXTCLASSLOADER_PROP, FALSE);
+    setPropertyDefault(REGISTERSERVICEURLHANDLER_PROP, TRUE);
+    setPropertyDefault(STARTLEVEL_COMPAT_PROP, FALSE);
+    setPropertyDefault(STARTLEVEL_USE_PROP, TRUE);
+    setPropertyDefault(READ_ONLY_PROP, FALSE);
+  }
+
+}
\ No newline at end of file
diff --git a/osgi/framework/src/org/knopflerfish/framework/FWResourceURLStreamHandler.java b/osgi/framework/src/org/knopflerfish/framework/FWResourceURLStreamHandler.java
new file mode 100644
index 0000000..4fc7064
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FWResourceURLStreamHandler.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+
+/**
+ * Framework resource URL handling, used for accessing framework
+ * resources.
+ *
+ * Accepts URLs on the form
+ * <pre>
+ *  fwresource:file
+ * </pre>
+ * Where <tt>file</tt> is a valid framework resource path.
+ *
+ * TODO: Handle multiple frameworks in the same JVM correctly
+ *       when we have multiple classloaders.
+ */
+public class FWResourceURLStreamHandler extends URLStreamHandler {
+
+  final public static String PROTOCOL = "fwresource";
+
+  final private ClassLoader classLoader;
+
+  FWResourceURLStreamHandler() {
+    this.classLoader = getClass().getClassLoader();
+  }
+
+  /**
+   *
+   */
+  @Override
+  protected URLConnection openConnection(URL u) throws IOException {
+      final URL resourceUrl = classLoader.getResource(u.getPath());
+      return resourceUrl.openConnection();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/FileArchive.java b/osgi/framework/src/org/knopflerfish/framework/FileArchive.java
new file mode 100644
index 0000000..22dd436
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FileArchive.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Set;
+
+/**
+ * Interface for managing bundle contents.
+ *
+ * @author Jan Stein
+ */
+public interface FileArchive {
+
+  /**
+   * Get a byte array containg the contents of named file from a bundle archive.
+   *
+   * @param component File to get.
+   * @return Byte array with contents of file or null if file doesn't exist.
+   * @exception IOException if failed to read jar entry.
+   */
+  byte[] getClassBytes(String component) throws IOException;
+
+
+  /**
+   * Get a BundleResourceStream to named entry inside a bundle. Leading '/' is
+   * stripped.
+   *
+   * @param component Entry to get reference to.
+   * @param ix index of sub archives. A postive number is the classpath entry
+   *          index. 0 means look in the main bundle.
+   * @return BundleResourceStream to entry or null if it doesn't exist.
+   */
+  BundleResourceStream getBundleResourceStream(String component);
+
+
+  /**
+   * Returns an Enumeration of all the paths (<code>String</code> objects) to
+   * entries within the bundle whose longest sub-path matches the supplied path
+   * argument.
+   *
+   * @param name
+   * @return
+   */
+  Enumeration<String> findResourcesPath(String path);
+
+
+  /**
+   * Check for native library in archive.
+   *
+   * @param path Name of native code file to get.
+   * @return If native library exist return libname, otherwise null.
+   */
+  String checkNativeLibrary(String path);
+
+
+  /**
+   * Get native code library filename.
+   *
+   * @param libNameKey Key for native lib to get.
+   * @return A string with the path to the native library.
+   */
+  String getNativeLibrary(String libNameKey);
+
+
+  /**
+   * Get BundleGeneration object for this archive.
+   */
+  BundleGeneration getBundleGeneration();
+
+
+  /**
+   * Get sub-archive id for this archive.
+   */
+  int getSubId();
+
+
+  /**
+   * Check if a file exists (or dir, if dirs is true).
+   *
+   * @param path
+   * @param dirs
+   * @return
+   */
+  boolean exists(String path, boolean dirs);
+
+
+  /**
+   * List all entries for named directory.
+   *
+   * @param path
+   * @return
+   */
+  Set<String> listDir(String path);
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/FileTree.java b/osgi/framework/src/org/knopflerfish/framework/FileTree.java
new file mode 100644
index 0000000..b692975
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FileTree.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2003-2011, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.*;
+
+/**
+ * FileTree is extension to java.io.File that handles copying and deletion of
+ * complete file structures.
+ * 
+ * @author Jan Stein
+ */
+public class FileTree extends File {
+
+  private static final long serialVersionUID = 3396907770563704920L;
+
+
+  /**
+   * Creates a new FileTree instance based on given pathname string.
+   */
+  public FileTree(String name) {
+    super(name);
+  }
+
+
+  /**
+   * Creates a new Filetree instance by a pathname string to an existing File or
+   * FileTree.
+   */
+  public FileTree(File file, String name) {
+    super(file, name);
+  }
+
+
+  /**
+   * Creates a new FileTree instance from a parent pathname string and a child
+   * pathname string.
+   */
+  public FileTree(String n1, String n2) {
+    super(n1, n2);
+  }
+
+
+  /**
+   * Copy this file tree to specified destination.
+   * 
+   * @param copyFile File object representing the destination.
+   * @exception IOException if copy failed. Will leave destination in an
+   *              unspecified state.
+   */
+  public void copyTo(File copyFile) throws IOException {
+    if (isDirectory()) {
+      copyFile.mkdirs();
+      String[] dirs = list();
+      for (int i = dirs.length - 1; i >= 0; i--) {
+        (new FileTree(this, dirs[i])).copyTo(new File(copyFile, dirs[i]));
+      }
+    } else {
+      InputStream is = null;
+      OutputStream os = null;
+      try {
+        is = new BufferedInputStream(new FileInputStream(this));
+        os = new BufferedOutputStream(new FileOutputStream(copyFile));
+        byte[] buf = new byte[4096];
+        for (;;) {
+          int n = is.read(buf);
+          if (n < 0) {
+            break;
+          }
+          os.write(buf, 0, n);
+        }
+      } finally {
+        try {
+          if (is != null) {
+            is.close();
+          }
+        } finally {
+          if (os != null) {
+            os.close();
+          }
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Delete this file tree from disk.
+   * 
+   * @return True if operation completed okay.
+   */
+  public boolean delete() {
+    boolean allDeleted = true;
+    if (isDirectory()) {
+      String[] dirs = list();
+      if (dirs != null) {
+        for (int i = dirs.length - 1; i >= 0; i--) {
+          allDeleted &= (new FileTree(this, dirs[i])).delete();
+        }
+      }
+    }
+    boolean thisDeleted = super.delete();
+
+    return allDeleted & thisDeleted;
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Fragment.java b/osgi/framework/src/org/knopflerfish/framework/Fragment.java
new file mode 100644
index 0000000..d31a3d5
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Fragment.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Vector;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.VersionRange;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * Fragment information
+ */
+class Fragment
+  implements BundleRequirement
+{
+  final BundleGeneration gen;
+  final String hostName;
+  final String extension;
+  final VersionRange versionRange;
+  final Map<String,Object> attributes;
+  final Map<String,String> directives;
+
+  private final Vector<BundleGeneration> hosts = new Vector<BundleGeneration>(2);
+
+
+  /**
+   * @param gen
+   *          The bundle generation of this fragment.
+   * @param headerEntry
+   *          the fragment-host manifest header describing this fragment.
+   */
+  Fragment(final BundleGeneration gen, final HeaderEntry headerEntry) {
+    this.gen = gen;
+    this.hostName = headerEntry.getKey();
+
+    if (gen.archive.getAttribute(Constants.BUNDLE_ACTIVATOR) != null) {
+      throw new IllegalArgumentException("A fragment bundle can not have a Bundle-Activator.");
+    }
+
+    final Map<String,String>dirs = headerEntry.getDirectives();
+    final String extension = dirs.get(Constants.EXTENSION_DIRECTIVE);
+    if (Constants.EXTENSION_FRAMEWORK.equals(extension)
+        || Constants.EXTENSION_BOOTCLASSPATH.equals(extension)) {
+      // an extension bundle must target the system bundle.
+      if (!Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(hostName)
+          && !BundleGeneration.KNOPFLERFISH_SYMBOLICNAME.equals(hostName)) {
+        throw new IllegalArgumentException("An extension bundle must target "
+            + "the system bundle(" + Constants.SYSTEM_BUNDLE_SYMBOLICNAME + " or "
+            + BundleGeneration.KNOPFLERFISH_SYMBOLICNAME + ")");
+      }
+
+      if (gen.archive.getAttribute(Constants.IMPORT_PACKAGE) != null
+          || gen.archive.getAttribute(Constants.REQUIRE_BUNDLE) != null
+          || gen.archive.getAttribute(Constants.BUNDLE_NATIVECODE) != null
+          || gen.archive.getAttribute(Constants.DYNAMICIMPORT_PACKAGE) != null
+          || gen.archive.getAttribute(Constants.BUNDLE_ACTIVATOR) != null) {
+        throw new IllegalArgumentException("An extension bundle cannot specify: "
+            + Constants.IMPORT_PACKAGE + ", " + Constants.REQUIRE_BUNDLE + ", "
+            + Constants.BUNDLE_NATIVECODE + ", " + Constants.DYNAMICIMPORT_PACKAGE + " or "
+            + Constants.BUNDLE_ACTIVATOR);
+      }
+
+      if (!gen.bundle.fwCtx.props.getBooleanProperty(Constants.SUPPORTS_FRAMEWORK_EXTENSION)
+          && Constants.EXTENSION_FRAMEWORK.equals(extension)) {
+        throw new UnsupportedOperationException(
+            "Framework extension bundles are not supported "
+                + "by this framework. Consult the documentation");
+      }
+      if (!gen.bundle.fwCtx.props.getBooleanProperty(Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION)
+          && Constants.EXTENSION_BOOTCLASSPATH.equals(extension)) {
+        throw new UnsupportedOperationException(
+            "Bootclasspath extension bundles are not supported "
+                + "by this framework. Consult the documentation");
+      }
+    } else {
+      if (extension != null) {
+        throw new IllegalArgumentException("Did not recognize directive "
+            + Constants.EXTENSION_DIRECTIVE + ":=" + extension + ".");
+      }
+    }
+    this.extension = extension;
+
+    final String range = (String) headerEntry.getAttributes()
+        .remove(Constants.BUNDLE_VERSION_ATTRIBUTE);
+    this.versionRange = range == null ? null : new VersionRange(range);
+
+    this.attributes = headerEntry.getAttributes();
+    final Filter filter = toFilter();
+    if (null!=filter) {
+      dirs.put(Constants.FILTER_DIRECTIVE, filter.toString());
+    }
+    this.directives = Collections.unmodifiableMap(dirs);
+  }
+
+
+  void addHost(BundleGeneration host) {
+    hosts.add(host);
+  }
+
+
+  void removeHost(BundleGeneration host) {
+    if (host == null) {
+      hosts.clear();
+    } else {
+      hosts.remove(host);
+    }
+  }
+
+
+  boolean isHost(BundleGeneration host) {
+    return hosts.contains(host);
+  }
+
+
+  @SuppressWarnings("unchecked")
+  Vector<BundleGeneration> getHosts() {
+    return (Vector<BundleGeneration>)hosts.clone();
+  }
+
+
+  boolean hasHosts()
+  {
+    return !hosts.isEmpty();
+  }
+
+  boolean isTarget(BundleGeneration bg)
+  {
+    return hostName.equals(bg.symbolicName)
+           && (versionRange == null || versionRange.includes(bg.version))
+           && bg.bsnAttrMatch(attributes);
+  }
+
+  List<BundleGeneration> targets()
+  {
+    final List<BundleGeneration> lbg = gen.bundle.fwCtx.bundles.getBundles(hostName,
+                                                                           versionRange);
+    for (Iterator<BundleGeneration> i = lbg.iterator(); i.hasNext();) {
+      final BundleGeneration tbg = i.next();
+      if (tbg.attachPolicy.equals(Constants.FRAGMENT_ATTACHMENT_NEVER) ||
+          !isTarget(tbg)) {
+        i.remove();
+      }
+    }
+    return lbg;
+  }
+
+  @Override
+  public String getNamespace() {
+    return BundleRevision.HOST_NAMESPACE;
+  }
+
+
+  @Override
+  public Map<String, String> getDirectives() {
+    return directives;
+  }
+
+
+  private Filter toFilter()
+  {
+    final StringBuffer sb = new StringBuffer(80);
+    boolean multipleConditions = false;
+
+    sb.append('(');
+    sb.append(BundleRevision.HOST_NAMESPACE);
+    sb.append('=');
+    if (Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(hostName)) {
+      sb.append(BundleGeneration.KNOPFLERFISH_SYMBOLICNAME);
+    } else {
+      sb.append(hostName);
+    }
+    sb.append(')');
+
+    if (versionRange != null) {
+      sb.append(versionRange.toFilterString(Constants.BUNDLE_VERSION_ATTRIBUTE));
+      multipleConditions = true;
+    }
+
+    for (final Entry<String,Object> entry : attributes.entrySet()) {
+      sb.append('(');
+      sb.append(entry.getKey());
+      sb.append('=');
+      sb.append(entry.getValue().toString());
+      sb.append(')');
+      multipleConditions |= true;
+    }
+
+    if (multipleConditions) {
+      sb.insert(0, "(&");
+      sb.append(')');
+    }
+    try {
+      return FrameworkUtil.createFilter(sb.toString());
+    } catch (final InvalidSyntaxException _ise) {
+      // Should not happen...
+      System.err.println("createFilter: '" +sb.toString() +"': " +_ise.getMessage());
+      return null;
+    }
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public Map<String, Object> getAttributes() {
+    return Collections.EMPTY_MAP;
+  }
+
+
+  @Override
+  public BundleRevision getRevision() {
+    return gen.bundleRevision;
+  }
+
+
+  @Override
+  public BundleRevision getResource() {
+    return gen.bundleRevision;
+  }
+
+
+  @Override
+  public boolean matches(BundleCapability capability) {
+    if (BundleRevision.HOST_NAMESPACE.equals(capability.getNamespace())) {
+      return toFilter().matches(capability.getAttributes());
+    }
+    return false;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java b/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java
new file mode 100644
index 0000000..a9df5c1
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FrameworkContext.java
@@ -0,0 +1,886 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+
+
+/**
+ * This class contains references to all common data structures
+ * inside the framework.
+ *
+ * @author Jan Stein, Erik Wistrand, Philippe Laporte,
+ *         Mats-Ola Persson, Gunnar Ekolin
+ */
+public class FrameworkContext  {
+
+  private static final String CONDITIONAL_PERMISSION_SECURITY_MANAGER = "org.knopflerfish.framework.permissions.ConditionalPermissionSecurityManager";
+
+  private static final String KF_SECURITY_MANAGER = "org.knopflerfish.framework.permissions.KFSecurityManager";
+
+  private static final String SECURE_PERMISSON_OPS = "org.knopflerfish.framework.SecurePermissionOps";
+
+  /**
+   * Debug handle.
+   */
+  public Debug debug;
+
+  /**
+   * All bundle in this framework.
+   */
+  Bundles bundles;
+
+  /**
+   * All listeners in this framework.
+   */
+  Listeners listeners;
+
+  /**
+   * All service hooks.
+   */
+  ServiceHooks serviceHooks;
+
+  /**
+   * All bundle hooks.
+   */
+  BundleHooks bundleHooks;
+
+  /**
+   * All resolver hooks.
+   */
+  ResolverHooks resolverHooks;
+
+  /**
+   * All weaving hooks.
+   */
+  WeavingHooks weavingHooks;
+
+
+  /**
+   * All capabilities, exported and imported packages in this framework.
+   */
+  Resolver resolver;
+
+  /**
+   * All registered services in this framework.
+   */
+  Services services;
+
+  /**
+   * PermissionOps handle.
+   */
+  PermissionOps perm;
+
+  /**
+   * System bundle
+   */
+  SystemBundle systemBundle;
+
+  /**
+   * Bundle Storage
+   */
+  BundleStorage storage;
+
+  /**
+   * Bundle Validator
+   */
+  List<Validator> validator = null;
+
+  /**
+   * Private Bundle Data Storage
+   */
+  FileTree dataStorage /*= null*/;
+
+  /**
+   * The start level controller.
+   */
+  StartLevelController startLevelController;
+
+  /**
+   * Factory for handling service-based URLs
+   */
+  ServiceURLStreamHandlerFactory urlStreamHandlerFactory;
+
+  /**
+   * Factory for handling service-based URL contents
+   */
+  ServiceContentHandlerFactory contentHandlerFactory;
+
+  /**
+   * Patterns from the boot delegation property.
+   */
+  ArrayList<String> bootDelegationPatterns;
+  boolean bootDelegationUsed /*= false*/;
+
+  /**
+   * The parent class loader for bundle classloaders.
+   */
+  ClassLoader parentClassLoader;
+
+  /**
+   * All bundle in this framework.
+   */
+  boolean firstInit = true;
+
+  /**
+   * Framework id.
+   */
+  final int id;
+
+  /**
+   * Framework init count.
+   */
+  int initCount = 0;
+
+  /**
+   * Framework properties.
+   */
+  public FWProps props;
+
+  /**
+   * Framework Thread Group.
+   */
+  public ThreadGroup threadGroup;
+
+  /**
+   * Threads for running listeners and activators
+   */
+  LinkedList<BundleThread> bundleThreads;
+
+  /**
+   * Package admin handle
+   */
+  PackageAdminImpl packageAdmin = null;
+
+  /**
+   * Mode for BSN collision checks.
+   */
+  String bsnversionMode;
+
+  /**
+   * Factory for handling service-based URLs
+   */
+  volatile static ServiceURLStreamHandlerFactory systemUrlStreamHandlerFactory;
+
+  /**
+   * Factory for handling service-based URL contents
+   */
+  volatile static ServiceContentHandlerFactory   systemContentHandlerFactory;
+
+  /**
+   * JVM global lock.
+   */
+  static Object globalFwLock = new Object();
+
+  /**
+   * Id to use for next instance of KF framework.
+   */
+  static int globalId = 0;
+
+  /**
+   * Reference counter for security manager.
+   */
+  static int smUse = 0;
+
+
+  static void setupURLStreamHandleFactory() {
+    ServiceURLStreamHandlerFactory res = new ServiceURLStreamHandlerFactory();
+    try {
+      URL.setURLStreamHandlerFactory(res);
+      systemUrlStreamHandlerFactory = res;
+    } catch (final Throwable e) {
+      System.err.println("Cannot set global URL handlers, "
+         +"continuing without OSGi service URL handler (" +e +")");
+    }
+  }
+
+
+  /**
+   * Contruct a framework context
+   *
+   */
+  FrameworkContext(Map<String, String> initProps)  {
+    synchronized (globalFwLock) {
+      id = globalId++;
+    }
+    threadGroup = new ThreadGroup("FW#" + id);
+    props = new FWProps(initProps, this);
+    perm = new PermissionOps();
+    systemBundle = new SystemBundle(this);
+    log("created");
+  }
+
+
+  /**
+   * Public method used by permissionshandling for fetching
+   * the class loader used for named class.
+   *
+   */
+  public ClassLoader getClassLoader(String clazz) {
+    if (clazz != null) {
+      final int pos = clazz.lastIndexOf('.');
+      if (pos != -1) {
+        final Pkg p = resolver.getPkg(clazz.substring(0, pos));
+        if (p != null) {
+          final ExportPkg ep = p.getBestProvider();
+          if (ep != null) {
+            return ep.bpkgs.bg.getClassLoader();
+          }
+        }
+      }
+    }
+    return systemBundle.getClassLoader();
+  }
+
+
+  /**
+   * Initialize the framework, see spec v4.2 sec 4.2.4
+   *
+   */
+  void init()
+  {
+    log("initializing");
+    initCount++;
+
+    if (firstInit && Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
+        .equals(props.getProperty(Constants.FRAMEWORK_STORAGE_CLEAN))) {
+      deleteFWDir();
+      firstInit = false;
+    }
+
+    buildBootDelegationPatterns();
+    selectBootDelegationParentClassLoader();
+
+    if (setSecurityManager()) {
+      perm = (PermissionOps) doNew(SECURE_PERMISSON_OPS);
+      systemBundle.secure = perm;
+    }
+    perm.init();
+
+    final String v = props.getProperty(FWProps.VALIDATOR_PROP);
+    if (!v.equalsIgnoreCase("none") && !v.equalsIgnoreCase("null")) {
+      validator = new ArrayList<Validator>();
+      for (int start = 0; start < v.length(); ) {
+        int end = v.indexOf(',', start);
+        if (end == -1) {
+          end = v.length();
+        }
+        final String vs = "org.knopflerfish.framework.validator." + v.substring(start, end).trim();
+        validator.add((Validator) doNew(vs));
+        start = end + 1;
+      }
+    }
+
+    if (null == urlStreamHandlerFactory) {
+      // Set up URL handlers before creating the storage
+      // implementation, with the exception of the bundle: URL
+      // handler, since this requires an intialized framework to work
+      if (props.REGISTERSERVICEURLHANDLER) {
+        // Check if we already have registered one
+        if (systemUrlStreamHandlerFactory == null) {
+          setupURLStreamHandleFactory();
+        }
+        urlStreamHandlerFactory = systemUrlStreamHandlerFactory;
+        if (systemContentHandlerFactory != null) {
+          contentHandlerFactory   = systemContentHandlerFactory;
+        } else {
+          contentHandlerFactory   = new ServiceContentHandlerFactory(this);
+          try {
+            URLConnection.setContentHandlerFactory(contentHandlerFactory);
+            systemContentHandlerFactory   = contentHandlerFactory;
+          } catch (final Throwable e) {
+            debug.printStackTrace
+              ("Cannot set global content handlers, "
+               +"continuing without OSGi service content handler (" +e +")", e);
+          }
+        }
+      } else {
+        urlStreamHandlerFactory = new ServiceURLStreamHandlerFactory();
+        contentHandlerFactory   = new ServiceContentHandlerFactory(this);
+      }
+    }
+
+    props.props.put(Constants.FRAMEWORK_UUID, getUUID());
+
+    String bsnProp = props.getProperty(Constants.FRAMEWORK_BSNVERSION).trim().toLowerCase();
+
+    if (bsnProp.equals(Constants.FRAMEWORK_BSNVERSION_MANAGED) ||
+        bsnProp.equals(Constants.FRAMEWORK_BSNVERSION_MULTIPLE) ||
+        bsnProp.equals(Constants.FRAMEWORK_BSNVERSION_SINGLE)) {
+      bsnversionMode = bsnProp;
+    } else {
+      bsnversionMode = Constants.FRAMEWORK_BSNVERSION_MANAGED;
+      debug.println("Unknown property value: " + Constants.FRAMEWORK_BSNVERSION + " = " + bsnProp);
+    }
+
+    final String storageClass = "org.knopflerfish.framework.bundlestorage." +
+      props.getProperty(FWProps.BUNDLESTORAGE_PROP) + ".BundleStorageImpl";
+    try {
+      @SuppressWarnings("unchecked")
+      final
+      Class<? extends BundleStorage> storageImpl =
+          (Class<? extends BundleStorage>) Class.forName(storageClass);
+
+      final Constructor<? extends BundleStorage> cons =
+          storageImpl.getConstructor(new Class[] { FrameworkContext.class });
+      storage = cons.newInstance(new Object[] { this });
+    } catch (final Exception e) {
+      Throwable cause = e;
+      if (e instanceof InvocationTargetException) {
+        // Use the nested exception as cause in this case.
+        cause = ((InvocationTargetException)e).getTargetException();
+      }
+      throw new RuntimeException("Failed to initialize storage "
+                                 + storageClass, cause);
+    }
+    if (props.getBooleanProperty(FWProps.READ_ONLY_PROP)) {
+      dataStorage = null;
+    } else {
+      dataStorage = Util.getFileStorage(this, "data");
+    }
+
+    BundleThread.checkWarnStopActionNotSupported(this);
+    bundleThreads = new LinkedList<BundleThread>();
+
+    resolver  = new Resolver(this);
+    listeners = new Listeners(this, perm);
+    services  = new Services(this, perm);
+
+    // Add this framework to the bundle URL handle
+    urlStreamHandlerFactory.addFramework(this);
+
+    serviceHooks = new ServiceHooks(this);
+    bundleHooks = new BundleHooks(this);
+    resolverHooks = new ResolverHooks(this);
+    weavingHooks = new WeavingHooks(this);
+
+    systemBundle.initSystemBundle();
+
+    bundles = new Bundles(this);
+
+    serviceHooks.open();
+    resolverHooks.open();
+    weavingHooks.open();
+
+    perm.registerService();
+
+    packageAdmin = new PackageAdminImpl(this);
+    @SuppressWarnings("deprecation")
+    final
+    String[] classes = new String [] { org.osgi.service.packageadmin.PackageAdmin.class.getName() };
+    services.register(systemBundle,
+                      classes,
+                      packageAdmin,
+                      null);
+
+    registerStartLevel();
+
+    bundles.load();
+
+    log("inited");
+
+    log("Installed bundles:");
+    // Use the ordering in the bundle storage to get a sorted list of bundles.
+    final BundleArchive [] allBAs = storage.getAllBundleArchives();
+    for (final BundleArchive ba : allBAs) {
+      final Bundle b = bundles.getBundle(ba.getBundleLocation());
+      log(" #" +b.getBundleId() +" " +b.getSymbolicName() +":"
+          +b.getVersion() +" location:" +b.getLocation());
+    }
+  }
+
+
+  private Object doNew(final String clazz) {
+    try {
+      final Class<?> n = (Class<?>) Class.forName(clazz);
+      final Constructor<?> nc = n.getConstructor(new Class[] { FrameworkContext.class });
+      return nc.newInstance(new Object[] { this });
+    } catch (final InvocationTargetException ite) {
+      throw new RuntimeException(clazz + ", constructor failed with, " + ite.getTargetException(), ite);
+    } catch (final NoSuchMethodException e) {
+      // If no validator, probably stripped framework
+      throw new RuntimeException(clazz + ", found no such class", e);
+    } catch (final NoClassDefFoundError ncdfe) {
+      // Validator uses class not supported by JVM ignore
+      throw new RuntimeException(clazz + ", class not supported by JVM", ncdfe);
+    } catch (final Exception e) {
+      throw new RuntimeException(clazz + ", constructor failed", e);
+    }
+  }
+
+
+  /**
+   * Undo as much as possible of what init() does.
+   *
+   */
+  void uninit()
+  {
+    log("uninit");
+    startLevelController = null;
+
+    systemBundle.uninitSystemBundle();
+
+    resolverHooks = null;
+
+    if(props.REGISTERSERVICEURLHANDLER) {
+      urlStreamHandlerFactory.removeFramework(this);
+      // Since handlers can only be registered once, keep them in this
+      // case.
+    } else {
+      urlStreamHandlerFactory = null;
+      contentHandlerFactory   = null;
+    }
+
+    bundles.clear();
+    bundles = null;
+
+    services.clear();
+    services = null;
+
+    listeners.clear();
+    listeners = null;
+
+    resolver.clear();
+    resolver = null;
+
+    synchronized (bundleThreads) {
+      while (!bundleThreads.isEmpty()) {
+        bundleThreads.remove(0).quit();
+      }
+    }
+    bundleThreads = null;
+
+    dataStorage = null;
+
+    storage.close();
+    storage = null;
+
+    perm = new PermissionOps();
+
+    synchronized (globalFwLock) {
+      if (--smUse == 0) {
+        System.setSecurityManager(null);
+      }
+    }
+
+    parentClassLoader = null;
+    bootDelegationPatterns = null;
+  }
+
+
+  /**
+   * Check and/or set security manager.
+   *
+   */
+  private boolean setSecurityManager() {
+    synchronized (globalFwLock) {
+      SecurityManager current = System.getSecurityManager();
+      final String osgiSecurity = props.getProperty(Constants.FRAMEWORK_SECURITY);
+
+      if (osgiSecurity.length() > 0) {
+        if (!Constants.FRAMEWORK_SECURITY_OSGI.equals(osgiSecurity)) {
+          throw new SecurityException("Unknown OSGi security, " + osgiSecurity);
+        }
+        if (current == null) {
+          final String POLICY_PROPERTY = "java.security.policy";
+          final String defaultPolicy
+            = this.getClass().getResource("/framework.policy").toString();
+          final String policy = System.getProperty(POLICY_PROPERTY, defaultPolicy);
+          if (debug.framework) {
+            debug.println("Installing OSGi security manager, policy="+policy);
+          }
+          System.setProperty(POLICY_PROPERTY, policy);
+          // Make sure policy is updated, required for some JVMs.
+          java.security.Policy.getPolicy().refresh();
+          current = (SecurityManager) doNew(KF_SECURITY_MANAGER);
+          System.setSecurityManager(current);
+          smUse = 1;
+        } else {
+          Class<?> cpsmc;
+          try {
+            cpsmc = Class.forName(CONDITIONAL_PERMISSION_SECURITY_MANAGER);
+          } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Missing class", e); 
+          }
+          if (cpsmc.isInstance(current)) {
+            if (smUse == 0) {
+              smUse = 2;
+            } else {
+              smUse++;
+            }
+          } else {
+            throw new SecurityException("Incompatible security manager installed");
+          }
+        }
+      }
+      return current != null;
+    }
+  }
+
+
+  /**
+   * Delete framework directory if it exists.
+   *
+   */
+  private void deleteFWDir() {
+    final String d = Util.getFrameworkDir(this);
+
+    final FileTree dir = (d != null) ? new FileTree(d) : null;
+    if (dir != null) {
+      if(dir.exists()) {
+        log("deleting old framework directory.");
+        final boolean bOK = dir.delete();
+        if(!bOK) {
+          debug.println("Failed to remove existing fwdir "
+                              +dir.getAbsolutePath());
+        }
+      }
+    }
+  }
+
+
+  private String getUUID() {
+    // We use a "pseudo" random UUID (Version 4).
+    final String sid = Integer.toHexString(id * 65536 + initCount);
+    final String baseUUID = "4e524769-3136-4b46-8000-00000000";
+    return baseUUID.substring(0, baseUUID.length() - sid.length()) + sid;
+  }
+
+
+  /**
+   * Setup start level service, if enabled.
+   *
+   */
+  private void registerStartLevel() {
+    if (props.getBooleanProperty(FWProps.STARTLEVEL_USE_PROP)) {
+      if (debug.startlevel) {
+        debug.println("[using startlevel service]");
+      }
+      startLevelController = new StartLevelController(this);
+
+      // restoreState just reads from persistent storage
+      // open() needs to be called to actually do the work
+      // This is done after framework has been launched.
+      startLevelController.restoreState();
+
+      @SuppressWarnings("deprecation")
+      final
+      String [] clsName = new String [] { org.osgi.service.startlevel.StartLevel.class.getName() };
+      services.register(systemBundle,
+                        clsName,
+                        startLevelController,
+                        null);
+    }
+  }
+
+
+  /**
+   * Get private bundle data storage file handle.
+   *
+   */
+  public FileTree getDataStorage(long id) {
+    if (dataStorage != null) {
+      return new FileTree(dataStorage, Long.toString(id));
+    }
+    return null;
+  }
+
+
+  /**
+   * Check that bundle belongs to this framework instance.
+   *
+   */
+  void checkOurBundle(Bundle b) {
+    if (b == null || !(b instanceof BundleImpl) || this != ((BundleImpl)b).fwCtx) {
+      throw new IllegalArgumentException("Bundle does not belong to this framework: " + b);
+    }
+  }
+
+
+  /**
+   * Parse boot-delegation pattern property.
+   *
+   */
+  void buildBootDelegationPatterns() {
+    final String bootDelegationString
+      = props.getProperty(Constants.FRAMEWORK_BOOTDELEGATION);
+
+    bootDelegationUsed = bootDelegationString.length() > 0;
+    bootDelegationPatterns = new ArrayList<String>(1);
+
+    if (bootDelegationUsed) {
+      try {
+        for (final HeaderEntry he : Util
+            .parseManifestHeader(Constants.FRAMEWORK_BOOTDELEGATION,
+                                 bootDelegationString, true, true, false)) {
+          final String key = he.getKey();
+          if (key.equals("*")) {
+            bootDelegationPatterns = null;
+            //in case funny person puts a * amongst other things
+            break;
+          }
+          else if (key.endsWith(".*")) {
+            bootDelegationPatterns.add(key.substring(0, key.length() - 1));
+          }
+          else if (key.endsWith(".")) {
+            frameworkError(systemBundle, new IllegalArgumentException
+                           (Constants.FRAMEWORK_BOOTDELEGATION
+                            +" entry ends with '.': " +key));
+          }
+          else if (key.indexOf("*") != - 1) {
+            frameworkError(systemBundle, new IllegalArgumentException
+                           (Constants.FRAMEWORK_BOOTDELEGATION
+                            +" entry contains a '*': " + key));
+          }
+          else {
+            bootDelegationPatterns.add(key);
+          }
+        }
+      }
+      catch (final IllegalArgumentException e) {
+        debug.printStackTrace("Failed to parse " +
+                              Constants.FRAMEWORK_BOOTDELEGATION, e);
+      }
+    }
+  }
+
+
+  /**
+   * Check if named resource is matched by the bootdelegation pattern
+   *
+   */
+  boolean isBootDelegatedResource(String name) {
+    // Convert resource name to class name format, preserving the
+    // package part of the path/name.
+    final int pos = name.lastIndexOf('/');
+    return pos != -1
+      ? isBootDelegated(name.substring(0,pos).replace('/','.')+".X")
+      : false;
+  }
+
+
+  /**
+   * Check if named class is matched by the bootdelegation pattern
+   *
+   */
+  boolean isBootDelegated(String className){
+    if(!bootDelegationUsed){
+      return false;
+    }
+    if (bootDelegationPatterns == null) {
+      return true;
+    }
+    final int pos = className.lastIndexOf('.');
+    if (pos != -1) {
+      final String classPackage = className.substring(0, pos);
+      for (final String ps : bootDelegationPatterns) {
+        if ((ps.endsWith(".") &&
+             classPackage.regionMatches(0, ps, 0, ps.length() - 1)) ||
+            classPackage.equals(ps)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * Select the parent class loader,to be used by bundle classloaders.
+   *
+   */
+  private void selectBootDelegationParentClassLoader() {
+    final String s = props.getProperty(Constants.FRAMEWORK_BUNDLE_PARENT);
+    if (Constants.FRAMEWORK_BUNDLE_PARENT_EXT.equals(s)) {
+      parentClassLoader = ClassLoader.getSystemClassLoader();
+      if (parentClassLoader != null) {
+        parentClassLoader = parentClassLoader.getParent();
+      }
+    } else if (Constants.FRAMEWORK_BUNDLE_PARENT_APP.equals(s)) {
+      parentClassLoader = ClassLoader.getSystemClassLoader();
+    } else if (Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK.equals(s)) {
+      parentClassLoader = this.getClass().getClassLoader();
+    } else {
+      parentClassLoader = Object.class.getClassLoader();
+    }
+    // If bootclassloader, wrap it
+    if (parentClassLoader == null) {
+      parentClassLoader = new BCLoader();
+    }
+  }
+
+  /**
+   * The list of active {@link ExtensionContext} instances for attached
+   * extensions with an ExtensionActivator.
+   */
+  private final List<ExtensionContext> extCtxs = new ArrayList<ExtensionContext>();
+
+  /**
+   * Create a new {@link ExtensionContext} instances for the specified
+   * extension. This will create an instance of the extension
+   * activator class and call its activate-method of.
+   *
+   * @param extension the extension bundle to activate.
+   */
+  void activateExtension(final BundleGeneration extension) {
+    extCtxs.add( new ExtensionContext(this, extension) );
+  }
+
+  /**
+   * Inform all active extension contexts about a newly created bundle
+   * class loader.
+   *
+   * @param bcl the new bundle class loader to inform about.
+   */
+  void bundleClassLoaderCreated(final BundleClassLoader bcl) {
+    for (final ExtensionContext extCtx : extCtxs) {
+      extCtx.bundleClassLoaderCreated(bcl);
+    }
+  }
+
+  /**
+   * Inform all active extension contexts about a closed down bundle
+   * class loader.
+   *
+   * @param bcl the closed down bundle class loader to inform about.
+   */
+  void bundleClassLoaderClosed(final BundleClassLoader bcl) {
+    for (final ExtensionContext extCtx : extCtxs) {
+      extCtx.bundleClassLoaderClosed(bcl);
+    }
+  }
+
+
+  /**
+   * Convenience method for throwing framework error event.
+   *
+   * @param b Bundle which caused the error.
+   * @param t Throwable generated.
+   */
+  public void frameworkError(Bundle b, Throwable t, FrameworkListener... oneTimeListeners) {
+    listeners.frameworkEvent(new FrameworkEvent(FrameworkEvent.ERROR, b, t), oneTimeListeners);
+  }
+
+
+  /**
+   * Convenience method for throwing framework error event.
+   *
+   * @param bc BundleContext for bundle which caused the error.
+   * @param t Throwable generated.
+   */
+  public void frameworkError(BundleContextImpl bc, Throwable t, FrameworkListener... oneTimeListeners) {
+    listeners.frameworkEvent(new FrameworkEvent(FrameworkEvent.ERROR, bc.bundle, t), oneTimeListeners);
+  }
+
+
+  /**
+   * Convenience method for throwing framework info event.
+   *
+   * @param b Bundle which caused the throwable.
+   * @param t Throwable generated.
+   */
+  public void frameworkInfo(Bundle b, Throwable t, FrameworkListener... oneTimeListeners) {
+    listeners.frameworkEvent(new FrameworkEvent(FrameworkEvent.INFO, b, t), oneTimeListeners);
+  }
+
+
+  /**
+   * Convenience method for throwing framework warning event.
+   *
+   * @param b Bundle which caused the throwable.
+   * @param t Throwable generated.
+   */
+  public void frameworkWarning(Bundle b, Throwable t, FrameworkListener... oneTimeListeners) {
+    listeners.frameworkEvent(new FrameworkEvent(FrameworkEvent.WARNING, b, t), oneTimeListeners);
+  }
+
+
+  /**
+   * Convenience method for throwing framework warning event.
+   *
+   * @param b Bundle which caused the throwable.
+   * @param t Throwable generated.
+   */
+  public void frameworkWarning(BundleGeneration bg, Throwable t, FrameworkListener... oneTimeListeners) {
+    frameworkWarning(bg.bundle, t, oneTimeListeners);
+  }
+
+
+  /**
+   * Log message for debugging framework
+   *
+   */
+  void log(String msg) {
+    if (debug.framework) {
+      debug.println("Framework instance " +hashCode() +": " +msg);
+    }
+  }
+
+
+  /**
+   * Log message for debugging framework
+   *
+   */
+  void log(String msg, Throwable t) {
+    if (debug.framework) {
+      debug.printStackTrace("Framework instance " +hashCode() +": "
+                                  +msg, t);
+    }
+  }
+
+
+  /**
+   * Wrapper class for BootClassLoader.
+   *
+   */
+  private static class BCLoader extends ClassLoader {
+    protected BCLoader() {
+      super(null);
+    }
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/FrameworkFactoryImpl.java b/osgi/framework/src/org/knopflerfish/framework/FrameworkFactoryImpl.java
new file mode 100644
index 0000000..4b4f308
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FrameworkFactoryImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Map;
+
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+
+public class FrameworkFactoryImpl implements FrameworkFactory {
+
+  public FrameworkFactoryImpl() {
+  }
+
+  public Framework newFramework(Map<String, String> configuration) {
+    final FrameworkContext ctx = new FrameworkContext(configuration);
+
+    return ctx.systemBundle;
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/FrameworkWiringImpl.java b/osgi/framework/src/org/knopflerfish/framework/FrameworkWiringImpl.java
new file mode 100644
index 0000000..31e6c64
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/FrameworkWiringImpl.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+public class FrameworkWiringImpl implements FrameworkWiring {
+
+  private final FrameworkContext fwCtx;
+
+  static final String SPEC_VERSION = "1.0";
+
+  FrameworkWiringImpl(FrameworkContext fwCtx) {
+    this.fwCtx = fwCtx;
+  }
+
+  public Bundle getBundle() {
+    return fwCtx.systemBundle;
+  }
+
+  public void refreshBundles(Collection<Bundle> bundles, FrameworkListener... listeners) {
+    final Bundle[] bs = bundles != null ?
+                  bundles.toArray(new Bundle[bundles.size()]) :
+                  null;
+    fwCtx.packageAdmin.refreshPackages(bs, listeners);
+  }
+
+  public boolean resolveBundles(Collection<Bundle> bundles) {
+    final Bundle[] bs = bundles != null ?
+                  bundles.toArray(new Bundle[bundles.size()]) :
+                  null;
+    return fwCtx.packageAdmin.resolveBundles(bs);
+  }
+
+  public Collection<Bundle> getRemovalPendingBundles() {
+    Set<Bundle> res = new HashSet<Bundle>();
+    fwCtx.bundles.getRemovalPendingBundles(res);
+    return res;
+  }
+
+  public Collection<Bundle> getDependencyClosure(Collection<Bundle> bundles) {
+    final HashSet<Bundle> res = new HashSet<Bundle>();
+    for (Bundle b : bundles) {
+      fwCtx.checkOurBundle(b);
+      res.add(b);
+    }
+    fwCtx.resolver.closure(res);
+    return res;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/HeaderDictionary.java b/osgi/framework/src/org/knopflerfish/framework/HeaderDictionary.java
new file mode 100644
index 0000000..03a8f25
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/HeaderDictionary.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map.Entry;
+import java.util.jar.Attributes;
+
+/**
+ * Dictionary for Bundle Manifest headers.
+ *
+ * @author Jan Stein
+ */
+public class HeaderDictionary extends Dictionary<String, String> implements Cloneable
+{
+  private final Hashtable<Attributes.Name, String> headers;
+
+  /**
+   * Create a dictionary from manifest attributes.
+   */
+  public HeaderDictionary(Attributes in) {
+    headers = new Hashtable<Attributes.Name, String>();
+    for (final Entry<Object, Object> e : in.entrySet()) {
+      headers.put((Attributes.Name)e.getKey(), (String)e.getValue());
+    }
+  }
+
+
+  /**
+   * Create a dictionary of an existing Hashtable.
+   */
+  private HeaderDictionary(Hashtable<Attributes.Name, String> t) {
+    headers = t;
+  }
+
+
+  /**
+   * Returns an enumeration of the values in this dictionary.
+   */
+  @Override
+  public Enumeration<String> elements() {
+    return headers.elements();
+  }
+
+
+  /**
+   * Returns the value to which the key is mapped in this dictionary.
+   */
+  @Override
+  public String get(Object key) {
+    return headers.get(new Attributes.Name((String)key));
+  }
+
+
+  /**
+   * Tests if this dictionary maps no keys to value.
+   */
+  @Override
+  public boolean isEmpty() {
+    return headers.isEmpty();
+  }
+
+
+  /**
+   *  Returns an enumeration of the keys in this dictionary.
+   */
+  @Override
+  public Enumeration<String> keys()
+  {
+    final Enumeration<Attributes.Name> keys = headers.keys();
+    return new Enumeration<String>() {
+      public boolean hasMoreElements()
+      {
+        return keys.hasMoreElements();
+      }
+
+      public String nextElement()
+      {
+        return keys.nextElement().toString();
+      }
+    };
+  }
+
+  /**
+   * Maps the specified key to the specified value in this dictionary.
+   */
+  @Override
+  public String put(String key, String value) {
+    return headers.put(new Attributes.Name(key), value);
+  }
+
+
+  /**
+   * Removes the key (and its corresponding value) from this dictionary.
+   */
+  @Override
+  public String remove(Object key) {
+    return headers.remove(new Attributes.Name((String)key));
+  }
+
+
+  /**
+   * Returns the number of entries (distinct keys) in this dictionary.
+   */
+  @Override
+  public int size() {
+    return headers.size();
+  }
+
+  /**
+   * Clone
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public Object clone() {
+    return new HeaderDictionary((Hashtable<Attributes.Name, String>)headers.clone());
+  }
+
+  @SuppressWarnings("unchecked")
+  HeaderDictionary cloneHD() {
+    return new HeaderDictionary((Hashtable<Attributes.Name, String>)headers.clone());
+  }
+
+
+  @Override
+  public String toString() {
+    return headers.toString();
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ImportPkg.java b/osgi/framework/src/org/knopflerfish/framework/ImportPkg.java
new file mode 100644
index 0000000..ce8f6bd
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ImportPkg.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2005-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+
+/**
+ * Data structure for import package definitions.
+ *
+ * @author Jan Stein, Gunnar Ekolin
+ */
+class ImportPkg implements BundleRequirement, Comparable<ImportPkg> {
+
+  /**
+   * The value of the resolution directive for dynamically imported packages.
+   */
+  static final String RESOLUTION_DYNAMIC = "dynamic";
+
+  @SuppressWarnings("deprecation")
+  private static final String PACKAGE_SPECIFICATION_VERSION = Constants.PACKAGE_SPECIFICATION_VERSION;
+
+  // To maintain the creation order in the osgi.wiring.package name space.
+  static private int importPkgCount = 0;
+
+  final int orderal = ++importPkgCount;
+
+  final String name;
+  final BundlePackages bpkgs;
+  final String resolution;
+  final String bundleSymbolicName;
+  final VersionRange packageRange;
+  final VersionRange bundleRange;
+  final Map<String,Object> attributes;
+  final Map<String,String> directives;
+  final ImportPkg parent;
+
+  // Link to pkg entry
+  Pkg pkg = null;
+
+  // Link to exporter
+  ExportPkg provider = null;
+  // Link to interal exporter ok to use
+  ExportPkg internalOk = null;
+
+  // Ordering of dynamic imports
+  int dynId = 0;
+
+
+  /**
+   * Create an import package entry from manifest parser data.
+   *
+   * @param name the name of the package to be imported.
+   * @param he the parsed import package statement.
+   * @param b back link to the bundle revision owning this import declaration.
+   * @param dynamic Set to true if this is a dynamic import package declaration.
+   */
+  ImportPkg(final String name, final HeaderEntry he, final BundlePackages b,
+            boolean dynamic)
+  {
+    this.bpkgs = b;
+    this.name = name;
+    if (name.startsWith("java.")) {
+      throw new IllegalArgumentException("You can not import a java.* package");
+    }
+    final Map<String, String> dirs = he.getDirectives();
+    final String res = dirs.get(Constants.RESOLUTION_DIRECTIVE);
+    if (dynamic) {
+      if (res != null) {
+        throw new IllegalArgumentException("Directives not supported for "
+                                           + "Dynamic-Import, found "
+                                           + Constants.RESOLUTION_DIRECTIVE
+                                           + ":=" +res);
+      }
+      this.resolution = RESOLUTION_DYNAMIC;
+    } else {
+      if (res != null) {
+        if (Constants.RESOLUTION_OPTIONAL.equals(res)) {
+          this.resolution = Constants.RESOLUTION_OPTIONAL;
+        } else if (Constants.RESOLUTION_MANDATORY.equals(res)) {
+          this.resolution = Constants.RESOLUTION_MANDATORY;
+        } else {
+          throw new IllegalArgumentException("Directive " + Constants.RESOLUTION_DIRECTIVE +
+                                             ", unexpected value: " + res);
+        }
+      } else {
+        this.resolution = Constants.RESOLUTION_MANDATORY;
+      }
+    }
+    this.bundleSymbolicName = (String) he.getAttributes()
+        .remove(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+    final String versionStr = (String) he.getAttributes()
+        .remove(Constants.VERSION_ATTRIBUTE);
+    final String specVersionStr = (String) he.getAttributes()
+        .remove(PACKAGE_SPECIFICATION_VERSION);
+    if (specVersionStr != null) {
+      this.packageRange = new VersionRange(specVersionStr);
+      if (versionStr != null && !this.packageRange.equals(new VersionRange(versionStr))) {
+        throw new IllegalArgumentException("Both " + Constants.VERSION_ATTRIBUTE +
+                                           " and " + PACKAGE_SPECIFICATION_VERSION +
+                                           " are specified, but differs");
+      }
+    } else if (versionStr != null) {
+      this.packageRange = new VersionRange(versionStr);
+    } else {
+      this.packageRange = null;
+    }
+    final String rangeStr = (String) he.getAttributes()
+        .remove(Constants.BUNDLE_VERSION_ATTRIBUTE);
+    if (rangeStr != null) {
+      this.bundleRange = new VersionRange(rangeStr);
+    } else {
+      this.bundleRange = null;
+    }
+    this.attributes = Collections.unmodifiableMap(he.getAttributes());
+    final Filter filter = toFilter();
+    if (null!=filter) {
+      dirs.put(Constants.FILTER_DIRECTIVE, filter.toString());
+    }
+    this.directives = Collections.unmodifiableMap(dirs);
+    this.parent = null;
+  }
+
+
+  /**
+   * Create an import package entry with a new name from an import template.
+   */
+  ImportPkg(ImportPkg ip, String name) {
+    this.name = name;
+    this.bpkgs = ip.bpkgs;
+    this.resolution = ip.resolution;
+    this.bundleSymbolicName = ip.bundleSymbolicName;
+    this.packageRange = ip.packageRange;
+    this.bundleRange = ip.bundleRange;
+    this.attributes = ip.attributes;
+    this.directives = ip.directives;
+    this.parent = ip;
+  }
+
+
+  /**
+   * Creates an import package entry with a new host bundle.
+   */
+  ImportPkg(ImportPkg ip, BundlePackages bpkgs) {
+    this.name = ip.name;
+    this.bpkgs = bpkgs;
+    this.resolution = ip.resolution;
+    this.bundleSymbolicName = ip.bundleSymbolicName;
+    this.packageRange = ip.packageRange;
+    this.bundleRange = ip.bundleRange;
+    this.attributes = ip.attributes;
+    this.directives = ip.directives;
+    this.parent = ip.parent;
+  }
+
+
+  /**
+   * Create an import package entry.
+   */
+  ImportPkg(ExportPkg p) {
+    this.name = p.name;
+    this.bpkgs = p.bpkgs;
+    this.resolution = Constants.RESOLUTION_MANDATORY;
+    this.bundleSymbolicName = null;
+    if (p.version == Version.emptyVersion) {
+      this.packageRange = null;
+    } else {
+      this.packageRange = new VersionRange(p.version.toString());
+    }
+    this.bundleRange = null;
+    this.attributes = p.attributes;
+    // TODO, should we import unknown directives?
+    final Map<String,String> dirs = new HashMap<String, String>();
+    final Filter filter = toFilter();
+    if (null!=filter) {
+      dirs.put(Constants.FILTER_DIRECTIVE, filter.toString());
+    }
+    this.directives = Collections.unmodifiableMap(dirs);
+    this.parent = null;
+  }
+
+
+  /**
+   * Attach this to a Pkg object which indicate that it is a valid importer.
+   */
+  void attachPkg(Pkg p) {
+    pkg = p;
+  }
+
+
+  /**
+   * Detach this from a Pkg object which indicate that it is no longer valid.
+   */
+  void detachPkg() {
+    pkg = null;
+    provider = null;
+  }
+
+
+  /**
+   * Check if version fulfills import package constraints.
+   *
+   * @param ver Version to compare to.
+   * @return Return 0 if equals, negative if this object is less than obj and
+   *         positive if this object is larger then obj.
+   */
+  public boolean okPackageVersion(Version ver) {
+    return packageRange == null || packageRange.includes(ver);
+  }
+
+
+  /**
+   * Check that all package attributes match.
+   *
+   * @param ep Exported package.
+   * @return True if okay, otherwise false.
+   */
+  boolean checkAttributes(ExportPkg ep) {
+    /* Mandatory attributes */
+    if (!checkMandatory(ep.mandatory)) {
+      return false;
+    }
+    /* Predefined attributes */
+    if (!okPackageVersion(ep.version) ||
+        (bundleSymbolicName != null &&
+         !bundleSymbolicName.equals(ep.bpkgs.bg.symbolicName)) ||
+         (bundleRange != null &&
+         !bundleRange.includes(ep.bpkgs.bg.version))) {
+      return false;
+    }
+    /* Other attributes */
+    for (final Entry<String,Object> entry : attributes.entrySet()) {
+      final String a = (String) ep.attributes.get(entry.getKey());
+      if (a == null || !a.equals(entry.getValue())) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  /**
+   * Check that we have import permission for exported package.
+   *
+   * @param ep Exported package.
+   * @return True if okay, otherwise false.
+   */
+  boolean checkPermission(ExportPkg ep) {
+    return bpkgs.bg.bundle.fwCtx.perm.hasImportPackagePermission(bpkgs.bg.bundle, ep);
+  }
+
+
+  /**
+   * Check that we can do an internal wire to the exported package.
+   *
+   * @return True if okay, otherwise false.
+   */
+  boolean mustBeResolved() {
+    return resolution == Constants.RESOLUTION_MANDATORY && internalOk == null;
+  }
+
+
+  /**
+   * Check that we intersect specified ImportPkg.
+   *
+   * @param ip ImportPkg to check.
+   * @return True if we overlap, otherwise false.
+   */
+  boolean intersect(ImportPkg ip) {
+    if (ip.bundleSymbolicName != null && bundleSymbolicName != null &&
+        !ip.bundleSymbolicName.equals(bundleSymbolicName)) {
+      return false;
+    }
+
+    // Check that no other attributes conflict
+    for (final Entry<String,Object> entry : attributes.entrySet()) {
+      final String a = (String) ip.attributes.get(entry.getKey());
+      if (a != null && !a.equals(entry.getValue())) {
+        return false;
+      }
+    }
+
+    // Resolution doesn't need to be checked.
+    // This is handle when resolving package.
+    // If one import is mandatory then all must match.
+
+    if (packageRange != null && packageRange.intersection(ip.packageRange).isEmpty()) {
+      return false;
+    }
+    return bundleRange == null || !bundleRange.intersection(ip.bundleRange).isEmpty();
+  }
+
+
+  /**
+   * String describing package name and specification version, if specified.
+   *
+   * @return String.
+   */
+  public String pkgString() {
+    // NYI! More info?
+    if (packageRange != null) {
+      return name + ";" + Constants.VERSION_ATTRIBUTE + "=" + packageRange;
+    } else {
+      return name;
+    }
+  }
+
+
+  /**
+   * String describing this object.
+   *
+   * @return String.
+   */
+  @Override
+  public String toString() {
+    return pkgString() + "(" + bpkgs.bg.bundle + ")";
+  }
+
+
+  boolean isDynamic() {
+    return resolution == RESOLUTION_DYNAMIC;
+  }
+
+
+  /**
+   * Check that we have all mandatory attributes.
+   *
+   * @param mandatory Collection of mandatory attribute.
+   * @return Return true if we have all mandatory attributes, otherwise false.
+   */
+  private boolean checkMandatory(final Collection<String> mandatory) {
+    if (mandatory != null) {
+      for (final String a : mandatory) {
+        if (Constants.VERSION_ATTRIBUTE.equals(a)) {
+          if (packageRange == null) {
+            return false;
+          }
+        } else if (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equals(a)) {
+          if (bundleSymbolicName == null) {
+            return false;
+          }
+        } else if (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(a)) {
+          if (bundleRange == null) {
+            return false;
+          }
+        } else if (!attributes.containsKey(a)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public String getNamespace() {
+    return BundleRevision.PACKAGE_NAMESPACE;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public Map<String, String> getDirectives() {
+    return directives;
+  }
+
+
+  private Filter toFilter()
+  {
+    final StringBuffer sb = new StringBuffer(80);
+    boolean multipleConditions = false;
+
+    sb.append('(');
+    sb.append(BundleRevision.PACKAGE_NAMESPACE);
+    sb.append('=');
+    sb.append(name);
+    if (name.length()==0 || name.endsWith(".")) {
+      // Dynamic import with wild-card.
+      sb.append('*');
+    }
+    sb.append(')');
+
+    if (packageRange != null) {
+      sb.append(packageRange.toFilterString(Constants.VERSION_ATTRIBUTE));
+      multipleConditions = true;
+    }
+
+    if (bundleSymbolicName != null) {
+      sb.append('(');
+      sb.append(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+      sb.append('=');
+      sb.append(bundleSymbolicName);
+      sb.append(')');
+      multipleConditions |= true;
+    }
+
+    if (bundleRange != null) {
+      sb.append(bundleRange.toFilterString(Constants.BUNDLE_VERSION_ATTRIBUTE));
+      multipleConditions = true;
+    }
+
+    for (final Entry<String,Object> entry : attributes.entrySet()) {
+      sb.append('(');
+      sb.append(entry.getKey());
+      sb.append('=');
+      sb.append(entry.getValue().toString());
+      sb.append(')');
+      multipleConditions |= true;
+    }
+
+    if (multipleConditions) {
+      sb.insert(0, "(&");
+      sb.append(')');
+    }
+    try {
+      return FrameworkUtil.createFilter(sb.toString());
+    } catch (final InvalidSyntaxException _ise) {
+      // Should not happen...
+      System.err.println("createFilter: '" +sb.toString() +"': " +_ise.getMessage());
+      return null;
+    }
+  }
+
+  // BundleRequirement method
+  @Override
+ public Map<String, Object> getAttributes() {
+    @SuppressWarnings("unchecked")
+    final
+    Map<String, Object> res = Collections.EMPTY_MAP;
+    return res;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public BundleRevision getRevision() {
+    return bpkgs.bg.bundleRevision;
+  }
+
+
+  @Override
+  public BundleRevision getResource() {
+    return bpkgs.bg.bundleRevision;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public boolean matches(BundleCapability capability) {
+    if (BundleRevision.PACKAGE_NAMESPACE.equals(capability.getNamespace())) {
+      return toFilter().matches(capability.getAttributes());
+    }
+    return false;
+  }
+
+
+  /**
+   * The default ordering is the order in which the {@code ImportPkg}-objects
+   * has been created. I.e., the order they appeared in the {@code Import-Package}
+   * header.
+   *
+   * @param o other object to compare with.
+   * @return Less than zero, zero or greater than zero of this object is smaller
+   *  than, equals to or greater than {@code o}.
+   */
+  @Override
+  public int compareTo(ImportPkg o)
+  {
+    return this.orderal - o.orderal;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/IteratorIterator.java b/osgi/framework/src/org/knopflerfish/framework/IteratorIterator.java
new file mode 100644
index 0000000..0131640
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/IteratorIterator.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.*;
+
+/**
+ * Meta Iterator
+ *
+ * @author Jan Stein
+ */
+public class IteratorIterator<A> implements Iterator<A>
+{
+
+  final private Iterator<Iterator<A>> iter;
+  /* The current iterator */
+  private Iterator<A> current = null;
+
+  public  IteratorIterator(List<Iterator<A>> ilist) {
+    iter = ilist.iterator();
+    if (iter.hasNext()) {
+      current = iter.next();
+    } else {
+      // We need an empty iterator as current, reuse iter.
+      @SuppressWarnings("unchecked")
+      Iterator<A> empty = (Iterator<A>) iter;
+      current = empty;
+    }
+  }
+
+
+  public boolean hasNext() {
+    return getIterator().hasNext();
+  }
+
+  public void remove() {
+    current.remove();
+  }
+
+  public A next() {
+    return getIterator().next();
+  }
+
+
+  private Iterator<A> getIterator() {
+    while (!current.hasNext() && iter.hasNext()) {
+      current = iter.next();
+    }
+    return current;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/IteratorIteratorSorted.java b/osgi/framework/src/org/knopflerfish/framework/IteratorIteratorSorted.java
new file mode 100644
index 0000000..5fad604
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/IteratorIteratorSorted.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.*;
+
+/**
+ * Meta Iterator that takes sorted list and returns
+ * a sorted result.
+ *
+ * @author Jan Stein
+ */
+public class IteratorIteratorSorted<A> implements Iterator<A>
+{
+
+  final private Iterator<A> [] iter;
+  final private A [] top;
+  final private Util.Comparator<A,A> comp;
+  int size;
+
+  public  IteratorIteratorSorted(List<Iterator<A>> ilist, Util.Comparator<A,A> comp) {
+    this.comp = comp;
+    size = ilist.size();
+    @SuppressWarnings("unchecked")
+    Iterator<A> [] iters = new Iterator [size + 1];
+    iter = iters;
+    @SuppressWarnings("unchecked")
+    A[] topA = (A[]) new Object[size + 1];
+    top = topA;
+    int pos = 1;
+    for (Iterator<Iterator<A>> i = ilist.iterator(); i.hasNext(); ) {
+      Iterator<A> si = i.next();
+      if (si.hasNext()) {
+        top[pos] = si.next();
+        iter[pos++] = si;
+      } else {
+        size--;
+      }
+    }
+    for (pos = size / 2; pos > 0; pos--) {
+      balance(pos);
+    }
+  }
+
+
+  public boolean hasNext() {
+    return size > 0;
+  }
+
+  public void remove() {
+    throw new UnsupportedOperationException();
+  }
+
+  public A next() {
+    if (hasNext()) {
+      A res = top[1];
+      if (iter[1].hasNext()) {
+        top[1] = iter[1].next();
+      } else {
+        top[1] = top[size];
+        iter[1] = iter[size--];
+      }
+      balance(1);
+      return res;
+    }
+    throw new NoSuchElementException();
+  }
+
+  /**
+   * Balance heap.
+   */
+  private void balance(int current) {
+    A tmp = top[current];
+    Iterator<A> itmp = iter[current];
+
+    int child;
+    while (current * 2 <= size) {
+      child = current * 2;
+      if (child != size && comp.compare(top[child + 1], top[child]) > 0) {
+        child++;
+      }
+      if (comp.compare(top[child], tmp) > 0) {
+        top[current] = top[child];
+        iter[current] = iter[child];
+      } else {
+        break;
+      }
+      current = child;
+    }
+    top[current] = tmp;
+    iter[current] = itmp;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/LDAPExpr.java b/osgi/framework/src/org/knopflerfish/framework/LDAPExpr.java
new file mode 100644
index 0000000..01b24b8
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/LDAPExpr.java
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class LDAPExpr {
+  public static final int AND = 0;
+  public static final int OR = 1;
+  public static final int NOT = 2;
+  public static final int EQ = 4;
+  public static final int LE = 8;
+  public static final int GE = 16;
+  public static final int APPROX = 32;
+  public static final int COMPLEX = AND | OR | NOT;
+  public static final int SIMPLE = EQ | LE | GE | APPROX;
+
+  private static final char WILDCARD = 65535;
+  private static final String WILDCARD_STRING = new String(new char[] { WILDCARD });
+
+  private static final String NULL = "Null query";
+  private static final String GARBAGE = "Trailing garbage";
+  private static final String EOS = "Unexpected end of query";
+  private static final String MALFORMED = "Malformed query";
+  private static final String OPERATOR = "Undefined operator";
+
+  private static Class<?> classBigDecimal;
+  private static Constructor<?> consBigDecimal;
+  private static Method compBigDecimal;
+
+  private static Class<?> classBigInteger;
+  private static Constructor<?> consBigInteger;
+  private static Method compBigInteger;
+
+  public int operator;
+  public LDAPExpr[] args;
+  public String attrName;
+  public String attrValue;
+
+
+  public LDAPExpr(String filter) throws InvalidSyntaxException {
+
+    final ParseState ps = new ParseState(filter);
+    LDAPExpr expr = null;
+    try {
+      expr = parseExpr(ps);
+    } catch (final StringIndexOutOfBoundsException e) {
+      ps.error(EOS);
+    }
+    if (ps.rest().trim().length() != 0)
+      ps.error(GARBAGE + " '" + ps.rest() + "'");
+    operator = expr.operator;
+    args = expr.args;
+    attrName = expr.attrName;
+    attrValue = expr.attrValue;
+  }
+
+
+  private LDAPExpr(int operator, LDAPExpr[] args) {
+    this.operator = operator;
+    this.args = args;
+    this.attrName = null;
+    this.attrValue = null;
+  }
+
+
+  private LDAPExpr(int operator, String attrName, String attrValue) {
+    this.operator = operator;
+    this.args = null;
+    this.attrName = attrName;
+    this.attrValue = attrValue;
+  }
+
+
+  /**
+   * Get a set of object classes that might match this LDAP expression. This will not work
+   * with wildcards and NOT expressions. If a set can not be determined return
+   * null - meaning that all object classes must be considered when looking for matches.
+   *
+   * @return A set of classes that might match, otherwise <code>null</code>.
+   */
+  public Set<String> getMatchedObjectClasses() {
+    Set<String> objClasses = null;
+    if (operator == EQ) {
+      if (attrName.equalsIgnoreCase(Constants.OBJECTCLASS) && attrValue.indexOf(WILDCARD) < 0) {
+        objClasses = new OneSet<String>(attrValue);
+      }
+    } else if (operator == AND) {
+      for (final LDAPExpr arg : args) {
+        final Set<String> r = arg.getMatchedObjectClasses();
+        if (r != null) {
+          if (objClasses == null) {
+            objClasses = new TreeSet<String>();
+          }
+          objClasses.addAll(r);
+        }
+      }
+    } else if (operator == OR) {
+      for (final LDAPExpr arg : args) {
+        final Set<String> r = arg.getMatchedObjectClasses();
+        if (r != null) {
+          if (objClasses == null) {
+            objClasses = new TreeSet<String>();
+          }
+          objClasses.addAll(r);
+        } else {
+          objClasses = null;
+          break;
+        }
+      }
+    }
+    return objClasses;
+  }
+
+
+  /**
+   * Checks if this LDAP expression is "simple". The definition of a simple
+   * filter is:
+   * <ul>
+   * <li>{@code (<it>name</it>=<it>value</it>)} is simple if <it>name</it>
+   * is a member of the provided {@code keywords}, and <it>value</it> does
+   * not contain a wildcard character;</li>
+   * <li>{@code (| EXPR+ )} is simple if all {@code EXPR} expressions
+   * are simple;</li>
+   * <li>No other expressions are simple.</li>
+   * </ul>
+   * If the filter is found to be simple, the {@code cache} is filled with
+   * mappings from the provided keywords to lists of attribute values. The
+   * keyword-value-pairs are the ones that satisfy this expression, for the
+   * given keywords.
+   *
+   * @param keywords The keywords to look for.
+   * @param cache An array (indexed by the keyword indexes) of lists to fill in
+   *          with values saturating this expression.
+   * @return {@code true} if this expression is simple, {@code false}
+   *         otherwise.
+   */
+  public boolean isSimple(List<String> keywords, List<Object>[] cache, boolean matchCase) {
+    if (operator == EQ) {
+      int index;
+      if ((index = keywords.indexOf(matchCase ? attrName : attrName.toLowerCase())) >= 0
+          && attrValue.indexOf(WILDCARD) < 0) {
+        if (cache[index] == null) {
+          cache[index] = new ArrayList<Object>();
+        }
+        cache[index].add(attrValue);
+        return true;
+      }
+    } else if (operator == OR) {
+      for (int i = 0; i < args.length; i++) {
+        if (!args[i].isSimple(keywords, cache, matchCase))
+          return false;
+      }
+      return true;
+    }
+    return false;
+  }
+
+
+  public static boolean query(String filter, Dictionary<String, Object> pd)
+      throws InvalidSyntaxException
+  {
+    return new LDAPExpr(filter).evaluate(pd, false);
+  }
+
+  /**
+   * Evaluate this LDAP filter.
+   */
+  public boolean evaluate(Dictionary<String, ?> p, boolean matchCase) {
+    if ((operator & SIMPLE) != 0) {
+      return compare(p.get(matchCase ? attrName : attrName.toLowerCase()), operator, attrValue);
+    } else { // (operator & COMPLEX) != 0
+      switch (operator) {
+      case AND:
+        for (int i = 0; i < args.length; i++) {
+          if (!args[i].evaluate(p, matchCase))
+            return false;
+        }
+        return true;
+      case OR:
+        for (final LDAPExpr arg : args) {
+          if (arg.evaluate(p, matchCase))
+            return true;
+        }
+        return false;
+      case NOT:
+        return !args[0].evaluate(p, matchCase);
+      default:
+        return false; // Cannot happen
+      }
+    }
+  }
+
+
+  /**** Private methods ****/
+
+  protected boolean compare(Object obj, int op, String s) {
+    if (obj == null)
+      return false;
+    if (op == EQ && s.equals(WILDCARD_STRING))
+      return true;
+    try {
+      if (obj instanceof String) {
+        return compareString((String)obj, op, s);
+      } else if (obj instanceof Character) {
+        return compareString(obj.toString(), op, s);
+      } else if (obj instanceof Boolean) {
+        if (op == LE || op == GE)
+          return false;
+        if (((Boolean)obj).booleanValue()) {
+          return s.equalsIgnoreCase("true");
+        } else {
+          return s.equalsIgnoreCase("false");
+        }
+      } else if (obj instanceof Number) {
+        if (obj instanceof Byte) {
+          switch (op) {
+          case LE:
+            return ((Byte)obj).byteValue() <= Byte.parseByte(s);
+          case GE:
+            return ((Byte)obj).byteValue() >= Byte.parseByte(s);
+          default: /* APPROX and EQ */
+            return (new Byte(s)).equals(obj);
+          }
+        } else if (obj instanceof Integer) {
+          switch (op) {
+          case LE:
+            return ((Integer)obj).intValue() <= Integer.parseInt(s);
+          case GE:
+            return ((Integer)obj).intValue() >= Integer.parseInt(s);
+          default: /* APPROX and EQ */
+            return (new Integer(s)).equals(obj);
+          }
+        } else if (obj instanceof Short) {
+          switch (op) {
+          case LE:
+            return ((Short)obj).shortValue() <= Short.parseShort(s);
+          case GE:
+            return ((Short)obj).shortValue() >= Short.parseShort(s);
+          default: /* APPROX and EQ */
+            return (new Short(s)).equals(obj);
+          }
+        } else if (obj instanceof Long) {
+          switch (op) {
+          case LE:
+            return ((Long)obj).longValue() <= Long.parseLong(s);
+          case GE:
+            return ((Long)obj).longValue() >= Long.parseLong(s);
+          default: /* APPROX and EQ */
+            return (new Long(s)).equals(obj);
+          }
+        } else if (obj instanceof Float) {
+          switch (op) {
+          case LE:
+            return ((Float)obj).floatValue() <= (new Float(s)).floatValue();
+          case GE:
+            return ((Float)obj).floatValue() >= (new Float(s)).floatValue();
+          default: /* APPROX and EQ */
+            return (new Float(s)).equals(obj);
+          }
+        } else if (obj instanceof Double) {
+          switch (op) {
+          case LE:
+            return ((Double)obj).doubleValue() <= (new Double(s)).doubleValue();
+          case GE:
+            return ((Double)obj).doubleValue() >= (new Double(s)).doubleValue();
+          default: /* APPROX and EQ */
+            return (new Double(s)).equals(obj);
+          }
+        } else if (classBigInteger != null && classBigInteger.isInstance(obj)) {
+          final Object n = consBigInteger.newInstance(new Object[] { s });
+          final int c = ((Integer)compBigInteger.invoke(obj, new Object[] { n })).intValue();
+
+          switch (op) {
+          case LE:
+            return c <= 0;
+          case GE:
+            return c >= 0;
+          default: /* APPROX and EQ */
+            return c == 0;
+          }
+        } else if (classBigDecimal != null && classBigDecimal.isInstance(obj)) {
+          final Object n = consBigDecimal.newInstance(new Object[] { s });
+          final int c = ((Integer)compBigDecimal.invoke(obj, new Object[] { n })).intValue();
+
+          switch (op) {
+          case LE:
+            return c <= 0;
+          case GE:
+            return c >= 0;
+          default: /* APPROX and EQ */
+            return c == 0;
+          }
+        }
+      } else if (obj instanceof Collection) {
+        for (final Object name : ((Collection<?>) obj))
+          if (compare(name, op, s))
+            return true;
+      } else if (obj.getClass().isArray()) {
+        final int len = Array.getLength(obj);
+        for (int i = 0; i < len; i++)
+          if (compare(Array.get(obj, i), op, s))
+            return true;
+      } else {
+        // Extended comparison
+        // Allow simple EQ comparison on all classes having
+        // a string constructor, and use compareTo if they
+        // implement Comparable
+        final Class<?> clazz = obj.getClass();
+        final Constructor<?> cons = getConstructor(clazz);
+
+        if (cons != null) {
+          final Object other = cons.newInstance(new Object[] { s });
+          if (obj instanceof Comparable) {
+            @SuppressWarnings({ "unchecked" })
+            final int c = ((Comparable<Object>)obj).compareTo(other);
+            switch (op) {
+            case LE:
+              return c <= 0;
+            case GE:
+              return c >= 0;
+            default: /* APPROX and EQ */
+              return c == 0;
+            }
+          } else {
+            boolean b = false;
+            if (op == LE || op == GE || op == EQ || op == APPROX) {
+              b = obj.equals(other);
+            }
+            return b;
+          }
+        }
+      }
+    } catch (final Exception ignored_but_evals_to_false) {
+      // This might happen if a string-to-datatype conversion fails
+      // Just consider it a false match and ignore the exception
+    }
+    return false;
+  }
+
+  // Clazz -> Constructor(String)
+  private static HashMap<Class<?>, Constructor<?>> constructorMap
+    = new HashMap<Class<?>, Constructor<?>>();
+
+
+  /**
+   * Get cached String constructor for a class
+   */
+  private static Constructor<?> getConstructor(Class<?> clazz) {
+    synchronized (constructorMap) {
+
+      // This might be null
+      Constructor<?> cons = constructorMap.get(clazz);
+
+      // ...check if we have tried before. A failed try
+      // is stored as null
+      if (!constructorMap.containsKey(clazz)) {
+        try {
+          cons = clazz.getConstructor(new Class[] { String.class });
+        } catch (final Exception e) {
+          // remember by storing null in map
+        }
+        constructorMap.put(clazz, cons);
+      }
+      return cons;
+    }
+  }
+
+  static {
+    try {
+      classBigDecimal = Class.forName("java.math.BigDecimal");
+      consBigDecimal = getConstructor(classBigDecimal);
+      compBigDecimal = classBigDecimal.getMethod("compareTo", new Class[] { classBigDecimal });
+    } catch (final Exception ignore) {
+      classBigDecimal = null;
+    }
+    try {
+      classBigInteger = Class.forName("java.math.BigInteger");
+      consBigInteger = getConstructor(classBigInteger);
+      compBigInteger = classBigInteger.getMethod("compareTo", new Class[] { classBigInteger });
+    } catch (final Exception ignore) {
+      classBigInteger = null;
+    }
+  }
+
+
+  private static boolean compareString(String s1, int op, String s2) {
+    switch (op) {
+    case LE:
+      return s1.compareTo(s2) <= 0;
+    case GE:
+      return s1.compareTo(s2) >= 0;
+    case EQ:
+      return patSubstr(s1, s2);
+    case APPROX:
+      return fixupString(s2).equals(fixupString(s1));
+    default:
+      return false;
+    }
+  }
+
+
+  private static String fixupString(String s) {
+    final StringBuffer sb = new StringBuffer();
+    final int len = s.length();
+    for (int i = 0; i < len; i++) {
+      char c = s.charAt(i);
+      if (!Character.isWhitespace(c)) {
+        if (Character.isUpperCase(c))
+          c = Character.toLowerCase(c);
+        sb.append(c);
+      }
+    }
+    return sb.toString();
+  }
+
+
+  private static boolean patSubstr(String s, String pat) {
+    return s == null ? false : patSubstr(s.toCharArray(), 0, pat.toCharArray(), 0);
+  }
+
+
+  private static boolean patSubstr(char[] s, int si, char[] pat, int pi) {
+    if (pat.length - pi == 0)
+      return s.length - si == 0;
+    if (pat[pi] == WILDCARD) {
+      pi++;
+      for (;;) {
+        if (patSubstr(s, si, pat, pi))
+          return true;
+        if (s.length - si == 0)
+          return false;
+        si++;
+      }
+    } else {
+      if (s.length - si == 0) {
+        return false;
+      }
+      if (s[si] != pat[pi]) {
+        return false;
+      }
+      return patSubstr(s, ++si, pat, ++pi);
+    }
+  }
+
+
+  private static LDAPExpr parseExpr(ParseState ps) throws InvalidSyntaxException {
+    ps.skipWhite();
+    if (!ps.prefix("("))
+      ps.error(MALFORMED);
+
+    int operator;
+    ps.skipWhite();
+    switch (ps.peek()) {
+    case '&':
+      operator = AND;
+      break;
+    case '|':
+      operator = OR;
+      break;
+    case '!':
+      operator = NOT;
+      break;
+    default:
+      return parseSimple(ps);
+    }
+    ps.skip(1); // Ignore the operator
+    final List<LDAPExpr> v = new ArrayList<LDAPExpr>();
+    do {
+      v.add(parseExpr(ps));
+      ps.skipWhite();
+    } while (ps.peek() == '(');
+    final int n = v.size();
+    if (!ps.prefix(")") || n == 0 || (operator == NOT && n > 1))
+      ps.error(MALFORMED);
+    final LDAPExpr[] args = new LDAPExpr[n];
+    v.toArray(args);
+    return new LDAPExpr(operator, args);
+  }
+
+
+  private static LDAPExpr parseSimple(ParseState ps) throws InvalidSyntaxException {
+    final String attrName = ps.getAttributeName();
+    if (attrName == null)
+      ps.error(MALFORMED);
+    int operator = 0;
+    if (ps.prefix("="))
+      operator = EQ;
+    else if (ps.prefix("<="))
+      operator = LE;
+    else if (ps.prefix(">="))
+      operator = GE;
+    else if (ps.prefix("~="))
+      operator = APPROX;
+    else {
+      // System.out.println("undef op='" + ps.peek() + "'");
+      ps.error(OPERATOR); // Does not return
+    }
+    final String attrValue = ps.getAttributeValue();
+    if (!ps.prefix(")"))
+      ps.error(MALFORMED);
+    return new LDAPExpr(operator, attrName, attrValue);
+  }
+
+
+  @Override
+  public String toString() {
+    final StringBuffer res = new StringBuffer();
+    res.append("(");
+    if ((operator & SIMPLE) != 0) {
+      res.append(attrName);
+      switch (operator) {
+      case EQ:
+        res.append("=");
+        break;
+      case LE:
+        res.append("<=");
+        break;
+      case GE:
+        res.append(">=");
+        break;
+      case APPROX:
+        res.append("~=");
+        break;
+      }
+      for (int i = 0; i < attrValue.length(); i++) {
+        char c = attrValue.charAt(i);
+        if (c == '(' || c == ')' || c == '*' || c == '\\') {
+          res.append('\\');
+        } else if (c == WILDCARD) {
+          c = '*';
+        }
+        res.append(c);
+      }
+    } else {
+      switch (operator) {
+      case AND:
+        res.append("&");
+        break;
+      case OR:
+        res.append("|");
+        break;
+      case NOT:
+        res.append("!");
+        break;
+      }
+      for (final LDAPExpr arg : args) {
+        res.append(arg.toString());
+      }
+    }
+    res.append(")");
+    return res.toString();
+  }
+
+  /**
+   * Contains the current parser position and parsing utility methods.
+   */
+  private static class ParseState {
+    int pos;
+    String str;
+
+
+    public ParseState(String str) throws InvalidSyntaxException {
+      this.str = str;
+      if (str.length() == 0)
+        error(NULL);
+      pos = 0;
+    }
+
+
+    public boolean prefix(String pre) {
+      if (!str.startsWith(pre, pos))
+        return false;
+      pos += pre.length();
+      return true;
+    }
+
+
+    public char peek() {
+      return str.charAt(pos);
+    }
+
+
+    public void skip(int n) {
+      pos += n;
+    }
+
+
+    public String rest() {
+      return str.substring(pos);
+    }
+
+
+    public void skipWhite() {
+      while (Character.isWhitespace(str.charAt(pos))) {
+        pos++;
+      }
+    }
+
+
+    public String getAttributeName() {
+      final int start = pos;
+      int end = -1;
+      for (;; pos++) {
+        final char c = str.charAt(pos);
+        if (c == '(' || c == ')' || c == '<' || c == '>' || c == '=' || c == '~') {
+          break;
+        } else if (!Character.isWhitespace(c)) {
+          end = pos;
+        }
+      }
+      if (end == -1) {
+        return null;
+      }
+      return str.substring(start, end + 1);
+    }
+
+
+    public String getAttributeValue() {
+      final StringBuffer sb = new StringBuffer();
+      label: for (;; pos++) {
+        final char c = str.charAt(pos);
+        switch (c) {
+        case '(':
+        case ')':
+          break label;
+        case '*':
+          sb.append(WILDCARD);
+          break;
+        case '\\':
+          sb.append(str.charAt(++pos));
+          break;
+        default:
+          sb.append(c);
+          break;
+        }
+      }
+      return sb.toString();
+    }
+
+
+    public void error(String m) throws InvalidSyntaxException {
+      throw new InvalidSyntaxException(m, (str == null) ? "" : str.substring(pos));
+    }
+  }
+
+  /**
+   * Set with one element maximum.
+   */
+  private static class OneSet<E> extends AbstractSet<E> {
+
+    final private E elem;
+
+
+    OneSet(E o) {
+      elem = o;
+    }
+
+
+    @Override
+    public Iterator<E> iterator() {
+      return new Iterator<E>() {
+        E ielem = elem;
+
+
+        public boolean hasNext() {
+          return ielem != null;
+        }
+
+
+        public E next() {
+          if (ielem != null) {
+            final E r = ielem;
+            ielem = null;
+            return r;
+          } else {
+            throw new NoSuchElementException();
+          }
+        }
+
+
+        public void remove() {
+          throw new UnsupportedOperationException();
+        }
+      };
+    }
+
+
+    @Override
+    public int size() {
+      return elem == null ? 0 : 1;
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ListenerEntry.java b/osgi/framework/src/org/knopflerfish/framework/ListenerEntry.java
new file mode 100644
index 0000000..0b50886
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ListenerEntry.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2003-2011, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.EventListener;
+
+class ListenerEntry {
+  final BundleContextImpl bc;
+  final EventListener listener;
+  boolean bRemoved = false;
+
+  ListenerEntry(BundleContextImpl bc, EventListener l) {
+    this.bc = bc;
+    listener = l;
+  }
+
+  /**
+   * Listener are considered equal if bc and listener are equal, this so that
+   * the HashSet of listeners should work.
+   */
+  public boolean equals(Object o) {
+    if (o instanceof ListenerEntry) {
+      return bc == ((ListenerEntry) o).bc && listener == ((ListenerEntry) o).listener;
+    }
+    return false;
+  }
+
+  /**
+   * Only use listener as hash value, since it is almost always unique.
+   */
+  public int hashCode() {
+    return listener.hashCode();
+  }
+
+  /**
+   */
+  void setRemoved(boolean b) {
+    this.bRemoved = b;
+  }
+
+  /**
+   */
+  public boolean isRemoved() {
+    return bRemoved;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Listeners.java b/osgi/framework/src/org/knopflerfish/framework/Listeners.java
new file mode 100644
index 0000000..d5643f5
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Listeners.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Collection;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServicePermission;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * Here we handle all listeners that bundles have registered.
+ *
+ * @author Jan Stein, Philippe Laporte, Gunnar Ekolin
+ */
+class Listeners {
+
+  /**
+   * All bundle event listeners.
+   */
+  HashSet<ListenerEntry> bundleListeners = new HashSet<ListenerEntry>();
+  HashSet<ListenerEntry> syncBundleListeners = new HashSet<ListenerEntry>();
+
+  /**
+   * All framework event listeners.
+   */
+  private final HashSet<ListenerEntry> frameworkListeners = new HashSet<ListenerEntry>();
+
+  /**
+   * All service event listeners.
+   */
+  ServiceListenerState serviceListeners;
+
+  /**
+   * Queue of async events to deliver
+   */
+  private LinkedList<AsyncEvent> asyncEventQueue = null;
+
+  /**
+   * All threads for delivering async events
+   */
+  private AsyncEventThread [] threads = null;
+
+  /**
+   * Map of active listeners to thread.
+   */
+  private HashMap<ListenerEntry, Thread> activeListeners = null;
+
+  /**
+   * Handle to secure call class.
+   */
+  private PermissionOps secure;
+
+  FrameworkContext fwCtx;
+
+  boolean nocacheldap;
+
+  volatile boolean quit = false;
+
+
+  Listeners(FrameworkContext framework, PermissionOps perm) {
+    this.fwCtx = framework;
+    secure = perm;
+    nocacheldap = framework.props.getBooleanProperty(FWProps.LDAP_NOCACHE_PROP);
+    serviceListeners = new ServiceListenerState(this);
+    final String ets = framework.props.getProperty(FWProps.LISTENER_N_THREADS_PROP);
+    int n_threads = 1;
+    if (ets != null) {
+      try {
+        n_threads = Integer.parseInt(ets);
+      } catch (final NumberFormatException nfe) {
+        // NYI, report error
+      }
+    }
+    if (n_threads > 0) {
+      asyncEventQueue = new LinkedList<AsyncEvent>();
+      threads = new AsyncEventThread[n_threads];
+      for (int i = 0; i < n_threads; i++) {
+        threads[i] = new AsyncEventThread(i);
+        threads[i].start();
+      }
+      if (n_threads > 1) {
+        activeListeners = new HashMap<ListenerEntry, Thread>();
+      }
+    }
+  }
+
+
+  void clear()
+  {
+    bundleListeners.clear();
+    syncBundleListeners.clear();
+    frameworkListeners.clear();
+    serviceListeners.clear();
+    secure = null;
+    fwCtx = null;
+  }
+
+
+  /**
+   * Add a bundle listener to the current framework.
+   *
+   * @param bundle Who wants to add listener.
+   * @param listener Object to add.
+   */
+  void addBundleListener(BundleContextImpl bc, BundleListener listener) {
+    final ListenerEntry le = new ListenerEntry(bc, listener);
+    if (listener instanceof SynchronousBundleListener) {
+      secure.checkListenerAdminPerm(bc.bundle);
+      synchronized (syncBundleListeners) {
+          syncBundleListeners.add(le);
+      }
+    }
+    else {
+      synchronized (bundleListeners) {
+          bundleListeners.add(le);
+      }
+    }
+  }
+
+
+  /**
+   * Remove bundle listener from current framework. Silently ignore
+   * if listener doesn't exist. If listener is registered more than
+   * once remove one instances.
+   *
+   * @param bundle Who wants to remove listener.
+   * @param listener Object to remove.
+   */
+  void removeBundleListener(BundleContextImpl bc, BundleListener listener) {
+    final ListenerEntry le = new ListenerEntry(bc, listener);
+    if (listener instanceof SynchronousBundleListener) {
+      synchronized (syncBundleListeners) {
+        secure.checkListenerAdminPerm(bc.bundle);
+        syncBundleListeners.remove(le);
+      }
+    } else {
+      synchronized (bundleListeners) {
+        bundleListeners.remove(le);
+      }
+    }
+  }
+
+
+  /**
+   * Add a bundle listener to current framework.
+   *
+   * @param bc Who wants to add listener.
+   * @param listener Object to add.
+   */
+  void addFrameworkListener(BundleContextImpl bc, FrameworkListener listener) {
+    final ListenerEntry le = new ListenerEntry(bc, listener);
+    synchronized (frameworkListeners) {
+      frameworkListeners.add(le);
+    }
+  }
+
+
+  /**
+   * Remove framework listener from current framework. Silently ignore
+   * if listener doesn't exist. If listener is registered more than
+   * once remove all instances.
+   *
+   * @param bc Who wants to remove listener.
+   * @param listener Object to remove.
+   */
+  void removeFrameworkListener(BundleContextImpl bc, FrameworkListener listener) {
+    synchronized (frameworkListeners) {
+      frameworkListeners.remove(new ListenerEntry(bc, listener));
+    }
+  }
+
+
+  /**
+   * Add a service listener with filter to current framework.
+   * If no filter is wanted, call with filter param set to null.
+   *
+   * @param bundle Who wants to add listener.
+   * @param listener Object to add.
+   * @param filter LDAP String used for filtering event before calling listener.
+   */
+  void addServiceListener(BundleContextImpl bc, ServiceListener listener, String filter)
+    throws InvalidSyntaxException {
+    serviceListeners.add(bc, listener, filter);
+  }
+
+
+  /**
+   * Remove service listener from current framework. Silently ignore
+   * if listener doesn't exist. If listener is registered more than
+   * once remove all instances.
+   *
+   * @param bundle Who wants to remove listener.
+   * @param listener Object to remove.
+   */
+  void removeServiceListener(BundleContextImpl bc, ServiceListener listener) {
+    serviceListeners.remove(bc, listener);
+  }
+
+
+  /**
+   * Remove all listener registered by a bundle in the current framework.
+   *
+   * @param bi Bundle which listeners we want to remove.
+   */
+  void removeAllListeners(BundleContextImpl bc) {
+    removeAllListeners(syncBundleListeners, bc);
+    removeAllListeners(bundleListeners, bc);
+    removeAllListeners(frameworkListeners, bc);
+    serviceListeners.removeAll(bc);
+  }
+
+
+
+  /**
+   * Receive notification that a bundle has had a change occur in its lifecycle.
+   * NOTE! Must be called with AllPermission!?
+   *
+   * @see org.osgi.framework.BundleListener#bundleChanged
+   */
+  void bundleChanged(final BundleEvent evt) {
+    final HashSet<ListenerEntry> filteredSyncBundleListeners = new HashSet<ListenerEntry>();
+    HashSet<ListenerEntry> filteredBundleListeners = null;
+
+
+    final int type = evt.getType();
+
+    if (type != BundleEvent.LAZY_ACTIVATION &&
+        type != BundleEvent.STARTING &&
+        type != BundleEvent.STOPPING) {
+      filteredBundleListeners = new HashSet<ListenerEntry>();
+    }
+
+    fwCtx.bundleHooks.filterBundleEventReceivers(
+        evt,
+        filteredSyncBundleListeners,
+        filteredBundleListeners);
+
+    for(final ListenerEntry le : filteredSyncBundleListeners) {
+      bundleChanged(le, evt);
+    }
+    if (filteredBundleListeners != null) {
+      if (asyncEventQueue != null) {
+        synchronized (asyncEventQueue) {
+          for(final ListenerEntry le : filteredBundleListeners) {
+            asyncEventQueue.addLast(new AsyncEvent(le, evt));
+          }
+          asyncEventQueue.notify();
+        }
+      } else {
+        for(final ListenerEntry le : filteredBundleListeners) {
+          bundleChanged(le, evt);
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Receive notification of a general framework event.
+   *
+   * @see org.osgi.framework.FrameworkListener#frameworkEvent
+   */
+  void frameworkEvent(final FrameworkEvent evt, FrameworkListener... oneTimeListeners) {
+    if (fwCtx.debug.errors) {
+      if (evt.getType() == FrameworkEvent.ERROR) {
+        fwCtx.debug.println("errors - FrameworkErrorEvent bundle #" +
+                                evt.getBundle().getBundleId());
+        fwCtx.debug.printStackTrace("errors - FrameworkErrorEvent throwable: ",
+                                        evt.getThrowable());
+      }
+    }
+    if (fwCtx.debug.warnings) {
+      if (evt.getType() == FrameworkEvent.WARNING) {
+        fwCtx.debug.println("warnings - FrameworkErrorEvent bundle #" +
+                                evt.getBundle().getBundleId());
+        fwCtx.debug.printStackTrace("warnings - FrameworkErrorEvent throwable: ",
+                                        evt.getThrowable());
+      }
+    }
+    if (fwCtx.debug.startlevel) {
+      if (evt.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+        fwCtx.debug
+            .println("startlevel: FrameworkEvent Startlevel Changed");
+      } else if (evt.getType() == FrameworkEvent.STARTED) {
+        fwCtx.debug.println("startlevel: FrameworkEvent Started");
+      }
+    }
+
+    if (asyncEventQueue != null) {
+      synchronized (asyncEventQueue) {
+        if (oneTimeListeners!=null) {
+          for (final FrameworkListener fl : oneTimeListeners) {
+            asyncEventQueue.addLast(new AsyncEvent(new ListenerEntry(null, fl), evt));
+          }
+        }
+        synchronized (frameworkListeners) {
+          for (final ListenerEntry listenerEntry : frameworkListeners) {
+            asyncEventQueue.addLast(new AsyncEvent(listenerEntry, evt));
+          }
+        }
+        asyncEventQueue.notify();
+      }
+    } else {
+      if (oneTimeListeners != null) {
+        for (final FrameworkListener ofl : oneTimeListeners) {
+          frameworkEvent(new ListenerEntry(null, ofl), evt);
+        }
+      }
+      ListenerEntry [] fl;
+      synchronized (frameworkListeners) {
+        fl = new ListenerEntry[frameworkListeners.size()];
+        frameworkListeners.toArray(fl);
+      }
+      for (final ListenerEntry element : fl) {
+        frameworkEvent(element, evt);
+      }
+    }
+  }
+
+
+  /**
+   * Receive notification that a service has had a change occur in its lifecycle.
+   *
+   * @see org.osgi.framework.ServiceListener#serviceChanged
+   */
+  void serviceChanged(final Collection<ServiceListenerEntry> receivers,
+                      final ServiceEvent evt,
+                      final Set<ServiceListenerEntry> matchBefore) {
+    final ServiceReferenceImpl<?> sr = (ServiceReferenceImpl<?>)evt.getServiceReference();
+    final String[] classes = (String[])sr.getProperty(Constants.OBJECTCLASS);
+    final int n = 0;
+
+    // TODO: OSGi43 the interplay between ldap filters, hooks and MODIFIED_ENDMATCH should be revised
+    if (matchBefore != null) {
+      for (final ServiceListenerEntry l : receivers) {
+        matchBefore.remove(l);
+      }
+    }
+
+    fwCtx.serviceHooks.filterServiceEventReceivers(evt, receivers);
+
+    for (final ServiceListenerEntry l : receivers) {
+      try {
+        if (!l.isRemoved()
+            && (!secure.checkPermissions() ||
+                l.bc.bundle.hasPermission(new ServicePermission(sr, ServicePermission.GET)))) {
+          final boolean testAssignable = !(l.listener instanceof AllServiceListener);
+          for (int i = 0; i < classes.length; i++) {
+            if (testAssignable && !sr.isAssignableTo(l.bc.bundle, classes[i])){
+              continue;
+            }
+            try {
+              ((ServiceListener)l.listener).serviceChanged(evt);
+            } catch (final Throwable pe) {
+              fwCtx.frameworkError(l.bc, pe);
+            }
+            break;
+          }
+        }
+      } catch (final IllegalStateException ignore) {
+        // Bundle got UNINSTALLED, skip it
+      }
+    }
+    if (fwCtx.debug.ldap) {
+      fwCtx.debug.println("Notified " + n + " listeners");
+    }
+  }
+
+
+  /**
+   *
+   *
+   */
+  Set<ServiceListenerEntry> getMatchingServiceListeners(final ServiceReference<?> sr) {
+    return serviceListeners.getMatchingListeners((ServiceReferenceImpl<?>)sr);
+  }
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Remove all listener registered by a bundle in specified list within
+   * the current framework. Silently ignore if listener doesn't exist.
+   *
+   * @param s Which set to remove from bundle, framework or service.
+   * @param bc Bundle which listeners we want to remove.
+   */
+  private void removeAllListeners(Set<ListenerEntry> s, BundleContext bc) {
+    synchronized (s) {
+      for (final Iterator<ListenerEntry> i = s.iterator(); i.hasNext();) {
+        if (i.next().bc == bc) {
+          i.remove();
+        }
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  private void bundleChanged(final ListenerEntry le, final BundleEvent evt) {
+    try {
+      ((BundleListener)le.listener).bundleChanged(evt);
+    } catch (final Throwable pe) {
+      fwCtx.frameworkError(le.bc, pe);
+    }
+  }
+
+
+  /**
+   *
+   */
+  private void frameworkEvent(final ListenerEntry le, FrameworkEvent evt) {
+    try {
+      ((FrameworkListener)le.listener).frameworkEvent(evt);
+    } catch (final Exception pe) {
+      // Don't report Error events again, since probably would go into an infinite loop.
+      if (evt.getType() != FrameworkEvent.ERROR) {
+        fwCtx.frameworkError(le.bc, pe);
+      }
+    }
+  }
+
+  //
+  // Private classes
+  //
+
+  static class AsyncEvent {
+    final ListenerEntry le;
+    final EventObject evt;
+
+    AsyncEvent(ListenerEntry le, EventObject evt) {
+      this.le = le;
+      this.evt = evt;
+    }
+  }
+
+
+  /**
+   * Thread that deliver asynchronous events.
+   */
+  private class AsyncEventThread extends Thread {
+
+    AsyncEventThread(int i) {
+      super(fwCtx.threadGroup, "AsyncEventThread#" + i);
+    }
+
+
+    @Override
+    public void run() {
+      while (true) {
+        AsyncEvent ae;
+
+        synchronized (asyncEventQueue) {
+          while (!quit && asyncEventQueue.isEmpty()) {
+            try {
+              asyncEventQueue.wait();
+            } catch (final InterruptedException ignored) { }
+          }
+          if (quit) {
+            break;
+          }
+          ae = asyncEventQueue.removeFirst();
+        }
+
+        if (activeListeners != null) {
+          synchronized (activeListeners) {
+            while (activeListeners.containsKey(ae.le)) {
+              // TODO, implement detection of hanging listeners?
+              try {
+                activeListeners.wait();
+              } catch (final InterruptedException ignore) { }
+            }
+            activeListeners.put(ae.le, Thread.currentThread());
+          }
+        }
+        // Either an unregistered one-time listener or the bundle
+        // owning the listener must be valid.
+        if (ae.le.bc==null || ae.le.bc.isValid()) {
+          if (ae.evt instanceof BundleEvent) {
+            bundleChanged(ae.le, (BundleEvent)ae.evt);
+          } else {
+            frameworkEvent(ae.le, (FrameworkEvent)ae.evt);
+          }
+        }
+        if (activeListeners != null) {
+          synchronized (activeListeners) {
+            activeListeners.remove(ae.le);
+            activeListeners.notifyAll();
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Main.java b/osgi/framework/src/org/knopflerfish/framework/Main.java
new file mode 100644
index 0000000..fb776c9
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Main.java
@@ -0,0 +1,1511 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+
+/**
+ * This is the main startup code for the framework and enables
+ * basic operations as install, start, stop, uninstall
+ * and update.
+ *
+ * @author Jan Stein, Erik Wistrand, Mats-Ola Persson, Gunnar Ekolin
+ */
+public class Main
+{
+  // Main object
+  static Main main;
+
+  // Verbosity level of printouts. 0 is low.
+  int verbosity;
+
+  // Will be filled in from manifest entry during startup
+  String version = "<unknown>";
+
+  // Top directory (excluding trailing /)
+  String topDir = "";
+
+  // Set to true if JRE is started without any arguments
+  boolean bZeroArgs;
+
+  // Save beginning start level as long as true
+  boolean saveStartLevel = true;
+
+  // will be initialized by main() - up for anyone for grabbing
+  public String bootText;
+
+  // Framework properties, i.e., configuration properties from -Fkey=value
+  Map<String, String> fwProps = new HashMap<String, String>();
+
+  // System properties, i.e., configuration properties from -Dkey=value
+  Map<String, String> sysProps = new HashMap<String, String>();
+
+  static public final String JARDIR_PROP    = "org.knopflerfish.gosg.jars";
+  static public final String JARDIR_DEFAULT = "file:jars/;"
+      + FWResourceURLStreamHandler.PROTOCOL + ":jars/";
+
+  static public final String XARGS_INIT     = "init.xargs";
+  static public final String XARGS_RESTART  = "restart.xargs";
+  static public final String FWPROPS_XARGS  = "fwprops.xargs";
+
+  static public final String CMDIR_PROP    = "org.knopflerfish.bundle.cm.store";
+  static public final String CMDIR_DEFAULT = "cmdir";
+
+  static public final String VERBOSITY_PROP    = "org.knopflerfish.framework.main.verbosity";
+  static public final String VERBOSITY_DEFAULT = "0";
+
+   /**
+   * Name of framework property controlling whether to write an
+   * FWPROPS_XARGS file or not at startup.
+   */
+  static public final String WRITE_FWPROPS_XARGS_PROP =
+    "org.knopflerfish.framework.main.write.fwprops.xargs";
+
+  static public final String XARGS_WRITESYSPROPS_PROP =
+    "org.knopflerfish.framework.main.xargs.writesysprops";
+
+  static public final String XARGS_DEFAULT     = "default";
+
+  static public final String PRODVERSION_PROP     = "org.knopflerfish.prodver";
+
+  static public final String BOOT_TEXT_PROP
+    = "org.knopflerfish.framework.main.bootText";
+
+  /**
+   * Default values for some framework properties.
+   */
+  Map<String, String> defaultFwProps = new HashMap<String,String>() {
+    private static final long serialVersionUID = 1L;
+  {
+    put(CMDIR_PROP,    CMDIR_DEFAULT);
+  }};
+
+
+  FrameworkFactory ff;
+  Framework framework;
+
+  /**
+   * Help class for starting the OSGi framework.
+   */
+  public static void main(String[] args) {
+    main = new Main();
+    main.start(args);
+    System.exit(0);
+  }
+
+
+  public Main() {
+    try { // Set the initial verbosity level.
+      final String vpv = System.getProperty(VERBOSITY_PROP);
+      verbosity = Integer.parseInt(null==vpv ? VERBOSITY_DEFAULT: vpv);
+    } catch (final Exception ignored) { }
+    populateSysProps();
+    // Setup URLStremFactory so that we can use fwresource:
+    FrameworkContext.setupURLStreamHandleFactory();
+  }
+
+
+  protected void start(String[] args) {
+    version = Util.readFrameworkVersion();
+    final String tstampYear = Util.readTstampYear();
+
+    bootText =
+      "Knopflerfish OSGi framework launcher, version " + version + "\n" +
+      "Copyright 2003-" +tstampYear +" Knopflerfish. All Rights Reserved.\n" +
+      "See http://www.knopflerfish.org for more information.\n";
+
+    System.out.println(bootText);
+
+    // Check if framework is started with no args at all.
+    // This typically happens when starting with "java -jar framework.jar"
+    // or similar (e.g by double-clicking on framework.jar)
+    bZeroArgs = (args.length == 0);
+    if (!bZeroArgs) {// Also true if started with only -D/-F/-ff args
+      bZeroArgs = true;
+      for (int i=0; bZeroArgs && i<args.length; i++) {
+        // -Dx=y, -Fx=y -init and -ff class does not count as args
+        if ("-ff".equals(args[i])) {
+          if (null!=framework) {
+            throw new IllegalArgumentException
+              ("a framework instance is already created.");
+          }
+          if (i+1 < args.length) {
+            i++;
+            ff = getFrameworkFactory(args[i]);
+          } else {
+            throw new IllegalArgumentException("No framework factory argument");
+          }
+        } else {
+          bZeroArgs = args[i].startsWith("-D")
+            || args[i].startsWith("-F")
+            || "-init".equals(args[i]);
+        }
+      }
+    }
+
+    processProperties(args);
+
+    if (bZeroArgs) {// Add default xargs file to command line
+      // To determine the fwdir we must process all -D/-F definitions
+      // on the current command line.
+      if (0==args.length) {
+        args = new String[] {"--xargs", XARGS_DEFAULT};
+      } else {
+        final String[] newArgs = new String[args.length +2];
+        newArgs[0] = "--xargs";
+        newArgs[1] = XARGS_DEFAULT;
+        System.arraycopy(args, 0, newArgs, 2, args.length);
+        args = newArgs;
+      }
+    }
+
+    args = expandArgs(args);
+    handleArgs(args);
+  }
+
+
+  /**
+   * Shall framework properties be exported as system properties?
+   */
+  private boolean writeSysProps() {
+    Object val = fwProps.get(XARGS_WRITESYSPROPS_PROP);
+    if (val == null) {
+      val = sysProps.get(XARGS_WRITESYSPROPS_PROP);
+    }
+
+    println("writeSysProps? '" + val + "'", 2);
+    return "true".equals(val);
+  }
+
+
+  public FrameworkFactory getFrameworkFactory() {
+    String factoryClassName = FrameworkFactoryImpl.class.getName();
+    try {
+      final String factoryS = new String(Util.readResource("/META-INF/services/org.osgi.framework.launch.FrameworkFactory"), "UTF-8");
+      final String[] w = Util.splitwords(factoryS, "\n\r");
+      for(int i = 0; i < w.length; i++) {
+        if(w[i].length() > 0 && !w[i].startsWith("#")) {
+          factoryClassName = w[i].trim();
+          break;
+        }
+      }
+
+    } catch (final Exception e) {
+      // META-INF/services may be lost when putting framework in Android .apk
+      println("failed to get FrameworkFactory, using default", 6, e);
+    }
+    return getFrameworkFactory(factoryClassName);
+  }
+
+
+  public FrameworkFactory getFrameworkFactory(String factoryClassName) {
+    try {
+      println("getFrameworkFactory(" + factoryClassName + ")", 2);
+      final Class<?> clazz = Class.forName(factoryClassName);
+      final Constructor<?> cons  = clazz.getConstructor(new Class[] { });
+      final FrameworkFactory ff = (FrameworkFactory) cons.newInstance(new Object[] { });
+      return ff;
+    } catch (final Exception e) {
+      error("failed to create " + factoryClassName, e);
+      throw new RuntimeException("failed to create " + factoryClassName + ": " + e);
+    }
+  }
+
+
+  URL[] getJarBase() {
+    assertFramework();
+    String jars = framework.getBundleContext().getProperty(JARDIR_PROP);
+    if(jars == null) {
+      jars = JARDIR_DEFAULT;
+    }
+
+    final String[] ja = Util.splitwords(jars, ";");
+    ArrayList<URL> res = new ArrayList<URL>();
+    for (int i=0; i<ja.length; i++) {
+      final String u = ja[i].trim();
+      try {
+        res.add(new URL(u));
+        println("jar base[" + i + "]=" + u, 3);
+      } catch (final MalformedURLException ignored) {
+        System.err.println("Skip illegal jar base: " + u);
+      }
+    }
+
+    return res.toArray(new URL[res.size()]);
+  }
+
+
+  /**
+   * Process one command line argument for setting a property.
+   *
+   * If the line contains an '=' then property will be set.
+   *
+   * Example "org.knopflerfish.test=apa" is equivalent to calling
+   * <tt>setProperty("org.knopflerfish.test", "apa")</tt> in the given
+   * props object.
+   *
+   * @param prefix The prefix (<tt>-D</tt>/<tt>-F</tt>) to print in the trace.
+   * @param arg    The command line argument to process.
+   * @param props  The properties object to add the property to.
+   */
+  void setProperty(String prefix, String arg, Map<String, String> props) {
+    final int ix = arg.indexOf("=");
+    if(ix != -1) {
+      final String key = arg.substring(2, ix);
+      final String value = arg.substring(ix + 1);
+
+      println(prefix +key +"=" +value, 1);
+      props.put(key,value);
+
+      if (Constants.FRAMEWORK_BEGINNING_STARTLEVEL.equals(key)) {
+        saveStartLevel = false;
+      }
+      if (VERBOSITY_PROP.equals(key)) {
+        // redo this here since verbosity level may have changed
+        try {
+          final int old = verbosity;
+          verbosity = Integer.parseInt( value.length()==0
+                                        ? VERBOSITY_DEFAULT : value);
+          if (old != verbosity) {
+            println("Verbosity changed to "+verbosity, 1);
+          }
+        } catch (final Exception ignored) {}
+      }
+    }
+  }
+
+
+  /**
+   * Process all property related command line arguments. I.e.,
+   * arguments on the form
+   * <ul>
+   *
+   *   <li> <tt>-D<it>*</it></tt> a system property definition.
+   *
+   *   <li> <tt>-F<it>*</it></tt> a framework property definition.
+   *
+   *   <li> <tt>-init</it></tt> a request to clear the frameworks
+   *        persistent state on the first call to init(). This will
+   *        set the framework property named
+   *        <tt>org.osgi.framework.storage.clean</tt> to the value
+   *        <tt>onFirstInit</tt>.
+   *
+   * </ul>
+   *
+   * Example
+   * "-Dorg.knopflerfish.test=apa" is equivalent to the code
+   * <tt>System.setProperty("org.knopflerfish.test", "apa");</tt>
+   *
+   * @param args  The command line argument array to process
+   */
+  void processProperties(String[] args) {
+    for (int i = 0; i < args.length; i++) {
+      try {
+        if(args[i].startsWith("-D")) { // A system property
+          setProperty("-D", args[i], sysProps);
+        } else if (args[i].startsWith("-F")) { // A framework property
+          setProperty("-F", args[i], fwProps);
+        } else if ("-init".equals(args[i])) {
+          fwProps.put(Constants.FRAMEWORK_STORAGE_CLEAN,
+                      Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
+        } else if ("-launch".equals(args[i])) {
+          saveStartLevel = false;
+        } else if (saveStartLevel && i+1 < args.length && "-startlevel".equals(args[i])) {
+          fwProps.put(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, args[i+1]);
+        }
+      } catch (final Exception e) {
+        e.printStackTrace(System.err);
+        error("Command \"" +args[i] +"\" failed, " + e.getMessage());
+      }
+    }
+  }
+
+
+  /**
+   * Save all framework properties as an xargs-file in the framework
+   * directory for restarts.
+   */
+  private void save_restart_props(Map<String, String> props) {
+    final String ro = framework.getBundleContext().getProperty(FWProps.READ_ONLY_PROP);
+    if ("true".equalsIgnoreCase(ro)) {
+      return;
+    }
+    final String xrwp = framework.getBundleContext().getProperty(WRITE_FWPROPS_XARGS_PROP);
+    if ("false".equalsIgnoreCase(xrwp)) {
+      return;
+    }
+    PrintWriter pr = null;
+    try {
+      final String fwDirStr = Util.getFrameworkDir(props);
+      final File fwDir      = new File(fwDirStr);
+      fwDir.mkdirs();
+
+      final File propsFile = new File(fwDir, Main.FWPROPS_XARGS);
+      pr = new PrintWriter(new BufferedWriter(new FileWriter(propsFile)));
+      for (final Entry<String, String> entry : props.entrySet()) {
+        final String key   = entry.getKey();
+        final String value = entry.getValue();
+
+        // Don't save clean onFirstInit
+        if (!Constants.FRAMEWORK_STORAGE_CLEAN.equals(key) ||
+            !Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT.equals(value)) {
+          pr.println("-F" +key +"=" +value);
+        }
+      }
+    } catch (final Exception e) {
+      if(e instanceof RuntimeException) {
+        throw (RuntimeException)e;
+      }
+      throw new IllegalArgumentException("Failed to create "+ Main.FWPROPS_XARGS
+                                         + ": " + e);
+    } finally {
+      if (null!=pr) {
+        pr.close();
+      }
+    }
+  }
+
+
+  /**
+   * Ensure that a framework instance is created and initialized, if
+   * not finalize properties and create a framework instance.
+   */
+  void assertFramework() {
+    if(ff == null) {
+      ff = getFrameworkFactory();
+      println("Created FrameworkFactory " + ff.getClass().getName(), 1);
+    }
+    if(framework == null) {
+      // Expand property values and export them as system properties
+      finalizeProperties();
+
+      framework = ff.newFramework(fwProps);
+      try {
+        framework.init();
+        save_restart_props(fwProps);
+
+        // Make the boot text available to any bundle (e.g., desktop).
+        // Added it here since we can not save multiline properties.
+        fwProps.put(BOOT_TEXT_PROP, bootText);
+
+      } catch (final BundleException be) {
+        error("Failed to initialize the framework: " +be.getMessage(), be);
+      }
+      println("Framework class " + framework.getClass().getName(), 1);
+      System.out.println("Created Framework: " + framework.getSymbolicName()
+                         + ", version=" + framework.getVersion() + ".");
+    }
+  }
+
+
+  /**
+   * Handle command line options.
+   *
+   * @param args argument line
+   */
+  private void handleArgs(String[] args) {
+    boolean bLaunched = false;
+
+    // If not init, check if we have saved framework properties
+    if (!Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
+        .equals(fwProps.get(Constants.FRAMEWORK_STORAGE_CLEAN))) {
+      final File propsFile = new File(Util.getFrameworkDir(fwProps), Main.FWPROPS_XARGS);
+      if (propsFile.exists()) {
+        final String[] newArgs = new String[args.length +2];
+        newArgs[0] = "-xargs";
+        newArgs[1] = propsFile.getAbsolutePath();
+        System.arraycopy(args, 0, newArgs, 2, args.length);
+        args = expandArgs(newArgs);
+      }
+    }
+    // Since we must have all framework properties in the
+    // fwProps-map before creating the framework instance we must
+    // first handle all args that define properties. I.e., args
+    // starting with '-D' and '-F'.
+    processProperties(args);
+    if(verbosity > 5) {
+      for(int i = 0; i < args.length; i++) {
+        println("argv[" + i + "]=" + args[i], 5);
+      }
+    }
+
+    // Process all other options.
+    for (int i = 0; i < args.length; i++) {
+      try {
+        if ("-exit".equals(args[i])) {
+          println("Exit.", 0);
+          System.exit(0);
+        } else if (args[i].startsWith("-F")) {
+          // Skip, handled in processProperties(String[])
+        } else if (args[i].startsWith("-D")) {
+          // Skip, handled in processProperties(String[])
+        } else if ("-init".equals(args[i])) {
+          // Skip, handled in processProperties(String[])
+        } else if ("-version".equals(args[i])) {
+          System.out.println("Knopflerfish release: " + readRelease());
+          System.out.println("Framework version: " + Util.readFrameworkVersion());
+          printResource("/tstamp");
+          System.exit(0);
+        } else if ("-help".equals(args[i])) {
+          printResource("/help.txt");
+          System.exit(0);
+        } else if ("-jvminfo".equals(args[i])) {
+          assertFramework();
+          printJVMInfo(framework);
+          System.exit(0);
+        } else if ("-ff".equals(args[i])) {
+          // Already handled; skip class name
+          i++;
+        } else if ("-create".equals(args[i])) {
+          if (null!=framework
+              && ((Bundle.RESOLVED)&framework.getState())==0) {
+            throw new IllegalArgumentException
+              ("a framework instance is already created."
+               +" The '-create' command must either be the first command"
+               +" or come directly after a '-shutdown mSEC' command.");
+          }
+          framework = null;
+        } else if ("-install".equals(args[i])) {
+          assertFramework();
+          if (i+1 < args.length) {
+            final String bundle = args[i+1];
+            final Bundle b = framework.getBundleContext()
+              .installBundle(completeLocation(bundle), null);
+            println("Installed: ", b);
+            i++;
+          } else {
+            error("No URL for install command");
+          }
+        } else if ("-istart".equals(args[i])) {
+          assertFramework();
+          if (i+1 < args.length) {
+            final String bundle = args[i+1];
+            final Bundle b = framework.getBundleContext()
+              .installBundle(completeLocation(bundle), null);
+
+            b.start(Bundle.START_ACTIVATION_POLICY);
+            println("Installed and started (policy): ", b);
+            i++;
+          } else {
+            error("No URL for install command");
+          }
+        } else if ("-launch".equals(args[i])) {
+          bLaunched = doLaunch();
+        } else if ("-shutdown".equals(args[i])) {
+          if (i+1 < args.length) {
+            i++;
+            final long timeout = Long.parseLong(args[i]);
+            try {
+              if(framework != null) {
+                framework.stop();
+                final FrameworkEvent stopEvent = framework.waitForStop(timeout);
+                switch (stopEvent.getType()) {
+                case FrameworkEvent.STOPPED:
+                  // FW terminated, Main is done!
+                  println("Framework terminated", 0);
+                  break;
+                case FrameworkEvent.STOPPED_UPDATE:
+                  // Automatic FW restart, wait again.
+                  println("Framework stopped for update", 0);
+                  break;
+                case FrameworkEvent.STOPPED_BOOTCLASSPATH_MODIFIED:
+                  // A manual FW restart with new boot class path is needed.
+                  println("Framework stopped for bootclasspath update", 0);
+                  break;
+                case FrameworkEvent.ERROR:
+                  // Stop failed or other error, give up.
+                  error("Fatal framework error, terminating.",
+                        stopEvent.getThrowable());
+                  break;
+                case FrameworkEvent.WAIT_TIMEDOUT:
+                  // Should not happen with timeout==0, give up.
+                  error("Framework waitForStop(" +timeout +") timed out!",
+                        stopEvent.getThrowable());
+                  break;
+                }
+                println("Framework shutdown", 0);
+              } else {
+                throw new IllegalArgumentException("No framework to shutdown");
+              }
+            } catch (final Exception e) {
+              error("Failed to shutdown", e);
+            }
+          } else {
+            error("No timout for shutdown command");
+          }
+        } else if ("-sleep".equals(args[i])) {
+          if (i+1 < args.length) {
+            final long t = Long.parseLong(args[i+1]);
+            try {
+              println("Sleeping " + t + " seconds...", 0);
+              Thread.sleep(t * 1000);
+            } catch (final InterruptedException e) {
+              error("Sleep interrupted.");
+            }
+            i++;
+          } else {
+            error("No time for sleep command");
+          }
+        } else if ("-start".equals(args[i])) {
+          i = doStartBundle(args, i, Bundle.START_ACTIVATION_POLICY, "Started (policy): ");
+        } else if ("-start_e".equals(args[i])) {
+          i = doStartBundle(args, i, 0, "Started (eager): ");
+        } else if ("-start_et".equals(args[i])) {
+          i = doStartBundle(args, i, Bundle.START_TRANSIENT, "Started (eager,transient): ");
+        } else if ("-start_pt".equals(args[i])) {
+          i = doStartBundle(args, i, Bundle.START_TRANSIENT | Bundle.START_ACTIVATION_POLICY,
+                            "Start (policy,transient): ");
+        } else if ("-stop".equals(args[i])) {
+          i = doStopBundle(args, i, 0);
+        } else if ("-stop_t".equals(args[i])) {
+          i = doStopBundle(args, i, Bundle.STOP_TRANSIENT);
+        } else if ("-uninstall".equals(args[i])) {
+          assertFramework();
+          if (i+1 < args.length) {
+            final long id = getBundleID(framework, args[i+1]);
+            final Bundle b = framework.getBundleContext().getBundle(id);
+            b.uninstall();
+            println("Uninstalled: ", b);
+            i++;
+          } else {
+            error("No id for uninstall command");
+          }
+        } else if ("-update".equals(args[i])) {
+          assertFramework();
+          if (i+1 < args.length) {
+            Bundle[] bl = null;
+            if("ALL".equals(args[i+1])) {
+              bl = framework.getBundleContext().getBundles();
+            } else {
+              bl = new Bundle[] { framework.getBundleContext().getBundle(getBundleID(framework, args[i+1])) };
+            }
+            for(int n = 0; bl != null && n < bl.length; n++) {
+              final Bundle b = bl[n];
+              b.update();
+              println("Updated: ", b);
+            }
+            i++;
+          } else {
+            error("No id for update command");
+          }
+        } else if ("-initlevel".equals(args[i])) {
+          assertFramework();
+          if (i+1 < args.length) {
+            final int n = Integer.parseInt(args[i+1]);
+            final FrameworkStartLevel fsl = framework.adapt(FrameworkStartLevel.class);
+            if (fsl!=null) {
+              fsl.setInitialBundleStartLevel(n);
+            }
+            i++;
+          } else {
+            error("No integer level for initlevel command");
+          }
+        } else if ("-startlevel".equals(args[i])) {
+          assertFramework();
+          if (i+1 < args.length) {
+            final int n = Integer.parseInt(args[i+1]);
+            final FrameworkStartLevel fsl = framework.adapt(FrameworkStartLevel.class);
+            if (fsl!=null) {
+              fsl.setStartLevel(n);
+            }
+            i++;
+          } else {
+            error("No integer level for startlevel command");
+          }
+        } else {
+          error("Unknown option: " + args[i] +
+                "\nUse option -help to see all options");
+        }
+      } catch (final BundleException e) {
+        final Throwable ne = e.getNestedException();
+        if (ne != null) {
+          e.getNestedException().printStackTrace(System.err);
+        } else {
+          e.printStackTrace(System.err);
+        }
+        error("Command \"" + args[i] +
+              ((i+1 < args.length && !args[i+1].startsWith("-")) ?
+               " " + args[i+1] :
+               "") +
+              "\" failed, " + e.getMessage());
+      } catch (final Exception e) {
+        e.printStackTrace(System.err);
+        error("Command \"" + args[i] +
+              ((i+1 < args.length && !args[i+1].startsWith("-")) ?
+               " " + args[i+1] :
+               "") +
+              "\" failed, " + e.getMessage());
+      }
+    }
+
+    assertFramework();
+    if(!bLaunched) {
+      try {
+        bLaunched = doLaunch();
+      } catch (Throwable t) {
+        if (t instanceof BundleException) {
+          final BundleException be = (BundleException) t;
+          final Throwable ne = be.getNestedException();
+          if (ne != null) t = ne;
+        }
+        error("Framework launch failed, " + t.getMessage(), t);
+      }
+    }
+    FrameworkEvent stopEvent = null;
+    while (true) { // Ignore interrupted exception.
+      try {
+        stopEvent = framework.waitForStop(0L);
+        switch (stopEvent.getType()) {
+        case FrameworkEvent.STOPPED:
+          // FW terminated, Main is done!
+          println("Framework terminated", 0);
+          return;
+        case FrameworkEvent.STOPPED_UPDATE:
+          // Automatic FW restart, wait again.
+          break;
+        case FrameworkEvent.STOPPED_BOOTCLASSPATH_MODIFIED:
+          // A manual FW restart with new boot class path is needed.
+          return;
+        case FrameworkEvent.ERROR:
+          // Stop failed or other error, give up.
+          error("Fatal framework error, terminating.",
+                stopEvent.getThrowable());
+          return;
+        case FrameworkEvent.WAIT_TIMEDOUT:
+          // Should not happen with timeout==0, give up.
+          error("Framework waitForStop(0) timed out!",
+                stopEvent.getThrowable());
+          break;
+        }
+      } catch (final InterruptedException ie) { }
+    }
+  }
+
+
+  private int doStopBundle(final String[] args, int i, final int options)
+  {
+    assertFramework();
+    if (i+1 < args.length) {
+      final long id = getBundleID(framework, args[i+1]);
+      final Bundle b = framework.getBundleContext().getBundle(id);
+      try {
+        b.stop(options);
+        println("Stopped: ", b);
+      } catch (final Exception e) {
+        error("Failed to stop", e);
+      }
+      i++;
+    } else {
+      error("No ID for stop command");
+    }
+    return i;
+  }
+
+
+  private boolean doLaunch()
+      throws BundleException
+  {
+    boolean bLaunched;
+    if (null!=framework && (Bundle.ACTIVE&framework.getState())!=0) {
+      throw new IllegalArgumentException
+        ("a framework instance is already active.");
+    }
+    assertFramework();
+    framework.start();
+    bLaunched = true;
+    closeSplash();
+    println("Framework launched", 0);
+    return bLaunched;
+  }
+
+
+  private int doStartBundle(final String[] args, int i, final int options, final String logMsg)
+      throws BundleException
+  {
+    assertFramework();
+    if (i+1 < args.length) {
+      final long id = getBundleID(framework, args[i+1]);
+      final Bundle b = framework.getBundleContext().getBundle(id);
+      b.start(options);
+      println(logMsg, b);
+      i++;
+    } else {
+      error("No ID for start command");
+    }
+    return i;
+  }
+
+
+  /**
+   * Returns a bundle id from a string. The string is either a number
+   * or the location used for the bundle in the
+   * "-install bundleLocation" or "-istart" command.
+   * @param base Base URL to complete locations with.
+   * @param idLocation bundle id or location of the bundle to lookup
+   */
+  private long getBundleID(Framework fw, String idLocation) {
+    try {
+      return Long.parseLong(idLocation);
+    } catch (final NumberFormatException nfe) {
+      final Bundle[] bl = fw.getBundleContext().getBundles();
+      final String loc = completeLocation(idLocation);
+      for(int i = 0; bl != null && i < bl.length; i++) {
+        if(loc.equals(bl[i].getLocation())) {
+          return bl[i].getBundleId();
+        }
+      }
+      throw new IllegalArgumentException
+        ("Invalid bundle id/location: " +idLocation);
+    }
+  }
+
+
+  /**
+   * Complete location relative to topDir.
+   * @param location The location to be completed.
+   */
+  private String completeLocation(String location) {
+    // Handle file: case where topDir is not ""
+    if(location.startsWith("file:jars/") && !topDir.equals("")) {
+      location = ("file:" + topDir + "/" + location.substring(5)).replace('\\', '/');
+      println("mangled bundle location to " + location, 2);
+    }
+    final int ic = location.indexOf(":");
+    if (ic<2 || ic>location.indexOf("/")) {
+      println("location=" + location, 2);
+      final URL[] base = getJarBase();
+      // URL without protocol complete it.
+      for (int i=0; i<base.length; i++) {
+        println("base[" + i + "]=" + base[i], 2);
+        try {
+        	final URL url = new URL(base[i], location);
+
+          println("check " + url, 2);
+          if ("file".equals(url.getProtocol())) {
+            final File f = new File(url.getFile()).getAbsoluteFile();
+            if (!f.exists() || !f.canRead()) {
+              continue; // Noope; try next.
+            }
+          } else if ("http".equals(url.getProtocol())) {
+            final HttpURLConnection uc = (HttpURLConnection) url.openConnection();
+            uc.connect();
+            final int rc = uc.getResponseCode();
+            uc.disconnect();
+            if (rc!=HttpURLConnection.HTTP_OK) {
+              println("Can't access HTTP bundle: " + url + ", response code=" + rc, 0);
+              continue; // Noope; try next.
+            }
+          } else {
+            // Generic case; Check if we can read data from this URL
+            InputStream is = null;
+            try {
+              is = url.openStream();
+            } finally {
+              if (is!=null) is.close();
+            }
+          }
+          location = url.toString();
+          println("found location=" + location, 5);
+          break; // Found.
+        } catch (final Exception _ignore) { }
+      }
+    }
+    return location;
+  }
+
+
+  /**
+   * Expand all occurrence of <tt>-xarg <URL></tt> and <tt>--xarg
+   * <URL></tt> into a new array without any <tt>-xargs</tt>,
+   * <tt>--xargs</tt>.
+   *
+   * @param argv array of command line options to expand all
+   *             <tt>-xarg <URL></tt> options in.
+   * @return New argv array where all <tt>-xarg <URL></tt>
+   *         options have been expanded.
+   */
+  String[] expandArgs(String[] argv) {
+    final List<String> v = new ArrayList<String>();
+    int i = 0;
+    while(i < argv.length) {
+      if ("-xargs".equals(argv[i]) || "--xargs".equals(argv[i])) {
+        // if "--xargs", ignore any load errors of xargs file
+        final boolean bIgnoreException = argv[i].equals("--xargs");
+        if (i+1 < argv.length) {
+          final String   xargsPath = argv[i+1];
+          i++;
+          try {
+            final String[] moreArgs = loadArgs(xargsPath, argv);
+            final String[] r = expandArgs(moreArgs);
+            for (final String element : r) {
+              v.add(element);
+            }
+          } catch (final RuntimeException e) {
+            if(bIgnoreException) {
+              println("Failed to load --xargs " + xargsPath, 1, e);
+            } else {
+              throw e;
+            }
+          }
+        } else {
+          throw new IllegalArgumentException("-xargs without argument");
+        }
+      } else {
+        v.add(argv[i]);
+      }
+      i++;
+    }
+    final String[] r = new String[v.size()];
+
+    v.toArray(r);
+    return r;
+  }
+
+
+  /**
+   * Print help for starting the platform.
+   */
+  void printResource(String name) {
+    try {
+      System.out.println(new String(Util.readResource(name)));
+    } catch (final Exception e) {
+      System.out.println("No resource '" + name + "' available");
+    }
+  }
+
+
+  /**
+   * Print help for starting the platform.
+   */
+  void printJVMInfo(Framework framework) {
+    try {
+      final Properties props = System.getProperties();
+      System.out.println("--- System properties ---");
+      for(final Enumeration<?> e = props.keys(); e.hasMoreElements(); ) {
+        final String key = (String) e.nextElement();
+        System.out.println(key + ": " + props.get(key));
+      }
+
+      System.out.println("\n");
+      System.out.println("--- Framework properties ---");
+
+      final String keyStr = framework.getBundleContext().getProperty("org.knopflerfish.framework.bundleprops.keys");
+      final String[] keys = Util.splitwords(keyStr != null ? keyStr : "", ",");
+
+      for (final String key : keys) {
+        System.out.println(key + ": " + framework.getBundleContext().getProperty(key));
+      }
+    } catch (final Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+
+  // should this be read from the manifest instead?
+  static String readRelease() {
+    return Util.readResource("/release", "0.0.0.snapshot", "UTF-8");
+  }
+
+
+  /**
+   * Helper method which tries to find a default xargs files to use.
+   * Note: Make sure that fwProps are up to date by calling
+   * processProperties(args) before calling this method.
+   *
+   * @throws IOException 
+   */
+  BufferedReader getDefaultXArgs() throws IOException {
+    boolean bInit = Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
+      .equals(fwProps.get(Constants.FRAMEWORK_STORAGE_CLEAN));
+
+    final String fwDirStr = Util.getFrameworkDir(fwProps);
+    // avoid getAbsoluteFile since some profiles don't have this
+    final File fwDir      = new File(new File(fwDirStr).getAbsolutePath());
+    println("fwdir is " + fwDir, 1);
+
+    if (!bInit) { // Implicit init needed?
+      bInit = !(fwDir.exists() && fwDir.isDirectory());
+      if (bInit) println("Implicit -init since fwdir does not exist.", 2);
+    }
+    println("init is "  +bInit, 2);
+
+    // avoid getParentFile since some profiles don't have this
+    final String defDirStr = fwDir.getParent();
+    final File   defDir    = defDirStr != null ? new File(defDirStr) : null;
+
+    println("defDir=" +defDir, 5);
+
+    final File[] dirs = null!=defDir ?
+      new File[]{ fwDir, defDir } : new File[]{ fwDir };
+
+    // Determine the root OSGi dir, a.k.a. topDir
+    for (final File dir : dirs) {
+      final File jarsDir = new File(dir,"jars");
+      if (jarsDir.exists() && jarsDir.isDirectory()) {
+        topDir = dir.getAbsolutePath();
+        break;
+      }
+    }
+    println("Knopflerfish root directory is " +topDir, 2);
+
+    final String osName = Alias.unifyOsName(System.getProperty("os.name"));
+    final String[] xargNames = bInit
+      ? new String[]{"init_" +osName +".xargs",
+                     XARGS_INIT,
+                     "remote-" +XARGS_INIT }
+      : new String[]{XARGS_RESTART};
+
+    String xargsFound  = null;
+    println("Searching for default xargs file:", 5);
+    xargsSearch:
+    for (int i = 0; i<dirs.length; i++) {
+      for (int k = 0; k<xargNames.length; k++) {
+        final File xargsFile = new File(dirs[i], xargNames[k]);
+        println("  trying " +xargsFile.getAbsolutePath(), 5);
+        if (xargsFile.exists()) {
+          xargsFound = xargsFile.getAbsolutePath();
+          break xargsSearch;
+        }
+      }
+    }
+    if (xargsFound != null) {
+      println("default xargs file is " + xargsFound, 2);
+      return getXargsReader(xargsFound);
+    } else {
+      IOException failure = null;
+      for (int i = 0; i<xargNames.length; i++) {
+        try {
+          return getXargsReader(xargNames[i]);
+        } catch (IOException e) {
+          failure = e;
+        }
+      }
+      throw failure;
+    }
+  }
+
+
+  /**
+   * Add default properties and set default values if important ones
+   * are missing. The default values are taken from the
+   * <tt>defaultFwProps</tt> variable.
+   *
+   * <p>The <tt>org.knopflerfish.gosg.jars</tt> system property (if
+   * not defined) is created by scanning the "jars" directory for
+   * subdirs.</p>
+   *
+   * @see defaultSysProps
+   */
+  protected void addDefaultProps() {
+    for (final Entry<String, String> entry : defaultFwProps.entrySet()) {
+      final String key = entry.getKey();
+      if(!fwProps.containsKey(key)) {
+        final String val = entry.getValue();
+        println("Using default " + key + "=" + val, 1);
+        fwProps.put(key, val);
+      } else {
+        println("framework prop " + key + "=" + fwProps.get(key), 1);
+      }
+    }
+
+    // Set version info
+    if(null == fwProps.get(PRODVERSION_PROP)) {
+      fwProps.put(PRODVERSION_PROP, version);
+    }
+
+    // If jar dir is not specified, default to "file:jars/" and its
+    // subdirs
+    String jars = fwProps.get(JARDIR_PROP);
+    if (jars == null) {
+      jars = sysProps.get(JARDIR_PROP);
+    }
+
+    if(!(jars == null || "".equals(jars))) {
+      println("old jars=" + jars, 1);
+    } else {
+      final String jarBaseDir = topDir + File.separator + "jars";
+      println("jarBaseDir=" + jarBaseDir, 2);
+
+      // avoid getAbsoluteFile since some profiles don't have this
+      final File jarDir = new File(new File(jarBaseDir).getAbsolutePath());
+      if(jarDir.exists() && jarDir.isDirectory()) {
+
+        // avoid FileNameFilter since some profiles don't have it
+        final String [] names = jarDir.list();
+        final List<String> v = new ArrayList<String>();
+        for (final String name : names) {
+          final File f = new File(jarDir, name);
+          if(f.isDirectory()) {
+            v.add(name);
+          }
+        }
+        final String [] subdirs = new String[v.size()];
+        v.toArray(subdirs);
+
+        final StringBuffer sb = new StringBuffer();
+        sb.append("file:" + jarBaseDir + "/");
+        for (final String subdir : subdirs) {
+          sb.append(";file:" + jarBaseDir + "/" + subdir + "/");
+        }
+        sb.append(FWResourceURLStreamHandler.PROTOCOL + ":jars/");
+        jars = sb.toString().replace('\\', '/');
+        fwProps.put(JARDIR_PROP, jars);
+        println("scanned " +JARDIR_PROP +"=" + jars, 2);
+      }
+    }
+  }
+
+
+  /**
+   * Populates the sysProps Map<String,String> with all entries
+   * from the system properties object.
+   */
+  void populateSysProps() {
+    final Properties systemProperties = System.getProperties();
+    final Enumeration<?> systemPropertiesNames = systemProperties.propertyNames();
+    while (systemPropertiesNames.hasMoreElements()) {
+      try {
+        final String name  = (String) systemPropertiesNames.nextElement();
+        final String value = systemProperties.getProperty(name);
+        sysProps.put(name, value);
+        if (Constants.FRAMEWORK_BEGINNING_STARTLEVEL.equals(name)) {
+          saveStartLevel = false;
+        }
+        println("Initial system property: " +name +"=" +value, 3);
+      } catch (final Exception e) {
+        println("Failed to process system property: " +e, 1, e);
+      }
+    }
+  }
+
+
+  /**
+   * Add all entires in the given map to the set of system properties.
+   *
+   * @param props The map with name value pairs to add to the system
+   *              properties.
+   */
+  void mergeSystemProperties(Map<String, String> props) {
+    final Properties p = System.getProperties();
+    p.putAll(props);
+    System.setProperties(p);
+  }
+
+
+  /**
+   * Do the final processing of framework and system properties before
+   * creating the framework instance using them.
+   *
+   * <ul>
+   *   <li>Perform variable expansion on property values.
+   *   <li>System properties are then merged into the real system
+   *       properties.
+   *   <li>If <tt>writeSysProps()</tt> is <tt>true</tt> merge
+   *       framework properties into the real system properties.
+   *   <li>Add default properties.
+   * </ul>
+   */
+  void finalizeProperties() {
+    expandPropValues(sysProps, null);
+    expandPropValues(fwProps, sysProps);
+    addDefaultProps();
+
+    mergeSystemProperties(sysProps);
+    if(writeSysProps()) {
+      mergeSystemProperties(fwProps);
+      println("merged Framework to System properties " + fwProps, 2);
+    }
+
+  }
+
+
+  /**
+   * If any of the values in <tt>toExpand</tt> contains a sub-string
+   * like "<tt>${propname}</tt>" replace it with value of the named
+   * property in the map if found, else if <tt>fallback</tt> is
+   * non-null then replace with the value from that map if any.
+   *
+   * @param toExpand Map in which to expand variables in the values.
+   * @param fallback Optional map to get expansion values from if not
+   *                 found in the map to be expanded.
+   */
+  void expandPropValues(Map<String, String> toExpand, Map<String, String> fallback)
+  {
+    Map<String, String> all = null;
+
+    for (final Entry<String, String> entry : toExpand.entrySet()) {
+      String value = entry.getValue();
+
+      if(-1 != value.indexOf("${")) {
+        if (null==all) {
+          all = new HashMap<String, String>();
+          if (null!=fallback) {
+            all.putAll(fallback);
+          }
+          all.putAll(toExpand);
+        }
+        for (final Entry<String, String> allEntry : all.entrySet()) {
+          final String rk = "${" + allEntry.getKey() + "}";
+          final String rv = allEntry.getValue();
+          value = Util.replace(value, rk, rv);
+        }
+        entry.setValue(value);
+        println("Expanded property: " +entry.getKey() +"=" +value, 1);
+      }
+    }
+  }
+
+
+  /**
+   * If the last to elements in args "-xargs" or "--xargs" then expand
+   * it with arg as argument and replace the last element in args with
+   * the expansion. Otherwise just add arg to args.
+   * <p>
+   * This expansion is necessarry to allow redefinition of a system
+   * property after inclusion of xargs-file that sets the same property.
+   *
+   * @param args The list to add elements to.
+   * @param arg  The element to add.
+   */
+  private void addArg(List<String> args, String arg) {
+    if (0==args.size()) {
+      args.add(arg);
+    } else {
+      final String lastArg = args.get(args.size()-1);
+      if ("-xargs".equals(lastArg) || "--xargs".equals(lastArg)) {
+        final String[] exArgs = expandArgs( new String[]{ lastArg, arg } );
+        args.remove(args.size()-1);
+        for (final String exArg : exArgs) {
+          args.add(exArg);
+        }
+      } else {
+        args.add(arg);
+      }
+    }
+  }
+
+
+  /**
+   * Helper method when OS shell does not allow long command lines. This
+   * method has now days become the only reasonable way to start the
+   * framework due to the amount of properties.
+   *
+   * <p>
+   * Loads a specified file or URL and
+   * creates a new String array where each entry corresponds to entries
+   * in the loaded file.
+   * </p>
+   *
+   * <p>
+   * File format:<br>
+   *
+   * <ul>
+   *  <li>Each line starting with '-D' or '-F' is used dirctly as an
+   *      entry in the new command line array.
+   *  <li>Each line of length zero is ignored.
+   *  <li>Each line starting with '#' is ignored.
+   *  <li>Lines starting with '-' is used a command with optional argument
+   *      after space.
+   *  <li>All other lines is used directly as an entry to the new
+   *      command line array.
+   * </ul>
+   * </p>
+   *
+   * @param xargsPath The URL to load the xargs-file from. The URL
+   *                  protcoll defaults to "file:". File URLs are
+   *                  first search for in the parent directory of the
+   *                  current FW-dir, then in the current working directory.
+   * @param oldArgs   The command line arguments as it looks before
+   *                  the file named in <tt>xargsPath</tt> have been
+   *                  expanded.
+   * @return array with command line options loaded from
+   *         <tt>xargsPath</tt> suitable to be merged into
+   *         <tt>argv</tt> by the caller.
+   */
+  String [] loadArgs(String xargsPath, String[] oldArgs) {
+    // out result
+    final List<String> v = new ArrayList<String>();
+
+    BufferedReader in = null;
+    try {
+      if (XARGS_DEFAULT.equals(xargsPath)) {
+        processProperties(oldArgs);
+        in = getDefaultXArgs();
+      } else {
+        in = getXargsReader(xargsPath);
+      }
+      StringBuffer contLine = new StringBuffer();
+      String       line     = null;
+      String       tmpline  = null;
+      for(tmpline = in.readLine(); tmpline != null;
+          tmpline = in.readLine()) {
+        tmpline = tmpline.trim();
+
+        // check for line continuation char and
+        // build up line until a line without such a mark is found.
+        if(tmpline.endsWith("\\")) {
+          // found continuation mark, store actual line to
+          // buffered continuation line
+          tmpline = tmpline.substring(0, tmpline.length() - 1);
+          if(contLine == null) {
+            contLine = new StringBuffer(tmpline);
+          } else {
+            contLine.append(tmpline);
+          }
+          // read next line
+          continue;
+        } else {
+          // No continuation mark, gather stored line + newly read line
+          if(contLine != null) {
+            contLine.append(tmpline);
+            line     = contLine.toString();
+            contLine = null;
+          } else {
+            // this is the normal case if no continuation char is found
+            // or any buffered line is found
+            line = tmpline;
+          }
+        }
+
+        if(line.startsWith("-D")) {
+          // Preserve System property
+          addArg(v,line);
+        } else if(line.startsWith("-F")) {
+          // Preserve framework property
+          addArg(v,line);
+        } else if(line.startsWith("#")) {
+          // Ignore comments
+        } else if(line.startsWith("-")) {
+          // Split command that contains a ' ' int two args
+          final int i = line.indexOf(' ');
+          if (i != -1) {
+            addArg(v, line.substring(0,i));
+            line = line.substring(i).trim();
+            if(line.length() > 0) {
+              addArg(v, line);
+            }
+          } else {
+            addArg(v, line);
+          }
+        } else if(line.length() > 0) {
+          // Add argument
+          addArg(v,line);
+        }
+      }
+
+      // Write to framework properties. This should be the primary
+      // source for all code, including the framework itself.
+      // framework.props.setProperties(sysProps);
+
+    } catch (final Exception e) {
+      if(e instanceof RuntimeException) {
+        throw (RuntimeException)e;
+      }
+      throw new IllegalArgumentException("xargs loading failed: " + e);
+    } finally {
+      if (null!=in) {
+        try {
+          in.close();
+        } catch (final IOException ignore) { }
+      }
+    }
+
+    final String [] args2 = new String[v.size()];
+    v.toArray(args2);
+
+    return args2;
+  }
+
+
+  private BufferedReader getXargsReader(String xargsPath)
+      throws IOException {
+    BufferedReader in = null;
+    println("Searching for xargs file with '" +xargsPath +"'.", 2);
+
+    // 1) Search in parent dir of the current framework directory
+    final String fwDirStr = Util.getFrameworkDir(fwProps);
+
+    // avoid getAbsoluteFile() since some profiles don't have this
+    final File fwDir      = new File(new File(fwDirStr).getAbsolutePath());
+
+    // avoid getParentFile() since some profiles don't have this
+    final String defDirStr = fwDir.getParent();
+    final File   defDir    = defDirStr != null ? new File(defDirStr) : null;
+    if (null!=defDir) {
+      // Make the file object absolute before calling exists(), see
+      // http://forum.java.sun.com/thread.jspa?threadID=428403&messageID=2595075
+      // for details.
+      final File f = new File(new File(defDir,xargsPath).getAbsolutePath());
+      println(" trying " +f, 5);
+      if(f.exists()) {
+        println("Loading xargs file " + f, 1);
+        in = new BufferedReader(new FileReader(f));
+      }
+    }
+
+    // 2) Search in the current working directory
+    if (null==in) {
+      // Make the file object absolute before calling exists(), see
+      // http://forum.java.sun.com/thread.jspa?threadID=428403&messageID=2595075
+      // for details.
+      final File f = new File(new File(xargsPath).getAbsolutePath());
+      println(" trying " +f, 5);
+      if(f.exists()) {
+        println("Loading xargs file " + f, 1);
+        in = new BufferedReader(new FileReader(f));
+      }
+    }
+
+    // 3) Try argument as URL if it contains ':'.
+    if (in == null && xargsPath.indexOf(':') != -1) {
+      try {
+        println(" trying URL " +xargsPath, 5);
+        final URL url = new URL(xargsPath);
+        println("Loading xargs url " + url, 1);
+        in = new BufferedReader(new InputStreamReader(url.openStream()));
+      } catch (final MalformedURLException _ignore)  { }
+    }
+    // 4) Try as resource
+    if (null==in) {
+      ClassLoader cl = getClass().getClassLoader();
+      while (cl != null) {
+        InputStream is = cl.getResourceAsStream(xargsPath);
+        if (is != null) {
+          in = new BufferedReader(new InputStreamReader(is));
+          break;
+        }
+        cl = cl.getParent();
+      }
+    }
+    if (null==in) {
+      throw new FileNotFoundException("Didn't find xargs file: " + xargsPath);
+    }
+    return in;
+  }
+
+
+  // If a splash screen hash been shown, try to close it.
+  void closeSplash() {
+    // User reflection, and ignore errors since this is only supported
+    // in Java SE 6.
+    try {
+      final Class<?> splashScreenCls = Class.forName("java.awt.SplashScreen");
+      final Method getSplashScreenMethod
+        = splashScreenCls.getMethod("getSplashScreen", (Class[]) null);
+      final Object splashScreen = getSplashScreenMethod.invoke( (Object) null,
+                                                                (Object[])null);
+      if (null!=splashScreen) {
+        final Method closeMethod = splashScreenCls.getMethod("close",
+                                                             (Class[]) null);
+        closeMethod.invoke(splashScreen, (Object[]) null);
+      }
+    } catch (final Exception e) {
+      // Ignore any error.
+      println("close splash screen: ", 6, e);
+    }
+  }
+
+
+  /**
+   * Print string to System.out if level >= current verbosity.
+   *
+   * @param s String to print.
+   * @param level print level.
+   */
+  void println(String s, int level) {
+    println(s, level, null);
+  }
+
+
+  void println(String s, Bundle b) {
+    println(s + b.getLocation() + " (id#" + b.getBundleId() + ")", 1);
+  }
+
+
+  void println(String s, int level, Exception e) {
+    if(verbosity >= level) {
+      System.out.println((level > 0 ? ("#" + level + ": ") : "") + s);
+      if(e != null) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+
+  /**
+   * Report error and exit.
+   */
+  void error(final String s) {
+    error(s, null);
+  }
+
+
+  void error(final String s, final Throwable t) {
+    System.err.println("Error: " + s);
+    if(t != null) {
+      t.printStackTrace();
+    }
+    System.exit(1);
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/MainClassBundleActivator.java b/osgi/framework/src/org/knopflerfish/framework/MainClassBundleActivator.java
new file mode 100644
index 0000000..b8dee39
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/MainClassBundleActivator.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.lang.reflect.Method;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+
+/**
+ * BundleActivator implementation that can handle a jar file
+ * with just a Main-class attribute.
+ *
+ * <p>
+ * When the <tt>start</tt> method is called, a new thread is started for
+ * the bundle and the static <tt>main</tt> method is called with zero
+ * arguments.
+ * </p>
+ *
+ * <p>
+ * When the <tt>stop</tt> method is called, any static method named "stop"
+ * is called.
+ * </p>
+ */
+public class MainClassBundleActivator implements BundleActivator, Runnable {
+
+  Method startMethod = null;
+  Method stopMethod  = null;
+
+  Thread runner      = null;
+
+  String[] argv = new String[] { };
+
+  public MainClassBundleActivator(Class<?> clazz) throws Exception {
+    startMethod = clazz.getMethod("main", new Class[] { argv.getClass() });
+
+    // Check for optional stop method
+    try {
+      stopMethod  = clazz.getMethod("stop", new Class[] { });
+    } catch (final Exception ignored) {
+    }
+  }
+
+  public void start(BundleContext bc) throws BundleException {
+
+    try {
+      final BundleImpl b = (BundleImpl)bc.getBundle();
+      runner = new Thread(b.fwCtx.threadGroup,
+                          "start thread for executable jar file, bundle id="
+                          + b.getBundleId());
+      runner.start();
+    } catch (final Exception e) {
+      throw new BundleException("Failed to start main class",
+                                BundleException.UNSPECIFIED, e);
+    }
+  }
+
+  public void stop(BundleContext bc) throws BundleException {
+    if(stopMethod != null) {
+      try {
+        stopMethod.invoke(null, new Object[] { } );
+      } catch (final Exception e) {
+        throw new BundleException("Failed to stop main class",
+                                  BundleException.UNSPECIFIED, e);
+      }
+    }
+  }
+
+  public void run() {
+    try {
+      startMethod.invoke(null, new Object[] { argv } );
+    } catch (final Exception e) {
+      System.err.println("Failed to start executable jar file: " + e);
+    }
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/PackageAdminImpl.java b/osgi/framework/src/org/knopflerfish/framework/PackageAdminImpl.java
new file mode 100644
index 0000000..c3ee544
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/PackageAdminImpl.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.VersionRange;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.packageadmin.RequiredBundle;
+
+/**
+ * Framework service which allows bundle programmers to inspect the packages
+ * exported in the framework and eagerly update or uninstall bundles.
+ *
+ * If present, there will only be a single instance of this service registered
+ * in the framework.
+ *
+ * <p>
+ * The term <i>exported package</i> (and the corresponding interface
+ * {@link ExportedPackage}) refers to a package that has actually been exported
+ * (as opposed to one that is available for export).
+ *
+ * <p>
+ * Note that the information about exported packages returned by this service is
+ * valid only until the next time {@link #refreshPackages} is called. If an
+ * ExportedPackage becomes stale, (that is, the package it references has been
+ * updated or removed as a result of calling PackageAdmin.refreshPackages()),
+ * its getName() and getSpecificationVersion() continue to return their old
+ * values, isRemovalPending() returns true, and getExportingBundle() and
+ * getImportingBundles() return null.
+ *
+ * @see org.osgi.service.packageadmin.PackageAdmin
+ * @author Jan Stein
+ * @author Erik Wistrand
+ * @author Robert Shelley
+ * @author Philippe Laporte
+ * @author Mats-Ola Persson
+ */
+ at SuppressWarnings("deprecation")
+public class PackageAdminImpl implements PackageAdmin {
+
+  final static String SPEC_VERSION = "1.2";
+
+  private final FrameworkContext fwCtx;
+
+  volatile private Vector<Thread> refreshSync = new Vector<Thread>(1);
+
+  PackageAdminImpl(FrameworkContext fw) {
+    fwCtx = fw;
+  }
+
+  /**
+   * Gets the packages exported by the specified bundle.
+   *
+   * @param bundle The bundle whose exported packages are to be returned, or
+   *          <tt>null</tt> if all the packages currently exported in the
+   *          framework are to be returned. If the specified bundle is the
+   *          system bundle (that is, the bundle with id 0), this method returns
+   *          all the packages on the system classpath whose name does not start
+   *          with "java.". In an environment where the exhaustive list of
+   *          packages on the system classpath is not known in advance, this
+   *          method will return all currently known packages on the system
+   *          classpath, that is, all packages on the system classpath that
+   *          contains one or more classes that have been loaded.
+   *
+   * @return The array of packages exported by the specified bundle, or
+   *         <tt>null</tt> if the specified bundle has not exported any
+   *         packages.
+   */
+  public ExportedPackage[] getExportedPackages(Bundle bundle) {
+    final ArrayList<ExportedPackageImpl> pkgs = new ArrayList<ExportedPackageImpl>();
+    if (bundle != null) {
+      for (final Iterator<ExportPkg> i = ((BundleImpl)bundle).getExports(); i.hasNext();) {
+        final ExportPkg ep = i.next();
+        if (ep.isExported()) {
+          pkgs.add(new ExportedPackageImpl(ep));
+        }
+      }
+    } else {
+      for (final BundleImpl b : fwCtx.bundles.getBundles()) {
+        for (final Iterator<ExportPkg> i = b.getExports(); i.hasNext();) {
+          final ExportPkg ep = i.next();
+          if (ep.isExported()) {
+            pkgs.add(new ExportedPackageImpl(ep));
+          }
+        }
+      }
+    }
+    final int size = pkgs.size();
+    if (size > 0) {
+      return pkgs.toArray(new ExportedPackage[size]);
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Gets the exported packages for the specified package name.
+   *
+   * @param name The name of the exported packages to be returned.
+   *
+   * @return An array of the exported packages, or <code>null</code> if no
+   *         exported packages with the specified name exists.
+   */
+  public ExportedPackage[] getExportedPackages(String name) {
+    final Pkg pkg = fwCtx.resolver.getPkg(name);
+    ExportedPackage[] res = null;
+    if (pkg != null) {
+      synchronized (pkg) {
+        final int size = pkg.exporters.size();
+        if (size > 0) {
+          res = new ExportedPackage[size];
+          final Iterator<ExportPkg> i = pkg.exporters.iterator();
+          for (int pos = 0; pos < size;) {
+            res[pos++] = new ExportedPackageImpl(i.next());
+          }
+        }
+      }
+    }
+    return res;
+  }
+
+  /**
+   * Gets the ExportedPackage with the specified package name. All exported
+   * packages will be checked for the specified name. In an environment where
+   * the exhaustive list of packages on the system classpath is not known in
+   * advance, this method attempts to see if the named package is on the system
+   * classpath. This means that this method may discover an ExportedPackage that
+   * was not present in the list returned by <tt>getExportedPackages()</tt>.
+   *
+   * @param name The name of the exported package to be returned.
+   *
+   * @return The exported package with the specified name, or <tt>null</tt> if
+   *         no expored package with that name exists.
+   */
+  public ExportedPackage getExportedPackage(String name) {
+    final Pkg p = fwCtx.resolver.getPkg(name);
+    if (p != null) {
+      final ExportPkg ep = p.getBestProvider();
+      if (ep != null) {
+        return new ExportedPackageImpl(ep);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Forces the update (replacement) or removal of packages exported by the
+   * specified bundles.
+   *
+   * @see org.osgi.service.packageadmin.PackageAdmin#refreshPackages
+   */
+  public void refreshPackages(final Bundle[] bundles) {
+    refreshPackages(bundles, null);
+  }
+
+  void refreshPackages(final Bundle[] bundles, final FrameworkListener[] fl) {
+    fwCtx.perm.checkResolveAdminPerm();
+
+    boolean restart = false;
+    if (bundles != null) {
+      for (int i = 0; i < bundles.length; i++) {
+        fwCtx.checkOurBundle(bundles[i]);
+        if (((BundleImpl)bundles[i]).extensionNeedsRestart()) {
+          restart = true;
+          break;
+        }
+      }
+    } else {
+      restart = fwCtx.bundles.checkExtensionBundleRestart();
+    }
+    if (restart) {
+      try {
+        // will restart the framework.
+        fwCtx.systemBundle.update();
+      } catch (final BundleException ignored) {
+        /* this can't be happening. */
+      }
+      return;
+    }
+
+    final PackageAdminImpl thisClass = this;
+    synchronized (refreshSync) {
+      final Thread t = new Thread(fwCtx.threadGroup, "RefreshPackages") {
+        @Override
+        public void run() {
+          fwCtx.perm.callRefreshPackages0(thisClass, bundles, fl);
+        }
+      };
+      t.setDaemon(false);
+      refreshSync.add(t);
+      t.start();
+      // Wait for a refresh thread to start
+      try {
+        refreshSync.wait(500);
+      } catch (final InterruptedException ignore) {
+      }
+    }
+  }
+
+  /**
+   *
+   */
+  void refreshPackages0(final Bundle[] bundles, final FrameworkListener...fl) {
+    if (fwCtx.debug.resolver) {
+      fwCtx.debug.println("PackageAdminImpl.refreshPackages() starting");
+    }
+
+    final ArrayList<BundleImpl> startList = new ArrayList<BundleImpl>();
+    BundleImpl [] bi;
+
+    synchronized (fwCtx.resolver) {
+      final TreeSet<Bundle> zombies = fwCtx.resolver.getZombieAffected(bundles);
+      bi = zombies.toArray(new BundleImpl[zombies.size()]);
+
+      synchronized (refreshSync) {
+        refreshSync.notifyAll();
+      }
+      // Stop affected bundles and remove their classloaders
+      // in reverse start order
+      for (int bx = bi.length; bx-- > 0;) {
+        if (bi[bx].state == Bundle.ACTIVE || bi[bx].state == Bundle.STARTING) {
+          startList.add(0, bi[bx]);
+          try {
+            bi[bx].waitOnOperation(fwCtx.resolver, "PackageAdmin.refreshPackages", false);
+            final Exception be = bi[bx].stop0();
+            if (be != null) {
+              fwCtx.frameworkError(bi[bx], be);
+            }
+          } catch (final BundleException ignore) {
+            // Wait failed, we will try again
+          }
+        }
+      }
+
+      // Update the affected bundle states in normal start order
+      int startPos = startList.size() - 1;
+      BundleImpl nextStart = startPos >= 0 ? startList.get(startPos) : null;
+      for (int bx = bi.length; bx-- > 0;) {
+        Exception be = null;
+        switch (bi[bx].state) {
+        case Bundle.STARTING:
+        case Bundle.ACTIVE:
+          // Bundle must stop before we can continue
+          // We could hang forever here.
+          while (true) {
+            try {
+              bi[bx].waitOnOperation(fwCtx.resolver, "PackageAdmin.refreshPackages", true);
+              break;
+            } catch (final BundleException we) {
+              if (fwCtx.debug.resolver) {
+                fwCtx.debug
+                    .println("PackageAdminImpl.refreshPackages() timeout on bundle stop, retry...");
+              }
+              fwCtx.frameworkWarning(bi[bx], we);
+            }
+          }
+          be = bi[bx].stop0();
+          if (be != null) {
+            fwCtx.frameworkError(bi[bx], be);
+          }
+          if (nextStart != bi[bx]) {
+            startList.add(startPos + 1, bi[bx]);
+          }
+          // Fall through...
+        case Bundle.STOPPING:
+        case Bundle.RESOLVED:
+          bi[bx].setStateInstalled(true);
+          if (bi[bx] == nextStart) {
+            nextStart = --startPos >= 0 ? startList.get(startPos) : null;
+          }
+          // Fall through...
+        case Bundle.INSTALLED:
+        case Bundle.UNINSTALLED:
+          break;
+        }
+        bi[bx].purge();
+      }
+    }
+    if (fwCtx.debug.resolver) {
+      fwCtx.debug.println("PackageAdminImpl.refreshPackages() "
+                          + "all affected bundles now in state INSTALLED");
+    }
+
+    // Restart previously active bundles in normal start order
+    startBundles(startList);
+    final FrameworkEvent fe = new FrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED,
+                                           fwCtx.systemBundle, null);
+    fwCtx.listeners.frameworkEvent(fe, fl);
+    refreshSync.remove(Thread.currentThread());
+    if (fwCtx.debug.resolver) {
+      fwCtx.debug.println("PackageAdminImpl.refreshPackages() done.");
+    }
+  }
+
+
+  /**
+   * Start a list of bundles in order
+   *
+   * @param slist Bundles to start.
+   */
+  private void startBundles(List<BundleImpl> slist) {
+    // Sort in start order
+    // Resolve first to avoid dead lock
+    BundleImpl [] triggers = slist.toArray(new BundleImpl[slist.size()]);
+    for (final BundleImpl rb : slist) {
+      rb.getUpdatedState(triggers);
+    }
+    try {
+      fwCtx.resolverHooks.endResolve(triggers);
+    } catch (final BundleException be) {
+      // TODO Fix correct bundle
+      fwCtx.frameworkError(fwCtx.systemBundle, be);
+    }
+    for (final BundleImpl rb : slist) {
+      if (rb.getState() == Bundle.RESOLVED) {
+        try {
+          rb.start();
+        } catch (final BundleException be) {
+          fwCtx.frameworkError(rb, be);
+        }
+      }
+    }
+  }
+
+
+
+  /**
+   *
+   */
+  public boolean resolveBundles(Bundle[] bundles) {
+    fwCtx.perm.checkResolveAdminPerm();
+    synchronized (fwCtx.resolver) {
+      fwCtx.resolverHooks.checkResolveBlocked();
+      List<BundleImpl> bl = new ArrayList<BundleImpl>();
+      boolean res = true;
+      if (bundles != null) {
+        for (final Bundle bundle : bundles) {
+          if (bundle.getState() == Bundle.INSTALLED) {
+            bl.add((BundleImpl)bundle);
+          } else if (bundle.getState() == Bundle.UNINSTALLED) {
+            res = false;
+          }
+        }
+      } else {
+        for (final BundleImpl bundle : fwCtx.bundles.getBundles()) {
+          if (bundle.getState() == Bundle.INSTALLED) {
+            bl.add(bundle);
+          }
+        }
+      }
+      if (!bl.isEmpty()) {
+        final BundleImpl [] triggers = bl.toArray(new BundleImpl[bl.size()]);
+        // TODO Resolve all at once, so that we can handle resolver abort correctly! 
+        for (final Bundle bundle : bl) {
+          final BundleImpl b = (BundleImpl)bundle;
+          if (b.getUpdatedState(triggers) == Bundle.INSTALLED) {
+            res = false;
+          }
+        }
+        try {
+          fwCtx.resolverHooks.endResolve(triggers);
+        } catch (BundleException be) {
+          // TODO Fix correct bundle
+          fwCtx.frameworkError(fwCtx.systemBundle, be);
+        }
+      }
+      return res;
+    }
+  }
+
+  public RequiredBundle[] getRequiredBundles(String symbolicName) {
+    List<BundleGeneration> bgs = fwCtx.bundles.getBundleGenerations(symbolicName);
+    final ArrayList<RequiredBundleImpl> res = new ArrayList<RequiredBundleImpl>();
+    for (final BundleGeneration bg : bgs) {
+      if ((bg.bundle.isResolved() || bg.bundle.getRequiredBy().size() > 0)
+          && !bg.isFragment()) {
+        res.add(new RequiredBundleImpl(bg.bpkgs));
+      }
+    }
+    final int s = res.size();
+    if (s > 0) {
+      return res.toArray(new RequiredBundle[s]);
+    } else {
+      return null;
+    }
+  }
+
+  public Bundle[] getBundles(String symbolicName, String versionRange) {
+    final VersionRange vr = versionRange != null ? new VersionRange(versionRange.trim()) :
+        null;
+    final List<BundleGeneration> bgs = fwCtx.bundles.getBundles(symbolicName, vr);
+    final int size = bgs.size();
+    if (size > 0) {
+      final Bundle[] res = new Bundle[size];
+      final Iterator<BundleGeneration> i = bgs.iterator();
+      for (int pos = 0; pos < size;) {
+        res[pos++] = i.next().bundle;
+      }
+      return res;
+    } else {
+      return null;
+    }
+  }
+
+  public Bundle[] getFragments(Bundle bundle) {
+    if (bundle == null) {
+      return null;
+    }
+
+    final BundleGeneration bg = ((BundleImpl)bundle).current();
+
+    if (bg.isFragment()) {
+      return null;
+    }
+
+    if (bg.isFragmentHost()) {
+      @SuppressWarnings("unchecked")
+      final Vector<BundleGeneration> fix = (Vector<BundleGeneration>) bg.fragments.clone();
+      final Bundle[] r = new Bundle[fix.size()];
+      for (int i = fix.size() - 1; i >= 0; i--) {
+        r[i] = fix.get(i).bundle;
+      }
+      return r;
+    } else {
+      return null;
+    }
+  }
+
+  public Bundle[] getHosts(Bundle bundle) {
+    final BundleImpl b = (BundleImpl) bundle;
+    if (b != null) {
+      final Vector<BundleGeneration> h = b.getHosts(false);
+      if (h != null) {
+        final Bundle[] r = new Bundle[h.size()];
+        int pos = 0;
+        for (final BundleGeneration bg : h) {
+          r[pos++] = bg.bundle;
+        }
+        return r;
+      }
+    }
+    return null;
+  }
+
+  public Bundle getBundle(@SuppressWarnings("rawtypes") Class  clazz) {
+    final ClassLoader cl = clazz.getClassLoader();
+    if (cl instanceof BundleClassLoader) {
+      return ((BundleClassLoader)cl).getBundle();
+    } else {
+      return null;
+    }
+  }
+
+  public int getBundleType(Bundle bundle) {
+    final BundleGeneration bg = ((BundleImpl)bundle).current();
+    return bg.isFragment() && !bg.isExtension() ? BUNDLE_TYPE_FRAGMENT : 0;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/PermissionOps.java b/osgi/framework/src/org/knopflerfish/framework/PermissionOps.java
new file mode 100644
index 0000000..8aa47ee
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/PermissionOps.java
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2006-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This is a wrapper class for operations that requires some kind of security
+ * checks or privileged operations.
+ */
+class PermissionOps {
+
+  void init() {
+  }
+
+
+  void registerService() {
+  }
+
+
+  boolean checkPermissions() {
+    return false;
+  }
+
+
+  //
+  // Permission checks
+  //
+
+  boolean okClassAdminPerm(Bundle b) {
+    return true;
+  }
+
+
+  void checkExecuteAdminPerm(Bundle b) {
+  }
+
+
+  void checkExtensionLifecycleAdminPerm(Bundle b) {
+  }
+
+
+  void checkExtensionLifecycleAdminPerm(Bundle b, Object checkContext) {
+  }
+
+
+  void checkLifecycleAdminPerm(Bundle b) {
+  }
+
+
+  void checkLifecycleAdminPerm(Bundle b, Object checkContext) {
+  }
+
+
+  void checkListenerAdminPerm(Bundle b) {
+  }
+
+
+  void checkMetadataAdminPerm(Bundle b) {
+  }
+
+
+  void checkResolveAdminPerm() {
+  }
+
+
+  void checkResourceAdminPerm(Bundle b) {
+  }
+
+
+  boolean okResourceAdminPerm(Bundle b) {
+    return true;
+  }
+
+
+  void checkContextAdminPerm(Bundle b) {
+  }
+
+
+  void checkStartLevelAdminPerm() {
+  }
+
+
+  void checkGetProtectionDomain() {
+  }
+
+
+  void checkWeaveAdminPerm(Bundle b) {
+  }
+
+  //
+  // Bundle permission checks
+  //
+
+  boolean okFragmentBundlePerm(BundleImpl b) {
+    return true;
+  }
+
+
+  boolean okHostBundlePerm(BundleImpl b) {
+    return true;
+  }
+
+
+  boolean okProvideBundlePerm(BundleImpl b) {
+    return true;
+  }
+
+
+  boolean okRequireBundlePerm(BundleImpl b) {
+    return true;
+  }
+
+
+  boolean okAllPerm(BundleImpl b) {
+    return true;
+  }
+
+
+  //
+  // Package permission checks
+  //
+
+  boolean hasExportPackagePermission(ExportPkg ep) {
+    return true;
+  }
+
+
+  boolean hasImportPackagePermission(BundleImpl b, ExportPkg ep) {
+    return true;
+  }
+
+
+  //
+  // Service permission checks
+  //
+
+  void checkRegisterServicePerm(String clazz) {
+  }
+
+
+  void checkGetServicePerms(ServiceReference<?> sr) {
+  }
+
+
+  boolean okGetServicePerms(ServiceReference<?> sr) {
+    return true;
+  }
+
+
+  void filterGetServicePermission(Set<ServiceRegistrationImpl<?>> srs) {
+  }
+
+  //
+  // Capability and Requirement checks
+  //
+
+  boolean hasProvidePermission(BundleCapabilityImpl bc) {
+    return true;
+  }
+
+
+  boolean hasRequirePermission(BundleRequirementImpl br) {
+    return true;
+  }
+
+
+  boolean hasRequirePermission(BundleRequirementImpl br, BundleCapabilityImpl bc) {
+    return true;
+  }
+
+  //
+  // AdaptPermission checks
+  //
+
+  <A> void checkAdaptPerm(BundleImpl b, Class<A> type) {
+  }
+
+  //
+  // BundleArchive secure operations
+  //
+
+  BundleResourceStream callGetBundleResourceStream(final BundleArchive archive,
+                                                   final String name, final int ix) {
+    return archive.getBundleResourceStream(name, ix);
+  }
+
+
+  Enumeration<String> callFindResourcesPath(final BundleArchive archive, final String path) {
+    return archive.findResourcesPath(path);
+  }
+
+
+  //
+  // BundleClassLoader secure operations
+  //
+
+  Object callSearchFor(final BundleClassLoader cl, final String name, final String pkg,
+                       final String path, final BundleClassLoader.SearchAction action,
+                       final int options,
+                       final BundleClassLoader requestor, final HashSet<BundleClassLoader> visited) {
+    return cl.searchFor(name, pkg, path, action, options, requestor, visited);
+  }
+
+
+  String callFindLibrary0(final BundleClassLoader cl, final String name) {
+    return cl.findLibrary0(name);
+  }
+
+
+  //
+  // BundleImpl secure operations
+  //
+
+  void callFinalizeActivation(final BundleImpl b) throws BundleException {
+    b.finalizeActivation();
+  }
+
+
+  BundleThread createBundleThread(final FrameworkContext fc) {
+    return new BundleThread(fc);
+  }
+
+
+  void callUpdate0(final BundleImpl b, final InputStream in, final boolean wasActive)
+      throws BundleException {
+    b.update0(in, wasActive, null);
+  }
+
+
+  void callUninstall0(final BundleImpl b) {
+    b.uninstall0();
+  }
+
+
+  void callSetAutostartSetting(final BundleImpl b, final int setting) {
+    b.setAutostartSetting0(setting);
+  }
+
+
+  HeaderDictionary callGetHeaders0(final BundleGeneration bg, final String locale) {
+    return bg.getHeaders0(locale);
+  }
+
+
+  Vector<URL> callFindEntries(final BundleGeneration bg, final String path,
+                              final String filePattern, final boolean recurse) {
+    return bg.findEntries(path, filePattern, recurse);
+  }
+
+
+  BundleClassLoader newBundleClassLoader(final BundleGeneration bg) throws BundleException {
+    return new BundleClassLoader(bg);
+  }
+
+
+  Vector<URL> getBundleClassPathEntries(final BundleGeneration bg, final String name, final boolean onlyFirst) {
+    return bg.getBundleClassPathEntries(name, onlyFirst);
+  }
+
+
+  AccessControlContext getAccessControlContext(BundleImpl bundle) {
+    return null;
+  }
+
+  //
+  // Bundles Secure operation
+  //
+
+  BundleImpl callInstall0(final Bundles bs, final String location, final InputStream in, final Bundle caller)
+      throws BundleException {
+    return bs.install0(location, in, null, caller);
+  }
+
+
+  //
+  // Listeners Secure operations
+  //
+
+  void callBundleChanged(final FrameworkContext fwCtx, final BundleEvent evt) {
+    fwCtx.listeners.bundleChanged(evt);
+  }
+
+
+  void callServiceChanged(final FrameworkContext fwCtx, final Collection<ServiceListenerEntry> receivers,
+                          final ServiceEvent evt, final Set<ServiceListenerEntry> matchBefore) {
+    fwCtx.listeners.serviceChanged(receivers, evt, matchBefore);
+  }
+
+
+  //
+  // PackageAdmin secure operations
+  //
+
+  void callRefreshPackages0(final PackageAdminImpl pa, final Bundle[] bundles, final FrameworkListener[] fl) {
+    pa.refreshPackages0(bundles, fl);
+  }
+
+
+  //
+  // ServiceRegisterationImpl secure operations
+  //
+
+  <S> S callGetService(final ServiceRegistrationImpl<S> sr, final Bundle b) {
+    @SuppressWarnings("unchecked")
+    final ServiceFactory<S> srf = (ServiceFactory<S>)sr.service;
+    return srf.getService(b, sr);
+  }
+
+
+  <S> void callUngetService(final ServiceRegistrationImpl<S> sr,
+                            final Bundle b,
+                            final S instance)
+  {
+    @SuppressWarnings("unchecked")
+    final ServiceFactory<S> srf = (ServiceFactory<S>)sr.service;
+    srf.ungetService(b, sr, instance);
+  }
+
+
+  //
+  // StartLevelController secure operations
+  //
+
+  void callSetStartLevel(final BundleImpl b, final int startlevel) {
+    b.setStartLevel(startlevel);
+  }
+
+  void callSetInitialBundleStartLevel0(final StartLevelController slc,
+                                       final int startlevel) {
+    slc.setInitialBundleStartLevel0(startlevel, true);
+  }
+
+  //
+  // SystemBundle secure operations
+  //
+
+  void callShutdown(final SystemBundle sb, final boolean restart) {
+    sb.shutdown(restart);
+  }
+
+
+  //
+  // Permissions package functionality
+  //
+
+  ProtectionDomain getProtectionDomain(final BundleGeneration bg) {
+    return null;
+  }
+
+
+  /**
+   * Get bundle URL using a bundle: spec and the BundleURLStreamHandler.
+   *
+   * <p>
+   * Note:<br>
+   * Creating bundle: URLs by the URL(String) constructor will only work if the
+   * the fw URL handler is registered, which may be turned off.
+   * </p>
+   */
+  URL getBundleURL(FrameworkContext fwCtx, String s) throws MalformedURLException {
+    return new URL(null, s,
+        fwCtx.urlStreamHandlerFactory.createURLStreamHandler(BundleURLStreamHandler.PROTOCOL));
+  }
+
+
+  //
+  // Privileged system calls
+  //
+
+  ClassLoader getClassLoaderOf(final Class<?> c) {
+    return c.getClassLoader();
+  }
+
+
+  //
+  // Cleaning
+  //
+
+  /**
+   * Purge all cached information for specified bundle.
+   */
+  void purge(BundleImpl b, ProtectionDomain pc) {
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Pkg.java b/osgi/framework/src/org/knopflerfish/framework/Pkg.java
new file mode 100644
index 0000000..01ae72e
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Pkg.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+
+import org.osgi.framework.Version;
+
+
+/**
+ * Class representing a package.
+ *
+ * @author Jan Stein
+ */
+class Pkg {
+
+  final String pkg;
+
+  final ArrayList<ExportPkg> exporters = new ArrayList<ExportPkg>(1);
+
+  final ArrayList<ImportPkg> importers = new ArrayList<ImportPkg>();
+
+  final ArrayList<ExportPkg> providers = new ArrayList<ExportPkg>(1);
+
+
+  /**
+   * Create package entry.
+   */
+  Pkg(String pkg) {
+    this.pkg = pkg;
+  }
+
+
+  /**
+   * Add an exporter entry from this package.
+   *
+   * @param pe ExportPkg to add.
+   */
+  synchronized void addExporter(ExportPkg ep) {
+    final int i = Math.abs(Util.binarySearch(exporters, epComp, ep) + 1);
+    exporters.add(i, ep);
+    ep.attachPkg(this);
+  }
+
+
+  /**
+   * Remove an exporter entry from this package.
+   *
+   * @param p ExportPkg to remove.
+   * @return false if package is provider otherwise true.
+   */
+  synchronized boolean removeExporter(ExportPkg p) {
+    providers.remove(p);
+    exporters.remove(p);
+    p.detachPkg();
+    return true;
+  }
+
+
+  /**
+   * Add an importer entry to this package.
+   *
+   * @param pe ImportPkg to add.
+   */
+  synchronized void addImporter(ImportPkg ip) {
+    final int i = Math.abs(Util.binarySearch(importers, ipComp, ip) + 1);
+    importers.add(i, ip);
+    ip.attachPkg(this);
+  }
+
+
+  /**
+   * Remove an importer entry from this package.
+   *
+   * @param p ImportPkg to remove.
+   */
+  synchronized void removeImporter(ImportPkg ip) {
+    importers.remove(ip);
+    ip.detachPkg();
+  }
+
+
+  /**
+   * Add an exporter entry as a provider for this package.
+   * If exporter already is provider don't add duplicate.
+   *
+   * @param pe ExportPkg to add.
+   */
+  synchronized void addProvider(ExportPkg ep) {
+    final int i = Util.binarySearch(providers, epComp, ep);
+    if (i < 0) {
+      providers.add(-i - 1, ep);
+    }
+  }
+
+
+  /**
+   * Get best provider. Best provider is provider
+   * with highest version number.
+   *
+   * @return Provider ExportPkg or null if none..
+   */
+  synchronized ExportPkg getBestProvider() {
+    if (!providers.isEmpty()) {
+      return providers.get(0);
+    } else {
+      ExportPkg best = null;
+      // See if there are any resolved exporters.
+      for (final ExportPkg exportPkg : exporters) {
+        final ExportPkg ep = exportPkg;
+        if (ep.bpkgs.bg.bundle.isResolved()) {
+          if (best == null || best.version.compareTo(ep.version) < 0) {
+            best = ep;
+          }
+        }
+      }
+      return best;
+    }
+  }
+
+
+  /**
+   * Check if this package has any exporters or importers.
+   *
+   * @return true if no exporters or importers, otherwise false.
+   */
+  synchronized boolean isEmpty() {
+    return exporters.size() == 0 && importers.size() == 0;
+  }
+
+
+  @Override
+  public String toString() {
+    return toString(2);
+  }
+
+
+  public String toString(int level) {
+    final StringBuffer sb = new StringBuffer();
+    sb.append("Pkg[");
+
+    if(level > 0) {
+      sb.append("pkg=" + pkg);
+    }
+    if(level > 1) {
+      sb.append(", providers=" + providers);
+    }
+    if(level > 2) {
+      sb.append(", exporters=" + exporters);
+    }
+    sb.append("]");
+
+    return sb.toString();
+  }
+
+
+  static final Util.Comparator<ExportPkg, ExportPkg> epComp = new Util.Comparator<ExportPkg, ExportPkg>() {
+    /**
+     * Version compare two ExportPkg objects. If same version, order according
+     * to bundle id, lowest first.
+     *
+     * @param a
+     *          ExportPkg to compare.
+     * @param b
+     *          ExportPkg to compare.
+     * @return Return 0 if equals, negative if first object is less than second
+     *         object and positive if first object is larger then second object.
+     */
+    public int compare(ExportPkg a, ExportPkg b)
+    {
+      int d = a.version.compareTo(b.version);
+      if (d == 0) {
+        final long ld = b.bpkgs.bg.bundle.id - a.bpkgs.bg.bundle.id;
+        if (ld < 0)
+          d = -1;
+        else if (ld > 0)
+          d = 1;
+      }
+      return d;
+    }
+  };
+
+  static final Util.Comparator<ImportPkg, ImportPkg> ipComp = new Util.Comparator<ImportPkg, ImportPkg>() {
+    /**
+     * Version compare two ImportPkg objects. If same version, order according
+     * to bundle id, lowest first.
+     *
+     * @param a
+     *          ImportPkg to compare.
+     * @param b
+     *          ImportPkg to compare.
+     * @return Return 0 if equals, negative if first object is less than second
+     *         object and positive if first object is larger then second object.
+     * @exception ClassCastException
+     *              if object is not a ImportPkg object.
+     */
+    public int compare(ImportPkg a, ImportPkg b)
+    {
+      int d;
+      if (a.packageRange == null) {
+        d = b.packageRange == null ? 0 : Version.emptyVersion.compareTo(b.packageRange.getLeft());
+      } else if (b.packageRange == null) {
+        d = a.packageRange.getLeft().compareTo(Version.emptyVersion);        
+      } else {
+        d = a.packageRange.getLeft().compareTo(b.packageRange.getLeft());
+      }
+      if (d == 0) {
+        final long ld = b.bpkgs.bg.bundle.id - a.bpkgs.bg.bundle.id;
+        if (ld < 0)
+          d = -1;
+        else if (ld > 0)
+          d = 1;
+      }
+      return d;
+    }
+  };
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/PropertiesDictionary.java b/osgi/framework/src/org/knopflerfish/framework/PropertiesDictionary.java
new file mode 100644
index 0000000..e94be9f
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/PropertiesDictionary.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.osgi.framework.Constants;
+
+/**
+ * Creates a copy of the properties associated with a service registration.
+ * Checks that all the keys are strings and adds the class names.
+ * Note! Creation of PropertiesDictionary must be synchronized.
+ *
+ * @author Jan Stein
+ */
+class PropertiesDictionary extends Dictionary<String, Object>
+{
+  private final String [] keys;
+  private final Object [] values;
+  private int size;
+
+  private int ocIndex = -1;
+  private int sidIndex = -1;
+
+  private static long nextServiceID = 1;
+
+  PropertiesDictionary(@SuppressWarnings("rawtypes") Dictionary in) {
+    final int max_size = in != null ? in.size() + 2 : 2;
+    keys = new String[max_size];
+    values = new Object[max_size];
+    size = 0;
+    if (in != null) {
+      try {
+        for (@SuppressWarnings("rawtypes")
+        final Enumeration e = in.keys(); e.hasMoreElements();) {
+          final String key = (String) e.nextElement();
+          if (ocIndex == -1 && key.equalsIgnoreCase(Constants.OBJECTCLASS)) {
+            ocIndex = size;
+          } else if (sidIndex == -1
+                     && key.equalsIgnoreCase(Constants.SERVICE_ID)) {
+            sidIndex = size;
+          } else {
+            for (int i = size - 1; i >= 0; i--) {
+              if (key.equalsIgnoreCase(keys[i])) {
+                throw new IllegalArgumentException(
+                                                   "Several entries for property: "
+                                                       + key);
+              }
+            }
+          }
+          keys[size] = key;
+          values[size++] = in.get(key);
+        }
+      } catch (final ClassCastException ignore) {
+        throw new IllegalArgumentException(
+                                           "Properties contains key that is not of type java.lang.String");
+      }
+    }
+  }
+
+  PropertiesDictionary(@SuppressWarnings("rawtypes") Dictionary in,
+                       String[] classes, Long sid)
+  {
+    this(in);
+    if (ocIndex == -1) {
+      keys[size] = Constants.OBJECTCLASS;
+      ocIndex = size++;
+    }
+    values[ocIndex] = classes;
+    if (sidIndex == -1) {
+      keys[size] = Constants.SERVICE_ID;
+      sidIndex = size++;
+    }
+    values[sidIndex] = sid != null ? sid : new Long(nextServiceID++);
+  }
+
+  @Override
+  public Object get(Object key) {
+    if (key == Constants.OBJECTCLASS) {
+      return (ocIndex >= 0) ? values[ocIndex] : null;
+    } else if (key == Constants.SERVICE_ID) {
+      return (sidIndex >= 0) ? values[sidIndex] : null;
+    }
+    for (int i = size - 1; i >= 0; i--) {
+      if (((String)key).equalsIgnoreCase(keys[i])) {
+	return values[i];
+      }
+    }
+    return null;
+  }
+
+
+  public String [] keyArray() {
+    final String [] nkeys = new String[size];
+    System.arraycopy(keys, 0, nkeys, 0, size);
+    return nkeys;
+  }
+
+
+  @Override
+  public int size() {
+    return size;
+  }
+
+  // These aren't used but we implement to fulfill Dictionary class
+
+  @Override
+  public Enumeration<Object> elements() { throw new UnsupportedOperationException("Not implemented"); }
+
+  @Override
+  public boolean isEmpty() { throw new UnsupportedOperationException("Not implemented"); }
+
+  @Override
+  public Enumeration<String> keys() { throw new UnsupportedOperationException("Not implemented"); }
+
+  @Override
+  public Object put(String k, Object v) { throw new UnsupportedOperationException("Not implemented"); }
+
+  @Override
+  public Object remove(Object k) { throw new UnsupportedOperationException("Not implemented"); }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Queue.java b/osgi/framework/src/org/knopflerfish/framework/Queue.java
new file mode 100644
index 0000000..e69a5e8
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Queue.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Vector;
+
+/**
+ * The <code>Queue</code> class represents a first-in-first-out (FIFO) queue of
+ * objects.
+ *
+ * @author Per Lundgren
+ */
+public class Queue<E> extends Vector<E> {
+
+  private static final long serialVersionUID = 1L;
+  private int m_nMaxSize = -1;
+  private boolean queueClosed = false;
+
+  // ==================== Queue ====================
+  /**
+   ** Constructs an Queue with the specifies maximum size.
+   **
+   ** @param size
+   *          maximum queue size.
+   */
+  public Queue(int size) {
+    m_nMaxSize = size;
+  }
+
+  // ==================== insert ====================
+  /**
+   ** Inserts an item into the queue. If there are threads blocked on
+   ** <code>remove</code>, one of them is unblocked.
+   **
+   ** @param item
+   *          the item to be inserted.
+   ** @exception IndexOutOfBoundsException
+   *              if maximum queue size is reached.
+   */
+  public synchronized void insert(E item) throws IndexOutOfBoundsException {
+    // Check if queue is full
+    if (m_nMaxSize > 0 && size() >= m_nMaxSize)
+      throw new IndexOutOfBoundsException("Queue full");
+
+    addElement(item);
+    notify();
+  }
+
+  // ==================== insertFirst ====================
+  /**
+   ** Inserts an item first into the queue. If there are threads blocked on
+   ** <code>remove</code>, one of them is unblocked.
+   **
+   ** @param item
+   *          the item to be inserted.
+   */
+  public synchronized void insertFirst(E item) {
+    insertElementAt(item, 0);
+    notify();
+  }
+
+  // ==================== remove ====================
+  /**
+   ** Removes and returns the first item in the queue. If the queue is empty, the
+   * calling thread will block.
+   **
+   ** @param timeout
+   *          timeout in seconds.
+   ** @return The first item in the queue, or <code>null</code> if a timeout
+   *         occurred. To distinguish timeouts, <code>null</code> items should
+   *         not be inserted in the queue.
+   */
+  public synchronized E removeWait(float timeout) {
+    E obj = null;
+
+    // If queue is empty wait for object to be inserted
+    if (isEmpty() && !queueClosed) {
+      try {
+        if (timeout > 0) {
+          wait(Math.round(timeout * 1000.0f));
+        } else
+          wait();
+      } catch (final InterruptedException e) {
+      }
+    }
+
+    if (queueClosed || isEmpty()) {
+      return null;
+    }
+
+    obj = firstElement();
+    removeElementAt(0);
+
+    return obj;
+  }
+
+  // ==================== remove ====================
+  /**
+   ** Removes and returns the first object in the queue. Same as
+   * <code>remove(float timeout)</code> but this function blocks forever.
+   **
+   ** @return The first item in the queue.
+   */
+  public E remove() {
+    return removeWait(0);
+  }
+
+  // ==================== close ====================
+  /**
+   ** Closes the queue, i.e. wakes up all threads blocking on a call to remove().
+   */
+
+  public synchronized void close() {
+    queueClosed = true;
+    notifyAll();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ReferenceURLStreamHandler.java b/osgi/framework/src/org/knopflerfish/framework/ReferenceURLStreamHandler.java
new file mode 100644
index 0000000..8f22588
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ReferenceURLStreamHandler.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.*;
+import java.net.*;
+
+
+/**
+ * Reference URL handling, used for accepting file: references.
+ *
+ * Accepts URLs on the form
+ * <pre>
+ *  reference:file URL]
+ * </pre>
+ * Where <tt>[file URL]</tt> is any valid file: URL. 
+ *
+ * <p>
+ * <tt>openConnection</tt> simply returns the URLConnection
+ * created by removing the <tt>reference:</tt> prefix.
+ * </p>
+ *
+ */
+public class ReferenceURLStreamHandler extends URLStreamHandler {
+
+  final public static String PROTOCOL = "reference";
+
+  ReferenceURLStreamHandler() {
+    super();
+  }
+
+  /**
+   *
+   * @throws IOException if the specified URL is not a reference to a
+   *                     file: URL
+   */
+  public URLConnection openConnection(URL url) throws IOException {
+    URL actual = new URL(getActual(url));
+    
+    if(!"file".equals(actual.getProtocol())) {
+      throw 
+	new IOException("Only file: URLs are allowed as references, got " + url);
+    }
+
+    return actual.openConnection();
+  }
+
+
+  /**
+   * Get the actual URL string represented by the specified 
+   * <tt>reference:</tt> URL.
+   *
+   * @throws IllegalArgumentException if the specified URL does not
+   *                                  have a reference: protocol.
+   */
+  protected static String getActual(URL u) {
+    String s = u.toString();
+    if(!s.startsWith(PROTOCOL + ":")) {
+      throw new IllegalArgumentException("URL " + u + " does not start with " + 
+					 PROTOCOL + ":");
+    }
+    return s.substring(PROTOCOL.length() + 1);
+  }    
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/RemoveOnlyCollection.java b/osgi/framework/src/org/knopflerfish/framework/RemoveOnlyCollection.java
new file mode 100644
index 0000000..982b072
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/RemoveOnlyCollection.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ *
+ */
+class RemoveOnlyCollection<E> extends AbstractCollection<E> {
+
+  final Collection<E> org;
+  public RemoveOnlyCollection(Collection<E> values) {
+    org = values;
+  }
+
+  @Override
+  public boolean add(E obj) {
+    throw new UnsupportedOperationException("objects can only be removed");
+  }
+
+  @Override
+  public boolean addAll(Collection<? extends E> objs) {
+    throw new UnsupportedOperationException("objects can only be removed");
+  }
+
+  @Override
+  public Iterator<E> iterator() {
+    return org.iterator();
+  }
+
+  @Override
+  public boolean remove(Object o) {
+    return org.remove(o);
+  }
+
+  @Override
+  public int size() {
+    return org.size();
+  }
+}
\ No newline at end of file
diff --git a/osgi/framework/src/org/knopflerfish/framework/RequireBundle.java b/osgi/framework/src/org/knopflerfish/framework/RequireBundle.java
new file mode 100644
index 0000000..2a60d52
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/RequireBundle.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2006-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.VersionRange;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+
+class RequireBundle
+  implements BundleRequirement, Comparable<RequireBundle>
+{
+  // To maintain the creation order in the osgi.wiring.bundle name space.
+  static private int requireBundleCount = 0;
+  final int orderal = ++requireBundleCount;
+
+  final BundlePackages requestor;
+  final String name;
+  final String visibility;
+  final String resolution;
+  final VersionRange bundleRange;
+  BundlePackages bpkgs = null;
+  final Map<String,Object> attributes;
+  final Map<String,String> directives;
+
+
+  /**
+   * A re-required bundle for fragment hosts.
+   * @param parent    The fragment require bundle object to re-require.
+   * @param requestor The bundle packages of the fragment host that
+   *                  re-requires a required bundle from one of its
+   *                  fragments.
+   */
+  RequireBundle(RequireBundle  parent, BundlePackages requestor)
+  {
+    this.requestor  = requestor;
+    this.name       = parent.name;
+    this.visibility = parent.visibility;
+    this.resolution = parent.resolution;
+    this.bundleRange= parent.bundleRange;
+    this.attributes = parent.attributes;
+    this.directives = parent.directives;
+  }
+
+  /**
+   * A require bundle requirement.
+   *
+   * @param requestor
+   *          The bundle packages of the fragment host that requires a bundle.
+   * @param he
+   *          The parsed require bundle header.
+   */
+  RequireBundle(final BundlePackages requestor, final HeaderEntry he)
+  {
+    this.requestor = requestor;
+    this.name = he.getKey();
+
+    final Map<String,String> dirs = he.getDirectives();
+    final String visibility = dirs.get(Constants.VISIBILITY_DIRECTIVE);
+    if (visibility != null) {
+      this.visibility = visibility.intern();
+      if (this.visibility!=Constants.VISIBILITY_PRIVATE &&
+          this.visibility!=Constants.VISIBILITY_REEXPORT ) {
+        throw new IllegalArgumentException
+          ("Invalid directive : '"
+           +Constants.VISIBILITY_DIRECTIVE +":="+this.visibility
+           +"' in manifest header '"
+           +Constants.REQUIRE_BUNDLE +": " +this.name
+           +"' of bundle with id " +this.requestor.bg.bundle.getBundleId()
+           +" ("+this.requestor.bg.symbolicName+")"
+           +". The value must be either '"
+           +Constants.VISIBILITY_PRIVATE  +"' or '"
+           +Constants.VISIBILITY_REEXPORT +"'.");
+      }
+    } else {
+      this.visibility = Constants.VISIBILITY_PRIVATE;
+    }
+
+    final String resolution = dirs.get(Constants.RESOLUTION_DIRECTIVE);
+    if (resolution != null) {
+      this.resolution = resolution.intern();
+      if (this.resolution!=Constants.RESOLUTION_MANDATORY &&
+          this.resolution!=Constants.RESOLUTION_OPTIONAL ) {
+        throw new IllegalArgumentException
+          ("Invalid directive : '"
+           +Constants.RESOLUTION_DIRECTIVE +":="+this.resolution
+           +"' in manifest header '"
+           +Constants.REQUIRE_BUNDLE +": " +this.name
+           +"' of bundle with id " +this.requestor.bg.bundle.getBundleId()
+           +" ("+this.requestor.bg.symbolicName+")"
+           +". The value must be either '"
+           +Constants.RESOLUTION_MANDATORY +"' or '"
+           +Constants.RESOLUTION_OPTIONAL  +"'.");
+      }
+    } else {
+      this.resolution = Constants.RESOLUTION_MANDATORY;
+    }
+
+    this.attributes = he.getAttributes();
+    final String range = (String) attributes.remove(Constants.BUNDLE_VERSION_ATTRIBUTE);
+    if (range != null) {
+      this.bundleRange = new VersionRange(range);
+    } else {
+      this.bundleRange = null;
+    }
+    final Filter filter = toFilter();
+    if (null!=filter) {
+      dirs.put(Constants.FILTER_DIRECTIVE, filter.toString());
+    }
+    this.directives = Collections.unmodifiableMap(dirs);
+  }
+
+
+  /**
+   * Check if this object completely overlap specified RequireBundle.
+   *
+   * @return True if we overlap, otherwise false.
+   */
+  boolean overlap(RequireBundle rb) {
+    if (visibility.equals(Constants.VISIBILITY_REEXPORT) &&
+        !rb.visibility.equals(Constants.VISIBILITY_REEXPORT)) {
+      return false;
+    }
+    if (resolution.equals(Constants.RESOLUTION_MANDATORY) &&
+        !rb.resolution.equals(Constants.RESOLUTION_MANDATORY)) {
+      return false;
+    }
+    return  bundleRange == null || !bundleRange.intersection(rb.bundleRange).isEmpty();
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public String getNamespace()
+  {
+    return BundleRevision.BUNDLE_NAMESPACE;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public Map<String, String> getDirectives()
+  {
+    return directives;
+  }
+
+
+  private Filter toFilter()
+  {
+    final StringBuffer sb = new StringBuffer(80);
+    boolean multipleConditions = false;
+
+    sb.append('(');
+    sb.append(BundleRevision.BUNDLE_NAMESPACE);
+    sb.append('=');
+    sb.append(name);
+    sb.append(')');
+
+    if (bundleRange != null) {
+      sb.append(bundleRange.toFilterString(Constants.BUNDLE_VERSION_ATTRIBUTE));
+      multipleConditions = true;
+    }
+
+    for (final Entry<String,Object> entry : attributes.entrySet()) {
+      sb.append('(');
+      sb.append(entry.getKey());
+      sb.append('=');
+      sb.append(entry.getValue().toString());
+      sb.append(')');
+      multipleConditions = true;
+    }
+
+    if (multipleConditions) {
+      sb.insert(0, "(&");
+      sb.append(')');
+    }
+    try {
+      return FrameworkUtil.createFilter(sb.toString());
+    } catch (final InvalidSyntaxException _ise) {
+      throw new RuntimeException("Internal error, createFilter: '" +sb.toString() +"': " +_ise.getMessage());
+    }
+  }
+
+
+  // BundleRequirement method
+  @SuppressWarnings("unchecked")
+  @Override
+  public Map<String, Object> getAttributes()
+  {
+    return Collections.EMPTY_MAP;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public BundleRevision getRevision()
+  {
+    return requestor.bg.bundleRevision;
+  }
+
+
+  @Override
+  public BundleRevision getResource() {
+    return requestor.bg.bundleRevision;
+  }
+
+
+  // BundleRequirement method
+  @Override
+  public boolean matches(BundleCapability capability)
+  {
+    if (BundleRevision.BUNDLE_NAMESPACE.equals(capability.getNamespace())) {
+      return toFilter().matches(capability.getAttributes());
+    }
+    return false;
+  }
+
+
+  @Override
+  public int compareTo(RequireBundle o)
+  {
+    return this.orderal - o.orderal;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/RequiredBundleImpl.java b/osgi/framework/src/org/knopflerfish/framework/RequiredBundleImpl.java
new file mode 100644
index 0000000..c0edecd
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/RequiredBundleImpl.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2006-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.service.packageadmin.RequiredBundle;
+
+/**
+ * Implementation for required bundle interface.
+ *
+ */
+ at SuppressWarnings("deprecation")
+public class RequiredBundleImpl implements RequiredBundle
+{
+
+  /**
+   */
+  private final BundlePackages bpkgs;
+
+  /**
+   *
+   */
+  RequiredBundleImpl(BundlePackages b) {
+    bpkgs = b;
+  }
+
+
+  /**
+   * Returns the symbolic name of this required bundle.
+   *
+   * @return The symbolic name of this required bundle.
+   */
+  public String getSymbolicName() {
+    return bpkgs.bg.symbolicName;
+  }
+
+
+  /**
+   * Returns the bundle associated with this required bundle.
+   *
+   * @return The bundle, or <code>null</code> if this
+   *         <code>RequiredBundle</code> object has become stale.
+   */
+  public Bundle getBundle() {
+    if (bpkgs.isRegistered()) {
+      return bpkgs.bg.bundle;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Returns the bundles that currently require this required bundle.
+   *
+   * <p>
+   * If this required bundle is required and then re-exported by another
+   * bundle then all the requiring bundles of the re-exporting bundle are
+   * included in the returned array.
+   *
+   * @return An array of bundles currently requiring this required bundle, or
+   *         <code>null</code> if this <code>RequiredBundle</code> object
+   *         has become stale.
+   */
+  public Bundle[] getRequiringBundles() {
+    if (bpkgs.isRegistered()) {
+      final List<BundlePackages> rl = bpkgs.bg.bundle.getRequiredBy();
+      final Bundle[] res = new Bundle[rl.size()];
+      for (int i = rl.size() - 1; i >= 0; i--) {
+        res[i] = rl.get(i).bg.bundle;
+      }
+      return res;
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns the version of this required bundle.
+   *
+   * @return The version of this required bundle, or
+   *         {@link Version#emptyVersion} if no version information is
+   *         available.
+   */
+  public Version getVersion() {
+    return bpkgs.bg.version;
+  }
+
+
+  /**
+   * Returns <code>true</code> if the bundle associated with this
+   * <code>RequiredBundle</code> object has been updated or uninstalled.
+   *
+   * @return <code>true</code> if the reqiured bundle has been updated or
+   *         uninstalled, or if the <code>RequiredBundle</code> object has
+   *         become stale; <code>false</code> otherwise.
+   */
+  public boolean isRemovalPending() {
+    return !bpkgs.bg.isCurrent();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Resolver.java b/osgi/framework/src/org/knopflerfish/framework/Resolver.java
new file mode 100644
index 0000000..7908bc2
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Resolver.java
@@ -0,0 +1,1421 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+
+/**
+ * Here we handle all the java packages that are imported and exported within
+ * the framework.
+ *
+ * @author Jan Stein, Erik Wistrand
+ */
+class Resolver {
+
+  static final String RESOLVER_HOOK_VETO = "ResolverHook Veto";
+
+  /**
+   * Framework for bundle.
+   */
+  final FrameworkContext framework;
+
+  /**
+   * All exported and imported packages.
+   */
+  private final Hashtable<String, Pkg> packages = new Hashtable<String, Pkg>();
+
+  /*
+   * All BundleCapabilities that can be or is resolved.
+   */
+  private final Capabilities capabilities = new Capabilities();
+
+  /**
+   * Temporary set of resolved bundles during a resolve operation.
+   */
+  private volatile HashSet<BundleGeneration> tempResolved = null;
+
+  /**
+   * Temporary map of package providers during a resolve operation.
+   */
+  private HashMap<String, ExportPkg> tempProvider = null;
+
+  /**
+   * Temporary map of required bundle connections done during a resolve
+   * operation.
+   */
+  private HashMap<RequireBundle, BundlePackages> tempRequired = null;
+
+  /**
+   * Temporary set of package providers that are black listed in the resolve
+   * operation.
+   */
+  private HashSet<ExportPkg> tempBlackList = null;
+
+  /**
+   * Temporary set of bundle checked package uses back track.
+   */
+  private HashSet<BundlePackages> tempBackTracked = null;
+
+  /**
+   * Temporary list of bundle wires during a resolve operation.
+   */
+  private ArrayList<BundleWireImpl> tempWires = null;
+
+  /**
+   * Temporary to keep track exports that causes colliding imports. 
+   */
+  private ExportPkg tempCollision;
+
+  /**
+   * Thread currently doing resolve
+   */
+  private Object resolveThread;
+
+  /* Statistics to check need for tempBlackList */
+  int tempBlackListChecks = 0;
+  int tempBlackListHits = 0;
+
+
+  /**
+   * Construct Packages object.
+   */
+  Resolver(FrameworkContext fw) {
+    framework = fw;
+  }
+
+
+  /**
+   * Clear all datastructures in this object.
+   */
+  void clear() {
+    packages.clear();
+    if (null != tempResolved) {
+      tempResolved.clear();
+    }
+    if (null != tempProvider) {
+      tempProvider.clear();
+    }
+    if (null != tempRequired) {
+      tempRequired.clear();
+    }
+    if (null != tempBlackList) {
+      tempBlackList.clear();
+    }
+    if (null != tempBackTracked) {
+      tempBackTracked.clear();
+    }
+    if (null != tempWires) {
+      tempWires.clear();
+    }
+  }
+
+
+  /**
+   * Register all packages a bundle needs to export and import. If it is
+   * registered by the system bundle, export it immediately.
+   *
+   * @param exports Exported packages.
+   * @param imports Imported packages.
+   */
+  synchronized void registerCapabilities(Map<String, List<BundleCapabilityImpl>> capabilities,
+                                         Iterator<ExportPkg> exports,
+                                         Iterator<ImportPkg> imports) {
+    this.capabilities.addCapabilities(capabilities);
+    while (exports.hasNext()) {
+      final ExportPkg pe = exports.next();
+      Pkg p = packages.get(pe.name);
+      if (p == null) {
+        p = new Pkg(pe.name);
+        packages.put(pe.name, p);
+      }
+      p.addExporter(pe);
+      if (framework.debug.resolver) {
+        framework.debug.println("registerPackages: export, " + pe);
+      }
+    }
+    while (imports.hasNext()) {
+      final ImportPkg pe = imports.next();
+      Pkg p = packages.get(pe.name);
+      if (p == null) {
+        p = new Pkg(pe.name);
+        packages.put(pe.name, p);
+      }
+      p.addImporter(pe);
+      if (framework.debug.resolver) {
+        framework.debug.println("registerPackages: import, " + pe);
+      }
+    }
+  }
+
+
+  /**
+   * Dynamically check and register a dynamic package import.
+   *
+   * @param pe ImportPkg import to add.
+   * @return ExportPkg for package provider.
+   * @throws BundleException Resolver hook complaint.
+   */
+  synchronized ExportPkg registerDynamicImport(ImportPkg ip) throws BundleException {
+    if (framework.debug.resolver) {
+      framework.debug.println("registerDynamicImport: try " + ip);
+    }
+    ExportPkg res = null;
+    final Pkg p = packages.get(ip.name);
+    if (p != null) {
+      // Wait for other resolve operations to
+      while (tempResolved != null) {
+        checkThread();
+        try {
+          wait();
+        } catch (final InterruptedException _ignore) { }
+      }
+      resolveThread = Thread.currentThread();
+      tempResolved = new HashSet<BundleGeneration>();
+      tempProvider = new HashMap<String, ExportPkg>();
+      tempRequired = new HashMap<RequireBundle, BundlePackages>();
+      tempBlackList = new HashSet<ExportPkg>();
+      tempBackTracked = new HashSet<BundlePackages>();
+      backTrackUses(ip);
+      tempBackTracked = null;
+      final List<ImportPkg> pkgs = Collections.singletonList(ip);
+      p.addImporter(ip);
+      try {
+        if (resolvePackages(pkgs.iterator(), null)) {
+          registerNewProviders(ip.bpkgs.bg.bundle);
+          res = tempProvider.get(ip.name);
+          ip.provider = res;
+        } else {
+          p.removeImporter(ip);
+        }
+      } catch (BundleException be) {
+        p.removeImporter(ip);
+        throw be;
+      } finally {
+        tempBlackList = null;
+        tempProvider = null;
+        tempRequired = null;
+        tempResolved = null;
+        resolveThread = null;
+        notifyAll();
+      }
+    }
+    if (framework.debug.resolver) {
+      framework.debug.println("registerDynamicImport: Done for " + ip.name + ", res = " + res);
+    }
+    return res;
+  }
+
+
+  /**
+   * Unregister bundle packages in framework. If we find exported packages that
+   * has been selected as providers don't unregister them unless the parameter
+   * force is true. If not all exporters were removed, the don't remove any
+   * importers
+   *
+   * @param exports Exported packages.
+   * @param imports Imported packages.
+   * @param force If true force unregistration of package providers.
+   * @return True if all packages were successfully unregistered, otherwise
+   *         false.
+   */
+  synchronized boolean unregisterCapabilities(Map<String, List<BundleCapabilityImpl>> capabilities,
+                                              Iterator<ExportPkg> exports,
+                                              Iterator<ImportPkg> imports,
+                                              boolean force) {
+    // Check if somebody other than ourselves use our exports
+    if (!force) {
+      final ArrayList<ExportPkg> saved = new ArrayList<ExportPkg>();
+      for (final Iterator<ExportPkg> i = exports; i.hasNext();) {
+        final ExportPkg ep = i.next();
+        saved.add(ep);
+        // Is the exporting bundle wired to any bundle via Require-Bundle
+        if (ep.bpkgs.isRequired()) {
+          if (framework.debug.resolver) {
+            framework.debug.println("unregisterPackages: Failed to unregister, "
+                                    + ep + " is still in use via Require-Bundle.");
+          }
+          markAsZombies(saved, exports);
+          return false;
+        }
+        final Pkg p = ep.pkg;
+        if (p.providers.contains(ep)) {
+          for (final Object element : p.importers) {
+            final ImportPkg ip = (ImportPkg)element;
+            if (ep == ip.provider && ep.bpkgs != ip.bpkgs) {
+              if (framework.debug.resolver) {
+                framework.debug.println("unregisterPackages: Failed to unregister, "
+                                        + ep + " is still in use via import-package.");
+              }
+              markAsZombies(saved, exports);
+              return false;
+            }
+          }
+        }
+      }
+      exports = saved.iterator();
+      for (List<BundleCapabilityImpl> lbc : capabilities.values()) {
+        for (BundleCapabilityImpl bc : lbc) {
+          if (bc.isWired()) {
+            return false;
+          }
+        }
+      }
+    }
+
+    while (exports.hasNext()) {
+      final ExportPkg ep = exports.next();
+      final Pkg p = ep.pkg;
+      if (framework.debug.resolver) {
+        framework.debug.println("unregisterPackages: unregister export - " + ep);
+      }
+      p.removeExporter(ep);
+      if (p.isEmpty()) {
+        packages.remove(ep.name);
+      }
+    }
+
+    while (imports.hasNext()) {
+      final ImportPkg ip = imports.next();
+      final Pkg p = ip.pkg;
+      if (framework.debug.resolver) {
+        framework.debug.println("unregisterPackages: unregister import - "
+                                + ip.pkgString());
+      }
+      p.removeImporter(ip);
+      if (p.isEmpty()) {
+        packages.remove(ip.name);
+      }
+    }
+    this.capabilities.removeCapabilities(capabilities);
+    for (List<BundleCapabilityImpl> lbc : capabilities.values()) {
+      for (BundleCapabilityImpl bc : lbc) {
+        bc.removeWires();
+      }
+    }
+    return true;
+  }
+
+
+  /**
+   * Try to resolve all packages for a bundle.
+   *
+   * @param bundle Bundle owning packages.
+   * @param pkgs List of packages to be resolved.
+   * @return String with reason for failure or null if all were resolved.
+   * @throws BundleException Resolver hook complaint.
+   */
+  synchronized String resolve(BundleGeneration bg, BundlePackages importBpkgs, BundleImpl[] triggers) throws BundleException {
+    String res = null;
+    if (framework.debug.resolver) {
+      framework.debug.println("resolve: " + bg);
+    }
+    // If we enter with tempResolved set, it means that we already have
+    // resolved bundles. Check that it is true!
+    if (tempResolved != null) {
+      if (tempResolved.remove(bg)) {
+        return null;
+      }
+      // Not true, wait before starting new resolve process.
+      checkThread();
+      do {
+ 	     try {
+  	      wait();
+    	  } catch (final InterruptedException _ignore) { }
+      } while (tempResolved != null);
+   	}
+
+    resolveThread = Thread.currentThread();
+    tempResolved = new HashSet<BundleGeneration>();
+    try {
+      if (!addTempResolved(bg)) {
+        res = RESOLVER_HOOK_VETO;
+      }
+    } catch (BundleException be) {
+      tempResolved = null;
+      resolveThread = null;
+      notifyAll();
+      throw be;
+    }
+    if (res == null) {
+      final BundleGeneration sbg = checkBundleSingleton(bg);
+      if (sbg != null) {
+        res = "Singleton bundle failed to resolve because " +
+              sbg.bundle + " is already resolved";
+      }
+    }
+    if (res != null) {
+      tempResolved = null;
+      resolveThread = null;
+      notifyAll();
+      return res;
+    }
+    
+    HashSet<ExportPkg> baseTempBlackList = new HashSet<ExportPkg>();
+    tempBlackList = new HashSet<ExportPkg>();
+    tempProvider = new HashMap<String, ExportPkg>();
+    tempRequired = new HashMap<RequireBundle, BundlePackages>();
+    tempWires = new ArrayList<BundleWireImpl>();
+    try {
+      while (true) {
+        tempCollision = null;
+        res = checkBundleRequirements(bg);
+        if (res == null) {
+          res = checkRequireBundle(bg);
+          if (res == null) {
+            StringBuffer failReason = new StringBuffer(
+                "Missing package(s) or can not resolve all of the them:");
+            if (resolvePackages(importBpkgs.getImports(), failReason)) {
+              if (triggers != null && triggers.length == 1) {
+                framework.resolverHooks.endResolve(triggers);
+              }
+              registerNewWires();
+              registerNewProviders(bg.bundle);
+              res = null;
+            } else {
+              res = failReason.toString();
+            }
+          }
+        }
+        if (res != null && tempCollision != null) {
+          baseTempBlackList.add(tempCollision);
+          tempResolved.clear();
+          tempResolved.add(bg);
+          tempBlackList.clear();
+          tempBlackList.addAll(baseTempBlackList);
+          tempProvider.clear();
+          tempRequired.clear();
+          tempWires.clear();
+        } else {
+          break;
+        }
+      }
+    } finally {
+      tempResolved = null;
+      tempProvider = null;
+      tempRequired = null;
+      tempBlackList = null;
+      tempWires = null;
+      resolveThread = null;
+      notifyAll();
+    }
+    if (framework.debug.resolver) {
+      framework.debug.println("resolve: Done for " + bg);
+    }
+    return res;
+  }
+
+
+  private boolean addTempResolved(BundleGeneration bg) throws BundleException {
+    if (framework.resolverHooks.filterResolvable(bg)) {
+      tempResolved.add(bg);
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * Get Pkg object for named package.
+   *
+   * @param pkg Package name.
+   * @return Pkg that represents the package, null if no such package.
+   */
+  Pkg getPkg(String pkg) {
+    return packages.get(pkg);
+  }
+
+
+  /**
+   * Get bundles affected by zombie packages.
+   *
+   * Compute a graph of bundles starting with the specified bundles. If no
+   * bundles are specified, compute a graph of bundles starting with all
+   * exporting a zombie package. Any bundle that imports a package that is
+   * currently exported by a bundle in the graph (or requires a bundle that is
+   * in the graph) is added to the graph. The graph is fully constructed when
+   * there is no bundle outside the graph that imports a package from a bundle
+   * in the graph (and there is no bundle outside the graph that requires a
+   * bundle in the graph). The graph may contain <tt>UNINSTALLED</tt> bundles
+   * that are currently still exporting packages.
+   *
+   * @param bundles Initial bundle set.
+   * @return List of bundles affected.
+   */
+  synchronized TreeSet<Bundle> getZombieAffected(Bundle[] bundles) {
+    // set of affected bundles will be in start-level/bundle-id order
+    final TreeSet<Bundle> affected = new TreeSet<Bundle>(new Comparator<Bundle>() {
+      public int compare(Bundle b1, Bundle b2) {
+        int dif = ((BundleImpl) b1).getStartLevel() - ((BundleImpl) b2).getStartLevel();
+        if (dif == 0) {
+          dif = (int)(b1.getBundleId() - b2.getBundleId());
+        }
+        return dif;
+      }
+
+      public boolean equals(Object o) {
+        return ((o != null) && getClass().equals(o.getClass()));
+      }
+    });
+
+    if (bundles == null) {
+      if (framework.debug.resolver) {
+        framework.debug.println("getZombieAffected: check - null");
+      }
+      framework.bundles.getRemovalPendingBundles(affected);
+      framework.bundles.getUnattachedBundles(affected);
+    } else {
+      for (final Bundle bundle : bundles) {
+        final BundleImpl tmp = (BundleImpl)bundle;
+        if (tmp != null) {
+          if (framework.debug.resolver) {
+            framework.debug.println("getZombieAffected: check - " + bundle);
+          }
+          affected.add(tmp);
+        }
+      }
+    }
+    closure(affected);
+    return affected;
+  }
+
+
+  synchronized void closure(Set<Bundle> bundles) {
+    final ArrayList<Bundle> moreBundles = new ArrayList<Bundle>(bundles);
+    for (int i = 0; i < moreBundles.size(); i++) {
+      final BundleImpl b = (BundleImpl) moreBundles.get(i);
+      for (final Iterator<ExportPkg> j = b.getExports(); j.hasNext();) {
+        final ExportPkg ep = j.next();
+        if (ep.pkg != null && ep.pkg.providers.contains(ep)) {
+          for (final ImportPkg ip : ep.getPackageImporters()) {
+            final BundleImpl ib = ip.bpkgs.bg.bundle;
+            if (!bundles.contains(ib)) {
+              moreBundles.add(ib);
+              if (framework.debug.resolver) {
+                framework.debug.println("closure: added importing bundle - "
+                                        + ib);
+              }
+              bundles.add(ib);
+            }
+          }
+        }
+        for (final Object element : ep.bpkgs.getRequiredBy()) {
+          final BundlePackages rbpkgs = (BundlePackages)element;
+          final BundleImpl rb = rbpkgs.bg.bundle;
+          if (!bundles.contains(rb)) {
+            moreBundles.add(rb);
+            if (framework.debug.resolver) {
+              framework.debug.println("closure: added requiring bundle - "
+                                      + rb);
+            }
+            bundles.add(rb);
+          }
+        }
+      }
+      for (BundleGeneration bbg : b.generations) {
+        List<BundleWireImpl> bwl = bbg.getCapabilityWires();
+        if (bwl != null) {
+          for (final BundleWireImpl bcw : bwl) {
+            BundleImpl bbr = bcw.getRequirerGeneration().bundle;
+            if (!bundles.contains(bbr)) {
+              moreBundles.add(bbr);
+              if (framework.debug.resolver) {
+                framework.debug.println("closure: added wired bundle - "
+                                        + bbr);
+              }
+              bundles.add(bbr);
+            }
+          }
+        }
+        if (bbg.isFragmentHost()) {
+          @SuppressWarnings("unchecked")
+          final Vector<BundleGeneration> fix = (Vector<BundleGeneration>)bbg.fragments.clone();
+          for (BundleGeneration fbg : fix) {
+            if (!bundles.contains(fbg.bundle)) {
+              moreBundles.add(fbg.bundle);
+              if (framework.debug.resolver) {
+                framework.debug.println("closure: added fragment bundle - "
+                                        + fbg.bundle);
+              }
+              bundles.add(fbg.bundle);
+            }
+          }
+        }
+        if (bbg.isFragment()) {
+          final Set<BundleImpl> hosts = bbg.getResolvedHosts();
+          for (BundleImpl hb : hosts) {
+            if (!bundles.contains(hb)) {
+              moreBundles.add(hb);
+              if (framework.debug.resolver) {
+                framework.debug.println("closure: added fragment host bundle - " + hb);
+              }
+              bundles.add(hb);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  //
+  // Private methods.
+  //
+
+  /**
+   * Backtrack package "uses" so that we can initialize tempProvider with
+   * relevent packages. This perhaps to ambitious.
+   *
+   * @param ip Imported package to back-track from.
+   * @return True if we found bundles "using" this package, otherwise we return
+   *         false.
+   */
+  private boolean backTrackUses(ImportPkg ip) {
+    if (framework.debug.resolver) {
+      framework.debug.println("backTrackUses: check - " + ip.pkgString());
+    }
+    if (tempBackTracked.contains(ip.bpkgs)) {
+      return false;
+    }
+    tempBackTracked.add(ip.bpkgs);
+    final Iterator<ExportPkg> i = getPackagesProvidedBy(ip.bpkgs).iterator();
+    if (i.hasNext()) {
+      do {
+        final ExportPkg ep = i.next();
+        boolean foundUses = false;
+        for (final Object element : ep.pkg.importers) {
+          final ImportPkg iip = (ImportPkg)element;
+          if (iip.provider == ep) {
+            if (backTrackUses(iip)) {
+              foundUses = true;
+            }
+          }
+        }
+        if (!foundUses) {
+          checkUses(ep.uses, ep, ep.bpkgs);
+        }
+      } while (i.hasNext());
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+
+  /**
+   * Mark list of exporters as zombie packages.
+   *
+   * @param exporters List of ExportPkg.
+   */
+  private void markAsZombies(List<ExportPkg> e1, Iterator<ExportPkg> e2) {
+    for (final ExportPkg exportPkg : e1) {
+      exportPkg.zombie = true;
+    }
+    while (e2.hasNext()) {
+      e2.next().zombie = true;
+    }
+  }
+
+
+  /**
+   * Get packages provide by specified BundlePackages.
+   *
+   * @param bpkgs BundlePackages exporting packages.
+   * @return List of packages exported by BundlePackages.
+   */
+  private Collection<ExportPkg> getPackagesProvidedBy(BundlePackages bpkgs) {
+    final ArrayList<ExportPkg> res = new ArrayList<ExportPkg>();
+    for (final Iterator<ExportPkg> i = bpkgs.getExports(); i.hasNext();) {
+      final ExportPkg ep = i.next();
+      if (ep.pkg.providers.contains(ep)) {
+        res.add(ep);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Check if a bundle has all its package dependencies resolved.
+   *
+   * @param pkgs List of packages to be resolved.
+   * @param failReason If not null, puts resolve fail message here.
+   * @return True if all packages resolvable, otherwise false.
+   * @throws BundleException Resolver hook throw an exception.
+   */
+  private boolean resolvePackages(Iterator<ImportPkg> pkgs, StringBuffer failReason)
+      throws BundleException {
+    StringBuffer pkgFail = failReason != null ? new StringBuffer() : null;
+    boolean res = true;
+    tempCollision = null;
+    while (pkgs.hasNext()) {
+      ExportPkg provider = null;
+      final ImportPkg ip = pkgs.next();
+      if (ip.provider != null) {
+        framework.frameworkError(ip.bpkgs.bg.bundle,
+            new Exception("resolvePackages: InternalError1!"));
+      }
+      if (framework.debug.resolver) {
+        framework.debug.println("resolvePackages: check - " + ip.pkgString());
+      }
+      List<ExportPkg> possibleProvider = new LinkedList<ExportPkg>();
+      for (ExportPkg ep : ip.pkg.exporters) {
+        if (ip.checkAttributes(ep)) {
+          if (ip.bpkgs == ep.bpkgs || ip.checkPermission(ep)) {
+            possibleProvider.add(ep);
+          } else if (pkgFail != null) {
+            newFailReason(pkgFail, "No import permission", ep);
+          }
+        } else if (pkgFail != null) {
+          newFailReason(pkgFail, "Attributes don't match", ep);
+        }
+      }
+      if (pkgFail != null) {
+        if (possibleProvider.isEmpty() && pkgFail.length() == 0) {
+          pkgFail.append("No providers found.");
+        }
+      }
+      framework.resolverHooks.filterMatches((BundleRequirement)ip,
+                                            (Collection<? extends BundleCapability>) possibleProvider);
+      if (pkgFail != null && pkgFail.length() == 0 && possibleProvider.isEmpty()) {
+        pkgFail.append("Resolver hooks filtered all possible providers");
+      }
+      provider = tempProvider.get(ip.name);
+      if (provider != null) {
+        if (framework.debug.resolver) {
+          framework.debug.println("resolvePackages: " + ip.name
+              + " - has temporary provider - "
+                                  + provider);
+        }
+        if (!possibleProvider.contains(provider)) {
+          String r = "provider not used, rejected by constraints or resolver hooks - "
+                     + provider;
+          if (framework.debug.resolver) {
+            framework.debug.println("resolvePackages: " + ip.name
+                                    + " - " + r);
+          }
+          if (possibleProvider.isEmpty()) {
+            provider = null;
+          } else {
+            // Try with different provider
+            tempCollision = provider;
+            return false;
+          }
+        }
+      } else {
+        for (ExportPkg ep : ip.pkg.providers) {
+          if (!possibleProvider.contains(ep)) {
+            continue;
+          }
+          if (tempBlackList.contains(ep)) {
+            possibleProvider.remove(ep);
+            tempBlackListHits++;
+            if (pkgFail != null) {
+              newFailReason(pkgFail, "Collied with previous selection", ep);
+            }
+            continue;
+          }
+          if (ep.zombie) {
+            continue;
+          }
+          final HashMap<String, ExportPkg> oldTempProvider = tempProviderClone();
+          if (checkUses(ep.uses, ep, ep.bpkgs)) {
+            provider = ep;
+            break;
+          } else {
+            tempProvider = oldTempProvider;
+            tempBlackList.add(ep);
+            possibleProvider.remove(ep);
+            if (pkgFail != null) {
+              newFailReason(pkgFail, "Provider rejected because of uses directive ", ep);
+            }
+          }
+        }
+        if (provider == null) {
+          provider = pickProvider(ip, possibleProvider, pkgFail);
+        }
+        if (provider != null) {
+          tempProvider.put(ip.pkg.pkg, provider);
+        }
+      }
+      if (provider == null) {
+        if (ip.mustBeResolved()) {
+          res = false;
+          if (failReason != null) {
+            failReason.append(FWProps.NL);
+            failReason.append(ip.pkgString());
+            failReason.append(" -- ");
+            failReason.append(pkgFail);
+          }
+        } else {
+          if (framework.debug.resolver) {
+            framework.debug.println("resolvePackages: Ok, no provider for optional " + ip.name);
+          }
+        }
+      }
+      if (pkgFail != null) {
+        pkgFail.setLength(0);
+      }
+    }
+    return res;
+  }
+
+
+  @SuppressWarnings("unchecked")
+  private HashMap<String, ExportPkg> tempProviderClone() {
+    return (HashMap<String, ExportPkg>)tempProvider.clone();
+  }
+
+
+  /**
+   * Find a provider for specified package.
+   *
+   * @param pkg Package to find provider for.
+   * @return Package entry that can provide.
+   * @throws BundleException Resolver hook throw an exception.
+   */
+  private ExportPkg pickProvider(ImportPkg ip, List<ExportPkg> possibleProvider,
+                                 StringBuffer failReason)
+                                     throws BundleException {
+    if (framework.debug.resolver) {
+      framework.debug.println("pickProvider: for - " + ip);
+    }
+    boolean zombieExists = false;
+    for (Iterator<ExportPkg> i = possibleProvider.iterator(); i.hasNext();) {
+      ExportPkg ep = i.next();
+      tempBlackListChecks++;
+      if (tempBlackList.contains(ep)) {
+        tempBlackListHits++;
+        i.remove();
+        if (failReason != null) {
+          newFailReason(failReason, "Collied with previous selection", ep);
+        }
+        continue;
+      }
+      if (ip.bpkgs == ep.bpkgs) {
+        if (framework.debug.resolver) {
+          framework.debug.println("pickProvider: internal wire ok for - " + ep);
+        }
+        ip.internalOk = ep;
+      } else if (!ep.checkPermission()) {
+        if (framework.debug.resolver) {
+          framework.debug.println("pickProvider: no export permission for - " + ep);
+        }
+        i.remove();
+        if (failReason != null) {
+          newFailReason(failReason, "No export permission for", ep);
+        }
+        continue;
+      }
+      if (ep.bpkgs.bg.bundle.state != Bundle.INSTALLED) {
+        final HashMap<String, ExportPkg> oldTempProvider = tempProviderClone();
+        if (checkUses(ep.uses, ep, ep.bpkgs)) {
+          if (framework.debug.resolver) {
+            framework.debug.println("pickProvider: " + ip +
+                                    " - got resolved provider - " + ep);
+          }
+          return ep;
+        } else {
+          tempProvider = oldTempProvider;
+          tempBlackList.add(ep);
+          i.remove();
+          if (failReason != null) {
+            newFailReason(failReason, "Uses directive block", ep);
+          }
+          continue;
+        }
+      }
+      if (ep.zombie) {
+        zombieExists  = true;
+      }
+    }
+    if (zombieExists) {
+      for (Iterator<ExportPkg> iep = possibleProvider.iterator(); iep.hasNext();) {
+        final ExportPkg ep = iep.next();
+        if (tempResolved.contains(ep.bpkgs.bg)) {
+          if (framework.debug.resolver) {
+            framework.debug.println("pickProvider: " + ip + " - got temp provider - " + ep);
+          }
+          return ep;
+        } else if (ep.zombie) {
+          final HashMap<String, ExportPkg> oldTempProvider = tempProviderClone();
+          if (checkUses(ep.uses, ep, ep.bpkgs)) {
+            if (framework.debug.resolver) {
+              framework.debug.println("pickProvider: " + ip +
+                                      " - got zombie provider - " + ep);
+            }
+            return ep;
+          }
+          tempProvider = oldTempProvider;
+          tempBlackList.add(ep);
+          if (failReason != null) {
+            newFailReason(failReason, "Uses directive block", ep);
+          }
+          iep.remove();
+        }
+      }
+    }
+    ExportPkg savedCollision = null;
+    for (final ExportPkg ep : possibleProvider) {
+      if (framework.debug.resolver) {
+        framework.debug.println("pickProvider: check possible provider - " + ep);
+      }
+      if (checkResolve(ep.bpkgs.bg, ep)) {
+        if (framework.debug.resolver) {
+          framework.debug.println("pickProvider: " + ip + " - got provider - " + ep);
+        }
+        return ep;
+      }
+      if (tempCollision != null  && savedCollision  == null) {
+        // Save collision so that we can backtrack and try to avoid collision
+        // if we don't find a provider.
+        savedCollision = tempCollision;
+      }
+      if (failReason != null) {
+        newFailReason(failReason, "Could not resolve exporting bundle", ep);
+      }
+    }
+    if (framework.debug.resolver) {
+      framework.debug.println("pickProvider: " + ip + " - found no provider");
+    }
+    if (savedCollision != null) {
+      tempCollision = savedCollision;
+    }
+    return null;
+  }
+
+
+  private void newFailReason(StringBuffer failReason, String string, ExportPkg ep) {
+    if (failReason.length() > 0) {
+      failReason.append(" || ");
+    }
+    failReason.append(string);
+    if (ep != null) {
+      failReason.append(" - ");
+      failReason.append(ep);
+    }
+    failReason.append(".");
+  }
+
+
+  /**
+   * Check if a bundle can be resolved. If resolvable, then the objects
+   * tempResolved, tempProvider and tempBlackList are updated. Bundle must be in
+   * installed state.
+   *
+   * @param bg BundleGeneration to be checked.
+   * @param ep ExportPkg that must be exported by bundle.
+   * @return true if resolvable otherwise false.
+   * @throws BundleException Resolver hook throw an exception.
+   */
+  private boolean checkResolve(BundleGeneration bg, ExportPkg ep) throws BundleException {
+    if (tempResolved.contains(bg)) {
+      return true;
+    }
+    if (checkBundleSingleton(bg) == null) {
+      boolean retry;
+      final HashSet<ExportPkg> collisions = new HashSet<ExportPkg>();
+      do {
+        retry = false;
+        @SuppressWarnings("unchecked")
+        final HashSet<BundleGeneration> oldTempResolved = (HashSet<BundleGeneration>)tempResolved.clone();
+        if (!addTempResolved(bg)) {
+          return false;
+        }
+        final HashMap<String, ExportPkg> oldTempProvider = tempProviderClone();
+        @SuppressWarnings("unchecked")
+        final HashMap<RequireBundle, BundlePackages> oldTempRequired = (HashMap<RequireBundle, BundlePackages>)tempRequired.clone();
+        @SuppressWarnings("unchecked")
+        final HashSet<ExportPkg> oldTempBlackList = (HashSet<ExportPkg>)tempBlackList.clone();
+        tempBlackList.addAll(collisions);
+        final int oldTempWiresSize = tempWires.size();
+        if (ep != null) {
+          tempProvider.put(ep.pkg.pkg, ep);
+        }
+        final String breq = checkBundleRequirements(bg);
+        if (breq == null) {
+          if (checkRequireBundle(bg) == null) {
+            if (resolvePackages(bg.bpkgs.getImports(), null)) {
+              return true;
+            }
+            if (tempCollision != null) {
+              if (!oldTempProvider.containsValue(tempCollision)) {
+                collisions.add(tempCollision);
+                retry = true;
+                tempCollision = null;
+              }
+            }
+          }
+        }
+        tempResolved = oldTempResolved;
+        tempProvider = oldTempProvider;
+        tempRequired = oldTempRequired;
+        tempBlackList = oldTempBlackList;
+        tempWires.subList(oldTempWiresSize, tempWires.size()).clear();
+      } while (retry);
+    }
+    return false;
+  }
+
+
+  /**
+   * Check that the packages that this provider uses do not collied with
+   * previous selections. If a bundle doesn't have a uses directive we check all
+   * currently imported packages. This is then applied recursively.
+   *
+   * @param pkg Exported package to check
+   * @return True if we checked all packages without collision.
+   */
+  private boolean checkUses(Set<String> uses, BundleCapability bc, BundlePackages bpkgs) {
+    if (framework.debug.resolver) {
+      framework.debug.println("checkUses: check if packages used by " + bc + " is okay.");
+    }
+    if (framework.debug.resolver) {
+      framework.debug.println("checkUses: provider with bpkgs=" + bpkgs);
+    }
+    final Iterator<ImportPkg> i = bpkgs.getActiveImports();
+    if (i != null) {
+      final ArrayList<ExportPkg> checkList = new ArrayList<ExportPkg>();
+      while (i.hasNext()) {
+        final ImportPkg ip = i.next();
+        if (uses != null && !uses.contains(ip.pkg.pkg)) {
+          continue;
+        }
+        final ExportPkg ep = tempProvider.get(ip.pkg.pkg);
+        if (framework.debug.resolver) {
+          framework.debug.println("checkUses: check import, " + ip +
+                                  " with provider, " + ip.provider);
+        }
+        if (ep == null) {
+          tempProvider.put(ip.pkg.pkg, ip.provider);
+          checkList.add(ip.provider);
+        } else if (ep != ip.provider) {
+          if (framework.debug.resolver) {
+            framework.debug.println("checkUses: mismatch in providers for, " + ip.pkg.pkg);
+          }
+          return false;
+        }
+      }
+      for (final ExportPkg exportPkg : checkList) {
+        if (!checkUses(exportPkg.uses, exportPkg, exportPkg.bpkgs)) {
+          return false;
+        }
+      }
+    }
+    if (framework.debug.resolver) {
+      framework.debug.println("checkUses: " + bc + " is okay.");
+    }
+    return true;
+  }
+
+
+  /**
+   * Check that the bundle specified can be resolved without violating any
+   * singleton requirements.
+   *
+   * @param b Bundle to check, must be in INSTALLED state
+   * @return Bundle blocking resolve, otherwise null.
+   * @throws BundleException Resolver hook throw an exception.
+   */
+  private BundleGeneration checkBundleSingleton(BundleGeneration bg) throws BundleException {
+    if (bg.symbolicName != null && bg.singleton) {
+      if (framework.debug.resolver) {
+        framework.debug.println("checkBundleSingleton: check singleton bundle " + bg);
+      }
+      final List<BundleGeneration> bl = framework.bundles.getBundleGenerations(bg.symbolicName);
+      if (bl.size() > 1) {
+        if (framework.resolverHooks.hasHooks()) {
+          final BundleCapability bc = bg.getBundleCapability();
+          Collection<BundleCapability> candidates = new LinkedList<BundleCapability>();
+          List<BundleNameVersionCapability> active = new ArrayList<BundleNameVersionCapability>(bl.size());
+          for (final BundleGeneration bg2 : bl) {
+            if (bg2.singleton) {
+              if (bg2 != bg) {
+                BundleNameVersionCapability bc2 = bg2.getBundleCapability();
+                if (bc2 != null) {
+                  if (bg2.bpkgs.isActive()) {
+                    active.add(bc2);
+                  } else {
+                    candidates.add(bc2);
+                  }
+                }
+              }
+            }
+          }
+          if (!active.isEmpty()) {
+            for (BundleNameVersionCapability abc : active) {
+              Collection<BundleCapability> c = new LinkedList<BundleCapability>(candidates);
+              c.add(bc);
+              framework.resolverHooks.filterSingletonCollisions(abc, c);
+              if (c.contains(bc)) {
+                return abc.gen;
+              } else {
+                candidates.removeAll(c);
+              }
+            }
+          }
+          if (!candidates.isEmpty()) {
+            framework.resolverHooks.filterSingletonCollisions(bc, candidates);
+            for (final BundleCapability bc2 : candidates) {
+              BundleGeneration bg2 = ((BundleRevisionImpl)bc2.getRevision()).gen;
+              if (tempResolved.contains(bg2)) {
+                // TODO add to blacklist to avoid resolve tries?!
+                if (framework.debug.resolver) {
+                  framework.debug.println("checkBundleSingleton: Reject because of bundle: "
+                                          + bg2.bundle);
+               }
+                return bg2;
+              }
+            }
+          }
+        } else {
+          for (final BundleGeneration bg2 : bl) {
+            if (bg != bg2 && bg2.singleton && (bg2.bpkgs.isActive() || tempResolved.contains(bg2))) {
+              if (framework.debug.resolver) {
+                framework.debug.println("checkBundleSingleton: Reject because of bundle: "
+                                        + bg2.bundle);
+              }
+              return bg2;
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Check that the bundle specified can resolve all its Require-Capability
+   * constraints.
+   * 
+   * @param b Bundle to check, must be in INSTALLED state
+   * @return Capability not full name of bundle blocking resolve, otherwise null.
+   * @throws BundleException Resolver hook throw an exception.
+   */
+  private String checkBundleRequirements(BundleGeneration bg) throws BundleException {
+    for (Entry<String, List<BundleRequirementImpl>> e : bg.getOtherRequirements().entrySet()) {
+      String namespace = e.getKey(); 
+      for (BundleRequirementImpl br : e.getValue()) {
+        if (!br.shouldResolve()) {
+          continue;
+        }
+        if (framework.debug.resolver) {
+          framework.debug.println("checkBundleRequirements: Check requirement: " + br);
+        }
+        final boolean reqPerm = framework.perm.hasRequirePermission(br);
+        List<BundleCapabilityImpl> bcs = capabilities.getCapabilities(namespace);
+        BundleWireImpl found = null;
+        if (bcs != null) {
+          List<BundleCapabilityImpl> mbcs = new LinkedList<BundleCapabilityImpl>();
+          for (BundleCapabilityImpl bc : bcs) {
+            if (br.matches(bc) && bc.checkPermission() && (reqPerm || framework.perm.hasRequirePermission(br, bc))) {
+              mbcs.add(bc);
+            }
+          }
+          if (framework.resolverHooks.hasHooks()) {
+            framework.resolverHooks.filterMatches(br, (Collection<? extends BundleCapability>) mbcs);
+          }
+          List<BundleCapabilityImpl> matches = new ArrayList<BundleCapabilityImpl>();
+          int n_active = 0;
+          for (BundleCapabilityImpl bc : mbcs) {
+            BundleGeneration bcbg = bc.getBundleGeneration();
+            if (bcbg.isCurrent()) {
+              // Select active or soon active first
+              if (bcbg.bpkgs.isActive() || tempResolved.contains(bcbg)) {
+                matches.add(0, bc);
+                n_active++;
+                if (framework.debug.resolver) {
+                  framework.debug.println("checkBundleRequirements: Found active capability: " + bc);
+                }
+              } else {
+                matches.add(n_active, bc);
+                if (framework.debug.resolver) {
+                  framework.debug.println("checkBundleRequirements: Found unresolved capability: " + bc);
+                }
+              }
+            } else {
+              // Select zombies last
+              matches.add(bc);
+              if (framework.debug.resolver) {
+                framework.debug.println("checkBundleRequirements: Found zombie capability: " + bc);
+              }
+            }
+          }
+          for (BundleCapabilityImpl bc : matches) {
+            BundleGeneration bcbg = bc.getBundleGeneration();
+            if (!tempResolved.contains(bcbg)) {
+              if (bcbg.bundle.state == Bundle.INSTALLED) {
+                if (!checkResolve(bcbg, null)) {
+                  continue;
+                }
+              } else {
+                // Check uses
+                Set<String> uses = bc.getUses();
+                if (uses != null && !checkUses(uses, bc, bc.getBundleGeneration().bpkgs)) {
+                  continue;
+                }
+              }
+            }
+            found = new BundleWireImpl(bc, bcbg, br, bg);
+            break;
+          }
+        }
+        if (found != null) {
+          tempWires.add(found);
+        } else if (!br.isOptional()) {
+          return "Failed to satisfy: " + br;
+        }
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Check that the bundle specified can resolve all its Require-Bundle
+   * constraints.
+   *
+   * @param b Bundle to check, must be in INSTALLED state
+   * @return Symbolic name of bundle blocking resolve, otherwise null.
+   * @throws BundleException Resolver hook throw an exception.
+   */
+  private String checkRequireBundle(BundleGeneration bg) throws BundleException {
+    // NYI! More speed?
+    final Iterator<RequireBundle> i = bg.bpkgs.getRequire();
+    if (i.hasNext()) {
+      if (framework.debug.resolver) {
+        framework.debug.println("checkRequireBundle: check requiring bundle " + bg);
+      }
+      if (!framework.perm.okRequireBundlePerm(bg.bundle)) {
+        return "No permission to require bundle: " + bg.symbolicName;
+      }
+      final HashMap<RequireBundle, BundlePackages> res = new HashMap<RequireBundle, BundlePackages>();
+      do {
+        final RequireBundle br = i.next();
+        BundleGeneration ok = null;
+        List<BundleNameVersionCapability> possibleProvider = new LinkedList<BundleNameVersionCapability>();
+        for (BundleGeneration bg2 : framework.bundles.getBundles(br.name, br.bundleRange)) {
+          possibleProvider.add(new BundleNameVersionCapability(bg2, BundleRevision.BUNDLE_NAMESPACE));
+        }
+        framework.resolverHooks.filterMatches((BundleRequirement)br,
+                                              (Collection<? extends BundleCapability>) possibleProvider);
+        for (final BundleNameVersionCapability bc : possibleProvider) {
+          final BundleGeneration bg2 = bc.gen;
+          if (!bg2.bsnAttrMatch(br.attributes)) {
+            continue;
+          }
+          if (tempResolved.contains(bg2)) {
+            ok = bg2;
+            break;
+          } else if (bg2.bpkgs.isActive()) {
+            final HashMap<String, ExportPkg> oldTempProvider = tempProviderClone();
+            ok = bg2;
+            for (final Iterator<ExportPkg> epi = bg2.bpkgs.getExports(); epi.hasNext();) {
+              final ExportPkg ep = epi.next();
+              if (!checkUses(ep.uses, ep, ep.bpkgs)) {
+                tempProvider = oldTempProvider;
+                tempBlackList.add(ep);
+                ok = null;
+                break;
+              }
+            }
+            if (ok != null) {
+              break;
+            }
+          } else if (bg2.bundle.state == Bundle.INSTALLED &&
+                     framework.perm.okProvideBundlePerm(bg2.bundle) &&
+                     checkResolve(bg2, null)) {
+            ok = bg2;
+            break;
+          }
+        }
+        if (ok != null) {
+          if (framework.debug.resolver) {
+            framework.debug.println("checkRequireBundle: added required bundle " + ok);
+          }
+          res.put(br, ok.bpkgs);
+        } else if (br.resolution == Constants.RESOLUTION_MANDATORY) {
+          if (framework.debug.resolver) {
+            framework.debug.println("checkRequireBundle: failed to satisfy: " + br.name);
+          }
+          return "Failed to resolve required bundle: " + br.name;
+        }
+      } while (i.hasNext());
+      tempRequired.putAll(res);
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  private void registerNewProviders(BundleImpl bundle) {
+    for (final ExportPkg ep : tempProvider.values()) {
+      ep.pkg.addProvider(ep);
+    }
+    for (final Entry<RequireBundle, BundlePackages> entry : tempRequired.entrySet()) {
+      final BundlePackages bpkgs = entry.getValue();
+      final RequireBundle br = entry.getKey();
+      br.bpkgs = bpkgs;
+      bpkgs.addRequiredBy(br.requestor);
+      if (framework.debug.resolver) {
+        framework.debug.println("registerNewProviders: '"
+                                + Constants.REQUIRE_BUNDLE + ": " + br.name
+                                + "' for " + br.requestor.bg.bundle.getBundleId()
+                                + " bound to (id=" + bpkgs.bg.bundle.getBundleId()
+                                + ",gen=" + bpkgs.bg.generation + ")");
+      }
+      if (br.visibility == Constants.VISIBILITY_REEXPORT) {
+        // Create necessary re-export entries
+        for (final Iterator<ExportPkg> be = bpkgs.getExports(); be.hasNext();) {
+          final ExportPkg ep = be.next();
+          br.requestor.checkReExport(ep);
+          if (framework.debug.resolver) {
+            framework.debug.println("registerNewProviders: "
+                                    + br.requestor.bg.bundle.getBundleId()
+                                    + " reexports package " + ep.name);
+          }
+        }
+      }
+    }
+    List<BundleImpl> resolve = new ArrayList<BundleImpl>(tempResolved.size());
+    for (final BundleGeneration bg : tempResolved) {
+      if (!bg.bpkgs.isActive()) {
+        for (final Iterator<ImportPkg> bi = bg.bpkgs.getImports(); bi.hasNext();) {
+          final ImportPkg ip = bi.next();
+          final ExportPkg ep = tempProvider.get(ip.name);
+          if (ep == null) {
+            // There could be an internal connection, that should export a
+            // package
+            if (ip.internalOk != null) {
+              if (ip.internalOk.pkg.providers.isEmpty() &&
+                  ip.internalOk.checkPermission()) {
+                ip.internalOk.pkg.addProvider(ip.internalOk);
+                if (framework.debug.resolver) {
+                  framework.debug.println("registerNewProviders: exported internal wire, "
+                                          + ip + " -> " + ip.internalOk);
+                }
+              } else {
+                if (framework.debug.resolver) {
+                  framework.debug.println("registerNewProviders: internal wire, "
+                                          + ip + " -> " + ip.internalOk);
+                }
+              }
+            }
+          } else {
+            // TODO! This check is already done, we should cache result
+            if (ip.checkAttributes(ep) && ip.checkPermission(ep)) {
+              ip.provider = ep;
+            } else {
+              // Check if got a missmatching internal wire.
+              if (ip.internalOk != null) {
+                if (ip.internalOk == ep) {
+                  if (framework.debug.resolver) {
+                    framework.debug.println("registerNewProviders: internal wire, " + ip + ", "
+                        + ep);
+                  }
+                } else {
+                  // TODO, should we resolve when this happens!?
+                  framework.frameworkError(bg.bundle,
+                       new Exception("registerNewProviders: Warning! Internal wire for, " + ip +
+                                     ", does not match exported. " + ep));
+                }
+              }
+            }
+          }
+        }
+        if (bg.bundle != bundle) {
+          resolve.add(bg.bundle);
+        }
+      }
+    }
+    for (final BundleImpl b : resolve) {
+      if (b.getUpdatedState(null) == Bundle.INSTALLED) {
+        framework.frameworkError(b,
+            new Exception("registerNewProviders: InternalError!"));
+      }
+    }
+  }
+
+  /**
+   *
+   */
+  private void registerNewWires() {
+    for (final BundleWireImpl bw : tempWires) {
+      ((BundleRequirementImpl)bw.getRequirement()).setWire(bw);
+    }
+  }
+
+  /**
+   * Check if current thread is a bundle thread involved in
+   * resolve operation, if so abort to avoid deadlock.
+   * @throws BundleException 
+   *  
+   */
+  private void checkThread() throws BundleException {
+    Thread t = Thread.currentThread();
+    if (t.equals(resolveThread)) {
+      throw new BundleException("Can not currently start new resolve during a resolve.");      
+    }
+    for (BundleGeneration bg : tempResolved) {
+      if (bg.bundle.isBundleThread(t)) {
+		    throw new BundleException("Can not resolve a bundle inside current BundleListener." +
+                                  "Will cause a dead-lock. BID=" + bg.bundle.id);
+      }
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ResolverHooks.java b/osgi/framework/src/org/knopflerfish/framework/ResolverHooks.java
new file mode 100644
index 0000000..ae90348
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ResolverHooks.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+package org.knopflerfish.framework;
+
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.hooks.resolver.ResolverHook;
+import org.osgi.framework.hooks.resolver.ResolverHookFactory;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ResolverHooks {
+
+  private final FrameworkContext fwCtx;
+  private ServiceTracker<ResolverHookFactory, TrackedResolverHookFactory> resolverHookTracker;
+
+  private List<TrackedResolverHookFactory> active = null;
+  private BundleImpl [] currentTriggers = null;
+  private Map<BundleGeneration, Boolean> resolvableBundles = null;
+  private Thread blockThread = null;
+
+  ResolverHooks(FrameworkContext frameworkContext) {
+    this.fwCtx = frameworkContext;
+  }
+
+  synchronized void open() {
+    if (fwCtx.debug.hooks) {
+      fwCtx.debug.println("Begin Tracking Resolver Hooks");
+    }
+    
+    resolverHookTracker = new ServiceTracker<ResolverHookFactory, TrackedResolverHookFactory>(
+        (BundleContext) fwCtx.systemBundle.bundleContext, ResolverHookFactory.class,
+        new ServiceTrackerCustomizer<ResolverHookFactory, TrackedResolverHookFactory>() {
+          public TrackedResolverHookFactory addingService(
+              ServiceReference<ResolverHookFactory> reference) {
+            return new TrackedResolverHookFactory(
+                (ResolverHookFactory) fwCtx.systemBundle.bundleContext
+                    .getService(reference), reference.getBundle());
+          }
+
+          public void modifiedService(ServiceReference<ResolverHookFactory> reference,
+              TrackedResolverHookFactory service) {
+
+          }
+
+          public void removedService(ServiceReference<ResolverHookFactory> reference,
+              TrackedResolverHookFactory service) {
+            service.resetResolverHook();
+          }
+        });
+
+    resolverHookTracker.open();
+  }
+
+  synchronized void close() {
+    resolverHookTracker.close();
+    resolverHookTracker = null;
+  }
+
+  boolean isOpen() {
+    return resolverHookTracker != null;
+  }
+
+  synchronized void beginResolve(final BundleImpl [] triggers) throws BundleException {
+    if (!isOpen()) {
+      return;
+    }
+    if (currentTriggers == null) {
+      Collection<BundleRevision> triggerCollection = new ArrayList<BundleRevision>();
+      for (BundleImpl b : triggers) {
+        triggerCollection.add(b.current().bundleRevision);
+      }
+      active = new ArrayList<TrackedResolverHookFactory>();
+      for (Entry<ServiceReference<ResolverHookFactory>, TrackedResolverHookFactory> e : resolverHookTracker.getTracked().entrySet()) {
+        TrackedResolverHookFactory rhf = resolverHookTracker.getService(e.getKey());
+        if (null != rhf) {
+          blockResolveForHooks();
+          try {
+            if (rhf.begin(triggerCollection)) {
+              active.add(rhf);
+              currentTriggers = triggers;
+            }
+          } catch (RuntimeException re) {
+            throw new BundleException("Resolver hook throw an exception, bid="
+                                      + rhf.bundle.getBundleId(),
+                                      BundleException.REJECTED_BY_HOOK, re);
+          } finally {
+            unblockResolveForHooks();
+          }
+        }
+      }
+      if (active.isEmpty()) {
+        active = null;
+      } else {
+        resolvableBundles = new HashMap<BundleGeneration, Boolean>();
+      }
+    }
+  }
+
+
+  synchronized void endResolve(final BundleImpl [] triggers) throws BundleException {
+    if (triggers == currentTriggers) {
+      BundleException saved = null;
+      if (active != null) {
+        blockResolveForHooks();
+        for (TrackedResolverHookFactory rhf : active) {
+          final ResolverHook rh = rhf.getResolverHook();
+          try {
+            rh.end();
+          } catch (RuntimeException re) {
+            saved  = new BundleException("Resolver end hook throw an exception, bid="
+                + rhf.bundle.getBundleId(),
+                BundleException.REJECTED_BY_HOOK, re);
+          }
+        }
+        unblockResolveForHooks();
+        active = null;
+        resolvableBundles = null;
+      }
+      currentTriggers = null;
+      if (saved != null) {
+        throw saved;
+      }
+    }
+  }
+
+
+  void filterMatches(BundleRequirement requirement , Collection<? extends BundleCapability> candidates) throws BundleException {
+    if (hasHooks()) {
+      @SuppressWarnings("unchecked")
+      Collection<BundleCapability> c = new RemoveOnlyCollection<BundleCapability>((Collection<BundleCapability>) candidates);
+      blockResolveForHooks();
+      try {
+        for (TrackedResolverHookFactory rhf : active) {
+          final ResolverHook rh = checkActiveRemoved(rhf);
+          try {
+            rh.filterMatches(requirement, c);
+          } catch (RuntimeException re) {
+            throw new BundleException("Resolver hook throw an exception, bid="
+                                      + rhf.bundle.getBundleId(),
+                                      BundleException.REJECTED_BY_HOOK, re);
+          }
+        }
+      } finally {
+        unblockResolveForHooks();
+      }
+    }
+  }
+
+
+  boolean filterMatches(BundleRequirement requirement , BundleCapability candidate) throws BundleException {
+    if (hasHooks()) {
+      Collection<BundleCapability> c = new ShrinkableSingletonCollection<BundleCapability>(candidate);
+      filterMatches(requirement, c);
+      return !c.isEmpty();
+    }
+    return true;
+  }
+
+
+  boolean filterResolvable(BundleGeneration bg) throws BundleException {
+    if (hasHooks()) {
+      Boolean res = resolvableBundles.get(bg);
+      if (res == null) {
+        Collection<BundleRevision> c = new ShrinkableSingletonCollection<BundleRevision>(bg.bundleRevision);
+        blockResolveForHooks();
+        try {
+          for (TrackedResolverHookFactory rhf : active) {
+            final ResolverHook rh = checkActiveRemoved(rhf);
+            try {
+              rh.filterResolvable(c);
+            } catch (RuntimeException re) {
+              throw new BundleException("Resolver hook throw an exception, bid="
+                                      + rhf.bundle.getBundleId(),
+                                        BundleException.REJECTED_BY_HOOK, re);
+            }
+          }
+        } finally {
+          unblockResolveForHooks();
+        }
+        res = Boolean.valueOf(!c.isEmpty());
+        resolvableBundles.put(bg, res);
+      }
+      return res.booleanValue();
+    }
+    return true;
+  }
+
+
+  void filterSingletonCollisions(BundleCapability singleton , Collection<BundleCapability> candidates) throws BundleException {
+    if (hasHooks()) {
+      Collection<BundleCapability> c = new RemoveOnlyCollection<BundleCapability>(candidates);
+      blockResolveForHooks();
+      try {
+        for (TrackedResolverHookFactory rhf : active) {
+          final ResolverHook rh = checkActiveRemoved(rhf);
+          try {
+            rh.filterSingletonCollisions(singleton, c);
+          } catch (RuntimeException re) {
+            throw new BundleException("Resolver hook throw an exception, bid="
+                                      + rhf.bundle.getBundleId(),
+                                      BundleException.REJECTED_BY_HOOK, re);
+          }
+        }
+      } finally {
+        unblockResolveForHooks();
+      }
+    }
+  }
+
+
+  void checkResolveBlocked() {
+    if (blockThread != null && Thread.currentThread() == blockThread) {
+      throw new IllegalStateException("Resolve hooks aren't allowed to resolve bundle");
+    }
+  }
+
+
+  boolean hasHooks() throws BundleException {
+    return active != null;
+  }
+
+  private ResolverHook checkActiveRemoved(TrackedResolverHookFactory rhf) throws BundleException {
+    ResolverHook rh = rhf.getResolverHook();
+    if (null == rh) {
+      throw new BundleException("Resolver hook service was unregistered",
+                                BundleException.REJECTED_BY_HOOK);
+    }
+    return rh;
+  }
+
+
+  private void blockResolveForHooks() {
+    blockThread = Thread.currentThread();
+  }
+
+
+  private void unblockResolveForHooks() {
+    blockThread = null;
+  }
+
+  // Classes
+
+  static class TrackedResolverHookFactory
+  {
+    final ResolverHookFactory tracked;
+    final Bundle bundle;
+    private ResolverHook resolverHook = null;
+  
+    TrackedResolverHookFactory(ResolverHookFactory tracked, Bundle bundle) {
+      this.tracked = tracked;
+      this.bundle = bundle;
+    }
+  
+    boolean begin(final Collection<BundleRevision> triggers) {
+      resolverHook = tracked.begin(triggers);
+      return resolverHook != null;
+    }
+  
+    ResolverHook getResolverHook() {
+      return resolverHook;
+    }
+    
+    void resetResolverHook() {
+      resolverHook = null;
+    }
+  
+  }
+
+
+  static class ShrinkableSingletonCollection<T> extends AbstractCollection<T>
+  {
+    T singleton;
+    
+    public ShrinkableSingletonCollection(T singleton) {
+      this.singleton = singleton;
+    }
+
+    @Override
+    public boolean add(T br) {
+      throw new UnsupportedOperationException("Add not allowed");
+    }
+  
+    @Override
+    public boolean addAll(Collection<? extends T> c) {
+      throw new UnsupportedOperationException("Add not allowed");
+    }
+  
+    @Override
+    public boolean isEmpty() {
+      return singleton == null;
+    }
+  
+    @Override
+    public Iterator<T> iterator() {
+      return new Iterator<T>() {
+        boolean hasNext = !isEmpty();
+        
+        @Override
+        public boolean hasNext() {
+          return hasNext;
+        }
+
+        @Override
+        public T next() {
+          if (hasNext) {
+            hasNext = false;
+            if (isEmpty()) {
+              throw new ConcurrentModificationException();
+            }
+            return singleton;
+          }
+          throw new NoSuchElementException();
+        }
+
+        @Override
+        public void remove() {
+          if (hasNext || isEmpty()) {
+            throw new IllegalStateException();
+          }
+          singleton = null;
+        }
+      };
+    }
+  
+    @Override
+    public boolean remove(Object o) {
+      if (singleton != null && singleton.equals(o)) {
+        singleton = null;
+        return true;
+      }
+      return false;
+    }
+  
+    @Override
+    public int size() {
+      return singleton != null ? 1 : 0;
+    }
+  
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/SecurePermissionOps.java b/osgi/framework/src/org/knopflerfish/framework/SecurePermissionOps.java
new file mode 100644
index 0000000..98a0e35
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/SecurePermissionOps.java
@@ -0,0 +1,974 @@
+/*
+ * Copyright (c) 2006-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.knopflerfish.framework.permissions.PermissionsHandle;
+import org.osgi.framework.AdaptPermission;
+import org.osgi.framework.AdminPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundlePermission;
+import org.osgi.framework.CapabilityPermission;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.PackagePermission;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServicePermission;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
+import org.osgi.service.permissionadmin.PermissionAdmin;
+
+public class SecurePermissionOps
+  extends PermissionOps
+{
+
+  private static final int AP_CLASS = 0;
+  private static final int AP_EXECUTE = 1;
+  private static final int AP_EXTENSIONLIFECYCLE = 2;
+  private static final int AP_LIFECYCLE = 3;
+  private static final int AP_LISTENER = 4;
+  private static final int AP_METADATA = 5;
+  private static final int AP_RESOURCE = 6;
+  private static final int AP_CONTEXT = 7;
+  private static final int AP_WEAVE = 8;
+  private static final int AP_MAX = 9;
+
+  private static String[] AP_TO_STRING = new String[] {
+                                                       AdminPermission.CLASS,
+                                                       AdminPermission.EXECUTE,
+                                                       AdminPermission.EXTENSIONLIFECYCLE,
+                                                       AdminPermission.LIFECYCLE,
+                                                       AdminPermission.LISTENER,
+                                                       AdminPermission.METADATA,
+                                                       AdminPermission.RESOURCE,
+                                                       AdminPermission.CONTEXT,
+                                                       AdminPermission.WEAVE };
+
+  private final FrameworkContext framework;
+  private PermissionsHandle ph;
+
+  private AdminPermission ap_resolve = null;
+  private AdminPermission ap_startlevel = null;
+
+  private RuntimePermission rp_getprotectiondomain = null;
+
+  Hashtable<Bundle, AdminPermission[]> adminPerms = new Hashtable<Bundle, AdminPermission[]>();
+
+  public SecurePermissionOps(FrameworkContext fw)
+  {
+    framework = fw;
+  }
+
+  @Override
+  void init()
+  {
+    ph = new PermissionsHandle(framework);
+  }
+
+  @Override
+  void registerService()
+  {
+    if (framework.props
+        .getBooleanProperty(FWProps.SERVICE_PERMISSIONADMIN_PROP)) {
+      final String[] classes = new String[] { PermissionAdmin.class.getName() };
+      framework.services.register(framework.systemBundle, classes,
+                                  ph.getPermissionAdminService(), null);
+    }
+    if (framework.props
+        .getBooleanProperty(FWProps.SERVICE_CONDITIONALPERMISSIONADMIN_PROP)) {
+      final ConditionalPermissionAdmin cpa = ph
+          .getConditionalPermissionAdminService();
+      if (cpa != null) {
+        final String[] classes = new String[] { ConditionalPermissionAdmin.class
+            .getName() };
+        framework.services.register(framework.systemBundle, classes, cpa, null);
+      }
+    }
+  }
+
+  @Override
+  boolean checkPermissions()
+  {
+    return true;
+  }
+
+  //
+  // Permission checks
+  //
+
+  @Override
+  boolean okClassAdminPerm(Bundle b)
+  {
+    try {
+      final SecurityManager sm = System.getSecurityManager();
+      if (null != sm) {
+        sm.checkPermission(getAdminPermission(b, AP_CLASS));
+      }
+      return true;
+    } catch (final SecurityException _ignore) {
+      return false;
+    }
+  }
+
+  @Override
+  void checkExecuteAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_EXECUTE));
+    }
+  }
+
+  @Override
+  void checkExtensionLifecycleAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_EXTENSIONLIFECYCLE));
+    }
+  }
+
+  @Override
+  void checkExtensionLifecycleAdminPerm(Bundle b, Object checkContext)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm && checkContext != null) {
+      sm.checkPermission(getAdminPermission(b, AP_EXTENSIONLIFECYCLE),
+                         checkContext);
+    }
+  }
+
+  @Override
+  void checkLifecycleAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_LIFECYCLE));
+    }
+  }
+
+  @Override
+  void checkLifecycleAdminPerm(Bundle b, Object checkContext)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm && checkContext != null) {
+      sm.checkPermission(getAdminPermission(b, AP_LIFECYCLE), checkContext);
+    }
+  }
+
+  @Override
+  void checkListenerAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_LISTENER));
+    }
+  }
+
+  @Override
+  void checkMetadataAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_METADATA));
+    }
+  }
+
+  @Override
+  void checkResolveAdminPerm()
+  {
+    if (ap_resolve == null) {
+      ap_resolve = new AdminPermission(framework.systemBundle,
+                                       AdminPermission.RESOLVE);
+    }
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(ap_resolve);
+    }
+  }
+
+  @Override
+  void checkResourceAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_RESOURCE));
+    }
+  }
+
+  @Override
+  boolean okResourceAdminPerm(Bundle b)
+  {
+    try {
+      checkResourceAdminPerm(b);
+      return true;
+    } catch (final SecurityException ignore) {
+      if (framework.debug.bundle_resource) {
+        framework.debug
+            .printStackTrace("No permission to access resources in bundle #"
+                             + b.getBundleId(), ignore);
+      }
+      return false;
+    }
+  }
+
+  @Override
+  void checkContextAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_CONTEXT));
+    }
+  }
+
+  @Override
+  void checkStartLevelAdminPerm()
+  {
+    if (ap_startlevel == null) {
+      ap_startlevel = new AdminPermission(framework.systemBundle,
+                                          AdminPermission.STARTLEVEL);
+    }
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(ap_startlevel);
+    }
+  }
+
+  @Override
+  void checkGetProtectionDomain()
+  {
+    if (rp_getprotectiondomain == null) {
+      rp_getprotectiondomain = new RuntimePermission("getProtectionDomain");
+    }
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(rp_getprotectiondomain);
+    }
+  }
+
+  @Override
+  void checkWeaveAdminPerm(Bundle b)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(getAdminPermission(b, AP_WEAVE));
+    }
+  }
+
+  //
+  // Bundle permission checks
+  //
+
+  @Override
+  boolean okFragmentBundlePerm(BundleImpl b)
+  {
+    final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+    return pc.implies(new BundlePermission(b.getSymbolicName(),
+                                           BundlePermission.FRAGMENT));
+  }
+
+  @Override
+  boolean okHostBundlePerm(BundleImpl b)
+  {
+    final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+    return pc.implies(new BundlePermission(b.getSymbolicName(),
+                                           BundlePermission.HOST));
+  }
+
+  @Override
+  boolean okProvideBundlePerm(BundleImpl b)
+  {
+    final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+    return pc.implies(new BundlePermission(b.getSymbolicName(),
+                                           BundlePermission.PROVIDE));
+  }
+
+  @Override
+  boolean okRequireBundlePerm(BundleImpl b)
+  {
+    final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+    return pc.implies(new BundlePermission(b.getSymbolicName(),
+                                           BundlePermission.REQUIRE));
+  }
+
+  @Override
+  boolean okAllPerm(BundleImpl b)
+  {
+    final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+    return pc.implies(new AllPermission());
+  }
+
+  //
+  // Package permission checks
+  //
+
+  @Override
+  boolean hasExportPackagePermission(ExportPkg ep)
+  {
+    final BundleImpl b = ep.bpkgs.bg.bundle;
+    if (b.id != 0) {
+      final PermissionCollection pc = ph
+          .getPermissionCollection(new Long(b.id));
+      return pc.implies(new PackagePermission(ep.name,
+                                              PackagePermission.EXPORTONLY));
+    }
+    return true;
+  }
+
+  @Override
+  boolean hasImportPackagePermission(BundleImpl b, ExportPkg ep)
+  {
+    if (b.id != 0) {
+      final PermissionCollection pc = ph
+          .getPermissionCollection(new Long(b.id));
+      return pc.implies(new PackagePermission(ep.name, ep.bpkgs.bg.bundle,
+                                              PackagePermission.IMPORT));
+    }
+    return true;
+  }
+
+  //
+  // Service permission checks
+  //
+
+  @Override
+  void checkRegisterServicePerm(String clazz)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(new ServicePermission(clazz,
+                                               ServicePermission.REGISTER));
+    }
+  }
+
+  @Override
+  void checkGetServicePerms(ServiceReference<?> sr)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(new ServicePermission(sr, ServicePermission.GET));
+    }
+  }
+
+  @Override
+  boolean okGetServicePerms(ServiceReference<?> sr)
+  {
+    try {
+      checkGetServicePerms(sr);
+      return true;
+    } catch (final SecurityException ignore) {
+      if (framework.debug.service_reference) {
+        framework.debug
+            .printStackTrace("No permission to get service ref: "
+                                 + sr.getProperty(Constants.OBJECTCLASS),
+                             ignore);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Filter out all services that we don't have permission to get.
+   *
+   * @param srs
+   *          Set of ServiceRegistrationImpls to check.
+   */
+  @Override
+  void filterGetServicePermission(Set<ServiceRegistrationImpl<?>> srs)
+  {
+    for (final Iterator<ServiceRegistrationImpl<?>> i = srs.iterator(); i
+        .hasNext();) {
+      final ServiceRegistrationImpl<?> sr = i.next();
+      ;
+      if (!okGetServicePerms(sr.getReference())) {
+        i.remove();
+      }
+    }
+  }
+
+  //
+  // Capability and Requirement checks
+  //
+
+  @Override
+  boolean hasProvidePermission(BundleCapabilityImpl bc) {
+    final BundleImpl b = bc.getBundleGeneration().bundle;
+    if (b.id != 0) {
+      final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+      return pc.implies(new CapabilityPermission(bc.getNamespace(),
+                                                 CapabilityPermission.PROVIDE));
+    }
+    return true;
+  }
+
+
+  @Override
+  boolean hasRequirePermission(BundleRequirementImpl br) {
+    final BundleImpl b = br.getBundleGeneration().bundle;
+    if (b.id != 0) {
+      final PermissionCollection pc = ph.getPermissionCollection(new Long(b.id));
+      return pc.implies(new CapabilityPermission(br.getNamespace(),
+                                                 CapabilityPermission.REQUIRE));
+    }
+    return true;
+  }
+
+
+  @Override
+  boolean hasRequirePermission(BundleRequirementImpl br, BundleCapabilityImpl bc) {
+    final BundleImpl bbr = br.getBundleGeneration().bundle;
+    if (bbr.id != 0) {
+      final PermissionCollection pc = ph.getPermissionCollection(new Long(bbr.id));
+      return pc.implies(new CapabilityPermission(bc.getNamespace(),
+                                                 bc.getAttributes(),
+                                                 bc.getBundleGeneration().bundle,
+                                                 CapabilityPermission.REQUIRE));
+    }
+    return true;
+  }
+
+  //
+  // AdaptPermission checks
+  //
+
+  @Override
+  <A> void checkAdaptPerm(BundleImpl b, Class<A> type)
+  {
+    final SecurityManager sm = System.getSecurityManager();
+    if (null != sm) {
+      sm.checkPermission(new AdaptPermission(type.getName(), b,
+                                             AdaptPermission.ADAPT));
+    }
+  }
+
+  //
+  // BundleArchive secure operations
+  //
+
+  @Override
+  BundleResourceStream callGetBundleResourceStream(final BundleArchive archive,
+                                                   final String name,
+                                                   final int ix)
+  {
+    return AccessController
+        .doPrivileged(new PrivilegedAction<BundleResourceStream>() {
+          public BundleResourceStream run()
+          {
+            return archive.getBundleResourceStream(name, ix);
+          }
+        });
+  }
+
+  @Override
+  Enumeration<String> callFindResourcesPath(final BundleArchive archive,
+                                            final String path)
+  {
+    return AccessController
+        .doPrivileged(new PrivilegedAction<Enumeration<String>>() {
+          public Enumeration<String> run()
+          {
+            return archive.findResourcesPath(path);
+          }
+        });
+  }
+
+  //
+  // BundleClassLoader secure operations
+  //
+
+  @Override
+  Object callSearchFor(final BundleClassLoader cl,
+                       final String name,
+                       final String pkg,
+                       final String path,
+                       final BundleClassLoader.SearchAction action,
+                       final int options,
+                       final BundleClassLoader requestor,
+                       final HashSet<BundleClassLoader> visited)
+  {
+    return AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        return cl.searchFor(name, pkg, path, action, options, requestor,
+                            visited);
+      }
+    });
+  }
+
+  @Override
+  String callFindLibrary0(final BundleClassLoader cl, final String name)
+  {
+    return AccessController.doPrivileged(new PrivilegedAction<String>() {
+      public String run()
+      {
+        return cl.findLibrary0(name);
+      }
+    });
+  }
+
+  //
+  // BundleImpl secure operations
+  //
+
+  @Override
+  void callFinalizeActivation(final BundleImpl b)
+      throws BundleException
+  {
+    try {
+      AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+        public Object run()
+            throws BundleException
+        {
+          b.finalizeActivation();
+          return null;
+        }
+      });
+    } catch (final PrivilegedActionException e) {
+      throw (BundleException) e.getException();
+    }
+  }
+
+  @Override
+  BundleThread createBundleThread(final FrameworkContext fc)
+  {
+    return AccessController.doPrivileged(new PrivilegedAction<BundleThread>() {
+      public BundleThread run()
+      {
+        return new BundleThread(fc);
+      }
+    });
+  }
+
+  @Override
+  void callUpdate0(final BundleImpl b,
+                   final InputStream in,
+                   final boolean wasActive)
+      throws BundleException
+  {
+    try {
+      final AccessControlContext acc = AccessController.getContext();
+      AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+        public Object run()
+            throws BundleException
+        {
+          b.update0(in, wasActive, acc);
+          return null;
+        }
+      });
+    } catch (final PrivilegedActionException e) {
+      throw (BundleException) e.getException();
+    }
+  }
+
+  @Override
+  void callUninstall0(final BundleImpl b)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        b.uninstall0();
+        return null;
+      }
+    });
+  }
+
+  @Override
+  void callSetAutostartSetting(final BundleImpl b, final int settings)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        b.setAutostartSetting0(settings);
+        return null;
+      }
+    });
+  }
+
+  @Override
+  HeaderDictionary callGetHeaders0(final BundleGeneration bg,
+                                   final String locale)
+  {
+    return AccessController
+        .doPrivileged(new PrivilegedAction<HeaderDictionary>() {
+          public HeaderDictionary run()
+          {
+            return bg.getHeaders0(locale);
+          }
+        });
+  }
+
+  @Override
+  Vector<URL> callFindEntries(final BundleGeneration bg,
+                              final String path,
+                              final String filePattern,
+                              final boolean recurse)
+  {
+    return AccessController.doPrivileged(new PrivilegedAction<Vector<URL>>() {
+      public Vector<URL> run()
+      {
+        return bg.findEntries(path, filePattern, recurse);
+      }
+    });
+  }
+
+  @Override
+  BundleClassLoader newBundleClassLoader(final BundleGeneration bg)
+      throws BundleException
+  {
+    try {
+      return AccessController
+          .doPrivileged(new PrivilegedExceptionAction<BundleClassLoader>() {
+            public BundleClassLoader run()
+                throws Exception
+            {
+              return new BundleClassLoader(bg);
+            }
+          });
+    } catch (final PrivilegedActionException pe) {
+      throw (BundleException) pe.getException();
+    }
+  }
+
+  Vector<URL> getBundleClassPathEntry(final BundleGeneration bg,
+                                      final String name,
+                                      final boolean onlyFirst)
+  {
+    return  AccessController.doPrivileged(new PrivilegedAction<Vector<URL>>() {
+      public Vector<URL> run()
+      {
+        return bg.getBundleClassPathEntries(name, onlyFirst);
+      }
+    });
+  }
+
+  @Override
+  AccessControlContext getAccessControlContext(BundleImpl bundle) {
+    ProtectionDomain pd = bundle.current().getProtectionDomain();
+    return pd != null ?new AccessControlContext(new ProtectionDomain[] {pd}) : null;
+  }
+
+  //
+  // Bundles Secure operation
+  //
+
+  @Override
+  BundleImpl callInstall0(final Bundles bs,
+                          final String location,
+                          final InputStream in,
+                          final Bundle caller)
+      throws BundleException
+  {
+    try {
+      final AccessControlContext acc = AccessController.getContext();
+      return  AccessController
+          .doPrivileged(new PrivilegedExceptionAction<BundleImpl>() {
+            public BundleImpl run()
+                throws BundleException
+            {
+              return bs.install0(location, in, acc, caller);
+            }
+          });
+    } catch (final PrivilegedActionException e) {
+      throw (BundleException) e.getException();
+    }
+  }
+
+  //
+  // Listeners Secure operations
+  //
+
+  @Override
+  void callBundleChanged(final FrameworkContext fwCtx, final BundleEvent evt)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        fwCtx.listeners.bundleChanged(evt);
+        return null;
+      }
+    });
+  }
+
+  @Override
+  void callServiceChanged(final FrameworkContext fwCtx,
+                          final Collection<ServiceListenerEntry> receivers,
+                          final ServiceEvent evt,
+                          final Set<ServiceListenerEntry> matchBefore)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        fwCtx.listeners.serviceChanged(receivers, evt, matchBefore);
+        return null;
+      }
+    });
+  }
+
+  //
+  // PackageAdmin secure operations
+  //
+
+  @Override
+  void callRefreshPackages0(final PackageAdminImpl pa,
+                            final Bundle[] bundles,
+                            final FrameworkListener[] fl)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        pa.refreshPackages0(bundles, fl);
+        return null;
+      }
+    });
+  }
+
+  //
+  // ServiceRegisterationImpl secure operations
+  //
+
+  @Override
+  <S> S callGetService(final ServiceRegistrationImpl<S> sr, final Bundle b)
+  {
+    return AccessController.doPrivileged(new PrivilegedAction<S>() {
+      public S run()
+      {
+        @SuppressWarnings("unchecked")
+        final ServiceFactory<S> srf = (ServiceFactory<S>) sr.service;
+        return srf.getService(b, sr);
+      }
+    });
+  }
+
+  @Override
+  <S> void callUngetService(final ServiceRegistrationImpl<S> sr,
+                            final Bundle b,
+                            final S instance)
+  {
+    @SuppressWarnings("unchecked")
+    final ServiceFactory<S> srf = (ServiceFactory<S>) sr.service;
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        srf.ungetService(b, sr, instance);
+        return null;
+      }
+    });
+  }
+
+  //
+  // StartLevelController secure operations
+  //
+
+  @Override
+  void callSetStartLevel(final BundleImpl b, final int startlevel)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        b.setStartLevel(startlevel);
+        return null;
+      }
+    });
+  }
+
+  @Override
+  void callSetInitialBundleStartLevel0(final StartLevelController slc,
+                                       final int startlevel)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        slc.setInitialBundleStartLevel0(startlevel, true);
+        return null;
+      }
+    });
+  }
+
+  //
+  // SystemBundle secure operations
+  //
+
+  @Override
+  void callShutdown(final SystemBundle sb, final boolean restart)
+  {
+    AccessController.doPrivileged(new PrivilegedAction<Object>() {
+      public Object run()
+      {
+        sb.shutdown(restart);
+        return null;
+      }
+    });
+  }
+
+  //
+  // Permissions package functionality
+  //
+
+  /**
+   * Get protection domain for bundle
+   */
+  @Override
+  ProtectionDomain getProtectionDomain(final BundleGeneration bg)
+  {
+    try {
+      // We cannot use getBundleURL() here because that will
+      // trigger a persmission check while we're still in
+      // the phase of building permissions
+      String h = Long.toString(bg.bundle.id);
+      if (bg.generation != 0) {
+        h += "." + Long.toString(bg.generation);
+      }
+      final URLStreamHandler ush = bg.bundle.fwCtx.urlStreamHandlerFactory
+          .createURLStreamHandler(BundleURLStreamHandler.PROTOCOL);
+      final URL bundleUrl = new URL(BundleURLStreamHandler.PROTOCOL, h, -1, "",
+                                    ush);
+
+      final InputStream pis = bg.archive
+          .getBundleResourceStream("OSGI-INF/permissions.perm", 0);
+      final PermissionCollection pc = ph
+          .createPermissionCollection(bg.bundle.location, bg.bundle, pis);
+      final ArrayList<List<X509Certificate>> cc = bg.archive.getCertificateChains(false);
+      Certificate[] cca;
+      if (cc != null) {
+        final ArrayList<X509Certificate> tmp = new ArrayList<X509Certificate>();
+        for (final List<X509Certificate> list : cc) {
+          tmp.addAll(list);
+        }
+        cca = tmp.toArray(new Certificate[tmp.size()]);
+      } else {
+        cca = null;
+      }
+      return new ProtectionDomain(new CodeSource(bundleUrl, cca), pc);
+    } catch (final MalformedURLException _ignore) {
+    }
+    return null;
+  }
+
+  @Override
+  URL getBundleURL(final FrameworkContext fwCtx, final String s)
+      throws MalformedURLException
+  {
+    try {
+      return AccessController
+          .doPrivileged(new PrivilegedExceptionAction<URL>() {
+            public URL run()
+                throws MalformedURLException
+            {
+              return new URL(null, s, fwCtx.urlStreamHandlerFactory
+                  .createURLStreamHandler(BundleURLStreamHandler.PROTOCOL));
+            }
+          });
+    } catch (final PrivilegedActionException e) {
+      throw (MalformedURLException) e.getException();
+    }
+  }
+
+  //
+  // Privileged system calls
+  //
+
+  @Override
+  ClassLoader getClassLoaderOf(final Class<?> c)
+  {
+    return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+      public ClassLoader run()
+      {
+        return c.getClassLoader();
+      }
+    });
+  }
+
+  //
+  // Cleaning
+  //
+
+  /**
+   * Purge all cached information for specified bundle.
+   */
+  @Override
+  void purge(BundleImpl b, ProtectionDomain pd)
+  {
+    if (ph.purgePermissionCollection(new Long(b.id), pd.getPermissions())) {
+      adminPerms.remove(b);
+    }
+  }
+
+  //
+  // Private
+  //
+
+  AdminPermission getAdminPermission(Bundle b, int ti)
+  {
+    AdminPermission[] res;
+    res = adminPerms.get(b);
+    if (res != null) {
+      if (res[ti] != null) {
+        return res[ti];
+      }
+    } else {
+      res = new AdminPermission[AP_MAX];
+      adminPerms.put(b, res);
+    }
+    res[ti] = new AdminPermission(b, AP_TO_STRING[ti]);
+    return res[ti];
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceContentHandlerFactory.java b/osgi/framework/src/org/knopflerfish/framework/ServiceContentHandlerFactory.java
new file mode 100644
index 0000000..bcdab60
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceContentHandlerFactory.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.net.ContentHandler;
+import java.net.ContentHandlerFactory;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.url.URLConstants;
+
+/**
+ * Factory creating ContentHandlers from both built-in
+ * handlers and OSGi-registered ContentHandlers
+ */
+public class ServiceContentHandlerFactory
+  implements ContentHandlerFactory
+{
+  FrameworkContext framework;
+
+  // JVM classpath handlers. Initialized once at startup
+  String[] jvmPkgs = null;
+
+  // String (mimetype) -> ContentHandlerWrapper
+  Map<String, ContentHandlerWrapper> wrapMap
+    = new HashMap<String, ContentHandlerWrapper>();
+
+  ServiceContentHandlerFactory(FrameworkContext fw) {
+    this.framework = fw;
+
+    // Initialize JVM classpath handlers
+    final String s = framework.props.getProperty("java.content.handler.pkgs");
+    if (s != null && s.length() > 0) {
+      jvmPkgs = Util.splitwords(s, "|");
+      for(int i = 0; i < jvmPkgs.length; i++) {
+        jvmPkgs[i] = jvmPkgs[i].trim();
+        if(framework.debug.url) {
+          framework.debug.println("JVMClassPathCH - jvmPkgs[" + i + "]=" + jvmPkgs[i]);
+        }
+      }
+    }
+  }
+
+  public ContentHandler createContentHandler(String mimetype) {
+
+    if(framework.debug.url) {
+      framework.debug.println("createContentHandler protocol=" + mimetype);
+    }
+
+    ContentHandler handler = getJVMClassPathHandler(mimetype);
+
+    if(handler != null) {
+      if(framework.debug.url) {
+	framework.debug.println("using JVMClassPath handler for " + mimetype);
+      }
+      return handler;
+    }
+
+
+    handler = getServiceHandler(mimetype);
+
+    if(handler != null) {
+      if(framework.debug.url) {
+	framework.debug.println("Using service ContentHandler for " + mimetype
+                                + ", handler=" + handler);
+      }
+      return handler;
+    }
+
+    if(framework.debug.url) {
+      framework.debug.println("Using default ContentHandler for " + mimetype);
+    }
+
+    // delegate to system handler
+    return null;
+  }
+
+  ContentHandler getServiceHandler(String mimetype) {
+    try {
+      final String filter = "(" + URLConstants.URL_CONTENT_MIMETYPE + "=" + mimetype + ")";
+      //TODO true or false?
+      @SuppressWarnings("unchecked")
+      final ServiceReference<ContentHandler>[] srl
+        = (ServiceReference<ContentHandler>[])
+          framework.services.get(ContentHandler.class.getName(), filter, null);
+
+      if (srl != null && srl.length > 0) {
+        ContentHandlerWrapper wrapper = wrapMap.get(mimetype);
+
+        if (wrapper == null) {
+          wrapper = new ContentHandlerWrapper(framework, mimetype);
+          wrapMap.put(mimetype, wrapper);
+        }
+        return wrapper;
+      }
+    } catch (final InvalidSyntaxException e) {
+      throw new RuntimeException("Failed to get service: " + e);
+    }
+
+    return null;
+  }
+
+
+
+  ContentHandler getJVMClassPathHandler(String mimetype) {
+    if (jvmPkgs != null) {
+      for (final String jvmPkg : jvmPkgs) {
+        final String converted = convertMimetype(mimetype);
+
+        final String className = jvmPkg + "." + converted + ".Handler";
+        try {
+          if(framework.debug.url) {
+            framework.debug.println("JVMClassPathCH - trying ContentHandler class="
+                                    + className);
+          }
+          final Class<?> clazz = Class.forName(className);
+          final ContentHandler handler = (ContentHandler)clazz.newInstance();
+
+          if(framework.debug.url) {
+            framework.debug.println("JVMClassPathCH - created ContentHandler class="
+                                    + className);
+          }
+
+          return handler;
+        } catch (final Throwable t) {
+          if(framework.debug.url) {
+            framework.debug.println("JVMClassPathCH - no ContentHandler class " + className);
+          }
+        }
+      }
+    }
+
+    if(framework.debug.url) {
+      framework.debug.println("JVMClassPath - no ContentHandler for " + mimetype);
+    }
+
+    return null;
+  }
+
+  // please check this one for correctness
+  static String convertMimetype(String s) {
+
+    final String bad = ".,:;*-";
+    for(int i = 0; i < bad.length(); i++) {
+      s = s.replace(bad.charAt(i), '_');
+    }
+
+    s = s.replace('/', '.');
+
+    return s;
+  }
+}
+
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceHooks.java b/osgi/framework/src/org/knopflerfish/framework/ServiceHooks.java
new file mode 100644
index 0000000..9d0f177
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceHooks.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.hooks.service.EventListenerHook;
+import org.osgi.framework.hooks.service.FindHook;
+import org.osgi.framework.hooks.service.ListenerHook;
+import org.osgi.framework.hooks.service.ListenerHook.ListenerInfo;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * Handle all framework hooks, mostly dispatched from BundleImpl, Services
+ * and ServiceListenerState
+ *
+ */
+ at SuppressWarnings("deprecation")
+class ServiceHooks {
+
+  final private FrameworkContext fwCtx;
+  ServiceTracker<ListenerHook,ListenerHook> listenerHookTracker;
+
+  boolean bOpen;
+
+  ServiceHooks(FrameworkContext fwCtx) {
+    this.fwCtx = fwCtx;
+  }
+
+  synchronized void open() {
+    if(fwCtx.debug.hooks) {
+      fwCtx.debug.println("opening hooks");
+    }
+
+    listenerHookTracker = new ServiceTracker<ListenerHook,ListenerHook>
+      (fwCtx.systemBundle.bundleContext,
+       ListenerHook.class,
+       new ServiceTrackerCustomizer<ListenerHook,ListenerHook>() {
+         public ListenerHook addingService(ServiceReference<ListenerHook> reference) {
+           final ListenerHook lh = fwCtx.systemBundle.bundleContext.getService(reference);
+           try {
+             Collection<ServiceListenerEntry> c = getServiceCollection();
+             @SuppressWarnings({ "rawtypes", "unchecked" })
+             final Collection<ListenerInfo> li = (Collection) c;
+             lh.added(li);
+           } catch (final Exception e) {
+             fwCtx.debug.printStackTrace("Failed to call listener hook  #" +
+                                         reference.getProperty(Constants.SERVICE_ID), e);
+           }
+           return lh;
+         }
+
+         public void modifiedService(ServiceReference<ListenerHook> reference, ListenerHook service) {
+           // noop
+         }
+
+         public void removedService(ServiceReference<ListenerHook> reference, ListenerHook service) {
+           fwCtx.systemBundle.bundleContext.ungetService(reference);
+         }
+
+       });
+
+
+    listenerHookTracker.open();
+
+    bOpen = true;
+  }
+
+
+  /**
+   *
+   */
+  synchronized void close() {
+    listenerHookTracker.close();
+    listenerHookTracker = null;
+
+    bOpen = false;
+  }
+
+
+  /**
+   *
+   */
+  synchronized public boolean isOpen() {
+    return bOpen;
+  }
+
+
+  /**
+   *
+   */
+  void filterServiceReferences(BundleContextImpl bc,
+                               String service,
+                               String filter,
+                               boolean allServices,
+                               Collection<ServiceReference<?>> refs)
+  {
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    final List<ServiceRegistrationImpl<FindHook>> srl
+      = (List) fwCtx.services.get(FindHook.class.getName());
+    if (srl != null) {
+      final RemoveOnlyCollection<ServiceReference<?>> filtered
+        = new RemoveOnlyCollection<ServiceReference<?>>(refs);
+
+      for (final ServiceRegistrationImpl<FindHook> fhr : srl) {
+        final ServiceReferenceImpl<FindHook> sr = fhr.reference;
+        final FindHook fh = sr.getService(fwCtx.systemBundle);
+        if (fh != null) {
+          try {
+            fh.find(bc, service, filter, allServices, filtered);
+          } catch (final Exception e) {
+            fwCtx.frameworkError(bc,
+                new BundleException("Failed to call find hook  #" +
+                                    sr.getProperty(Constants.SERVICE_ID), e));
+          }
+        }
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  void filterServiceEventReceivers(final ServiceEvent evt,
+                                   final Collection<ServiceListenerEntry> receivers) {
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    final List<ServiceRegistrationImpl<org.osgi.framework.hooks.service.EventHook>> eventHooks
+      = (List) fwCtx.services.get(org.osgi.framework.hooks.service.EventHook.class.getName());
+
+    if (eventHooks != null) {
+      final HashSet<BundleContext> ctxs = new HashSet<BundleContext>();
+      for (final ServiceListenerEntry sle : receivers) {
+        ctxs.add(sle.getBundleContext());
+      }
+      final int start_size = ctxs.size();
+      final RemoveOnlyCollection<BundleContext> filtered
+        = new RemoveOnlyCollection<BundleContext>(ctxs);
+
+      for (final ServiceRegistrationImpl<org.osgi.framework.hooks.service.EventHook> sregi : eventHooks) {
+        final ServiceReferenceImpl<org.osgi.framework.hooks.service.EventHook> sr = sregi.reference;
+        final org.osgi.framework.hooks.service.EventHook eh = sr.getService(fwCtx.systemBundle);
+        if (eh != null) {
+          try {
+            eh.event(evt, filtered);
+          } catch (final Exception e) {
+            fwCtx.debug.printStackTrace("Failed to call event hook  #" +
+                                        sr.getProperty(Constants.SERVICE_ID), e);
+          }
+        }
+      }
+      // TODO, refactor this for speed!?
+      if (start_size != ctxs.size()) {
+        for (final Iterator<ServiceListenerEntry> ir = receivers.iterator(); ir.hasNext(); ) {
+          if (!ctxs.contains(ir.next().getBundleContext())) {
+            ir.remove();
+          }
+        }
+      }
+    }
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    final List<ServiceRegistrationImpl<EventListenerHook>> eventListenerHooks
+      = (List) fwCtx.services.get(EventListenerHook.class.getName());
+    if (eventListenerHooks != null) {
+      final HashMap<BundleContext, Collection<ListenerInfo>> listeners
+        = new HashMap<BundleContext, Collection<ListenerInfo>>();
+
+      for (final ServiceListenerEntry sle : receivers) {
+        if(!listeners.containsKey(sle.getBundleContext())) {
+          listeners.put(sle.getBundleContext(), new ArrayList<ListenerInfo>());
+        }
+        listeners.get(sle.getBundleContext()).add(sle);
+      }
+
+      for(final Entry<BundleContext, Collection<ListenerInfo>> e : listeners.entrySet()) {
+        e.setValue(new RemoveOnlyCollection<ListenerInfo>(e.getValue()));
+      }
+
+      final RemoveOnlyMap<BundleContext, Collection<ListenerInfo>> filtered
+        = new RemoveOnlyMap<BundleContext, Collection<ListenerInfo>>(listeners);
+
+      for(final ServiceRegistrationImpl<EventListenerHook> sri : eventListenerHooks) {
+        final EventListenerHook elh = sri.reference.getService(fwCtx.systemBundle);
+        if(elh != null) {
+          try {
+            elh.event(evt, filtered);
+          } catch(final Exception e) {
+            fwCtx.debug.printStackTrace("Failed to call event hook  #" +
+                sri.reference.getProperty(Constants.SERVICE_ID), e);
+          }
+        }
+      }
+      receivers.clear();
+      for(final Collection<ListenerInfo> li : listeners.values()) {
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        final Collection<ServiceListenerEntry> sles = (Collection) li;
+        receivers.addAll(sles);
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  Collection<ServiceListenerEntry> getServiceCollection() {
+    // TODO think about threads?!
+    return Collections.unmodifiableSet(fwCtx.listeners.serviceListeners.serviceSet);
+  }
+
+
+  /**
+   *
+   */
+  void handleServiceListenerReg(ServiceListenerEntry sle) {
+    if(!isOpen() || listenerHookTracker.size() == 0) {
+      return;
+    }
+
+    final ServiceReference<ListenerHook>[] srl
+      = listenerHookTracker.getServiceReferences();
+
+    final Set<ListenerInfo> set = toImmutableSet((ListenerInfo) sle);
+
+    if (srl!=null) {
+    for (final ServiceReference<ListenerHook> sr : srl) {
+      final ListenerHook lh = listenerHookTracker.getService(sr);
+      try {
+        lh.added(set);
+      } catch (final Exception e) {
+        fwCtx.debug.printStackTrace("Failed to call listener hook #" +
+                                    sr.getProperty(Constants.SERVICE_ID), e);
+      }
+      }
+
+    }
+  }
+
+
+  /**
+   *
+   */
+  void handleServiceListenerUnreg(ServiceListenerEntry sle) {
+    if(isOpen()) {
+      handleServiceListenerUnreg(toImmutableSet(sle));
+    }
+  }
+
+
+  /**
+   *
+   */
+  void handleServiceListenerUnreg(Collection<ServiceListenerEntry> set) {
+    if(!isOpen() || listenerHookTracker.size() == 0) {
+      return;
+    }
+    final ServiceReference<ListenerHook>[] srl
+      = listenerHookTracker.getServiceReferences();
+
+    if (srl != null) {
+      @SuppressWarnings({ "rawtypes", "unchecked" })
+      final Collection<ListenerInfo> lis = (Collection) set;
+
+      for (final ServiceReference<ListenerHook> sr : srl) {
+        final ListenerHook lh = listenerHookTracker.getService(sr);
+        try {
+          lh.removed(lis);
+        } catch (final Exception e) {
+          fwCtx.debug
+              .printStackTrace("Failed to call listener hook #"
+                                   + sr.getProperty(Constants.SERVICE_ID),
+                               e);
+        }
+      }
+    }
+  }
+
+  /**
+   *
+   */
+  static <E> Set<E> toImmutableSet(E obj) {
+    Set<E> set = new HashSet<E>();
+    set.add(obj);
+    set = Collections.unmodifiableSet(set);
+    return set;
+  }
+
+
+  static class RemoveOnlyMap<K,V> implements Map<K,V> {
+    final Map<K,V> original;
+    public RemoveOnlyMap(Map<K,V> original) {
+      this.original = original;
+    }
+
+    public void clear() {
+      original.clear();
+    }
+
+    public boolean containsKey(Object k) {
+      return original.containsKey(k);
+    }
+
+
+    public boolean containsValue(Object v) {
+      return original.containsValue(v);
+    }
+
+    public Set<Entry<K,V>> entrySet() {
+      return original.entrySet();
+    }
+
+    public V get(Object k) {
+      return original.get(k);
+    }
+
+    public boolean isEmpty() {
+      return original.isEmpty();
+    }
+
+    public Set<K> keySet() {
+      return original.keySet();
+    }
+
+    public V put(Object k, Object v) {
+      throw new UnsupportedOperationException("objects can only be removed");
+    }
+
+    public void putAll(Map<? extends K,? extends V> m) {
+      throw new UnsupportedOperationException("objects can only be removed");
+    }
+
+    public V remove(Object k) {
+      return original.remove(k);
+    }
+
+    public int size() {
+      return original.size();
+    }
+
+    public Collection<V> values() {
+      return original.values();
+    }
+
+  }
+
+  /*
+  void printSLE(String pre, Collection c, String post) {
+    if(pre != null) {
+      System.out.println(pre);
+      System.out.flush();
+    }
+    for(Object o : c) {
+      ServiceListenerEntry sle = (ServiceListenerEntry)o;
+      System.out.println("SLE: " + sle.listener.getClass().getName() + "@" + sle.getFilter());
+      System.out.flush();
+    }
+    if(post != null) {
+      System.out.println(post);
+      System.out.flush();
+    }
+  }
+
+  void printSLE(String pre, Map m, String post) {
+    System.out.println(pre);
+    System.out.flush();
+    for(Object o : m.values()) {
+      Collection c = (Collection)o;
+      printSLE(null, c, null);
+    }
+    System.out.println(post);
+    System.out.flush();
+  }
+*/
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceListenerEntry.java b/osgi/framework/src/org/knopflerfish/framework/ServiceListenerEntry.java
new file mode 100644
index 0000000..160714f
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceListenerEntry.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2003-20103, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.EventListener;
+import java.util.List;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.UnfilteredServiceListener;
+import org.osgi.framework.hooks.service.ListenerHook;
+
+/**
+ * Data structure for saving service listener info. Contains
+ * the optional service listener filter, in addition to the info
+ * in ListenerEntry.
+ */
+class ServiceListenerEntry
+  extends ListenerEntry
+  implements ListenerHook.ListenerInfo
+{
+  final LDAPExpr ldap;
+  final boolean noFiltering;
+
+  /**
+   * The elements of "simple" filters are cached, for easy lookup.
+   *
+   * The grammar for simple filters is as follows:
+   *
+   * <pre>
+   * Simple = '(' attr '=' value ')'
+   *        | '(' '|' Simple+ ')'
+   * </pre>
+   * where <code>attr</code> is one of {@link Constants#OBJECTCLASS},
+   * {@link Constants#SERVICE_ID} or {@link Constants#SERVICE_PID}, and
+   * <code>value</code> must not contain a wildcard character.
+   * <p>
+   * The index of the vector determines which key the cache is for
+   * (see {@link ServiceListenerState#hashedKeys}). For each key, there is
+   * a vector pointing out the values which are accepted by this
+   * ServiceListenerEntry's filter. This cache is maintained to make
+   * it easy to remove this service listener.
+   */
+  List<Object>[] local_cache;
+
+  ServiceListenerEntry(BundleContextImpl bc, EventListener l, String filter)
+    throws InvalidSyntaxException {
+    super(bc, l);
+    if (filter != null) {
+      ldap = new LDAPExpr(filter);
+      noFiltering = l instanceof UnfilteredServiceListener;
+    } else {
+      ldap = null;
+      noFiltering = true;
+    }
+  }
+
+  ServiceListenerEntry(BundleContextImpl bc, EventListener l) {
+    super(bc, l);
+    ldap = null;
+    noFiltering = true;
+  }
+
+  public BundleContext getBundleContext() {
+    return bc;
+  }
+
+  public String getFilter() {
+    return ldap != null ? ldap.toString() : null;
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceListenerState.java b/osgi/framework/src/org/knopflerfish/framework/ServiceListenerState.java
new file mode 100644
index 0000000..4d53044
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceListenerState.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+
+/**
+ * Container of all service listeners.
+ */
+class ServiceListenerState {
+  protected final static String[] hashedKeys =
+    new String[] { Constants.OBJECTCLASS.toLowerCase(),
+                   Constants.SERVICE_ID.toLowerCase(),
+                   Constants.SERVICE_PID.toLowerCase()
+    };
+  private final static int OBJECTCLASS_IX = 0;
+  private final static int SERVICE_ID_IX  = 1;
+  private final static int SERVICE_PID_IX = 2;
+  protected static List<String> hashedKeysV;
+
+  /* Service listeners with complicated or empty filters */
+  List<ServiceListenerEntry> complicatedListeners = new ArrayList<ServiceListenerEntry>();
+
+  /* Service listeners with "simple" filters are cached. */
+  /* [Value -> List(ServiceListenerEntry)] */
+  @SuppressWarnings("unchecked")
+  Map<Object,List<ServiceListenerEntry>>[] cache
+    = new HashMap[hashedKeys.length];
+
+  Set<ServiceListenerEntry> serviceSet = new HashSet<ServiceListenerEntry>();
+
+  Listeners listeners;
+
+  ServiceListenerState(Listeners listeners) {
+    this.listeners = listeners;
+    hashedKeysV = new ArrayList<String>();
+    for (int i = 0; i < hashedKeys.length; i++) {
+      hashedKeysV.add(hashedKeys[i]);
+      cache[i] = new HashMap<Object,List<ServiceListenerEntry>>();
+    }
+  }
+
+  void clear()
+  {
+    hashedKeysV.clear();
+    complicatedListeners.clear();
+    for (int i = 0; i < hashedKeys.length; i++) {
+      cache[i].clear();
+    }
+    serviceSet.clear();
+    listeners = null;;
+  }
+
+  /**
+   * Add a new service listener. If an old one exists, and it has the
+   * same owning bundle, the old listener is removed first.
+   *
+   * @param bc The bundle context adding this listener.
+   * @param listener The service listener to add.
+   * @param filter An LDAP filter string to check when a service is modified.
+   * @exception org.osgi.framework.InvalidSyntaxException
+   * If the filter is not a correct LDAP expression.
+   */
+  synchronized void add(BundleContextImpl bc,
+                        ServiceListener listener,
+                        String filter)
+      throws InvalidSyntaxException
+  {
+    final ServiceListenerEntry sle = new ServiceListenerEntry(bc, listener, filter);
+    if (serviceSet.contains(sle)) {
+      remove(bc, listener);
+    }
+    serviceSet.add(sle);
+    listeners.fwCtx.serviceHooks.handleServiceListenerReg(sle);
+    checkSimple(sle);
+  }
+
+  /**
+   * Remove a service listener.
+   *
+   * @param bc The bundle context removing this listener.
+   * @param listener The service listener to remove.
+   */
+  synchronized void remove(BundleContextImpl bc, ServiceListener listener) {
+    for (final Iterator<ServiceListenerEntry> it = serviceSet.iterator(); it.hasNext();) {
+      final ServiceListenerEntry sle = it.next();
+      if (sle.bc == bc && sle.listener == listener) {
+        sle.setRemoved(true);
+        listeners.fwCtx.serviceHooks.handleServiceListenerUnreg(sle);
+        removeFromCache(sle);
+        it.remove();
+        break;
+      }
+    }
+  }
+
+  /**
+   * Remove all references to a service listener from the service listener
+   * cache.
+   */
+  private void removeFromCache(ServiceListenerEntry sle) {
+    if (sle.local_cache != null) {
+      for (int i = 0; i < hashedKeys.length; i++) {
+        final Map<Object, List<ServiceListenerEntry>> keymap = cache[i];
+        final List<Object> l = sle.local_cache[i];
+        if (l != null) {
+          for (final Object value : l) {
+            final List<ServiceListenerEntry> sles = keymap.get(value);
+            if(sles != null) {
+              sles.remove(sles.indexOf(sle));
+              if (sles.isEmpty()) {
+                keymap.remove(value);
+              }
+            }
+          }
+        }
+      }
+    } else {
+      complicatedListeners.remove(sle);
+    }
+  }
+
+
+  /**
+   * Remove all service listeners registered by the specified bundle context.
+   *
+   * @param bc The bundle context to remove listeners for.
+   */
+  synchronized void removeAll(BundleContextImpl bc) {
+    for (final Iterator<ServiceListenerEntry> it = serviceSet.iterator(); it.hasNext();) {
+      final ServiceListenerEntry sle = it.next();
+      if (sle.bc == bc) {
+        removeFromCache(sle);
+        it.remove();
+      }
+    }
+  }
+
+
+  /**
+   * Remove all service listeners registered by the specified bundle.
+   *
+   * @param bundle The bundle to remove listeners for.
+   */
+  synchronized void hooksBundleStopped(BundleContextImpl bc) {
+    final List<ServiceListenerEntry> entries = new ArrayList<ServiceListenerEntry>();
+    for (final ServiceListenerEntry sle : serviceSet) {
+      if (sle.bc == bc) {
+        entries.add(sle);
+      }
+    }
+    listeners.fwCtx.serviceHooks.handleServiceListenerUnreg(Collections.unmodifiableList(entries));
+  }
+
+
+  /**
+   * Checks if the specified service listener's filter is simple enough
+   * to cache.
+   */
+  public void checkSimple(ServiceListenerEntry sle) {
+    if (sle.noFiltering || listeners.nocacheldap) {
+      complicatedListeners.add(sle);
+    } else {
+      @SuppressWarnings("unchecked")
+      final List<Object>[] local_cache = new List[hashedKeys.length];
+      if (sle.ldap.isSimple(hashedKeysV, local_cache, false)) {
+        sle.local_cache = local_cache;
+        for (int i = 0; i < hashedKeys.length; i++) {
+          if (local_cache[i] != null) {
+            for (final Object value : local_cache[i]) {
+              List<ServiceListenerEntry> sles = cache[i].get(value);
+              if (sles == null)
+                cache[i].put(value, sles = new ArrayList<ServiceListenerEntry>());
+              sles.add(sle);
+            }
+          }
+        }
+      } else {
+        if (listeners.fwCtx.debug.ldap) {
+          listeners.fwCtx.debug.println("Too complicated filter: " + sle.ldap);
+        }
+        complicatedListeners.add(sle);
+      }
+    }
+  }
+
+  /**
+   * Gets the listeners interested in modifications of the service reference
+   *
+   * @param sr The reference related to the event describing the service modification.
+   * @return A set of listeners to notify.
+   */
+  synchronized Set<ServiceListenerEntry> getMatchingListeners(ServiceReferenceImpl<?> sr)
+  {
+    final Set<ServiceListenerEntry> set = new HashSet<ServiceListenerEntry>();
+    // Check complicated or empty listener filters
+    int n = 0;
+    for (final ServiceListenerEntry sle : complicatedListeners) {
+      if (sle.noFiltering || sle.ldap.evaluate(sr.getProperties(), false)) {
+        set.add(sle);
+      }
+      ++n;
+    }
+    if (listeners.fwCtx.debug.ldap) {
+      listeners.fwCtx.debug.println("Added " + set.size() + " out of " + n +
+                                        " listeners with complicated filters");
+    }
+    // Check the cache
+    final String[] c = (String[])sr.getProperty(Constants.OBJECTCLASS);
+    for (final String element : c) {
+      addToSet(set, OBJECTCLASS_IX, element);
+    }
+    final Long service_id = (Long)sr.getProperty(Constants.SERVICE_ID);
+    if (service_id != null) {
+      addToSet(set, SERVICE_ID_IX, service_id.toString());
+    }
+    final Object service_pid = sr.getProperty(Constants.SERVICE_PID);
+    if (service_pid != null) {
+      if (service_pid instanceof String) {
+        addToSet(set, SERVICE_PID_IX, service_pid);
+      } else if (service_pid instanceof String []) {
+        final String [] sa = (String [])service_pid;
+        for (final String element : sa) {
+          addToSet(set, SERVICE_PID_IX, element);
+        }
+      } else if (service_pid instanceof Collection) {
+        // TODO should we report if type isn't a String?
+        @SuppressWarnings("unchecked")
+        final Collection<String> pids = (Collection<String>) service_pid;
+        for (final String pid : pids) {
+          addToSet(set, SERVICE_PID_IX, pid);
+        }
+      }
+    }
+    return set;
+  }
+
+  /**
+   * Add all members of the specified list to the specified set.
+   */
+  private void addToSet(Set<ServiceListenerEntry> set, int cache_ix, Object val) {
+    final List<ServiceListenerEntry> l = cache[cache_ix].get(val);
+    if (l != null) {
+      if (listeners.fwCtx.debug.ldap) {
+        listeners.fwCtx.debug.println(hashedKeys[cache_ix] + " matches " + l.size());
+      }
+      set.addAll(l);
+    } else {
+      if (listeners.fwCtx.debug.ldap) {
+        listeners.fwCtx.debug.println(hashedKeys[cache_ix] + " matches none");
+      }
+    }
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceReferenceImpl.java b/osgi/framework/src/org/knopflerfish/framework/ServiceReferenceImpl.java
new file mode 100644
index 0000000..12d7c15
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceReferenceImpl.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Implementation of the ServiceReference object.
+ *
+ * @see org.osgi.framework.ServiceReference
+ * @author Jan Stein
+ */
+public class ServiceReferenceImpl<S> implements ServiceReference<S>
+{
+
+  /**
+   * Link to registration object for this reference.
+   */
+  private final ServiceRegistrationImpl<S> registration;
+
+
+  /**
+   * Construct a ServiceReference based on given ServiceRegistration.
+   *
+   * @param reg ServiceRegistration pointed to be this reference.
+   */
+  ServiceReferenceImpl(ServiceRegistrationImpl<S> reg) {
+    registration = reg;
+  }
+
+  //
+  // ServiceReference interface
+  //
+
+  /**
+   * Get the value of a service's property.
+   *
+   * @see org.osgi.framework.ServiceReference#getProperty
+   */
+  public Object getProperty(String key) {
+    return cloneObject(registration.getProperty(key));
+  }
+
+
+  /**
+   * Get the list of key names for the service's properties.
+   *
+   * @see org.osgi.framework.ServiceReference#getPropertyKeys
+   */
+  public String[] getPropertyKeys() {
+    return registration.getProperties().keyArray();
+  }
+
+
+  /**
+   * Return the bundle which registered the service.
+   *
+   * @see org.osgi.framework.ServiceReference#getBundle
+   */
+  public Bundle getBundle() {
+    return registration.bundle;
+  }
+
+
+  /**
+   * Test if ServiceReferences points to same service.
+   *
+   * @see org.osgi.framework.ServiceReference
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (o instanceof ServiceReferenceImpl) {
+      final ServiceReferenceImpl<?> that = (ServiceReferenceImpl<?>)o;
+      return registration == that.registration;
+    }
+    return false;
+  }
+
+  /**
+   * Compare two ServiceReferences
+   *
+   * @see org.osgi.framework.ServiceReference
+   */
+  public int compareTo(Object obj) {
+    final ServiceReference<?> that = (ServiceReference<?>)obj;
+
+    boolean sameFw = false;
+    if (that instanceof ServiceReferenceImpl) {
+      final ServiceReferenceImpl<?> thatImpl = (ServiceReferenceImpl<?>) that;
+      sameFw
+        = this.registration.fwCtx == thatImpl.registration.fwCtx;
+    }
+    if (!sameFw) {
+      throw new IllegalArgumentException("Can not compare service references "
+                                         +"belonging to different framework "
+                                         +"instances (this=" +this +", other="
+                                         +that +").");
+    }
+
+    final Object ro1 = this.getProperty(Constants.SERVICE_RANKING);
+    final Object ro2 = that.getProperty(Constants.SERVICE_RANKING);
+    final int r1 = (ro1 instanceof Integer) ? ((Integer)ro1).intValue() : 0;
+    final int r2 = (ro2 instanceof Integer) ? ((Integer)ro2).intValue() : 0;
+
+    if (r1 != r2) {
+      // use ranking if ranking differs
+      return r1 < r2 ? -1 : 1;
+    } else {
+      final Long id1 = (Long)this.getProperty(Constants.SERVICE_ID);
+      final Long id2 = (Long)that.getProperty(Constants.SERVICE_ID);
+
+      // otherwise compare using IDs,
+      // is less than if it has a higher ID.
+      return id2.compareTo(id1);
+    }
+  }
+
+
+  /**
+   * Return a hashcode for the service.
+   *
+   * @see org.osgi.framework.ServiceReference
+   */
+  @Override
+  public int hashCode() {
+    return registration.hashCode();
+  }
+
+  //
+  // ServiceReference interface OSGI R2
+  //
+
+  /**
+   * Return the bundles that are using the service wrapped by this
+   * ServiceReference, i.e., whose usage count for this service
+   * is greater than zero.
+   *
+   * @return array of bundles whose usage count for the service wrapped by
+   * this ServiceReference is greater than zero, or <tt>null</tt> if no
+   * bundles currently are using this service
+   *
+   * @since 1.1
+   */
+  public Bundle[] getUsingBundles() {
+    return registration.getUsingBundles();
+  }
+
+  //
+  // Package methods
+  //
+
+  /**
+   * Get the service object.
+   *
+   * @param bundle requester of service.
+   * @return Service requested or null in case of failure.
+   */
+  S getService(final BundleImpl bundle) {
+    bundle.fwCtx.perm.checkGetServicePerms(this);
+    return registration.getService(bundle);
+  }
+
+
+  /**
+   * Unget the service object.
+   *
+   * @param bundle Bundle who wants remove service.
+   * @return True if service was used, otherwise false.
+   */
+  boolean ungetService(BundleImpl bundle) {
+    return registration.ungetService(bundle, true);
+  }
+
+
+  /**
+   * Get all properties registered with this service.
+   *
+   * @return Dictionary containing properties or null
+   *         if service has been removed.
+   */
+  PropertiesDictionary getProperties() {
+    return registration.getProperties();
+  }
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Clone object. Handles all service property types
+   * and does this recursively.
+   *
+   * @param bundle Object to clone.
+   * @return Cloned object.
+   */
+  Object cloneObject(Object val) {
+    if (val instanceof Object []) {
+      val = ((Object [])val).clone();
+      final int len = Array.getLength(val);
+      if (len > 0 && Array.get(val, 0).getClass().isArray()) {
+        for (int i = 0; i < len; i++) {
+          Array.set(val, i, cloneObject(Array.get(val, i)));
+        }
+      }
+    } else if (val instanceof boolean []) {
+      val = ((boolean [])val).clone();
+    } else if (val instanceof byte []) {
+      val = ((byte [])val).clone();
+    } else if (val instanceof char []) {
+      val = ((char [])val).clone();
+    } else if (val instanceof double []) {
+      val = ((double [])val).clone();
+    } else if (val instanceof float []) {
+      val = ((float [])val).clone();
+    } else if (val instanceof int []) {
+      val = ((int [])val).clone();
+    } else if (val instanceof long []) {
+      val = ((long [])val).clone();
+    } else if (val instanceof short []) {
+      val = ((short [])val).clone();
+    } else if (val instanceof Vector) {
+      @SuppressWarnings({ "rawtypes", "unchecked" })
+      final Vector<Object> c = (Vector)((Vector)val).clone();
+      for (int i = 0; i < c.size(); i++) {
+        c.setElementAt(cloneObject(c.elementAt(i)), i);
+      }
+      val = c;
+    }
+    return val;
+  }
+
+
+  public boolean isAssignableTo(Bundle bundle, String className) {
+    final BundleImpl sBundle = registration.bundle;
+    if (sBundle == null) {
+        throw new IllegalStateException("Service is unregistered");
+    }
+    final FrameworkContext fwCtx = sBundle.fwCtx;
+    if (((BundleImpl)bundle).fwCtx != fwCtx) {
+      throw new IllegalArgumentException("Bundle is not from same framework as service");
+    }
+    // Check if bootdelegated
+    if (fwCtx.isBootDelegated(className)) {
+      return true;
+    }
+    final int pos = className.lastIndexOf('.');
+    if (pos != -1) {
+      final String name = className.substring(0, pos);
+      final Pkg p = fwCtx.resolver.getPkg(name);
+      // Is package exported by a bundle
+      if (p != null) {
+        final BundlePackages rbp = sBundle.current().bpkgs;
+        final BundlePackages pkgExporter = rbp.getProviderBundlePackages(name);
+        List<BundleGeneration> pkgProvider;
+        if (pkgExporter == null) {
+          // Package not imported by provide, is it required
+          pkgProvider = rbp.getRequiredBundleGenerations(name);
+        } else {
+          pkgProvider = new ArrayList<BundleGeneration>(1);
+          pkgProvider.add(pkgExporter.bg);
+        }
+        final BundlePackages bb = ((BundleImpl)bundle).current().bpkgs;
+        final BundlePackages bbp = bb.getProviderBundlePackages(name);
+        List<BundleGeneration> pkgConsumer;
+        if (bbp == null) {
+          // Package not imported by bundle, is it required
+          pkgConsumer = bb.getRequiredBundleGenerations(name);
+        } else {
+          pkgConsumer = new ArrayList<BundleGeneration>(1);
+          pkgConsumer.add(bbp.bg);
+        }
+        if (pkgConsumer == null) {
+          // NYI! Check dynamic import?
+          if (bb.isExported(name)) {
+            // If bundle only exports package, then return true if
+            // bundle is provider.
+            return pkgProvider!=null ? pkgProvider.contains(bb.bg) : true;
+          } else {
+            // If bundle doesn't import or export package, then return true and
+            // assume that the bundle only uses reflection to access service.
+            return true;
+          }
+        } else if (pkgProvider == null) {
+          // Package not imported by registrar. E.g. proxy registration.
+          final Object sService = registration.service;
+          if (sService == null) {
+            throw new IllegalStateException("Service is unregistered");
+          }
+          if (p.providers.size() == 1) {
+            // Only one version available, allow.
+            return true;
+          } else if (sService instanceof ServiceFactory) {
+            // Factory, allow.
+            return true;
+          } else {
+            // Use the classloader of bundle to load the class, then check
+            // if the service's class is assignable.
+            final ClassLoader bCL = bb.getClassLoader();
+            if (bCL!=null) {
+              try {
+                final Class<?> bCls = bCL.loadClass(className);
+                // NYI, Handle Service Factories.
+                return bCls.isAssignableFrom(sService.getClass());
+              } catch (final Exception e) {
+                // If we can not load, assume that we are just a proxy.
+                return true;
+              }
+            }
+          }
+          // Fallback: Always OK when singleton provider of the package
+        } else { // Package imported by both parties
+          // Return true if we have same provider as service.
+          for (final Object element : pkgProvider) {
+            if (pkgConsumer.contains(element)) {
+              return true;
+            }
+          }
+        }
+      } else {
+        // Not a package under package control. System package?
+        if (name.startsWith("java.") || sBundle == bundle) {
+          return true;
+        } else {
+          // NYI! We have a private service, check if bundle can use it.
+          // Now, allow it to handle reflection of service.
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceRegistrationImpl.java b/osgi/framework/src/org/knopflerfish/framework/ServiceRegistrationImpl.java
new file mode 100644
index 0000000..636ec68
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceRegistrationImpl.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2003-2012, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceException;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+
+/**
+ * Implementation of the ServiceRegistration object.
+ *
+ * @see org.osgi.framework.ServiceRegistration
+ * @author Jan Stein
+ */
+public class ServiceRegistrationImpl<S> implements ServiceRegistration<S>
+{
+  /**
+   * Bundle registering this service.
+   */
+  final FrameworkContext fwCtx;
+
+  /**
+   * Bundle registering this service.
+   */
+  BundleImpl bundle;
+
+  /**
+   * Service or ServiceFactory object.
+   */
+  Object service;
+
+  /**
+   * Reference object to this service registration.
+   */
+  ServiceReferenceImpl<S> reference;
+
+  /**
+   * Service properties.
+   */
+  private PropertiesDictionary properties;
+
+  /**
+   * Bundles dependent on this service. Integer is used as
+   * reference counter, counting number of unbalanced getService().
+   */
+  private Hashtable<Bundle,Integer> dependents = new Hashtable<Bundle, Integer>();
+
+  /**
+   * Object instances that factory has produced.
+   */
+  private HashMap<Bundle,S> serviceInstances = new HashMap<Bundle, S>();
+
+  /**
+   * Unget in progress for bundle in set.
+   */
+  private final HashSet<Bundle> ungetInProgress = new HashSet<Bundle>();
+
+  /**
+   * Is service available. I.e., if <code>true</code> then holders
+   * of a ServiceReference for the service are allowed to get it.
+   */
+  private volatile boolean available;
+
+  /**
+   * Lock object for synchronous event delivery.
+   */
+  private final Object eventLock = new Object();
+
+  /**
+   * Avoid recursive unregistrations. I.e., if <code>true</code> then
+   * unregistration of this service have started but are not yet
+   * finished.
+   */
+  private volatile boolean unregistering = false;
+
+
+  /**
+   * Detect recursive service factory calls. Is set to thread executing
+   * service factory code, otherwise <code>null</code>.
+   */
+  private Thread factoryThread = null;
+
+
+  /**
+   * Construct a ServiceRegistration for a registered service.
+   *
+   * @param b Bundle providing service.
+   * @param s Service object.
+   * @param props Properties describing service.
+   */
+  ServiceRegistrationImpl(BundleImpl b, Object s, PropertiesDictionary props) {
+    fwCtx = b.fwCtx;
+    bundle = b;
+    service = s;
+    properties = props;
+    reference = new ServiceReferenceImpl<S>(this);
+    available = true;
+  }
+
+  //
+  // ServiceRegistration interface
+  //
+
+  /**
+   * Returns a ServiceReference object for this registration.
+   *
+   * @see org.osgi.framework.ServiceRegistration#getReference
+   */
+  public ServiceReference<S> getReference() {
+    final ServiceReference<S> res = reference;
+    if (res != null) {
+      return res;
+    } else {
+      throw new IllegalStateException("Service is unregistered");
+    }
+  }
+
+
+  /**
+   * Update the properties associated with this service.
+   *
+   * @see org.osgi.framework.ServiceRegistration#setProperties
+   */
+  public void setProperties(Dictionary<String,?> props) {
+    synchronized (eventLock) {
+      if (available) {
+        Set<ServiceListenerEntry> before;
+        // TODO, optimize the locking of services
+        synchronized (fwCtx.services) {
+          synchronized (properties) {
+            // NYI! Optimize the MODIFIED_ENDMATCH code
+            final Object old_rank = properties.get(Constants.SERVICE_RANKING);
+            before = fwCtx.listeners.getMatchingServiceListeners(reference);
+            final String[] classes = (String[])properties.get(Constants.OBJECTCLASS);
+            final Long sid = (Long)properties.get(Constants.SERVICE_ID);
+            properties = new PropertiesDictionary(props, classes, sid);
+            final Object new_rank = properties.get(Constants.SERVICE_RANKING);
+            if (old_rank != new_rank && new_rank instanceof Integer &&
+                !((Integer)new_rank).equals(old_rank)) {
+              fwCtx.services.updateServiceRegistrationOrder(this, classes);
+            }
+          }
+        }
+        fwCtx.perm
+          .callServiceChanged(fwCtx,
+                              fwCtx.listeners.getMatchingServiceListeners(reference),
+                              new ServiceEvent(ServiceEvent.MODIFIED, reference),
+                              before);
+        if (!before.isEmpty()) {
+          fwCtx.perm
+            .callServiceChanged(fwCtx,
+                                before,
+                                new ServiceEvent(ServiceEvent.MODIFIED_ENDMATCH, reference),
+                                null);
+        }
+      } else {
+        throw new IllegalStateException("Service is unregistered");
+      }
+    }
+  }
+
+  /**
+   * Unregister the service.
+   *
+   * @see org.osgi.framework.ServiceRegistration#unregister
+   */
+  public void unregister() {
+    if (unregistering) return; // Silently ignore redundant unregistration.
+    synchronized (eventLock) {
+      if (unregistering) return;
+      unregistering = true;
+
+      if (available) {
+        if (null!=bundle) {
+          fwCtx.services.removeServiceRegistration(this);
+        }
+      } else {
+        throw new IllegalStateException("Service is unregistered");
+      }
+    }
+
+    if (null!=bundle) {
+      fwCtx.perm
+        .callServiceChanged(fwCtx,
+                            fwCtx.listeners.getMatchingServiceListeners(reference),
+                            new ServiceEvent(ServiceEvent.UNREGISTERING, reference),
+                            null);
+    }
+    synchronized (eventLock) {
+      available = false;
+      final Bundle [] using = getUsingBundles();
+      if (using != null) {
+        for (final Bundle element : using) {
+          ungetService(element, false);
+        }
+      }
+      synchronized (properties) {
+        bundle = null;
+        dependents = null;
+        reference = null;
+        service = null;
+        serviceInstances = null;
+        unregistering = false;
+      }
+    }
+  }
+
+  //
+  // Framework internal
+  //
+
+  /**
+   * Get all properties
+   */
+  PropertiesDictionary getProperties() {
+    return properties;
+  }
+
+
+  /**
+   * Get specified property
+   */
+  Object getProperty(String key) {
+    return properties.get(key);
+  }
+
+
+  /**
+   * Get the service object.
+   *
+   * @param bundle requester of service.
+   * @return Service requested or null in case of failure.
+   */
+  S getService(Bundle b) {
+    Integer ref;
+    BundleImpl sBundle = null;
+    synchronized (properties) {
+      if (available) {
+        ref = dependents.get(b);
+        if (service instanceof ServiceFactory) {
+          if (ref == null) {
+            dependents.put(b, new Integer(0));
+            factoryThread = Thread.currentThread();
+          } else if (factoryThread != null) {
+            if (factoryThread.equals(Thread.currentThread())) {
+              throw new IllegalStateException("Recursive call of getService");
+            }
+          }
+        } else {
+          dependents.put(b, new Integer(ref != null ? ref.intValue() + 1 : 1));
+          @SuppressWarnings("unchecked")
+          final
+          S res = (S) service;
+          return res;
+        }
+        sBundle = bundle;
+      } else {
+        return null;
+      }
+    }
+    S s = null;
+    if (ref == null) {
+      try {
+        s = sBundle.fwCtx.perm.callGetService(this, b);
+        if (s == null) {
+          sBundle.fwCtx.frameworkWarning(sBundle,
+             new ServiceException("ServiceFactory produced null",
+                                  ServiceException.FACTORY_ERROR));
+        }
+      } catch (final Throwable pe) {
+        sBundle.fwCtx.frameworkError(sBundle,
+            new ServiceException("ServiceFactory throw an exception",
+                                ServiceException.FACTORY_EXCEPTION, pe));
+      }
+      if (s != null) {
+        final String[] classes = (String[])getProperty(Constants.OBJECTCLASS);
+        for (final String classe : classes) {
+          final String cls = classe;
+          if (!sBundle.fwCtx.services.checkServiceClass(s, cls)) {
+            sBundle.fwCtx.frameworkError(sBundle,
+                new ServiceException("ServiceFactory produced an object " +
+                                     "that did not implement: " + cls,
+                                     ServiceException.FACTORY_ERROR));
+            s = null;
+            break;
+          }
+        }
+      }
+      if (s == null) {
+        synchronized (properties) {
+          if (dependents != null) {
+            dependents.remove(b);
+          }
+          factoryThread = null;
+          return null;
+        }
+      }
+    }
+
+    boolean recall = false;
+    synchronized (properties) {
+      if (s == null) {
+        // Wait for service factory
+        while (true) {
+          s = serviceInstances.get(b);
+          if (s != null) {
+            break;
+          }
+          try {
+            properties.wait(500);
+          } catch (final InterruptedException ie) { }
+          if (dependents == null || !dependents.containsKey(b)) {
+            // Service has been returned
+            break;
+          }
+        }
+      } else {
+        factoryThread = null;
+        serviceInstances.put(b, s);
+        properties.notifyAll();
+      }
+      if (s != null) {
+        ref = dependents != null ? (Integer)dependents.get(b) : null;
+        if (ref != null) {
+          dependents.put(b, new Integer(ref.intValue() + 1));
+        } else {
+          // ungetService has been called during factory call.
+          // Recall service
+          recall = true;
+        }
+      }
+    }
+    if (recall) {
+      try {
+        sBundle.fwCtx.perm.callUngetService(this, b, s);
+      } catch (final Throwable e) {
+        sBundle.fwCtx.frameworkError(sBundle, e);
+      }
+      return null;
+    } else {
+      return s;
+    }
+  }
+
+  Bundle[] getUsingBundles() {
+    final Hashtable<Bundle, Integer> d = dependents;
+    if (d != null) {
+      synchronized (d) {
+        int size = d.size() + ungetInProgress.size();
+        if (size > 0) {
+          final Bundle[] res =  new Bundle[size];
+          for (final Enumeration<Bundle> e = d.keys(); e.hasMoreElements(); ) {
+            res[--size] = e.nextElement();
+          }
+          for (final Bundle b : ungetInProgress) {
+            res[--size] = b;
+          }
+          return res;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Check if a bundle uses this service
+   *
+   * @param b Bundle to check
+   * @return true if bundle uses this service
+   */
+  boolean isUsedByBundle(Bundle b) {
+    final Hashtable<Bundle, Integer> deps = dependents;
+    if (deps != null) {
+      return deps.containsKey(b);
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Unget the service object.
+   *
+   * @param b Bundle who wants remove service.
+   * @param checkRefCounter If true decrement reference counter and remove service
+   *                        if we reach zero. If false remove service without
+   *                        checking reference counter.
+   * @return True if service was used, otherwise false.
+   *
+   */
+  boolean ungetService(Bundle b, boolean checkRefCounter) {
+    S serviceToRemove = null;
+    Hashtable<Bundle,Integer> deps;
+    BundleImpl sBundle;
+    synchronized (properties) {
+      if (dependents == null) {
+        return false;
+      }
+      final Object countInteger = dependents.get(b);
+      if (countInteger == null) {
+        return false;
+      }
+
+      final int count = ((Integer) countInteger).intValue();
+      if (checkRefCounter && count > 1) {
+        dependents.put(b, new Integer(count - 1));
+      } else {
+        synchronized (dependents) {
+          ungetInProgress.add(b);
+          dependents.remove(b);
+        }
+        serviceToRemove = serviceInstances.remove(b);
+      }
+      deps = dependents;
+      sBundle = bundle;
+    }
+
+    if (serviceToRemove != null) {
+      if (service instanceof ServiceFactory) {
+        try {
+          sBundle.fwCtx.perm.callUngetService(this, b, serviceToRemove);
+        } catch (final Throwable e) {
+          sBundle.fwCtx.frameworkError(sBundle, e);
+        }
+      }
+    }
+    synchronized (deps) {
+      ungetInProgress.remove(b);
+    }
+    return true;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/ServiceURLStreamHandlerFactory.java b/osgi/framework/src/org/knopflerfish/framework/ServiceURLStreamHandlerFactory.java
new file mode 100644
index 0000000..b04d284
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/ServiceURLStreamHandlerFactory.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.url.URLConstants;
+import org.osgi.service.url.URLStreamHandlerService;
+
+
+/**
+ * Factory creating URLStreamHandlers from both built-in
+ * handlers and OSGi-registered URLStreamHandlerServices.
+ * 
+ * TODO: Handle separation between different frameworks.
+ */
+public class ServiceURLStreamHandlerFactory
+  implements URLStreamHandlerFactory
+{
+  Vector<FrameworkContext> framework = new Vector<FrameworkContext>(2);
+
+  //
+  // Special framework handlers
+  //
+  Hashtable<String, URLStreamHandler> handlers = new Hashtable<String, URLStreamHandler>();
+
+  // JVM classpath handlers. Initialized once at startup
+  String[] jvmPkgs = null;
+
+  //
+  // OSGi URLStreamHandlerService wrappers
+  // This map is not really necessary since the JVM
+  // caches handlers anyway, but it just seems nice to have.
+  //
+  HashMap<String, URLStreamHandlerWrapper> wrapMap
+    = new HashMap<String, URLStreamHandlerWrapper>();
+
+  //
+  BundleURLStreamHandler bundleHandler;
+
+  // Debug handle for fw which created this factory
+  private Debug debug = null;
+
+
+  ServiceURLStreamHandlerFactory() {
+    // Initialize JVM classpath packages
+    final String s = System.getProperty("java.protocol.handler.pkgs");
+    if (s != null) {
+      jvmPkgs = Util.splitwords(s, "|");
+      for(int i = 0; i < jvmPkgs.length; i++) {
+        jvmPkgs[i] = jvmPkgs[i].trim();
+      }
+    }
+    // Add framework protocols
+    setURLStreamHandler(FWResourceURLStreamHandler.PROTOCOL, new FWResourceURLStreamHandler());
+    setURLStreamHandler(ReferenceURLStreamHandler.PROTOCOL, new ReferenceURLStreamHandler());
+    bundleHandler = new BundleURLStreamHandler();
+    setURLStreamHandler(BundleURLStreamHandler.PROTOCOL, bundleHandler);
+  }
+
+  /**
+   *
+   */
+  public URLStreamHandler createURLStreamHandler(String protocol) {
+    Debug doDebug = debug;
+    if (doDebug != null && !doDebug.url) {
+      doDebug = null;
+    }
+    if (doDebug != null) {
+      doDebug.println("createURLStreamHandler protocol=" + protocol);
+    }
+
+    // Check for
+    // 1. JVM classpath handlers
+    // 2. Framework built-in handlers
+    // 2. OSGi-based handlers
+    // 3. system handlers
+    URLStreamHandler handler = getJVMClassPathHandler(protocol);
+    if (handler != null) {
+      if (doDebug != null) {
+        doDebug.println("using JVMClassPath handler for " + protocol);
+      }
+      return handler;
+    }
+    handler = (URLStreamHandler)handlers.get(protocol);
+    if (handler != null) {
+      if (doDebug != null) {
+        doDebug.println("using predefined handler for " + protocol);
+      }
+      return handler;
+    }
+
+    handler = getServiceHandler(protocol);
+    if (handler != null) {
+      if (doDebug != null) {
+        doDebug.println("Using service URLHandler for " + protocol);
+      }
+      return handler;
+    }
+
+    if (doDebug != null) {
+      doDebug.println("Using default URLHandler for " + protocol);
+    }
+    return null;
+  }
+
+
+  /**
+   * Sets the handler for a named protocol.
+   *
+   * <p>
+   * Any old handler for the specified protocol will be lost.
+   * </p>
+   *
+   * @param protocol Protocol name.
+   * @param handler Handler for the specified protocol name.
+   */
+  void setURLStreamHandler(String protocol, URLStreamHandler handler) {
+    handlers.put(protocol, handler);
+  }
+
+
+  /**
+   * Add framework that uses this URLStreamHandlerFactory.
+   *
+   * @param fw Framework context for framework to add.
+   */
+  void addFramework(FrameworkContext fw) {
+    bundleHandler.addFramework(fw);
+    synchronized (wrapMap) {
+      if (debug == null) {
+        debug = fw.debug;
+      }
+      framework.add(fw);
+    }
+  }
+
+
+  /**
+   * Remove framework that uses this URLStreamHandlerFactory.
+   *
+   * @param fw Framework context for framework to remove.
+   */
+  void removeFramework(FrameworkContext fw) {
+    bundleHandler.removeFramework(fw);
+    synchronized (wrapMap) {
+      for (Iterator<Map.Entry<String, URLStreamHandlerWrapper>> i = wrapMap.entrySet().iterator(); i.hasNext(); ) {
+        Map.Entry<String, URLStreamHandlerWrapper> e = i.next();
+        if ((e.getValue()).removeFramework(fw)) {
+          i.remove();
+        }
+      }
+      framework.remove(fw);
+      if (debug == fw.debug) {
+        if (framework.isEmpty()) {
+          debug = null;
+        } else {
+          debug = framework.get(0).debug;
+        }
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  private URLStreamHandler getServiceHandler(final String protocol)
+  {
+    try {
+      final String filter =
+        "(" +
+        URLConstants.URL_HANDLER_PROTOCOL +
+        "=" + protocol +
+        ")";
+      @SuppressWarnings("unchecked")
+      final Vector<FrameworkContext> sfws = (Vector<FrameworkContext>)framework.clone();
+      for (final FrameworkContext sfw : sfws) {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<URLStreamHandlerService>[] srl
+          = (ServiceReference<URLStreamHandlerService>[]) sfw.services
+            .get(URLStreamHandlerService.class.getName(), filter, null);
+
+        if (srl != null && srl.length > 0) {
+          synchronized (wrapMap) {
+            URLStreamHandlerWrapper wrapper = wrapMap.get(protocol);
+            if (wrapper == null) {
+              wrapper = new URLStreamHandlerWrapper(sfw, protocol);
+              wrapMap.put(protocol, wrapper);
+            } else {
+              wrapper.addFramework(sfw);
+            }
+            return wrapper;
+          }
+        }
+      }
+    } catch (final InvalidSyntaxException e) {
+      throw new RuntimeException("Failed to get service: " + e);
+    }
+
+    // no handler found
+    return null;
+  }
+
+
+  /**
+   * Check if there exists a JVM classpath handler for a protocol.
+   */
+  private URLStreamHandler getJVMClassPathHandler(final String protocol)
+  {
+    Debug doDebug = debug;
+    if (doDebug != null && !doDebug.url) {
+      doDebug = null;
+    }
+    if (jvmPkgs != null) {
+      for (final String jvmPkg : jvmPkgs) {
+        final String className = jvmPkg + "." + protocol + ".Handler";
+        try {
+          if (doDebug != null) {
+            doDebug.println("JVMClassPath - trying URLHandler class=" + className);
+          }
+          final Class<?> clazz = Class.forName(className);
+          final URLStreamHandler handler = (URLStreamHandler)clazz.newInstance();
+
+          if (doDebug != null) {
+            doDebug.println("JVMClassPath - created URLHandler class=" + className);
+          }
+
+          return handler;
+        } catch (final Throwable t) {
+          if (doDebug != null) {
+            doDebug.println("JVMClassPath - no URLHandler class " + className);
+          }
+        }
+      }
+    }
+
+    if (doDebug != null) {
+      doDebug.println("JVMClassPath - no URLHandler for " + protocol);
+    }
+
+    return null;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Services.java b/osgi/framework/src/org/knopflerfish/framework/Services.java
new file mode 100644
index 0000000..b50382b
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Services.java
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
+import org.osgi.service.permissionadmin.PermissionAdmin;
+
+
+/**
+ * Here we handle all the services that are registered in framework.
+ *
+ * @author Jan Stein, Philippe Laporte, Gunnar Ekolin
+ */
+class Services {
+
+  /**
+   * All registered services in the current framework.
+   * Mapping of registered service to class names under which service
+   * is registered.
+   */
+  HashMap<ServiceRegistrationImpl<?>, String[]> services
+    = new HashMap<ServiceRegistrationImpl<?>, String[]>();
+
+  /**
+   * Mapping of class name to registered service.
+   * The List of registered service are order in with highest
+   * ranked service first.
+   */
+  private final HashMap<String,List<ServiceRegistrationImpl<?>>> classServices
+    = new HashMap<String, List<ServiceRegistrationImpl<?>>>();
+
+  /**
+   * Handle to secure call class.
+   */
+  private PermissionOps secure;
+
+
+  FrameworkContext framework;
+
+  Services(FrameworkContext fwCtx, PermissionOps perm) {
+    this.framework = fwCtx;
+    secure = perm;
+  }
+
+  void clear()
+  {
+    services.clear();
+    classServices.clear();
+    secure = null;
+    framework = null;
+  }
+
+  /**
+   * Register a service in the framework wide register.
+   *
+   * @param bundle The bundle registering the service.
+   * @param classes The class names under which the service can be located.
+   * @param service The service object.
+   * @param properties The properties for this service.
+   * @return A {@link ServiceRegistration} object.
+   * @exception java.lang.IllegalArgumentException If one of the following is true:
+   * <ul>
+   * <li>The service object is null.</li>
+   * <li>The defining class of the service parameter is not owned by the bundle.</li>
+   * <li>The service parameter is not a ServiceFactory and is not an
+   * instance of all the named classes in the classes parameter.</li>
+   * </ul>
+   */
+  @SuppressWarnings("deprecation")
+  ServiceRegistration<?> register(BundleImpl bundle,
+                                  String[] classes,
+                                  Object service,
+                                  Dictionary<String, ?> properties)
+  {
+    if (service == null) {
+      throw new IllegalArgumentException("Can't register null as a service");
+    }
+    // Check if service implements claimed classes and that they exist.
+    for (final String classe : classes) {
+      final String cls = classe;
+      if (cls == null) {
+        throw new IllegalArgumentException("Can't register as null class");
+      }
+      secure.checkRegisterServicePerm(cls);
+      if (bundle.id != 0) {
+        if (cls.equals(org.osgi.service.packageadmin.PackageAdmin.class.getName())) {
+          throw new IllegalArgumentException
+            ("Registeration of a PackageAdmin service is not allowed");
+        }
+        if (cls.equals(PermissionAdmin.class.getName())) {
+          throw new IllegalArgumentException
+            ("Registeration of a PermissionAdmin service is not allowed");
+        }
+        if (cls.equals(ConditionalPermissionAdmin.class.getName())) {
+          throw new IllegalArgumentException
+            ("Registeration of a ConditionalPermissionAdmin service is not allowed");
+        }
+      }
+      if (!(service instanceof ServiceFactory)) {
+        if (!checkServiceClass(service, cls)) {
+          throw new IllegalArgumentException
+            ("Service object is not an instance of " + cls);
+        }
+      }
+    }
+
+    @SuppressWarnings("rawtypes")
+    final ServiceRegistrationImpl<?> res =
+      new ServiceRegistrationImpl(bundle, service,
+                                  new PropertiesDictionary(properties, classes, null));
+    synchronized (this) {
+      services.put(res, classes);
+      for (final String clazz : classes) {
+        List<ServiceRegistrationImpl<?>> s
+          = classServices.get(clazz);
+        if (s == null) {
+          s = new ArrayList<ServiceRegistrationImpl<?>>(1);
+          classServices.put(clazz, s);
+        }
+        final int ip = Math.abs(Util.binarySearch(s, sComp, res) + 1);
+        s.add(ip, res);
+      }
+    }
+    final ServiceReference<?> r = res.getReference();
+    bundle.fwCtx.perm
+      .callServiceChanged(bundle.fwCtx,
+                          bundle.fwCtx.listeners.getMatchingServiceListeners(r),
+                          new ServiceEvent(ServiceEvent.REGISTERED, r),
+                          null);
+    return res;
+  }
+
+
+  /**
+   * Service ranking changed, reorder registered services
+   * according to ranking.
+   *
+   * @param serviceRegistration The serviceRegistration object.
+   * @param rank New rank of object.
+   */
+  synchronized void updateServiceRegistrationOrder(ServiceRegistrationImpl<?> sr,
+                                                   String[] classes)
+  {
+    for (final String clazz : classes) {
+      final List<ServiceRegistrationImpl<?>> s = classServices.get(clazz);
+      s.remove(sr);
+      s.add(Math.abs(Util.binarySearch(s, sComp, sr) + 1), sr);
+    }
+  }
+
+
+  /**
+   * Checks that a given service object is an instance of the given
+   * class name.
+   *
+   * @param service The service object to check.
+   * @param cls     The class name to check for.
+   * @throws IllegalArgumentException if the given class is not an
+   *            instance of the given class name.
+   */
+  boolean checkServiceClass(Object service, String cls)
+  {
+    final Class<?> sc = service.getClass();
+    final ClassLoader scl = secure.getClassLoaderOf(sc);
+    Class<?> c = null;
+    boolean ok = false;
+    try {
+      if (scl != null) {
+        c = scl.loadClass(cls);
+      } else {
+        c = Class.forName(cls);
+      }
+      ok = c.isInstance(service);
+    } catch (final ClassNotFoundException e) {
+      for (Class<?> csc = sc; csc != null; csc = csc.getSuperclass()) {
+        if (cls.equals(csc.getName())) {
+          ok = true;
+          break;
+        } else {
+          final Class<?> [] ic = csc.getInterfaces();
+          for (int iic = ic.length - 1; iic >= 0; iic--) {
+            if (cls.equals(ic[iic].getName())) {
+              ok = true;
+              break;
+            }
+          }
+        }
+      }
+    }
+    return ok;
+  }
+
+
+  /**
+   * Get all service implementing a certain class.
+   * Only used internally by framework.
+   *
+   * @param clazz The class name of requested service.
+   * @return A sorted list of {@link ServiceRegistrationImpl} objects
+   *         or null if no services is available.
+   */
+  synchronized List<ServiceRegistrationImpl<?>> get(String clazz) {
+    final List<ServiceRegistrationImpl<?>> v = classServices.get(clazz);
+    if (v != null) {
+      @SuppressWarnings({ "rawtypes", "unchecked" })
+      final List<ServiceRegistrationImpl<?>> res
+        = (List<ServiceRegistrationImpl<?>>) ((ArrayList) v).clone();
+      return res;
+    }
+    return null;
+  }
+
+
+  /**
+   * Get a service implementing a certain class.
+   *
+   * @param bundle bundle requesting reference
+   * @param clazz The class name of requested service.
+   * @return A {@link ServiceReference} object.
+   */
+  synchronized ServiceReference<?> get(BundleImpl bundle, String clazz) {
+    try {
+      final ServiceReference<?>[] srs = get(clazz, null, bundle);
+      if (framework.debug.service_reference) {
+        framework.debug.println("get service ref " + clazz + " for bundle " + bundle.location
+                                + " = " + (srs != null ? srs[0] : null));
+      }
+      if (srs != null) {
+        return srs[0];
+      }
+    } catch (final InvalidSyntaxException _never) { }
+    return null;
+  }
+
+
+  /**
+   * Get all services implementing a certain class and then
+   * filter these with a property filter.
+   *
+   * @param clazz The class name of requested service.
+   * @param filter The property filter.
+   * @param bundle bundle requesting reference. can be null if doAssignableToTest is false
+   * (this is not an interface class so don't check)
+   * @param isAssignableToTest whether to if the bundle that registered the service
+   * referenced by this ServiceReference and the specified bundle are both wired to
+   * same source for the registration class.
+   * @return An array of {@link ServiceReference} object.
+   */
+  synchronized ServiceReference<?>[] get(String clazz, String filter, BundleImpl bundle)
+    throws InvalidSyntaxException {
+    Iterator<ServiceRegistrationImpl<?>> s;
+    LDAPExpr ldap = null;
+    if (clazz == null) {
+      if (filter != null) {
+        ldap = new LDAPExpr(filter);
+        final Set<String> matched = ldap.getMatchedObjectClasses();
+        if (matched != null) {
+          List<ServiceRegistrationImpl<?>> v = null;
+          boolean vReadOnly = true;;
+          for (final String match : matched) {
+            final List<ServiceRegistrationImpl<?>> cl = classServices.get(match);
+            if (cl != null) {
+              if (v == null) {
+                v = cl;
+              } else {
+                if (vReadOnly) {
+                  v = new ArrayList<ServiceRegistrationImpl<?>>(v);
+                  vReadOnly = false;
+                }
+                v.addAll(cl);
+              }
+            }
+          }
+          if (v != null) {
+            s = v.iterator();
+          } else {
+            return null;
+          }
+        } else {
+          s = services.keySet().iterator();
+        }
+      } else {
+        s = services.keySet().iterator();
+      }
+    } else {
+      final List<ServiceRegistrationImpl<?>> v = classServices.get(clazz);
+      if (v != null) {
+        s = v.iterator();
+      } else {
+        return null;
+      }
+      if (filter != null) {
+        ldap = new LDAPExpr(filter);
+      }
+    }
+    final Collection<ServiceReference<?>> res
+      = new ArrayList<ServiceReference<?>>();
+    while (s.hasNext()) {
+      final ServiceRegistrationImpl<?> sr = s.next();
+      ServiceReference<?> sri = sr.getReference();
+      if (!secure.okGetServicePerms(sri)) {
+        continue; //sr not part of returned set
+      }
+      if (filter == null || ldap.evaluate(sr.getProperties(), false)) {
+        if (bundle != null) {
+          final String[] classes = services.get(sr);
+          for (int i = 0; i < classes.length; i++) {
+            if (!sri.isAssignableTo(bundle, classes[i])){
+              sri = null;
+              break;
+            }
+          }
+        }
+        if (sri != null) {
+          res.add(sri);
+        }
+      }
+    }
+    if (res.isEmpty()) {
+      return null;
+    } else {
+      if (bundle != null) {
+        framework.serviceHooks.filterServiceReferences(bundle.bundleContext,
+                                                clazz, filter, false, res);
+      } else {
+        framework.serviceHooks.filterServiceReferences(null, clazz, filter, true, res);
+      }
+      if (res.isEmpty()) {
+        return null;
+      } else {
+        return res.toArray(new ServiceReference [res.size()]);
+      }
+    }
+  }
+
+
+  /**
+   * Remove a registered service.
+   *
+   * @param sr The ServiceRegistration object that is registered.
+   */
+  synchronized void removeServiceRegistration(ServiceRegistrationImpl<?> sr) {
+    final String[] classes = (String[]) sr.getProperty(Constants.OBJECTCLASS);
+    services.remove(sr);
+    for (final String clazz : classes) {
+      final List<ServiceRegistrationImpl<?>> s = classServices.get(clazz);
+      if (s.size() > 1) {
+        s.remove(sr);
+      } else {
+        classServices.remove(clazz);
+      }
+    }
+  }
+
+
+  /**
+   * Get all services that a bundle has registered.
+   *
+   * @param b The bundle
+   * @return A set of {@link ServiceRegistration} objects
+   */
+  synchronized Set<ServiceRegistrationImpl<?>> getRegisteredByBundle(Bundle b) {
+    final HashSet<ServiceRegistrationImpl<?>> res = new HashSet<ServiceRegistrationImpl<?>>();
+    for (final ServiceRegistrationImpl<?> sr : services.keySet()) {
+      if (sr.bundle == b) {
+        res.add(sr);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Get all services that a bundle uses.
+   *
+   * @param b The bundle
+   * @return A set of {@link ServiceRegistration} objects
+   */
+  synchronized Set<ServiceRegistrationImpl<?>> getUsedByBundle(Bundle b) {
+    final HashSet<ServiceRegistrationImpl<?>> res = new HashSet<ServiceRegistrationImpl<?>>();
+    for (final ServiceRegistrationImpl<?> sr : services.keySet()) {
+      if (sr.isUsedByBundle(b)) {
+        res.add(sr);
+      }
+    }
+    return res;
+  }
+
+
+  static final Util.Comparator<ServiceRegistrationImpl<?>,ServiceRegistrationImpl<?>> sComp
+  = new Util.Comparator<ServiceRegistrationImpl<?>, ServiceRegistrationImpl<?>>() {
+      /**
+       * Name compare two ServiceRegistrationImpl objects according
+       * to the ServiceReference compareTo.
+       *
+       * @param a ServiceRegistrationImpl to compare.
+       * @param b ServiceRegistrationImpl to compare.
+       * @return Return 0 if equals, negative if first object is less than second
+       *         object and positive if first object is larger then second object.
+       */
+    public int compare(ServiceRegistrationImpl<?> a,
+                       ServiceRegistrationImpl<?> b)
+    {
+      return a.reference.compareTo(b.reference);
+    }
+    };
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/StartLevelController.java b/osgi/framework/src/org/knopflerfish/framework/StartLevelController.java
new file mode 100644
index 0000000..c7682f7
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/StartLevelController.java
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.File;
+import java.util.List;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.service.startlevel.StartLevel;
+
+
+/**
+ * StartLevel service implementation.
+ *
+ */
+ at SuppressWarnings("deprecation")
+public class StartLevelController
+  implements Runnable, ServiceFactory<StartLevel>
+{
+  // The version of the StartLevel service API
+  public static final String SPEC_VERSION = "1.1";
+
+  // The version of the StartLevel API
+  public static final String API_SPEC_VERSION = "1.0";
+
+  final static int START_MIN = 0;
+  final static int START_MAX = Integer.MAX_VALUE;
+
+  final static String LEVEL_FILE = "currentlevel";
+  final static String INITIAL_LEVEL_FILE = "initiallevel";
+
+  Thread        wc;
+  long          wcDelay  = 2000;
+  boolean       bRun     = false;
+  Queue<Runnable> jobQueue = new Queue<Runnable>(100);
+
+  int currentLevel     = 0;
+  int initStartLevel   = 1;
+  int targetStartLevel = currentLevel;
+  boolean acceptChanges = true;
+
+  final FrameworkContext fwCtx;
+
+  FileTree storage;
+
+  // Set to true indicates startlevel compatibility mode.
+  // all bundles and current start level will be 1
+  final boolean  bCompat /*= false*/;
+
+  final private boolean readOnly;
+
+
+  StartLevelController(FrameworkContext fwCtx)
+  {
+    this.fwCtx = fwCtx;
+    bCompat = fwCtx.props.getBooleanProperty(FWProps.STARTLEVEL_COMPAT_PROP);
+
+    readOnly = fwCtx.props.getBooleanProperty(FWProps.READ_ONLY_PROP);
+    storage = Util.getFileStorage(fwCtx, "startlevel", !readOnly);
+  }
+
+  void open() {
+    if (fwCtx.debug.startlevel) {
+      fwCtx.debug.println("startlevel: open");
+    }
+
+    final Runnable lastJob = jobQueue.lastElement();
+    wc = new Thread(fwCtx.threadGroup, this, "startlevel job");
+    synchronized (lastJob) {
+      bRun = true;
+      wc.start();
+      if (!acceptChanges) {
+        acceptChanges = true;
+      }
+      // Wait for the last of the jobs scheduled before starting the
+      // framework to complete before return
+      try {
+        lastJob.wait();
+      } catch (final InterruptedException _ignore) { }
+    }
+  }
+
+  /**
+   * Load persistent state from storage and set up all actions
+   * necessary to bump bundle states. If no persistent state was found,
+   * try to set the target start level from the beginning start level
+   * framework property.
+   *
+   * <p>Note that {@link open()} needs to be called for any work to
+   * be done.</p>
+   */
+  void restoreState() {
+    if (fwCtx.debug.startlevel) {
+      fwCtx.debug.println("startlevel: restoreState");
+    }
+    if (storage != null) {
+      // Set the target start level to go to when open() is called.
+      int startLevel = -1;
+      try {
+        final String s = Util.getContent(new File(storage, LEVEL_FILE));
+        if (s != null) {
+          startLevel = Integer.parseInt(s);
+          if (fwCtx.debug.startlevel) {
+            fwCtx.debug.println("startlevel: restored level " + startLevel);
+          }
+        }
+      } catch (final Exception _ignored) { }
+      if (startLevel == -1) {
+        // No stored start level to restore, try the beginning start level
+        final String sBeginningLevel
+          = fwCtx.props.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL);
+        try {
+          startLevel = Integer.parseInt(sBeginningLevel);
+          if (fwCtx.debug.startlevel) {
+            fwCtx.debug.println("startlevel: beginning level " + startLevel);
+          }
+        } catch (final NumberFormatException nfe) {
+          fwCtx.debug.printStackTrace("Invalid number '" + sBeginningLevel +
+                                      "' in value of property named '"
+                                      + Constants.FRAMEWORK_BEGINNING_STARTLEVEL
+                                      + "'.", nfe);
+        }
+      }
+      if (startLevel<0) {
+        startLevel = 1;
+      }
+      setStartLevel0(startLevel, false, false, true);
+
+      // Restore the initial bundle start level
+      try {
+        final String s = Util.getContent(new File(storage, INITIAL_LEVEL_FILE));
+        if (s != null) {
+          setInitialBundleStartLevel0(Integer.parseInt(s), false);
+        }
+      } catch (final Exception _ignored) { }
+    }
+  }
+
+
+  void close() {
+    if (fwCtx.debug.startlevel) {
+      fwCtx.debug.println("*** closing startlevel service");
+    }
+
+    bRun = false;
+    jobQueue.insert(new Runnable() {
+        public void run() {
+          jobQueue.close();
+        }
+      });
+    if(wc != null) {
+      try {
+        wc.join(wcDelay * 2);
+      } catch (final Exception ignored) {
+      }
+      wc = null;
+    }
+  }
+
+  void shutdown() {
+    acceptChanges = false;
+    synchronized (wc) {
+      setStartLevel0(0, false, true, false);
+      while (currentLevel > 0) {
+        try { wc.wait(); } catch (final Exception e) {}
+      }
+    }
+    close();
+  }
+
+  public void run() {
+    while(bRun) {
+      try {
+        final Runnable job = jobQueue.removeWait((float)(wcDelay / 1000.0));
+        if (job != null) {
+          job.run();
+          synchronized (job) {
+            job.notify();
+          }
+        }
+      } catch (final Exception ignored) {
+        ignored.printStackTrace();
+      }
+    }
+  }
+
+
+  int getStartLevel() {
+    return currentLevel;
+  }
+
+  void setStartLevel(final int startLevel)
+  {
+    setStartLevel(startLevel, (FrameworkListener[]) null);
+  }
+
+  void setStartLevel(final int startLevel, final FrameworkListener... listeners)
+  {
+    fwCtx.perm.checkStartLevelAdminPerm();
+    if (startLevel <= 0) {
+      throw new IllegalArgumentException("Initial start level must be > 0, is "
+                                         + startLevel);
+    }
+    if (acceptChanges) {
+      // No start-level changed events if called before open() or after close().
+      setStartLevel0(startLevel, bRun, false, true, listeners);
+    }
+  }
+
+  private void setStartLevel0(final int startLevel,
+                              final boolean notifyFw,
+                              final boolean notifyWC,
+                              final boolean storeLevel,
+                              final FrameworkListener... listeners)
+  {
+    if (fwCtx.debug.startlevel) {
+      fwCtx.debug.println("startlevel: setStartLevel " + startLevel);
+    }
+
+    jobQueue.insert(new Runnable() {
+      public void run() {
+        final int sl = bCompat ? 1 : startLevel;
+        targetStartLevel = sl;
+
+        while (targetStartLevel > currentLevel) {
+          increaseStartLevel();
+        }
+
+        while (targetStartLevel < currentLevel) {
+          decreaseStartLevel();
+        }
+
+        // Skip level save in mem storage since bundle levels
+        // won't be saved anyway
+        if (storeLevel && storage != null && !readOnly) {
+          try {
+            Util.putContent(new File(storage, LEVEL_FILE),
+                            Integer.toString(currentLevel));
+          } catch (final Exception e) {
+            e.printStackTrace();
+          }
+        }
+        if (notifyFw) {
+          final FrameworkEvent event
+            = new FrameworkEvent(FrameworkEvent.STARTLEVEL_CHANGED,
+                                 fwCtx.systemBundle, null);
+          // Send event to all registered framework listeners
+          fwCtx.listeners.frameworkEvent(event, listeners);
+        }
+        if (notifyWC && wc != null) {
+          synchronized (wc) {
+            wc.notifyAll();
+          }
+        }
+      }
+    });
+  }
+
+
+  Object lock = new Object();
+
+
+  void increaseStartLevel() {
+    synchronized (lock) {
+
+      currentLevel++;
+
+      if (fwCtx.debug.startlevel) {
+        fwCtx.debug.println("startlevel: increaseStartLevel currentLevel="
+                            + currentLevel);
+      }
+      final Vector<BundleImpl> set = new Vector<BundleImpl>();
+
+      final List<BundleImpl> bundles = fwCtx.bundles.getBundles();
+
+      for (final BundleImpl bs : bundles) {
+        if (canStart(bs)) {
+          if (bs.getStartLevel() == currentLevel) {
+            if (bs.current().archive.getAutostartSetting()!=-1) {
+              set.addElement(bs);
+            }
+          }
+        }
+      }
+
+      Util.sort(set, BSComparator, false);
+
+      for (int i = 0; i < set.size(); i++) {
+        final BundleImpl bs = set.elementAt(i);
+        try {
+          if (bs.current().archive.getAutostartSetting()!=-1) {
+            if (fwCtx.debug.startlevel) {
+              fwCtx.debug.println("startlevel: start " + bs);
+            }
+            int startOptions = Bundle.START_TRANSIENT;
+            if (isBundleActivationPolicyUsed(bs.current().archive)) {
+              startOptions |= Bundle.START_ACTIVATION_POLICY;
+            }
+            bs.start(startOptions);
+          }
+        } catch (final IllegalStateException ignore) {
+          // Tried to start an uninstalled bundle, skip
+        } catch (final Exception e) {
+          fwCtx.frameworkError(bs, e);
+        }
+      }
+    }
+  }
+
+
+  void decreaseStartLevel() {
+    synchronized (lock) {
+      currentLevel--;
+
+      final Vector<BundleImpl> set = new Vector<BundleImpl>();
+
+      final List<BundleImpl> bundles = fwCtx.bundles.getBundles();
+
+      for (final BundleImpl bs : bundles) {
+        if (bs.getState() == Bundle.ACTIVE ||
+            (bs.getState() == Bundle.STARTING && bs.current().lazyActivation)) {
+          if (bs.getStartLevel() == currentLevel + 1) {
+            set.addElement(bs);
+          }
+        }
+      }
+
+      Util.sort(set, BSComparator, true);
+
+      synchronized (fwCtx.resolver) {
+        for (int i = 0; i < set.size(); i++) {
+          final BundleImpl bs = set.elementAt(i);
+          if (bs.getState() == Bundle.ACTIVE ||
+              (bs.getState() == Bundle.STARTING && bs.current().lazyActivation)) {
+            if (fwCtx.debug.startlevel) {
+              fwCtx.debug.println("startlevel: stop " + bs);
+            }
+
+            try {
+              bs.stop(Bundle.STOP_TRANSIENT);
+            } catch (final Throwable t) {
+              fwCtx.frameworkError(bs, t);
+            }
+          }
+        }
+      }
+    }
+  }
+
+
+  boolean canStart(BundleImpl b) {
+    return b.getState() != Bundle.UNINSTALLED;
+  }
+
+
+  static final Util.Comparator<BundleImpl,BundleImpl>
+    BSComparator = new Util.Comparator<BundleImpl,BundleImpl>() {
+    public int compare(BundleImpl b1, BundleImpl b2)
+    {
+      int res = b1.getStartLevel() - b2.getStartLevel();
+      if (res == 0) {
+        res = (int) (b1.getBundleId() - b2.getBundleId());
+      }
+      return res;
+    }
+  };
+
+  int getBundleStartLevel(BundleImpl bundle) {
+    if (bundle.getBundleId() == 0) {
+      return 0;
+    }
+    return bundle.getStartLevel();
+  }
+
+
+  void setBundleStartLevel(final BundleImpl bundle, final int startLevel) {
+    fwCtx.perm.checkExecuteAdminPerm(bundle);
+
+    if (startLevel <= 0) {
+      throw new IllegalArgumentException("Initial start level must be > 0, is " + startLevel);
+    }
+
+    if (bundle.getBundleId() == 0) {
+      throw new IllegalArgumentException("System bundle start level cannot be changed");
+    }
+
+    fwCtx.perm.callSetStartLevel(bundle, bCompat ? 1 : startLevel);
+
+    jobQueue.insert(new Runnable() {
+      public void run() {
+        syncStartLevel(bundle);
+      }
+    });
+  }
+
+
+  void syncStartLevel(BundleImpl bs) {
+    try {
+      if (fwCtx.debug.startlevel) {
+        fwCtx.debug.println("syncstartlevel: " + bs);
+      }
+      synchronized (lock) {
+        synchronized (fwCtx.resolver) {
+          if (bs.getStartLevel() <= currentLevel) {
+            final BundleGeneration current = bs.current();
+            if ((bs.getState() & (Bundle.INSTALLED|Bundle.RESOLVED|Bundle.STOPPING)) != 0
+                && current.archive.getAutostartSetting()!=-1) {
+              if (fwCtx.debug.startlevel) {
+                fwCtx.debug.println("startlevel: start " + bs);
+              }
+              int startOptions = Bundle.START_TRANSIENT;
+              if (isBundleActivationPolicyUsed(current.archive)) {
+                startOptions |= Bundle.START_ACTIVATION_POLICY;
+              }
+              bs.start(startOptions);
+            }
+          } else if (bs.getStartLevel() > currentLevel) {
+            if ((bs.getState() & (Bundle.ACTIVE|Bundle.STARTING)) != 0) {
+              if (fwCtx.debug.startlevel) {
+                fwCtx.debug.println("startlevel: stop " + bs);
+              }
+              bs.stop(Bundle.STOP_TRANSIENT);
+            }
+          }
+        }
+      }
+    } catch (final Throwable t) {
+      fwCtx.frameworkError(bs, t);
+    }
+  }
+
+
+  int getInitialBundleStartLevel() {
+    return initStartLevel;
+  }
+
+
+  void setInitialBundleStartLevel(int startLevel) {
+    fwCtx.perm.checkStartLevelAdminPerm();
+    fwCtx.perm.callSetInitialBundleStartLevel0(this, startLevel);
+  }
+
+
+  void setInitialBundleStartLevel0(int startLevel, boolean save) {
+    if(startLevel <= 0) {
+      throw new IllegalArgumentException("Initial start level must be > 0, is " + startLevel);
+    }
+    initStartLevel = bCompat ? 1 : startLevel;
+    if (storage != null && !readOnly && save) {
+      try {
+        Util.putContent(new File(storage, INITIAL_LEVEL_FILE),
+                        Integer.toString(initStartLevel));
+      } catch (final Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+
+  boolean isBundlePersistentlyStarted(BundleArchive archive) {
+    return archive == null || archive.getAutostartSetting() != -1;
+  }
+
+
+  boolean isBundleActivationPolicyUsed(BundleArchive archive) {
+    return archive != null && archive.getAutostartSetting() == Bundle.START_ACTIVATION_POLICY;
+  }
+
+
+  public StartLevel getService(Bundle bundle,
+                               ServiceRegistration<StartLevel> registration)
+  {
+    return new StartLevelImpl(this);
+  }
+
+  public void ungetService(Bundle bundle,
+                           ServiceRegistration<StartLevel> registration,
+                           StartLevel service)
+  {
+  }
+
+  public static class StartLevelImpl
+    implements StartLevel
+  {
+    private final StartLevelController st;
+
+    StartLevelImpl(StartLevelController st) {
+      this.st = st;
+    }
+
+    public int getBundleStartLevel(Bundle bundle) {
+      return st.getBundleStartLevel(checkBundle(bundle));
+    }
+
+    public int getInitialBundleStartLevel() {
+      return st.getInitialBundleStartLevel();
+    }
+
+    public int getStartLevel() {
+      return st.getStartLevel();
+    }
+
+    public boolean isBundleActivationPolicyUsed(Bundle bundle) {
+      return st.isBundleActivationPolicyUsed(getBundleArchive(bundle));
+    }
+
+    public boolean isBundlePersistentlyStarted(Bundle bundle) {
+      return st.isBundlePersistentlyStarted(getBundleArchive(bundle));
+    }
+
+    public void setBundleStartLevel(Bundle bundle, int startlevel) {
+      st.setBundleStartLevel(checkBundle(bundle), startlevel);
+    }
+
+    public void setInitialBundleStartLevel(int startlevel) {
+      st.setInitialBundleStartLevel(startlevel);
+    }
+
+    public void setStartLevel(int startlevel) {
+      st.setStartLevel(startlevel);
+    }
+
+    private BundleImpl checkBundle(Bundle b) {
+      if (b instanceof BundleImpl) {
+        final BundleImpl res = (BundleImpl)b;
+        if (res.fwCtx == st.fwCtx) {
+          if (res.state != Bundle.UNINSTALLED) {
+            return res;
+          }
+          throw new IllegalArgumentException("Bundle is in UNINSTALLED state");
+        }
+      }
+      throw new IllegalArgumentException("Bundle doesn't belong to the same framework as the StartLevel service");
+    }
+
+    private BundleArchive getBundleArchive(Bundle b) {
+      final BundleImpl bi = checkBundle(b);
+      final BundleArchive res = bi.current().archive;
+      if (res == null && bi.id != 0) {
+        throw new IllegalArgumentException("Bundle is in UNINSTALLED state");
+      }
+      return res;
+    }
+
+  }
+
+  BundleStartLevel bundleStartLevel(final BundleImpl bi) {
+    return new BundleStartLevelImpl(this, bi);
+  }
+
+  static class BundleStartLevelImpl
+    implements BundleStartLevel
+  {
+    final StartLevelController st;
+    final BundleImpl bi;
+
+    BundleStartLevelImpl(final StartLevelController st, final BundleImpl bi) {
+      this.st = st;
+      this.bi = bi;
+    }
+
+    public Bundle getBundle()
+    {
+      return bi;
+    }
+
+    public int getStartLevel()
+    {
+      return st.getBundleStartLevel(bi);
+    }
+
+    public void setStartLevel(int startlevel)
+    {
+      st.setBundleStartLevel(bi, startlevel);
+    }
+
+    public boolean isPersistentlyStarted()
+    {
+      return st.isBundlePersistentlyStarted(getBundleArchive());
+    }
+
+    public boolean isActivationPolicyUsed()
+    {
+      return st.isBundleActivationPolicyUsed(getBundleArchive());
+    }
+
+    private BundleArchive getBundleArchive() {
+      final BundleArchive res = bi.current().archive;
+      if (res == null && bi.id != 0) {
+        throw new IllegalArgumentException("Bundle is in UNINSTALLED state");
+      }
+      return res;
+    }
+
+  }
+
+  FrameworkStartLevel frameworkStartLevel(final BundleImpl bi)
+  {
+    return new FrameworkStartLevelImpl(this, bi);
+  }
+
+  static class FrameworkStartLevelImpl
+    implements FrameworkStartLevel
+  {
+    final StartLevelController st;
+    final BundleImpl bi;
+
+    public FrameworkStartLevelImpl(StartLevelController startLevelController,
+        BundleImpl bi)
+    {
+      this.st = startLevelController;
+      this.bi = bi;
+    }
+
+    public Bundle getBundle()
+    {
+      return bi;
+    }
+
+    public int getStartLevel()
+    {
+      return st.getStartLevel();
+    }
+
+    public void setStartLevel(int startlevel, FrameworkListener... listeners)
+    {
+      st.setStartLevel(startlevel, listeners);
+    }
+
+    public int getInitialBundleStartLevel()
+    {
+      return st.getInitialBundleStartLevel();
+    }
+
+    public void setInitialBundleStartLevel(int startlevel)
+    {
+      st.setInitialBundleStartLevel(startlevel);
+    }
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/SystemBundle.java b/osgi/framework/src/org/knopflerfish/framework/SystemBundle.java
new file mode 100644
index 0000000..9af63e6
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/SystemBundle.java
@@ -0,0 +1,1057 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/**
+ * Implementation of the System Bundle object.
+ *
+ * @see org.osgi.framework.Bundle
+ * @author Jan Stein
+ * @author Philippe Laporte
+ * @author Mats-Ola Persson
+ */
+public class SystemBundle extends BundleImpl implements Framework {
+
+  /**
+   * The file where we store the class path
+   */
+  private final static String BOOT_CLASSPATH_FILE = "boot_cp";
+
+  /**
+   * Export-Package string for system packages
+   */
+  private String exportPackageString;
+
+  /**
+   * Provide-Capability string for the system bundle.
+   */
+  private String provideCapabilityString;
+
+  /**
+   * The event to return to callers waiting in Framework.waitForStop() when the
+   * framework has been stopped.
+   */
+  volatile private FrameworkEvent stopEvent = null;
+
+  /**
+   * The thread that performs shutdown of this framework instance.
+   */
+  private Thread shutdownThread = null;
+
+  /**
+   * Lock object
+   */
+  private final Object lock = new Object();
+
+  /**
+   * Marker that we need to restart JVM.
+   */
+  boolean bootClassPathHasChanged;
+
+  private FrameworkWiringImpl fwWiring;
+
+
+  /**
+   * Construct the System Bundle handle.
+   *
+   */
+  SystemBundle(FrameworkContext fw) {
+    super(fw);
+  }
+
+
+  /**
+   * Initialize this framework.
+   *
+   * @see org.osgi.framework.Framework#init
+   */
+  @Override
+  public void init() throws BundleException {
+    secure.checkExecuteAdminPerm(this);
+
+    synchronized (lock) {
+      waitOnOperation(lock, "Framework.init", true);
+
+      switch (state) {
+      case INSTALLED:
+      case RESOLVED:
+        break;
+      case STARTING:
+      case ACTIVE:
+        return;
+      default:
+        throw new IllegalStateException("INTERNAL ERROR, Illegal state, " + state);
+      }
+      doInit();
+    }
+  }
+
+
+  /**
+   * Start this framework.
+   *
+   * @see org.osgi.framework.Framework#start
+   */
+  @Override
+  public void start(int options) throws BundleException {
+    List<String> bundlesToStart = null;
+    synchronized (lock) {
+      waitOnOperation(lock, "Framework.start", true);
+
+      switch (state) {
+      case INSTALLED:
+      case RESOLVED:
+        doInit();
+        // Fall through
+      case STARTING:
+        operation = ACTIVATING;
+        break;
+      case ACTIVE:
+        return;
+      default:
+        throw new IllegalStateException("INTERNAL ERROR, Illegal state, " + state);
+      }
+      if (fwCtx.startLevelController == null) {
+        bundlesToStart = fwCtx.storage.getStartOnLaunchBundles();
+      }
+    }
+
+    if (fwCtx.startLevelController != null) {
+      // start level open is delayed to this point to
+      // correctly work at restart
+      fwCtx.startLevelController.open();
+    } else {
+      // Start bundles according to their autostart setting.
+      final Iterator<String> i = bundlesToStart.iterator();
+      while (i.hasNext()) {
+        final BundleImpl b = (BundleImpl)fwCtx.bundles.getBundle(i.next());
+        try {
+          final int autostartSetting = b.current().archive.getAutostartSetting();
+          // Launch must not change the autostart setting of a bundle
+          int option = Bundle.START_TRANSIENT;
+          if (Bundle.START_ACTIVATION_POLICY == autostartSetting) {
+            // Transient start according to the bundles activation policy.
+            option |= Bundle.START_ACTIVATION_POLICY;
+          }
+          b.start(option);
+        } catch (final BundleException be) {
+          fwCtx.frameworkError(b, be);
+        }
+      }
+    }
+    synchronized (lock) {
+      state = ACTIVE;
+      operation = IDLE;
+      lock.notifyAll();
+      fwCtx.listeners.frameworkEvent(new FrameworkEvent(FrameworkEvent.STARTED, this, null));
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public FrameworkEvent waitForStop(long timeout) throws InterruptedException {
+    synchronized (lock) {
+      // Already stopped?
+      if (((INSTALLED | RESOLVED) & state) == 0) {
+        stopEvent = null;
+        while (true) {
+          final long st = Util.timeMillis();
+          try {
+            lock.wait(timeout);
+            if (stopEvent != null) {
+              break;
+            }
+          } catch (final InterruptedException _) {
+          }
+          if (timeout > 0) {
+            timeout = timeout - (Util.timeMillis() - st);
+            if (timeout <= 0) {
+              break;
+            }
+          }
+        }
+        if (stopEvent == null) {
+          return new FrameworkEvent(FrameworkEvent.WAIT_TIMEDOUT, this, null);
+        }
+      } else if (stopEvent == null) {
+        // Return this if stop or update have not been called and framework is
+        // stopped.
+        stopEvent = new FrameworkEvent(FrameworkEvent.STOPPED, this, null);
+      }
+      return stopEvent;
+    }
+  }
+
+
+  /**
+   * Stop this framework.
+   *
+   * @see org.osgi.framework.Framework#stop
+   */
+  @Override
+  public void stop(int options) throws BundleException {
+    secure.checkExecuteAdminPerm(this);
+    secure.callShutdown(this, false);
+  }
+
+
+  /**
+   * Restart this framework.
+   *
+   * @see org.osgi.framework.Framework#update
+   */
+  @Override
+  public void update(InputStream in) throws BundleException {
+    secure.checkLifecycleAdminPerm(this);
+    if (in != null) {
+      try {
+        in.close();
+      } catch (final IOException ignore) {
+      }
+    }
+    secure.callShutdown(this, true);
+  }
+
+
+  /**
+   * Uninstall of framework are not allowed.
+   *
+   * @see org.osgi.framework.Framework#uninstall
+   */
+  @Override
+  public void uninstall() throws BundleException {
+    secure.checkLifecycleAdminPerm(this);
+    throw new BundleException("Uninstall of System bundle is not allowed",
+                              BundleException.INVALID_OPERATION);
+  }
+
+
+  /**
+   * The system has all the permissions.
+   *
+   * @see org.osgi.framework.Bundle#hasPermission
+   */
+  @Override
+  public boolean hasPermission(Object permission) {
+    return true;
+  }
+
+
+  /**
+   * Get header data.
+   *
+   * @see org.osgi.framework.Bundle#getHeaders
+   */
+  @Override
+  public Dictionary<String, String> getHeaders() {
+    return getHeaders(null);
+  }
+
+
+  /**
+   * Get header data.
+   *
+   * @see org.osgi.framework.Bundle#getHeaders
+   */
+  @SuppressWarnings("deprecation")
+  @Override
+  public Dictionary<String, String> getHeaders(String locale) {
+    secure.checkMetadataAdminPerm(this);
+    final Hashtable<String, String> headers = new Hashtable<String, String>();
+    headers.put(Constants.BUNDLE_SYMBOLICNAME, getSymbolicName());
+    headers.put(Constants.BUNDLE_NAME, location);
+    headers.put(Constants.EXPORT_PACKAGE, exportPackageString);
+    headers.put(Constants.BUNDLE_VERSION, getVersion().toString());
+    headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+    headers.put(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT,
+        fwCtx.props.getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT));
+    headers.put("Bundle-Icon", "icon.png;size=32,icon64.png;size=64");
+    headers.put(Constants.BUNDLE_VENDOR, "Knopflerfish");
+    headers.put(Constants.BUNDLE_DESCRIPTION, "Knopflerfish System Bundle");
+    headers.put(Constants.PROVIDE_CAPABILITY, provideCapabilityString);
+    return headers;
+  }
+
+
+  /**
+   * Get bundle data. Get resources from bundle or fragment jars.
+   *
+   * @see org.osgi.framework.Bundle#findEntries
+   */
+  @Override
+  public Enumeration<URL> findEntries(String path,
+                                      String filePattern,
+                                      boolean recurse)
+  {
+    // TODO, What should system bundle return?
+    return null;
+  }
+
+  /**
+   *
+   */
+  @Override
+  public URL getEntry(String name) {
+    if (secure.okResourceAdminPerm(this)) {
+      return getClassLoader().getResource(name);
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public Enumeration<String> getEntryPaths(String path) {
+    return null;
+  }
+
+  // Don't delegate to BundleImp since Bundle adaptations may not
+  // apply to the SystemBundle.
+  @Override
+  @SuppressWarnings("unchecked")
+  public <A> A adapt(Class<A> type)
+  {
+    secure.checkAdaptPerm(this, type);
+    Object res = null;
+    if (FrameworkWiring.class.equals(type)) {
+      res = fwWiring;
+    } else if (FrameworkStartLevel.class.equals(type)) {
+      if (fwCtx.startLevelController != null) {
+        res = fwCtx.startLevelController.frameworkStartLevel(this);
+      }
+    } else if (Framework.class.equals(type)) {
+      res = this;
+    } else {
+      // TODO filter which adaptation we can do?!
+      res = adaptSecure(type);
+    }
+    return (A) res;
+  }
+
+
+  //
+  // Package method
+  //
+
+  /**
+   * Get class loader for this bundle.
+   *
+   * @return System Bundle classloader.
+   */
+  @Override
+  ClassLoader getClassLoader() {
+    return getClass().getClassLoader();
+  }
+
+
+  /**
+   * Set system bundle state to stopping
+   */
+  void systemShuttingdown(final boolean restart) throws BundleException {
+  }
+
+
+  /**
+   * Shutting down is done.
+   */
+  void systemShuttingdownDone(final FrameworkEvent fe) {
+    synchronized (lock) {
+      if (state != INSTALLED) {
+        state = RESOLVED;
+        operation = IDLE;
+        lock.notifyAll();
+      }
+      stopEvent = fe;
+    }
+  }
+
+
+  /**
+   * Adds an bundle as an extension that will be included in the boot class path
+   * on restart.
+   * @throws BundleException Should not happened.
+   */
+  void attachExtension(BundleGeneration extension) throws BundleException  {
+    if (extension.isBootClassPathExtension()) {
+      // if we attach during startup, we assume that bundle is in BCP.
+      if (getClassLoader() == null) {
+        current().attachFragment(extension);
+      } else {
+        throw new UnsupportedOperationException(
+            "Bootclasspath extension can not be dynamicly activated");
+      }
+    } else {
+      try {
+        addClassPathURL(new URL("file:" + extension.archive.getJarLocation()));
+        current().attachFragment(extension);
+        handleExtensionActivator(extension);
+      } catch (final Exception e) {
+        throw new UnsupportedOperationException(
+            "Framework extension could not be dynamicly activated, " + e);
+      }
+    }
+  }
+
+
+  /**
+   * Reads all localization entries that affects this bundle (including its
+   * host/fragments)
+   *
+   * @param locale locale == "" the bundle.properties will be read o/w it will
+   *          read the files as described in the spec.
+   * @param localization_entries will append the new entries to this dictionary
+   * @param baseName the basename for localization properties, <code>null</code>
+   *          will choose OSGi default
+   */
+  void readLocalization(String locale,
+                        Hashtable<String, String> localization_entries,
+                        String baseName)
+  {
+    @SuppressWarnings("unchecked")
+    final Vector<BundleGeneration> fragments = (Vector<BundleGeneration>)current().fragments.clone();
+    if (fragments == null) {
+      // NYI! read localization from framework.
+      // There is no need for this now since it isn't used.
+      return;
+    }
+    if (baseName == null) {
+      baseName = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+    }
+    if (!locale.equals("")) {
+      locale = "_" + locale;
+    }
+    while (true) {
+      final String l = baseName + locale + ".properties";
+      for (int i = fragments.size() - 1; i >= 0; i--) {
+        final BundleGeneration bg = fragments.get(i);
+        final Hashtable<String, String> tmp = bg.archive.getLocalizationEntries(l);
+        if (tmp != null) {
+          localization_entries.putAll(tmp);
+          return;
+        }
+      }
+      final int pos = locale.lastIndexOf('_');
+      if (pos == -1) {
+        break;
+      }
+      locale = locale.substring(0, pos);
+    }
+  }
+
+
+  /**
+   *
+   */
+  void initSystemBundle() {
+    bundleContext = new BundleContextImpl(this);
+    final StringBuffer sp = new StringBuffer(
+        fwCtx.props.getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES));
+    if (sp.length() == 0) {
+      // Try the system packages file
+      addSysPackagesFromFile(sp, fwCtx.props.getProperty(FWProps.SYSTEM_PACKAGES_FILE_PROP), null);
+      if (sp.length() == 0) {
+        // Try the system packages base property.
+        sp.append(fwCtx.props.getProperty(FWProps.SYSTEM_PACKAGES_BASE_PROP));
+
+        if (sp.length() == 0) {
+          // use default set of packages.
+          String jver = fwCtx.props.getProperty(FWProps.SYSTEM_PACKAGES_VERSION_PROP);
+
+          Version jv;
+          if (jver == null) {
+            jv = new Version(FWProps.javaVersionMajor, FWProps.javaVersionMinor, 0);
+          } else {
+            try {
+              jv = new Version(jver);
+            } catch (IllegalArgumentException _ignore){
+              if (fwCtx.debug.framework) {
+                fwCtx.debug.println("No built in list of Java packages to be exported "
+                    + "by the system bundle for JRE with version '" + jver
+                    + "', using the list for 1.7.");
+              }
+              jv = new Version(1,7,0);
+            }
+          }
+          addSysPackagesFromFile(sp, "packages.txt", jv);
+        } else {
+          if (sp.charAt(sp.length() - 1) == ',') {
+            sp.deleteCharAt(sp.length() - 1);
+          }
+        }
+        addSysPackagesFromFile(sp, "exports", null);
+      }
+    }
+    final String extraPkgs = fwCtx.props.getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
+    if (extraPkgs.length() > 0) {
+      sp.append(",").append(extraPkgs);
+    }
+    exportPackageString = sp.toString();
+
+    sp.setLength(0);
+    sp.append(fwCtx.props.getProperty(Constants.FRAMEWORK_SYSTEMCAPABILITIES));
+    if (sp.length()==0) {
+      // Derive osgi.ee capabilities from the EE header.
+      addSysCapabilitiesFromEE(sp);
+    }
+    // Add in extra system capabilities
+    final String epc = fwCtx.props.getProperty(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA);
+    if (epc.length()>0) {
+      if (sp.length()>0) {
+        sp.append(',');
+      }
+      sp.append(epc);
+    }
+    provideCapabilityString = sp.toString();
+
+    final BundleGeneration gen = new BundleGeneration(this, exportPackageString,
+                                                      provideCapabilityString);
+    generations.add(gen);
+    gen.bpkgs.registerPackages();
+    try {
+      gen.bpkgs.resolvePackages(null);
+    } catch (final BundleException _ignore) {
+      // Shouldn't happend, hooks not active;
+    }
+    gen.setWired();
+    fwWiring = new FrameworkWiringImpl(fwCtx);
+  }
+
+
+  /**
+   *
+   */
+  void uninitSystemBundle() {
+    bundleContext.invalidate();
+    bundleContext = null;
+    if (!bootClassPathHasChanged) {
+      for (final BundleGeneration bg : fwCtx.bundles.getFragmentBundles(current())) {
+        if (bg.isBootClassPathExtension() && bg.bundle.extensionNeedsRestart()) {
+          bootClassPathHasChanged = true;
+          break;
+        }
+      }
+    }
+  }
+
+  //
+  // Private methods
+  //
+
+  /**
+   *
+   */
+  private void doInit() throws BundleException {
+    state = STARTING;
+    bootClassPathHasChanged = false;
+    fwCtx.init();
+  }
+
+
+  /**
+   * Read a file with package names and add them to a stringbuffer. The file is
+   * searched for in the current working directory, then on the class path.
+   * Each line can have a java version guard at the end with format <tt>!VersionRange</tt>.
+   *
+   * @param sp Buffer to append the exports to. Same format as the
+   *          Export-Package manifest header.
+   * @param sysPkgFile Name of the file to load packages to be exported from.
+   * @param guard Version to test version guarded lines against.
+   */
+  private void addSysPackagesFromFile(StringBuffer sp, String sysPkgFile, Version guard) {
+    if (null == sysPkgFile || 0 == sysPkgFile.length()) {
+      return;
+    }
+
+    if (fwCtx.debug.resolver) {
+      fwCtx.debug.println("Will add system packages from file " + sysPkgFile);
+    }
+
+    URL url = null;
+    final File f = new File(new File(sysPkgFile).getAbsolutePath());
+
+    if (!f.exists() || !f.isFile()) {
+      url = SystemBundle.class.getResource(sysPkgFile);
+      if (null == url) {
+        url = SystemBundle.class.getResource("/" + sysPkgFile);
+      }
+      if (null == url) {
+        if (fwCtx.debug.resolver) {
+          fwCtx.debug.println("Could not add system bundle package exports from '" + sysPkgFile
+              + "', file not found.");
+        }
+      }
+    }
+    BufferedReader in = null;
+    try {
+      Reader reader = null;
+      String source = null;
+
+      if (null == url) {
+        reader = new FileReader(f);
+        source = f.getAbsolutePath().toString();
+      } else {
+        reader = new InputStreamReader(url.openStream());
+        source = url.toString();
+      }
+      in = new BufferedReader(reader);
+      if (fwCtx.debug.resolver) {
+        fwCtx.debug.println("\treading from " + source);
+      }
+
+      String line;
+      for (line = in.readLine(); line != null; line = in.readLine()) {
+        line = line.trim();
+        if (line.length() > 0 && !line.startsWith("#")) {
+          int idx = line.lastIndexOf('!');
+          if (idx != -1) {
+            try {
+              if (new VersionRange(line.substring(idx +1)).includes(guard)) {
+                line = line.substring(0, idx);
+              } else {
+                // Not in version range skip.
+                continue;
+              }
+            } catch (IllegalArgumentException _ignore) { }
+          }
+          if (sp.length() > 0) {
+            sp.append(",");
+          }
+          sp.append(line);
+        }
+      }
+    } catch (final IOException e) {
+      throw new IllegalArgumentException("Failed to read " + sysPkgFile + ": " + e);
+    } finally {
+      try {
+        in.close();
+      } catch (final Exception _ignore) {
+      }
+    }
+  }
+
+
+  /**
+   * Create bundle capabilities in the {@code osgi.ee} name-space for all
+   * execution environments that the framework supports.
+   *
+   * This method converts all BREEs defined using the framework environment
+   * property {@code org.osgi.framework.executionenvironment} into
+   * {@code osgi.ee}-capabilities.
+   *
+   * <p>A Bundle Required Execution Environment often on a from that matches:
+   * <pre>
+   * bree'  ::= n1 ( '-' v )? ( '/' n2 ( '-' v )? )?
+   * </pre>
+   * If it matches the BRWW will be transformed to an osgi.ee
+   * capability with attributes as below:
+   * <pre>
+   *   osgi.ee = n1 ('/' n2 ) ; version:List<Version> = "v"
+   *   osgi.ee = <ee name>
+   * </pre>
+   * If it does not match the {@code osgi.ee} attribute is set to the original
+   * BREE value.
+   *
+   * BREE definitions for Java standard edition uses different names, "J2SE" and
+   * "JavaSE" depending on the Java major version, but in
+   * {@code osgi.ee}-capabilities the name shall be "JavaSE" independent of Java
+   * release.
+   *
+   * @param sp string buffer with all framework provided capabilities to append
+   * to.
+   */
+  private void addSysCapabilitiesFromEE(StringBuffer sp)
+  {
+    final Map<String, SortedSet<Version>> eeNameVersions
+      = new HashMap<String, SortedSet<Version>>();
+    @SuppressWarnings("deprecation")
+    final String fwEE = fwCtx.props
+        .getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+
+    if (fwEE!=null && fwEE.length()>0) {
+      final String[] ees = Util.splitwords(fwEE, ",");
+      for(final String ee : ees) {
+        final String[] n1n2 = Util.splitwords(ee, "/");
+        switch (n1n2.length) {
+        case 1:
+          final String[] nv = Util.splitwords(ee, "-");
+          if (nv.length==2) {
+            try {
+              final Version v = new Version(nv[1]);
+              addSysCapabilityEE(eeNameVersions, nv[0], v);
+            } catch (final Exception e) {
+              addSysCapabilityEE(eeNameVersions, ee, null);
+            }
+          } else {
+            addSysCapabilityEE(eeNameVersions, ee, null);
+          }
+          break;
+        case 2:
+          final String[] n1v = Util.splitwords(n1n2[0], "-");
+          final String[] n2v = Util.splitwords(n1n2[1], "-");
+          try {
+            final Version v1 = n1v.length==2 ? new Version(n1v[1]) : null;
+            final Version v2 = n2v.length==2 ? new Version(n2v[1]) : null;
+            final String n = n1v[0] +"/" +n2v[0];
+            if (v1 != null && v2 != null && v1.equals(v2)) {
+              addSysCapabilityEE(eeNameVersions, n, v1);
+            } else if (v1!=null && v2==null) {
+              addSysCapabilityEE(eeNameVersions, n, v1);
+            } else if (v1==null && v2!=null) {
+              addSysCapabilityEE(eeNameVersions, n, v2);
+            } else {
+              addSysCapabilityEE(eeNameVersions, ee, null);
+            }
+          } catch (final Exception e) {
+            addSysCapabilityEE(eeNameVersions, ee, null);
+          }
+          break;
+        default:
+          addSysCapabilityEE(eeNameVersions, ee, null);
+        }
+      }
+    }
+    addSysCapabilityForEE(sp, eeNameVersions);
+  }
+
+
+  private void addSysCapabilityEE(final Map<String, SortedSet<Version>> eeNameVersions,
+                                  String name,
+                                  final Version v)
+  {
+    if ("J2SE".equals(name)) {
+      name = "JavaSE";
+    }
+    SortedSet<Version> versions = eeNameVersions.get(name);
+    if (versions==null) {
+      versions = new TreeSet<Version>();
+      eeNameVersions.put(name, versions);
+    }
+    if (v !=null) {
+      versions.add(v);
+    }
+  }
+
+
+  private void addSysCapabilityForEE(final StringBuffer sb,
+                                     final Map<String, SortedSet<Version>> eeNameVersions)
+  {
+    for (final Entry<String, SortedSet<Version>> entry : eeNameVersions
+        .entrySet()) {
+      if (sb.length() > 0) {
+        sb.append(',');
+      }
+      sb.append(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
+      sb.append(';');
+      sb.append(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
+      sb.append('=');
+      sb.append(entry.getKey());
+      if (!entry.getValue().isEmpty()) {
+        sb.append(";version:List<Version>=\"");
+        for (final Version v : entry.getValue()) {
+          sb.append(v.toString());
+          sb.append(',');
+        }
+        sb.setCharAt(sb.length() - 1, '"');
+      }
+    }
+  }
+
+  /**
+   * This method start a thread that stop this Framework, stopping all started
+   * bundles.
+   *
+   * <p>
+   * If the framework is not started, this method does nothing. If the framework
+   * is started, this method will:
+   * <ol>
+   * <li>Set the state of the FrameworkContext to <i>inactive</i>.</li>
+   * <li>Suspended all started bundles as described in the
+   * {@link Bundle#stop(int)} method except that the persistent state of the
+   * bundle will continue to be started. Reports any exceptions that occur
+   * during stopping using <code>FrameworkErrorEvents</code>.</li>
+   * <li>Disable event handling.</li>
+   * </ol>
+   * </p>
+   *
+   */
+  void shutdown(final boolean restart) {
+    synchronized (lock) {
+      boolean wasActive = false;
+      switch (state) {
+      case Bundle.INSTALLED:
+      case Bundle.RESOLVED:
+        shutdownDone(false);
+        break;
+      case Bundle.ACTIVE:
+        wasActive = true;
+        // Fall through
+      case Bundle.STARTING:
+        if (shutdownThread == null) {
+          try {
+            final boolean wa = wasActive;
+            shutdownThread = new Thread(fwCtx.threadGroup, "Framework shutdown") {
+              @Override
+              public void run() {
+                shutdown0(restart, wa);
+              }
+            };
+            shutdownThread.setDaemon(false);
+            shutdownThread.start();
+          } catch (final Exception e) {
+            systemShuttingdownDone(new FrameworkEvent(FrameworkEvent.ERROR, this, e));
+          }
+        }
+        break;
+      case Bundle.STOPPING:
+        // Shutdown already inprogress
+        break;
+      }
+    }
+  }
+
+
+  /**
+   * Stop this FrameworkContext, suspending all started contexts. This method
+   * suspends all started contexts so that they can be automatically restarted
+   * when this FrameworkContext is next launched.
+   *
+   * <p>
+   * If the framework is not started, this method does nothing. If the framework
+   * is started, this method will:
+   * <ol>
+   * <li>Set the state of the FrameworkContext to <i>inactive</i>.</li>
+   * <li>Stop all started bundles as described in the {@link Bundle#stop(int)}
+   * method except that the persistent state of the bundle will continue to be
+   * started. Reports any exceptions that occur during stopping using
+   * <code>FrameworkErrorEvents</code>.</li>
+   * <li>Disable event handling.</li>
+   * </ol>
+   * </p>
+   *
+   */
+  private void shutdown0(final boolean restart, final boolean wasActive) {
+    try {
+      synchronized (lock) {
+        waitOnOperation(lock, "Framework." + (restart ? "update" : "stop"), true);
+        operation = DEACTIVATING;
+        state = STOPPING;
+      }
+      fwCtx.listeners.bundleChanged(new BundleEvent(BundleEvent.STOPPING, this));
+      if (wasActive) {
+        stopAllBundles();
+        saveClasspaths();
+      }
+      synchronized (lock) {
+        fwCtx.uninit();
+        shutdownThread = null;
+        shutdownDone(restart);
+      }
+      if (restart) {
+        if (wasActive) {
+          start();
+        } else {
+          init();
+        }
+      }
+    } catch (final Exception e) {
+      shutdownThread = null;
+      systemShuttingdownDone(new FrameworkEvent(FrameworkEvent.ERROR, this, e));
+    }
+
+  }
+
+
+  /**
+   * Tell system bundle shutdown finished.
+   */
+  private void shutdownDone(boolean restart) {
+    int t;
+    if (bootClassPathHasChanged) {
+      t = FrameworkEvent.STOPPED_BOOTCLASSPATH_MODIFIED;
+    } else {
+      t = restart ? FrameworkEvent.STOPPED_UPDATE : FrameworkEvent.STOPPED;
+    }
+    systemShuttingdownDone(new FrameworkEvent(t, this, null));
+  }
+
+
+  /**
+   * Stop and unresolve all bundles.
+   */
+  private void stopAllBundles() {
+    if (fwCtx.startLevelController != null) {
+      fwCtx.startLevelController.shutdown();
+    }
+
+    // Stop all active bundles, in reverse bundle ID order
+    // The list will be empty when the start level service is in use.
+    final List<BundleImpl> activeBundles = fwCtx.bundles.getActiveBundles();
+    for (int i = activeBundles.size() - 1; i >= 0; i--) {
+      final BundleImpl b = activeBundles.get(i);
+      try {
+        if (((Bundle.ACTIVE | Bundle.STARTING) & b.getState()) != 0) {
+          // Stop bundle without changing its autostart setting.
+          b.stop(Bundle.STOP_TRANSIENT);
+        }
+      } catch (final BundleException be) {
+        fwCtx.frameworkError(b, be);
+      }
+    }
+
+    final List<BundleImpl> allBundles = fwCtx.bundles.getBundles();
+
+    // Set state to INSTALLED and purge any unrefreshed bundles
+    for (final BundleImpl bundleImpl : allBundles) {
+      final BundleImpl b = bundleImpl;
+      if (b.getBundleId() != 0) {
+        b.setStateInstalled(false);
+        b.purge();
+      }
+    }
+  }
+
+
+  private void saveClasspaths() {
+    final StringBuffer bootClasspath = new StringBuffer();
+    for (final BundleGeneration bundleGeneration : fwCtx.bundles.getFragmentBundles(current())) {
+      final BundleGeneration ebg = bundleGeneration;
+      final String path = ebg.archive.getJarLocation();
+      if (ebg.isBootClassPathExtension()) {
+        if (bootClasspath.length() > 0) {
+          bootClasspath.append(File.pathSeparator);
+        }
+        bootClasspath.append(path);
+      }
+    }
+
+    // Post processing to handle boot class extension
+    try {
+      final File bcpf = new File(Util.getFrameworkDir(fwCtx), BOOT_CLASSPATH_FILE);
+      if (bootClasspath.length() > 0) {
+        saveStringBuffer(bcpf, bootClasspath);
+      } else {
+        bcpf.delete();
+      }
+    } catch (final IOException e) {
+      if (fwCtx.debug.errors) {
+        fwCtx.debug.println("Could not save classpath " + e);
+      }
+    }
+  }
+
+
+  private void saveStringBuffer(File f, StringBuffer content) throws IOException {
+    PrintStream out = null;
+    try {
+      out = new PrintStream(new FileOutputStream(f));
+      out.println(content.toString());
+    } finally {
+      if (out != null) {
+        out.close();
+      }
+    }
+  }
+
+
+  private void addClassPathURL(URL url) throws Exception {
+    final ClassLoader cl = getClassLoader();
+    Method m = Util.getMethod(cl.getClass(), "addURL", new Class[] { URL.class });
+    if (m != null) {
+      m.invoke(cl, new Object[] { url });
+    } else {
+      throw new NoSuchMethodException("addURL");
+    }
+  }
+
+
+  /**
+   * If the extension has an extension activator header process it.
+   *
+   * @param extension the extension bundle to process.
+   */
+  private void handleExtensionActivator(final BundleGeneration extension) {
+    String extActivatorName =
+      extension.archive.getAttribute("Extension-Activator");
+    extActivatorName = null!=extActivatorName ? extActivatorName.trim() : null;
+
+    if (null!=extActivatorName && extActivatorName.length()>0) {
+      fwCtx.log("Activating extension: " + extension.symbolicName
+                + ":" +extension.version + " using: " +extActivatorName);
+      fwCtx.activateExtension(extension);
+    }
+  }
+
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/URLStreamHandlerWrapper.java b/osgi/framework/src/org/knopflerfish/framework/URLStreamHandlerWrapper.java
new file mode 100644
index 0000000..9f840e5
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/URLStreamHandlerWrapper.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.util.ArrayList;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.url.URLConstants;
+import org.osgi.service.url.URLStreamHandlerService;
+import org.osgi.service.url.URLStreamHandlerSetter;
+
+/**
+ * Wrapper which delegates an URL protocol to
+ * OSGi URLStreamHandlerServices.
+ *
+ * <p>
+ * Each instance of URLStreamHandlerWrapper tracks URLStreamHandlerServices
+ * for a named protocol and selects the best from all available services.
+ * </p>
+ */
+public class URLStreamHandlerWrapper
+  extends    URLStreamHandler
+  implements URLStreamHandlerSetter
+{
+  ArrayList<FrameworkContext> framework = new ArrayList<FrameworkContext>(2);
+  final String protocol;
+  final String filter;
+  final ServiceListener serviceListener;
+
+  private ServiceReference<URLStreamHandlerService> best;
+  private URLStreamHandlerService bestService;
+  private FrameworkContext currentFw;
+
+  URLStreamHandlerWrapper(final FrameworkContext  fw,
+			  final String proto)
+  {
+    protocol  = proto;
+    filter = "(&(" + Constants.OBJECTCLASS + "=" +
+      URLStreamHandlerService.class.getName() + ")" +
+      "(" + URLConstants.URL_HANDLER_PROTOCOL + "=" + protocol +
+      "))";
+
+    serviceListener = new ServiceListener() {
+        synchronized public void serviceChanged(ServiceEvent evt) {
+          @SuppressWarnings("unchecked")
+          final ServiceReference<URLStreamHandlerService> ref =
+            (ServiceReference<URLStreamHandlerService>) evt.getServiceReference();
+          final FrameworkContext fw = ((BundleImpl)ref.getBundle()).fwCtx;
+          if (fw == currentFw) {
+            switch (evt.getType()) {
+            case ServiceEvent.MODIFIED:
+              // fall through
+            case ServiceEvent.REGISTERED:
+              if (best != null && best.compareTo(ref) < 0) {
+                best = ref;
+                bestService = null;
+              }
+              break;
+            case ServiceEvent.MODIFIED_ENDMATCH:
+              // fall through
+            case ServiceEvent.UNREGISTERING:
+              if (best != null && best.equals(ref)) {
+                best = null;
+                bestService = null;
+              }
+            }
+          }
+        }
+      };
+
+    framework.add(fw);
+    try {
+      fw.systemBundle.bundleContext.addServiceListener(serviceListener, filter);
+    } catch (final InvalidSyntaxException e) {
+      throw new IllegalArgumentException("Protocol name contains illegal characters: " + proto);
+    }
+
+    if (fw.debug.url) {
+      fw.debug.println("created wrapper for " + protocol + ", filter=" + filter
+                       + ", " + toString());
+    }
+  }
+
+
+  /**
+   *
+   */
+  void addFramework(FrameworkContext fw) {
+    try {
+      fw.systemBundle.bundleContext.addServiceListener(serviceListener, filter);
+      framework.add(fw);
+      if (fw.debug.url) {
+        fw.debug.println("created wrapper for " + protocol + ", filter=" + filter
+                         + ", " + toString());
+      }
+    } catch (final InvalidSyntaxException _no) { }
+  }
+
+
+  /**
+   *
+   */
+  boolean removeFramework(FrameworkContext fw) {
+    framework.remove(fw);
+    return framework.isEmpty();
+  }
+
+
+  /**
+   *
+   */
+  private URLStreamHandlerService getService() {
+    FrameworkContext fw;
+    if (framework.size() == 1) {
+      fw = framework.get(0);
+    } else {
+      // Get current FrameworkContext
+      throw new RuntimeException("NYI - walk stack to get framework");
+    }
+    synchronized (serviceListener) {
+      if (best == null) {
+        try {
+          @SuppressWarnings("unchecked")
+          final ServiceReference<URLStreamHandlerService>[] refs =
+            (ServiceReference<URLStreamHandlerService>[])
+              fw.systemBundle.bundleContext.getServiceReferences(URLStreamHandlerService.class.getName(), filter);
+          if (refs != null) {
+            // KF gives us highest ranked first.
+            best = refs[0];
+          }
+        } catch (final InvalidSyntaxException _no) { }
+      }
+      if (best == null) {
+        throw new IllegalStateException("null: Lost service for protocol="+ protocol);
+      }
+      if (bestService == null) {
+        bestService = fw.systemBundle.bundleContext.getService(best);
+      }
+      if (bestService == null) {
+        throw new IllegalStateException("null: Lost service for protocol=" + protocol);
+      }
+      currentFw = fw;
+      return bestService;
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public boolean equals(URL u1, URL u2) {
+    return getService().equals(u1, u2);
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected int getDefaultPort() {
+    return getService().getDefaultPort();
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected InetAddress getHostAddress(URL u) {
+    return getService().getHostAddress(u);
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected int hashCode(URL u) {
+    return getService().hashCode(u);
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected boolean hostsEqual(URL u1, URL u2) {
+    return getService().hostsEqual(u1, u2);
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected URLConnection openConnection(URL u) throws IOException {
+    try {
+      return getService().openConnection(u);
+    } catch(final IllegalStateException e) {
+      throw new MalformedURLException(e.getMessage());
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected  void parseURL(URL u, String spec, int start, int limit) {
+    getService().parseURL(this, u, spec, start, limit);
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  protected  boolean sameFile(URL u1, URL u2) {
+    return getService().sameFile(u1, u2);
+  }
+
+
+  /**
+   * This method is deprecated, but wrap it in the same
+   * way as JSDK1.4 wraps it.
+   */
+  @Override
+  public  void setURL(URL u, String protocol, String host, int port, String file, String ref) {
+
+    // parse host as "user:passwd at host"
+
+    String authority = null;
+    String userInfo = null;
+
+    if (host != null && host.length() != 0) {
+
+      authority = (port == -1) ? host : host + ":" + port;
+
+      final int ix = host.lastIndexOf('@');
+      if (ix != -1) {
+        userInfo = host.substring(0, ix);
+        host     = host.substring(ix+1);
+      }
+    }
+
+
+    // Parse query part from file ending with '?'
+    String path  = null;
+    String query = null;
+
+    if (file != null) {
+      final int ix = file.lastIndexOf('?');
+      if (ix != -1) {
+        query = file.substring(ix + 1);
+        path  = file.substring(0, ix);
+      } else {
+        path = file;
+      }
+    }
+    setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
+  }
+
+  @Override
+  public void setURL(URL u,
+                     String protocol,
+                     String host,
+                     int port,
+                     String authority,
+                     String userInfo,
+                     String path,
+                     String query,
+                     String ref)
+  {
+    super
+        .setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
+  }
+
+  @Override
+  protected  String toExternalForm(URL u) {
+    return getService().toExternalForm(u);
+  }
+
+  @Override
+  public String toString() {
+    final StringBuffer sb = new StringBuffer();
+
+    sb.append("URLStreamHandlerWrapper[");
+
+    final ServiceReference<URLStreamHandlerService> ref = best;
+    sb.append("protocol=" + protocol);
+    //    sb.append(", size=" + tracker.size());
+    if(ref != null) {
+      sb.append(", id=" + ref.getProperty(Constants.SERVICE_ID));
+      sb.append(", rank=" + ref.getProperty(Constants.SERVICE_RANKING));
+
+//       ServiceReference[] srl = tracker.getServiceReferences();
+//       for(int i = 0; srl != null && i < srl.length; i++) {
+// 	sb.append(", {");
+// 	sb.append("id=" + srl[i].getProperty(Constants.SERVICE_ID));
+// 	sb.append(", rank=" + srl[i].getProperty(Constants.SERVICE_RANKING));
+
+// 	String[] sa = (String[])srl[i].getProperty(URLConstants.URL_HANDLER_PROTOCOL);
+// 	sb.append(", proto=");
+
+// 	for(int j = 0; j < sa.length; j++) {
+// 	  sb.append(sa[j]);
+// 	  if(j < sa.length - 1) {
+// 	    sb.append(", ");
+// 	  }
+// 	}
+// 	sb.append("}");
+//       }
+
+    } else {
+      sb.append(" no service tracked");
+    }
+
+    sb.append("]");
+
+    return sb.toString();
+  }
+}
+
diff --git a/osgi/framework/src/org/knopflerfish/framework/Util.java b/osgi/framework/src/org/knopflerfish/framework/Util.java
new file mode 100644
index 0000000..5eeef4b
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Util.java
@@ -0,0 +1,1309 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+public class Util {
+
+  // Type names used for types OSGi attributes in manifest headers.
+  private static final String DOUBLE_TYPE = "Double";
+  private static final String LONG_TYPE = "Long";
+  private static final String LIST_TYPE = "List";
+  private static final String STRING_TYPE = "String";
+  private static final String VERSION_TYPE = "Version";
+
+  /**
+   * Pre OSGi 4.2 property used by KF, replaced by Constants.FRAMEWORK_STORAGE
+   * as of OSGi R4 v4.2.
+   */
+  static public final String FWDIR_PROP = "org.osgi.framework.dir";
+  static public final String FWDIR_DEFAULT = "fwdir";
+
+  static private final Method nanoTimeMethod = getMethod(System.class, "nanoTime", new Class[] { });
+
+
+  public static String getFrameworkDir(Map<String,String> props) {
+    String s = props.get(Constants.FRAMEWORK_STORAGE);
+    if (s == null || s.length() == 0) {
+      s = props.get(FWDIR_PROP);
+    }
+    if (s == null || s.length() == 0) {
+      s = System.getProperty(FWDIR_PROP);
+    }
+    if (s == null || s.length() == 0) {
+      s = FWDIR_DEFAULT;
+    }
+    return s;
+  }
+
+
+  public static String getFrameworkDir(FrameworkContext ctx) {
+    String s = ctx.props.getProperty(Constants.FRAMEWORK_STORAGE);
+    if (s == null || s.length() == 0) {
+      s = ctx.props.getProperty(FWDIR_PROP);
+    }
+    if (s == null || s.length() == 0) {
+      s = FWDIR_DEFAULT;
+    }
+    return s;
+  }
+
+
+  /**
+   * Check for local file storage directory.
+   *
+   * @return A FileTree object of directory or null if no storage is available.
+   */
+  public static FileTree getFileStorage(FrameworkContext ctx, String name, boolean create) {
+    // See if we have a storage directory
+    final String fwdir = getFrameworkDir(ctx);
+    if (fwdir == null) {
+      return null;
+    }
+    final FileTree dir = new FileTree((new File(fwdir)).getAbsoluteFile(), name);
+    if (dir != null) {
+      if (dir.exists()) {
+        if (!dir.isDirectory()) {
+          throw new RuntimeException("Not a directory: " + dir);
+        }
+      } else {
+        if (create && !dir.mkdirs()) {
+          throw new RuntimeException("Cannot create directory: " + dir);
+        }
+      }
+    }
+    return dir;
+  }
+
+  public static FileTree getFileStorage(FrameworkContext ctx, String name) {
+    return getFileStorage(ctx, name, true);
+  }
+
+
+  /**
+   * Compare to strings formatted as '<int>[.<int>[.<int>]]'. If string is null,
+   * then it counts as ZERO.
+   *
+   * @param ver1 First version string.
+   * @param ver2 Second version string.
+   * @return Return 0 if equals, -1 if ver1 < ver2 and 1 if ver1 > ver2.
+   * @exception NumberFormatException on syntax error in input.
+   */
+  public static int compareStringVersion(String ver1, String ver2)
+      throws NumberFormatException {
+    int i1, i2;
+    while (ver1 != null || ver2 != null) {
+      if (ver1 != null) {
+        final int d1 = ver1.indexOf(".");
+        if (d1 == -1) {
+          i1 = Integer.parseInt(ver1.trim());
+          ver1 = null;
+        } else {
+          i1 = Integer.parseInt(ver1.substring(0, d1).trim());
+          ver1 = ver1.substring(d1 + 1);
+        }
+      } else {
+        i1 = 0;
+      }
+      if (ver2 != null) {
+        final int d2 = ver2.indexOf(".");
+        if (d2 == -1) {
+          i2 = Integer.parseInt(ver2.trim());
+          ver2 = null;
+        } else {
+          i2 = Integer.parseInt(ver2.substring(0, d2).trim());
+          ver2 = ver2.substring(d2 + 1);
+        }
+      } else {
+        i2 = 0;
+      }
+      if (i1 < i2) {
+        return -1;
+      }
+      if (i1 > i2) {
+        return 1;
+      }
+    }
+    return 0;
+  }
+
+
+  /**
+   * Parse strings of format:
+   *
+   * ENTRY (, ENTRY)*
+   *
+   * @param d Directive being parsed
+   * @param s String to parse
+   * @return A HashSet with enumeration or null if enumeration string was null.
+   * @exception IllegalArgumentException If syntax error in input string.
+   */
+  public static Set<String> parseEnumeration(String d, String s)
+  {
+    final HashSet<String> result = new HashSet<String>();
+    if (s != null) {
+      final AttributeTokenizer at = new AttributeTokenizer(s);
+      do {
+        final String key = at.getKey(true);
+        if (key == null) {
+          throw new IllegalArgumentException("Directive " + d
+                                             + ", unexpected character at: "
+                                             + at.getRest());
+        }
+        if (!at.getEntryEnd()) {
+          throw new IllegalArgumentException("Directive " + d
+                                             + ", expected end of entry at: "
+                                             + at.getRest());
+        }
+        result.add(key);
+      } while (!at.getEnd());
+      return result;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Parse manifest header values on format:
+   * <pre>
+   * ENTRY (',' ENTRY)*
+   * ENTRY = key (';' key)* (';' PARAM)*
+   * PARAM = attribute (':' TYPE)? '=' value
+   * PARAM = directive ':=' value
+   * TYPE = SCALAR | LIST
+   * SCALAR = 'String' | 'Version' | 'Long' | 'Double'
+   * LIST = 'List<' SCALAR '>'
+   * </pre>
+   *
+   * The default attribute value type is 'String'. For list values the 'List'
+   * and its following '<' are treated as separate tokens to comply with the
+   * OSGi TCK.
+   *
+   * The parse result is one {@link HeaderEntry}-instance for each entry.
+   * If {@code single} is true then the entry only contains one key that can be
+   * accesses by calling {@link HeaderEntry#getKey()}.
+   *
+   * If {@code unique} is true the attribute values in the map are scalars
+   * otherwise the values from different attribute definitions with the same
+   * name are wrapped in a {@code List<?>}.
+   *
+   * @param a Name of attribute being parsed, for error messages.
+   * @param s String to parse.
+   * @param single If true, only allow one key per ENTRY.
+   * @param unique Only allow unique attributes for each ENTRY.
+   * @param single_entry If true, only allow one ENTRY in {@code s}.
+   *
+   * @return List of {@link HeaderEntry}-object, one per entry in {@code s}.
+   *
+   * @exception IllegalArgumentException If syntax error in input string.
+   */
+  public static List<HeaderEntry> parseManifestHeader(String a,
+                                                      String s,
+                                                      boolean single,
+                                                      boolean unique,
+                                                      boolean single_entry)
+  {
+    final List<HeaderEntry> res = new ArrayList<Util.HeaderEntry>();
+
+    if (s != null) {
+      final AttributeTokenizer at = new AttributeTokenizer(s);
+      do {
+        final HeaderEntry he = new HeaderEntry(a, single);
+        String key = at.getKey(single);
+        if (key == null) {
+          final String msg = "Definition, " + a + ", expected key at: "
+              + at.getRest() + ". Key values are terminated "
+              + "by a ';' or a ',' and may not "
+              + "contain unquoted ':', '=' if multiple keys are allowed.";
+          throw new IllegalArgumentException(msg);
+        }
+        he.keys.add(key);
+        if (!single) {
+          while ((key = at.getKey(false)) != null) {
+            he.keys.add(key);
+          }
+        }
+        String param;
+        while ((param = at.getParam()) != null) {
+          final boolean is_directive = at.isDirective();
+          if (is_directive) {
+            if (he.directives.containsKey(param)) {
+              final String msg = "Definition, " + a + ", duplicate directive: "
+                    + param;
+              throw new IllegalArgumentException(msg);
+            }
+            final String valueStr = at.getValue(false);
+            if (valueStr == null) {
+              final String msg = "Definition, " + a + ", expected value for "
+                  + " directive " + param + " at: " + at.getRest();
+              throw new IllegalArgumentException(msg);
+            }
+            he.directives.put(param, valueStr);
+          } else {
+            // Attribute definition with optional type
+            final Object old = he.attributes.get(param);
+            if (old != null && unique) {
+              final String msg = "Definition, " + a + ", duplicate attribute: "
+                                + param;
+              throw new IllegalArgumentException(msg);
+            }
+            final String paramType = at.getParamType();
+            final boolean keepEscape = paramType != null
+                                       && paramType.startsWith("List");
+            final String valueStr = at.getValue(keepEscape);
+            if (valueStr == null) {
+              final String msg = "Definition, " + a + ", expected value for "
+                  + " attribute " + param + " at: " + at.getRest();
+              throw new IllegalArgumentException(msg);
+            }
+            final Object value = toValue(a, param, paramType, valueStr);
+            if (unique) {
+              he.attributes.put(param, value);
+            } else {
+              @SuppressWarnings("unchecked")
+              List<Object> oldValues = (List<Object>) old;
+              if (oldValues == null) {
+                oldValues = new ArrayList<Object>();
+                he.attributes.put(param, oldValues);
+              }
+              oldValues.add(value);
+            }
+          }
+        }
+        if (at.getEntryEnd()) {
+          res.add(he);
+        } else {
+          throw new IllegalArgumentException("Definition, " + a
+              + ", expected end of entry at: " + at.getRest());
+        }
+        if (single_entry && !at.getEnd()) {
+          throw new IllegalArgumentException("Definition, " + a
+              + ", expected end of single entry at: " + at.getRest());
+        }
+      } while (!at.getEnd());
+    }
+
+    return res;
+  }
+
+
+  /**
+   * Convert an attribute value from string to the requested type.
+   *
+   * The types supported are described in
+   * {@link #parseEntries(String, String, boolean, boolean, boolean)}.
+   *
+   * @param a Name of attribute being parsed, for error messages.
+   * @param p Name of parameter to assign the value to, for error messages.
+   * @param type the type to convert to.
+   * @param value the value to convert.
+   * @return
+   */
+  private static Object toValue(String a,
+                                String param,
+                                String type,
+                                String value)
+  {
+    Object res;
+
+    type = type == null ? STRING_TYPE : type.intern();
+    if (STRING_TYPE == type) {
+      res = value;
+    } else if (LONG_TYPE == type) {
+      try {
+        res = new Long(value.trim());
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new
+        IllegalArgumentException("Definition, " +a
+                                 +", expected value of type Long but found '"
+                                 +value +"' for attribute '"
+                                 +param + "'.").initCause(e);
+      }
+    } else if (DOUBLE_TYPE == type) {
+      try {
+        res = new Double(value.trim());
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new
+        IllegalArgumentException("Definition, " +a
+                                 +", expected value of type Double but found '"
+                                 +value +"' for attribute '"
+                                 +param + "'.").initCause(e);
+      }
+    } else if (VERSION_TYPE == type) {
+      try {
+        res = new Version(value);
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new
+        IllegalArgumentException("Definition, " +a
+                                 +", expected value of type Version but found '"
+                                 +value +"' for attribute '"
+                                 +param + "'.").initCause(e);
+      }
+    } else if (type.startsWith(LIST_TYPE)) {
+      String elemType = type.substring(LIST_TYPE.length()).trim();
+      // Let "List" without any "<type>" default to "List<String>"
+      if (elemType.length()>0) {
+        if ('<' != elemType.charAt(0)
+            || elemType.charAt(elemType.length() - 1) != '>') {
+          throw new IllegalArgumentException
+            ("Definition, " + a + ", expected List type definition '"
+                + type + "' for attribute '" + param + "'.");
+        }
+        elemType = elemType.substring(1, elemType.length() - 1).trim().intern();
+      }
+      // The default element type is STRING.
+      if (elemType.length()==0) elemType = STRING_TYPE;
+
+      try {
+        final List<String> elements = splitWords(value, ',', STRING_TYPE!=elemType);
+        final List<Object> l = new ArrayList<Object>(elements.size());
+        for (final String elem : elements) {
+          l.add(toValue(a, param, elemType, elem));
+        }
+        res = l;
+      } catch (final Exception e) {
+        throw (IllegalArgumentException) new IllegalArgumentException
+          ("Definition, " + a + ", expected '" + type + "' value but found '"
+              + value + "' for attribute '" + param + "'.").initCause(e);
+      }
+    } else {
+        throw new IllegalArgumentException("Definition, " +a
+                                 +", unknown type '" +type +"' for attribute '"
+                                 +param + "'.");
+    }
+    return res;
+  }
+
+  /**
+   * Read a resource into a byte array.
+   *
+   * @param name resource name to read
+   * @return byte array with contents of resource.
+   */
+  static byte[] readResource(String name) throws IOException {
+    final byte[] buf = new byte[1024];
+
+    final InputStream in = Util.class.getResourceAsStream(name);
+    try {
+      final ByteArrayOutputStream bout = new ByteArrayOutputStream();
+      int n;
+      while ((n = in.read(buf)) > 0) {
+        bout.write(buf, 0, n);
+      }
+      return bout.toByteArray();
+    } finally {
+      try {
+        in.close();
+      } catch (final Exception ignored) {
+      }
+    }
+  }
+
+
+  /**
+   * Read a resource into a String.
+   *
+   * @param name resource name to read
+   * @param defaultValue if no resource is available
+   * @param encoding resource encoding
+   * @return String with contents of resource or supplied default value.
+   */
+  static String readResource(String file, String defaultValue, String encoding) {
+    try {
+      return (new String(readResource(file), encoding)).trim();
+    } catch (final Exception e) {
+      return defaultValue;
+    }
+  }
+
+
+  /**
+   * Read framework version file
+   */
+  static String readFrameworkVersion() {
+    return readResource("/version", "0.0.0", "UTF-8");
+  }
+
+  /**
+   * Read framework build year from the tstamp-file
+   */
+  static String readTstampYear() {
+    // tstamp format: "Build EE MMMM d yyyy, HH:mm:ss"
+    String year = readResource("/tstamp", "2013", "UTF-8");
+
+    int pos = year.indexOf(',');
+    if (pos>-1) {
+      year = year.substring(0, pos);
+      pos = year.lastIndexOf(' ');
+      if (pos>-1) {
+        year = year.substring(pos+1);
+      }
+    }
+    return year;
+  }
+
+  /**
+   * Default whitespace string for splitwords(). Value is <tt>" \t\n\r"</tt>)
+   */
+  protected static String WHITESPACE = " \t\n\r";
+
+  /**
+   * Default citation char for splitwords(). Value is <tt>'"'</tt>
+   */
+  protected static char CITCHAR = '"';
+
+
+  /**
+   * Utility method to split a string into words separated by whitespace.
+   *
+   * <p>
+   * Equivalent to <tt>splitwords(s, WHITESPACE)</tt>
+   * </p>
+   */
+  public static String[] splitwords(String s) {
+    return splitwords(s, WHITESPACE);
+  }
+
+
+  /**
+   * Utility method to split a string into words separated by whitespace.
+   *
+   * <p>
+   * Equivalent to <tt>splitwords(s, WHITESPACE, CITCHAR)</tt>
+   * </p>
+   */
+  public static String[] splitwords(String s, String whiteSpace) {
+    return splitwords(s, whiteSpace, CITCHAR);
+  }
+
+
+  /**
+   * Split a string into words separated by whitespace.
+   * <p>
+   * Citation chars may be used to group words with embedded whitespace.
+   * </p>
+   *
+   * @param s String to split.
+   * @param whiteSpace whitespace to use for splitting. Any of the characters in
+   *          the whiteSpace string are considered whitespace between words and
+   *          will be removed from the result. If no words are found, return an
+   *          array of length zero.
+   * @param citChar Citation character used for grouping words with embedded
+   *          whitespace. Typically '"'
+   */
+  public static String[] splitwords(String s,
+                                     String whiteSpace,
+                                     char citChar) {
+    boolean bCit = false; // true when inside citation chars.
+    final Vector<String> v = new Vector<String>(); // (String) individual words after splitting
+    StringBuffer buf = new StringBuffer();
+    int i = 0;
+
+    while (i < s.length()) {
+      final char c = s.charAt(i);
+
+      if (bCit || whiteSpace.indexOf(c) == -1) {
+        // Build up word until we breaks on either a citation char or whitespace
+        if (c == citChar) {
+          bCit = !bCit;
+        } else {
+          if (buf == null) {
+            buf = new StringBuffer();
+          }
+          buf.append(c);
+        }
+        i++;
+      } else {
+        // found whitespace or end of citation, append word if we have one
+        if (buf != null) {
+          v.addElement(buf.toString());
+          buf = null;
+        }
+
+        // and skip whitespace so we start clean on a word or citation char
+        while ((i < s.length()) && (-1 != whiteSpace.indexOf(s.charAt(i)))) {
+          i++;
+        }
+      }
+    }
+
+    // Add possible remaining word
+    if (buf != null) {
+      v.addElement(buf.toString());
+    }
+
+    // Copy back into an array
+    final String[] r = new String[v.size()];
+    v.copyInto(r);
+
+    return r;
+  }
+
+
+  /**
+   * Split a string into words separated by a separator char.
+   *
+   * If the separator char shall be part of a word it must be escaped with a
+   * '\' (\u005C). One level of escaping is consumed by this method.
+   *
+   * @param s String to split.
+   * @param sepChar separator char to split on.
+   * @param trim trim whitespace from the words if {@code true}.
+   *
+   * @return List with the words of the specified string.
+   */
+  public static List<String> splitWords(String s,
+                                        char sepChar,
+                                        boolean trim)
+  {
+    final List<String> res = new ArrayList<String>();
+    final StringBuffer buf = new StringBuffer();
+    int pos = 0;
+    final int length = s.length();
+
+    boolean esc = false;
+    int end = 0;
+    for (; pos < length; pos++) {
+      if (esc) {
+        esc = false;
+        buf.append(s.charAt(pos));
+        end = buf.length();
+      } else {
+        final char c = s.charAt(pos);
+        if (c == '\\') {
+          esc = true;
+        } else if (c == sepChar) {
+          // trim trailing whitespace.
+          if (trim) buf.setLength(end);
+          res.add(buf.toString());
+          buf.setLength(0);
+          end = 0;
+        } else if (Character.isWhitespace(c)) {
+          if (buf.length()>0 || !trim) {
+            buf.append(c);
+          }
+        } else {
+          buf.append(c);
+          end = buf.length();
+        }
+      }
+    }
+    if (esc) {
+      throw new IllegalArgumentException("Value ends on escape character");
+    }
+    // The last element.
+    if (trim) buf.setLength(end);
+    res.add(buf.toString());
+
+    return res;
+  }
+
+
+  /**
+   * Replace all occurrences of a substring with another string.
+   *
+   * <p>
+   * The returned string will shrink or grow as necessary depending on the
+   * lengths of <tt>v1</tt> and <tt>v2</tt>.
+   * </p>
+   *
+   * <p>
+   * Implementation note: This method avoids using the standard String
+   * manipulation methods to increase execution speed. Using the
+   * <tt>replace</tt> method does however include two <tt>new</tt> operations in
+   * the case when matches are found.
+   * </p>
+   *
+   *
+   * @param s
+   *          Source string.
+   * @param v1
+   *          String to be replaced with <code>v2</code>.
+   * @param v2
+   *          String replacing <code>v1</code>.
+   * @return Modified string. If any of the input strings are <tt>null</tt>, the
+   *         source string <tt>s</tt> will be returned unmodified. If
+   *         <tt>v1.length == 0</tt>, <tt>v1.equals(v2)</tt> or no occurrences
+   *         of <tt>v1</tt> is found, also return <tt>s</tt> unmodified.
+   *
+   * @author Erik Wistrand
+   */
+  public static String replace(final String s,
+                               final String v1,
+                               final String v2) {
+
+    // return quick when nothing to do
+    if (s == null
+        || v1 == null
+        || v2 == null
+        || v1.length() == 0
+        || v1.equals(v2)) {
+      return s;
+    }
+
+    int ix = 0;
+    final int v1Len = v1.length();
+    int n = 0;
+
+    // count number of occurances to be able to correctly size
+    // the resulting output char array
+    while (-1 != (ix = s.indexOf(v1, ix))) {
+      n++;
+      ix += v1Len;
+    }
+
+    // No occurances at all, just return source string
+    if (n == 0) {
+      return s;
+    }
+
+    // Set up an output char array of correct size
+    int start = 0;
+    final int v2Len = v2.length();
+    final char[] r = new char[s.length() + n * (v2Len - v1Len)];
+    int rPos = 0;
+
+    // for each occurance, copy v2 where v1 used to be
+    while (-1 != (ix = s.indexOf(v1, start))) {
+      while (start < ix)
+        r[rPos++] = s.charAt(start++);
+      for (int j = 0; j < v2Len; j++) {
+        r[rPos++] = v2.charAt(j);
+      }
+      start += v1Len;
+    }
+
+    // ...and add all remaining chars
+    ix = s.length();
+    while (start < ix)
+      r[rPos++] = s.charAt(start++);
+
+    // ..ouch. this hurts.
+    return new String(r);
+  }
+
+
+  public static String getContent(File f) {
+    DataInputStream in = null;
+    try {
+      in = new DataInputStream(new FileInputStream(f));
+      return in.readUTF();
+    } catch (final IOException ignore) {
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) {
+        }
+      }
+    }
+    return null;
+  }
+
+
+  public static void putContent(File f, String content) throws IOException {
+    putContent(f, content, true);
+  }
+
+
+  public static void putContent(File f, String content, boolean useUTF8) throws IOException {
+    DataOutputStream out = null;
+    try {
+      out = new DataOutputStream(new FileOutputStream(f));
+      if (useUTF8) {
+        out.writeUTF(content);
+      } else {
+        out.writeChars(content);
+      }
+    } finally {
+      if (out != null) {
+        out.close();
+      }
+    }
+  }
+
+  /**
+   * Compare two object. Normally both types are the same, but sometimes its
+   * convenient to avoid creating a template object when using the comparator
+   * for lookup. In the latter case {@code B} would be the type of the key used
+   * in a {@code Comparator<A,A>}.
+   */
+  public interface Comparator<A,B> {
+    public int compare(A a, B b);
+  }
+
+
+  /**
+   * Sort a vector with objects comparable using a comparison function.
+   *
+   * @param a Vector to sort
+   * @param cf comparison function
+   */
+  static public <A> void sort(List<A> a, Comparator<A,A> cf, boolean bReverse) {
+    sort(a, 0, a.size() - 1, cf, bReverse ? -1 : 1);
+  }
+
+
+  /**
+   * Vector QSort implementation.
+   */
+  static <A> void sort(List<A> a, int lo0, int hi0, Comparator<A,A> cf, int k) {
+    int lo = lo0;
+    int hi = hi0;
+    A mid;
+
+    if (hi0 > lo0) {
+
+      mid = a.get((lo0 + hi0) / 2);
+
+      while (lo <= hi) {
+        while ((lo < hi0) && (k * cf.compare(a.get(lo), mid) < 0)) {
+          ++lo;
+        }
+
+        while ((hi > lo0) && (k * cf.compare(a.get(hi), mid) > 0)) {
+          --hi;
+        }
+
+        if (lo <= hi) {
+          swap(a, lo, hi);
+          ++lo;
+          --hi;
+        }
+      }
+
+      if (lo0 < hi) {
+        sort(a, lo0, hi, cf, k);
+      }
+
+      if (lo < hi0) {
+        sort(a, lo, hi0, cf, k);
+      }
+    }
+  }
+
+
+  private static <A> void swap(List<A> a, int i, int j) {
+    final A tmp = a.get(i);
+    a.set(i, a.get(j));
+    a.set(j, tmp);
+  }
+
+
+  /**
+   * Do binary search for a package entry in the list with the same version
+   * number add the specifies package entry.
+   *
+   * @param pl Sorted list of package entries to search.
+   * @param c comparator determining the ordering.
+   * @param k The key of the Package entry to search for.
+   * @return index of the found entry. If no entry is found, return
+   *         {@code (-(<i>insertion point</i>) - 1)}. The insertion point is
+   *         defined as the point at which the key would be inserted into the
+   *         list.
+   */
+  public static <A,B> int binarySearch(List<A> pl, Comparator<A,B> c, B k) {
+    int l = 0;
+    int u = pl.size() - 1;
+
+    while (l <= u) {
+      final int m = (l + u) / 2;
+      final int v = c.compare(pl.get(m), k);
+      if (v > 0) {
+        l = m + 1;
+      } else if (v < 0) {
+        u = m - 1;
+      } else {
+        return m;
+      }
+    }
+    return -(l + 1); // key not found.
+  }
+
+  private static final byte encTab[] = {
+      0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+      0x50,
+      0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65,
+      0x66,
+      0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+      0x76,
+      0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b,
+      0x2f
+  };
+
+
+  public static String base64Encode(String s) throws IOException {
+    return encode(s.getBytes(), 0);
+  }
+
+
+  /**
+   * Encode a raw byte array to a Base64 String.
+   *
+   * @param in Byte array to encode.
+   */
+  // public static String encode(byte[] in) throws IOException {
+  // return encode(in, 0);
+  // }
+
+  /**
+   * Encode a raw byte array to a Base64 String.
+   *
+   * @param in Byte array to encode.
+   * @param len Length of Base64 lines. 0 means no line breaks.
+   */
+  public static String encode(byte[] in, int len) throws IOException {
+    ByteArrayOutputStream baos = null;
+    ByteArrayInputStream bais = null;
+    try {
+      baos = new ByteArrayOutputStream();
+      bais = new ByteArrayInputStream(in);
+      encode(bais, baos, len);
+      // ASCII byte array to String
+      return (new String(baos.toByteArray()));
+    } finally {
+      if (baos != null)
+        baos.close();
+      if (bais != null)
+        bais.close();
+    }
+  }
+
+
+  public static void encode(InputStream in, OutputStream out, int len)
+      throws IOException {
+
+    // Check that length is a multiple of 4 bytes
+    if (len % 4 != 0)
+      throw new IllegalArgumentException("Length must be a multiple of 4");
+
+    // Read input stream until end of file
+    int bits = 0;
+    int nbits = 0;
+    int nbytes = 0;
+    int b;
+
+    while ((b = in.read()) != -1) {
+      bits = (bits << 8) | b;
+      nbits += 8;
+      while (nbits >= 6) {
+        nbits -= 6;
+        out.write(encTab[0x3f & (bits >> nbits)]);
+        nbytes++;
+        // New line
+        if (len != 0 && nbytes >= len) {
+          out.write(0x0d);
+          out.write(0x0a);
+          nbytes -= len;
+        }
+      }
+    }
+
+    switch (nbits) {
+    case 2:
+      out.write(encTab[0x3f & (bits << 4)]);
+      out.write(0x3d); // 0x3d = '='
+      out.write(0x3d);
+      break;
+    case 4:
+      out.write(encTab[0x3f & (bits << 2)]);
+      out.write(0x3d);
+      break;
+    }
+
+    if (len != 0) {
+      if (nbytes != 0) {
+        out.write(0x0d);
+        out.write(0x0a);
+      }
+      out.write(0x0d);
+      out.write(0x0a);
+    }
+  }
+
+
+  /**
+   * Merges target with the entries in extra. After this method has returned
+   * target will contain all entries in extra that did not exist in target.
+   */
+  static <A, B> void mergeDictionaries(Dictionary<A, B> target, Dictionary<A,B> extra) {
+    for (final Enumeration<A> e = extra.keys(); e.hasMoreElements();) {
+      final A key = e.nextElement();
+      if (target.get(key) == null) {
+        target.put(key, extra.get(key));
+      }
+    }
+  }
+
+
+  /**
+   * Check wild-card filter matches the string
+   */
+  public static boolean filterMatch(String filter, String s) {
+    return patSubstr(s.toCharArray(), 0, filter.toCharArray(), 0);
+  }
+
+
+  /**
+   */
+  private static boolean patSubstr(char[] s, int si, char[] pat, int pi) {
+    if (pat.length - pi == 0)
+      return s.length - si == 0;
+    if (pat[pi] == '*') {
+      pi++;
+      for (;;) {
+        if (patSubstr(s, si, pat, pi))
+          return true;
+        if (s.length - si == 0)
+          return false;
+        si++;
+      }
+    } else {
+      if (s.length - si == 0) {
+        return false;
+      }
+      if (s[si] != pat[pi]) {
+        return false;
+      }
+      return patSubstr(s, ++si, pat, ++pi);
+    }
+  }
+
+  /**
+   * Get method from class
+   */
+  public static Method getMethod(Class<?> c, String name, Class<?> [] args) {
+    Method m = null;
+    while (true) {
+      try {
+        m = c.getDeclaredMethod(name, args);
+        break;
+      } catch (NoSuchMethodException e) {
+        c = c.getSuperclass();
+        if (c == null) {
+          return null;
+        }
+      }
+    }
+    m.setAccessible(true);
+    return m;
+  }
+
+  /**
+   * Use System.nanoTime() if available, otherwise revert to
+   * System.currentTimeMillis(). Return 
+   */
+  public static long timeMillis() {
+    if (nanoTimeMethod != null) {
+      try  {
+        Object res = nanoTimeMethod.invoke(null, new Object[] { });
+        if (res != null) {
+          return ((Long)res).longValue() / 1000000L;
+        }
+      } catch (IllegalAccessException _ignore) { 
+      } catch (InvocationTargetException _ignore) { }
+    }
+    return System.currentTimeMillis();
+  }
+
+  /**
+   * Class for tokenize an attribute string.
+   */
+  static class AttributeTokenizer {
+
+    final String s;
+    int length;
+    int pos = 0;
+
+
+    AttributeTokenizer(final String input) {
+      s = input;
+      length = s.length();
+    }
+
+    // get word (non-whitespace chars) up to the next non-quoted
+    // ',', ';' or ':', '=' if not valueWord is set
+    String getWord(boolean keepEscapse, boolean valueWord) {
+      skipWhite();
+      boolean backslash = false;
+      boolean quote = false;
+      final StringBuffer val = new StringBuffer();
+      int end = 0;
+      loop: for (; pos < length; pos++) {
+        if (backslash) {
+          backslash = false;
+          if (keepEscapse) {
+            val.append('\\');
+          }
+          val.append(s.charAt(pos));
+          end = val.length();
+        } else {
+          final char c = s.charAt(pos);
+          switch (c) {
+          case '"':
+            quote = !quote;
+            end = val.length();
+            break;
+          case '\\':
+            backslash = true;
+            break;
+          case ':':
+          case ',':
+          case ';':
+          case '=':
+            if (!quote && !(valueWord && (c==':' || c=='='))) {
+              break loop;
+            }
+            // Fall through
+          default:
+            val.append(c);
+            if (!Character.isWhitespace(c)) {
+              end = val.length();
+            }
+            break;
+          }
+        }
+      }
+      if (quote || backslash || end == 0) {
+        return null;
+      }
+      val.setLength(end);
+      return val.toString();
+    }
+
+
+    String getKey(boolean singleKey) {
+      if (pos >= length) {
+        return null;
+      }
+      final int save = pos;
+      if (s.charAt(pos) == ';') {
+        pos++;
+      }
+      final String res = getWord(false, singleKey);
+      if (res != null) {
+        if (pos == length) {
+          return res;
+        }
+        final char c = s.charAt(pos);
+        if (c == ';' || c == ',') {
+          return res;
+        }
+      }
+      pos = save;
+      return null;
+    }
+
+
+    String getParam() {
+      if (pos == length || s.charAt(pos) != ';') {
+        return null;
+      }
+      final int save = pos++;
+      final String res = getWord(false, false);
+      if (res != null) {
+        if (pos < length && s.charAt(pos) == '=') {
+          // Untyped parameter
+          return res;
+        }
+        if (pos < length && s.charAt(pos) == ':') {
+          // Typed parameter or directive
+          return res;
+        }
+      }
+      pos = save;
+      return null;
+    }
+
+
+    boolean isDirective() {
+      if (pos + 1 < length && s.charAt(pos) == ':' && s.charAt(pos + 1) == '=') {
+        pos++;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+
+    String getParamType() {
+      if (pos == length || s.charAt(pos) != ':') {
+        return null;
+      }
+      final int save = pos++;
+      final String res = getWord(false, false);
+      if (res != null) {
+        if (pos < length && s.charAt(pos) == '=') {
+          return res;
+        }
+      }
+      pos = save;
+      return null;
+    }
+
+
+    String getValue() {
+      return getValue(false);
+    }
+
+    String getValue(boolean keepEscapes) {
+      if (s.charAt(pos) != '=') {
+        return null;
+      }
+      final int save = pos++;
+      skipWhite();
+      final String val = getWord(keepEscapes, true);
+      if (val == null) {
+        pos = save;
+        return null;
+      }
+      return val;
+    }
+
+
+    boolean getEntryEnd() {
+      final int save = pos;
+      skipWhite();
+      if (pos == length) {
+        return true;
+      } else if (s.charAt(pos) == ',') {
+        pos++;
+        return true;
+      } else {
+        pos = save;
+        return false;
+      }
+    }
+
+
+    boolean getEnd() {
+      final int save = pos;
+      skipWhite();
+      if (pos == length) {
+        return true;
+      } else {
+        pos = save;
+        return false;
+      }
+    }
+
+
+    String getRest() {
+      final String res = s.substring(pos).trim();
+      return res.length() == 0 ? "<END OF LINE>" : res;
+    }
+
+
+    private void skipWhite() {
+      for (; pos < length; pos++) {
+        if (!Character.isWhitespace(s.charAt(pos))) {
+          break;
+        }
+      }
+    }
+  }
+
+  /**
+   * A class that holds the parse result for one entry of a manifest header
+   * following the general OSGi manifest header syntax. See
+   * {@link Util#parseManifestHeader()} for
+   * details on the syntax.
+   */
+  public static class HeaderEntry
+  {
+    final String headerName;
+    final boolean singleKey;
+    final List<String> keys = new ArrayList<String>();
+    final Map<String, Object> attributes = new HashMap<String, Object>();
+    final Map<String, String> directives = new HashMap<String, String>();
+
+    /**
+     * @param singleKey
+     */
+    HeaderEntry(String headerName, boolean singleKey)
+    {
+      this.headerName = headerName;
+      this.singleKey = singleKey;
+    }
+
+    public String getKey()
+    {
+      if  (singleKey)
+        return keys.get(0);
+      throw new IllegalArgumentException("Requesting single key for multi key header clause");
+    }
+
+    public List<String> getKeys()
+    {
+      return keys;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+      return attributes;
+    }
+
+    public Map<String, String> getDirectives()
+    {
+      return directives;
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/Validator.java b/osgi/framework/src/org/knopflerfish/framework/Validator.java
new file mode 100644
index 0000000..7369d35
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/Validator.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+/**
+ * Interface for certificate validators.
+ *
+ * @author Jan Stein
+ */
+public interface Validator {
+
+  /**
+   * Check if a certificate chain is to be trusted.
+   *
+   * @return true, if validator trusts certificate chain, otherwise false.
+   */
+   boolean validateCertificateChain(List<X509Certificate> certs);
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/WeavingHooks.java b/osgi/framework/src/org/knopflerfish/framework/WeavingHooks.java
new file mode 100644
index 0000000..b2ea139
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/WeavingHooks.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2013-2013, 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.
+ */
+
+package org.knopflerfish.framework;
+
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.SortedMap;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.hooks.weaving.WeavingException;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+class WeavingHooks {
+  final private FrameworkContext fwCtx;
+  ServiceTracker<WeavingHook, TrackedWeavingHook> weavingHookTracker;
+
+  WeavingHooks(FrameworkContext fwCtx) {
+    this.fwCtx = fwCtx;
+  }
+
+  synchronized void open() {
+    if (fwCtx.debug.hooks) {
+      fwCtx.debug.println("Begin Tracking Weaving Hooks");
+    }
+
+    weavingHookTracker = new ServiceTracker<WeavingHook, TrackedWeavingHook>(
+        fwCtx.systemBundle.bundleContext, WeavingHook.class,
+        new ServiceTrackerCustomizer<WeavingHook, TrackedWeavingHook>() {
+          public TrackedWeavingHook addingService(
+              ServiceReference<WeavingHook> reference) {
+            return new TrackedWeavingHook(
+                fwCtx.systemBundle.bundleContext
+                    .getService(reference), reference);
+          }
+
+          public void modifiedService(ServiceReference<WeavingHook> reference,
+              TrackedWeavingHook service) {
+
+          }
+
+          public void removedService(ServiceReference<WeavingHook> reference,
+              TrackedWeavingHook service) {
+          }
+        });
+
+    weavingHookTracker.open();
+  }
+
+  synchronized void close() {
+    weavingHookTracker.close();
+    weavingHookTracker = null;
+  }
+
+  synchronized public boolean isOpen() {
+    return weavingHookTracker != null;
+  }
+
+  synchronized void callHooks(WovenClassImpl wc) throws Exception {
+    if (!isOpen()) {
+      return;
+    }
+
+    if (wc.isWeavingComplete()) {
+      throw new RuntimeException("ERROR!!");
+    }
+
+    try {
+      final SortedMap<ServiceReference<WeavingHook>, TrackedWeavingHook> hooks = weavingHookTracker
+          .getTracked();
+
+      for (final TrackedWeavingHook twh : hooks.values()) {
+        if (twh.isBlackListed())
+          continue;
+        try {
+          twh.weave(wc);
+        } catch (final WeavingException we) {
+          fwCtx.frameworkError(twh.reference.getBundle(), we);
+          final ClassFormatError cfe = new ClassFormatError(
+              "WeavingException thrown: " + we.getMessage() + " by hook "
+                  + twh.getClass().getName());
+          cfe.initCause(we);
+          throw cfe;
+        } catch (final Throwable t) {
+          fwCtx.frameworkError(twh.reference.getBundle(), t);
+          twh.blacklist();
+          final ClassFormatError cfe = new ClassFormatError("Exception throw: " + t
+              + " while calling hook " + twh.getClass().getName());
+          cfe.initCause(t);
+          throw cfe;
+        }
+      }
+    } finally {
+      wc.markAsComplete();
+    }
+  }
+
+  static class TrackedWeavingHook implements WeavingHook {
+    final WeavingHook tracked;
+    final ServiceReference<WeavingHook> reference;
+    boolean blacklisted = false;
+
+    TrackedWeavingHook(WeavingHook tracked,
+        ServiceReference<WeavingHook> reference) {
+      this.tracked = tracked;
+      this.reference = reference;
+    }
+
+    public void weave(WovenClass wovenClass) {
+      tracked.weave(wovenClass);
+    }
+
+    void blacklist() {
+      blacklisted = true;
+    }
+
+    boolean isBlackListed() {
+      return blacklisted;
+    }
+  }
+
+  static class WovenClassImpl implements WovenClass {
+    final BundleImpl bundle;
+    final String name;
+    byte[] current = null;
+    boolean complete = false;
+    Class<?> c = null;
+    final List<String> dynamicImports = new DynamicImportList<String>(this);
+  
+    WovenClassImpl(BundleImpl bundle, String name, byte[] initial) {
+      this.bundle = bundle;
+      this.name = name;
+      this.current = initial;
+    }
+  
+    public byte[] getBytes() {
+      bundle.fwCtx.perm.checkWeaveAdminPerm(bundle);
+      if (complete) {
+        final byte[] r = new byte[current.length];
+        System.arraycopy(current, 0, r, 0, current.length);
+        return r;
+      } else {
+        return current;
+      }
+    }
+  
+    public void setBytes(byte[] newBytes) {
+      bundle.fwCtx.perm.checkWeaveAdminPerm(bundle);
+      if (complete)
+        throw new IllegalStateException(
+            "Trying to call WovenClass.setBytes(byte[]) after weaving is complete");
+      if (newBytes == null)
+        throw new NullPointerException(
+            "Trying to call WovenClass.setBytes(byte[]) with null newBytes");
+      current = newBytes;
+    }
+  
+    public List<String> getDynamicImports() {
+      return dynamicImports;
+    }
+  
+    public boolean isWeavingComplete() {
+      return complete;
+    }
+  
+    public String getClassName() {
+      return name;
+    }
+  
+    public ProtectionDomain getProtectionDomain() {
+      return c == null ? null : c.getProtectionDomain();
+    }
+  
+    public Class<?> getDefinedClass() {
+      return c;
+    }
+  
+    public BundleWiring getBundleWiring() {
+      return bundle.current().bundleRevision.getWiring();
+    }
+  
+    void markAsComplete() {
+      complete = true;
+    }
+  
+    void setDefinedClass(Class<?> c) {
+      markAsComplete();
+      this.c = c;
+    }
+  
+    @Override
+    public String toString() {
+      return "WovenClass[" + name + ", " + toString(dynamicImports) + ", byte["
+          + current.length + "]=" + current + "]";
+    }
+  
+    String getDynamicImportsAsString() {
+      final StringBuffer sb = new StringBuffer();
+      for (final String s : dynamicImports) {
+        if (sb.length() > 0) {
+          sb.append(", ");
+        }
+        sb.append(s);
+      }
+      return sb.toString();
+    }
+  
+    String toString(List<String> sl) {
+      final StringBuffer sb = new StringBuffer();
+      sb.append("(");
+      for (final String s : sl) {
+        if (sb.length() > 1) {
+          sb.append(", ");
+        }
+        sb.append(s);
+      }
+      sb.append(")");
+      return sb.toString();
+    }
+  
+    public boolean hasAdditionalDynamicImports() {
+      return !dynamicImports.isEmpty();
+    }
+  }
+
+  public static class DynamicImportList<E> implements List<E> {
+  
+    final private List<E> org;
+    final private WovenClassImpl parent;
+    
+    public DynamicImportList(WovenClassImpl parent) {
+      this.parent = parent;
+      this.org = new ArrayList<E>();
+    }
+
+
+    public DynamicImportList(WovenClassImpl parent, List<E> subList) {
+      this.parent = parent;
+      org = subList;
+    }
+
+
+    @Override
+    public boolean add(E elem) {
+      checkChangeAllowed();
+      return org.add(elem);
+    }
+
+
+    @Override
+    public void add(int index, E elem) {
+      checkChangeAllowed();
+      org.add(index, elem);
+    }
+  
+
+    @Override
+    public boolean addAll(Collection<? extends E> elems) {
+      checkChangeAllowed();
+      return org.addAll(elems);
+    }
+
+
+    @Override
+    public boolean addAll(int index, Collection<? extends E> elems) {
+      checkChangeAllowed();
+      return org.addAll(index, elems);
+    }
+
+
+    @Override
+    public void clear() {
+      checkChangeAllowed();
+      org.clear();
+    }
+
+
+    @Override
+    public boolean contains(Object elem) {
+      return org.contains(elem);
+    }
+
+
+    @Override
+    public boolean containsAll(Collection<?> elems) {
+      return org.containsAll(elems);
+    }
+
+
+    @Override
+    public E get(int index) {
+      return org.get(index);
+    }
+
+
+    @Override
+    public int indexOf(Object elem) {
+      return org.indexOf(elem);
+    }
+
+
+    @Override
+    public boolean isEmpty() {
+      return org.isEmpty();
+    }
+
+
+    @Override
+    public Iterator<E> iterator() {
+      return new DynamicListIterator<E>(parent, org.listIterator());
+    }
+
+
+    @Override
+    public int lastIndexOf(Object elem) {
+      return org.lastIndexOf(elem);
+    }
+
+
+    @Override
+    public ListIterator<E> listIterator() {
+      return new DynamicListIterator<E>(parent, org.listIterator());
+    }
+
+
+    @Override
+    public ListIterator<E> listIterator(int index) {
+      return new DynamicListIterator<E>(parent, org.listIterator(index));
+    }
+
+
+    @Override
+    public E remove(int index) {
+      checkChangeAllowed();
+      return org.remove(index);
+    }
+  
+
+    @Override
+    public boolean remove(Object elem) {
+      checkChangeAllowed();
+      return org.remove(elem);
+    }
+  
+
+    @Override
+    public boolean removeAll(Collection<?> elems) {
+      checkChangeAllowed();
+      return org.removeAll(elems);
+    }
+  
+
+    @Override
+    public boolean retainAll(Collection<?> elems) {
+      checkChangeAllowed();
+      return org.removeAll(elems);
+    }
+
+
+    @Override
+    public E set(int index, E elem) {
+      checkChangeAllowed();
+      return org.set(index, elem);
+    }
+
+
+    @Override
+    public int size() {
+      return org.size();
+    }
+
+
+    @Override
+    public List<E> subList(int from, int to) {
+      return new DynamicImportList<E>(parent, org.subList(from, to));
+    }
+
+
+    @Override
+    public Object[] toArray() {
+      return org.toArray();
+    }
+
+
+    @Override
+    public <T> T[] toArray(T[] a) {
+      return org.toArray(a);
+    }
+
+
+    private void checkChangeAllowed() throws UnsupportedOperationException {
+      if (parent.isWeavingComplete()) {
+        throw new IllegalStateException("Parent WovenClass is frozen");
+      }
+      parent.bundle.fwCtx.perm.checkWeaveAdminPerm(parent.bundle);
+    }
+  
+  }
+
+  public static class DynamicListIterator<E> implements ListIterator<E> {
+
+    final private WovenClassImpl parent;
+    final private ListIterator<E> org;
+ 
+
+    public DynamicListIterator(WovenClassImpl parent, ListIterator<E> org) {
+      this.parent = parent;
+      this.org = org;
+    }
+
+    @Override
+    public void add(E elem) {
+      checkChangeAllowed();
+      org.add(elem);
+    }
+
+    @Override
+    public boolean hasNext() {
+      return org.hasNext();
+    }
+
+    @Override
+    public boolean hasPrevious() {
+      return org.hasPrevious();
+    }
+
+    @Override
+    public E next() {
+      return org.next();
+    }
+
+    @Override
+    public int nextIndex() {
+      return org.nextIndex();
+    }
+
+    @Override
+    public E previous() {
+      return org.previous();
+    }
+
+    @Override
+    public int previousIndex() {
+      return org.previousIndex();
+    }
+
+    @Override
+    public void remove() {
+      checkChangeAllowed();
+      org.remove();
+    }
+
+    @Override
+    public void set(E elem) {
+      checkChangeAllowed();
+      org.set(elem);
+    }
+  
+    private void checkChangeAllowed() throws UnsupportedOperationException {
+      if (parent.isWeavingComplete()) {
+        throw new IllegalStateException("Parent WovenClass is frozen");
+      }
+      parent.bundle.fwCtx.perm.checkWeaveAdminPerm(parent.bundle);
+    }
+  
+  }
+
+  
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/Util.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/Util.java
new file mode 100644
index 0000000..38e1bdd
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/Util.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage;
+
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Interface for managing bundle contents.
+ *
+ * @author Jan Stein
+ */
+public class Util {
+
+  /**
+   * Take an array of X509 certificates and arrange them as a list
+   * of chains. Certificates of unknown types and broken chains are
+   * add returned in failed list.
+   *
+   */
+  public static ArrayList<List<X509Certificate>> getCertificateChains(Certificate[] c,
+                                                                      ArrayList<Certificate> failed)
+  {
+    if (c == null) {
+      return null;
+    }
+    final ArrayList<List<X509Certificate>> res = new ArrayList<List<X509Certificate>>(3);
+    ArrayList<X509Certificate> chain = new ArrayList<X509Certificate>(3);
+    int i = 0;
+    while (i < c.length) {
+      if (c[i] instanceof X509Certificate) {
+        final X509Certificate cert = (X509Certificate) c[i++];
+        // TBD, can we use == and do we need to check uniqID?
+        chain.add(cert);
+        if (cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal())) {
+          res.add(chain);
+          chain = new ArrayList<X509Certificate>(3);
+        }
+      } else {
+        // Unsupported type
+        if (!chain.isEmpty()) {
+          failed.addAll(chain);
+          chain.clear();
+        }
+        failed.add(c[i++]);
+      }
+    }
+    // Add remaining certs as failed
+    failed.addAll(chain);
+
+    return res;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/Archive.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/Archive.java
new file mode 100644
index 0000000..0442e61
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/Archive.java
@@ -0,0 +1,1546 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage.file;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.URL;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.knopflerfish.framework.AutoManifest;
+import org.knopflerfish.framework.BundleGeneration;
+import org.knopflerfish.framework.BundleResourceStream;
+import org.knopflerfish.framework.FileArchive;
+import org.knopflerfish.framework.FileTree;
+import org.knopflerfish.framework.Util;
+import org.knopflerfish.framework.Util.HeaderEntry;
+import org.osgi.framework.Constants;
+
+/**
+ * JAR file handling.
+ *
+ * @author Jan Stein
+ * @author Philippe Laporte
+ * @author Mats-Ola Persson
+ * @author Gunnar Ekolin
+ */
+public class Archive implements FileArchive {
+
+  /**
+   * Base for filename used to store copy of archive.
+   */
+  final private static String ARCHIVE = "jar";
+
+  /**
+   * Directory base name to use for sub-archives.
+   */
+  final private static String SUBDIR = "sub";
+
+  /**
+   * File suffix for certificates.
+   */
+  final private static String CERTS_SUFFIX = ".crt";
+
+  /**
+   * Directory where JAR meta data are stored.
+   */
+  final private static String META_INF_DIR = "META-INF/";
+
+  /**
+   * Directory where optional bundle files are stored these need not be unpacked
+   * locally.
+   */
+  final private static String OSGI_OPT_DIR = "OSGI-OPT/";
+
+  /**
+   * File handle for file that contains current archive.
+   */
+  private FileTree file;
+
+  /**
+   * Set to true if above file is a reference outside framework storage.
+   */
+  private boolean fileIsReference = false;
+
+  /**
+   * JAR file handle for file that contains current archive.
+   */
+  private ZipFile jar;
+
+  final private String location;
+
+  /**
+   * Certificates for this archive.
+   */
+  private Certificate[] certs = null;
+
+  /**
+   * Archive's manifest
+   */
+  Manifest manifest /* = null */;
+
+  /**
+   * JAR Entry handle for file that contains current archive. If not null, it is
+   * a sub jar instead.
+   */
+  private ZipEntry subJar /* = null */;
+
+  /**
+   * Is Archive closed.
+   */
+  private boolean bClosed = false;
+
+  /**
+   *
+   */
+  private Map<String, String> nativeLibs;
+
+  /**
+   *
+   */
+  private Map<String, String> renameLibs;
+
+  /**
+   *
+   */
+  final private BundleArchiveImpl ba;
+
+  /**
+   *
+   */
+  final private int subId;
+
+
+  /**
+   * Create an Archive based on contents of an InputStream, the archive is saved
+   * as local copy in the specified directory.
+   *
+   * @param ba BundleArchiveImpl for this archive.
+   * @param dir Directory to save data in.
+   * @param rev Revision of bundle content (used for updates).
+   * @param is Jar file data in an InputStream.
+   * @param url URL to use to CodeSource.
+   * @param location Location for archive
+   */
+  Archive(BundleArchiveImpl ba, File dir, int rev, InputStream is, URL source, String location)
+      throws IOException {
+    this.location = location;
+    this.ba = ba;
+    subId = 0;
+
+    boolean isDirectory = false;
+    final FileTree sourceFile;
+    final FileTree bsFile = new FileTree(dir, ARCHIVE + rev);
+
+    if (isReference(source)) {
+      fileIsReference = true;
+      sourceFile = new FileTree(getFile(source));
+      file = sourceFile;
+    } else {
+      sourceFile = isFile(source) ? new FileTree(getFile(source)) : null;
+      file = bsFile;
+    }
+    if (sourceFile != null) {
+      isDirectory = sourceFile.isDirectory();
+      if (isDirectory) {
+        final File mfd = new File(sourceFile.getAbsolutePath(), META_INF_DIR);
+        final File mf = new File(mfd, "MANIFEST.MF");
+        final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(mf));
+        try {
+          manifest = new Manifest(bis);
+        } finally {
+          bis.close();
+        }
+      }
+    }
+
+    BufferedInputStream bis = null;
+    boolean doUnpack = false;
+    JarInputStream ji = null;
+    if (manifest == null) {
+      bis = new BufferedInputStream(is);
+      if (ba.storage.alwaysUnpack) {
+        ji = new JarInputStream(bis, ba.storage.checkSigned);
+        manifest = ji.getManifest();
+        doUnpack = true;
+      } else if (ba.storage.unpack) {
+        // Is 1000000 enough, Must be big enough to hold the MANIFEST.MF entry
+        // Hope implement of BufferedInputStream allocates dynamicly.
+        bis.mark(1000000);
+        ji = new JarInputStream(bis, ba.storage.checkSigned);
+        manifest = ji.getManifest();
+        // If manifest == null then, Manifest probably not first in JAR, should
+        // we complain?
+        // Now, try to use the jar anyway. Maybe the manifest is there.
+        if (manifest == null || !needUnpack(manifest.getMainAttributes())) {
+          bis.reset();
+        } else {
+          doUnpack = true;
+        }
+      }
+      if (doUnpack) {
+        if (ba.storage.isReadOnly()) {
+          throw new IOException("Bundle storage is read-only, no archive unpack.");
+        }
+        if (fileIsReference) {
+          fileIsReference = false;
+          file = bsFile;
+        }
+        file.mkdirs();
+        if (manifest == null) {
+          if (ba.storage.checkSigned) {
+            // TBD? Which exception to use?
+            throw new IOException("MANIFEST.MF must be first in archive when using signatures.");
+          }
+        } else {
+          final File f = new File(file, META_INF_DIR);
+          f.mkdir();
+          final FileOutputStream fo = new FileOutputStream(new File(f, "MANIFEST.MF"));
+          final BufferedOutputStream o = new BufferedOutputStream(fo);
+          try {
+            manifest.write(o);
+          } finally {
+            o.close();
+          }
+        }
+        boolean verify = ba.storage.checkSigned;
+        int verifiedEntries = 0;
+        while (processNextJarEntry(ji, verify, file)) {
+          if (verify) {
+            if (isArchiveSigned()) {
+              verifiedEntries++;
+            } else {
+              verify = false;
+            }
+          }
+        }
+        if (verify) {
+          checkCertificates(verifiedEntries);
+        }
+        jar = null;
+      }
+    }
+    if (!doUnpack) {
+      if (isDirectory) {
+        if (!fileIsReference) {
+          if (ba.storage.isReadOnly()) {
+            throw new IOException("Bundle storage is read-only, unable to save archive.");
+          }
+          sourceFile.copyTo(file);
+        }
+        if (ba.storage.checkSigned) {
+          // NYI! Verify signed directory
+        }
+        jar = null;
+      } else {
+        if (!fileIsReference) {
+          loadFile(file, bis);
+        }
+        if (ba.storage.checkSigned) {
+          processSignedJar(file);
+        }
+        jar = new ZipFile(file);
+      }
+    }
+    if (manifest != null) {
+      manifest = new AutoManifest(ba.storage.framework, manifest, location);
+    } else {
+      manifest = getManifest();
+    }
+    checkManifest();
+
+    handleAutoManifest();
+
+    saveCertificates();
+
+    if (ji != null) {
+      ji.close();
+    } else if (bis != null) {
+      bis.close();
+    }
+  }
+
+
+  /**
+   * Get the file path from an URL, handling the case where it's a
+   * reference:file: URL
+   */
+  String getFile(URL source) {
+    final String sfile = source.getFile();
+    if (sfile.startsWith("file:")) {
+      return sfile.substring(5);
+    } else {
+      return sfile;
+    }
+  }
+
+
+  boolean isFile(URL source) {
+    return source != null && "file".equals(source.getProtocol());
+  }
+
+
+  /**
+   * Check if an URL is a reference: URL or if we have global references on all
+   * file: URLs
+   */
+  boolean isReference(URL source) {
+    return (source != null)
+        && ("reference".equals(source.getProtocol()) || (ba.storage.fileReference && isFile(source)));
+  }
+
+
+  /**
+   * Create an Archive based on contents of a saved archive in the specified
+   * directory. Take lowest versioned archive and remove rest.
+   *
+   */
+  Archive(BundleArchiveImpl ba, File dir, int rev, String location) throws IOException {
+    this.location = location;
+    this.ba = ba;
+    subId = 0;
+    final String[] f = dir.list();
+    file = null;
+    if (rev != -1) {
+      file = new FileTree(dir, ARCHIVE + rev);
+    } else {
+      rev = Integer.MAX_VALUE;
+      for (final String element : f) {
+        if (element.startsWith(ARCHIVE)) {
+          try {
+            final int c = Integer.parseInt(element.substring(ARCHIVE.length()));
+            if (c < rev) {
+              rev = c;
+              file = new FileTree(dir, element);
+            }
+          } catch (final NumberFormatException ignore) {
+          }
+        }
+      }
+    }
+    for (final String element : f) {
+      if (element.startsWith(ARCHIVE)) {
+        try {
+          final int c = Integer.parseInt(element.substring(ARCHIVE.length()));
+          if (c != rev) {
+            (new FileTree(dir, element)).delete();
+          }
+        } catch (final NumberFormatException ignore) {
+        }
+      }
+      if (element.startsWith(SUBDIR)) {
+        try {
+          final int c = Integer.parseInt(element.substring(SUBDIR.length()));
+          if (c != rev) {
+            (new FileTree(dir, element)).delete();
+          }
+        } catch (final NumberFormatException ignore) {
+        }
+      }
+    }
+    if (file == null) {
+      if (location != null) {
+        try {
+          final URL url = new URL(location);
+          if (isReference(url)) {
+            file = new FileTree(getFile(url));
+          }
+        } catch (final Exception e) {
+          throw new IOException("Bad file URL stored in referenced jar in: "
+              + dir.getAbsolutePath() + ", location=" + location + ", e=" + e);
+        }
+      }
+      if (file == null || !file.exists()) {
+        throw new IOException("No saved jar file found in: " + dir.getAbsolutePath()
+            + ", old location=" + location);
+      }
+      fileIsReference = true;
+    }
+
+    if (file.isDirectory()) {
+      jar = null;
+    } else {
+      jar = new ZipFile(file);
+    }
+    if (ba.storage.checkSigned) {
+      loadCertificates();
+    }
+    if (manifest == null) {
+      manifest = getManifest();
+    }
+    handleAutoManifest();
+  }
+
+
+  /**
+   * Create a Sub-Archive based on a path to in an already existing Archive. The
+   * new archive is saved in a subdirectory below local copy of the existing
+   * Archive.
+   *
+   * @param a Parent Archive.
+   * @param path Path of new Archive inside old Archive.
+   * @exception FileNotFoundException if no such Jar file in archive.
+   * @exception IOException if failed to read Jar file.
+   */
+  Archive(Archive a, String path, int id) throws IOException {
+    this.location = a.location;
+    this.ba = a.ba;
+    subId = id;
+    if (a.jar != null) {
+      jar = a.jar;
+      // Try a directory first, make sure that path ends with "/"
+      if (!path.endsWith("/")) {
+        path += "/";
+      }
+      subJar = jar.getEntry(path);
+      if (subJar == null) {
+        subJar = jar.getEntry(path.substring(0, path.length() - 1));
+      }
+      if (subJar == null) {
+        throw new IOException("No such JAR component: " + path);
+      }
+      file = a.file;
+    } else {
+      file = findFile(a.file, path);
+      if (file.isDirectory()) {
+        jar = null;
+      } else {
+        jar = new ZipFile(file);
+      }
+    }
+  }
+
+
+  /**
+   * Show file name for archive, if zip show if it is sub archive.
+   *
+   * @return A string with result.
+   */
+  @Override
+  public String toString() {
+    if (subJar != null) {
+      return file.getAbsolutePath() + "(" + subJar.getName() + ")";
+    } else {
+      return file.getAbsolutePath();
+    }
+  }
+
+
+  /**
+   * Get revision number this archive.
+   *
+   * @return Archive revision number
+   */
+  int getRevision() {
+    try {
+      return Integer.parseInt(file.getName().substring(ARCHIVE.length()));
+    } catch (final NumberFormatException ignore) {
+      // assert?
+      return -1;
+    }
+  }
+
+
+  /**
+   * Get bundle id for this archive.
+   */
+  public BundleGeneration getBundleGeneration() {
+    return ba.getBundleGeneration();
+  }
+
+
+  /**
+   * Get sub-archive id for this archive.
+   */
+  public int getSubId() {
+    return subId;
+  }
+
+
+  /**
+   * Get an attribute from the manifest of the archive.
+   *
+   * @param key Name of attribute to get.
+   * @return A string with result or null if the entry doesn't exists.
+   */
+  String getAttribute(String key) {
+    final Attributes a = manifest.getMainAttributes();
+    if (a != null) {
+      return a.getValue(key);
+    }
+    return null;
+  }
+
+
+  /**
+   * Get a byte array containg the contents of named class file from the
+   * archive.
+   *
+   * @param Class File to get.
+   * @return Byte array with contents of class file or null if file doesn't
+   *         exist.
+   * @exception IOException if failed to read jar entry.
+   */
+  public byte[] getClassBytes(String classFile) throws IOException {
+    if (bClosed) {
+      return null;
+    }
+    final BundleResourceStream cif = getBundleResourceStream(classFile);
+    if (cif != null) {
+      byte[] bytes;
+      final long ilen = cif.getContentLength();
+      if (ilen >= 0) {
+        bytes = new byte[(int)ilen];
+        final DataInputStream dis = new DataInputStream(cif);
+        dis.readFully(bytes);
+      } else {
+        bytes = new byte[0];
+        final byte[] tmp = new byte[8192];
+        try {
+          int len;
+          while ((len = cif.read(tmp)) > 0) {
+            final byte[] oldbytes = bytes;
+            bytes = new byte[oldbytes.length + len];
+            System.arraycopy(oldbytes, 0, bytes, 0, oldbytes.length);
+            System.arraycopy(tmp, 0, bytes, oldbytes.length, len);
+          }
+        } catch (final EOFException ignore) {
+          // On Pjava we somtimes get a mysterious EOF excpetion,
+          // but everything seems okey. (SUN Bug 4040920)
+        }
+      }
+      cif.close();
+      return bytes;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * Get a BundleResourceStream to named entry inside an Archive.
+   *
+   * @param component Entry to get reference to.
+   * @return BundleResourceStream to entry or null if it doesn't exist.
+   */
+  @SuppressWarnings("resource")
+  public BundleResourceStream getBundleResourceStream(String component) {
+    if (bClosed) {
+      return null;
+    }
+    if (component.startsWith("/")) {
+      throw new RuntimeException("Assert! Path should never start with / here");
+    }
+    ZipEntry ze;
+    try {
+      if (jar != null) {
+        if (subJar != null) {
+          if (subJar.isDirectory()) {
+            ze = jar.getEntry(subJar.getName() + component);
+            if (null != ze) {
+              InputStream is = jar.getInputStream(ze);
+              if (null != is) {
+                return new BundleResourceStream(is, ze.getSize());
+              } else {
+                // Workaround for directories given without trailing
+                // "/"; they will not yield an input-stream.
+                if (!component.endsWith("/")) {
+                  final ZipEntry ze2 = jar.getEntry(subJar.getName() + component + "/");
+                  is = jar.getInputStream(ze2);
+                }
+                return new BundleResourceStream(is, ze.getSize());
+              }
+            }
+          } else {
+            if (component.equals("")) {
+              // Return a stream to the entire Jar.
+              return new BundleResourceStream(jar.getInputStream(subJar), subJar.getSize());
+            } else {
+              final JarInputStream ji = new JarInputStream(jar.getInputStream(subJar));
+              do {
+                ze = ji.getNextJarEntry();
+                if (ze == null) {
+                  ji.close();
+                  return null;
+                }
+              } while (!component.equals(ze.getName()));
+              return new BundleResourceStream(ji, ze.getSize());
+            }
+          }
+        } else {
+          if (component.equals("")) {
+            // Return a stream to the entire Jar.
+            final File f = new File(jar.getName());
+            return new BundleResourceStream(new FileInputStream(f), f.length());
+          } else {
+            ze = jar.getEntry(component);
+            if (null != ze) {
+              InputStream is = jar.getInputStream(ze);
+              if (null != is) {
+                return new BundleResourceStream(is, ze.getSize());
+              } else {
+                // Workaround for directories given without trailing
+                // "/"; they will not yield an input-stream.
+                if (!component.endsWith("/")) {
+                  final ZipEntry ze2 = jar.getEntry(component + "/");
+                  is = jar.getInputStream(ze2);
+                }
+                return new BundleResourceStream(is, ze.getSize());
+              }
+            }
+          }
+        }
+      } else {
+        final File f = findFile(file, component);
+        return f.exists() ? new BundleResourceStream(new FileInputStream(f), f.length()) : null;
+      }
+    } catch (final IOException ignore) {
+    }
+    return null;
+  }
+
+
+  public Enumeration<String> findResourcesPath(String path) {
+    if (bClosed) {
+      return null;
+    }
+    final Vector<String> answer = new Vector<String>();
+    if (jar != null) {
+      ZipEntry entry;
+      // "normalize" + erroneous path check: be generous
+      path = path.replace('\\', '/');
+      if (path.startsWith("/")) {
+        path = path.substring(1);
+      }
+      if (!path.endsWith("/")/* in case bad argument */) {
+        if (path.length() > 1) {
+          path += "/";
+        }
+      }
+
+      final Enumeration<? extends ZipEntry> entries = jar.entries();
+      while (entries.hasMoreElements()) {
+        entry = entries.nextElement();
+        final String name = entry.getName();
+        if (name.startsWith(path)) {
+          int idx = name.lastIndexOf('/');
+          if (entry.isDirectory()) {
+            idx = name.substring(0, idx).lastIndexOf('/');
+          }
+          if (idx > 0) {
+            if (name.substring(0, idx + 1).equals(path)) {
+              answer.add(name);
+            }
+          } else if (path.equals("")) {
+            answer.add(name);
+          }
+        }
+      }
+    } else {
+      final File f = findFile(file, path);
+      if (!f.exists()) {
+        return null;
+      }
+      if (!f.isDirectory()) {
+        return null;
+      }
+      final File[] files = f.listFiles();
+      final int length = files.length;
+      for (int i = 0; i < length; i++) {
+        String filePath = files[i].getPath();
+        filePath = filePath.substring(file.getPath().length() + 1);
+        filePath = filePath.replace(File.separatorChar, '/');
+        if (files[i].isDirectory()) {
+          filePath += "/";
+        }
+        answer.add(filePath);
+      }
+    }
+
+    if (answer.size() == 0) {
+      return null;
+    }
+    return answer.elements();
+  }
+
+
+  /**
+   * Get a BundleResourceStream to named entry inside an Archive.
+   *
+   * @param component Entry to get reference to.
+   * @return BundleResourceStream to entry or null if it doesn't exist.
+   */
+  public Set<String> listDir(String path) {
+    if (bClosed) {
+      return null;
+    }
+    if (path.startsWith("/")) {
+      throw new RuntimeException("Assert! Path should never start with / here");
+    }
+    try {
+      if (jar != null) {
+        if (path.length() > 0 && !path.endsWith("/")) {
+          path = path + "/";
+        }
+        if (subJar != null) {
+          if (subJar.isDirectory()) {
+            path = subJar.getName() + path;
+          } else {
+            final JarInputStream ji = new JarInputStream(jar.getInputStream(subJar));
+            return listZipDir(path, ji);
+          }
+        }
+        Set<String> res = new HashSet<String>();
+        for (Enumeration<? extends ZipEntry> ize = jar.entries(); ize.hasMoreElements(); ) {
+          ZipEntry ze = ize.nextElement();
+          String e = matchPath(path, ze.getName());
+          if (e != null) {
+            res.add(e);
+          }
+        }
+        return res;
+      } else {
+        final File f = findFile(file, path);
+        if (f.isDirectory()) {
+          Set<String> res = new HashSet<String>();
+          for (File fl : f.listFiles()) {
+            if (fl.isDirectory()) {
+              res.add(fl.getName() + "/");
+            } else {
+              res.add(fl.getName());
+            }
+          }
+          return res;
+        }
+      }
+    } catch (final IOException ignore) {
+    }
+    return null;
+  }
+
+
+  private Set<String> listZipDir(String path, final JarInputStream ji) {
+    ZipEntry ze;
+    HashSet<String> res = new HashSet<String>();
+    try {
+      for (ze = ji.getNextJarEntry(); ze != null; ) {
+        String e = matchPath(path, ze.getName());
+        if (e != null) {
+          res.add(e);
+        }
+      }
+    } catch (IOException ioe) {
+      try {
+        ji.close();
+      } catch (IOException _ignore) {
+      }
+    }
+    return res;
+  }
+
+
+  private String matchPath(String basePath, String path) {
+    final int len = basePath.length();
+    if (path.length() > len && path.startsWith(basePath)) {
+      int i = path.indexOf('/', len);
+      if (i == -1) {
+        return path.substring(len);
+      } else {
+        return path.substring(len, i + 1);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Get a BundleResourceStream to named entry inside an Archive.
+   *
+   * @param component Entry to get reference to.
+   * @return BundleResourceStream to entry or null if it doesn't exist.
+   */
+  public boolean exists(String path, boolean onlyDirs) {
+    if (bClosed) {
+      return false;
+    }
+    if (path.startsWith("/")) {
+      throw new RuntimeException("Assert! Path should never start with / here");
+    }
+    if (path.equals("")) {
+      return true;
+    }
+    ZipEntry ze;
+    try {
+      if (jar != null) {
+        if (onlyDirs && !path.endsWith("/")) {
+          path = path + "/";
+        }
+        if (subJar != null) {
+          if (subJar.isDirectory()) {
+            path = subJar.getName() + path;
+            ze = jar.getEntry(path);
+            if (null != ze) {
+              return ze.isDirectory() || !onlyDirs;
+            }
+            if (onlyDirs) {
+              return checkMatch(path);
+            }
+          } else {
+            final JarInputStream ji = new JarInputStream(jar.getInputStream(subJar));
+            try {
+              String n;
+              if (onlyDirs && !path.endsWith("/")) {
+                path = path + "/";
+              }
+              for (ze = ji.getNextJarEntry(); ze != null; ) {
+                n = ze.getName();
+                if (onlyDirs) {
+                  if (n.startsWith(path)) {
+                    return true;
+                  }
+                } else if (n.equals(path)) {
+                  return true;
+                }
+              }
+            } finally {
+              ji.close();
+            }
+          }
+        } else {
+          ze = jar.getEntry(path);
+          if (null != ze) {
+            return ze.isDirectory() || !onlyDirs;
+          }
+          if (onlyDirs) {
+            return checkMatch(path);
+          }
+        }
+      } else {
+        final File f = findFile(file, path);
+        if (f.exists()) {
+          return f.isDirectory() || !onlyDirs;
+        }
+      }
+    } catch (final IOException ignore) {
+    }
+    return false;
+  }
+
+
+  private boolean checkMatch(String path) {
+    ZipEntry ze;
+    if (!path.endsWith("/")) {
+      path = path + "/";
+    }
+    for (Enumeration<? extends ZipEntry> ize = jar.entries(); ize.hasMoreElements(); ) {
+      ze = ize.nextElement();
+      String e = matchPath(path, ze.getName());
+      if (e != null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * Check for native library in archive.
+   *
+   * @param path Name of native code file to get.
+   * @return If native library exist return libname, otherwise null.
+   */
+  public String checkNativeLibrary(String path) {
+    if (bClosed) {
+      return null; // throw new IOException("Archive is closed");
+    }
+    if (path.startsWith("/")) {
+      path = path.substring(1);
+    }
+    File lib;
+    if (jar != null) {
+      lib = getSubFile(this, path);
+      if (!lib.exists()) {
+        (new File(lib.getParent())).mkdirs();
+        final ZipEntry ze = jar.getEntry(path);
+        if (ze != null) {
+          InputStream is = null;
+          try {
+            is = jar.getInputStream(ze);
+            loadFile(lib, is);
+          } catch (final IOException _ignore) {
+            // TBD log this
+            if (is != null) {
+              try {
+                is.close();
+              } catch (final IOException _ignore2) {
+              }
+            }
+            return null;
+          }
+        } else {
+          return null;
+        }
+      }
+    } else {
+      lib = findFile(file, path);
+      if (!lib.exists()) {
+        if (lib.getParent() != null) {
+          final String libname = lib.getName();
+          final File[] list = lib.getParentFile().listFiles(new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+              final int pos = name.lastIndexOf(libname);
+              return ((pos > 1) && (name.charAt(pos - 1) == '_'));
+            }
+          });
+          if (list.length > 0) {
+            list[0].renameTo(lib);
+          } else {
+            return null;
+          }
+        } else {
+          return null;
+        }
+      }
+    }
+    setPerm(lib);
+    final String libstr = lib.getAbsolutePath();
+    final int sp = libstr.lastIndexOf(File.separatorChar);
+    final String key = (sp != -1) ? libstr.substring(sp + 1) : libstr;
+    if (nativeLibs == null) {
+      nativeLibs = new HashMap<String, String>();
+      renameLibs = new HashMap<String, String>();
+    }
+    // TBD, What to do if entry already exists?
+    nativeLibs.put(key, libstr);
+    return key;
+  }
+
+
+  /**
+   * Get native code library filename.
+   *
+   * @param libNameKey Key for native lib to get.
+   * @return A string with the path to the native library.
+   */
+  public String getNativeLibrary(String libNameKey) {
+    final String file = nativeLibs.get(libNameKey);
+    if (file != null) {
+      final File f = new File(file);
+      if (f.isFile()) {
+        return doRename(libNameKey, f);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Renaming to allow multiple versions of the lib when there are more than one
+   * classloader for this bundle. E.g., after a bundle update.
+   */
+  private String doRename(String key, File file1) {
+    String val = file1.getAbsolutePath();
+    // TODO should we fail when we are readonly
+    if (!ba.storage.isReadOnly() && renameLibs.containsKey(key)) {
+      final File file2 = new File(renameLibs.get(key));
+      if (file1.renameTo(file2)) {
+        val = file2.getAbsolutePath();
+        nativeLibs.put(key, val);
+      }
+    }
+    final StringBuffer rename = new StringBuffer(val);
+    final int index0 = val.lastIndexOf(File.separatorChar) + 1;
+    final int index1 = val.indexOf("_", index0);
+    if ((index1 > index0) && (index1 == val.length() - key.length() - 1)) {
+      try {
+        final int prefix = Integer.parseInt(val.substring(index0, index1));
+        rename.replace(index0, index1, Integer.toString(prefix + 1));
+      } catch (final Throwable t) {
+        rename.insert(index0, "0_");
+      }
+    } else {
+      rename.insert(index0, "0_");
+    }
+    renameLibs.put(key, rename.toString());
+    return val;
+  }
+
+
+  /**
+   *
+   */
+  private void setPerm(File f) {
+    // No OS-cmd for setting permissions given.
+    if (ba.storage.isReadOnly() || ba.storage.execPermCmd.length() == 0) {
+      return;
+    }
+    final String abspath = f.getAbsolutePath();
+    final String[] execarray = Util.splitwords(ba.storage.execPermCmd);
+    final String[] cmdarray;
+    int start;
+
+    // Windows systems need a "cmd /c" at the begin
+    if (ba.storage.isWindows && !execarray[0].equalsIgnoreCase("cmd")) {
+      cmdarray = new String[execarray.length + 2];
+      cmdarray[0] = "cmd";
+      cmdarray[1] = "/c";
+      start = 2;
+    } else {
+      cmdarray = new String[execarray.length];
+      start = 0;
+    }
+    for (int i = 0; i < execarray.length; i++) {
+      cmdarray[i + start] = Util.replace(execarray[i], "${abspath}", abspath);
+    }
+    try {
+      final Process p = Runtime.getRuntime().exec(cmdarray);
+      final Thread ti = new InputGlobber(null, p.getInputStream());
+      final Thread te = new InputGlobber(cmdarray, p.getErrorStream());
+      ti.start();
+      te.start();
+      while (true) {
+        try {
+          p.waitFor();
+          break;
+        } catch (final InterruptedException _ie) {
+          _ie.printStackTrace();
+        }
+      }
+      while (true) {
+        try {
+          ti.join();
+          break;
+        } catch (final InterruptedException _ie) {
+          _ie.printStackTrace();
+        }
+      }
+      while (true) {
+        try {
+          te.join();
+          break;
+        } catch (final InterruptedException _ie) {
+          _ie.printStackTrace();
+        }
+      }
+    } catch (final IOException _ioe) {
+      _ioe.printStackTrace();
+    }
+  }
+
+  // A thread class that consumes all data on an input stream and then
+  // terminates.
+  static class InputGlobber extends Thread {
+    String[] cmd;
+    final InputStream in;
+    boolean copyToStdout;
+
+
+    InputGlobber(String[] cmd, InputStream in) {
+      this.cmd = cmd;
+      this.in = in;
+      copyToStdout = cmd != null;
+    }
+
+
+    @Override
+    public void run() {
+      final BufferedReader br = new BufferedReader(new InputStreamReader(in));
+      try {
+        String line = br.readLine();
+        while (null != line) {
+          if (null != cmd) {
+            final StringBuffer sb = new StringBuffer();
+            for (final String element : cmd) {
+              if (sb.length() > 0)
+                sb.append(" ");
+              sb.append(element);
+            }
+            // NYI! Log error
+            System.err.println("Failed to execute: '" + sb.toString() + "':");
+            cmd = null;
+          }
+          if (copyToStdout)
+            System.out.println(line);
+          line = br.readLine();
+        }
+      } catch (final IOException _ioe) {
+        _ioe.printStackTrace();
+      }
+    }
+  }
+
+
+  /**
+   * Remove archive and any unpacked sub-archives.
+   */
+  void purge() {
+    close();
+    // Remove archive if not flagged as keep
+    if (!fileIsReference) {
+      file.delete();
+    }
+
+    // Remove any cached sub files
+    getSubFileTree(this).delete();
+
+    // Remove any saved certificates.
+    removeCertificates();
+  }
+
+
+  /**
+   * Close archive and all open sub-archives. If close fails it is silently
+   * ignored.
+   */
+  void close() {
+    bClosed = true; // Mark as closed to safely handle referenced files
+    if (subJar == null && jar != null) {
+      try {
+        jar.close();
+      } catch (final IOException ignore) {
+      }
+    }
+  }
+
+
+  /**
+   * Returns the path to this bundle.
+   */
+  String getPath() {
+    return file.getAbsolutePath();
+  }
+
+
+  /**
+   * Return certificates for signed bundle, otherwise null.
+   *
+   * @return An array of certificates or null.
+   */
+  Certificate[] getCertificates() {
+    return certs;
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Check that we have a valid manifest.
+   *
+   * @exception IllegalArgumentException if we have a broken manifest.
+   */
+  private void checkManifest() {
+    final Attributes a = manifest.getMainAttributes();
+    Util.parseManifestHeader(Constants.EXPORT_PACKAGE,
+                             a.getValue(Constants.EXPORT_PACKAGE), false, true,
+                             false);
+    Util.parseManifestHeader(Constants.IMPORT_PACKAGE,
+                             a.getValue(Constants.IMPORT_PACKAGE), false, true,
+                             false);
+    // NYI, more checks?
+  }
+
+
+  /**
+   * Check if we should unpack bundle, i.e has native code file or subjars. This
+   * decision is based on minimizing the expected size.
+   *
+   * @return true if bundle needs to be unpacked.
+   * @exception IllegalArgumentException if we have a broken manifest.
+   */
+  private boolean needUnpack(Attributes a) {
+    final List<HeaderEntry> nc = Util
+        .parseManifestHeader(Constants.BUNDLE_NATIVECODE,
+                             a.getValue(Constants.BUNDLE_NATIVECODE), false,
+                             false, false);
+    final String bc = a.getValue(Constants.BUNDLE_CLASSPATH);
+    return (bc != null && !bc.trim().equals(".")) || !nc.isEmpty();
+  }
+
+
+  /**
+   * Handle automanifest stuff. Archive manifest must be set.
+   */
+  private void handleAutoManifest() throws IOException {
+    // TBD Should we check this, should it not always be true!
+    if (manifest instanceof AutoManifest) {
+      final AutoManifest mf = (AutoManifest)manifest;
+      if (mf.isAuto()) {
+        if (jar != null) {
+          mf.addZipFile(jar);
+        } else if (file != null && file.isDirectory()) {
+          mf.addFile(file.getAbsolutePath(), file);
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Get file handle for file inside a directory structure. The path for the
+   * file is always specified with a '/' separated path.
+   *
+   * @param root Directory structure to search.
+   * @param path Path to file to find.
+   * @return The File object for file <code>path</code>.
+   */
+  private FileTree findFile(File root, String path) {
+    return new FileTree(root, path.replace('/', File.separatorChar));
+  }
+
+
+  /**
+   * Get the manifest for this archive.
+   *
+   * @return The manifest for this Archive
+   */
+  private AutoManifest getManifest() throws IOException {
+    // TBD: Should recognize entry with lower case?
+    final BundleResourceStream mi = getBundleResourceStream("META-INF/MANIFEST.MF");
+    if (mi != null) {
+      return new AutoManifest(ba.storage.framework, new Manifest(mi), location);
+    } else {
+      throw new IOException("Manifest is missing");
+    }
+  }
+
+
+  /**
+   * Get dir for unpacked components.
+   *
+   * @param archive Archive which contains the components.
+   * @return FileTree for archives component cache directory.
+   */
+  private FileTree getSubFileTree(Archive archive) {
+    return new FileTree(archive.file.getParent(), SUBDIR
+        + archive.file.getName().substring(ARCHIVE.length()));
+  }
+
+
+  /**
+   * Get file for an unpacked component.
+   *
+   * @param archive Archive which contains the component.
+   * @param path Name of the component to get.
+   * @return File for components cache file.
+   */
+  private File getSubFile(Archive archive, String path) {
+    return new File(getSubFileTree(archive), path.replace('/', '-'));
+  }
+
+
+  /**
+   * Loads a file from an InputStream and stores it in a file.
+   *
+   * @param output File to save data in, if <code>null</code>, discard output.
+   * @param is InputStream to read from.
+   */
+  private void loadFile(File output, InputStream is) throws IOException {
+    if (ba.storage.isReadOnly()) {
+      throw new IOException("Bundle storage is read-only, unable to save: " + output);
+    }
+    OutputStream os = null;
+    try {
+      if (output != null) {
+        os = new FileOutputStream(output);
+      }
+      final byte[] buf = new byte[8192];
+      int n;
+      try {
+        while ((n = is.read(buf)) >= 0) {
+          if (os != null) {
+            os.write(buf, 0, n);
+          }
+        }
+      } catch (final EOFException ignore) {
+        // On Pjava we sometimes get a mysterious EOF exception,
+        // but everything seems okey. (SUN Bug 4040920)
+      }
+    } catch (final IOException e) {
+      if (os != null) {
+        output.delete();
+      }
+      throw e;
+    } finally {
+      if (os != null) {
+        os.close();
+      }
+    }
+  }
+
+
+  /**
+   * Check if archive is signed
+   */
+  private boolean isArchiveSigned() {
+    return certs != null;
+  }
+
+
+  /**
+   *
+   */
+  private boolean processNextJarEntry(JarInputStream ji, boolean verify, File saveDir)
+      throws IOException {
+    JarEntry je;
+    while ((je = ji.getNextJarEntry()) != null) {
+      if (je.isDirectory()) {
+        continue;
+      }
+      final String name = je.getName();
+      if (saveDir != null && !startsWithIgnoreCase(name, OSGI_OPT_DIR)) {
+        final StringTokenizer st = new StringTokenizer(name, "/");
+        File f = new File(saveDir, st.nextToken());
+        while (st.hasMoreTokens()) {
+          f.mkdir();
+          f = new File(f, st.nextToken());
+        }
+        loadFile(f, ji);
+      } else {
+        // Read entry to update certificates.
+        loadFile(null, ji);
+      }
+      ji.closeEntry();
+      if (startsWithIgnoreCase(name, META_INF_DIR)) {
+        String sub = name.substring(META_INF_DIR.length());
+        if (sub.indexOf('/') == -1) {
+          if (startsWithIgnoreCase(sub, "SIG-")) {
+            continue;
+          }
+          int idx = sub.lastIndexOf('.');
+          if (idx != -1) {
+            sub = sub.substring(idx + 1);
+            if (sub.equalsIgnoreCase("DSA") ||
+                sub.equalsIgnoreCase("RSA") ||
+                sub.equalsIgnoreCase("SF")) {
+              continue;
+            }
+          }
+        }
+        if (ba.storage.jarVerifierBug) {
+          // There is a bug in Oracles java library.
+          // JavaInputStream will verify files in
+          // META-INF if they directly follow the META-INF
+          // signature related files.
+          if (certs == null) {
+            certs = new Certificate[0];
+            verify = false;
+          } else if (certs.length == 0) {
+            verify = false;
+          }
+        }
+      }
+      if (verify) {
+        final Certificate[] c = je.getCertificates();
+        if (c != null) {
+          if (certs != null && certs.length > 0) {
+            // TBD, perhaps we should allow permuted chains.
+            if (!Arrays.equals(c, certs)) {
+              certs = null;
+            }
+          } else {
+            certs = c;
+          }
+        } else {
+          certs = null;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * Check if <code>name</code> start with <code>prefix</code> ignoring
+   * case of letters.
+   * 
+   * @param name String to check
+   * @param prefix Prefix string, must be in upper case.
+   * 
+   * @return <code>true</code> if name start with prefix, otherwise
+   *         <code>false</code>
+   */
+  private boolean startsWithIgnoreCase(final String name, final String prefix) {
+    if (name.length() >= prefix.length()) {
+      for (int i = 0; i < prefix.length(); i++) {
+        if (Character.toUpperCase(name.charAt(i)) != prefix.charAt(i)) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * Go through jar file and check signatures.
+   */
+  private void processSignedJar(File file) throws IOException {
+    final FileInputStream fis = new FileInputStream(file);
+    JarInputStream ji = null;
+    try {
+      final BufferedInputStream bis = new BufferedInputStream(fis);
+      ji = new JarInputStream(bis);
+      int count = 0;
+
+      manifest = ji.getManifest();
+
+      while (processNextJarEntry(ji, true, null)) {
+        if (isArchiveSigned()) {
+          count++;
+        } else {
+          break;
+        }
+      }
+      checkCertificates(count);
+    } finally {
+      if (ji != null) {
+        ji.close();
+      } else {
+        fis.close();
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  private void checkCertificates(int filesVerified) {
+    if (filesVerified > 0) {
+      Exception warn = null;
+      if (certs != null) {
+        if (certs.length > 0) {
+          // TODO, check that we have all entries in .SF file
+          return;
+        } else {
+          warn = new IOException("Only contained META-INF entries with no certs due to JRE bug. Entries found " + filesVerified);          
+        }
+      } else {
+        warn = new IOException("All entries in bundle not completly signed, scan aborted");
+      }
+      certs = null;
+      ba.frameworkWarning(warn);
+    }
+  }
+
+
+  /**
+   *
+   */
+  private void saveCertificates() throws IOException {
+    if (!ba.storage.isReadOnly()) {
+      final File f = new File(getPath() + CERTS_SUFFIX);
+      if (certs != null) {
+        try {
+          final FileOutputStream fos = new FileOutputStream(f);
+          for (final Certificate cert : certs) {
+            fos.write(cert.getEncoded());
+          }
+          fos.close();
+        } catch (final CertificateEncodingException e) {
+          ba.frameworkWarning(e);
+        }
+      }
+    }
+  }
+
+
+  /**
+   * TBD improve this.
+   */
+  private void loadCertificates() throws IOException {
+    final File f = new File(getPath() + CERTS_SUFFIX);
+    if (f.canRead()) {
+      try {
+        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        final FileInputStream fis = new FileInputStream(f);
+        final Collection<? extends Certificate> c = cf.generateCertificates(fis);
+        // TBD, check if order is preserved
+        if (c.size() > 0) {
+          certs = new Certificate[c.size()];
+          certs = c.toArray(certs);
+        }
+      } catch (final CertificateException e) {
+        ba.frameworkWarning(e);
+      }
+    }
+    // TODO, load certificates from both trusted and untrusted storage!?
+  }
+
+
+  /**
+   *
+   */
+  private void removeCertificates() {
+    final File f = new File(getPath() + CERTS_SUFFIX);
+    f.delete();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleArchiveImpl.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleArchiveImpl.java
new file mode 100644
index 0000000..511c548
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleArchiveImpl.java
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage.file;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+
+import org.knopflerfish.framework.BundleArchive;
+import org.knopflerfish.framework.BundleGeneration;
+import org.knopflerfish.framework.BundleResourceStream;
+import org.knopflerfish.framework.FileArchive;
+import org.knopflerfish.framework.FileTree;
+import org.knopflerfish.framework.HeaderDictionary;
+import org.knopflerfish.framework.bundlestorage.Util;
+
+/**
+ * Interface for managing bundle data.
+ *
+ * @author Jan Stein
+ * @author Erik Wistrand
+ * @author Robert Shelley
+ * @author Philippe Laporte
+ * @author Mats-Ola Persson
+ */
+class BundleArchiveImpl implements BundleArchive
+{
+
+  /**
+   * Bundle status files
+   */
+  private final static String LOCATION_FILE      = "location";
+  private final static String REV_FILE           = "revision";
+  private final static String AUTOSTART_FILE     = "autostart";
+  private final static String STARTLEVEL_FILE    = "startlevel";
+  private final static String LAST_MODIFIED_FILE = "lastModifed";
+
+
+  final BundleStorageImpl storage;
+
+  private final Archive archive;
+
+  private BundleGeneration bundleGeneration = null;
+
+  private final long id;
+
+  final private String location;
+
+  private int autostartSetting = -1; // => not started.
+
+  private final FileTree bundleDir;
+
+  private ArrayList<Archive> archives;
+
+  private int startLevel = -1;
+
+  private long lastModified = 0;
+
+  private ArrayList<List<X509Certificate>> trustedCerts = null;
+
+  private ArrayList<List<X509Certificate>> untrustedCerts = null;
+
+  private boolean checkCerts = true;
+  
+  private ArrayList<Exception> warnings = null;
+
+
+  /**
+   * Construct new bundle archive.
+   *
+   */
+  BundleArchiveImpl(BundleStorageImpl bundleStorage,
+                    FileTree          dir,
+                    InputStream       is,
+                    String            bundleLocation,
+                    long              bundleId)
+    throws Exception
+  {
+    URL source = null;
+    try {
+      source = new URL(bundleLocation);
+    } catch (final Exception e) {
+    }
+    bundleDir        = dir;
+    storage          = bundleStorage;
+    id               = bundleId;
+    location         = bundleLocation;
+    archive          = new Archive(this, bundleDir, 0, is, source, location);
+    putContent(LOCATION_FILE, location);
+  }
+
+  /**
+   * Construct new bundle archive based on saved data.
+   *
+   */
+  BundleArchiveImpl(BundleStorageImpl bundleStorage, FileTree dir, long bundleId)
+    throws Exception
+  {
+    bundleDir = dir;
+    location = getContent(LOCATION_FILE);
+    if (location == null || location.length() == 0) {
+      throw new IOException("No bundle location information found");
+    }
+    int rev = -1;
+    String s = getContent(REV_FILE);
+    if (s != null) {
+      try {
+        rev = Integer.parseInt(s);
+      } catch (final NumberFormatException e) { }
+    }
+
+    s = getContent(STARTLEVEL_FILE);
+    if (s != null) {
+      try {
+        startLevel = Integer.parseInt(s);
+      } catch (final NumberFormatException e) { }
+    }
+
+    s = getContent(LAST_MODIFIED_FILE);
+    if (s != null) {
+        try {
+                lastModified = Long.parseLong(s);
+        }
+        catch (final NumberFormatException ignore) {}
+    }
+
+    s = getContent(AUTOSTART_FILE);
+    if (s != null) {
+      try {
+        autostartSetting = Integer.parseInt(s);
+      } catch (final NumberFormatException ignore) {}
+    }
+
+    id            = bundleId;
+    storage       = bundleStorage;
+    archive       = new Archive(this, bundleDir, rev, location);
+  }
+
+
+  /**
+   * Construct new bundle archive in an existing bundle archive.
+   *
+   */
+  BundleArchiveImpl(BundleArchiveImpl old, InputStream is)
+    throws Exception
+  {
+    bundleDir = old.bundleDir;
+    location = old.location;
+    storage = old.storage;
+    id = old.id;
+    autostartSetting = old.autostartSetting;
+    final int rev = old.archive.getRevision() + 1;
+    URL source = null;
+
+    final boolean bReference = (is == null);
+    if(bReference) {
+      source = new URL(location);
+    }
+    archive = new Archive(this, bundleDir, rev, is, source, location);
+    if(!bReference) {
+      putContent(REV_FILE, Integer.toString(rev));
+    }
+  }
+
+
+  /**
+   * Get an attribute from the manifest of a bundle.
+   *
+   * @param key Name of attribute to get.
+   * @return A string with result or null if the entry doesn't exists.
+   */
+  public String getAttribute(String key) {
+    return archive.getAttribute(key);
+  }
+
+
+
+  /**
+   * Get a FileArchive handle to a named Jar file or directory
+   * within this archive.
+   *
+   * @param path Name of Jar file or directory to get.
+   * @return A FileArchive object representing new archive, null if not found.
+   * @exception IOException if we failed to get top of file archive.
+   */
+  public FileArchive getFileArchive(String path) {
+    if (".".equals(path)) {
+      return archive;
+    }
+    if (archives == null) {
+      archives = new ArrayList<Archive>();
+    }
+    try {
+      final Archive a = new Archive(archive, path, archives.size() + 1);
+      archives.add(a);
+      return a;
+    } catch (final IOException io) {
+      // TBD, Where to log this
+      return null;
+    }
+  }
+
+
+  /**
+   * returns the localization entries of this archive.
+   */
+  public Hashtable<String, String> getLocalizationEntries(String localeFile) {
+    final BundleResourceStream aif = archive.getBundleResourceStream(localeFile);
+    if (aif != null) {
+      final Properties l = new Properties();
+      try {
+        l.load(aif);
+      } catch (final IOException _ignore) { }
+      try {
+        aif.close();
+      } catch (final IOException _ignore) { }
+      @SuppressWarnings("rawtypes")
+      final
+      Hashtable ht = l;
+      @SuppressWarnings("unchecked")
+      final
+      Hashtable<String, String> res = ht;
+      return res;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * returns the raw unlocalized entries of this archive.
+   */
+  public HeaderDictionary getUnlocalizedAttributes() {
+    return new HeaderDictionary(archive.manifest.getMainAttributes());
+  }
+
+
+  /**
+   * Get bundle generation associated with this bundle archive.
+   *
+   * @return BundleGeneration object.
+   */
+  public BundleGeneration getBundleGeneration() {
+    return bundleGeneration;
+  }
+
+
+  /**
+   * Set bundle generation associated with this bundle archive.
+   *
+   * @param BundleGeneration object.
+   */
+  public void setBundleGeneration(BundleGeneration bg) {
+    bundleGeneration = bg;
+    if (warnings != null) {
+      for (Exception w : warnings) {
+        frameworkWarning(w);
+      }
+      warnings = null;
+    }
+  }
+
+
+  /**
+   * Get bundle identifier for this bundle archive.
+   *
+   * @return Bundle identifier.
+   */
+  public long getBundleId() {
+    return id;
+  }
+
+
+  /**
+   * Get bundle location for this bundle archive.
+   *
+   * @return Bundle location.
+   */
+  public String getBundleLocation() {
+    return location;
+  }
+
+
+  /**
+   *
+   */
+  public int getStartLevel() {
+    return startLevel;
+  }
+
+
+  /**
+   *
+   */
+  public void setStartLevel(int level) throws IOException {
+    if (startLevel != level) {
+      startLevel = level;
+      putContent(STARTLEVEL_FILE, Integer.toString(startLevel));
+    }
+  }
+
+
+  /**
+   *
+   */
+  public long getLastModified() {
+    return lastModified;
+  }
+
+
+  /**
+   *
+   */
+  public void setLastModified(long timemillisecs) throws IOException{
+    lastModified = timemillisecs;
+    putContent(LAST_MODIFIED_FILE, Long.toString(timemillisecs));
+  }
+
+
+  /**
+   * Get a BundleResourceStream to named entry inside a bundle.
+   * Leading '/' is stripped.
+   *
+   * @param component Entry to get reference to.
+   * @param ix index of sub archives. A postive number is the classpath entry
+   *            index. 0 means look in the main bundle.
+   * @return BundleResourceStream to entry or null if it doesn't exist.
+   */
+  public BundleResourceStream getBundleResourceStream(String component, int ix) {
+    if (component.startsWith("/")) {
+      component = component.substring(1);
+    }
+    if (ix == 0) {
+      return archive.getBundleResourceStream(component);
+    } else {
+      return archives.get(ix - 1).getBundleResourceStream(component);
+    }
+  }
+
+
+  /**
+   * Get autostart setting.
+   *
+   * @return the autostart setting.
+   */
+  public int getAutostartSetting() {
+    return autostartSetting;
+  }
+
+
+  /**
+   * Set autostart setting.
+   *
+   * @param setting the new autostart setting.
+   */
+  public void setAutostartSetting(int setting) throws IOException {
+    if (setting != autostartSetting) {
+      autostartSetting = setting;
+      putContent(AUTOSTART_FILE, String.valueOf(autostartSetting));
+    }
+  }
+
+
+  /**
+   */
+  public Enumeration<String> findResourcesPath(String path) {
+    return archive.findResourcesPath(path);
+  }
+
+
+  /**
+   */
+  public String getJarLocation() {
+    return archive.getPath();
+  }
+
+
+  /**
+   * Return certificates for signed bundle, otherwise null.
+   *
+   * @return An array of certificates or null.
+   */
+  public ArrayList<List<X509Certificate>> getCertificateChains(boolean onlyTrusted) {
+    if (checkCerts) {
+      final Certificate [] c = archive.getCertificates();
+      checkCerts = false;
+      if (c != null) {
+        final ArrayList<Certificate> failed = new ArrayList<Certificate>();
+        untrustedCerts = Util.getCertificateChains(c, failed);
+        if (!failed.isEmpty()) {
+          // NYI, log Bundle archive has invalid certificates
+          untrustedCerts = null;
+        }
+      }
+    }
+    ArrayList<List<X509Certificate>> res = trustedCerts;
+    if (!onlyTrusted && untrustedCerts != null) {
+      if (res == null) {
+        res = untrustedCerts;
+      } else {
+        res = new ArrayList<List<X509Certificate>>(trustedCerts.size() + untrustedCerts.size());
+        res.addAll(trustedCerts);
+        res.addAll(untrustedCerts);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Mark certificate chain as trusted.
+   *
+   */
+  public void trustCertificateChain(List<X509Certificate> trustedChain) {
+    if (trustedCerts == null) {
+      trustedCerts = new ArrayList<List<X509Certificate>>(untrustedCerts.size());
+    }
+    trustedCerts.add(trustedChain);
+    untrustedCerts.remove(trustedChain);
+    if (untrustedCerts.isEmpty()) {
+      untrustedCerts = null;
+    }
+  }
+
+
+  /**
+   * Remove bundle archive from persistent storage. If we removed
+   * the active revision also remove bundle status files.
+   */
+  public void purge() {
+    close();
+    if (!storage.isReadOnly()) {
+      if (storage.removeArchive(this)) {
+        (new File(bundleDir, LOCATION_FILE)).delete();
+        (new File(bundleDir, AUTOSTART_FILE)).delete();
+        (new File(bundleDir, REV_FILE)).delete();
+        (new File(bundleDir, STARTLEVEL_FILE)).delete();
+        (new File(bundleDir, LAST_MODIFIED_FILE)).delete();
+      }
+      archive.purge();
+      if (bundleDir.list().length == 0) {
+        bundleDir.delete();
+      }
+    }
+  }
+
+
+  /**
+   * Close archive for further access. It should still be possible
+   * to get attributes.
+   */
+  public void close() {
+    if (archives != null) {
+      for (final Archive archive2 : archives) {
+        archive2.close();
+      }
+      archives = null;
+    }
+    archive.close();
+  }
+
+  void frameworkWarning(Exception warn) {
+    if (bundleGeneration != null) {
+      storage.framework.frameworkWarning(bundleGeneration, warn);
+    } else {
+      if (warnings == null) {
+        warnings = new ArrayList<Exception>();
+      }
+      warnings.add(warn);
+    }
+  }
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Statically check if a directory contains info that a bundle
+   * is uninstalled.
+   *
+   * <p>
+   * Uninstalled is marked via a startlevel of -2. If last modified
+   * file is not available then the bundle is not complete.
+   * </p>
+   */
+  static boolean isUninstalled(File dir) {
+    String s = getContent(dir, LAST_MODIFIED_FILE);
+    if (s == null || s.length() == 0) {
+      return true;
+    }
+    s = getContent(dir, STARTLEVEL_FILE);
+    int n = -1;
+    try {
+      n = Integer.parseInt(s);
+    } catch (final Exception e) {
+    }
+    return n == -2;
+  }
+
+
+  /**
+   *
+   */
+  static String getContent(File dir, String f) {
+    DataInputStream in = null;
+    try {
+      in = new DataInputStream(new FileInputStream(new File(dir, f)));
+      return in.readUTF();
+    } catch (final IOException ignore) {
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) { }
+      }
+    }
+    return null;
+  }
+
+
+  //
+  // Private methods
+  //
+  
+  /**
+   * Read content of file as a string.
+   *
+   * @param f File to read from
+   * @return contents of the file as a single String
+   */
+  private String getContent(String f) {
+    DataInputStream in = null;
+    try {
+      in = new DataInputStream(new FileInputStream(new File(bundleDir, f)));
+      return in.readUTF();
+    } catch (final IOException ignore) {
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) { }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Write string to named file.
+   *
+   * @param f File to write too
+   * @param contenet String to write
+   * @exception IOException if we fail to save our string
+   */
+  private void putContent(String f, String content) throws IOException {
+    if (!storage.isReadOnly()) {
+      DataOutputStream out = null;
+      try {
+        out = new DataOutputStream(new FileOutputStream(new File(bundleDir, f)));
+        out.writeUTF(content);
+      } finally {
+        if (out != null) {
+          out.close();
+        }
+      }
+    }
+  }
+
+}//class
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleStorageImpl.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleStorageImpl.java
new file mode 100644
index 0000000..39b0fc9
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/file/BundleStorageImpl.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2003-2014, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage.file;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.osgi.framework.Constants;
+import org.knopflerfish.framework.BundleArchive;
+import org.knopflerfish.framework.BundleStorage;
+import org.knopflerfish.framework.FWProps;
+import org.knopflerfish.framework.FileTree;
+import org.knopflerfish.framework.FrameworkContext;
+import org.knopflerfish.framework.Util;
+
+
+/**
+ * Storage of all bundles jar content.
+ *
+ * @author Jan Stein, Mats-Ola Persson, Gunnar Ekolin
+ */
+public class BundleStorageImpl implements BundleStorage {
+
+  public final static String ALWAYS_UNPACK_PROP =
+    "org.knopflerfish.framework.bundlestorage.file.always_unpack";
+  public final static String REFERENCE_PROP =
+    "org.knopflerfish.framework.bundlestorage.file.reference";
+  public final static String TRUSTED_PROP =
+    "org.knopflerfish.framework.bundlestorage.file.trusted";
+  public final static String UNPACK_PROP =
+    "org.knopflerfish.framework.bundlestorage.file.unpack";
+  public final static String JAR_VERIFIER_BUG_PROP =
+    "org.knopflerfish.framework.bundlestorage.file.jar_verifier_bug";
+
+  /**
+   * Controls if we should try to unpack bundles with sub-jars and
+   * native code.
+   */
+  boolean alwaysUnpack;
+
+  /**
+   * Controls if file: URLs should be referenced only, not copied
+   * to bundle storage dir
+   */
+  boolean fileReference;
+
+  /**
+   * Controls if we should trust file storage to be secure.
+   */
+  boolean trustedStorage;
+
+  /**
+   * Controls if we should try to unpack bundles with sub-jars and
+   * native code.
+   */
+  boolean unpack;
+
+  /**
+   * Optional OS-command to set executable permission on native code.
+   */
+  String execPermCmd;
+
+  /**
+   * Is current OS a Windows OS.
+   */
+  boolean isWindows;
+
+  /**
+   * Is JarVerifier bug present.
+   */
+  boolean jarVerifierBug;
+
+  /**
+   * Top directory for storing all jar data for bundles.
+   */
+  private FileTree bundlesDir;
+
+  /**
+   * Next available bundle id.
+   */
+  private long nextFreeId = 1;
+
+  /**
+   * Bundle id sorted list of all active bundle archives.
+   */
+  private final ArrayList<BundleArchive> archives = new ArrayList<BundleArchive>();
+
+  /**
+   * Framework handle.
+   * Package protected to allow BundleArchiveImpl to get framework.
+   */
+  FrameworkContext     framework;
+
+  /**
+   * If we should check if bundles are signed
+   */
+  boolean checkSigned;
+
+  /**
+   * True if we shouldn't write any files.
+   */
+  private boolean readOnly;
+
+  /**
+   * Create a container for all bundle data in this framework.
+   * Try to restore all saved bundle archive state.
+   *
+   */
+  public BundleStorageImpl(FrameworkContext framework) {
+    this.framework = framework;
+    initProps(framework.props);
+    // See if we have a storage directory
+    bundlesDir = Util.getFileStorage(framework, "bs", !isReadOnly());
+    if (bundlesDir == null) {
+      throw new RuntimeException("No bundle storage area available!");
+    }
+    // Restore all saved bundles
+    final String [] list = bundlesDir.list();
+    for (int i = 0; list != null && i < list.length; i++) {
+      long id;
+      try {
+        id = Long.parseLong(list[i]);
+      } catch (final NumberFormatException e) {
+        continue;
+      }
+      if (id == 0) {
+        System.err.println("Saved bundle with illegal id 0 is ignored.");
+      }
+      final int pos = find(id);
+      if (pos < archives.size() && archives.get(pos).getBundleId() == id) {
+        System.err.println("There are two bundle directories with id: " + id);
+        break;
+      }
+      final FileTree dir = new FileTree(bundlesDir, list[i]);
+      if (dir.isDirectory()) {
+        try {
+          final boolean bUninstalled = BundleArchiveImpl.isUninstalled(dir);
+          if(bUninstalled) {
+            // silently remove any bundle marked as uninstalled
+            dir.delete();
+          } else {
+            final BundleArchive ba = new BundleArchiveImpl(this, dir, id);
+            archives.add(pos, ba);
+          }
+          if (id >= nextFreeId) {
+            nextFreeId = id + 1;
+          }
+        } catch (final Exception e) {
+          dir.delete();
+          System.err.println("Removed corrupt bundle dir (" + e.getMessage() + "): " + dir);
+        }
+      }
+    }
+  }
+
+
+  /**
+   * Insert bundle into persistent storage
+   *
+   * @param location Location of bundle.
+   * @param is Inputstrem with bundle content.
+   * @return Bundle archive object.
+   */
+  public BundleArchive insertBundleJar(String location, InputStream is)
+    throws Exception
+  {
+    final long id = nextFreeId++;
+    final FileTree dir = isReadOnly() ? null : new FileTree(bundlesDir, String.valueOf(id));
+    if (dir != null) {
+      if (dir.exists()) {
+        // remove any old garbage
+        dir.delete();
+      }
+      dir.mkdir();
+    }
+    try {
+      final BundleArchive ba = new BundleArchiveImpl(this, dir, is, location, id);
+      archives.add(ba);
+      return ba;
+    } catch (final Exception e) {
+      if (dir != null) {
+        dir.delete();
+      }
+      throw e;
+    }
+  }
+
+
+  /**
+   * Insert a new jar file into persistent storagedata as an update
+   * to an existing bundle archive. To commit this data a call to
+   * <code>replaceBundleArchive</code> is needed.
+   *
+   * @param old BundleArchive to be replaced.
+   * @param is Inputstrem with bundle content.
+   * @return Bundle archive object.
+   */
+  public BundleArchive updateBundleArchive(BundleArchive old, InputStream is)
+    throws Exception
+  {
+    return new BundleArchiveImpl((BundleArchiveImpl)old, is);
+  }
+
+
+  /**
+   * Replace old bundle archive with a new updated bundle archive, that
+   * was created with updateBundleArchive.
+   *
+   * @param oldBA BundleArchive to be replaced.
+   * @param newBA Inputstrem with bundle content.
+   * @return New bundle archive object.
+   */
+  public void replaceBundleArchive(BundleArchive oldBA, BundleArchive newBA)
+    throws Exception
+  {
+    int pos;
+    final long id = oldBA.getBundleId();
+    synchronized (archives) {
+      pos = find(id);
+      if (pos >= archives.size() || archives.get(pos) != oldBA) {
+        throw new Exception("replaceBundleJar: Old bundle archive not found, pos=" + pos);
+      }
+      archives.set(pos, newBA);
+    }
+  }
+
+
+  /**
+   * Get all bundle archive objects.
+   *
+   * @return Private array of all BundleArchives.
+   */
+  public BundleArchive [] getAllBundleArchives() {
+    synchronized (archives) {
+      return archives.toArray(new BundleArchive[archives.size()]);
+    }
+  }
+
+
+  /**
+   * Get all bundles to start at next launch of framework.
+   * This list is sorted in increasing bundle id order.
+   *
+   * @return Private copy of a List with bundle id's.
+   */
+  public List<String> getStartOnLaunchBundles() {
+    final ArrayList<String> res = new ArrayList<String>();
+    for (final BundleArchive ba : archives) {
+      if (ba.getAutostartSetting()!=-1) {
+        res.add(ba.getBundleLocation());
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Close bundle storage.
+   *
+   */
+  public void close()
+  {
+    for (final Iterator<BundleArchive> i = archives.iterator(); i.hasNext(); ) {
+      final BundleArchive ba = i.next();
+      ba.close();
+      i.remove();
+    }
+    framework = null;
+    bundlesDir = null;
+  }
+
+  //
+  // Package methods
+  //
+
+  boolean isReadOnly() {
+    return readOnly;
+  }
+
+
+  /**
+   * Remove bundle archive from archives list.
+   *
+   * @param id Bundle archive id to find.
+   * @return true if element was removed.
+   */
+  boolean removeArchive(BundleArchive ba) {
+    synchronized (archives) {
+      final int pos = find(ba.getBundleId());
+      if (pos < archives.size() && archives.get(pos) == ba) {
+        archives.remove(pos);
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Initialize values for properties.
+   *
+   */
+  private void initProps(FWProps props) {
+    props.setPropertyDefault(ALWAYS_UNPACK_PROP, FWProps.FALSE);
+    props.setPropertyDefault(REFERENCE_PROP, FWProps.FALSE);
+    props.setPropertyDefault(TRUSTED_PROP, FWProps.TRUE);
+    props.setPropertyDefault(UNPACK_PROP, FWProps.TRUE);
+    props.setPropertyDefault(JAR_VERIFIER_BUG_PROP, FWProps.FALSE);
+    alwaysUnpack = props.getBooleanProperty(ALWAYS_UNPACK_PROP);
+    fileReference = props.getBooleanProperty(REFERENCE_PROP);
+    trustedStorage = props.getBooleanProperty(TRUSTED_PROP);
+    unpack = props.getBooleanProperty(UNPACK_PROP);
+    execPermCmd = props.getProperty(Constants.FRAMEWORK_EXECPERMISSION).trim();
+    checkSigned = props.getBooleanProperty(FWProps.BUNDLESTORAGE_CHECKSIGNED_PROP);
+    isWindows = props.getProperty(Constants.FRAMEWORK_OS_NAME).startsWith("Windows");
+    jarVerifierBug = props.getBooleanProperty(JAR_VERIFIER_BUG_PROP);
+    readOnly = props.getBooleanProperty(FWProps.READ_ONLY_PROP);
+   }
+
+
+  /**
+   * Find posisition for BundleArchive with specified id
+   *
+   * @param id Bundle archive id to find.
+   * @return String to write
+   */
+  private int find(long id) {
+    int lb = 0;
+    int ub = archives.size() - 1;
+    int x = 0;
+    while (lb < ub) {
+      x = (lb + ub) / 2;
+      final long xid = archives.get(x).getBundleId();
+      if (id == xid) {
+        return x;
+      } else if (id < xid) {
+        ub = x;
+      } else {
+        lb = x+1;
+      }
+    }
+    if (lb < archives.size() && archives.get(lb).getBundleId() < id) {
+      return lb + 1;
+    }
+    return lb;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/Archive.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/Archive.java
new file mode 100644
index 0000000..82fde41
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/Archive.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage.memory;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.knopflerfish.framework.BundleGeneration;
+import org.knopflerfish.framework.BundleResourceStream;
+import org.knopflerfish.framework.FileArchive;
+
+/**
+ * JAR file handling.
+ *
+ * @author Jan Stein
+ * @author Philippe Laporte
+ */
+class Archive implements FileArchive {
+
+  /**
+   *
+   */
+  final private BundleArchiveImpl ba;
+
+  /**
+   * Archives manifest
+   */
+  Manifest manifest;
+
+  /**
+   * JAR Entry handle for file that contains current archive. If not null, it is
+   * a sub jar instead.
+   */
+  protected HashMap<String, byte[]> content;
+
+  ArrayList<String> subDirs/* = null */;
+
+  final String path;
+
+
+  /**
+   * Create an Archive based on contents of an InputStream, get file object for
+   * the stream and use it. Native code is not allowed.
+   *
+   * @param is Jar file data in an InputStream.
+   */
+  @SuppressWarnings("resource") // The input stream, is, must not be closed here.
+  Archive(BundleArchiveImpl ba, InputStream is) throws IOException {
+    this.ba = ba;
+    path = ".";
+    final JarInputStream ji = new JarInputStream(is);
+    manifest = ji.getManifest();
+    if (manifest == null) {
+      throw new IOException("Bundle manifest is missing");
+    }
+    content = loadJarStream(ji);
+  }
+
+
+  /**
+   * Create a Sub-Archive based on a path to in an already existing Archive. The
+   * new archive is saved in a subdirectory below local copy of the existing
+   * Archive.
+   *
+   * @param a Parent Archive.
+   * @param path Path of new Archive inside old Archive.
+   * @exception FileNotFoundException if no such Jar file in archive.
+   * @exception IOException if failed to read Jar file.
+   */
+  Archive(Archive a, String path) throws IOException {
+    ba = a.ba;
+    this.path = path;
+    if (null != path && path.length() > 0 && '/' == path.charAt(0)) {
+      path = path.substring(1);
+    }
+    final byte[] bs = a.content.remove(path);
+    if (bs != null) {
+      final JarInputStream ji = new JarInputStream(new ByteArrayInputStream(bs));
+      content = loadJarStream(ji);
+    } else {
+      throw new FileNotFoundException("No such file: " + path);
+    }
+  }
+
+
+  /**
+   * Get bundle id for this archive.
+   */
+  public BundleGeneration getBundleGeneration() {
+    return ba.getBundleGeneration();
+  }
+
+
+  /**
+   * Get sub-archive id for this archive.
+   */
+  public int getSubId() {
+    return 0;
+  }
+
+
+  /**
+   * Get an attribute from the manifest of the archive.
+   *
+   * @param key Name of attribute to get.
+   * @return A string with result or null if the entry doesn't exists.
+   */
+  String getAttribute(String key) {
+    return manifest.getMainAttributes().getValue(key);
+  }
+
+
+  /**
+   * Get a byte array containing the contents of named file from the archive.
+   *
+   * @param component File to get.
+   * @return Byte array with contents of file or null if file doesn't exist.
+   * @exception IOException if failed to read jar entry.
+   */
+  public byte[] getClassBytes(String classFile) throws IOException {
+    byte[] bytes;
+    if ((bytes = content.remove(classFile)) == null) {
+      if (subDirs == null) {
+        return null;
+      }
+      final Iterator<String> it = subDirs.iterator();
+      boolean found = false;
+      while (it.hasNext()) {
+        final String subDir = it.next();
+        bytes = content.remove(subDir + "/" + classFile);
+        if (bytes != null) {
+          found = true;
+          break;
+        }
+      }
+      if (!found) {
+        return null;
+      }
+    }
+    return bytes;
+  }
+
+
+  /**
+   * Get an InputStream to named entry inside an Archive.
+   *
+   * @param component Entry to get reference to.
+   * @return InputStream to entry or null if it doesn't exist.
+   */
+  public BundleResourceStream getBundleResourceStream(String component) {
+    if (component.startsWith("/")) {
+      component = component.substring(1);
+    }
+    final byte[] b = content.get(component);
+    if (b != null) {
+      return new BundleResourceStream(new ByteArrayInputStream(b), b.length);
+    } else {
+      return null;
+    }
+  }
+
+
+  // Known issues: see FrameworkTestSuite Frame068a and Frame211a. Seems like
+  // the manifest
+  // gets skipped (I guess in getNextJarEntry in loadJarStream) for some reason
+  // investigate further later
+  public Enumeration<String> findResourcesPath(String path) {
+    final Vector<String> answer = new Vector<String>();
+    // "normalize" + erroneous path check: be generous
+    path = path.replace('\\', '/');
+    if (path.startsWith("/")) {
+      path = path.substring(1);
+    }
+    if (!path.endsWith("/") /* in case bad argument */) {
+      if (path.length() > 1) {
+        path += "/";
+      }
+    }
+
+    final Iterator<String> it = content.keySet().iterator();
+    while (it.hasNext()) {
+      final String entry = it.next();
+      if (entry.startsWith(path)) {
+        final String terminal = entry.substring(path.length());
+        final StringTokenizer st = new StringTokenizer(terminal, "/");
+        String entryPath;
+        if (st.hasMoreTokens()) {
+          entryPath = path + st.nextToken();
+        } else {// this should not happen even for "", or?
+          entryPath = path;
+        }
+        if (!answer.contains(entryPath)) {
+          answer.add(entryPath);
+        }
+      }
+    }
+
+    if (answer.size() == 0) {
+      return null;
+    }
+    return answer.elements();
+  }
+
+
+  /**
+   * Get an Archive handle to a named Jar file within this archive.
+   *
+   * @param path Name of Jar file to get.
+   * @return An Archive object representing new archive.
+   * @exception FileNotFoundException if no such Jar file in archive.
+   * @exception IOException if failed to read Jar file.
+   */
+  Archive getSubArchive(String path) throws IOException {
+    return new Archive(this, path);
+  }
+
+
+  /**
+   * Check for native library in archive.
+   *
+   * @param path Name of native code file to get.
+   * @return If native library exist return libname, otherwise null.
+   */
+  public String checkNativeLibrary(String path) {
+    return null;
+  }
+
+
+  /**
+   * Get native code library filename.
+   *
+   * @param libNameKey Key for native lib to get.
+   * @return A string with the path to the native library.
+   */
+  public String getNativeLibrary(String libNameKey) {
+    return null;
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Loads all files in a JarInputStream and stores it in a HashMap.
+   *
+   * @param ji JarInputStream to read from.
+   */
+  private HashMap<String, byte[]> loadJarStream(JarInputStream ji) throws IOException {
+    final HashMap<String, byte[]> files = new HashMap<String, byte[]>();
+    JarEntry je;
+    while ((je = ji.getNextJarEntry()) != null) {
+      if (!je.isDirectory()) {
+        int len = (int)je.getSize();
+        if (len == -1) {
+          len = 8192;
+        }
+        byte[] b = new byte[len];
+        int pos = 0;
+        do {
+          if (pos == len) {
+            len *= 2;
+            final byte[] oldb = b;
+            b = new byte[len];
+            System.arraycopy(oldb, 0, b, 0, oldb.length);
+          }
+          int n;
+          while ((len - pos) > 0 && (n = ji.read(b, pos, len - pos)) > 0) {
+            pos += n;
+          }
+        } while (ji.available() > 0);
+        if (pos != b.length) {
+          final byte[] oldb = b;
+          b = new byte[pos];
+          System.arraycopy(oldb, 0, b, 0, pos);
+        }
+        files.put(je.getName(), b);
+      }
+    }
+    return files;
+  }
+
+
+  @Override
+  public boolean exists(String path, boolean onlyDirs) {
+    if (path.equals("")) {
+      return true;
+    }
+    if (onlyDirs) {
+      if (!path.endsWith("/")) {
+        path = path + "/";
+      }
+      for (String k : content.keySet()) {
+        if (k.startsWith(path)) {
+          return true;
+        }
+      }
+      return false;
+    } else {
+      return content.containsKey(path);
+    }
+  }
+
+
+  @Override
+  public Set<String> listDir(String path) {
+    Set<String> res = new HashSet<String>();
+    if (path.length() > 0 && !path.endsWith("/")) {
+      path = path + "/";
+    }
+    for (String k : content.keySet()) {
+      String e = matchPath(path, k);
+      if (e != null) {
+        res.add(e);
+      }
+    }
+    return res;
+  }
+
+
+  private String matchPath(String basePath, String path) {
+    final int len = basePath.length();
+    if (path.length() > len && path.startsWith(basePath)) {
+      int i = path.indexOf('/', len);
+      if (i == -1) {
+        return path.substring(len);
+      } else {
+        return path.substring(len, i + 1);
+      }
+    }
+    return null;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/BundleArchiveImpl.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/BundleArchiveImpl.java
new file mode 100644
index 0000000..15881be
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/BundleArchiveImpl.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage.memory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.Constants;
+
+import org.knopflerfish.framework.BundleArchive;
+import org.knopflerfish.framework.BundleGeneration;
+import org.knopflerfish.framework.BundleResourceStream;
+import org.knopflerfish.framework.FileArchive;
+import org.knopflerfish.framework.HeaderDictionary;
+
+/**
+ * Managing bundle data.
+ *
+ * @author Jan Stein
+ * @author Philippe Laporte
+ */
+class BundleArchiveImpl implements BundleArchive {
+
+  private final Archive archive;
+
+  private BundleGeneration bundleGeneration = null;
+
+  private final long id;
+
+  private final String location;
+
+  private int autostartSetting = -1; // -> not started.
+
+  private final BundleStorageImpl storage;
+
+  private Archive[] archives;
+
+  private int startLevel = -1;
+  private long lastModified;
+
+  private ArrayList<String> failedPath = null;
+
+
+  /**
+   * Construct new bundle archive.
+   *
+   */
+  BundleArchiveImpl(BundleStorageImpl bundleStorage, InputStream is, String bundleLocation,
+                    long bundleId) throws Exception {
+    archive = new Archive(this, is);
+    storage = bundleStorage;
+    id = bundleId;
+    location = bundleLocation;
+    setClassPath();
+  }
+
+
+  /**
+   * Construct new bundle archive in an existing bundle archive.
+   *
+   */
+  BundleArchiveImpl(BundleArchiveImpl old, InputStream is) throws Exception {
+    location = old.location;
+    storage = old.storage;
+    id = old.id;
+    autostartSetting = old.autostartSetting;
+    archive = new Archive(this, is);
+    setClassPath();
+  }
+
+
+  /**
+   * Get an attribute from the manifest of a bundle.
+   *
+   * @param key Name of attribute to get.
+   * @return A string with result or null if the entry doesn't exists.
+   */
+  public String getAttribute(String key) {
+    return archive.getAttribute(key);
+  }
+
+
+  /**
+   * Get a FileArchive handle to a named Jar file or directory within this
+   * archive.
+   *
+   * @param path Name of Jar file or directory to get.
+   * @return A FileArchive object representing new archive, null if not found.
+   */
+  public FileArchive getFileArchive(String path) {
+    for (Archive a : archives) {
+      if (a.path.equals(path)) {
+        return a;
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * returns the localization entries of this archive.
+   */
+  public Hashtable<String, String> getLocalizationEntries(String localeFile) {
+    final BundleResourceStream is = archive.getBundleResourceStream(localeFile);
+    if (is != null) {
+      final Properties l = new Properties();
+      try {
+        l.load(is);
+      } catch (final IOException _ignore) {
+      }
+      try {
+        is.close();
+      } catch (final IOException _ignore) {
+      }
+      @SuppressWarnings("rawtypes")
+      final Hashtable ht = l;
+      @SuppressWarnings("unchecked")
+      final Hashtable<String, String> res = ht;
+      return res;
+    } else {
+      return null;
+    }
+  }
+
+
+  /**
+   * returns the raw unlocalized entries of this archive.
+   */
+  public HeaderDictionary getUnlocalizedAttributes() {
+    return new HeaderDictionary(archive.manifest.getMainAttributes());
+  }
+
+
+  /**
+   * Get bundle generation associated with this bundle archive.
+   *
+   * @return BundleGeneration object.
+   */
+  public BundleGeneration getBundleGeneration() {
+    return bundleGeneration;
+  }
+
+
+  /**
+   * Set bundle generation associated with this bundle archive.
+   *
+   * @param BundleGeneration object.
+   */
+  public void setBundleGeneration(BundleGeneration bg) {
+    bundleGeneration = bg;
+  }
+
+
+  /**
+   * Get bundle identifier for this bundle archive.
+   *
+   * @return Bundle identifier.
+   */
+  public long getBundleId() {
+    return id;
+  }
+
+
+  /**
+   * Get bundle location for this bundle archive.
+   *
+   * @return Bundle location.
+   */
+  public String getBundleLocation() {
+    return location;
+  }
+
+
+  public int getStartLevel() {
+    return startLevel;
+  }
+
+
+  public void setStartLevel(int level) {
+    startLevel = level;
+  }
+
+
+  public long getLastModified() {
+    return lastModified;
+  }
+
+
+  public void setLastModified(long timemillisecs) throws IOException {
+    lastModified = timemillisecs;
+  }
+
+
+  /**
+   * Get a byte array containg the contents of named file from a bundle archive.
+   *
+   * @param sub index of jar, 0 means the top level.
+   * @param path Path to class file.
+   * @return Byte array with contents of file or null if file doesn't exist.
+   * @exception IOException if failed to read jar entry.
+   */
+  public byte[] getClassBytes(Integer sub, String path) throws IOException {
+    return archives[sub.intValue()].getClassBytes(path);
+  }
+
+
+  /**
+   * Get an specific InputStream to named entry inside a bundle. Leading '/' is
+   * stripped.
+   *
+   * @param component Entry to get reference to.
+   * @param ix index of sub archives. A postive number is the classpath entry
+   *          index. -1 means look in the main bundle.
+   * @return InputStream to entry or null if it doesn't exist.
+   */
+  public BundleResourceStream getBundleResourceStream(String component, int ix) {
+    if (component.startsWith("/")) {
+      component = component.substring(1);
+    }
+
+    if (ix == -1) {
+      return archive.getBundleResourceStream(component);
+    } else {
+      return archives[ix].getBundleResourceStream(component);
+    }
+  }
+
+
+  /**
+   * Get native library from JAR.
+   *
+   * @param libName Name of Jar file to get.
+   * @return A string with path to native library.
+   */
+  public String getNativeLibrary(String libName) {
+    return null;
+  }
+
+
+  /**
+   * Set autostart setting.
+   *
+   * @param setting the new autostart setting.
+   */
+  public void setAutostartSetting(int setting) throws IOException {
+    if (setting != autostartSetting) {
+      autostartSetting = setting;
+    }
+  }
+
+
+  /**
+   * Get autostart setting.
+   *
+   * @return the autostart setting.
+   */
+  public int getAutostartSetting() {
+    return autostartSetting;
+  }
+
+
+  /**
+   * Remove bundle archive from persistent storage. If we removed the active
+   * revision also remove bundle status files.
+   */
+  public void purge() {
+    storage.removeArchive(this);
+  }
+
+
+  /**
+   * Close archive for further access. It should still be possible to get
+   * attributes.
+   */
+  public void close() {
+  }
+
+
+  /**
+   * Get a list with all classpath entries we failed to locate.
+   *
+   * @return A List with all failed classpath entries, null if no failures.
+   */
+  public List<String> getFailedClassPathEntries() {
+    return failedPath;
+  }
+
+
+  /**
+   * Resolve native code libraries.
+   *
+   * @return null if resolve ok, otherwise return an error message.
+   */
+  public String resolveNativeCode() {
+    if (getAttribute(Constants.BUNDLE_NATIVECODE) != null) {
+      return "Native code not allowed by memory storage";
+    }
+    return null;
+  }
+
+
+  //
+  // Private methods
+  //
+
+  private void setClassPath() throws IOException {
+    final String bcp = getAttribute(Constants.BUNDLE_CLASSPATH);
+
+    if (bcp != null) {
+      final ArrayList<Archive> a = new ArrayList<Archive>();
+      final StringTokenizer st = new StringTokenizer(bcp, ",");
+      while (st.hasMoreTokens()) {
+        final String path = st.nextToken().trim();
+        if (".".equals(path)) {
+          a.add(archive);
+        } else if (path.endsWith(".jar")) {
+          try {
+            a.add(archive.getSubArchive(path));
+          } catch (final IOException ioe) {
+            if (failedPath == null) {
+              failedPath = new ArrayList<String>(1);
+            }
+            failedPath.add(path);
+          }
+        } else {
+          if (archive.subDirs == null) {
+            archive.subDirs = new ArrayList<String>(1);
+          }
+          // NYI Check that it exists!
+          archive.subDirs.add(path);
+        }
+      }
+      archives = a.toArray(new Archive[a.size()]);
+    } else {
+      archives = new Archive[] { archive };
+    }
+  }
+
+
+  public Enumeration<String> findResourcesPath(String path) {
+    return archive.findResourcesPath(path);
+  }
+
+
+  public String getJarLocation() {
+    return null;
+  }
+
+
+  /**
+   * Return certificates for signed bundle, otherwise null.
+   *
+   * @return An array of certificates or null.
+   */
+  public ArrayList<List<X509Certificate>> getCertificateChains(boolean onlyTrusted) {
+    // TODO
+    return null;
+  }
+
+
+  /**
+   * Mark certificate chain as trusted.
+   *
+   */
+  public void trustCertificateChain(List<X509Certificate> trustedChain) {
+    // TODO
+    throw new RuntimeException("NYI");
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/BundleStorageImpl.java b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/BundleStorageImpl.java
new file mode 100644
index 0000000..7569265
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/bundlestorage/memory/BundleStorageImpl.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework.bundlestorage.memory;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.knopflerfish.framework.BundleArchive;
+import org.knopflerfish.framework.BundleStorage;
+import org.knopflerfish.framework.FWProps;
+import org.knopflerfish.framework.FrameworkContext;
+
+
+/**
+ * Storage of all bundles jar content.
+ *
+ * @author Jan Stein, Gunnar Ekolin
+ */
+public class BundleStorageImpl implements BundleStorage {
+
+  /**
+   * Next available bundle id.
+   */
+  private long nextFreeId = 1;
+
+  /**
+   * Bundle id sorted list of all active bundle archives.
+   */
+  private final ArrayList<BundleArchive> archives = new ArrayList<BundleArchive>();
+
+  /**
+   * If we should check if bundles are signed
+   */
+  final boolean checkSigned;
+
+
+  /**
+   * Create a container for all bundle data in this framework.
+   * Try to restore all saved bundle archive state.
+   *
+   */
+  public BundleStorageImpl(FrameworkContext framework) {
+    checkSigned = framework.props.getBooleanProperty(FWProps.BUNDLESTORAGE_CHECKSIGNED_PROP);
+  }
+
+  /**
+   * Insert bundle into persistent storage
+   *
+   * @param location Location of bundle.
+   * @param is Input stream with bundle content.
+   * @return Bundle archive object.
+   */
+  public BundleArchive insertBundleJar(String location, InputStream is)
+    throws Exception
+  {
+    final long id = nextFreeId++;
+    final BundleArchive ba = new BundleArchiveImpl(this, is, location, id);
+    archives.add(ba);
+    return ba;
+  }
+
+
+  /**
+   * Insert a new jar file into persistent storagedata as an update
+   * to an existing bundle archive. To commit this data a call to
+   * <code>replaceBundleArchive</code> is needed.
+   *
+   * @param old BundleArchive to be replaced.
+   * @param is Inputstrem with bundle content.
+   * @return Bundle archive object.
+   */
+  public BundleArchive updateBundleArchive(BundleArchive old, InputStream is)
+    throws Exception
+  {
+    return new BundleArchiveImpl((BundleArchiveImpl)old, is);
+  }
+
+
+  /**
+   * Replace old bundle archive with a new updated bundle archive, that
+   * was created with updateBundleArchive.
+   *
+   * @param oldBA BundleArchive to be replaced.
+   * @param newBA Inputstrem with bundle content.
+   * @return New bundle archive object.
+   */
+  public void replaceBundleArchive(BundleArchive oldBA, BundleArchive newBA)
+    throws Exception
+  {
+    int pos;
+    final long id = oldBA.getBundleId();
+    synchronized (archives) {
+      pos = find(id);
+      if (pos >= archives.size() || archives.get(pos) != oldBA) {
+        throw new Exception("replaceBundleJar: Old bundle archive not found, pos=" + pos);
+      }
+      archives.set(pos, newBA);
+    }
+  }
+
+
+  /**
+   * Get all bundle archive objects.
+   *
+   * @return Private array of all BundleArchives.
+   */
+  public BundleArchive [] getAllBundleArchives() {
+    synchronized (archives) {
+      return archives.toArray(new BundleArchive[archives.size()]);
+    }
+  }
+
+
+  /**
+   * Get all bundles to start at next launch of framework.
+   * This list is sorted in increasing bundle id order.
+   *
+   * @return Private copy of a List with bundle id's.
+   */
+  public List<String> getStartOnLaunchBundles() {
+    final ArrayList<String> res = new ArrayList<String>();
+    for (final BundleArchive ba : archives) {
+      if (ba.getAutostartSetting()!=-1) {
+        res.add(ba.getBundleLocation());
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Close bundle storage.
+   *
+   */
+  public void close()
+  {
+    for (final Iterator<BundleArchive> i = archives.iterator(); i.hasNext(); ) {
+      final BundleArchive ba = i.next();
+      ba.close();
+      i.remove();
+    }
+  }
+
+  //
+  // Package methods
+  //
+
+  /**
+   * Remove bundle archive from archives list.
+   *
+   * @param id Bundle archive id to find.
+   * @return true if element was removed.
+   */
+  boolean removeArchive(BundleArchive ba) {
+    synchronized (archives) {
+      final int pos = find(ba.getBundleId());
+      if (archives.get(pos) == ba) {
+        archives.remove(pos);
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Find posisition for BundleArchive with specified id
+   *
+   * @param id Bundle archive id to find.
+   * @return String to write
+   */
+  private int find(long id) {
+    int lb = 0;
+    int ub = archives.size();
+    int x = 0;
+    while (lb != ub) {
+      x = (lb + ub) / 2;
+      final long xid = archives.get(x).getBundleId();
+      if (id <= xid) {
+        ub = x;
+      } else {
+        lb = x+1;
+      }
+    }
+    return lb;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermission.java b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermission.java
new file mode 100644
index 0000000..e7a4fb7
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermission.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2008-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.service.condpermadmin.Condition;
+
+
+/**
+ * A binding of a set of Conditions to a set of Permissions.
+ *
+ */
+public class ConditionalPermission
+{
+  private final ConditionalPermissionInfoImpl parent;
+  private Condition [] conditions;
+  final private PermissionCollection permissions;
+  private List<Condition> postponed = null;
+
+  final String access;
+
+  /**
+   */
+  ConditionalPermission(Condition [] conds, PermissionCollection perms, String access,
+                        ConditionalPermissionInfoImpl cpi) {
+    conditions = conds;
+    permissions = perms;
+    this.access = access;
+    parent = cpi;
+  }
+
+
+  /**
+   * Check immediate conditions and if asked save postponed conditions.
+   * If conditions are fulfilled check permission is ok.
+   *
+   */
+  boolean checkImmediateOk(Permission perm, boolean checkPostponed) {
+    if (conditions == null) {
+      return false;
+    }
+    postponed = new ArrayList<Condition>(1);
+    for (int i = 0; i < conditions.length; i++) {
+      final Condition c = conditions[i];
+      if (c == null) {
+        // Immutable condition has been removed
+        continue;
+      }
+      if (checkPostponed || !c.isPostponed()) {
+        final boolean mutable = c.isMutable();
+        if (c.isSatisfied()) {
+          if (!mutable) {
+            // Mark always ok by clearing condition element.
+            conditions[i] = null;
+          }
+        } else {
+          if (!mutable) {
+            // Mark always fail by clearing conditions.
+            conditions = null;
+          }
+          postponed = null;
+          return false;
+        }
+      } else {
+        postponed.add(c);
+      }
+    }
+    return permissions.implies(perm);
+  }
+
+
+  /**
+   * Check postponed conditions are OK.
+   *
+   */
+  boolean checkPostponedOk(Map<Class<? extends Condition>, Dictionary<Object, Object>> condDict,
+                           List<Class<? extends Condition>> checkedClasses)
+  {
+    if (conditions == null) {
+      return false;
+    }
+    // Loop through all postponed Conditions for ConditionalPermissions
+    for (final Condition c : postponed) {
+      final Class<? extends Condition> cc = c.getClass();
+      if (checkedClasses.contains(cc)) {
+        throw new SecurityException("Postponement condition check recursive for class: " + cc);
+      }
+      Dictionary<Object, Object> d = condDict.get(cc);
+      if (d == null) {
+        d = new Hashtable<Object, Object>();
+        condDict.put(cc, d);
+      }
+      checkedClasses.add(cc);
+      try {
+        final boolean m = c.isMutable();
+        if (c.isSatisfied(new Condition [] {c}, d)) {
+          if (!m) {
+            for (int i = 0; i < conditions.length; i++ ) {
+              if (conditions[i] == c) {
+                conditions[i] = null;
+                break;
+              }
+            }
+          }
+        } else {
+          if (!m) {
+            conditions = null;
+          }
+          // ConditionPermissional didn't match
+          return false;
+        }
+      } catch (final Throwable ignore) {
+        // NYI, Log this failure
+        // ConditionPermissional couldn't be evaluated, treat as fail
+        // TBD should we do this even if we have a DENY CondPerm.
+        return false;
+      } finally {
+        checkedClasses.remove(checkedClasses.size() - 1);
+      }
+    }
+    return true;
+  }
+
+
+  /**
+   * Check if we have saved any postponements in last
+   * checkImmediateOk call.
+   */
+  boolean hasPostponed() {
+    return !postponed.isEmpty();
+  }
+
+
+  /**
+   *
+   */
+  boolean isParent(ConditionalPermissionInfoImpl cpi) {
+    return cpi == parent;
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public String toString() {
+    return "HASH: " + hashCode() + " INFO: " + parent.toString();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionAdminImpl.java b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionAdminImpl.java
new file mode 100644
index 0000000..4e1cf3c
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionAdminImpl.java
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 2008-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+
+import java.io.File;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.condpermadmin.ConditionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+import org.knopflerfish.framework.FrameworkContext;
+import org.knopflerfish.framework.Util;
+
+/**
+ * Framework service to administer Conditional Permissions. Conditional
+ * Permissions can be added to, retrieved from, and removed from the framework.
+ *
+ */
+public class ConditionalPermissionAdminImpl implements ConditionalPermissionAdmin {
+
+  public final static String SPEC_VERSION = "1.1.0";
+
+  private final ConditionalPermissionInfoStorage cpis;
+
+  private final PermissionInfoStorage pis;
+
+  final private FrameworkContext framework;
+
+
+  /**
+   *
+   */
+  public ConditionalPermissionAdminImpl(ConditionalPermissionInfoStorage cpis,
+                                        PermissionInfoStorage pis,
+                                        FrameworkContext framework) {
+    this.cpis = cpis;
+    this.pis = pis;
+    this.framework = framework;
+  }
+
+
+  //
+  // Interface ConditionalPermissionAdmin
+  //
+
+  /**
+   * Create a new Conditional Permission Info.
+   *
+   * The Conditional Permission Info will be given a unique, never reused
+   * name.
+   *
+   * @param conds The Conditions that need to be satisfied to enable the
+   *        corresponding Permissions.
+   * @param perms The Permissions that are enable when the corresponding
+   *        Conditions are satisfied.
+   * @return The ConditionalPermissionInfo for the specified Conditions and
+   *         Permissions.
+   * @throws SecurityException If the caller does not have
+   *         <code>AllPermission</code>.
+   */
+  public ConditionalPermissionInfo
+  addConditionalPermissionInfo(ConditionInfo conds[], PermissionInfo perms[]) {
+    return cpis.put(null, conds, perms);
+  }
+
+
+  /**
+   * Set or create a Conditional Permission Info with a specified name.
+   *
+   * If the specified name is {@code null}, a new Conditional
+   * Permission Info must be created and will be given a unique, never reused
+   * name. If there is currently no Conditional Permission Info with the
+   * specified name, a new Conditional Permission Info must be created with
+   * the specified name. Otherwise, the Conditional Permission Info with the
+   * specified name must be updated with the specified Conditions and
+   * Permissions.
+   *
+   * @param name The name of the Conditional Permission Info, or
+   *        {@code null}.
+   * @param conds The Conditions that need to be satisfied to enable the
+   *        corresponding Permissions.
+   * @param perms The Permissions that are enable when the corresponding
+   *        Conditions are satisfied.
+   * @return The ConditionalPermissionInfo that for the specified name,
+   *         Conditions and Permissions.
+   * @throws SecurityException If the caller does not have
+   *         <code>AllPermission</code>.
+   */
+  public ConditionalPermissionInfo
+  setConditionalPermissionInfo(String name, ConditionInfo conds[], PermissionInfo perms[]) {
+    return cpis.put(name, conds, perms);
+  }
+
+
+  /**
+   * Returns the Conditional Permission Infos that are currently managed by
+   * Conditional Permission Admin. Calling
+   * {@link ConditionalPermissionInfo#delete()} will remove the Conditional
+   * Permission Info from Conditional Permission Admin.
+   *
+   * @return An enumeration of the Conditional Permission Infos that are
+   *         currently managed by Conditional Permission Admin.
+   */
+  public Enumeration<ConditionalPermissionInfo> getConditionalPermissionInfos() {
+    return cpis.getAllEnumeration();
+  }
+
+
+  /**
+   * Return the Conditional Permission Info with the specified name.
+   *
+   * @param name The name of the Conditional Permission Info to be returned.
+   * @return The Conditional Permission Info with the specified name.
+   */
+  public ConditionalPermissionInfo getConditionalPermissionInfo(String name) {
+    return cpis.get(name);
+  }
+
+
+  /**
+   * Returns the Access Control Context that corresponds to the specified
+   * signers.
+   *
+   * @param signers The signers for which to return an Access Control Context.
+   * @return An <code>AccessControlContext</code> that has the Permissions
+   *         associated with the signer.
+   */
+  public AccessControlContext getAccessControlContext(String[] signers) {
+    PermissionCollection perms;
+    synchronized (cpis) {
+      perms = new PermissionsWrapper(framework, pis, cpis, null, new DummyBundle(signers), null);
+    }
+    return new AccessControlContext(new ProtectionDomain[] {new ProtectionDomain(null, perms)});
+  }
+
+
+
+  /**
+   *
+   * @see org.osgi.service.condpermadmin.ConditionalPermissionAdmin#newConditionalPermissionUpdate()
+   */
+  public ConditionalPermissionUpdate newConditionalPermissionUpdate() {
+    return cpis.getUpdate();
+  }
+
+
+  /**
+   *
+   * @see org.osgi.service.condpermadmin.ConditionalPermissionAdmin#newConditionalPermissionInfo()
+   */
+  public ConditionalPermissionInfo newConditionalPermissionInfo(String name,
+                                                                ConditionInfo conditions[],
+                                                                PermissionInfo permissions[],
+                                                                String access)
+  {
+    if (ConditionalPermissionInfo.ALLOW.equalsIgnoreCase(access)) {
+      access = ConditionalPermissionInfo.ALLOW;
+    } else if (ConditionalPermissionInfo.DENY.equalsIgnoreCase(access)) {
+      access = ConditionalPermissionInfo.DENY;
+    } else {
+      throw new IllegalArgumentException("access must be " +
+                                         ConditionalPermissionInfo.ALLOW +
+                                         " or " +
+                                         ConditionalPermissionInfo.DENY);
+    }
+    if (permissions == null || permissions.length == 0) {
+      throw new IllegalArgumentException("permissions must contain atleast one element");
+    }
+    return new ConditionalPermissionInfoImpl(cpis, name, conditions,
+                                             permissions, access, framework);
+  }
+
+
+  /**
+   *
+   * @see org.osgi.service.condpermadmin.ConditionalPermissionAdmin#newConditionalPermissionInfo()
+   */
+  public ConditionalPermissionInfo newConditionalPermissionInfo(String encoded)  {
+    return new ConditionalPermissionInfoImpl(cpis, encoded, framework);
+  }
+
+
+  /**
+   * Dummy Bundle class only used for getAccessControlContext().
+   */
+  static class DummyBundle implements Bundle {
+
+    private final HashMap<X509Certificate,List<X509Certificate>> signerMap
+      = new HashMap<X509Certificate, List<X509Certificate>>();
+
+    DummyBundle(String [] signers) {
+      for (final String signer : signers) {
+        final String [] chain = Util.splitwords(signer, ";");
+        final ArrayList<X509Certificate> tmp
+          = new ArrayList<X509Certificate>(chain.length);
+        for (final String element : chain) {
+          tmp.add(new X509Dummy(element));
+        }
+        signerMap.put(tmp.get(0), tmp);
+      }
+    }
+
+
+    public int getState() {
+      return UNINSTALLED;
+    }
+
+    public void start() {
+      start(0);
+    }
+
+    public void start(int options) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public void stop() {
+      stop(0);
+    }
+
+    public void stop(int options) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public void update() {
+      update(null);
+    }
+
+    public void update(final InputStream in) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public void uninstall() {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public Dictionary<String, String> getHeaders() {
+      return getHeaders(null);
+    }
+
+    public long getBundleId() {
+      return -1;
+    }
+
+    public String getLocation() {
+      return "";
+    }
+
+    public ServiceReference<?>[] getRegisteredServices() {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public ServiceReference<?>[] getServicesInUse() {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public boolean hasPermission(Object permission) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public BundleContext getBundleContext() {
+      return null;
+    }
+
+    public URL getResource(String name) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public String getSymbolicName() {
+      return null;
+    }
+
+    public long getLastModified() {
+      return 0;
+    }
+
+    public Map<X509Certificate, List<X509Certificate>>
+      getSignerCertificates(int signersType)
+    {
+      @SuppressWarnings("unchecked")
+      final Map<X509Certificate, List<X509Certificate>> res
+        = (Map<X509Certificate, List<X509Certificate>>) signerMap.clone();
+      return res;
+    }
+
+    public Version getVersion() {
+      return Version.emptyVersion;
+    }
+
+    public <A> A adapt(Class<A> type) {
+      return null;
+    }
+
+    public File getDataFile(String filename) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public Enumeration<URL> findEntries(String path,
+                                        String filePattern,
+                                        boolean recurse)
+    {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public URL getEntry(String name) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public Enumeration<String> getEntryPaths(String path) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public Dictionary<String, String> getHeaders(String locale) {
+      return new Hashtable<String, String>();
+    }
+
+    public Enumeration<URL> getResources(String name) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public Class<?> loadClass(final String name) {
+      throw new IllegalStateException("Bundle is uninstalled");
+    }
+
+    public int compareTo(Bundle bundle) {
+      return 0;
+    }
+  }
+
+  /**
+   * Dummy X509 class only used for getAccessControlContext().
+   */
+  static class X509Dummy extends X509Certificate {
+
+    Principal subject;
+
+    X509Dummy(String dn) {
+      super();
+      subject = new PrincipalDummy(dn);
+    }
+
+    @Override
+    public void checkValidity() {
+    }
+
+    @Override
+    public void checkValidity(Date date) {
+    }
+
+    @Override
+    public int getVersion() {
+      return 1;
+    }
+
+    @Override
+    public BigInteger getSerialNumber() {
+      return null;
+    }
+
+    @Override
+    public Principal getIssuerDN() {
+      return null;
+    }
+
+    @Override
+    public Principal getSubjectDN() {
+      return subject;
+    }
+
+    @Override
+    public Date getNotBefore() {
+      return null;
+    }
+
+    @Override
+    public Date getNotAfter() {
+      return null;
+    }
+
+    @Override
+    public byte[] getTBSCertificate() {
+      return null;
+    }
+
+    @Override
+    public byte[] getSignature() {
+      return null;
+    }
+
+    @Override
+    public String getSigAlgName() {
+      return null;
+    }
+
+    @Override
+    public String getSigAlgOID() {
+      return null;
+    }
+
+    @Override
+    public byte[] getSigAlgParams() {
+      return null;
+    }
+
+    @Override
+    public boolean[] getIssuerUniqueID() {
+      return null;
+    }
+
+    @Override
+    public boolean[] getSubjectUniqueID() {
+      return null;
+    }
+
+    @Override
+    public boolean[] getKeyUsage() {
+      return null;
+    }
+
+    @Override
+    public int getBasicConstraints() {
+      return 0;
+    }
+
+    @Override
+    public byte [] getEncoded() {
+      return null;
+    }
+
+    @Override
+    public PublicKey getPublicKey() {
+      return null;
+    }
+
+    @Override
+    public String toString() {
+      return "X509Dummy, " + subject.getName();
+    }
+
+    @Override
+    public void verify(PublicKey k) {
+    }
+
+    @Override
+    public void verify(PublicKey k, String p) {
+    }
+
+    public byte [] getExtensionValue(String oid) {
+      return null;
+    }
+
+    public Set<String> getCriticalExtensionOIDs() {
+      return null;
+    }
+
+    public Set<String> getNonCriticalExtensionOIDs() {
+      return null;
+    }
+
+    public boolean hasUnsupportedCriticalExtension() {
+      return false;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      return subject.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+      return subject.hashCode();
+    }
+  }
+
+  /**
+   * Dummy Principal class only used for getAccessControlContext().
+   */
+  static class PrincipalDummy implements Principal {
+
+    final private String name;
+
+    PrincipalDummy(String dn) {
+      name = dn;
+    }
+
+    public String getName() {
+      return name;
+    }
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoImpl.java b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoImpl.java
new file mode 100644
index 0000000..e500fc9
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoImpl.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2008-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FrameworkContext;
+
+
+/**
+ * A binding of a set of Conditions to a set of Permissions.
+ *
+ */
+class ConditionalPermissionInfoImpl implements ConditionalPermissionInfo
+{
+  private ConditionalPermissionInfoStorage cpis;
+
+  final private ConditionInfo [] conditionInfos;
+  final private PermissionInfo [] permissionInfos;
+  final private String access;
+  final private FrameworkContext framework;
+  final private Debug debug;
+
+  private String name;
+  private PermissionCollection permissions;
+
+
+  /**
+   */
+  ConditionalPermissionInfoImpl(ConditionalPermissionInfoStorage cpis,
+                                String name, ConditionInfo[] conds,
+                                PermissionInfo[] perms, String access,
+                                FrameworkContext fw)
+  {
+    this.cpis = cpis;
+    this.name = name;
+    conditionInfos = conds;
+    permissionInfos = perms;
+    this.access = access;
+    framework = fw;
+    debug = fw.debug;
+    permissions = null;
+  }
+
+
+  /**
+   */
+  ConditionalPermissionInfoImpl(ConditionalPermissionInfoStorage cpis,
+                                String encoded, FrameworkContext fw) {
+    this.cpis = cpis;
+    framework = fw;
+    debug = fw.debug;
+    try {
+      final char [] eca = encoded.toCharArray();
+      int pos = PermUtil.skipWhite(eca, 0);
+      if ((eca[pos] == 'A' || eca[pos] == 'a') &&
+          (eca[pos+1] == 'L' || eca[pos+1] == 'l') &&
+          (eca[pos+2] == 'L' || eca[pos+2] == 'l') &&
+          (eca[pos+3] == 'O' || eca[pos+3] == 'o') &&
+          (eca[pos+4] == 'W' || eca[pos+4] == 'w') && eca[pos+5] == ' ') {
+        pos += 6;
+        access = ConditionalPermissionInfo.ALLOW;
+      } else if ((eca[pos] == 'D' || eca[pos] == 'd') &&
+                 (eca[pos+1] == 'E' || eca[pos+1] == 'e') &&
+                 (eca[pos+2] == 'N' || eca[pos+2] == 'n') &&
+                 (eca[pos+3] == 'Y' || eca[pos+3] == 'y') && eca[pos+4] == ' ') {
+        pos += 5;
+        access = ConditionalPermissionInfo.DENY;
+      } else {
+        throw new IllegalArgumentException("Access must be allow or deny");
+      }
+      pos = PermUtil.skipWhite(eca, pos);
+      if (eca[pos++] != '{') {
+        throw new IllegalArgumentException("Missing open brace");
+      }
+      final ArrayList<ConditionInfo> cal = new ArrayList<ConditionInfo>();
+      final ArrayList<PermissionInfo> pal = new ArrayList<PermissionInfo>();
+      boolean seenPermInfo = false;
+      while (true) {
+        pos = PermUtil.skipWhite(eca, pos);
+        char c = eca[pos];
+        char ec;
+        if (!seenPermInfo && c == '[') {
+          ec = ']';
+        } else if (c == '(') {
+          ec = ')';
+          seenPermInfo = true;
+        } else if (c == '}') {
+          pos++;
+          break;
+        } else {
+          throw new IllegalArgumentException("Unexpected char '" + c + "' at pos " + pos);
+        }
+        final int start_pos = pos++;
+        do {
+          c = eca[pos];
+          if (c == '"') {
+            pos = PermUtil.unquote(eca, pos, null);
+          } else {
+            pos++;
+          }
+        } while(c != ec);
+        final String info = new String(eca, start_pos, pos - start_pos);
+        if (c == ']') {
+          cal.add(new ConditionInfo(info));
+        } else {
+          pal.add(new PermissionInfo(info));
+        }
+      }
+      if (!seenPermInfo) {
+        throw new IllegalArgumentException("Permissions must contain atleast one element");
+      }
+      pos = PermUtil.endOfString(eca, pos, eca.length);
+      if (pos != -1) {
+        final StringBuffer buf = new StringBuffer();
+        pos = PermUtil.unquote(eca, pos, buf);
+        name = buf.toString();
+        if ((pos = PermUtil.endOfString(eca, pos, eca.length)) != -1) {
+          throw new IllegalArgumentException("Unexpected characters at end of string: " +
+                                             new String(eca, pos, eca.length - pos));
+        }
+      } else {
+        name = null;
+      }
+      conditionInfos = cal.toArray(new ConditionInfo [cal.size()]);
+      permissionInfos = pal.toArray(new PermissionInfo [pal.size()]);
+    } catch (final ArrayIndexOutOfBoundsException e) {
+      throw new IllegalArgumentException("Unexpected end of string");
+    }
+  }
+
+  // Interface ConditionalPermissionInfo
+
+  /**
+   * Returns the Condition Infos for the Conditions that must be satisfied to
+   * enable the Permissions.
+   *
+   * @return The Condition Infos for the Conditions in this Conditional
+   *         Permission Info.
+   */
+  public ConditionInfo[] getConditionInfos() {
+    return conditionInfos;
+  }
+
+
+  /**
+   * Returns the Permission Infos for the Permission in this Conditional
+   * Permission Info.
+   *
+   * @return The Permission Infos for the Permission in this Conditional
+   *         Permission Info.
+   */
+  public PermissionInfo[] getPermissionInfos() {
+    return permissionInfos;
+  }
+
+
+  /**
+   * Removes this Conditional Permission Info from the Conditional Permission
+   * Admin.
+   *
+   * @throws SecurityException If the caller does not have
+   *         <code>AllPermission</code>.
+   */
+  public void delete() {
+    if (cpis == null) {
+      throw new UnsupportedOperationException("Not in use");
+    }
+    cpis.remove(this);
+  }
+
+
+  /**
+   * Returns the name of this Conditional Permission Info.
+   *
+   * @return The name of this Conditional Permission Info.
+   */
+  public String getName() {
+    return name;
+  }
+
+
+  public String getAccessDecision() {
+    return access;
+  }
+
+
+  public String getEncoded() {
+    final StringBuffer res = new StringBuffer(access);
+    res.append(" { ");
+    if (conditionInfos != null) {
+      for (final ConditionInfo conditionInfo : conditionInfos) {
+        res.append(conditionInfo.getEncoded());
+        res.append(' ');
+      }
+    }
+    if (permissionInfos != null) {
+      for (final PermissionInfo permissionInfo : permissionInfos) {
+        res.append(permissionInfo.getEncoded());
+        res.append(' ');
+      }
+    }
+    res.append('}');
+    if (name != null) {
+      res.append(' ');
+      PermUtil.quote(name, res);
+    }
+    return res.toString();
+  }
+
+
+  /**
+   * Returns a string representation of this object.
+   *
+   */
+  @Override
+  public String toString() {
+    return getEncoded();
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public final boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (obj == this) {
+      return true;
+    }
+    final ConditionalPermissionInfo cpi = (ConditionalPermissionInfo)obj;
+    if (name == null ? cpi.getName() != null : !name.equals(cpi.getName())) {
+      return false;
+    }
+    // NYI, we should allow permuted arrays, also affects hashCode.
+    if (!Arrays.equals(permissionInfos, cpi.getPermissionInfos())) {
+      return false;
+    }
+    if (!Arrays.equals(conditionInfos, cpi.getConditionInfos())) {
+      return false;
+    }
+    return access == cpi.getAccessDecision();
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public final int hashCode() {
+    if (name != null) {
+      return name.hashCode();
+    }
+    final int res = conditionInfos != null && conditionInfos.length > 0
+      ? conditionInfos[0].hashCode()
+      : 0;
+    return res + permissionInfos[0].hashCode();
+  }
+
+  //
+  // Package methods
+  //
+
+  static final Class<?>[] argClasses = new Class[] {Bundle.class, ConditionInfo.class};
+
+  /**
+   *
+   */
+  ConditionalPermission getConditionalPermission(Bundle bundle) {
+    final String me = "ConditionalPermissionInfoImpl.getConditionalPermission: ";
+
+    final ArrayList<Condition> conds
+      = new ArrayList<Condition>(conditionInfos==null ? 0 :conditionInfos.length);
+
+    if (conditionInfos != null) {
+      for (final ConditionInfo conditionInfo : conditionInfos) {
+        Class<?> clazz;
+        Condition c;
+        try {
+          clazz = Class.forName(conditionInfo.getType(), true,
+                                framework.getClassLoader(null));
+          Constructor<?> cons = null;
+          Method method = null;
+          try {
+            method = clazz.getMethod("getCondition", argClasses);
+            if ((method.getModifiers() & Modifier.STATIC) == 0) {
+              method = null;
+            }
+          } catch (final NoSuchMethodException ignore) {
+          }
+          if (method != null) {
+            if (debug.permissions) {
+              debug.println(me + "Invoke, " + method + " for bundle " + bundle);
+            }
+            c = (Condition) method.invoke(null, new Object[] { bundle,
+                                                              conditionInfo });
+          } else {
+            try {
+              cons = clazz.getConstructor(argClasses);
+            } catch (final NoSuchMethodException ignore) {
+            }
+            if (cons != null) {
+              if (debug.permissions) {
+                debug.println(me + "Construct, " + cons + " for bundle "
+                              + bundle);
+              }
+              c = (Condition) cons.newInstance(new Object[] { bundle,
+                                                             conditionInfo });
+            } else {
+              debug.println("NYI! Log faulty ConditionInfo object!?");
+              continue;
+            }
+          }
+          if (!c.isMutable()) {
+            if (!c.isPostponed() /* || debug.tck401compat */) {
+              if (c.isSatisfied()) {
+                if (debug.permissions) {
+                  debug.println(me + "Immutable condition ok, continue");
+                }
+                continue;
+              } else {
+                if (debug.permissions) {
+                  debug.println(me + "Immutable condition NOT ok, abort");
+                }
+                return null;
+              }
+            }
+          }
+          conds.add(c);
+        } catch (final Throwable t) {
+          debug.printStackTrace("NYI! Log failed Condition creation", t);
+          return null;
+        }
+      }
+    }
+
+    final Condition[] conditions = conds.toArray(new Condition[conds.size()]);
+
+    return new ConditionalPermission(conditions, getPermissions(), access, this);
+  }
+
+
+  /**
+   *
+   */
+  PermissionCollection getPermissions() {
+    if (permissions == null) {
+      permissions = new PermissionInfoPermissions(framework, null, permissionInfos);
+    }
+    return permissions;
+  }
+
+
+  /**
+   * Set storage for this Conditional Permission Info.
+   *
+   */
+  void setPermissionInfoStorage(ConditionalPermissionInfoStorage storage) {
+    cpis = storage;
+  }
+
+
+  /**
+   * Set the name of this Conditional Permission Info.
+   *
+   */
+  void setName(String newName) {
+    name = newName;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java
new file mode 100644
index 0000000..7983c47
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionInfoStorage.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2008-2014, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FWProps;
+import org.knopflerfish.framework.Util;
+import org.osgi.service.condpermadmin.ConditionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+
+class ConditionalPermissionInfoStorage {
+
+  private final File condPermDir;
+
+  private long lastFile;
+
+  private ArrayList<ConditionalPermissionInfoImpl> cpiTable
+    = new ArrayList<ConditionalPermissionInfoImpl>();
+
+  private final PermissionsHandle ph;
+
+  private int generation = -1;
+
+  final private Debug debug;
+
+  final private boolean readOnly;
+
+  /**
+   *
+   */
+  ConditionalPermissionInfoStorage(PermissionsHandle ph) {
+    this.ph = ph;
+    debug = ph.framework.debug;
+    readOnly = ph.framework.props.getBooleanProperty(FWProps.READ_ONLY_PROP);
+    condPermDir = Util.getFileStorage(ph.framework, "condperm", !readOnly);
+    if (condPermDir == null) {
+      System.err.println("Property org.osgi.framework.dir not set," +
+                         "conditional permission info will not be saved between sessions");
+    } else {
+      load();
+    }
+  }
+
+
+  /**
+   * Get the specified conditional permissions.
+   *
+   * @param name The name of the Conditional Permission Info to be returned.
+   * @return The Conditional Permission Info with the specified name.
+   */
+  synchronized ConditionalPermissionInfo get(String name) {
+    final int i = find(name);
+    if (i >= 0) {
+      return cpiTable.get(i);
+    }
+    return null;
+  }
+
+
+  /**
+   * Get an enumeration of copied conditional permission info table.
+   *
+   * @return Enumeration of Conditional Permission Info objects.
+   */
+  synchronized Enumeration<ConditionalPermissionInfo> getAllEnumeration() {
+    return (new Vector<ConditionalPermissionInfo>(cpiTable)).elements();
+  }
+
+
+  /**
+   * Get conditional permission info table.
+   * Should be called from synchronized code.
+   *
+   * @return ArrayList of Conditional Permission Info objects.
+   */
+  ArrayList<ConditionalPermissionInfoImpl> getAll() {
+    return cpiTable;
+  }
+
+
+  /**
+   * Get a copy conditional permission info table.
+   *
+   * @return Enumeration of Conditional Permission Info objects.
+   */
+  synchronized ConditionalPermissionUpdate getUpdate() {
+    return new ConditionalPermissionUpdateImpl(this, cpiTable, generation);
+  }
+
+
+  /**
+   * Add a new or updated an old specified conditional permission.
+   *
+   * @param name The name of the Conditional Permission Info to be changed.
+   * @param conds The Conditions that need to be satisfied to enable the
+   *        corresponding Permissions.
+   * @param perms The Permissions that are enable when the corresponding
+   *        Conditions are satisfied.
+   * @return The ConditionalPermissionInfo object for the added
+   *         conditional permission.
+   */
+  synchronized ConditionalPermissionInfo put(String name,
+                                             ConditionInfo conds[],
+                                             PermissionInfo perms[])
+  {
+    int oldIx;
+    if (name == null) {
+      name = uniqueName();
+      oldIx = -1;
+    } else if (name.equals("")) {
+      throw new IllegalArgumentException("Name can not be an empty string");
+    } else {
+      oldIx = find(name);
+    }
+    ConditionalPermissionInfoImpl old;
+    final ConditionalPermissionInfoImpl res
+      = new ConditionalPermissionInfoImpl(this, name, conds, perms, ConditionalPermissionInfo.ALLOW, ph.framework);
+    if (oldIx >= 0) {
+      old = cpiTable.set(oldIx, res);
+      updateChangedConditionalPermission(res, oldIx, oldIx);
+    } else {
+      old = null;
+      cpiTable.add(0, res);
+      updateChangedConditionalPermission(res, 0, -1);
+    }
+    generation++;
+    save();
+    if (debug.permissions) {
+      debug.println("CondPermStorage set " + res);
+      if (old != null) {
+        debug.println("CondPermStorage replaced " + old);
+      }
+    }
+    return res;
+  }
+
+
+  /**
+   * Remove any specified conditional permission with the specified name.
+   *
+   * @param name The name of the Conditional Permission Info to be changed.
+   */
+  synchronized void remove(ConditionalPermissionInfoImpl obj) {
+    final int pos = cpiTable.indexOf(obj);
+    if (debug.permissions) {
+      debug.println("CondPermStorage remove " + obj + ", pos=" + pos);
+    }
+    if (pos >= 0) {
+      cpiTable.remove(pos);
+      updateChangedConditionalPermission(null, -1, pos);
+      generation++;
+      save();
+      if (debug.permissions) {
+        debug.println("CondPermStorage removed " + obj);
+      }
+    }
+  }
+
+
+  /**
+   * Commit a new cpi table.
+   *
+   * @param updatedTable The Conditional Permission Info to commit.
+   * @param parentGen generation number of the active table that update is
+   * based on.
+   */
+  synchronized boolean commitUpdate(List<ConditionalPermissionInfo> updatedTable,
+                                    int parentGen)
+  {
+    if (parentGen != generation) {
+      return false;
+    }
+    final ArrayList<ConditionalPermissionInfo> checkTable
+      = new ArrayList<ConditionalPermissionInfo>(updatedTable);
+    final HashSet<String> names = new HashSet<String>();
+    int oi = 0;
+    ConditionalPermissionInfoImpl ocpi = oi < cpiTable.size() ? cpiTable.get(oi) : null;
+    final int [] update = new int[cpiTable.size() + checkTable.size()];
+    int ui = 0;
+    String uniqueNameBase = Integer.toString(generation, Character.MAX_RADIX) + "_";
+    int nextRemove = update.length;
+    int i = 0;
+    for ( ; i < checkTable.size(); i++) {
+      ConditionalPermissionInfoImpl cpi;
+      try {
+        cpi = (ConditionalPermissionInfoImpl)checkTable.get(i);
+      } catch (final ClassCastException _) {
+        throw new IllegalStateException("Illegal class of element in updated table, index=" + i);
+      }
+      if (cpi == null) {
+        throw new IllegalStateException("Updated table contains null element, index=" + i);
+      }
+      final String name = cpi.getName();
+      if (name != null) {
+        if (!names.add(name)) {
+          throw new IllegalStateException("Updated table contains elements with same name, name=" + name);
+        }
+        while (name.startsWith(uniqueNameBase)) {
+          uniqueNameBase += "_";
+        }
+      }
+      if (cpi == ocpi) {
+        // Update doesn't differ check next
+        ocpi = ++oi < cpiTable.size() ? cpiTable.get(oi) : null;
+      } else {
+        int removed = 0;
+        for (int j = oi + 1; j < cpiTable.size(); j++) {
+          if (cpiTable.get(j) == cpi) {
+            // Found updated, further down the table, removed or moved intermediate.
+            removed = j;
+            break;
+          }
+        }
+        if (removed != 0) {
+          // remove intermediate objects
+          while (oi++ < removed) {
+            if (nextRemove > ui) {
+              nextRemove = ui;
+            }
+            update[ui++] = -i - 1;
+          }
+          ocpi = oi < cpiTable.size() ? cpiTable.get(oi) : null;
+        } else {
+          // New element add it
+          update[ui++] = i;
+        }
+      }
+    }
+    // remove trailing objects
+    if (oi++ < cpiTable.size()) {
+      if (nextRemove > ui) {
+        nextRemove = ui;
+      }
+      do {
+        update[ui++] = -i - 1;
+      } while (oi++ < cpiTable.size());
+    }
+
+    // If no updates just return
+    if (ui == 0) {
+      return true;
+    }
+
+    // Perform updates on caches and set null names
+    final int NOP = Integer.MIN_VALUE;
+    int nops = 0;
+    int uniqueCounter = 0;
+    for (int pui = 0; pui < ui; pui++) {
+      int u = update[pui];
+      if (u >= 0) {
+        // We have an insert, see if we find a matching remove to avoid array shuffling
+        boolean remove = false;
+        if (nextRemove < ui) {
+          int rMatch = u + nextRemove - pui - nops;
+          if (update[nextRemove] + 1 == -rMatch) {
+            update[nextRemove] = NOP;
+            nops++;
+            while (++nextRemove < ui && update[nextRemove] >= 0)
+              ;
+            remove = true;
+          }
+        }
+        final ConditionalPermissionInfoImpl cpi = (ConditionalPermissionInfoImpl)checkTable.get(u);
+        if (cpi.getName() == null) {
+          cpi.setName(uniqueNameBase + uniqueCounter++);
+        }
+        cpi.setPermissionInfoStorage(this);
+        if (remove) {
+          cpiTable.set(u, cpi);
+          updateChangedConditionalPermission(cpi, u, u);
+        } else {
+          cpiTable.add(u, cpi);
+          updateChangedConditionalPermission(cpi, u, -1);
+        }
+      } else if (u != NOP) {
+        while (++nextRemove < ui && update[nextRemove] >= 0)
+          ;
+        u = -1 - u;
+        cpiTable.remove(u);
+        updateChangedConditionalPermission(null, -1, u);
+      } else {
+        nops--;
+      }
+    }
+    generation++;
+    save();
+    if (debug.permissions) {
+      debug.println("CondPermStorage commited update, " + ui + " changes");
+    }
+    return true;
+  }
+
+
+  /**
+   * Get number of ConditionPermissionInfos stored.
+   *
+   * @return Number of ConditionPermissionInfos objects as an int.
+   */
+  synchronized int size() {
+    return cpiTable.size();
+  }
+
+
+  //
+  // Private methods
+  //
+
+
+  private int find(String name) {
+    for (int i = 0; i < cpiTable.size(); i++) {
+      if (((ConditionalPermissionInfo)cpiTable.get(i)).getName().equals(name)) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+
+  /**
+   * Find a unique name.
+   */
+  private String uniqueName() {
+    String uniqueNameBase = Integer.toString(generation, Character.MAX_RADIX) + "_";
+    for (final Object element : cpiTable) {
+      final String name = ((ConditionalPermissionInfoImpl)element).getName();
+      while (name.startsWith(uniqueNameBase)) {
+        uniqueNameBase += "_";
+      }
+    }
+    return uniqueNameBase + "0";
+  }
+
+
+  /**
+   * Update cached information.
+   */
+  private void updateChangedConditionalPermission(ConditionalPermissionInfoImpl cpi,
+                                                  int pos,
+                                                  int removePos)
+  {
+    for (final Iterator<PermissionsWrapper> i = ph.getPermissionWrappers(); i
+        .hasNext();) {
+      i.next().updateChangedConditionalPermission(cpi, pos, removePos,
+                                                  cpiTable.size());
+    }
+  }
+
+  final static String END_MARKER = "END";
+
+  /**
+   * Save a permission array.
+   */
+  private void save() {
+    if (debug.permissions) {
+      debug.println("CondPermStorage save " + size() + " cpis, gen=" + generation);
+    }
+    if (condPermDir != null && !readOnly) {
+      AccessController.doPrivileged(new PrivilegedAction<Object>() {
+          public Object run() {
+            purge();
+            final File f = new File(condPermDir, Long.toString(++lastFile));
+            BufferedWriter out = null;
+            try {
+              out = new BufferedWriter(new FileWriter(f));
+              out.write("# Save generation " + generation + " at: " +  System.currentTimeMillis());
+              out.newLine();
+              for (final Object element : cpiTable) {
+                out.write(((ConditionalPermissionInfoImpl)element).toString());
+                out.newLine();
+              }
+              out.write(END_MARKER);
+              out.newLine();
+              out.close();
+            } catch (final IOException e) {
+              if (out != null) {
+                try {
+                  out.close();
+                } catch (final IOException ignore) { }
+                f.delete();
+              }
+              debug.printStackTrace("NYI! Report error", e);
+            }
+            return null;
+          }
+        });
+    }
+  }
+
+
+  /**
+   * Load all saved conditional permission data.
+   */
+  private void load() {
+    final File[] files = PermUtil.getSortedFiles(condPermDir);
+    lastFile = -1;
+    for (int i = files.length - 1; i >= 0; i--) {
+      try {
+        final long l = Long.parseLong(files[i].getName());
+        if (l > lastFile) {
+          lastFile = l;
+        }
+      } catch (final Exception ignore) {
+        // Ignore file that isn't a number
+        continue;
+      }
+      if (load(files[i])) {
+        break;
+      } else {
+        // Load failed, purge file
+        files[i].delete();
+      }
+    }
+  }
+
+
+  /**
+   * Load saved conditional permission data from specified file.
+   */
+  private boolean load(File fh) {
+    BufferedReader in = null;
+    final ArrayList<ConditionalPermissionInfoImpl> loadTable
+      = new ArrayList<ConditionalPermissionInfoImpl>();
+    try {
+      in = new BufferedReader(new FileReader(fh));
+      for (String l = in.readLine(); l != null; l = in.readLine()) {
+        l = l.trim();
+        if (l.equals("") || l.startsWith("#")) {
+          continue;
+        } else if (l.equals(END_MARKER)) {
+          in.close();
+          cpiTable = loadTable;
+          return true;
+        } else {
+          final ConditionalPermissionInfoImpl res
+            = new ConditionalPermissionInfoImpl(this, l, ph.framework);
+          loadTable.add(res);
+        }
+      }
+      in.close();
+    } catch (final Exception e) {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) { }
+      }
+      debug.printStackTrace("NYI! Report error", e);
+    }
+    return false;
+  }
+
+
+  /**
+   * Prune unused data files in conditional permission directory.
+   */
+  private void purge() {
+    final File[] files = PermUtil.getSortedFiles(condPermDir);
+    int okName = 0;
+    for (int i = files.length - 1; i >= 0; i--) {
+      try {
+        Long.parseLong(files[i].getName());
+        if (++okName > 2) {
+          files[i].delete();
+        }
+      } catch (final Exception ignore) {
+        // Ignore files which aren't a number.
+      }
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionSecurityManager.java b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionSecurityManager.java
new file mode 100644
index 0000000..314c8fb
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionSecurityManager.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.util.List;
+
+
+/**
+ * Interface for SecurityManager that fully supports conditional permissions.
+ */
+public interface ConditionalPermissionSecurityManager {
+
+  public boolean isPostponeAvailable();
+
+  public void savePostponement(List<ConditionalPermission> postponement, Object debug);
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionUpdateImpl.java b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionUpdateImpl.java
new file mode 100644
index 0000000..181c526
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/ConditionalPermissionUpdateImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
+
+
+/**
+ * Framework service to administer Conditional Permissions. Conditional
+ * Permissions can be added to, retrieved from, and removed from the framework.
+ *
+ */
+public class ConditionalPermissionUpdateImpl implements ConditionalPermissionUpdate {
+
+  private final ConditionalPermissionInfoStorage storage;
+
+  private final ArrayList<ConditionalPermissionInfo> cpiTable;
+
+  private final int parent;
+
+
+  /**
+   *
+   */
+  ConditionalPermissionUpdateImpl(ConditionalPermissionInfoStorage cpis,
+                                  ArrayList<ConditionalPermissionInfoImpl> org,
+                                  int generation)
+  {
+    storage = cpis;
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    final ArrayList<ConditionalPermissionInfo> clone = (ArrayList) org.clone();
+    cpiTable = clone;
+    parent = generation;
+  }
+
+
+  /**
+   *
+   */
+  public List<ConditionalPermissionInfo> getConditionalPermissionInfos() {
+    return cpiTable;
+  }
+
+
+  /**
+   *
+   */
+  public boolean commit() {
+    return storage.commitUpdate(cpiTable, parent);
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/FrameworkPolicy.java b/osgi/framework/src/org/knopflerfish/framework/permissions/FrameworkPolicy.java
new file mode 100644
index 0000000..1e32b12
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/FrameworkPolicy.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+
+import org.knopflerfish.framework.BundleURLStreamHandler;
+
+
+/**
+ * Implementation of a Permission Policy for Framework.
+ *
+ * Special handling for all protection domains that corresponds to a
+ * bundle, for all other delegate to given default policy (normally
+ * the policy file based policy implementation).
+ *
+ * @see java.security.Policy
+ * @author Jan Stein, Philippe Laporte, Gunnar Ekolin
+ */
+
+class FrameworkPolicy extends Policy {
+
+  /** The policy to delegate non-bundle permission requests to. */
+  private final Policy defaultPolicy;
+
+  private final PermissionsHandle ph;
+
+
+  /**
+   */
+  FrameworkPolicy(Policy policy, PermissionsHandle ph) {
+    this.defaultPolicy = policy;
+    this.ph = ph;
+  }
+
+
+  // Delegate to the wrapped defaultPolicy for all non-bundle domains.
+  @Override
+  public PermissionCollection getPermissions(ProtectionDomain pd) {
+    if (null==pd)
+      return defaultPolicy.getPermissions(pd);
+
+    final CodeSource cs = pd.getCodeSource();
+    if (null==cs)
+      return defaultPolicy.getPermissions(pd);
+
+    final URL u = cs.getLocation();
+    if (u != null && BundleURLStreamHandler.PROTOCOL.equals(u.getProtocol())) {
+      return getPermissions(cs);
+    } else {
+      return defaultPolicy.getPermissions(pd);
+    }
+  }
+
+
+  /**
+   */
+  @Override
+  public PermissionCollection getPermissions(CodeSource cs) {
+    if (null==cs) {
+      // Not a code source for a bundle, delegate to the default policy
+      return defaultPolicy.getPermissions(cs);
+    }
+
+    final URL u = cs.getLocation();
+    if (u != null && BundleURLStreamHandler.PROTOCOL.equals(u.getProtocol())) {
+      try {
+        final Long id = new Long(BundleURLStreamHandler.getId(u.getHost()));
+        //return getPermissions(id);
+        final PermissionCollection pc = ph.getPermissionCollection(id);
+        if (pc != null) {
+          return copy(pc);
+        }
+      } catch (final NumberFormatException ignore) { }
+      return new Permissions();
+    } else {
+      return defaultPolicy.getPermissions(cs);
+    }
+  }
+
+
+  private static PermissionCollection copy(PermissionCollection pc) {
+    // TODO, provide a copy-on-write collection?!
+    final Permissions pc2 = new Permissions();
+    for (final Enumeration<Permission> e = pc.elements(); e.hasMoreElements();) {
+      pc2.add(e.nextElement());
+    }
+    return pc2;
+  }
+
+
+  /**
+   */
+  @Override
+  public boolean implies(final ProtectionDomain pd, final Permission p) {
+    // NYI! Optimize here for framework.jar + bootclasses?
+    final CodeSource cs = null != pd ? pd.getCodeSource() : null;
+    final URL u = null != cs ? cs.getLocation() : null;
+    if (u != null && BundleURLStreamHandler.PROTOCOL.equals(u.getProtocol())) {
+      final PermissionCollection pc = getPermissions(cs);
+      return (pc == null) ? false : pc.implies(p);
+    } else {
+      final Boolean res = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+          public Boolean run() {
+            return new Boolean(defaultPolicy.implies(pd, p));
+          }
+        });
+      return res.booleanValue();
+    }
+  }
+
+
+  /**
+   */
+  @Override
+  public void refresh() {
+    // A bundle permissions is allways up to date, but we must
+    // propagate to the wrapped defaultPolicy.
+    defaultPolicy.refresh();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/KFSecurityManager.java b/osgi/framework/src/org/knopflerfish/framework/permissions/KFSecurityManager.java
new file mode 100644
index 0000000..fa2969d
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/KFSecurityManager.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.util.List;
+
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FrameworkContext;
+
+
+public class KFSecurityManager extends SecurityManager
+  implements ConditionalPermissionSecurityManager {
+
+  private final ThreadLocal<PostponementCheck<?>> postponementCheck
+    = new ThreadLocal<PostponementCheck<?>>();
+
+  @SuppressWarnings("unused")
+  private final Debug debug;
+
+  public KFSecurityManager(FrameworkContext fwCtx) {
+    this.debug = fwCtx.debug;
+  }
+
+  /**
+   *
+   */
+  @Override
+  public void checkPermission(Permission perm, Object context) {
+    if (!(context instanceof AccessControlContext)) {
+      throw new SecurityException("Context not an AccessControlContext");
+    }
+    final PostponementCheck<?> old = postponementCheck.get();
+    final PostponementCheck<?> pc
+      = new PostponementCheck<Object>((AccessControlContext) context, perm, old);
+    postponementCheck.set(pc);
+    try {
+      AccessController.doPrivileged(pc);
+    } finally {
+      postponementCheck.set(old);
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public void checkPermission(Permission perm) {
+    checkPermission(perm, getSecurityContext());
+  }
+
+
+  /**
+   * Is it possible to do postponement checks.
+   * This is only possible if a checkPermission via
+   * a ConditionalPermissionSecurityManager is in progress.
+   *
+   * @return true is postponement is available, otherwise false
+   */
+  public boolean isPostponeAvailable() {
+    return postponementCheck.get() != null;
+  }
+
+
+  /**
+   * NYI! Think about security here!
+   */
+  public void savePostponement(List<ConditionalPermission> postponement,
+                               Object debug)
+  {
+    final PostponementCheck<?> pc = postponementCheck.get();
+    pc.savePostponement(postponement, debug);
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PermUtil.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PermUtil.java
new file mode 100644
index 0000000..c7aa2af
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PermUtil.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2006-2010, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.io.*;
+
+
+class PermUtil {
+
+  /**
+   */
+  public static StringBuffer quote(String str, StringBuffer out) {
+    if (out == null) {
+      out = new StringBuffer();
+    }
+    out.append('"');
+    int len = str.length();
+    for (int i = 0; i < len; i++) {
+      char c = str.charAt(i);
+      switch (c) {
+      case '"' : case '\\' :
+        out.append('\\');
+        out.append(c);
+        break;
+      case '\r' :
+        out.append("\\r");
+        break;
+      case '\n' :
+        out.append("\\n");
+        break;
+      default :
+        out.append(c);
+        break;
+      }
+    }
+    out.append('"');
+    return out;
+  }
+
+
+  /**
+   */
+  public static int skipWhite(char [] ca, int pos) {
+    while (Character.isWhitespace(ca[pos])) {
+      pos++;
+    }
+    return pos;
+  }
+
+
+  /**
+   */
+  public static int endOfString(char [] ca, int pos, int len) {
+    while (pos < len && Character.isWhitespace(ca[pos])) {
+      pos++;
+    }
+    return pos == len ? -1 : pos;
+  }
+
+
+  /**
+   *
+   */
+  public static int unquote(char [] ca, int pos, StringBuffer out) {
+    if (ca[pos++] != '"') {
+      throw new IllegalArgumentException("Input not a quoted string");
+    }
+    while (ca[pos] != '"') {
+      char c = ca[pos++];
+      if (c == '\\') {
+        switch (ca[pos++]) {
+        case '"' :
+          c = '"';
+          break;
+        case '\\' :
+          c = '\\';
+          break;
+        case 'n' :
+          c = '\n';
+          break;
+        case 'r' :
+          c = '\r';
+          break;
+        default :
+          throw new IllegalArgumentException("Illegal escape char in quoted string: \\" + ca[pos-1]);
+        }
+      }
+      if (out != null) {
+        out.append(c);
+      }
+    }
+    return pos + 1;
+  }
+
+
+  /**
+   * Get data files sorted, first all nonnumeric
+   * and then the numeric in ascending order.
+   */
+  public static File[] getSortedFiles(File dir) {
+    String[] files = dir.list();
+    File[] res = new File[files.length];
+    long[] lfiles = new long[files.length];
+    int lf = -1;
+    int pos = 0;
+    for (int i = 0; i < files.length; i++) {
+      try {
+        long fval = Long.parseLong(files[i]);
+        int j;
+        for (j = lf; j >= 0; j--) {
+          if (fval > lfiles[j]) {
+            break;
+          }
+        }
+        if (j >= lf) {
+          lfiles[++lf] = fval;
+        } else {
+          lf++;
+          j++;
+          System.arraycopy(lfiles, j, lfiles, j+1, lf-j);
+          lfiles[j] = fval;
+        }
+        files[i] = null;
+      } catch (NumberFormatException ignore) {
+        res[pos++] = new File(dir, files[i]);
+      }
+    }
+    for (int i = 0; i <= lf; i++) {
+      res[pos++] = new File(dir, Long.toString(lfiles[i]));
+    }
+    return res;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionAdminImpl.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionAdminImpl.java
new file mode 100644
index 0000000..e2d771c
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionAdminImpl.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003-2010, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.security.AllPermission;
+
+import org.osgi.service.permissionadmin.*;
+
+
+
+/**
+ * Implementation of the PermissionAdmin service.
+ *
+ * @see org.osgi.service.permissionadmin.PermissionAdmin
+ * @author Jan Stein
+ * @author Philippe Laporte
+ */
+
+public class PermissionAdminImpl implements PermissionAdmin {
+
+  public final static String SPEC_VERSION = "1.2";
+
+  /**
+   * AllPermission used for permission check.
+   */
+  final private AllPermission ALL_PERMISSION = new AllPermission();
+
+  final private PermissionInfoStorage pinfos;
+
+
+  public PermissionAdminImpl(PermissionInfoStorage pis) {
+    pinfos = pis;
+  }
+
+
+  //
+  // Interface PermissionAdmin
+  //
+
+  /**
+   * Gets the permissions assigned to the bundle with the specified
+   * location.
+   *
+   * @param location The location of the bundle whose permissions are to
+   * be returned.
+   *
+   * @return The permissions assigned to the bundle with the specified
+   * location, or <tt>null</tt> if that bundle has not been assigned any
+   * permissions.
+   */
+  public PermissionInfo[] getPermissions(String location) {
+    PermissionInfo[] res = pinfos.get(location, null);
+    return res != null ? (PermissionInfo[])res.clone() : null;
+  }
+
+
+  /**
+   * Assigns the specified permissions to the bundle with the specified
+   * location.
+   *
+   * @param location The location of the bundle that will be assigned the
+   *        permissions.
+   * @param permissions The permissions to be assigned, or <code>null</code> if
+   *        the specified location is to be removed from the permission table.
+   * @throws SecurityException If the caller does not have
+   *            <code>AllPermission</code>.
+   */
+  public synchronized void setPermissions(String location,
+                                          PermissionInfo[] perms) {
+    SecurityManager sm = System.getSecurityManager();
+    if(null!=sm){
+      sm.checkPermission(ALL_PERMISSION);
+    }
+    if (perms != null) {
+      pinfos.put(location, (PermissionInfo[])perms.clone());
+    } else {
+      pinfos.remove(location);
+    }
+  }
+
+
+  /**
+   * Returns the bundle locations that have permissions assigned to them, that
+   * is, bundle locations for which an entry exists in the permission table.
+   *
+   * @return The locations of bundles that have been assigned any permissions,
+   *         or <tt>null</tt> if the permission table is empty.
+   */
+  public String[] getLocations() {
+    return pinfos.getKeys();
+  }
+
+
+  /**
+   * Gets the default permissions.
+   *
+   * <p>These are the permissions granted to any bundle that does not
+   * have permissions assigned to its location.
+   *
+   * @return The default permissions, or <tt>null</tt> if default
+   * permissions have not been defined.
+   */
+  public synchronized PermissionInfo[] getDefaultPermissions() {
+    PermissionInfo[] res = pinfos.getDefault(null);
+    return res != null ? (PermissionInfo[])res.clone() : null;
+  }
+
+
+  /**
+   * Sets the default permissions.
+   *
+   * <p>
+   * These are the permissions granted to any bundle that does not have
+   * permissions assigned to its location.
+   *
+   * @param permissions The default permissions, or <code>null</code> if the
+   *        default permissions are to be removed from the permission table.
+   * @throws SecurityException If the caller does not have
+   *            <code>AllPermission</code>.
+   */
+  public synchronized void setDefaultPermissions(PermissionInfo[] perms) {
+    SecurityManager sm = System.getSecurityManager();
+    if(null!=sm){
+      sm.checkPermission(ALL_PERMISSION);
+    }
+    if (perms != null) {
+      perms = (PermissionInfo[])perms.clone();
+    }
+    pinfos.putDefault(perms);
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoPermissions.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoPermissions.java
new file mode 100644
index 0000000..1043586
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoPermissions.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.UnresolvedPermission;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FrameworkContext;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+
+/**
+ * Local Permission handling, with lazy loading of permissions
+ *
+ * @author Jan Stein
+ */
+
+
+class PermissionInfoPermissions extends PermissionCollection {
+  private static final long serialVersionUID = 1L;
+
+  private Permissions pc ;
+  volatile private PermissionInfo [] pinfo;
+  private int unresolved;
+
+  final private File dataRoot;
+  final private FrameworkContext framework;
+  final private Debug debug;
+
+  static final Permission allPermission = new AllPermission();
+  /**
+   *
+   */
+  PermissionInfoPermissions(FrameworkContext fw,
+                            File root,
+                            InputStream ps) {
+    framework = fw;
+    debug = fw.debug;
+    dataRoot = root;
+    try {
+      final BufferedReader dis = new BufferedReader(new InputStreamReader(ps));
+      String l;
+      final ArrayList<PermissionInfo> tmp = new ArrayList<PermissionInfo>();
+      while ((l = dis.readLine()) != null) {
+        l = l.trim();
+        if (l.startsWith("#") || l.startsWith("//") || l.length() == 0) {
+          continue;
+        }
+        try {
+          tmp.add(new PermissionInfo(l));
+        } catch (final Exception e) {
+          // TODO, handle this error
+        }
+      }
+      if (!tmp.isEmpty()) {
+        pinfo = tmp.toArray(new PermissionInfo[tmp.size()]);
+      }
+    } catch (final IOException e) {
+      // TODO, handle this error
+    } finally {
+      try {
+        ps.close();
+      } catch (final IOException _ignore) { }
+    }
+    if (pinfo != null) {
+      unresolved = pinfo.length;
+    } else {
+      unresolved = 0;
+      pc = new Permissions();
+    }
+  }
+
+
+  /**
+   *
+   */
+  PermissionInfoPermissions(FrameworkContext fw,
+                            File root,
+                            PermissionInfo [] pinfo) {
+    framework = fw;
+    dataRoot = root;
+    debug = fw.debug;
+    if (pinfo != null) {
+      this.pinfo = pinfo.clone();
+      unresolved = pinfo.length;
+    } else {
+      unresolved = 0;
+    }
+    if (unresolved == 0) {
+      pc = new Permissions();
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public void add(Permission permission) {
+    throw new UnsupportedOperationException("Readonly");
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public Enumeration<Permission> elements() {
+    if (unresolved != 0) {
+      resolve();
+    }
+    return pc.elements();
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public boolean implies(final Permission permission) {
+    if (unresolved != 0) {
+      resolve();
+    }
+    return pc.implies(permission);
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public boolean isReadOnly() {
+    return true;
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public void setReadOnly() {
+  }
+
+
+  /**
+   *
+   */
+  synchronized private void resolve() {
+    if (pinfo == null) {
+      return;
+    }
+    if (pc == null) {
+      pc = new Permissions();
+    }
+    for (int i = 0; i < pinfo.length; i++) {
+      if (pinfo[i] != null) {
+        final Permission p = makePermission(pinfo[i]);
+        if (p != null) {
+          pc.add(p);
+          unresolved--;
+          pinfo[i] = null;
+        }
+      } else if (debug.permissions) {
+        debug.println("makePermission: Failed to create permission " + pinfo[i]);
+      }
+    }
+    if (unresolved == 0) {
+      pinfo = null;
+    }
+  }
+
+
+
+
+  /**
+   *
+   * @param pi PermissionInfo to enter into the PermissionCollection.
+   *
+   * @return
+   */
+  private Permission makePermission(PermissionInfo pi) {
+    final String t = pi.getType();
+    if ("java.security.AllPermission".equals(t)) {
+      return allPermission;
+    }
+    final ClassLoader cl = framework.getClassLoader(t);
+    if (cl == null) {
+      return null;
+    }
+    final String a = pi.getActions();
+    String n = pi.getName();
+    try {
+      final Class<?> pc = Class.forName(t, true, cl);
+      final Constructor<?> c = pc.getConstructor(new Class[] { String.class, String.class });
+      if (FilePermission.class.equals(pc) && !"<<ALL FILES>>".equals(n)) {
+        File f = new File(n);
+        // NYI! How should we handle different separator chars.
+        if (!f.isAbsolute()) {
+          if (dataRoot == null) {
+            return null;
+          }
+          f = new File(dataRoot, n);
+        }
+        n = f.getPath();
+      }
+      return (Permission) c.newInstance(new Object[] { n, a });
+    } catch (final ClassNotFoundException ignore) {
+      return new UnresolvedPermission(t, n, a, null);
+    } catch (final NoSuchMethodException ignore) {
+    } catch (final InstantiationException ignore) {
+    } catch (final IllegalAccessException ignore) {
+    } catch (final InvocationTargetException ignore) {
+    }
+    return null;
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoStorage.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoStorage.java
new file mode 100644
index 0000000..eab1220
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionInfoStorage.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2006-2014, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.security.AccessController;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.osgi.service.permissionadmin.PermissionInfo;
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FWProps;
+import org.knopflerfish.framework.FrameworkContext;
+import org.knopflerfish.framework.Util;
+
+
+class PermissionInfoStorage {
+
+  final static String DEFAULTPERM = "(java.security.AllPermission)";
+
+  private PermissionInfo[] initialDefault = null;
+
+  private final File permDir;
+
+  private long lastPermFile;
+
+  private final HashMap<String, Element> permissions
+    = new HashMap<String, Element>();
+
+  private PermissionInfo[] defaultPermissions;
+
+  private final HashMap<String, ArrayList<PermissionsWrapper>>
+    defaultInvalidateCallbacks
+      = new HashMap<String, ArrayList<PermissionsWrapper>>();
+
+  final private Debug debug;
+
+  final boolean readOnly;
+
+  /**
+   *
+   */
+  public PermissionInfoStorage(FrameworkContext ctx) {
+    debug = ctx.debug;
+    initialDefault = new PermissionInfo[] { new PermissionInfo(DEFAULTPERM) };
+    defaultPermissions = initialDefault;
+
+    readOnly = ctx.props.getBooleanProperty(FWProps.READ_ONLY_PROP);
+    permDir = Util.getFileStorage(ctx, "perms", !readOnly);
+    if (permDir == null) {
+      System.err.println("Property org.osgi.framework.dir not set," +
+                         "permission data will not be saved between sessions");
+    } else {
+      load();
+    }
+  }
+
+
+  /**
+   * Get the specified permissions to the bundle with the specified
+   * location.
+   *
+   * @param location The location of the bundle.
+   */
+  synchronized PermissionInfo[] get(String location, PermissionsWrapper callInvalidate) {
+    final Element res = permissions.get(location);
+    if (res != null) {
+      if (callInvalidate != null) {
+        if (res.invalidateCallback == null) {
+          res.invalidateCallback = new ArrayList<PermissionsWrapper>(2);
+        }
+        res.invalidateCallback.add(callInvalidate);
+      }
+      return res.pi;
+    }
+    return null;
+  }
+
+
+  /**
+   * Get the default permissions.
+   * <p>
+   * These are the permissions granted to any bundle that does not have
+   * permissions assigned to its location.
+   *
+   * @return the default permissions.
+   */
+  synchronized PermissionInfo[] getDefault(PermissionsWrapper callInvalidate) {
+    if (callInvalidate != null && callInvalidate.location != null) {
+      ArrayList<PermissionsWrapper> cil = defaultInvalidateCallbacks.get(callInvalidate.location);
+      if (cil == null) {
+        cil = new ArrayList<PermissionsWrapper>(2);
+        defaultInvalidateCallbacks.put(callInvalidate.location, cil);
+      }
+      cil.add(callInvalidate);
+    }
+    return defaultPermissions;
+  }
+
+
+  /**
+   * Returns the bundle locations that have permissions assigned to them, that
+   * is, bundle locations for which an entry exists in the permission table.
+   *
+   * @return The locations of bundles that have been assigned any permissions,
+   *         or <tt>null</tt> if the permission table is empty.
+   */
+  synchronized String [] getKeys() {
+    final int size = permissions.size();
+    if (size == 0) {
+      return null;
+    } else {
+      final String [] res = new String [size];
+      int ix = 0;
+      for (final String string : permissions.keySet()) {
+        res[ix++] = string;
+      }
+      return res;
+    }
+  }
+
+
+  /**
+   * Assigns the specified permissions to the bundle with the specified
+   * location.
+   *
+   * @param location The location of the bundle that will be assigned the
+   *        permissions.
+   * @param permissions The permissions to be assigned, or {@code null} if
+   *        the specified location is to be removed from the permission table.
+   */
+  synchronized void put(String location, PermissionInfo[] perms)
+  {
+    final Element old = permissions.put(location, new Element(perms));
+    save(location, perms);
+    final ArrayList<PermissionsWrapper> vpw = old != null ? old.invalidateCallback
+        : defaultInvalidateCallbacks.remove(location);
+    if (vpw != null) {
+      for (final PermissionsWrapper permissionsWrapper : vpw) {
+        permissionsWrapper.invalidate();
+      }
+    }
+  }
+
+  /**
+   * Sets the default permissions.
+   *
+   * <p>
+   * These are the permissions granted to any bundle that does not have
+   * permissions assigned to its location.
+   *
+   * @param permissions The default permissions, or {@code null} if the
+   *        default permissions are to be removed from the permission table.
+   * @throws SecurityException If the caller does not have
+   *            {@code AllPermission}.
+   */
+  synchronized void putDefault(PermissionInfo[] permissions) {
+    if (permissions != null) {
+      defaultPermissions = permissions;
+    } else {
+      defaultPermissions = initialDefault;
+    }
+    save(null, defaultPermissions);
+    for (final ArrayList<PermissionsWrapper> pws : defaultInvalidateCallbacks.values()) {
+      for (final PermissionsWrapper pw : pws) {
+        pw.invalidate();
+      }
+    }
+    defaultInvalidateCallbacks.clear();
+  }
+
+
+  /**
+   * Remove any specified permissions to the bundle with the specified
+   * location.
+   *
+   * @param location The location of the bundle.
+   */
+  synchronized void remove(String location) {
+    final Element old = permissions.remove(location);
+    save(location, null);
+    if (old != null && old.invalidateCallback != null) {
+      for (final PermissionsWrapper permissionsWrapper : old.invalidateCallback) {
+        permissionsWrapper.invalidate();
+      }
+    }
+  }
+
+
+  /**
+   * Remove any reference to specified permission collection in the
+   * callback tables.
+   *
+   * @param pc The permission collection to purge.
+   */
+  synchronized void purgeCallback(PermissionCollection pc) {
+    final PermissionsWrapper pw = (PermissionsWrapper)pc;
+    final Element e = permissions.get(pw.location);
+    if (e != null && e.invalidateCallback != null && e.invalidateCallback.remove(pw)) {
+      if (e.invalidateCallback.isEmpty()) {
+        e.invalidateCallback = null;
+      }
+    } else {
+      final ArrayList<PermissionsWrapper> cil
+        = defaultInvalidateCallbacks.get(pw.location);
+      if (cil != null && cil.remove(pw)) {
+        if (cil.isEmpty()) {
+          defaultInvalidateCallbacks.remove(pw);
+        }
+      }
+    }
+  }
+
+  //
+  // Private methods
+  //
+
+  /**
+   * Save a permission array.
+   */
+  private void save(final String location, final PermissionInfo [] perms) {
+    if (permDir != null && !readOnly) {
+      AccessController.doPrivileged(new PrivilegedAction<Object>() {
+          public Object run() {
+            File f;
+            String loc;
+            if (location != null) {
+              if (lastPermFile % 20 == 0) {
+                purge();
+              }
+              f = new File(permDir, Long.toString(++lastPermFile));
+              loc = location;
+            } else {
+              // NYI! keep backups
+              f = new File(permDir, "default");
+              loc = "defaultPermissions";
+            }
+            BufferedWriter out = null;
+            try {
+              out = new BufferedWriter(new FileWriter(f));
+              int p;
+              while ((p = loc.indexOf('\n')) != -1) {
+                out.write(loc.substring(0, ++p) + " ");
+                loc = loc.substring(p);
+              }
+              out.write(loc + "\n\n");
+              if (perms != null) {
+                for (final PermissionInfo perm : perms) {
+                  out.write(perm.getEncoded() + "\n");
+                }
+              } else {
+                out.write("NULL\n");
+              }
+              out.write("\n");
+              out.close();
+            } catch (final IOException e) {
+              if (out != null) {
+                try {
+                  out.close();
+                } catch (final IOException ignore) { }
+                f.delete();
+              }
+              debug.printStackTrace("NYI! Report error", e);
+            }
+            return null;
+          }
+        });
+    }
+  }
+
+
+  /**
+   * Load all saved permission data.
+   */
+  private void load() {
+    final File[] files = PermUtil.getSortedFiles(permDir);
+    for (final File file : files) {
+      load(file);
+    }
+    try {
+      lastPermFile = Long.parseLong(files[files.length - 1].getName());
+    } catch (final Exception e) {
+      lastPermFile = -1;
+    }
+  }
+
+  /**
+   * Load saved permission data from named file.
+   */
+  private void load(File fh) {
+    BufferedReader in = null;
+    final boolean isDefault = "default".equals(fh.getName());
+    try {
+      in = new BufferedReader(new FileReader(fh));
+      final String loc = parseLocation(in);
+      final ArrayList<PermissionInfo> piv = new ArrayList<PermissionInfo>();
+      // Read permissions
+      int c = in.read();
+      while (c != -1) {
+        final StringBuffer pe = new StringBuffer();
+        while (c != -1 && c != '\n') {
+          pe.append((char) c);
+          c = in.read();
+        }
+        final String line = pe.toString();
+        if ("NULL".equals(line)) {
+          // Clear any previous entries
+          if (isDefault) {
+            defaultPermissions = null;
+          } else {
+            permissions.remove(loc);
+          }
+          try {
+            in.close();
+          } catch (final IOException ignore) { }
+          return;
+        } else if ("".equals(line)) {
+          // Correct end with double NL
+          break;
+        }
+        piv.add(new PermissionInfo(line));
+        c = in.read();
+      }
+      if (c == -1) {
+        throw new IOException("Premature EOF when parsing permission file: " + fh.getName());
+      }
+      if (in.read() != -1) {
+        throw new IOException("Garbage at end of file when parsing permission file: " + fh.getName());
+      }
+      in.close();
+      final PermissionInfo[] pi = new PermissionInfo[piv.size()];
+      piv.toArray(pi);
+      if (isDefault) {
+        defaultPermissions = pi;
+      } else {
+        permissions.put(loc, new Element(pi));
+      }
+    } catch (final IOException e) {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (final IOException ignore) { }
+      }
+      debug.printStackTrace("NYI! Report error", e);
+    }
+  }
+
+  /**
+   * Parse location data.
+   */
+  private String parseLocation(Reader in) throws IOException {
+    final StringBuffer loc = new StringBuffer();
+    int c;
+    // Read location
+    while ((c = in.read()) != -1) {
+      final char cc = (char)c;
+      if (cc == '\n') {
+        c = in.read();
+        if (c != ' ') {
+          break;
+        }
+      }
+      loc.append(cc);
+    }
+    return loc.toString();
+  }
+
+  /**
+   * Purge old saved permission data.
+   * Keep two latest version of permission data.
+   */
+  private void purge() {
+    final HashMap<String, Boolean> foundTwo = new HashMap<String, Boolean>();
+    final File[] files = PermUtil.getSortedFiles(permDir);
+    for (int i = files.length - 1; i >= 0; i--) {
+      String loc;
+      BufferedReader in = null;
+      try {
+        in = new BufferedReader(new FileReader(files[i]));
+        loc = parseLocation(in);
+      } catch (final IOException ignore) {
+        files[i].delete();
+        continue;
+      } finally {
+        if (in != null) {
+          try {
+            in.close();
+          } catch (final IOException ignore) { }
+        }
+      }
+      final Boolean v = foundTwo.get(loc);
+      if (v != null) {
+        if (v.booleanValue()) {
+          files[i].delete();
+        } else {
+          foundTwo.put(loc, new Boolean(true));
+        }
+      } else {
+        foundTwo.put(loc, new Boolean(false));
+      }
+    }
+  }
+
+
+  static class Element {
+    PermissionInfo[] pi;
+    ArrayList /* PermissionsWrapper */<PermissionsWrapper> invalidateCallback = null;
+
+    Element(PermissionInfo[] pi) {
+      this.pi = pi;
+    }
+  }
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionsHandle.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionsHandle.java
new file mode 100644
index 0000000..a39611e
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionsHandle.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2006-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.io.InputStream;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+import org.osgi.framework.Bundle;
+
+import org.knopflerfish.framework.FrameworkContext;
+
+
+/**
+ *
+ */
+public class PermissionsHandle {
+
+  FrameworkContext framework;
+
+  private final PermissionInfoStorage pinfos;
+  private final ConditionalPermissionInfoStorage cpinfos;
+  private final Hashtable<Long, PermissionsWrapper> pcCache
+    = new Hashtable<Long, PermissionsWrapper>();
+  private final PermissionAdminImpl pa;
+  private final ConditionalPermissionAdminImpl cpa;
+
+
+  /**
+   *
+   */
+  public PermissionsHandle(FrameworkContext fw) {
+    framework = fw;
+    pinfos = new PermissionInfoStorage(fw);
+    pa = new PermissionAdminImpl(pinfos);
+    cpinfos = new ConditionalPermissionInfoStorage(this);
+    cpa = new ConditionalPermissionAdminImpl(cpinfos, pinfos, fw);
+    Policy.setPolicy(new FrameworkPolicy(Policy.getPolicy(), this));
+  }
+
+
+  /**
+   * Get PermissionAdmin service.
+   *
+   * @return PermissionAdmin service object.
+   */
+  public PermissionAdminImpl getPermissionAdminService() {
+    return pa;
+  }
+
+
+  /**
+   * Get ConditionalPermissionAdmin service.
+   *
+   * @return ConditionalPermissionAdmin service object.
+   */
+  public ConditionalPermissionAdminImpl getConditionalPermissionAdminService() {
+    return cpa;
+  }
+
+
+  /**
+   * Gets the permissionCollection assigned to the bundle with the specified id.
+   * The collection contains the configured permissions for the bundle location
+   * plus implicit granted permissions (i.e FilePermission for the data area).
+   *
+   * @param bid The bundle id whose permissions are to be returned.
+   *
+   * @return The permissions assigned to the bundle with the specified
+   * location, or the default permissions if that bundle has not been assigned
+   * any permissions or does not yet exist.
+   */
+  public PermissionCollection getPermissionCollection(Long bid) {
+    return pcCache.get(bid);
+  }
+
+
+  /**
+   * Create the permissionCollection assigned to the bundle.
+   * We return a permission wrapper so that we can change it dynamically.
+   *
+   * @param loc Location of bundle whose permissions are to be created.
+   * @param b Bundle whose permissions are to be created.
+   * @param localPerms New local permissions for the bundle.
+   *
+   * @return The permissions assigned to the bundle with the specified
+   * location
+   */
+  public  PermissionCollection createPermissionCollection(String loc,
+                                                          Bundle b,
+                                                          InputStream localPerms) {
+    final Long bid = new Long(b.getBundleId());
+    // Need to lock cond.perm. changes, when adding a new PermissionsWrapper
+    PermissionsWrapper pc;
+    synchronized (cpinfos) {
+      pc = new PermissionsWrapper(framework, pinfos, cpinfos, loc, b, localPerms);
+      pcCache.put(bid, pc);
+    }
+    return pc;
+  }
+
+
+  /**
+   * Remove cached information about specified bundle.
+   *
+   * @param bid Bundle ID for bundle to be purged.
+   *
+   * @return True if we purged something, which means that we purged the last
+   *         permissionCollection not a zombie.
+   */
+  public boolean purgePermissionCollection(Long bid, PermissionCollection pc) {
+    pinfos.purgeCallback(pc);
+    if (pcCache.get(bid) == pc) {
+      pcCache.remove(bid);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Get iterator over all active PermissionWrappers.
+   *
+   * @return Iterator of PermissionWrappers
+   */
+  Iterator<PermissionsWrapper> getPermissionWrappers() {
+    return pcCache.values().iterator();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionsWrapper.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionsWrapper.java
new file mode 100644
index 0000000..09b057f
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PermissionsWrapper.java
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2003-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.io.InputStream;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.PropertyPermission;
+
+import org.osgi.framework.AdminPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.CapabilityPermission;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FrameworkContext;
+
+
+/**
+ * Wraps Permissions so that we can update it dynamically.
+ *
+ * @author Jan Stein, Philippe Laporte
+ */
+
+
+public class PermissionsWrapper extends PermissionCollection {
+  private static final long serialVersionUID = 1L;
+
+  String location;
+
+  private final Bundle bundle;
+  private final PermissionInfoStorage pinfos;
+  private final ConditionalPermissionInfoStorage cpinfos;
+  private PermissionCollection implicitPermissions;
+  private PermissionCollection localPermissions;
+  private volatile PermissionCollection systemPermissions;
+  private File dataRoot;
+  private boolean readOnly = false;
+  private ArrayList<ConditionalPermission> condPermList = null;
+  private ConditionalPermissionSecurityManager cpsm;
+
+  final private FrameworkContext framework;
+  final private Debug debug;
+
+  /**
+   *
+   */
+  PermissionsWrapper(FrameworkContext fw,
+                     PermissionInfoStorage pis,
+                     ConditionalPermissionInfoStorage cpis,
+                     String loc,
+                     Bundle b,
+                     InputStream localPerms) {
+    this.framework = fw;
+    debug = fw.debug;
+    pinfos = pis;
+    cpinfos = cpis;
+    location = loc;
+    bundle = b;
+    // If location is null, then we have a dummy bundle.
+    // Used for ConditionalPermissionAdmin.getAccessControlerContext()
+    if (loc != null) {
+      final SecurityManager sm = System.getSecurityManager();
+      if (sm instanceof ConditionalPermissionSecurityManager) {
+        cpsm = (ConditionalPermissionSecurityManager)sm;
+      }
+      dataRoot = fw.getDataStorage(b.getBundleId());
+      if (localPerms != null) {
+        localPermissions = new PermissionInfoPermissions(fw, dataRoot, localPerms);
+      }
+      implicitPermissions = makeImplicitPermissionCollection(fw, b);
+    }
+    initCondPermList();
+    systemPermissions = makePermissionCollection();
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public void add(Permission permission) {
+    final PermissionCollection p = getPerms();
+    if (p != null) {
+      p.add(permission);
+    } else {
+      throw new RuntimeException("NYI! Using Conditional Permissions");
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public Enumeration<Permission> elements() {
+    final PermissionCollection p = getPerms();
+    if (p == null) {
+      throw new RuntimeException("NYI! Using Conditional Permissions 2");
+    }
+
+    return new Enumeration<Permission>() {
+        private Enumeration<Permission> implicitElements = implicitPermissions.elements();
+        private final Enumeration<Permission> systemElements = p.elements();
+
+        public boolean hasMoreElements() {
+          if (implicitElements != null) {
+            if (implicitElements.hasMoreElements()) {
+              return true;
+            }
+            implicitElements = null;
+          }
+          return systemElements.hasMoreElements();
+        }
+
+
+        public Permission nextElement() {
+          if (implicitElements != null) {
+            try {
+              return implicitElements.nextElement();
+            } catch (final NoSuchElementException _ignore) { }
+            implicitElements = null;
+          }
+          return systemElements.nextElement();
+        }
+      };
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public boolean implies(final Permission permission) {
+    final String me = "PermissionWrapper.implies: ";
+    if (implicitPermissions != null && implicitPermissions.implies(permission)) {
+      if (debug.permissions) {
+        debug.println(me + "Implicitly OK for, " + permission);
+      }
+      return true;
+    } else if (localPermissions != null && !localPermissions.implies(permission)) {
+      if (debug.permissions) {
+        debug.println(me + "No localpermissions for, " + permission);
+      }
+      return false;
+    } else {
+      final PermissionCollection p = getPerms();
+      boolean res;
+      if (p != null) {
+        res = p.implies(permission);
+        if (debug.permissions) {
+          debug.println(me + (res ? "OK" : "No") +  " framework permission for, " + permission);
+        }
+      } else {
+        res = conditionalPermissionImplies(permission);
+        if (debug.permissions) {
+          debug.println(me + (res ? "OK" : "No") +  " conditional permission for, " + permission);
+        }
+      }
+      return res;
+    }
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public boolean isReadOnly() {
+    return readOnly;
+  }
+
+
+  /**
+   *
+   */
+  @Override
+  public void setReadOnly() {
+    if (!readOnly) {
+      readOnly = true;
+      final PermissionCollection p = getPerms();
+      if (p != null) {
+        p.setReadOnly();
+      } else {
+        // TBD, Conditional permission already readonly?
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  synchronized void invalidate() {
+    systemPermissions = null;
+  }
+
+
+  /**
+   *
+   */
+  private PermissionCollection getPerms0() {
+    if (systemPermissions == null) {
+      final PermissionCollection p = makePermissionCollection();
+      if (readOnly && p != null) {
+        p.setReadOnly();
+      }
+      systemPermissions = p;
+    }
+    return systemPermissions;
+  }
+
+
+  /**
+   *
+   */
+  private PermissionCollection getPerms() {
+    if (framework.props.isDoubleCheckedLockingSafe) {
+       if (systemPermissions == null) {
+        synchronized (this) {
+          return getPerms0();
+        }
+      }
+      return systemPermissions;
+    } else {
+      synchronized (this) {
+        return getPerms0();
+      }
+    }
+  }
+
+
+  /**
+   *
+   */
+  private PermissionCollection makeImplicitPermissionCollection(FrameworkContext fw, Bundle b) {
+    // NYI, perhaps we should optimize this collection.
+    final Permissions pc = new Permissions();
+    if (dataRoot != null) {
+      pc.add(new FilePermission(dataRoot.getPath(), "read,write"));
+      pc.add(new FilePermission((new File(dataRoot, "-")).getPath(),
+                                "read,write,delete"));
+    }
+    final StringBuffer sb = new StringBuffer("(id=");
+    sb.append(b.getBundleId());
+    sb.append(")");
+    pc.add(new AdminPermission(sb.toString(),
+                               AdminPermission.RESOURCE + "," +
+                               AdminPermission.METADATA + "," +
+                               AdminPermission.CLASS));
+    pc.add(new PropertyPermission("org.osgi.framework.*", "read"));
+    pc.add(new CapabilityPermission(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE,
+                                    CapabilityPermission.REQUIRE));
+    return pc;
+  }
+
+
+  /**
+   * Create the permissionCollection assigned to the bundle.
+   * The collection contains the configured permissions for the bundle location.
+   * Build the permissionCollection based on a set PermissionInfo objects. All the
+   * permissions that are available in the CLASSPATH are constructed and all the
+   * bundle based permissions are constructed as UnresolvedPermissions.
+   *
+   * @return The permissions assigned to the bundle with the specified
+   * location, or the default permissions if that bundle has not been assigned
+   * any permissions.
+   */
+  private PermissionCollection makePermissionCollection() {
+    PermissionInfo[] pi = pinfos.get(location, this) ;
+    final boolean useDefault = (pi == null);
+    if (useDefault) {
+      if (cpinfos != null && cpinfos.size() > 0) {
+        return null;
+      }
+      pi = pinfos.getDefault(this);
+    }
+    return new PermissionInfoPermissions(framework, useDefault ? null : dataRoot, pi);
+  }
+
+
+  /**
+   *
+   */
+  private boolean conditionalPermissionImplies(Permission permission) {
+    List<ConditionalPermission> postponement;
+    if (cpsm != null && cpsm.isPostponeAvailable()) {
+      postponement = new ArrayList<ConditionalPermission>();
+    } else {
+      postponement = null;
+    }
+    String immediateAccess = null;
+    // TBD, should condPermList by guard from changes!?
+    for (final Object element : condPermList) {
+      final ConditionalPermission cp = (ConditionalPermission)element;
+      if (cp == null) {
+        // Permission is already checked and is immutable and failed.
+        continue;
+      }
+      if (debug.permissions) {
+        debug.println("conditionalPermissionImplies: Check if " + cp + " implies " + permission + " for " + bundle);
+      }
+      if (cp.checkImmediateOk(permission, postponement == null)) {
+        if (postponement != null) {
+          postponement.add(cp);
+        }
+        if (cp.hasPostponed()) {
+          if (debug.permissions) {
+            debug.println("conditionalPermissionImplies: " + cp + " with postponement implies " + permission + " for " + bundle);
+          }
+        } else {
+          if (debug.permissions) {
+            debug.println("conditionalPermissionImplies: " + cp + " implies " + permission + " for " + bundle + ", end search");
+          }
+          immediateAccess = cp.access;
+          break;
+        }
+      } else {
+        if (debug.permissions) {
+          debug.println("conditionalPermissionImplies: " + cp + " does NOT imply " + permission + " for " + bundle);
+        }
+      }
+    }
+    if (postponement != null) {
+      // Optimize superfluous
+      int offset;
+      if (immediateAccess == null) {
+        immediateAccess = ConditionalPermissionInfo.DENY;
+        offset = 1;
+      } else {
+        offset = 2;
+      }
+      for (int pos = postponement.size() - offset; pos >= 0; pos--) {
+        if (postponement.get(pos).access == immediateAccess) {
+          final Object pruned = postponement.remove(pos);
+          if (debug.permissions) {
+            debug.println("conditionalPermissionImplies: pruned, " + pruned + " for " + bundle);
+          }
+        } else {
+          break;
+        }
+      }
+      // If we only have deny, do deny
+      if (immediateAccess == ConditionalPermissionInfo.DENY && postponement.size() < offset) {
+        return false;
+      }
+      if (debug.permissions) {
+        debug.println("conditionalPermissionImplies: postpone check of " + permission + " for " + bundle);
+      }
+      cpsm.savePostponement(postponement, debug);
+      return true;
+    } else {
+      return immediateAccess == ConditionalPermissionInfo.ALLOW;
+    }
+  }
+
+
+  /**
+   *
+   */
+  synchronized void updateChangedConditionalPermission(ConditionalPermissionInfoImpl cpi,
+                                                       int cpi_pos,
+                                                       int remove_pos,
+                                                       int expected_size)
+  {
+    final ConditionalPermission new_cp = cpi != null ? cpi
+        .getConditionalPermission(bundle) : null;
+    @SuppressWarnings("unused")
+    ConditionalPermission old_cp;
+    if (cpi_pos == remove_pos) {
+      old_cp = condPermList.set(cpi_pos, new_cp);
+    } else if (remove_pos == -1) {
+      condPermList.add(cpi_pos, new_cp);
+      old_cp = null;
+    } else if (cpi_pos == -1) {
+      old_cp = condPermList.remove(remove_pos);
+    } else {
+      // Case with different remove & insert position not used, yet
+      throw new RuntimeException("NYI");
+    }
+    if (expected_size != condPermList.size()) {
+      debug.printStackTrace("ASSERT, table size differ, " + expected_size
+                            + " != " + condPermList.size(), new Throwable());
+      throw new RuntimeException("ASSERT ERROR");
+    }
+    // TBD! How to optimize?   if (new_cp != null || old_cp != null) {
+      invalidate();
+    //    }
+  }
+
+
+  /**
+   *
+   */
+  private void initCondPermList() {
+    // cpinfos is locked when we are here.
+    final ArrayList<ConditionalPermissionInfoImpl> cpis = cpinfos.getAll();
+    condPermList = new ArrayList<ConditionalPermission>(cpis.size());
+    // TBD, perhaps we should go back to lazy instantiation.
+    for (final ConditionalPermissionInfoImpl cpi : cpis) {
+      if (debug.permissions) {
+        debug.println("conditionalPermissionImplies: " + cpi + " Bundle#" + bundle.getBundleId());
+      }
+      condPermList.add(cpi.getConditionalPermission(bundle));
+    }
+    invalidate();
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/permissions/PostponementCheck.java b/osgi/framework/src/org/knopflerfish/framework/permissions/PostponementCheck.java
new file mode 100644
index 0000000..9170cc0
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/permissions/PostponementCheck.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2009-2013, 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.
+ */
+
+package org.knopflerfish.framework.permissions;
+
+import java.security.AccessControlContext;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+
+import org.osgi.service.condpermadmin.Condition;
+import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
+
+import org.knopflerfish.framework.Debug;
+
+
+class PostponementCheck<T> implements PrivilegedAction<T> {
+
+  private final AccessControlContext acc;
+  private final Permission perm;
+  private ArrayList<Class<? extends Condition>> checkedClasses;
+  private ArrayList<List<ConditionalPermission>> ppList = null;
+
+  private Debug debug = null;
+
+  /**
+   *
+   */
+  PostponementCheck(AccessControlContext acc, Permission perm, PostponementCheck<?> previous) {
+    this.acc = acc;
+    this.perm = perm;
+    checkedClasses = previous != null ? previous.getCheckedClasses() : null;
+  }
+
+
+  /**
+   *
+   */
+  ArrayList<Class<? extends Condition>> getCheckedClasses() {
+    if (checkedClasses != null) {
+      @SuppressWarnings("unchecked")
+      final ArrayList<Class<? extends Condition>> res
+        = (ArrayList<Class<? extends Condition>>) checkedClasses.clone();
+      return res;
+    }
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  public void savePostponement(List<ConditionalPermission> postponement, Object debug) {
+    if (ppList == null) {
+      ppList = new ArrayList<List<ConditionalPermission>>(2);
+      this.debug = (Debug)debug;
+    }
+    ppList.add(postponement);
+  }
+
+
+  /**
+   *
+   */
+  public T run() {
+    acc.checkPermission(perm);
+    checkPostponements();
+    return null;
+  }
+
+
+  /**
+   *
+   */
+  private void checkPostponements() {
+    if (ppList != null) {
+      final HashMap<Class<? extends Condition>, Dictionary<Object,Object>> condDict
+        = new HashMap<Class<? extends Condition>, Dictionary<Object,Object>>();
+      if (checkedClasses == null) {
+        checkedClasses = new ArrayList<Class<? extends Condition>>();
+      }
+      // Loop through all bundle protection domains found on stack
+      for (final List<?> list : ppList) {
+        // Loop through all matching ConditionalPermissions
+        boolean deny = true;
+        for (final Object name : list) {
+          final ConditionalPermission cp = (ConditionalPermission)name;
+          if (!cp.checkPostponedOk(condDict, checkedClasses)) {
+            // ConditionPermissional didn't match, check next
+            continue;
+          }
+          if (cp.access == ConditionalPermissionInfo.ALLOW) {
+            // We allow, check next protection domain
+            deny = false;
+          }
+          break;
+        }
+        if (deny) {
+          // Denied
+          if (debug.permissions) {
+            debug.println("CHECK_POSTPONE: postponement failed");
+          }
+          throw new SecurityException("Postponed conditions failed");
+        }
+      }
+      if (debug.permissions) {
+        debug.println("CHECK_POSTPONE: postponement ok");
+      }
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java b/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java
new file mode 100644
index 0000000..0cdbb8e
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/validator/JKSValidator.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2009-2014, 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.
+ */
+
+package org.knopflerfish.framework.validator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathParameters;
+import java.security.cert.CertPathValidator;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+
+import org.knopflerfish.framework.Debug;
+import org.knopflerfish.framework.FrameworkContext;
+import org.knopflerfish.framework.Util;
+import org.knopflerfish.framework.Validator;
+import org.osgi.framework.Constants;
+
+
+/**
+ * JKS certificate validator
+ *
+ * @author Jan Stein
+ */
+public class JKSValidator implements Validator {
+
+  /**
+   * Property strings.
+   */
+  final private static String CA_CERTS_PROP =
+    "org.knopflerfish.framework.validator.jks.ca_certs";
+
+  final private static String CA_CERTS_PASSWORD_PROP =
+    "org.knopflerfish.framework.validator.jks.ca_certs_password";
+
+  final private static String CERT_PROVIDER_PROP =
+    "org.knopflerfish.framework.validator.jks.cert_provider";
+
+  final private static String CERT_DATE_PROP =
+      "org.knopflerfish.framework.validator.date";
+
+
+  /**
+   * Certificate provider;
+   */
+  private String certProvider;
+
+  /**
+   * 
+   */
+  private CertificateFactory certFactory = null;
+
+  /**
+   * 
+   */
+  private CertPathValidator certValidator = null;
+
+  /**
+   *
+   */
+  final private KeyStore keystore;
+
+  /**
+   *
+   */
+  private Date validationDate;
+
+  /**
+   * NYI make it configurable
+   */
+  private boolean trustKeys = true;
+
+  /**
+   * Debug handle
+   */
+  final private Debug debug;
+
+
+  /**
+   * Create a JKS based validator.
+   *
+   * @param fw FrameworkContext used to get configuration properties.
+   * @throws KeyStoreException 
+   * @throws ParseException 
+   */
+  public JKSValidator(FrameworkContext fw) throws KeyStoreException, ParseException
+  {
+    debug = fw.debug;
+    keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+    // NYI! Handle serveral repositories.
+    fw.props.setPropertyDefault(CERT_PROVIDER_PROP, "");
+    certProvider = fw.props.getProperty(CERT_PROVIDER_PROP);
+    String repos = fw.props.getProperty(Constants.FRAMEWORK_TRUST_REPOSITORIES);
+    if (repos.length() > 0) {
+      String [] l = Util.splitwords(repos, File.pathSeparator);
+      for (int i = 0; i < l.length; i++) {
+        String certRepo = l[i].trim();
+        if (certRepo.length() > 0) {
+          loadKeyStore(certRepo, null);
+        }
+      }
+    } else {
+      fw.props.setPropertyDefault(CA_CERTS_PROP,
+                                  System.getProperty("java.home")
+                                  + "/lib/security/cacerts".replace('/', File.separatorChar));
+      fw.props.setPropertyDefault(CA_CERTS_PASSWORD_PROP, "changeit");
+      final String caCertsFileName = fw.props.getProperty(CA_CERTS_PROP);
+      if (caCertsFileName != null) {
+        loadKeyStore(caCertsFileName, fw.props.getProperty(CA_CERTS_PASSWORD_PROP));
+      }
+    }
+    String d = fw.props.getProperty(CERT_DATE_PROP);
+    if (d != null) {
+      try {
+        validationDate = DateFormat.getDateInstance(DateFormat.SHORT).parse(d);
+      } catch (ParseException _ignore) {
+        // Always try US format
+        validationDate = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US).parse(d);
+      }
+      if (debug.certificates) {
+        debug.println("Set validation date to " + validationDate);
+      }
+    } else {
+      validationDate = null;
+    }
+  }
+
+
+  /**
+   * Check if a certificate chain is to be trusted.
+   *
+   * @return true, if validator trusts certificate chain, otherwise false.
+   */
+  public boolean validateCertificateChain(List<X509Certificate> chain) {
+    if (keystore == null) {
+      return false;
+    }
+    try {
+      CertPath c = getCertificateFactory().generateCertPath(chain);
+      CertPathValidator cpv = getCertPathValidator();
+      CertPathParameters params = getCertPathParameters(keystore);
+      cpv.validate(c, params);
+    } catch (GeneralSecurityException gse) {
+      if (debug.certificates) {
+        debug.printStackTrace("Failed to validate cert", gse);
+      }
+      // NYI! Log this?
+      return false;
+    }
+    return true;
+  }
+
+
+  /**
+   * 
+   */
+  private CertificateFactory getCertificateFactory()
+    throws GeneralSecurityException
+  {
+    if (certFactory == null) {
+      if (certProvider.length() > 0) {
+        certFactory = CertificateFactory.getInstance("X.509", certProvider);
+      } else {
+        certFactory = CertificateFactory.getInstance("X.509");
+      }
+    }
+    return certFactory;
+  }
+
+
+  /**
+   * 
+   */
+  private CertPathParameters getCertPathParameters(KeyStore keystore)
+    throws GeneralSecurityException
+  {
+    HashSet<TrustAnchor> tas = new HashSet<TrustAnchor>();
+    for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements(); ) {
+      String name = e.nextElement();
+      Certificate c = keystore.getCertificate(name);
+      if (c != null) {
+        if (trustKeys || keystore.isCertificateEntry(name)) {
+          tas.add(new TrustAnchor((X509Certificate)c, null)); 
+        }
+      }
+    }
+    PKIXParameters p = new PKIXParameters(tas);
+    // NYI! Handle CRLs
+    p.setRevocationEnabled(false);
+    if (validationDate != null) {
+      p.setDate(validationDate);
+    }
+    return p;
+  }
+
+
+  /**
+   * 
+   */
+  private CertPathValidator getCertPathValidator()
+    throws GeneralSecurityException
+  {
+    if (certValidator == null) {
+      if (certProvider.length() > 0) {
+        certValidator = CertPathValidator.getInstance("PKIX", certProvider);
+      } else {
+        certValidator = CertPathValidator.getInstance("PKIX");
+      }
+    }
+    return certValidator;
+  }
+
+
+  /**
+   * 
+   */
+  private void loadKeyStore(String file, String password) {
+    FileInputStream is = null;
+    try {
+      is = new FileInputStream(file);
+      keystore.load(is, password != null ? password.toCharArray() : null);
+      if (debug.certificates) {
+        debug.println("Loaded keystore, " + file);
+      }
+    } catch (Exception e) {
+      if (is != null) {
+        try {
+          is.close();
+        } catch (IOException ignore) { }
+      }
+      debug.printStackTrace("Failed to load keystore, " + file, e);
+    }
+  }
+
+}
diff --git a/osgi/framework/src/org/knopflerfish/framework/validator/SelfSignedValidator.java b/osgi/framework/src/org/knopflerfish/framework/validator/SelfSignedValidator.java
new file mode 100644
index 0000000..743fac5
--- /dev/null
+++ b/osgi/framework/src/org/knopflerfish/framework/validator/SelfSignedValidator.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009-2014, 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.
+ */
+
+package org.knopflerfish.framework.validator;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.List;
+
+import org.knopflerfish.framework.FrameworkContext;
+import org.knopflerfish.framework.Validator;
+
+/**
+ * Self signed certificate validator
+ * 
+ * @author Jan Stein
+ */
+public class SelfSignedValidator implements Validator {
+
+  final private static String CERT_DATE_PROP =
+      "org.knopflerfish.framework.validator.date";
+
+  /**
+   *
+   */
+  private Date validationDate;
+
+  /**
+   * Create a SelfSignedCertificate validator.
+   * 
+   * @param fw
+   *          FrameworkContext used to get configuration properties.
+   * @throws ParseException 
+   */
+  public SelfSignedValidator(FrameworkContext fw) throws ParseException {
+    String d = fw.props.getProperty(CERT_DATE_PROP);
+    if (d != null) {
+      validationDate = DateFormat.getDateInstance(DateFormat.SHORT).parse(d);
+    } else {
+      validationDate = null;
+    }
+  }
+
+  /**
+   * Check if a certificate chain is to be trusted. We expect the input to be a
+   * correct chain.
+   * 
+   * @return true, if validator trusts certificate chain, otherwise false.
+   */
+  public boolean validateCertificateChain(List<X509Certificate> chain) {
+    try {
+      for (X509Certificate cert : chain) {
+        if (validationDate != null) {
+          cert.checkValidity(validationDate);
+        } else {
+          cert.checkValidity();
+        }
+      }
+    } catch (CertificateException _) {
+      return false;
+    }
+    return true;
+  }
+
+}
diff --git a/osgi/framework/src/org/osgi/framework/AdaptPermission.java b/osgi/framework/src/org/osgi/framework/AdaptPermission.java
new file mode 100644
index 0000000..fbe70c1
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/AdaptPermission.java
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A bundle's authority to adapt an object to a type.
+ * 
+ * <p>
+ * {@code AdaptPermission} has one action: {@code adapt}.
+ * 
+ * @ThreadSafe
+ * @version $Id: 3bc095bd294db2d8ea25971a3d71991de1495b1a $
+ */
+public final class AdaptPermission extends BasicPermission {
+
+	private static final long						serialVersionUID	= 1L;
+
+	/**
+	 * The action string {@code initiate}.
+	 */
+	public final static String						ADAPT				= "adapt";
+
+	private final static int						ACTION_ADAPT		= 0x00000001;
+	private final static int						ACTION_ALL			= ACTION_ADAPT;
+	final static int								ACTION_NONE			= 0;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions				= null;
+
+	/**
+	 * The bundle used by this AdaptPermission.
+	 */
+	transient final Bundle							bundle;
+
+	/**
+	 * This holds a Filter matching object used to evaluate the filter in
+	 * implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * Creates a new granted {@code AdaptPermission} object.
+	 * 
+	 * This constructor must only be used to create a permission that is going
+	 * to be checked.
+	 * <p>
+	 * Examples:
+	 * 
+	 * <pre>
+	 * (adaptClass=com.acme.*)
+	 * (&(signer=\*,o=ACME,c=US)(adaptClass=com.acme.*))
+	 * (signer=\*,o=ACME,c=US)
+	 * </pre>
+	 * 
+	 * <p>
+	 * When a signer key is used within the filter expression the signer value
+	 * must escape the special filter chars ('*', '(', ')').
+	 * <p>
+	 * The name is specified as a filter expression. The filter gives access to
+	 * the following attributes:
+	 * <ul>
+	 * <li>signer - A Distinguished Name chain used to sign the exporting
+	 * bundle. Wildcards in a DN are not matched according to the filter string
+	 * rules, but according to the rules defined for a DN chain.</li>
+	 * <li>location - The location of the exporting bundle.</li>
+	 * <li>id - The bundle ID of the exporting bundle.</li>
+	 * <li>name - The symbolic name of the exporting bundle.</li>
+	 * <li>adaptClass - The name of the type to which an object can be adapted.</li>
+	 * </ul>
+	 * Filter attribute names are processed in a case sensitive manner.
+	 * 
+	 * @param filter A filter expression. Filter attribute names are processed
+	 *        in a case sensitive manner. A special value of {@code "*"} can be
+	 *        used to match all adaptations.
+	 * @param actions {@code adapt}.
+	 * @throws IllegalArgumentException If the filter has an invalid syntax.
+	 */
+	public AdaptPermission(String filter, String actions) {
+		this(parseFilter(filter), parseActions(actions));
+	}
+
+	/**
+	 * Creates a new requested {@code AdaptPermission} object to be used by the
+	 * code that must perform {@code checkPermission}. {@code AdaptPermission}
+	 * objects created with this constructor cannot be added to an
+	 * {@code AdaptPermission} permission collection.
+	 * 
+	 * @param adaptClass The name of the type to which an object can be adapted.
+	 * @param adaptableBundle The bundle associated with the object being
+	 *        adapted.
+	 * @param actions {@code adapt}.
+	 */
+	public AdaptPermission(String adaptClass, Bundle adaptableBundle, String actions) {
+		super(adaptClass);
+		setTransients(null, parseActions(actions));
+		this.bundle = adaptableBundle;
+		if (adaptClass == null) {
+			throw new NullPointerException("adaptClass must not be null");
+		}
+		if (adaptableBundle == null) {
+			throw new NullPointerException("adaptableBundle must not be null");
+		}
+	}
+
+	/**
+	 * Package private constructor used by AdaptPermissionCollection.
+	 * 
+	 * @param filter name filter
+	 * @param mask action mask
+	 */
+	AdaptPermission(Filter filter, int mask) {
+		super((filter == null) ? "*" : filter.toString());
+		setTransients(filter, mask);
+		this.bundle = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param filter Permission's filter or {@code null} for wildcard.
+	 * @param mask action mask
+	 */
+	private void setTransients(Filter filter, int mask) {
+		this.filter = filter;
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		this.action_mask = mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 4 && (a[i - 4] == 'a' || a[i - 4] == 'A')
+					&& (a[i - 3] == 'd' || a[i - 3] == 'D')
+					&& (a[i - 2] == 'a' || a[i - 2] == 'A')
+					&& (a[i - 1] == 'p' || a[i - 1] == 'P')
+					&& (a[i] == 't' || a[i] == 'T')) {
+				matchlen = 5;
+				mask |= ACTION_ADAPT;
+
+			} else {
+				// parse error
+				throw new IllegalArgumentException("invalid actions: " + actions);
+			}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfadapt". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid actions: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		filterString = filterString.trim();
+		if (filterString.equals("*")) {
+			return null;
+		}
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if the specified permission is implied by this object.
+	 * 
+	 * <p>
+	 * This method checks that the filter of the target is implied by the adapt
+	 * class name of this object. The list of {@code AdaptPermission} actions
+	 * must either match or allow for the list of the target object to imply the
+	 * target {@code AdaptPermission} action.
+	 * <p>
+	 * 
+	 * @param p The requested permission.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof AdaptPermission)) {
+			return false;
+		}
+		AdaptPermission requested = (AdaptPermission) p;
+		if (bundle != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested AdaptPermission which has already be
+	 *        validated as a proper argument. The requested AdaptPermission must
+	 *        not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(AdaptPermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+		/* Get filter */
+		Filter f = filter;
+		if (f == null) {
+			// it's "*"
+			return true;
+		}
+		return f.matches(requested.getProperties());
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * {@code AdaptPermission} actions.
+	 * 
+	 * <p>
+	 * Always returns present {@code AdaptPermission} actions in the following
+	 * order: {@code adapt}.
+	 * 
+	 * @return Canonical string representation of the {@code AdaptPermission}
+	 *         actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			actions = result = ADAPT;
+		}
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code AdaptPermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new AdaptPermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two {@code AdaptPermission} objects.
+	 * 
+	 * This method checks that specified permission has the same name and
+	 * {@code AdaptPermission} actions as this {@code AdaptPermission} object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code AdaptPermission} object.
+	 * @return {@code true} if {@code obj} is a {@code AdaptPermission}, and has
+	 *         the same name and actions as this {@code AdaptPermission} object;
+	 *         {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof AdaptPermission)) {
+			return false;
+		}
+
+		AdaptPermission cp = (AdaptPermission) obj;
+
+		return (action_mask == cp.action_mask) && getName().equals(cp.getName()) && ((bundle == cp.bundle) || ((bundle != null) && bundle.equals(cp.bundle)));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (bundle != null) {
+			h = 31 * h + bundle.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission object to a
+	 * stream. The actions are serialized, and the superclass takes care of the
+	 * name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		if (bundle != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(parseFilter(getName()), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code <@link AdaptPermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
+	 * 
+	 * @return a map of properties for this permission.
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		final Map<String, Object> map = new HashMap<String, Object>(5);
+		map.put("adaptClass", getName());
+		if (bundle != null) {
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				public Object run() {
+					map.put("id", new Long(bundle.getBundleId()));
+					map.put("location", bundle.getLocation());
+					String name = bundle.getSymbolicName();
+					if (name != null) {
+						map.put("name", name);
+					}
+					SignerProperty signer = new SignerProperty(bundle);
+					if (signer.isBundleSigned()) {
+						map.put("signer", signer);
+					}
+					return null;
+				}
+			});
+		}
+		return properties = map;
+	}
+}
+
+/**
+ * Stores a set of {@code AdaptPermission} permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class AdaptPermissionCollection extends PermissionCollection {
+	static final long						serialVersionUID	= -3350758995234427603L;
+	/**
+	 * Collection of permissions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, AdaptPermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean							all_allowed;
+
+	/**
+	 * Create an empty AdaptPermissions object.
+	 */
+	public AdaptPermissionCollection() {
+		permissions = new HashMap<String, AdaptPermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The {@code AdaptPermission} object to add.
+	 * @throws IllegalArgumentException If the specified permission is not a
+	 *         {@code AdaptPermission} instance or was constructed with a Bundle
+	 *         object.
+	 * @throws SecurityException If this {@code AdaptPermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof AdaptPermission)) {
+			throw new IllegalArgumentException("invalid permission: " + permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+		}
+
+		final AdaptPermission ap = (AdaptPermission) permission;
+		if (ap.bundle != null) {
+			throw new IllegalArgumentException("cannot add to collection: " + ap);
+		}
+
+		final String name = ap.getName();
+		synchronized (this) {
+			Map<String, AdaptPermission> pc = permissions;
+			final AdaptPermission existing = pc.get(name);
+			if (existing != null) {
+				final int oldMask = existing.action_mask;
+				final int newMask = ap.action_mask;
+				if (oldMask != newMask) {
+					pc.put(name, new AdaptPermission(existing.filter, oldMask | newMask));
+
+				}
+			} else {
+				pc.put(name, ap);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if the specified permissions implies the permissions expressed
+	 * in {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare with this
+	 *        {@code AdaptPermission} object.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof AdaptPermission)) {
+			return false;
+		}
+		final AdaptPermission requested = (AdaptPermission) permission;
+		/* if requested permission has a filter, then it is an invalid argument */
+		if (requested.filter != null) {
+			return false;
+		}
+
+		int effective = AdaptPermission.ACTION_NONE;
+
+		Collection<AdaptPermission> perms;
+		synchronized (this) {
+			Map<String, AdaptPermission> pc = permissions;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				AdaptPermission ap = pc.get("*");
+				if (ap != null) {
+					effective |= ap.action_mask;
+					final int desired = requested.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+			perms = pc.values();
+		}
+		/* iterate one by one over filteredPermissions */
+		for (AdaptPermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns an enumeration of all {@code AdaptPermission} objects in the
+	 * container.
+	 * 
+	 * @return Enumeration of all {@code AdaptPermission} objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", HashMap.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", permissions);
+		pfields.put("all_allowed", all_allowed);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		permissions = (HashMap<String, AdaptPermission>) gfields.get("permissions", null);
+		all_allowed = gfields.get("all_allowed", false);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/AdminPermission.java b/osgi/framework/src/org/osgi/framework/AdminPermission.java
new file mode 100644
index 0000000..324360c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/AdminPermission.java
@@ -0,0 +1,1004 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A bundle's authority to perform specific privileged administrative operations
+ * on or to get sensitive information about a bundle. The actions for this
+ * permission are:
+ * 
+ * <pre>
+ * Action             Methods
+ * class              Bundle.loadClass
+ * execute            Bundle.start
+ *                    Bundle.stop
+ *                    BundleStartLevel.setStartLevel
+ * extensionLifecycle BundleContext.installBundle for extension bundles
+ *                    Bundle.update for extension bundles
+ *                    Bundle.uninstall for extension bundles
+ * lifecycle          BundleContext.installBundle
+ *                    Bundle.update
+ *                    Bundle.uninstall
+ * listener           BundleContext.addBundleListener for SynchronousBundleListener
+ *                    BundleContext.removeBundleListener for SynchronousBundleListener
+ * metadata           Bundle.getHeaders
+ *                    Bundle.getLocation
+ * resolve            FrameworkWiring.refreshBundles
+ *                    FrameworkWiring.resolveBundles
+ * resource           Bundle.getResource
+ *                    Bundle.getResources
+ *                    Bundle.getEntry
+ *                    Bundle.getEntryPaths
+ *                    Bundle.findEntries
+ *                    Bundle resource/entry URL creation
+ * startlevel         FrameworkStartLevel.setStartLevel
+ *                    FrameworkStartLevel.setInitialBundleStartLevel
+ * context            Bundle.getBundleContext
+ * weave              WovenClass.setBytes
+ *                    WovenClass.getDynamicImports for modification
+ * </pre>
+ * 
+ * <p>
+ * The special action "*" will represent all actions. The
+ * {@code resolve} action is implied by the {@code class}, {@code execute} and
+ * {@code resource} actions.
+ * <p>
+ * The name of this permission is a filter expression. The filter gives access
+ * to the following attributes:
+ * <ul>
+ * <li>signer - A Distinguished Name chain used to sign a bundle. Wildcards in a
+ * DN are not matched according to the filter string rules, but according to the
+ * rules defined for a DN chain.</li>
+ * <li>location - The location of a bundle.</li>
+ * <li>id - The bundle ID of the designated bundle.</li>
+ * <li>name - The symbolic name of a bundle.</li>
+ * </ul>
+ * Filter attribute names are processed in a case sensitive manner.
+ * 
+ * @ThreadSafe
+ * @version $Id: cd883e81fde210ce8f0cabaebea377378d672818 $
+ */
+
+public final class AdminPermission extends BasicPermission {
+	static final long								serialVersionUID			= 307051004521261705L;
+
+	/**
+	 * The action string {@code class}. The {@code class} action implies the
+	 * {@code resolve} action.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						CLASS						= "class";
+	/**
+	 * The action string {@code execute}. The {@code execute} action implies the
+	 * {@code resolve} action.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						EXECUTE						= "execute";
+	/**
+	 * The action string {@code extensionLifecycle}.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						EXTENSIONLIFECYCLE			= "extensionLifecycle";
+	/**
+	 * The action string {@code lifecycle}.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						LIFECYCLE					= "lifecycle";
+	/**
+	 * The action string {@code listener}.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						LISTENER					= "listener";
+	/**
+	 * The action string {@code metadata}.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						METADATA					= "metadata";
+	/**
+	 * The action string {@code resolve}. The {@code resolve} action is implied
+	 * by the {@code class}, {@code execute} and {@code resource} actions.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						RESOLVE						= "resolve";
+	/**
+	 * The action string {@code resource}. The {@code resource} action implies
+	 * the {@code resolve} action.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						RESOURCE					= "resource";
+	/**
+	 * The action string {@code startlevel}.
+	 * 
+	 * @since 1.3
+	 */
+	public final static String						STARTLEVEL					= "startlevel";
+
+	/**
+	 * The action string {@code context}.
+	 * 
+	 * @since 1.4
+	 */
+	public final static String						CONTEXT						= "context";
+
+	/**
+	 * The action string {@code weave}.
+	 * 
+	 * @since 1.6
+	 */
+	public final static String						WEAVE						= "weave";
+
+	private final static int						ACTION_CLASS				= 0x00000001;
+	private final static int						ACTION_EXECUTE				= 0x00000002;
+	private final static int						ACTION_LIFECYCLE			= 0x00000004;
+	private final static int						ACTION_LISTENER				= 0x00000008;
+	private final static int						ACTION_METADATA				= 0x00000010;
+	private final static int						ACTION_RESOLVE				= 0x00000040;
+	private final static int						ACTION_RESOURCE				= 0x00000080;
+	private final static int						ACTION_STARTLEVEL			= 0x00000100;
+	private final static int						ACTION_EXTENSIONLIFECYCLE	= 0x00000200;
+	private final static int						ACTION_CONTEXT				= 0x00000400;
+	private final static int						ACTION_WEAVE				= 0x00000800;
+	private final static int						ACTION_ALL					= ACTION_CLASS | ACTION_EXECUTE | ACTION_LIFECYCLE | ACTION_LISTENER | ACTION_METADATA | ACTION_RESOLVE
+																						| ACTION_RESOURCE | ACTION_STARTLEVEL | ACTION_EXTENSIONLIFECYCLE | ACTION_CONTEXT | ACTION_WEAVE;
+	final static int								ACTION_NONE					= 0;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions						= null;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * If this AdminPermission was constructed with a filter, this holds a
+	 * Filter matching object used to evaluate the filter in implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * The bundle governed by this AdminPermission - only used if filter == null
+	 */
+	transient final Bundle							bundle;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * ThreadLocal used to determine if we have recursively called
+	 * getProperties.
+	 */
+	private static final ThreadLocal<Bundle>		recurse						= new ThreadLocal<Bundle>();
+
+	/**
+	 * Creates a new {@code AdminPermission} object that matches all bundles and
+	 * has all actions. Equivalent to AdminPermission("*","*");
+	 */
+	public AdminPermission() {
+		this(null, ACTION_ALL);
+	}
+
+	/**
+	 * Create a new AdminPermission.
+	 * 
+	 * This constructor must only be used to create a permission that is going
+	 * to be checked.
+	 * <p>
+	 * Examples:
+	 * 
+	 * <pre>
+	 * (signer=\*,o=ACME,c=US)   
+	 * (&(signer=\*,o=ACME,c=US)(name=com.acme.*)(location=http://www.acme.com/bundles/*))
+	 * (id>=1)
+	 * </pre>
+	 * 
+	 * <p>
+	 * When a signer key is used within the filter expression the signer value
+	 * must escape the special filter chars ('*', '(', ')').
+	 * <p>
+	 * Null arguments are equivalent to "*".
+	 * 
+	 * @param filter A filter expression that can use signer, location, id, and
+	 *        name keys. A value of "*" or {@code null} matches all
+	 *        bundle. Filter attribute names are processed in a case sensitive
+	 *        manner.
+	 * @param actions {@code class}, {@code execute}, {@code extensionLifecycle}
+	 *        , {@code lifecycle}, {@code listener}, {@code metadata},
+	 *        {@code resolve} , {@code resource}, {@code startlevel},
+	 *        {@code context} or {@code weave}. A value of "*" or {@code null}
+	 *        indicates all actions.
+	 * @throws IllegalArgumentException If the filter has an invalid syntax.
+	 */
+	public AdminPermission(String filter, String actions) {
+		// arguments will be null if called from a PermissionInfo defined with
+		// no args
+		this(parseFilter(filter), parseActions(actions));
+	}
+
+	/**
+	 * Creates a new requested {@code AdminPermission} object to be used by the
+	 * code that must perform {@code checkPermission}. {@code AdminPermission}
+	 * objects created with this constructor cannot be added to an
+	 * {@code AdminPermission} permission collection.
+	 * 
+	 * @param bundle A bundle.
+	 * @param actions {@code class}, {@code execute}, {@code extensionLifecycle}
+	 *        , {@code lifecycle}, {@code listener}, {@code metadata},
+	 *        {@code resolve} , {@code resource}, {@code startlevel},
+	 *        {@code context}, {@code weave}. A value of "*" or {@code null}
+	 *        indicates all actions.
+	 * @since 1.3
+	 */
+	public AdminPermission(Bundle bundle, String actions) {
+		super(createName(bundle));
+		setTransients(null, parseActions(actions));
+		this.bundle = bundle;
+	}
+
+	/**
+	 * Create a permission name from a Bundle
+	 * 
+	 * @param bundle Bundle to use to create permission name.
+	 * @return permission name.
+	 */
+	private static String createName(Bundle bundle) {
+		if (bundle == null) {
+			throw new IllegalArgumentException("bundle must not be null");
+		}
+		StringBuffer sb = new StringBuffer("(id=");
+		sb.append(bundle.getBundleId());
+		sb.append(")");
+		return sb.toString();
+	}
+
+	/**
+	 * Package private constructor used by AdminPermissionCollection.
+	 * 
+	 * @param filter name filter or {@code null} for wildcard.
+	 * @param mask action mask
+	 */
+	AdminPermission(Filter filter, int mask) {
+		super((filter == null) ? "*" : filter.toString());
+		setTransients(filter, mask);
+		this.bundle = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param filter Permission's filter or {@code null} for wildcard.
+	 * @param mask action mask
+	 */
+	private void setTransients(Filter filter, int mask) {
+		this.filter = filter;
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		this.action_mask = mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		if ((actions == null) || actions.equals("*")) {
+			return ACTION_ALL;
+		}
+
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 4 && (a[i - 4] == 'c' || a[i - 4] == 'C')
+					&& (a[i - 3] == 'l' || a[i - 3] == 'L')
+					&& (a[i - 2] == 'a' || a[i - 2] == 'A')
+					&& (a[i - 1] == 's' || a[i - 1] == 'S')
+					&& (a[i] == 's' || a[i] == 'S')) {
+				matchlen = 5;
+				mask |= ACTION_CLASS | ACTION_RESOLVE;
+
+			} else
+				if (i >= 6 && (a[i - 6] == 'e' || a[i - 6] == 'E')
+						&& (a[i - 5] == 'x' || a[i - 5] == 'X')
+						&& (a[i - 4] == 'e' || a[i - 4] == 'E')
+						&& (a[i - 3] == 'c' || a[i - 3] == 'C')
+						&& (a[i - 2] == 'u' || a[i - 2] == 'U')
+						&& (a[i - 1] == 't' || a[i - 1] == 'T')
+						&& (a[i] == 'e' || a[i] == 'E')) {
+					matchlen = 7;
+					mask |= ACTION_EXECUTE | ACTION_RESOLVE;
+
+				} else
+					if (i >= 17 && (a[i - 17] == 'e' || a[i - 17] == 'E')
+							&& (a[i - 16] == 'x' || a[i - 16] == 'X')
+							&& (a[i - 15] == 't' || a[i - 15] == 'T')
+							&& (a[i - 14] == 'e' || a[i - 14] == 'E')
+							&& (a[i - 13] == 'n' || a[i - 13] == 'N')
+							&& (a[i - 12] == 's' || a[i - 12] == 'S')
+							&& (a[i - 11] == 'i' || a[i - 11] == 'I')
+							&& (a[i - 10] == 'o' || a[i - 10] == 'O')
+							&& (a[i - 9] == 'n' || a[i - 9] == 'N')
+							&& (a[i - 8] == 'l' || a[i - 8] == 'L')
+							&& (a[i - 7] == 'i' || a[i - 7] == 'I')
+							&& (a[i - 6] == 'f' || a[i - 6] == 'F')
+							&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+							&& (a[i - 4] == 'c' || a[i - 4] == 'C')
+							&& (a[i - 3] == 'y' || a[i - 3] == 'Y')
+							&& (a[i - 2] == 'c' || a[i - 2] == 'C')
+							&& (a[i - 1] == 'l' || a[i - 1] == 'L')
+							&& (a[i] == 'e' || a[i] == 'E')) {
+						matchlen = 18;
+						mask |= ACTION_EXTENSIONLIFECYCLE;
+
+					} else
+						if (i >= 8 && (a[i - 8] == 'l' || a[i - 8] == 'L')
+								&& (a[i - 7] == 'i' || a[i - 7] == 'I')
+								&& (a[i - 6] == 'f' || a[i - 6] == 'F')
+								&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+								&& (a[i - 4] == 'c' || a[i - 4] == 'C')
+								&& (a[i - 3] == 'y' || a[i - 3] == 'Y')
+								&& (a[i - 2] == 'c' || a[i - 2] == 'C')
+								&& (a[i - 1] == 'l' || a[i - 1] == 'L')
+								&& (a[i] == 'e' || a[i] == 'E')) {
+							matchlen = 9;
+							mask |= ACTION_LIFECYCLE;
+
+						} else
+							if (i >= 7 && (a[i - 7] == 'l' || a[i - 7] == 'L')
+									&& (a[i - 6] == 'i' || a[i - 6] == 'I')
+									&& (a[i - 5] == 's' || a[i - 5] == 'S')
+									&& (a[i - 4] == 't' || a[i - 4] == 'T')
+									&& (a[i - 3] == 'e' || a[i - 3] == 'E')
+									&& (a[i - 2] == 'n' || a[i - 2] == 'N')
+									&& (a[i - 1] == 'e' || a[i - 1] == 'E')
+									&& (a[i] == 'r' || a[i] == 'R')) {
+								matchlen = 8;
+								mask |= ACTION_LISTENER;
+
+							} else
+								if (i >= 7
+										&& (a[i - 7] == 'm' || a[i - 7] == 'M')
+										&& (a[i - 6] == 'e' || a[i - 6] == 'E')
+										&& (a[i - 5] == 't' || a[i - 5] == 'T')
+										&& (a[i - 4] == 'a' || a[i - 4] == 'A')
+										&& (a[i - 3] == 'd' || a[i - 3] == 'D')
+										&& (a[i - 2] == 'a' || a[i - 2] == 'A')
+										&& (a[i - 1] == 't' || a[i - 1] == 'T')
+										&& (a[i] == 'a' || a[i] == 'A')) {
+									matchlen = 8;
+									mask |= ACTION_METADATA;
+
+								} else
+									if (i >= 6
+											&& (a[i - 6] == 'r' || a[i - 6] == 'R')
+											&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+											&& (a[i - 4] == 's' || a[i - 4] == 'S')
+											&& (a[i - 3] == 'o' || a[i - 3] == 'O')
+											&& (a[i - 2] == 'l' || a[i - 2] == 'L')
+											&& (a[i - 1] == 'v' || a[i - 1] == 'V')
+											&& (a[i] == 'e' || a[i] == 'E')) {
+										matchlen = 7;
+										mask |= ACTION_RESOLVE;
+
+									} else
+										if (i >= 7
+												&& (a[i - 7] == 'r' || a[i - 7] == 'R')
+												&& (a[i - 6] == 'e' || a[i - 6] == 'E')
+												&& (a[i - 5] == 's' || a[i - 5] == 'S')
+												&& (a[i - 4] == 'o' || a[i - 4] == 'O')
+												&& (a[i - 3] == 'u' || a[i - 3] == 'U')
+												&& (a[i - 2] == 'r' || a[i - 2] == 'R')
+												&& (a[i - 1] == 'c' || a[i - 1] == 'C')
+												&& (a[i] == 'e' || a[i] == 'E')) {
+											matchlen = 8;
+											mask |= ACTION_RESOURCE
+													| ACTION_RESOLVE;
+
+										} else
+											if (i >= 9
+													&& (a[i - 9] == 's' || a[i - 9] == 'S')
+													&& (a[i - 8] == 't' || a[i - 8] == 'T')
+													&& (a[i - 7] == 'a' || a[i - 7] == 'A')
+													&& (a[i - 6] == 'r' || a[i - 6] == 'R')
+													&& (a[i - 5] == 't' || a[i - 5] == 'T')
+													&& (a[i - 4] == 'l' || a[i - 4] == 'L')
+													&& (a[i - 3] == 'e' || a[i - 3] == 'E')
+													&& (a[i - 2] == 'v' || a[i - 2] == 'V')
+													&& (a[i - 1] == 'e' || a[i - 1] == 'E')
+													&& (a[i] == 'l' || a[i] == 'L')) {
+												matchlen = 10;
+												mask |= ACTION_STARTLEVEL;
+
+											} else
+												if (i >= 6
+														&& (a[i - 6] == 'c' || a[i - 6] == 'C')
+														&& (a[i - 5] == 'o' || a[i - 5] == 'O')
+														&& (a[i - 4] == 'n' || a[i - 4] == 'N')
+														&& (a[i - 3] == 't' || a[i - 3] == 'T')
+														&& (a[i - 2] == 'e' || a[i - 2] == 'E')
+														&& (a[i - 1] == 'x' || a[i - 1] == 'X')
+														&& (a[i] == 't' || a[i] == 'T')) {
+													matchlen = 7;
+													mask |= ACTION_CONTEXT;
+
+												} else
+													if (i >= 4
+															&& (a[i - 4] == 'w' || a[i - 4] == 'W')
+															&& (a[i - 3] == 'e' || a[i - 3] == 'E')
+															&& (a[i - 2] == 'a' || a[i - 2] == 'A')
+															&& (a[i - 1] == 'v' || a[i - 1] == 'V')
+															&& (a[i] == 'e' || a[i] == 'E')) {
+														matchlen = 5;
+														mask |= ACTION_WEAVE;
+
+													} else
+														if (i >= 0 && (a[i] == '*')) {
+															matchlen = 1;
+															mask |= ACTION_ALL;
+
+														} else {
+															// parse error
+															throw new IllegalArgumentException("invalid permission: " + actions);
+														}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfstartlevel". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle. If the specified filterString is
+	 *         {@code null} or equals "*", then {@code null} is returned to
+	 *         indicate a wildcard.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		if (filterString == null) {
+			return null;
+		}
+		filterString = filterString.trim();
+		if (filterString.equals("*")) {
+			return null;
+		}
+
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if the specified permission is implied by this object. This
+	 * method throws an exception if the specified permission was not
+	 * constructed with a bundle.
+	 * 
+	 * <p>
+	 * This method returns {@code true} if the specified permission is an
+	 * AdminPermission AND
+	 * <ul>
+	 * <li>this object's filter matches the specified permission's bundle ID,
+	 * bundle symbolic name, bundle location and bundle signer distinguished
+	 * name chain OR</li>
+	 * <li>this object's filter is "*"</li>
+	 * </ul>
+	 * AND this object's actions include all of the specified permission's
+	 * actions.
+	 * <p>
+	 * Special case: if the specified permission was constructed with "*"
+	 * filter, then this method returns {@code true} if this object's filter is
+	 * "*" and this object's actions include all of the specified permission's
+	 * actions
+	 * 
+	 * @param p The requested permission.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof AdminPermission)) {
+			return false;
+		}
+		AdminPermission requested = (AdminPermission) p;
+		if (bundle != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested AdminPermision which has already be
+	 *        validated as a proper argument. The requested AdminPermission must
+	 *        not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(AdminPermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+
+		/* Get our filter */
+		Filter f = filter;
+		if (f == null) {
+			// it's "*"
+			return true;
+		}
+		/* is requested a wildcard filter? */
+		if (requested.bundle == null) {
+			return false;
+		}
+		Map<String, Object> requestedProperties = requested.getProperties();
+		if (requestedProperties == null) {
+			/*
+			 * If the requested properties are null, then we have detected a
+			 * recursion getting the bundle location. So we return true to
+			 * permit the bundle location request in the AdminPermission check
+			 * up the stack to succeed.
+			 */
+			return true;
+		}
+		return f.matches(requestedProperties);
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * {@code AdminPermission} actions.
+	 * 
+	 * <p>
+	 * Always returns present {@code AdminPermission} actions in the following
+	 * order: {@code class}, {@code execute}, {@code extensionLifecycle},
+	 * {@code lifecycle}, {@code listener}, {@code metadata}, {@code resolve},
+	 * {@code resource}, {@code startlevel}, {@code context}, {@code weave}.
+	 * 
+	 * @return Canonical string representation of the {@code AdminPermission}
+	 *         actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			StringBuffer sb = new StringBuffer();
+
+			int mask = action_mask;
+			if ((mask & ACTION_CLASS) == ACTION_CLASS) {
+				sb.append(CLASS);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_EXECUTE) == ACTION_EXECUTE) {
+				sb.append(EXECUTE);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_EXTENSIONLIFECYCLE) == ACTION_EXTENSIONLIFECYCLE) {
+				sb.append(EXTENSIONLIFECYCLE);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_LIFECYCLE) == ACTION_LIFECYCLE) {
+				sb.append(LIFECYCLE);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_LISTENER) == ACTION_LISTENER) {
+				sb.append(LISTENER);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_METADATA) == ACTION_METADATA) {
+				sb.append(METADATA);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_RESOLVE) == ACTION_RESOLVE) {
+				sb.append(RESOLVE);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_RESOURCE) == ACTION_RESOURCE) {
+				sb.append(RESOURCE);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_STARTLEVEL) == ACTION_STARTLEVEL) {
+				sb.append(STARTLEVEL);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_CONTEXT) == ACTION_CONTEXT) {
+				sb.append(CONTEXT);
+				sb.append(',');
+			}
+
+			if ((mask & ACTION_WEAVE) == ACTION_WEAVE) {
+				sb.append(WEAVE);
+				sb.append(',');
+			}
+
+			// remove trailing comma
+			if (sb.length() > 0) {
+				sb.setLength(sb.length() - 1);
+			}
+
+			actions = result = sb.toString();
+		}
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code AdminPermission}s.
+	 * 
+	 * @return A new {@code PermissionCollection} object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new AdminPermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two {@code AdminPermission} objects.
+	 * 
+	 * @param obj The object being compared for equality with this object.
+	 * @return {@code true} if {@code obj} is equivalent to this
+	 *         {@code AdminPermission}; {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof AdminPermission)) {
+			return false;
+		}
+
+		AdminPermission ap = (AdminPermission) obj;
+
+		return (action_mask == ap.action_mask) && ((bundle == ap.bundle) || ((bundle != null) && bundle.equals(ap.bundle))) && (filter == null ? ap.filter == null : filter.equals(ap.filter));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (bundle != null) {
+			h = 31 * h + bundle.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission object to a
+	 * stream. The actions are serialized, and the superclass takes care of the
+	 * name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		if (bundle != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the data, then initialize the transients
+		s.defaultReadObject();
+		setTransients(parseFilter(getName()), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code implies0} on an AdminPermission which was constructed
+	 * with a Bundle. This method loads a map with the filter-matchable
+	 * properties of this bundle. The map is cached so this lookup only happens
+	 * once.
+	 * 
+	 * This method should only be called on an AdminPermission which was
+	 * constructed with a bundle
+	 * 
+	 * @return a map of properties for this bundle
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		/*
+		 * We may have recursed here due to the Bundle.getLocation call in the
+		 * doPrivileged below. If this is the case, return null to allow implies
+		 * to return true.
+		 */
+		final Object mark = recurse.get();
+		if (mark == bundle) {
+			return null;
+		}
+		recurse.set(bundle);
+		try {
+			final Map<String, Object> map = new HashMap<String, Object>(4);
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				public Object run() {
+					map.put("id", new Long(bundle.getBundleId()));
+					map.put("location", bundle.getLocation());
+					String name = bundle.getSymbolicName();
+					if (name != null) {
+						map.put("name", name);
+					}
+					SignerProperty signer = new SignerProperty(bundle);
+					if (signer.isBundleSigned()) {
+						map.put("signer", signer);
+					}
+					return null;
+				}
+			});
+			return properties = map;
+		} finally {
+			recurse.set(null);
+		}
+	}
+}
+
+/**
+ * Stores a collection of {@code AdminPermission}s.
+ */
+final class AdminPermissionCollection extends PermissionCollection {
+	private static final long						serialVersionUID	= 3906372644575328048L;
+	/**
+	 * Collection of permissions.
+	 * 
+	 * @GuardedBy this
+	 */
+	private transient Map<String, AdminPermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean									all_allowed;
+
+	/**
+	 * Create an empty AdminPermissions object.
+	 * 
+	 */
+	public AdminPermissionCollection() {
+		permissions = new HashMap<String, AdminPermission>();
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The {@code AdminPermission} object to add.
+	 * @throws IllegalArgumentException If the specified permission is not an
+	 *         {@code AdminPermission} instance or was constructed with a Bundle
+	 *         object.
+	 * @throws SecurityException If this {@code AdminPermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(Permission permission) {
+		if (!(permission instanceof AdminPermission)) {
+			throw new IllegalArgumentException("invalid permission: " + permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+		}
+		final AdminPermission ap = (AdminPermission) permission;
+		if (ap.bundle != null) {
+			throw new IllegalArgumentException("cannot add to collection: " + ap);
+		}
+		final String name = ap.getName();
+		synchronized (this) {
+			Map<String, AdminPermission> pc = permissions;
+			AdminPermission existing = pc.get(name);
+			if (existing != null) {
+				int oldMask = existing.action_mask;
+				int newMask = ap.action_mask;
+
+				if (oldMask != newMask) {
+					pc.put(name, new AdminPermission(existing.filter, oldMask | newMask));
+				}
+			} else {
+				pc.put(name, ap);
+			}
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if the specified permissions implies the permissions expressed
+	 * in {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare with the
+	 *        {@code AdminPermission} objects in this collection.
+	 * @return {@code true} if {@code permission} is implied by an
+	 *         {@code AdminPermission} in this collection, {@code false}
+	 *         otherwise.
+	 */
+	public boolean implies(Permission permission) {
+		if (!(permission instanceof AdminPermission)) {
+			return false;
+		}
+
+		AdminPermission requested = (AdminPermission) permission;
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		int effective = AdminPermission.ACTION_NONE;
+		Collection<AdminPermission> perms;
+		synchronized (this) {
+			Map<String, AdminPermission> pc = permissions;
+			// short circuit if the "*" Permission was added
+			if (all_allowed) {
+				AdminPermission ap = pc.get("*");
+				if (ap != null) {
+					effective |= ap.action_mask;
+					final int desired = requested.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+			perms = pc.values();
+		}
+
+		// just iterate one by one
+		for (AdminPermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns an enumeration of all {@code AdminPermission} objects in the
+	 * container.
+	 * 
+	 * @return Enumeration of all {@code AdminPermission} objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, AdminPermission> hashtable = new Hashtable<String, AdminPermission>(permissions);
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", hashtable);
+		pfields.put("all_allowed", all_allowed);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		Hashtable<String, AdminPermission> hashtable = (Hashtable<String, AdminPermission>) gfields.get("permissions", null);
+		permissions = new HashMap<String, AdminPermission>(hashtable);
+		all_allowed = gfields.get("all_allowed", false);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/AllServiceListener.java b/osgi/framework/src/org/osgi/framework/AllServiceListener.java
new file mode 100644
index 0000000..71e27cd
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/AllServiceListener.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A {@code ServiceEvent} listener that does not filter based upon package
+ * wiring. {@code AllServiceListener} is a listener interface that may be
+ * implemented by a bundle developer. When a {@code ServiceEvent} is fired, it
+ * is synchronously delivered to an {@code AllServiceListener}. The Framework
+ * may deliver {@code ServiceEvent} objects to an {@code AllServiceListener} out
+ * of order and may concurrently call and/or reenter an
+ * {@code AllServiceListener}.
+ * <p>
+ * An {@code AllServiceListener} object is registered with the Framework using
+ * the {@code BundleContext.addServiceListener} method.
+ * {@code AllServiceListener} objects are called with a {@code ServiceEvent}
+ * object when a service is registered, modified, or is in the process of
+ * unregistering.
+ * 
+ * <p>
+ * {@code ServiceEvent} object delivery to {@code AllServiceListener} objects is
+ * filtered by the filter specified when the listener was registered. If the
+ * Java Runtime Environment supports permissions, then additional filtering is
+ * done. {@code ServiceEvent} objects are only delivered to the listener if the
+ * bundle which defines the listener object's class has the appropriate
+ * {@code ServicePermission} to get the service using at least one of the named
+ * classes under which the service was registered.
+ * 
+ * <p>
+ * Unlike normal {@code ServiceListener} objects, {@code AllServiceListener}
+ * objects receive all {@code ServiceEvent} objects regardless of whether the
+ * package source of the listening bundle is equal to the package source of the
+ * bundle that registered the service. This means that the listener may not be
+ * able to cast the service object to any of its corresponding service
+ * interfaces if the service object is retrieved.
+ * 
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @ThreadSafe
+ * @since 1.3
+ * @version $Id: 7a0c82db414be7064a06e1868eb41a8c8f8d9d6c $
+ */
+
+public interface AllServiceListener extends ServiceListener {
+	// This is a marker interface
+}
diff --git a/osgi/framework/src/org/osgi/framework/Bundle.java b/osgi/framework/src/org/osgi/framework/Bundle.java
new file mode 100644
index 0000000..d814e9a
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/Bundle.java
@@ -0,0 +1,1243 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/**
+ * An installed bundle in the Framework.
+ * 
+ * <p>
+ * A {@code Bundle} object is the access point to define the lifecycle of an
+ * installed bundle. Each bundle installed in the OSGi environment must have an
+ * associated {@code Bundle} object.
+ * 
+ * <p>
+ * A bundle must have a unique identity, a {@code long}, chosen by the
+ * Framework. This identity must not change during the lifecycle of a bundle,
+ * even when the bundle is updated. Uninstalling and then reinstalling the
+ * bundle must create a new unique identity.
+ * 
+ * <p>
+ * A bundle can be in one of six states:
+ * <ul>
+ * <li>{@link #UNINSTALLED}
+ * <li>{@link #INSTALLED}
+ * <li>{@link #RESOLVED}
+ * <li>{@link #STARTING}
+ * <li>{@link #STOPPING}
+ * <li>{@link #ACTIVE}
+ * </ul>
+ * <p>
+ * Values assigned to these states have no specified ordering; they represent
+ * bit values that may be ORed together to determine if a bundle is in one of
+ * the valid states.
+ * 
+ * <p>
+ * A bundle should only have active threads of execution when its state is one
+ * of {@code STARTING},{@code ACTIVE}, or {@code STOPPING}. An
+ * {@code UNINSTALLED} bundle can not be set to another state; it is a zombie
+ * and can only be reached because references are kept somewhere.
+ * 
+ * <p>
+ * The Framework is the only entity that is allowed to create {@code Bundle}
+ * objects, and these objects are only valid within the Framework that created
+ * them.
+ * 
+ * <p>
+ * Bundles have a natural ordering such that if two {@code Bundle}s have the
+ * same {@link #getBundleId() bundle id} they are equal. A {@code Bundle} is
+ * less than another {@code Bundle} if it has a lower {@link #getBundleId()
+ * bundle id} and is greater if it has a higher bundle id.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 8a58ab72af389b1999b88348e4944203b7096510 $
+ */
+public interface Bundle extends Comparable<Bundle> {
+	/**
+	 * The bundle is uninstalled and may not be used.
+	 * 
+	 * <p>
+	 * The {@code UNINSTALLED} state is only visible after a bundle is
+	 * uninstalled; the bundle is in an unusable state but references to the
+	 * {@code Bundle} object may still be available and used for introspection.
+	 * <p>
+	 * The value of {@code UNINSTALLED} is 0x00000001.
+	 */
+	int	UNINSTALLED				= 0x00000001;
+
+	/**
+	 * The bundle is installed but not yet resolved.
+	 * 
+	 * <p>
+	 * A bundle is in the {@code INSTALLED} state when it has been installed in
+	 * the Framework but is not or cannot be resolved.
+	 * <p>
+	 * This state is visible if the bundle's code dependencies are not resolved.
+	 * The Framework may attempt to resolve an {@code INSTALLED} bundle's code
+	 * dependencies and move the bundle to the {@code RESOLVED} state.
+	 * <p>
+	 * The value of {@code INSTALLED} is 0x00000002.
+	 */
+	int	INSTALLED				= 0x00000002;
+
+	/**
+	 * The bundle is resolved and is able to be started.
+	 * 
+	 * <p>
+	 * A bundle is in the {@code RESOLVED} state when the Framework has
+	 * successfully resolved the bundle's code dependencies. These dependencies
+	 * include:
+	 * <ul>
+	 * <li>The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH}
+	 * Manifest header.
+	 * <li>The bundle's package dependencies from its
+	 * {@link Constants#EXPORT_PACKAGE} and {@link Constants#IMPORT_PACKAGE}
+	 * Manifest headers.
+	 * <li>The bundle's required bundle dependencies from its
+	 * {@link Constants#REQUIRE_BUNDLE} Manifest header.
+	 * <li>A fragment bundle's host dependency from its
+	 * {@link Constants#FRAGMENT_HOST} Manifest header.
+	 * </ul>
+	 * <p>
+	 * Note that the bundle is not active yet. A bundle must be put in the
+	 * {@code RESOLVED} state before it can be started. The Framework may
+	 * attempt to resolve a bundle at any time.
+	 * <p>
+	 * The value of {@code RESOLVED} is 0x00000004.
+	 */
+	int	RESOLVED				= 0x00000004;
+
+	/**
+	 * The bundle is in the process of starting.
+	 * 
+	 * <p>
+	 * A bundle is in the {@code STARTING} state when its {@link #start(int)
+	 * start} method is active. A bundle must be in this state when the bundle's
+	 * {@link BundleActivator#start(BundleContext)} is called. If the
+	 * {@code BundleActivator.start} method completes without exception, then
+	 * the bundle has successfully started and must move to the {@code ACTIVE}
+	 * state.
+	 * <p>
+	 * If the bundle has a {@link Constants#ACTIVATION_LAZY lazy activation
+	 * policy}, then the bundle may remain in this state for some time until the
+	 * activation is triggered.
+	 * <p>
+	 * The value of {@code STARTING} is 0x00000008.
+	 */
+	int	STARTING				= 0x00000008;
+
+	/**
+	 * The bundle is in the process of stopping.
+	 * 
+	 * <p>
+	 * A bundle is in the {@code STOPPING} state when its {@link #stop(int)
+	 * stop} method is active. A bundle must be in this state when the bundle's
+	 * {@link BundleActivator#stop(BundleContext)} method is called. When the
+	 * {@code BundleActivator.stop} method completes the bundle is stopped and
+	 * must move to the {@code RESOLVED} state.
+	 * <p>
+	 * The value of {@code STOPPING} is 0x00000010.
+	 */
+	int	STOPPING				= 0x00000010;
+
+	/**
+	 * The bundle is now running.
+	 * 
+	 * <p>
+	 * A bundle is in the {@code ACTIVE} state when it has been successfully
+	 * started and activated.
+	 * <p>
+	 * The value of {@code ACTIVE} is 0x00000020.
+	 */
+	int	ACTIVE					= 0x00000020;
+
+	/**
+	 * The bundle start operation is transient and the persistent autostart
+	 * setting of the bundle is not modified.
+	 * 
+	 * <p>
+	 * This bit may be set when calling {@link #start(int)} to notify the
+	 * framework that the autostart setting of the bundle must not be modified.
+	 * If this bit is not set, then the autostart setting of the bundle is
+	 * modified.
+	 * 
+	 * @since 1.4
+	 * @see #start(int)
+	 */
+	int	START_TRANSIENT			= 0x00000001;
+
+	/**
+	 * The bundle start operation must activate the bundle according to the
+	 * bundle's declared {@link Constants#BUNDLE_ACTIVATIONPOLICY activation
+	 * policy}.
+	 * 
+	 * <p>
+	 * This bit may be set when calling {@link #start(int)} to notify the
+	 * framework that the bundle must be activated using the bundle's declared
+	 * activation policy.
+	 * 
+	 * @since 1.4
+	 * @see Constants#BUNDLE_ACTIVATIONPOLICY
+	 * @see #start(int)
+	 */
+	int	START_ACTIVATION_POLICY	= 0x00000002;
+
+	/**
+	 * The bundle stop is transient and the persistent autostart setting of the
+	 * bundle is not modified.
+	 * 
+	 * <p>
+	 * This bit may be set when calling {@link #stop(int)} to notify the
+	 * framework that the autostart setting of the bundle must not be modified.
+	 * If this bit is not set, then the autostart setting of the bundle is
+	 * modified.
+	 * 
+	 * @since 1.4
+	 * @see #stop(int)
+	 */
+	int	STOP_TRANSIENT			= 0x00000001;
+
+	/**
+	 * Request that all certificates used to sign the bundle be returned.
+	 * 
+	 * @since 1.5
+	 * @see #getSignerCertificates(int)
+	 */
+	int	SIGNERS_ALL				= 1;
+
+	/**
+	 * Request that only certificates used to sign the bundle that are trusted
+	 * by the framework be returned.
+	 * 
+	 * @since 1.5
+	 * @see #getSignerCertificates(int)
+	 */
+	int	SIGNERS_TRUSTED			= 2;
+
+	/**
+	 * Returns this bundle's current state.
+	 * 
+	 * <p>
+	 * A bundle can be in only one state at any time.
+	 * 
+	 * @return An element of {@code UNINSTALLED},{@code INSTALLED},
+	 *         {@code RESOLVED}, {@code STARTING}, {@code STOPPING},
+	 *         {@code ACTIVE}.
+	 */
+	int getState();
+
+	/**
+	 * Starts this bundle.
+	 * 
+	 * <p>
+	 * If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
+	 * <p>
+	 * If the current start level is less than this bundle's start level:
+	 * <ul>
+	 * <li>If the {@link #START_TRANSIENT} option is set, then a
+	 * {@code BundleException} is thrown indicating this bundle cannot be
+	 * started due to the Framework's current start level.
+	 * 
+	 * <li>Otherwise, the Framework must set this bundle's persistent autostart
+	 * setting to <em>Started with declared activation</em> if the
+	 * {@link #START_ACTIVATION_POLICY} option is set or
+	 * <em>Started with eager activation</em> if not set.
+	 * </ul>
+	 * <p>
+	 * When the Framework's current start level becomes equal to or more than
+	 * this bundle's start level, this bundle will be started.
+	 * <p>
+	 * Otherwise, the following steps are required to start this bundle:
+	 * <ol>
+	 * <li>If this bundle is in the process of being activated or deactivated
+	 * then this method must wait for activation or deactivation to complete
+	 * before continuing. If this does not occur in a reasonable time, a
+	 * {@code BundleException} is thrown to indicate this bundle was unable to
+	 * be started.
+	 * 
+	 * <li>If this bundle's state is {@code ACTIVE} then this method returns
+	 * immediately.
+	 * 
+	 * <li>If the {@link #START_TRANSIENT} option is not set then set this
+	 * bundle's autostart setting to <em>Started with declared activation</em>
+	 * if the {@link #START_ACTIVATION_POLICY} option is set or
+	 * <em>Started with eager activation</em> if not set. When the Framework is
+	 * restarted and this bundle's autostart setting is not <em>Stopped</em>,
+	 * this bundle must be automatically started.
+	 * 
+	 * <li>If this bundle's state is not {@code RESOLVED}, an attempt is made to
+	 * resolve this bundle. If the Framework cannot resolve this bundle, a
+	 * {@code BundleException} is thrown.
+	 * 
+	 * <li>If the {@link #START_ACTIVATION_POLICY} option is set and this
+	 * bundle's declared activation policy is {@link Constants#ACTIVATION_LAZY
+	 * lazy} then:
+	 * <ul>
+	 * <li>If this bundle's state is {@code STARTING} then this method returns
+	 * immediately.
+	 * <li>This bundle's state is set to {@code STARTING}.
+	 * <li>A bundle event of type {@link BundleEvent#LAZY_ACTIVATION} is fired.
+	 * <li>This method returns immediately and the remaining steps will be
+	 * followed when this bundle's activation is later triggered.
+	 * </ul>
+	 * <i></i>
+	 * <li>This bundle's state is set to {@code STARTING}.
+	 * 
+	 * <li>A bundle event of type {@link BundleEvent#STARTING} is fired.
+	 * 
+	 * <li>The {@link BundleActivator#start(BundleContext)} method of this
+	 * bundle's {@code BundleActivator}, if one is specified, is called. If the
+	 * {@code BundleActivator} is invalid or throws an exception then:
+	 * <ul>
+	 * <li>This bundle's state is set to {@code STOPPING}.
+	 * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
+	 * <li>Any services registered by this bundle must be unregistered.
+	 * <li>Any services used by this bundle must be released.
+	 * <li>Any listeners registered by this bundle must be removed.
+	 * <li>This bundle's state is set to {@code RESOLVED}.
+	 * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
+	 * <li>A {@code BundleException} is then thrown.
+	 * </ul>
+	 * <i></i>
+	 * <li>If this bundle's state is {@code UNINSTALLED}, because this bundle
+	 * was uninstalled while the {@code BundleActivator.start} method was
+	 * running, a {@code BundleException} is thrown.
+	 * 
+	 * <li>This bundle's state is set to {@code ACTIVE}.
+	 * 
+	 * <li>A bundle event of type {@link BundleEvent#STARTED} is fired.
+	 * </ol>
+	 * 
+	 * <b>Preconditions </b>
+	 * <ul>
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED}
+	 * &#x007D; or &#x007B; {@code INSTALLED}, {@code RESOLVED},
+	 * {@code STARTING} &#x007D; if this bundle has a lazy activation policy.
+	 * </ul>
+	 * <b>Postconditions, no exceptions thrown </b>
+	 * <ul>
+	 * <li>Bundle autostart setting is modified unless the
+	 * {@link #START_TRANSIENT} option was set.
+	 * <li>{@code getState()} in &#x007B; {@code ACTIVE} &#x007D; unless the
+	 * lazy activation policy was used.
+	 * <li>{@code BundleActivator.start()} has been called and did not throw an
+	 * exception unless the lazy activation policy was used.
+	 * </ul>
+	 * <b>Postconditions, when an exception is thrown </b>
+	 * <ul>
+	 * <li>Depending on when the exception occurred, bundle autostart setting is
+	 * modified unless the {@link #START_TRANSIENT} option was set.
+	 * <li>{@code getState()} not in &#x007B; {@code STARTING}, {@code ACTIVE}
+	 * &#x007D;.
+	 * </ul>
+	 * 
+	 * @param options The options for starting this bundle. See
+	 *        {@link #START_TRANSIENT} and {@link #START_ACTIVATION_POLICY}. The
+	 *        Framework must ignore unrecognized options.
+	 * @throws BundleException If this bundle could not be started.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#START_TRANSIENT_ERROR},
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @since 1.4
+	 */
+	void start(int options) throws BundleException;
+
+	/**
+	 * Starts this bundle with no options.
+	 * 
+	 * <p>
+	 * This method performs the same function as calling {@code start(0)}.
+	 * 
+	 * @throws BundleException If this bundle could not be started.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see #start(int)
+	 */
+	void start() throws BundleException;
+
+	/**
+	 * Stops this bundle.
+	 * 
+	 * <p>
+	 * The following steps are required to stop a bundle:
+	 * <ol>
+	 * <li>If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
+	 * 
+	 * <li>If this bundle is in the process of being activated or deactivated
+	 * then this method must wait for activation or deactivation to complete
+	 * before continuing. If this does not occur in a reasonable time, a
+	 * {@code BundleException} is thrown to indicate this bundle was unable to
+	 * be stopped.
+	 * <li>If the {@link #STOP_TRANSIENT} option is not set then then set this
+	 * bundle's persistent autostart setting to to <em>Stopped</em>. When the
+	 * Framework is restarted and this bundle's autostart setting is
+	 * <em>Stopped</em>, this bundle must not be automatically started.
+	 * 
+	 * <li>If this bundle's state is not {@code STARTING} or {@code ACTIVE} then
+	 * this method returns immediately.
+	 * 
+	 * <li>This bundle's state is set to {@code STOPPING}.
+	 * 
+	 * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
+	 * 
+	 * <li>If this bundle's state was {@code ACTIVE} prior to setting the state
+	 * to {@code STOPPING}, the {@link BundleActivator#stop(BundleContext)}
+	 * method of this bundle's {@code BundleActivator}, if one is specified, is
+	 * called. If that method throws an exception, this method must continue to
+	 * stop this bundle and a {@code BundleException} must be thrown after
+	 * completion of the remaining steps.
+	 * 
+	 * <li>Any services registered by this bundle must be unregistered.
+	 * <li>Any services used by this bundle must be released.
+	 * <li>Any listeners registered by this bundle must be removed.
+	 * 
+	 * <li>If this bundle's state is {@code UNINSTALLED}, because this bundle
+	 * was uninstalled while the {@code BundleActivator.stop} method was
+	 * running, a {@code BundleException} must be thrown.
+	 * 
+	 * <li>This bundle's state is set to {@code RESOLVED}.
+	 * 
+	 * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
+	 * </ol>
+	 * 
+	 * <b>Preconditions </b>
+	 * <ul>
+	 * <li>{@code getState()} in &#x007B; {@code ACTIVE} &#x007D;.
+	 * </ul>
+	 * <b>Postconditions, no exceptions thrown </b>
+	 * <ul>
+	 * <li>Bundle autostart setting is modified unless the
+	 * {@link #STOP_TRANSIENT} option was set.
+	 * <li>{@code getState()} not in &#x007B; {@code ACTIVE}, {@code STOPPING}
+	 * &#x007D;.
+	 * <li>{@code BundleActivator.stop} has been called and did not throw an
+	 * exception.
+	 * </ul>
+	 * <b>Postconditions, when an exception is thrown </b>
+	 * <ul>
+	 * <li>Bundle autostart setting is modified unless the
+	 * {@link #STOP_TRANSIENT} option was set.
+	 * </ul>
+	 * 
+	 * @param options The options for stopping this bundle. See
+	 *        {@link #STOP_TRANSIENT}. The Framework must ignore unrecognized
+	 *        options.
+	 * @throws BundleException BundleException types thrown by this method
+	 *         include: {@link BundleException#STATECHANGE_ERROR} and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @since 1.4
+	 */
+	void stop(int options) throws BundleException;
+
+	/**
+	 * Stops this bundle with no options.
+	 * 
+	 * <p>
+	 * This method performs the same function as calling {@code stop(0)}.
+	 * 
+	 * @throws BundleException BundleException types thrown by this method
+	 *         include: {@link BundleException#STATECHANGE_ERROR} and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see #start(int)
+	 */
+	void stop() throws BundleException;
+
+	/**
+	 * Updates this bundle from an {@code InputStream}.
+	 * 
+	 * <p>
+	 * If the specified {@code InputStream} is {@code null}, the Framework must
+	 * create the {@code InputStream} from which to read the updated bundle by
+	 * interpreting, in an implementation dependent manner, this bundle's
+	 * {@link Constants#BUNDLE_UPDATELOCATION Bundle-UpdateLocation} Manifest
+	 * header, if present, or this bundle's original location.
+	 * 
+	 * <p>
+	 * If this bundle's state is {@code ACTIVE}, it must be stopped before the
+	 * update and started after the update successfully completes.
+	 * 
+	 * <p>
+	 * If this bundle has exported any packages that are imported by another
+	 * bundle, these packages must remain exported until the
+	 * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
+	 * FrameworkWiring.refreshBundles} method has been has been called or the
+	 * Framework is relaunched.
+	 * 
+	 * <p>
+	 * The following steps are required to update a bundle:
+	 * <ol>
+	 * <li>If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
+	 * 
+	 * <li>If this bundle's state is {@code ACTIVE}, {@code STARTING} or
+	 * {@code STOPPING}, this bundle is stopped as described in the
+	 * {@code Bundle.stop} method. If {@code Bundle.stop} throws an exception,
+	 * the exception is rethrown terminating the update.
+	 * 
+	 * <li>The updated version of this bundle is read from the input stream and
+	 * installed. If the Framework is unable to install the updated version of
+	 * this bundle, the original version of this bundle must be restored and a
+	 * {@code BundleException} must be thrown after completion of the remaining
+	 * steps.
+	 * 
+	 * <li>This bundle's state is set to {@code INSTALLED}.
+	 * 
+	 * <li>If the updated version of this bundle was successfully installed, a
+	 * bundle event of type {@link BundleEvent#UPDATED} is fired.
+	 * 
+	 * <li>If this bundle's state was originally {@code ACTIVE}, the updated
+	 * bundle is started as described in the {@code Bundle.start} method. If
+	 * {@code Bundle.start} throws an exception, a Framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing the exception.
+	 * </ol>
+	 * 
+	 * <b>Preconditions </b>
+	 * <ul>
+	 * <li>{@code getState()} not in &#x007B; {@code UNINSTALLED} &#x007D;.
+	 * </ul>
+	 * <b>Postconditions, no exceptions thrown </b>
+	 * <ul>
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED},
+	 * {@code ACTIVE} &#x007D;.
+	 * <li>This bundle has been updated.
+	 * </ul>
+	 * <b>Postconditions, when an exception is thrown </b>
+	 * <ul>
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED},
+	 * {@code ACTIVE} &#x007D;.
+	 * <li>Original bundle is still used; no update occurred.
+	 * </ul>
+	 * 
+	 * @param input The {@code InputStream} from which to read the new bundle or
+	 *        {@code null} to indicate the Framework must create the input
+	 *        stream from this bundle's {@link Constants#BUNDLE_UPDATELOCATION
+	 *        Bundle-UpdateLocation} Manifest header, if present, or this
+	 *        bundle's original location. The input stream must always be closed
+	 *        when this method completes, even if an exception is thrown.
+	 * @throws BundleException If this bundle could not be updated.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#READ_ERROR},
+	 *         {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR},
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,LIFECYCLE]} for both the current
+	 *         bundle and the updated bundle, and the Java Runtime Environment
+	 *         supports permissions.
+	 * @see #stop()
+	 * @see #start()
+	 */
+	void update(InputStream input) throws BundleException;
+
+	/**
+	 * Updates this bundle.
+	 * 
+	 * <p>
+	 * This method performs the same function as calling
+	 * {@link #update(InputStream)} with a {@code null} InputStream.
+	 * 
+	 * @throws BundleException If this bundle could not be updated.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#READ_ERROR},
+	 *         {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR},
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,LIFECYCLE]} for both the current
+	 *         bundle and the updated bundle, and the Java Runtime Environment
+	 *         supports permissions.
+	 * @see #update(InputStream)
+	 */
+	void update() throws BundleException;
+
+	/**
+	 * Uninstalls this bundle.
+	 * 
+	 * <p>
+	 * This method causes the Framework to notify other bundles that this bundle
+	 * is being uninstalled, and then puts this bundle into the
+	 * {@code UNINSTALLED} state. The Framework must remove any resources
+	 * related to this bundle that it is able to remove.
+	 * 
+	 * <p>
+	 * If this bundle has exported any packages, the Framework must continue to
+	 * make these packages available to their importing bundles until the
+	 * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
+	 * FrameworkWiring.refreshBundles} method has been called or the Framework
+	 * is relaunched.
+	 * 
+	 * <p>
+	 * The following steps are required to uninstall a bundle:
+	 * <ol>
+	 * <li>If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
+	 * 
+	 * <li>If this bundle's state is {@code ACTIVE}, {@code STARTING} or
+	 * {@code STOPPING}, this bundle is stopped as described in the
+	 * {@code Bundle.stop} method. If {@code Bundle.stop} throws an exception, a
+	 * Framework event of type {@link FrameworkEvent#ERROR} is fired containing
+	 * the exception.
+	 * 
+	 * <li>This bundle's state is set to {@code UNINSTALLED}.
+	 * 
+	 * <li>A bundle event of type {@link BundleEvent#UNINSTALLED} is fired.
+	 * 
+	 * <li>This bundle and any persistent storage area provided for this bundle
+	 * by the Framework are removed.
+	 * </ol>
+	 * 
+	 * <b>Preconditions </b>
+	 * <ul>
+	 * <li>{@code getState()} not in &#x007B; {@code UNINSTALLED} &#x007D;.
+	 * </ul>
+	 * <b>Postconditions, no exceptions thrown </b>
+	 * <ul>
+	 * <li>{@code getState()} in &#x007B; {@code UNINSTALLED} &#x007D;.
+	 * <li>This bundle has been uninstalled.
+	 * </ul>
+	 * <b>Postconditions, when an exception is thrown </b>
+	 * <ul>
+	 * <li>{@code getState()} not in &#x007B; {@code UNINSTALLED} &#x007D;.
+	 * <li>This Bundle has not been uninstalled.
+	 * </ul>
+	 * 
+	 * @throws BundleException If the uninstall failed. This can occur if
+	 *         another thread is attempting to change this bundle's state and
+	 *         does not complete in a timely manner. BundleException types
+	 *         thrown by this method include:
+	 *         {@link BundleException#STATECHANGE_ERROR}
+	 * @throws IllegalStateException If this bundle has been uninstalled or this
+	 *         bundle tries to change its own state.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see #stop()
+	 */
+	void uninstall() throws BundleException;
+
+	/**
+	 * Returns this bundle's Manifest headers and values. This method returns
+	 * all the Manifest headers and values from the main section of this
+	 * bundle's Manifest file; that is, all lines prior to the first blank line.
+	 * 
+	 * <p>
+	 * Manifest header names are case-insensitive. The methods of the returned
+	 * {@code Dictionary} object must operate on header names in a
+	 * case-insensitive manner.
+	 * 
+	 * If a Manifest header value starts with "%", it must be
+	 * localized according to the default locale. If no localization is found
+	 * for a header value, the header value without the leading "%" is
+	 * returned.
+	 * 
+	 * <p>
+	 * For example, the following Manifest headers and values are included if
+	 * they are present in the Manifest file:
+	 * 
+	 * <pre>
+	 *     Bundle-Name
+	 *     Bundle-Vendor
+	 *     Bundle-Version
+	 *     Bundle-Description
+	 *     Bundle-DocURL
+	 *     Bundle-ContactAddress
+	 * </pre>
+	 * 
+	 * <p>
+	 * This method must continue to return Manifest header information while
+	 * this bundle is in the {@code UNINSTALLED} state.
+	 * 
+	 * @return An unmodifiable {@code Dictionary} object containing this
+	 *         bundle's Manifest headers and values.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see Constants#BUNDLE_LOCALIZATION
+	 */
+	Dictionary<String, String> getHeaders();
+
+	/**
+	 * Returns this bundle's unique identifier. This bundle is assigned a unique
+	 * identifier by the Framework when it was installed in the OSGi
+	 * environment.
+	 * 
+	 * <p>
+	 * A bundle's unique identifier has the following attributes:
+	 * <ul>
+	 * <li>Is unique and persistent.
+	 * <li>Is a {@code long}.
+	 * <li>Its value is not reused for another bundle, even after a bundle is
+	 * uninstalled.
+	 * <li>Does not change while a bundle remains installed.
+	 * <li>Does not change when a bundle is updated.
+	 * </ul>
+	 * 
+	 * <p>
+	 * This method must continue to return this bundle's unique identifier while
+	 * this bundle is in the {@code UNINSTALLED} state.
+	 * 
+	 * @return The unique identifier of this bundle.
+	 */
+	long getBundleId();
+
+	/**
+	 * Returns this bundle's location identifier.
+	 * 
+	 * <p>
+	 * The location identifier is the location passed to
+	 * {@code BundleContext.installBundle} when a bundle is installed. The
+	 * location identifier does not change while this bundle remains installed,
+	 * even if this bundle is updated.
+	 * 
+	 * <p>
+	 * This method must continue to return this bundle's location identifier
+	 * while this bundle is in the {@code UNINSTALLED} state.
+	 * 
+	 * @return The string representation of this bundle's location identifier.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 */
+	String getLocation();
+
+	/**
+	 * Returns this bundle's {@code ServiceReference} list for all services it
+	 * has registered or {@code null} if this bundle has no registered services.
+	 * 
+	 * <p>
+	 * If the Java runtime supports permissions, a {@code ServiceReference}
+	 * object to a service is included in the returned list only if the caller
+	 * has the {@code ServicePermission} to get the service using at least one
+	 * of the named classes the service was registered under.
+	 * 
+	 * <p>
+	 * The list is valid at the time of the call to this method, however, as the
+	 * Framework is a very dynamic environment, services can be modified or
+	 * unregistered at anytime.
+	 * 
+	 * @return An array of {@code ServiceReference} objects or {@code null}.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @see ServiceRegistration
+	 * @see ServiceReference
+	 * @see ServicePermission
+	 */
+	ServiceReference<?>[] getRegisteredServices();
+
+	/**
+	 * Returns this bundle's {@code ServiceReference} list for all services it
+	 * is using or returns {@code null} if this bundle is not using any
+	 * services. A bundle is considered to be using a service if its use count
+	 * for that service is greater than zero.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment supports permissions, a
+	 * {@code ServiceReference} object to a service is included in the returned
+	 * list only if the caller has the {@code ServicePermission} to get the
+	 * service using at least one of the named classes the service was
+	 * registered under.
+	 * <p>
+	 * The list is valid at the time of the call to this method, however, as the
+	 * Framework is a very dynamic environment, services can be modified or
+	 * unregistered at anytime.
+	 * 
+	 * @return An array of {@code ServiceReference} objects or {@code null}.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @see ServiceReference
+	 * @see ServicePermission
+	 */
+	ServiceReference<?>[] getServicesInUse();
+
+	/**
+	 * Determines if this bundle has the specified permissions.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment does not support permissions, this method
+	 * always returns {@code true}.
+	 * <p>
+	 * {@code permission} is of type {@code Object} to avoid referencing the
+	 * {@code java.security.Permission} class directly. This is to allow the
+	 * Framework to be implemented in Java environments which do not support
+	 * permissions.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment does support permissions, this bundle and
+	 * all its resources including embedded JAR files, belong to the same
+	 * {@code java.security.ProtectionDomain}; that is, they must share the same
+	 * set of permissions.
+	 * 
+	 * @param permission The permission to verify.
+	 * @return {@code true} if this bundle has the specified permission or the
+	 *         permissions possessed by this bundle imply the specified
+	 *         permission; {@code false} if this bundle does not have the
+	 *         specified permission or {@code permission} is not an
+	 *         {@code instanceof} {@code java.security.Permission}.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 */
+	boolean hasPermission(Object permission);
+
+	/**
+	 * Find the specified resource from this bundle's class loader.
+	 * 
+	 * This bundle's class loader is called to search for the specified
+	 * resource. If this bundle's state is {@code INSTALLED}, this method must
+	 * attempt to resolve this bundle before attempting to get the specified
+	 * resource. If this bundle cannot be resolved, then only this bundle must
+	 * be searched for the specified resource. Imported packages cannot be
+	 * searched when this bundle has not been resolved. If this bundle is a
+	 * fragment bundle then {@code null} is returned.
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * URLs to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param name The name of the resource. See {@code ClassLoader.getResource}
+	 *        for a description of the format of a resource name.
+	 * @return A URL to the named resource, or {@code null} if the resource
+	 *         could not be found or if this bundle is a fragment bundle or if
+	 *         the caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @see #getEntry(String)
+	 * @see #findEntries(String, String, boolean)
+	 * @since 1.1
+	 */
+	URL getResource(String name);
+
+	/**
+	 * Returns this bundle's Manifest headers and values localized to the
+	 * specified locale.
+	 * 
+	 * <p>
+	 * This method performs the same function as {@code Bundle.getHeaders()}
+	 * except the manifest header values are localized to the specified locale.
+	 * 
+	 * <p>
+	 * If a Manifest header value starts with "%", it must be
+	 * localized according to the specified locale. If a locale is specified and
+	 * cannot be found, then the header values must be returned using the
+	 * default locale. Localizations are searched for in the following order:
+	 * 
+	 * <pre>
+	 *   bn + "_" + Ls + "_" + Cs + "_" + Vs
+	 *   bn + "_" + Ls + "_" + Cs
+	 *   bn + "_" + Ls
+	 *   bn + "_" + Ld + "_" + Cd + "_" + Vd
+	 *   bn + "_" + Ld + "_" + Cd
+	 *   bn + "_" + Ld
+	 *   bn
+	 * </pre>
+	 * 
+	 * Where {@code bn} is this bundle's localization basename, {@code Ls},
+	 * {@code Cs} and {@code Vs} are the specified locale (language, country,
+	 * variant) and {@code Ld}, {@code Cd} and {@code Vd} are the default locale
+	 * (language, country, variant).
+	 * 
+	 * If {@code null} is specified as the locale string, the header values must
+	 * be localized using the default locale. If the empty string ("")
+	 * is specified as the locale string, the header values must not be
+	 * localized and the raw (unlocalized) header values, including any leading
+	 * "%", must be returned. If no localization is found for a header
+	 * value, the header value without the leading "%" is returned.
+	 * 
+	 * <p>
+	 * This method must continue to return Manifest header information while
+	 * this bundle is in the {@code UNINSTALLED} state, however the header
+	 * values must only be available in the raw and default locale values.
+	 * 
+	 * @param locale The locale name into which the header values are to be
+	 *        localized. If the specified locale is {@code null} then the locale
+	 *        returned by {@code java.util.Locale.getDefault} is used. If the
+	 *        specified locale is the empty string, this method will return the
+	 *        raw (unlocalized) manifest headers including any leading
+	 *        "%".
+	 * @return An unmodifiable {@code Dictionary} object containing this
+	 *         bundle's Manifest headers and values.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see #getHeaders()
+	 * @see Constants#BUNDLE_LOCALIZATION
+	 * @since 1.3
+	 */
+	Dictionary<String, String> getHeaders(String locale);
+
+	/**
+	 * Returns the symbolic name of this bundle as specified by its
+	 * {@code Bundle-SymbolicName} manifest header. The bundle symbolic name
+	 * should be based on the reverse domain name naming convention like that
+	 * used for java packages.
+	 * 
+	 * <p>
+	 * This method must continue to return this bundle's symbolic name while
+	 * this bundle is in the {@code UNINSTALLED} state.
+	 * 
+	 * @return The symbolic name of this bundle or {@code null} if this bundle
+	 *         does not have a symbolic name.
+	 * @since 1.3
+	 */
+	String getSymbolicName();
+
+	/**
+	 * Loads the specified class using this bundle's class loader.
+	 * 
+	 * <p>
+	 * If this bundle is a fragment bundle then this method must throw a
+	 * {@code ClassNotFoundException}.
+	 * 
+	 * <p>
+	 * If this bundle's state is {@code INSTALLED}, this method must attempt to
+	 * resolve this bundle before attempting to load the class.
+	 * 
+	 * <p>
+	 * If this bundle cannot be resolved, a Framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a
+	 * {@code BundleException} with details of the reason this bundle could not
+	 * be resolved. This method must then throw a {@code ClassNotFoundException}.
+	 * 
+	 * <p>
+	 * If this bundle's state is {@code UNINSTALLED}, then an
+	 * {@code IllegalStateException} is thrown.
+	 * 
+	 * @param name The name of the class to load.
+	 * @return The Class object for the requested class.
+	 * @throws ClassNotFoundException If no such class can be found or if this
+	 *         bundle is a fragment bundle or if the caller does not have the
+	 *         appropriate {@code AdminPermission[this,CLASS]}, and the Java
+	 *         Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @since 1.3
+	 */
+	Class<?> loadClass(String name) throws ClassNotFoundException;
+
+	/**
+	 * Find the specified resources from this bundle's class loader.
+	 * 
+	 * This bundle's class loader is called to search for the specified
+	 * resources. If this bundle's state is {@code INSTALLED}, this method must
+	 * attempt to resolve this bundle before attempting to get the specified
+	 * resources. If this bundle cannot be resolved, then only this bundle must
+	 * be searched for the specified resources. Imported packages cannot be
+	 * searched when a bundle has not been resolved. If this bundle is a
+	 * fragment bundle then {@code null} is returned.
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * URLs to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param name The name of the resource. See
+	 *        {@code ClassLoader.getResources} for a description of the format
+	 *        of a resource name.
+	 * @return An enumeration of URLs to the named resources, or {@code null} if
+	 *         the resource could not be found or if this bundle is a fragment
+	 *         bundle or if the caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @throws IOException If there is an I/O error.
+	 * @since 1.3
+	 */
+	Enumeration<URL> getResources(String name) throws IOException;
+
+	/**
+	 * Returns an Enumeration of all the paths ({@code String} objects) to
+	 * entries within this bundle whose longest sub-path matches the specified
+	 * path. This bundle's class loader is not used to search for entries. Only
+	 * the contents of this bundle are searched.
+	 * <p>
+	 * The specified path is always relative to the root of this bundle and may
+	 * begin with a "/". A path value of "/" indicates the
+	 * root of this bundle.
+	 * <p>
+	 * Returned paths indicating subdirectory paths end with a "/".
+	 * The returned paths are all relative to the root of this bundle and must
+	 * not begin with "/".
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * Paths to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param path The path name for which to return entry paths.
+	 * @return An Enumeration of the entry paths ({@code String} objects) or
+	 *         {@code null} if no entry could be found or if the caller does not
+	 *         have the appropriate {@code AdminPermission[this,RESOURCE]} and
+	 *         the Java Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @since 1.3
+	 */
+	Enumeration<String> getEntryPaths(String path);
+
+	/**
+	 * Returns a URL to the entry at the specified path in this bundle. This
+	 * bundle's class loader is not used to search for the entry. Only the
+	 * contents of this bundle are searched for the entry.
+	 * <p>
+	 * The specified path is always relative to the root of this bundle and may
+	 * begin with "/". A path value of "/" indicates the
+	 * root of this bundle.
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * URLs to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param path The path name of the entry.
+	 * @return A URL to the entry, or {@code null} if no entry could be found or
+	 *         if the caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]} and the Java Runtime
+	 *         Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @since 1.3
+	 */
+	URL getEntry(String path);
+
+	/**
+	 * Returns the time when this bundle was last modified. A bundle is
+	 * considered to be modified when it is installed, updated or uninstalled.
+	 * 
+	 * <p>
+	 * The time value is the number of milliseconds since January 1, 1970,
+	 * 00:00:00 UTC.
+	 * 
+	 * @return The time when this bundle was last modified.
+	 * @since 1.3
+	 */
+	long getLastModified();
+
+	/**
+	 * Returns entries in this bundle and its attached fragments. This bundle's
+	 * class loader is not used to search for entries. Only the contents of this
+	 * bundle and its attached fragments are searched for the specified entries.
+	 * 
+	 * If this bundle's state is {@code INSTALLED}, this method must attempt to
+	 * resolve this bundle before attempting to find entries.
+	 * 
+	 * <p>
+	 * This method is intended to be used to obtain configuration, setup,
+	 * localization and other information from this bundle. This method takes
+	 * into account that the "contents" of this bundle can be extended
+	 * with fragments. This "bundle space" is not a namespace with
+	 * unique members; the same entry name can be present multiple times. This
+	 * method therefore returns an enumeration of URL objects. These URLs can
+	 * come from different JARs but have the same path name. This method can
+	 * either return only entries in the specified path or recurse into
+	 * subdirectories returning entries in the directory tree beginning at the
+	 * specified path. Fragments can be attached after this bundle is resolved,
+	 * possibly changing the set of URLs returned by this method. If this bundle
+	 * is not resolved, only the entries in the JAR file of this bundle are
+	 * returned.
+	 * <p>
+	 * Examples:
+	 * 
+	 * <pre>
+	 * // List all XML files in the OSGI-INF directory and below
+	 * Enumeration e = b.findEntries("OSGI-INF", "*.xml", true);
+	 * 
+	 * // Find a specific localization file
+	 * Enumeration e = b.findEntries("OSGI-INF/l10n",
+	 *     "bundle_nl_DU.properties", false);
+	 * if (e.hasMoreElements())
+	 *     return (URL) e.nextElement();
+	 * </pre>
+	 * 
+	 * <p>
+	 * URLs for directory entries must have their path end with "/".
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * URLs to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param path The path name in which to look. The path is always relative
+	 *        to the root of this bundle and may begin with "/". A
+	 *        path value of "/" indicates the root of this bundle.
+	 * @param filePattern The file name pattern for selecting entries in the
+	 *        specified path. The pattern is only matched against the last
+	 *        element of the entry path. If the entry is a directory then the
+	 *        trailing "/" is not used for pattern matching. Substring
+	 *        matching is supported, as specified in the Filter specification,
+	 *        using the wildcard character ("*"). If null is
+	 *        specified, this is equivalent to "*" and matches all
+	 *        files.
+	 * @param recurse If {@code true}, recurse into subdirectories. Otherwise
+	 *        only return entries from the specified path.
+	 * @return An enumeration of URL objects for each matching entry, or
+	 *         {@code null} if no matching entry could be found or if the caller
+	 *         does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+	 *         Environment supports permissions. The URLs are sorted such that
+	 *         entries from this bundle are returned first followed by the
+	 *         entries from attached fragments in attachment order. If this
+	 *         bundle is a fragment, then only matching entries in this fragment
+	 *         are returned.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @since 1.3
+	 */
+	Enumeration<URL> findEntries(String path, String filePattern, boolean recurse);
+
+	/**
+	 * Returns this bundle's {@link BundleContext}. The returned
+	 * {@code BundleContext} can be used by the caller to act on behalf of this
+	 * bundle.
+	 * 
+	 * <p>
+	 * If this bundle is not in the {@link #STARTING}, {@link #ACTIVE}, or
+	 * {@link #STOPPING} states or this bundle is a fragment bundle, then this
+	 * bundle has no valid {@code BundleContext}. This method will return
+	 * {@code null} if this bundle has no valid {@code BundleContext}.
+	 * 
+	 * @return A {@code BundleContext} for this bundle or {@code null} if this
+	 *         bundle has no valid {@code BundleContext}.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,CONTEXT]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @since 1.4
+	 */
+	BundleContext getBundleContext();
+
+	/**
+	 * Return the certificates for the signers of this bundle and the
+	 * certificate chains for those signers.
+	 * 
+	 * @param signersType If {@link #SIGNERS_ALL} is specified, then information
+	 *        on all signers of this bundle is returned. If
+	 *        {@link #SIGNERS_TRUSTED} is specified, then only information on
+	 *        the signers of this bundle trusted by the framework is returned.
+	 * @return The {@code X509Certificate}s for the signers of this bundle and
+	 *         the {@code X509Certificate} chains for those signers. The keys of
+	 *         the {@code Map} are the {@code X509Certificate}s of the signers
+	 *         of this bundle. The value for a key is a {@code List} containing
+	 *         the {@code X509Certificate} chain for the signer. The first item
+	 *         in the {@code List} is the signer's {@code X509Certificate} which
+	 *         is then followed by the rest of the {@code X509Certificate}
+	 *         chain. The returned {@code Map} will be empty if there are no
+	 *         signers. The returned {@code Map} is the property of the caller
+	 *         who is free to modify it.
+	 * @throws IllegalArgumentException If the specified {@code signersType} is
+	 *         not {@link #SIGNERS_ALL} or {@link #SIGNERS_TRUSTED}.
+	 * @since 1.5
+	 */
+	Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType);
+
+	/**
+	 * Returns the version of this bundle as specified by its
+	 * {@code Bundle-Version} manifest header. If this bundle does not have a
+	 * specified version then {@link Version#emptyVersion} is returned.
+	 * 
+	 * <p>
+	 * This method must continue to return this bundle's version while this
+	 * bundle is in the {@code UNINSTALLED} state.
+	 * 
+	 * @return The version of this bundle.
+	 * @since 1.5
+	 */
+	Version getVersion();
+
+	/**
+	 * Adapt this bundle to the specified type.
+	 * 
+	 * <p>
+	 * Adapting this bundle to the specified type may require certain checks,
+	 * including security checks, to succeed. If a check does not succeed, then
+	 * this bundle cannot be adapted and {@code null} is returned.
+	 * 
+	 * @param <A> The type to which this bundle is to be adapted.
+	 * @param type Class object for the type to which this bundle is to be
+	 *        adapted.
+	 * @return The object, of the specified type, to which this bundle has been
+	 *         adapted or {@code null} if this bundle cannot be adapted to the
+	 *         specified type.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdaptPermission[type,this,ADAPT]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @since 1.6
+	 */
+	<A> A adapt(Class<A> type);
+
+	/**
+	 * Creates a {@code File} object for a file in the persistent storage area
+	 * provided for this bundle by the Framework. This method will return
+	 * {@code null} if the platform does not have file system support or this
+	 * bundle is a fragment bundle.
+	 * 
+	 * <p>
+	 * A {@code File} object for the base directory of the persistent storage
+	 * area provided for this bundle by the Framework can be obtained by calling
+	 * this method with an empty string as {@code filename}.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment supports permissions, the Framework will
+	 * ensure that this bundle has the {@code java.io.FilePermission} with
+	 * actions {@code read},{@code write},{@code delete} for all files
+	 * (recursively) in the persistent storage area provided for this bundle.
+	 * 
+	 * @param filename A relative name to the file to be accessed.
+	 * @return A {@code File} object that represents the requested file or
+	 *         {@code null} if the platform does not have file system support or
+	 *         this bundle is a fragment bundle.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @since 1.6
+	 */
+	File getDataFile(String filename);
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundleActivator.java b/osgi/framework/src/org/osgi/framework/BundleActivator.java
new file mode 100644
index 0000000..acdb825
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundleActivator.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * Customizes the starting and stopping of a bundle.
+ * <p>
+ * {@code BundleActivator} is an interface that may be implemented when a bundle
+ * is started or stopped. The Framework can create instances of a bundle's
+ * {@code BundleActivator} as required. If an instance's
+ * {@code BundleActivator.start} method executes successfully, it is guaranteed
+ * that the same instance's {@code BundleActivator.stop} method will be called
+ * when the bundle is to be stopped. The Framework must not concurrently call a
+ * {@code BundleActivator} object.
+ * 
+ * <p>
+ * {@code BundleActivator} is specified through the {@code Bundle-Activator}
+ * Manifest header. A bundle can only specify a single {@code BundleActivator}
+ * in the Manifest file. Fragment bundles must not have a
+ * {@code BundleActivator}. The form of the Manifest header is:
+ * 
+ * <p>
+ * {@code Bundle-Activator: <i>class-name</i>}
+ * 
+ * <p>
+ * where {@code <i>class-name</i>} is a fully qualified Java classname.
+ * <p>
+ * The specified {@code BundleActivator} class must have a public constructor
+ * that takes no parameters so that a {@code BundleActivator} object can be
+ * created by {@code Class.newInstance()}.
+ * 
+ * @NotThreadSafe
+ * @version $Id: f5b2debe0064ab60669102d0a087feaeab13dc0e $
+ */
+
+public interface BundleActivator {
+	/**
+	 * Called when this bundle is started so the Framework can perform the
+	 * bundle-specific activities necessary to start this bundle. This method
+	 * can be used to register services or to allocate any resources that this
+	 * bundle needs.
+	 * 
+	 * <p>
+	 * This method must complete and return to its caller in a timely manner.
+	 * 
+	 * @param context The execution context of the bundle being started.
+	 * @throws Exception If this method throws an exception, this bundle is
+	 *         marked as stopped and the Framework will remove this bundle's
+	 *         listeners, unregister all services registered by this bundle, and
+	 *         release all services used by this bundle.
+	 */
+	public void start(BundleContext context) throws Exception;
+
+	/**
+	 * Called when this bundle is stopped so the Framework can perform the
+	 * bundle-specific activities necessary to stop the bundle. In general, this
+	 * method should undo the work that the {@code BundleActivator.start} method
+	 * started. There should be no active threads that were started by this
+	 * bundle when this bundle returns. A stopped bundle must not call any
+	 * Framework objects.
+	 * 
+	 * <p>
+	 * This method must complete and return to its caller in a timely manner.
+	 * 
+	 * @param context The execution context of the bundle being stopped.
+	 * @throws Exception If this method throws an exception, the bundle is still
+	 *         marked as stopped, and the Framework will remove the bundle's
+	 *         listeners, unregister all services registered by the bundle, and
+	 *         release all services used by the bundle.
+	 */
+	public void stop(BundleContext context) throws Exception;
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundleContext.java b/osgi/framework/src/org/osgi/framework/BundleContext.java
new file mode 100644
index 0000000..71c3b92
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundleContext.java
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Dictionary;
+
+/**
+ * A bundle's execution context within the Framework. The context is used to
+ * grant access to other methods so that this bundle can interact with the
+ * Framework.
+ * 
+ * <p>
+ * {@code BundleContext} methods allow a bundle to:
+ * <ul>
+ * <li>Subscribe to events published by the Framework.
+ * <li>Register service objects with the Framework service registry.
+ * <li>Retrieve {@code ServiceReferences} from the Framework service registry.
+ * <li>Get and release service objects for a referenced service.
+ * <li>Install new bundles in the Framework.
+ * <li>Get the list of bundles installed in the Framework.
+ * <li>Get the {@link Bundle} object for a bundle.
+ * <li>Create {@code File} objects for files in a persistent storage area
+ * provided for the bundle by the Framework.
+ * </ul>
+ * 
+ * <p>
+ * A {@code BundleContext} object will be created for a bundle when the bundle
+ * is started. The {@code Bundle} object associated with a {@code BundleContext}
+ * object is called the <em>context bundle</em>.
+ * 
+ * <p>
+ * The {@code BundleContext} object will be passed to the
+ * {@link BundleActivator#start(BundleContext)} method during activation of the
+ * context bundle. The same {@code BundleContext} object will be passed to the
+ * {@link BundleActivator#stop(BundleContext)} method when the context bundle is
+ * stopped. A {@code BundleContext} object is generally for the private use of
+ * its associated bundle and is not meant to be shared with other bundles in the
+ * OSGi environment.
+ * 
+ * <p>
+ * The {@code BundleContext} object is only valid during the execution of its
+ * context bundle; that is, during the period from when the context bundle is in
+ * the {@code STARTING}, {@code STOPPING}, and {@code ACTIVE} bundle states. If
+ * the {@code BundleContext} object is used subsequently, an
+ * {@code IllegalStateException} must be thrown. The {@code BundleContext}
+ * object must never be reused after its context bundle is stopped.
+ * 
+ * <p>
+ * Two {@code BundleContext} objects are equal if they both refer to the same
+ * execution context of a bundle. The Framework is the only entity that can
+ * create {@code BundleContext} objects and they are only valid within the
+ * Framework that created them.
+ * 
+ * <p>
+ * A {@link Bundle} can be {@link Bundle#adapt(Class) adapted} to its
+ * {@code BundleContext}. In order for this to succeed, the caller must have the
+ * appropriate {@code AdminPermission[bundle,CONTEXT]} if the Java Runtime
+ * Environment supports permissions.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 4f166fd274f3965e48a7dbc239213d00e062b6d0 $
+ */
+
+public interface BundleContext extends BundleReference {
+
+	/**
+	 * Returns the value of the specified property. If the key is not found in
+	 * the Framework properties, the system properties are then searched. The
+	 * method returns {@code null} if the property is not found.
+	 * 
+	 * <p>
+	 * All bundles must have permission to read properties whose names start
+	 * with "org.osgi.".
+	 * 
+	 * @param key The name of the requested property.
+	 * @return The value of the requested property, or {@code null} if the
+	 *         property is undefined.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code PropertyPermission} to read the property, and the Java
+	 *         Runtime Environment supports permissions.
+	 */
+	String getProperty(String key);
+
+	/**
+	 * Returns the {@code Bundle} object associated with this
+	 * {@code BundleContext}. This bundle is called the context bundle.
+	 * 
+	 * @return The {@code Bundle} object associated with this
+	 *         {@code BundleContext}.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 */
+	Bundle getBundle();
+
+	/**
+	 * Installs a bundle from the specified {@code InputStream} object.
+	 * 
+	 * <p>
+	 * If the specified {@code InputStream} is {@code null}, the Framework must
+	 * create the {@code InputStream} from which to read the bundle by
+	 * interpreting, in an implementation dependent manner, the specified
+	 * {@code location}.
+	 * 
+	 * <p>
+	 * The specified {@code location} identifier will be used as the identity of
+	 * the bundle. Every installed bundle is uniquely identified by its location
+	 * identifier which is typically in the form of a URL.
+	 * 
+	 * <p>
+	 * The following steps are required to install a bundle:
+	 * <ol>
+	 * <li>If a bundle containing the same location identifier is already
+	 * installed, the {@code Bundle} object for that bundle is returned.
+	 * 
+	 * <li>The bundle's content is read from the input stream. If this fails, a
+	 * {@link BundleException} is thrown.
+	 * 
+	 * <li>The bundle's associated resources are allocated. The associated
+	 * resources minimally consist of a unique identifier and a persistent
+	 * storage area if the platform has file system support. If this step fails,
+	 * a {@code BundleException} is thrown.
+	 * 
+	 * <li>The bundle's state is set to {@code INSTALLED}.
+	 * 
+	 * <li>A bundle event of type {@link BundleEvent#INSTALLED} is fired.
+	 * 
+	 * <li>The {@code Bundle} object for the newly or previously installed
+	 * bundle is returned.
+	 * </ol>
+	 * 
+	 * <b>Postconditions, no exceptions thrown </b>
+	 * <ul>
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED}
+	 * &#x007D;.
+	 * <li>Bundle has a unique ID.
+	 * </ul>
+	 * <b>Postconditions, when an exception is thrown </b>
+	 * <ul>
+	 * <li>Bundle is not installed. If there was an existing bundle for the
+	 * specified location, then that bundle must still be in the state it was
+	 * prior to calling this method.</li>
+	 * </ul>
+	 * 
+	 * @param location The location identifier of the bundle to install.
+	 * @param input The {@code InputStream} object from which this bundle will
+	 *        be read or {@code null} to indicate the Framework must create the
+	 *        input stream from the specified location identifier. The input
+	 *        stream must always be closed when this method completes, even if
+	 *        an exception is thrown.
+	 * @return The {@code Bundle} object of the installed bundle.
+	 * @throws BundleException If the installation failed. BundleException types
+	 *         thrown by this method include: {@link BundleException#READ_ERROR}
+	 *         , {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR}, and
+	 *         {@link BundleException#REJECTED_BY_HOOK}.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[installed bundle,LIFECYCLE]}, and the Java
+	 *         Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 */
+	Bundle installBundle(String location, InputStream input) throws BundleException;
+
+	/**
+	 * Installs a bundle from the specified {@code location} identifier.
+	 * 
+	 * <p>
+	 * This method performs the same function as calling
+	 * {@link #installBundle(String,InputStream)} with the specified
+	 * {@code location} identifier and a {@code null} InputStream.
+	 * 
+	 * @param location The location identifier of the bundle to install.
+	 * @return The {@code Bundle} object of the installed bundle.
+	 * @throws BundleException If the installation failed. BundleException types
+	 *         thrown by this method include: {@link BundleException#READ_ERROR}
+	 *         , {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR}, and
+	 *         {@link BundleException#REJECTED_BY_HOOK}.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[installed bundle,LIFECYCLE]}, and the Java
+	 *         Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #installBundle(String, InputStream)
+	 */
+	Bundle installBundle(String location) throws BundleException;
+
+	/**
+	 * Returns the bundle with the specified identifier.
+	 * 
+	 * @param id The identifier of the bundle to retrieve.
+	 * @return A {@code Bundle} object or {@code null} if the identifier does
+	 *         not match any installed bundle.
+	 */
+	Bundle getBundle(long id);
+
+	/**
+	 * Returns a list of all installed bundles.
+	 * <p>
+	 * This method returns a list of all bundles installed in the OSGi
+	 * environment at the time of the call to this method. However, since the
+	 * Framework is a very dynamic environment, bundles can be installed or
+	 * uninstalled at anytime.
+	 * 
+	 * @return An array of {@code Bundle} objects, one object per installed
+	 *         bundle.
+	 */
+	Bundle[] getBundles();
+
+	/**
+	 * Adds the specified {@code ServiceListener} object with the specified
+	 * {@code filter} to the context bundle's list of listeners. See
+	 * {@link Filter} for a description of the filter syntax.
+	 * {@code ServiceListener} objects are notified when a service has a
+	 * lifecycle state change.
+	 * 
+	 * <p>
+	 * If the context bundle's list of listeners already contains a listener
+	 * {@code l} such that {@code (l==listener)}, then this method replaces that
+	 * listener's filter (which may be {@code null}) with the specified one
+	 * (which may be {@code null}).
+	 * 
+	 * <p>
+	 * The listener is called if the filter criteria is met. To filter based
+	 * upon the class of the service, the filter should reference the
+	 * {@link Constants#OBJECTCLASS} property. If {@code filter} is {@code null}
+	 * , all services are considered to match the filter.
+	 * 
+	 * <p>
+	 * When using a {@code filter}, it is possible that the {@code ServiceEvent}
+	 * s for the complete lifecycle of a service will not be delivered to the
+	 * listener. For example, if the {@code filter} only matches when the
+	 * property {@code x} has the value {@code 1}, the listener will not be
+	 * called if the service is registered with the property {@code x} not set
+	 * to the value {@code 1}. Subsequently, when the service is modified
+	 * setting property {@code x} to the value {@code 1}, the filter will match
+	 * and the listener will be called with a {@code ServiceEvent} of type
+	 * {@code MODIFIED}. Thus, the listener will not be called with a
+	 * {@code ServiceEvent} of type {@code REGISTERED}.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment supports permissions, the
+	 * {@code ServiceListener} object will be notified of a service event only
+	 * if the bundle that is registering it has the {@code ServicePermission} to
+	 * get the service using at least one of the named classes the service was
+	 * registered under.
+	 * 
+	 * @param listener The {@code ServiceListener} object to be added.
+	 * @param filter The filter criteria.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
+	 *         filter string that cannot be parsed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see ServiceEvent
+	 * @see ServiceListener
+	 * @see ServicePermission
+	 */
+	void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Adds the specified {@code ServiceListener} object to the context bundle's
+	 * list of listeners.
+	 * 
+	 * <p>
+	 * This method is the same as calling
+	 * {@code BundleContext.addServiceListener(ServiceListener listener,
+	 * String filter)} with {@code filter} set to {@code null}.
+	 * 
+	 * @param listener The {@code ServiceListener} object to be added.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #addServiceListener(ServiceListener, String)
+	 */
+	void addServiceListener(ServiceListener listener);
+
+	/**
+	 * Removes the specified {@code ServiceListener} object from the context
+	 * bundle's list of listeners.
+	 * 
+	 * <p>
+	 * If {@code listener} is not contained in this context bundle's list of
+	 * listeners, this method does nothing.
+	 * 
+	 * @param listener The {@code ServiceListener} to be removed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 */
+	void removeServiceListener(ServiceListener listener);
+
+	/**
+	 * Adds the specified {@code BundleListener} object to the context bundle's
+	 * list of listeners if not already present. BundleListener objects are
+	 * notified when a bundle has a lifecycle state change.
+	 * 
+	 * <p>
+	 * If the context bundle's list of listeners already contains a listener
+	 * {@code l} such that {@code (l==listener)}, this method does nothing.
+	 * 
+	 * @param listener The {@code BundleListener} to be added.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @throws SecurityException If listener is a
+	 *         {@code SynchronousBundleListener} and the caller does not have
+	 *         the appropriate {@code AdminPermission[context bundle,LISTENER]},
+	 *         and the Java Runtime Environment supports permissions.
+	 * @see BundleEvent
+	 * @see BundleListener
+	 */
+	void addBundleListener(BundleListener listener);
+
+	/**
+	 * Removes the specified {@code BundleListener} object from the context
+	 * bundle's list of listeners.
+	 * 
+	 * <p>
+	 * If {@code listener} is not contained in the context bundle's list of
+	 * listeners, this method does nothing.
+	 * 
+	 * @param listener The {@code BundleListener} object to be removed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @throws SecurityException If listener is a
+	 *         {@code SynchronousBundleListener} and the caller does not have
+	 *         the appropriate {@code AdminPermission[context bundle,LISTENER]},
+	 *         and the Java Runtime Environment supports permissions.
+	 */
+	void removeBundleListener(BundleListener listener);
+
+	/**
+	 * Adds the specified {@code FrameworkListener} object to the context
+	 * bundle's list of listeners if not already present. FrameworkListeners are
+	 * notified of general Framework events.
+	 * 
+	 * <p>
+	 * If the context bundle's list of listeners already contains a listener
+	 * {@code l} such that {@code (l==listener)}, this method does nothing.
+	 * 
+	 * @param listener The {@code FrameworkListener} object to be added.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see FrameworkEvent
+	 * @see FrameworkListener
+	 */
+	void addFrameworkListener(FrameworkListener listener);
+
+	/**
+	 * Removes the specified {@code FrameworkListener} object from the context
+	 * bundle's list of listeners.
+	 * 
+	 * <p>
+	 * If {@code listener} is not contained in the context bundle's list of
+	 * listeners, this method does nothing.
+	 * 
+	 * @param listener The {@code FrameworkListener} object to be removed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 */
+	void removeFrameworkListener(FrameworkListener listener);
+
+	/**
+	 * Registers the specified service object with the specified properties
+	 * under the specified class names into the Framework. A
+	 * {@code ServiceRegistration} object is returned. The
+	 * {@code ServiceRegistration} object is for the private use of the bundle
+	 * registering the service and should not be shared with other bundles. The
+	 * registering bundle is defined to be the context bundle. Other bundles can
+	 * locate the service by using one of the
+	 * {@link #getServiceReferences(Class, String)},
+	 * {@link #getServiceReferences(String, String)},
+	 * {@link #getServiceReference(Class)} or
+	 * {@link #getServiceReference(String)} methods.
+	 * 
+	 * <p>
+	 * A bundle can register a service object that implements the
+	 * {@link ServiceFactory} interface to have more flexibility in providing
+	 * service objects to other bundles.
+	 * 
+	 * <p>
+	 * The following steps are required to register a service:
+	 * <ol>
+	 * <li>If {@code service} is not a {@code ServiceFactory}, an
+	 * {@code IllegalArgumentException} is thrown if {@code service} is not an
+	 * {@code instanceof} all the specified class names.
+	 * <li>The Framework adds the following service properties to the service
+	 * properties from the specified {@code Dictionary} (which may be
+	 * {@code null}): <br/>
+	 * A property named {@link Constants#SERVICE_ID} identifying the
+	 * registration number of the service <br/>
+	 * A property named {@link Constants#OBJECTCLASS} containing all the
+	 * specified classes. <br/>
+	 * Properties with these names in the specified {@code Dictionary} will be
+	 * ignored.
+	 * <li>The service is added to the Framework service registry and may now be
+	 * used by other bundles.
+	 * <li>A service event of type {@link ServiceEvent#REGISTERED} is fired.
+	 * <li>A {@code ServiceRegistration} object for this registration is
+	 * returned.
+	 * </ol>
+	 * 
+	 * @param clazzes The class names under which the service can be located.
+	 *        The class names in this array will be stored in the service's
+	 *        properties under the key {@link Constants#OBJECTCLASS}.
+	 * @param service The service object or a {@code ServiceFactory} object.
+	 * @param properties The properties for this service. The keys in the
+	 *        properties object must all be {@code String} objects. See
+	 *        {@link Constants} for a list of standard service property keys.
+	 *        Changes should not be made to this object after calling this
+	 *        method. To update the service's properties the
+	 *        {@link ServiceRegistration#setProperties(Dictionary)} method must
+	 *        be called. The set of properties may be {@code null} if the
+	 *        service has no properties.
+	 * @return A {@code ServiceRegistration} object for use by the bundle
+	 *         registering the service to update the service's properties or to
+	 *         unregister the service.
+	 * @throws IllegalArgumentException If one of the following is true:
+	 *         <ul>
+	 *         <li>{@code service} is {@code null}. <li>{@code service} is not a
+	 *         {@code ServiceFactory} object and is not an instance of all the
+	 *         named classes in {@code clazzes}. <li> {@code properties}
+	 *         contains case variants of the same key name.
+	 *         </ul>
+	 * @throws SecurityException If the caller does not have the
+	 *         {@code ServicePermission} to register the service for all the
+	 *         named classes and the Java Runtime Environment supports
+	 *         permissions.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see ServiceRegistration
+	 * @see ServiceFactory
+	 */
+	ServiceRegistration<?> registerService(String[] clazzes, Object service, Dictionary<String, ?> properties);
+
+	/**
+	 * Registers the specified service object with the specified properties
+	 * under the specified class name with the Framework.
+	 * 
+	 * <p>
+	 * This method is otherwise identical to
+	 * {@link #registerService(String[], Object, Dictionary)} and is provided as
+	 * a convenience when {@code service} will only be registered under a single
+	 * class name. Note that even in this case the value of the service's
+	 * {@link Constants#OBJECTCLASS} property will be an array of string, rather
+	 * than just a single string.
+	 * 
+	 * @param clazz The class name under which the service can be located.
+	 * @param service The service object or a {@code ServiceFactory} object.
+	 * @param properties The properties for this service.
+	 * @return A {@code ServiceRegistration} object for use by the bundle
+	 *         registering the service to update the service's properties or to
+	 *         unregister the service.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #registerService(String[], Object, Dictionary)
+	 */
+	ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties);
+
+	/**
+	 * Registers the specified service object with the specified properties
+	 * under the name of the specified class with the Framework.
+	 * 
+	 * <p>
+	 * This method is otherwise identical to
+	 * {@link #registerService(String, Object, Dictionary)} and is provided to
+	 * return a type safe {@code ServiceRegistration}.
+	 * 
+	 * @param <S> Type of Service.
+	 * @param clazz The class under whose name the service can be located.
+	 * @param service The service object or a {@code ServiceFactory} object.
+	 * @param properties The properties for this service.
+	 * @return A {@code ServiceRegistration} object for use by the bundle
+	 *         registering the service to update the service's properties or to
+	 *         unregister the service.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #registerService(String, Object, Dictionary)
+	 * @since 1.6
+	 */
+	<S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties);
+
+	/**
+	 * Returns an array of {@code ServiceReference} objects. The returned array
+	 * of {@code ServiceReference} objects contains services that were
+	 * registered under the specified class, match the specified filter
+	 * expression, and the packages for the class names under which the services
+	 * were registered match the context bundle's packages as defined in
+	 * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+	 * 
+	 * <p>
+	 * The list is valid at the time of the call to this method. However since
+	 * the Framework is a very dynamic environment, services can be modified or
+	 * unregistered at any time.
+	 * 
+	 * <p>
+	 * The specified {@code filter} expression is used to select the registered
+	 * services whose service properties contain keys and values which satisfy
+	 * the filter expression. See {@link Filter} for a description of the filter
+	 * syntax. If the specified {@code filter} is {@code null}, all registered
+	 * services are considered to match the filter. If the specified
+	 * {@code filter} expression cannot be parsed, an
+	 * {@link InvalidSyntaxException} will be thrown with a human readable
+	 * message where the filter became unparsable.
+	 * 
+	 * <p>
+	 * The result is an array of {@code ServiceReference} objects for all
+	 * services that meet all of the following conditions:
+	 * <ul>
+	 * <li>If the specified class name, {@code clazz}, is not {@code null}, the
+	 * service must have been registered with the specified class name. The
+	 * complete list of class names with which a service was registered is
+	 * available from the service's {@link Constants#OBJECTCLASS objectClass}
+	 * property.
+	 * <li>If the specified {@code filter} is not {@code null}, the filter
+	 * expression must match the service.
+	 * <li>If the Java Runtime Environment supports permissions, the caller must
+	 * have {@code ServicePermission} with the {@code GET} action for at least
+	 * one of the class names under which the service was registered.
+	 * <li>For each class name with which the service was registered, calling
+	 * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
+	 * bundle and the class name on the service's {@code ServiceReference}
+	 * object must return {@code true}
+	 * </ul>
+	 * 
+	 * @param clazz The class name with which the service was registered or
+	 *        {@code null} for all services.
+	 * @param filter The filter expression or {@code null} for all services.
+	 * @return An array of {@code ServiceReference} objects or {@code null} if
+	 *         no services are registered which satisfy the search.
+	 * @throws InvalidSyntaxException If the specified {@code filter} contains
+	 *         an invalid filter expression that cannot be parsed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 */
+	ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Returns an array of {@code ServiceReference} objects. The returned array
+	 * of {@code ServiceReference} objects contains services that were
+	 * registered under the specified class and match the specified filter
+	 * expression.
+	 * 
+	 * <p>
+	 * The list is valid at the time of the call to this method. However since
+	 * the Framework is a very dynamic environment, services can be modified or
+	 * unregistered at any time.
+	 * 
+	 * <p>
+	 * The specified {@code filter} expression is used to select the registered
+	 * services whose service properties contain keys and values which satisfy
+	 * the filter expression. See {@link Filter} for a description of the filter
+	 * syntax. If the specified {@code filter} is {@code null}, all registered
+	 * services are considered to match the filter. If the specified
+	 * {@code filter} expression cannot be parsed, an
+	 * {@link InvalidSyntaxException} will be thrown with a human readable
+	 * message where the filter became unparsable.
+	 * 
+	 * <p>
+	 * The result is an array of {@code ServiceReference} objects for all
+	 * services that meet all of the following conditions:
+	 * <ul>
+	 * <li>If the specified class name, {@code clazz}, is not {@code null}, the
+	 * service must have been registered with the specified class name. The
+	 * complete list of class names with which a service was registered is
+	 * available from the service's {@link Constants#OBJECTCLASS objectClass}
+	 * property.
+	 * <li>If the specified {@code filter} is not {@code null}, the filter
+	 * expression must match the service.
+	 * <li>If the Java Runtime Environment supports permissions, the caller must
+	 * have {@code ServicePermission} with the {@code GET} action for at least
+	 * one of the class names under which the service was registered.
+	 * </ul>
+	 * 
+	 * @param clazz The class name with which the service was registered or
+	 *        {@code null} for all services.
+	 * @param filter The filter expression or {@code null} for all services.
+	 * @return An array of {@code ServiceReference} objects or {@code null} if
+	 *         no services are registered which satisfy the search.
+	 * @throws InvalidSyntaxException If the specified {@code filter} contains
+	 *         an invalid filter expression that cannot be parsed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @since 1.3
+	 */
+	ServiceReference<?>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Returns a {@code ServiceReference} object for a service that implements
+	 * and was registered under the specified class.
+	 * 
+	 * <p>
+	 * The returned {@code ServiceReference} object is valid at the time of the
+	 * call to this method. However as the Framework is a very dynamic
+	 * environment, services can be modified or unregistered at any time.
+	 * 
+	 * <p>
+	 * This method is the same as calling
+	 * {@link #getServiceReferences(String, String)} with a {@code null} filter
+	 * expression and then finding the reference with the highest priority. It
+	 * is provided as a convenience for when the caller is interested in any
+	 * service that implements the specified class.
+	 * <p>
+	 * If multiple such services exist, the service with the highest priority is
+	 * selected. This priority is defined as the service reference with the
+	 * highest ranking (as specified in its {@link Constants#SERVICE_RANKING}
+	 * property) is returned.
+	 * <p>
+	 * If there is a tie in ranking, the service with the lowest service ID (as
+	 * specified in its {@link Constants#SERVICE_ID} property); that is, the
+	 * service that was registered first is returned.
+	 * 
+	 * @param clazz The class name with which the service was registered.
+	 * @return A {@code ServiceReference} object, or {@code null} if no services
+	 *         are registered which implement the named class.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #getServiceReferences(String, String)
+	 */
+	ServiceReference<?> getServiceReference(String clazz);
+
+	/**
+	 * Returns a {@code ServiceReference} object for a service that implements
+	 * and was registered under the name of the specified class.
+	 * 
+	 * <p>
+	 * The returned {@code ServiceReference} object is valid at the time of the
+	 * call to this method. However as the Framework is a very dynamic
+	 * environment, services can be modified or unregistered at any time.
+	 * 
+	 * <p>
+	 * This method is the same as calling
+	 * {@link #getServiceReferences(Class, String)} with a {@code null} filter
+	 * expression. It is provided as a convenience for when the caller is
+	 * interested in any service that implements the specified class.
+	 * <p>
+	 * If multiple such services exist, the service with the highest ranking (as
+	 * specified in its {@link Constants#SERVICE_RANKING} property) is returned.
+	 * <p>
+	 * If there is a tie in ranking, the service with the lowest service ID (as
+	 * specified in its {@link Constants#SERVICE_ID} property); that is, the
+	 * service that was registered first is returned.
+	 * 
+	 * @param <S> Type of Service.
+	 * @param clazz The class under whose name the service was registered. Must
+	 *        not be {@code null}.
+	 * @return A {@code ServiceReference} object, or {@code null} if no services
+	 *         are registered which implement the specified class.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #getServiceReferences(Class, String)
+	 * @since 1.6
+	 */
+	<S> ServiceReference<S> getServiceReference(Class<S> clazz);
+
+	/**
+	 * Returns a collection of {@code ServiceReference} objects. The returned
+	 * collection of {@code ServiceReference} objects contains services that
+	 * were registered under the name of the specified class, match the
+	 * specified filter expression, and the packages for the class names under
+	 * which the services were registered match the context bundle's packages as
+	 * defined in {@link ServiceReference#isAssignableTo(Bundle, String)}.
+	 * 
+	 * <p>
+	 * The collection is valid at the time of the call to this method. However
+	 * since the Framework is a very dynamic environment, services can be
+	 * modified or unregistered at any time.
+	 * 
+	 * <p>
+	 * The specified {@code filter} expression is used to select the registered
+	 * services whose service properties contain keys and values which satisfy
+	 * the filter expression. See {@link Filter} for a description of the filter
+	 * syntax. If the specified {@code filter} is {@code null}, all registered
+	 * services are considered to match the filter. If the specified
+	 * {@code filter} expression cannot be parsed, an
+	 * {@link InvalidSyntaxException} will be thrown with a human readable
+	 * message where the filter became unparsable.
+	 * 
+	 * <p>
+	 * The result is a collection of {@code ServiceReference} objects for all
+	 * services that meet all of the following conditions:
+	 * <ul>
+	 * <li>The service must have been registered with the name of the specified
+	 * class. The complete list of class names with which a service was
+	 * registered is available from the service's {@link Constants#OBJECTCLASS
+	 * objectClass} property.
+	 * <li>If the specified {@code filter} is not {@code null}, the filter
+	 * expression must match the service.
+	 * <li>If the Java Runtime Environment supports permissions, the caller must
+	 * have {@code ServicePermission} with the {@code GET} action for at least
+	 * one of the class names under which the service was registered.
+	 * <li>For each class name with which the service was registered, calling
+	 * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
+	 * bundle and the class name on the service's {@code ServiceReference}
+	 * object must return {@code true}
+	 * </ul>
+	 * 
+	 * @param <S> Type of Service
+	 * @param clazz The class under whose name the service was registered. Must
+	 *        not be {@code null}.
+	 * @param filter The filter expression or {@code null} for all services.
+	 * @return A collection of {@code ServiceReference} objects. May be empty if
+	 *         no services are registered which satisfy the search.
+	 * @throws InvalidSyntaxException If the specified {@code filter} contains
+	 *         an invalid filter expression that cannot be parsed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @since 1.6
+	 */
+	<S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Returns the service object referenced by the specified
+	 * {@code ServiceReference} object.
+	 * <p>
+	 * A bundle's use of a service is tracked by the bundle's use count of that
+	 * service. Each time a service's service object is returned by
+	 * {@link #getService(ServiceReference)} the context bundle's use count for
+	 * that service is incremented by one. Each time the service is released by
+	 * {@link #ungetService(ServiceReference)} the context bundle's use count
+	 * for that service is decremented by one.
+	 * <p>
+	 * When a bundle's use count for a service drops to zero, the bundle should
+	 * no longer use that service.
+	 * 
+	 * <p>
+	 * This method will always return {@code null} when the service associated
+	 * with this {@code reference} has been unregistered.
+	 * 
+	 * <p>
+	 * The following steps are required to get the service object:
+	 * <ol>
+	 * <li>If the service has been unregistered, {@code null} is returned.
+	 * <li>If the context bundle's use count for the service is currently zero
+	 * and the service was registered with an object implementing the
+	 * {@code ServiceFactory} interface, the
+	 * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
+	 * called to create a service object for the context bundle. If the service
+	 * object returned by the {@code ServiceFactory} object is {@code null}, not
+	 * an {@code instanceof} all the classes named when the service was
+	 * registered or the {@code ServiceFactory} object throws an exception or
+	 * will be recursively called for the context bundle, {@code null} is
+	 * returned and a Framework event of type {@link FrameworkEvent#ERROR}
+	 * containing a {@link ServiceException} describing the error is fired. <br>
+	 * This service object is cached by the Framework. While the context
+	 * bundle's use count for the service is greater than zero, subsequent calls
+	 * to get the services's service object for the context bundle will return
+	 * the cached service object.
+	 * <li>The context bundle's use count for this service is incremented by
+	 * one.
+	 * <li>The service object for the service is returned.
+	 * </ol>
+	 * 
+	 * @param <S> Type of Service.
+	 * @param reference A reference to the service.
+	 * @return A service object for the service associated with
+	 *         {@code reference} or {@code null} if the service is not
+	 *         registered, the service object returned by a
+	 *         {@code ServiceFactory} does not implement the classes under which
+	 *         it was registered or the {@code ServiceFactory} threw an
+	 *         exception.
+	 * @throws SecurityException If the caller does not have the
+	 *         {@code ServicePermission} to get the service using at least one
+	 *         of the named classes the service was registered under and the
+	 *         Java Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @throws IllegalArgumentException If the specified
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code BundleContext}.
+	 * @see #ungetService(ServiceReference)
+	 * @see ServiceFactory
+	 */
+	<S> S getService(ServiceReference<S> reference);
+
+	/**
+	 * Releases the service object referenced by the specified
+	 * {@code ServiceReference} object. If the context bundle's use count for
+	 * the service is zero, this method returns {@code false}. Otherwise, the
+	 * context bundle's use count for the service is decremented by one.
+	 * 
+	 * <p>
+	 * The service's service object should no longer be used and all references
+	 * to it should be destroyed when a bundle's use count for the service drops
+	 * to zero.
+	 * 
+	 * <p>
+	 * The following steps are required to unget the service object:
+	 * <ol>
+	 * <li>If the context bundle's use count for the service is zero or the
+	 * service has been unregistered, {@code false} is returned.
+	 * <li>The context bundle's use count for this service is decremented by
+	 * one.
+	 * <li>If the context bundle's use count for the service is currently zero
+	 * and the service was registered with a {@code ServiceFactory} object, the
+	 * {@link ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
+	 * method is called to release the service object for the context bundle.
+	 * <li>{@code true} is returned.
+	 * </ol>
+	 * 
+	 * @param reference A reference to the service to be released.
+	 * @return {@code false} if the context bundle's use count for the service
+	 *         is zero or if the service has been unregistered; {@code true}
+	 *         otherwise.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @throws IllegalArgumentException If the specified
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code BundleContext}.
+	 * @see #getService(ServiceReference)
+	 * @see ServiceFactory
+	 */
+	boolean ungetService(ServiceReference<?> reference);
+
+	/**
+	 * Creates a {@code File} object for a file in the persistent storage area
+	 * provided for the bundle by the Framework. This method will return
+	 * {@code null} if the platform does not have file system support.
+	 * 
+	 * <p>
+	 * A {@code File} object for the base directory of the persistent storage
+	 * area provided for the context bundle by the Framework can be obtained by
+	 * calling this method with an empty string as {@code filename}.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment supports permissions, the Framework will
+	 * ensure that the bundle has the {@code java.io.FilePermission} with
+	 * actions {@code read},{@code write},{@code delete} for all files
+	 * (recursively) in the persistent storage area provided for the context
+	 * bundle.
+	 * 
+	 * @param filename A relative name to the file to be accessed.
+	 * @return A {@code File} object that represents the requested file or
+	 *         {@code null} if the platform does not have file system support.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 */
+	File getDataFile(String filename);
+
+	/**
+	 * Creates a {@code Filter} object. This {@code Filter} object may be used
+	 * to match a {@code ServiceReference} object or a {@code Dictionary}
+	 * object.
+	 * 
+	 * <p>
+	 * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
+	 * thrown with a human readable message where the filter became unparsable.
+	 * 
+	 * @param filter The filter string.
+	 * @return A {@code Filter} object encapsulating the filter string.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
+	 *         filter string that cannot be parsed.
+	 * @throws NullPointerException If {@code filter} is null.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see "Framework specification for a description of the filter string syntax."
+	 * @see FrameworkUtil#createFilter(String)
+	 * @since 1.1
+	 */
+	Filter createFilter(String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Returns the bundle with the specified location.
+	 * 
+	 * @param location The location of the bundle to retrieve.
+	 * @return A {@code Bundle} object or {@code null} if the location does not
+	 *         match any installed bundle.
+	 * @since 1.6
+	 */
+	Bundle getBundle(String location);
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundleEvent.java b/osgi/framework/src/org/osgi/framework/BundleEvent.java
new file mode 100644
index 0000000..04a34a3
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundleEvent.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.EventObject;
+
+/**
+ * An event from the Framework describing a bundle lifecycle change.
+ * <p>
+ * {@code BundleEvent} objects are delivered to
+ * {@code SynchronousBundleListener}s and {@code BundleListener}s when a change
+ * occurs in a bundle's lifecycle. A type code is used to identify the event
+ * type for future extendability.
+ * 
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ * 
+ * @Immutable
+ * @see BundleListener
+ * @see SynchronousBundleListener
+ * @version $Id: 9e2102212eb526b5f11fdde4b0fc5c171a0b39c8 $
+ */
+
+public class BundleEvent extends EventObject {
+	static final long		serialVersionUID	= 4080640865971756012L;
+	/**
+	 * Bundle that had a change occur in its lifecycle.
+	 */
+	private final Bundle	bundle;
+
+	/**
+	 * Type of bundle lifecycle change.
+	 */
+	private final int		type;
+
+	/**
+	 * The bundle has been installed.
+	 * 
+	 * @see BundleContext#installBundle(String)
+	 */
+	public final static int	INSTALLED			= 0x00000001;
+
+	/**
+	 * The bundle has been started.
+	 * <p>
+	 * The bundle's {@link BundleActivator#start(BundleContext) BundleActivator
+	 * start} method has been executed if the bundle has a bundle activator
+	 * class.
+	 * 
+	 * @see Bundle#start()
+	 */
+	public final static int	STARTED				= 0x00000002;
+
+	/**
+	 * The bundle has been stopped.
+	 * <p>
+	 * The bundle's {@link BundleActivator#stop(BundleContext) BundleActivator
+	 * stop} method has been executed if the bundle has a bundle activator
+	 * class.
+	 * 
+	 * @see Bundle#stop()
+	 */
+	public final static int	STOPPED				= 0x00000004;
+
+	/**
+	 * The bundle has been updated.
+	 * 
+	 * @see Bundle#update()
+	 */
+	public final static int	UPDATED				= 0x00000008;
+
+	/**
+	 * The bundle has been uninstalled.
+	 * 
+	 * @see Bundle#uninstall()
+	 */
+	public final static int	UNINSTALLED			= 0x00000010;
+
+	/**
+	 * The bundle has been resolved.
+	 * 
+	 * @see Bundle#RESOLVED
+	 * @since 1.3
+	 */
+	public final static int	RESOLVED			= 0x00000020;
+
+	/**
+	 * The bundle has been unresolved.
+	 * 
+	 * @see Bundle#INSTALLED
+	 * @since 1.3
+	 */
+	public final static int	UNRESOLVED			= 0x00000040;
+
+	/**
+	 * The bundle is about to be activated.
+	 * <p>
+	 * The bundle's {@link BundleActivator#start(BundleContext) BundleActivator
+	 * start} method is about to be called if the bundle has a bundle activator
+	 * class. This event is only delivered to {@link SynchronousBundleListener}
+	 * s. It is not delivered to {@code BundleListener}s.
+	 * 
+	 * @see Bundle#start()
+	 * @since 1.3
+	 */
+	public final static int	STARTING			= 0x00000080;
+
+	/**
+	 * The bundle is about to deactivated.
+	 * <p>
+	 * The bundle's {@link BundleActivator#stop(BundleContext) BundleActivator
+	 * stop} method is about to be called if the bundle has a bundle activator
+	 * class. This event is only delivered to {@link SynchronousBundleListener}
+	 * s. It is not delivered to {@code BundleListener}s.
+	 * 
+	 * @see Bundle#stop()
+	 * @since 1.3
+	 */
+	public final static int	STOPPING			= 0x00000100;
+
+	/**
+	 * The bundle will be lazily activated.
+	 * <p>
+	 * The bundle has a {@link Constants#ACTIVATION_LAZY lazy activation policy}
+	 * and is waiting to be activated. It is now in the {@link Bundle#STARTING
+	 * STARTING} state and has a valid {@code BundleContext}. This event is only
+	 * delivered to {@link SynchronousBundleListener}s. It is not delivered to
+	 * {@code BundleListener}s.
+	 * 
+	 * @since 1.4
+	 */
+	public final static int	LAZY_ACTIVATION		= 0x00000200;
+
+	/**
+	 * Bundle that was the origin of the event. For install event type, this is
+	 * the bundle whose context was used to install the bundle. Otherwise it is
+	 * the bundle itself.
+	 * 
+	 * @since 1.6
+	 */
+	private final Bundle	origin;
+
+	/**
+	 * Creates a bundle event of the specified type.
+	 * 
+	 * @param type The event type.
+	 * @param bundle The bundle which had a lifecycle change.
+	 * @param origin The bundle which is the origin of the event. For the event
+	 *        type {@link #INSTALLED}, this is the bundle whose context was used
+	 *        to install the bundle. Otherwise it is the bundle itself.
+	 * @since 1.6
+	 */
+	public BundleEvent(int type, Bundle bundle, Bundle origin) {
+		super(bundle);
+		if (origin == null) {
+			throw new IllegalArgumentException("null origin");
+		}
+		this.bundle = bundle;
+		this.type = type;
+		this.origin = origin;
+	}
+
+	/**
+	 * Creates a bundle event of the specified type.
+	 * 
+	 * @param type The event type.
+	 * @param bundle The bundle which had a lifecycle change. This bundle is
+	 *        used as the origin of the event.
+	 */
+	public BundleEvent(int type, Bundle bundle) {
+		super(bundle);
+		this.bundle = bundle;
+		this.type = type;
+		this.origin = bundle;
+	}
+
+	/**
+	 * Returns the bundle which had a lifecycle change. This bundle is the
+	 * source of the event.
+	 * 
+	 * @return The bundle that had a change occur in its lifecycle.
+	 */
+	public Bundle getBundle() {
+		return bundle;
+	}
+
+	/**
+	 * Returns the type of lifecyle event. The type values are:
+	 * <ul>
+	 * <li>{@link #INSTALLED}
+	 * <li>{@link #RESOLVED}
+	 * <li>{@link #LAZY_ACTIVATION}
+	 * <li>{@link #STARTING}
+	 * <li>{@link #STARTED}
+	 * <li>{@link #STOPPING}
+	 * <li>{@link #STOPPED}
+	 * <li>{@link #UPDATED}
+	 * <li>{@link #UNRESOLVED}
+	 * <li>{@link #UNINSTALLED}
+	 * </ul>
+	 * 
+	 * @return The type of lifecycle event.
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * Returns the bundle that was the origin of the event.
+	 * 
+	 * <p>
+	 * For the event type {@link #INSTALLED}, this is the bundle whose context
+	 * was used to install the bundle. Otherwise it is the bundle itself.
+	 * 
+	 * @return The bundle that was the origin of the event.
+	 * @since 1.6
+	 */
+	public Bundle getOrigin() {
+		return origin;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundleException.java b/osgi/framework/src/org/osgi/framework/BundleException.java
new file mode 100644
index 0000000..c47eb77
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundleException.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A Framework exception used to indicate that a bundle lifecycle problem
+ * occurred.
+ * 
+ * <p>
+ * A {@code BundleException} object is created by the Framework to denote an
+ * exception condition in the lifecycle of a bundle. {@code BundleException}s
+ * should not be created by bundle developers. A type code is used to identify
+ * the exception type for future extendability.
+ * 
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ * 
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ * 
+ * @version $Id: 0c97ed2696b4576d61440020922b1a97545beb1e $
+ */
+
+public class BundleException extends Exception {
+	static final long		serialVersionUID		= 3571095144220455665L;
+	/**
+	 * Type of bundle exception.
+	 * 
+	 * @since 1.5
+	 */
+	private final int		type;
+
+	/**
+	 * No exception type is specified.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	UNSPECIFIED				= 0;
+	/**
+	 * The operation was unsupported. This type can be used anywhere a
+	 * BundleException can be thrown.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	UNSUPPORTED_OPERATION	= 1;
+	/**
+	 * The operation was invalid.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	INVALID_OPERATION		= 2;
+	/**
+	 * The bundle manifest was in error.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	MANIFEST_ERROR			= 3;
+	/**
+	 * The bundle was not resolved.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	RESOLVE_ERROR			= 4;
+	/**
+	 * The bundle activator was in error.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	ACTIVATOR_ERROR			= 5;
+	/**
+	 * The operation failed due to insufficient permissions.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	SECURITY_ERROR			= 6;
+	/**
+	 * The operation failed to complete the requested lifecycle state change.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	STATECHANGE_ERROR		= 7;
+
+	/**
+	 * The bundle could not be resolved due to an error with the
+	 * Bundle-NativeCode header.
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	NATIVECODE_ERROR		= 8;
+
+	/**
+	 * The install or update operation failed because another already installed
+	 * bundle has the same symbolic name and version. This exception type will
+	 * only occur if the framework is configured to only allow a single bundle
+	 * to be installed for a given symbolic name and version.
+	 * 
+	 * @see Constants#FRAMEWORK_BSNVERSION
+	 * @since 1.5
+	 */
+	public static final int	DUPLICATE_BUNDLE_ERROR	= 9;
+
+	/**
+	 * The start transient operation failed because the start level of the
+	 * bundle is greater than the current framework start level
+	 * 
+	 * @since 1.5
+	 */
+	public static final int	START_TRANSIENT_ERROR	= 10;
+
+	/**
+	 * The framework received an error while reading the input stream for a
+	 * bundle.
+	 * 
+	 * @since 1.6
+	 */
+	public static final int	READ_ERROR				= 11;
+
+	/**
+	 * A framework hook rejected the operation.
+	 * 
+	 * @since 1.6
+	 */
+	public static final int	REJECTED_BY_HOOK		= 12;
+
+	/**
+	 * Creates a {@code BundleException} with the specified message and
+	 * exception cause.
+	 * 
+	 * @param msg The associated message.
+	 * @param cause The cause of this exception.
+	 */
+	public BundleException(String msg, Throwable cause) {
+		this(msg, UNSPECIFIED, cause);
+	}
+
+	/**
+	 * Creates a {@code BundleException} with the specified message.
+	 * 
+	 * @param msg The message.
+	 */
+	public BundleException(String msg) {
+		this(msg, UNSPECIFIED);
+	}
+
+	/**
+	 * Creates a {@code BundleException} with the specified message, type and
+	 * exception cause.
+	 * 
+	 * @param msg The associated message.
+	 * @param type The type for this exception.
+	 * @param cause The cause of this exception.
+	 * @since 1.5
+	 */
+	public BundleException(String msg, int type, Throwable cause) {
+		super(msg, cause);
+		this.type = type;
+	}
+
+	/**
+	 * Creates a {@code BundleException} with the specified message and type.
+	 * 
+	 * @param msg The message.
+	 * @param type The type for this exception.
+	 * @since 1.5
+	 */
+	public BundleException(String msg, int type) {
+		super(msg);
+		this.type = type;
+	}
+
+	/**
+	 * Returns the cause of this exception or {@code null} if no cause was
+	 * specified when this exception was created.
+	 * 
+	 * <p>
+	 * This method predates the general purpose exception chaining mechanism.
+	 * The {@code getCause()} method is now the preferred means of obtaining
+	 * this information.
+	 * 
+	 * @return The result of calling {@code getCause()}.
+	 */
+	public Throwable getNestedException() {
+		return getCause();
+	}
+
+	/**
+	 * Returns the cause of this exception or {@code null} if no cause was set.
+	 * 
+	 * @return The cause of this exception or {@code null} if no cause was set.
+	 * @since 1.3
+	 */
+	public Throwable getCause() {
+		return super.getCause();
+	}
+
+	/**
+	 * Initializes the cause of this exception to the specified value.
+	 * 
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
+	 * @since 1.3
+	 */
+	public Throwable initCause(Throwable cause) {
+		return super.initCause(cause);
+	}
+
+	/**
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the type
+	 * was unspecified or unknown.
+	 * 
+	 * @return The type of this exception.
+	 * @since 1.5
+	 */
+	public int getType() {
+		return type;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundleListener.java b/osgi/framework/src/org/osgi/framework/BundleListener.java
new file mode 100644
index 0000000..8d86d30
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundleListener.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.EventListener;
+
+/**
+ * A {@code BundleEvent} listener. {@code BundleListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
+ * {@code BundleEvent} is fired, it is asynchronously delivered to a
+ * {@code BundleListener}. The Framework delivers {@code BundleEvent} objects to
+ * a {@code BundleListener} in order and must not concurrently call a
+ * {@code BundleListener}.
+ * <p>
+ * A {@code BundleListener} object is registered with the Framework using the
+ * {@link BundleContext#addBundleListener(BundleListener)} method.
+ * {@code BundleListener}s are called with a {@code BundleEvent} object when a
+ * bundle has been installed, resolved, started, stopped, updated, unresolved,
+ * or uninstalled.
+ * 
+ * @see BundleEvent
+ * @NotThreadSafe
+ * @version $Id: d48b4a8a59c839466a3d749dde23980d236f58c6 $
+ */
+
+public interface BundleListener extends EventListener {
+	/**
+	 * Receives notification that a bundle has had a lifecycle change.
+	 * 
+	 * @param event The {@code BundleEvent}.
+	 */
+	public void bundleChanged(BundleEvent event);
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundlePermission.java b/osgi/framework/src/org/osgi/framework/BundlePermission.java
new file mode 100644
index 0000000..f9e64ae
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundlePermission.java
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A bundle's authority to require or provide a bundle or to receive or attach
+ * fragments.
+ * 
+ * <p>
+ * A bundle symbolic name defines a unique fully qualified name. Wildcards may
+ * be used.
+ * 
+ * <pre>
+ * name ::= <symbolic name> | <symbolic name ending in ".*"> | *
+ * </pre>
+ * 
+ * Examples:
+ * 
+ * <pre>
+ * org.osgi.example.bundle
+ * org.osgi.example.*
+ * *
+ * </pre>
+ * 
+ * <p>
+ * {@code BundlePermission} has four actions: {@code provide}, {@code require},
+ * {@code host}, and {@code fragment}. The {@code provide} action implies the
+ * {@code require} action.
+ * 
+ * @since 1.3
+ * @ThreadSafe
+ * @version $Id: ccba905e3373800dfdb080118e97145abf778da2 $
+ */
+
+public final class BundlePermission extends BasicPermission {
+
+	private static final long	serialVersionUID	= 3257846601685873716L;
+
+	/**
+	 * The action string {@code provide}. The {@code provide} action implies the
+	 * {@code require} action.
+	 */
+	public final static String	PROVIDE				= "provide";
+
+	/**
+	 * The action string {@code require}. The {@code require} action is implied
+	 * by the {@code provide} action.
+	 */
+	public final static String	REQUIRE				= "require";
+
+	/**
+	 * The action string {@code host}.
+	 */
+	public final static String	HOST				= "host";
+
+	/**
+	 * The action string {@code fragment}.
+	 */
+	public final static String	FRAGMENT			= "fragment";
+
+	private final static int	ACTION_PROVIDE		= 0x00000001;
+	private final static int	ACTION_REQUIRE		= 0x00000002;
+	private final static int	ACTION_HOST			= 0x00000004;
+	private final static int	ACTION_FRAGMENT		= 0x00000008;
+	private final static int	ACTION_ALL			= ACTION_PROVIDE | ACTION_REQUIRE | ACTION_HOST | ACTION_FRAGMENT;
+	final static int			ACTION_NONE			= 0;
+	/**
+	 * The actions mask.
+	 */
+	private transient int		action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String		actions				= null;
+
+	/**
+	 * Defines the authority to provide and/or require and or specify a host
+	 * fragment symbolic name within the OSGi environment.
+	 * <p>
+	 * Bundle Permissions are granted over all possible versions of a bundle.
+	 * 
+	 * A bundle that needs to provide a bundle must have the appropriate
+	 * {@code BundlePermission} for the symbolic name; a bundle that requires a
+	 * bundle must have the appropriate {@code BundlePermssion} for that
+	 * symbolic name; a bundle that specifies a fragment host must have the
+	 * appropriate {@code BundlePermission} for that symbolic name.
+	 * 
+	 * @param symbolicName The bundle symbolic name.
+	 * @param actions {@code provide},{@code require}, {@code host},
+	 *        {@code fragment} (canonical order).
+	 */
+	public BundlePermission(String symbolicName, String actions) {
+		this(symbolicName, parseActions(actions));
+	}
+
+	/**
+	 * Package private constructor used by BundlePermissionCollection.
+	 * 
+	 * @param symbolicName the bundle symbolic name
+	 * @param mask the action mask
+	 */
+	BundlePermission(String symbolicName, int mask) {
+		super(symbolicName);
+		setTransients(mask);
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask
+	 */
+	private synchronized void setTransients(int mask) {
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+
+		action_mask = mask;
+	}
+
+	/**
+	 * Returns the current action mask.
+	 * <p>
+	 * Used by the BundlePermissionCollection class.
+	 * 
+	 * @return Current action mask.
+	 */
+	synchronized int getActionsMask() {
+		return action_mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
+					&& (a[i - 5] == 'r' || a[i - 5] == 'R')
+					&& (a[i - 4] == 'o' || a[i - 4] == 'O')
+					&& (a[i - 3] == 'v' || a[i - 3] == 'V')
+					&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+					&& (a[i - 1] == 'd' || a[i - 1] == 'D')
+					&& (a[i] == 'e' || a[i] == 'E')) {
+				matchlen = 7;
+				mask |= ACTION_PROVIDE | ACTION_REQUIRE;
+			} else
+				if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
+						&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+						&& (a[i - 4] == 'q' || a[i - 4] == 'Q')
+						&& (a[i - 3] == 'u' || a[i - 3] == 'U')
+						&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+						&& (a[i - 1] == 'r' || a[i - 1] == 'R')
+						&& (a[i] == 'e' || a[i] == 'E')) {
+					matchlen = 7;
+					mask |= ACTION_REQUIRE;
+				} else
+					if (i >= 3 && (a[i - 3] == 'h' || a[i - 3] == 'H')
+							&& (a[i - 2] == 'o' || a[i - 2] == 'O')
+							&& (a[i - 1] == 's' || a[i - 1] == 'S')
+							&& (a[i] == 't' || a[i] == 'T')) {
+						matchlen = 4;
+						mask |= ACTION_HOST;
+					} else
+						if (i >= 7 && (a[i - 7] == 'f' || a[i - 7] == 'F')
+								&& (a[i - 6] == 'r' || a[i - 6] == 'R')
+								&& (a[i - 5] == 'a' || a[i - 5] == 'A')
+								&& (a[i - 4] == 'g' || a[i - 4] == 'G')
+								&& (a[i - 3] == 'm' || a[i - 3] == 'M')
+								&& (a[i - 2] == 'e' || a[i - 2] == 'E')
+								&& (a[i - 1] == 'n' || a[i - 1] == 'N')
+								&& (a[i] == 't' || a[i] == 'T')) {
+							matchlen = 8;
+							mask |= ACTION_FRAGMENT;
+						} else {
+							// parse error
+							throw new IllegalArgumentException("invalid permission: " + actions);
+						}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfrequire". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Determines if the specified permission is implied by this object.
+	 * 
+	 * <p>
+	 * This method checks that the symbolic name of the target is implied by the
+	 * symbolic name of this object. The list of {@code BundlePermission}
+	 * actions must either match or allow for the list of the target object to
+	 * imply the target {@code BundlePermission} action.
+	 * <p>
+	 * The permission to provide a bundle implies the permission to require the
+	 * named symbolic name.
+	 * 
+	 * <pre>
+	 *       x.y.*,"provide" -> x.y.z,"provide" is true
+	 *       *,"require" -> x.y, "require"      is true
+	 *       *,"provide" -> x.y, "require"      is true
+	 *       x.y,"provide" -> x.y.z, "provide"  is false
+	 * </pre>
+	 * 
+	 * @param p The requested permission.
+	 * @return {@code true} if the specified {@code BundlePermission} action is
+	 *         implied by this object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof BundlePermission)) {
+			return false;
+		}
+		BundlePermission requested = (BundlePermission) p;
+
+		final int effective = getActionsMask();
+		final int desired = requested.getActionsMask();
+		return ((effective & desired) == desired) && super.implies(requested);
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * {@code BundlePermission} actions.
+	 * 
+	 * <p>
+	 * Always returns present {@code BundlePermission} actions in the following
+	 * order: {@code provide}, {@code require}, {@code host}, {@code fragment}.
+	 * 
+	 * @return Canonical string representation of the {@code BundlePermission
+	 *         } actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+
+			if ((action_mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
+				sb.append(PROVIDE);
+				comma = true;
+			}
+
+			if ((action_mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
+				if (comma)
+					sb.append(',');
+				sb.append(REQUIRE);
+				comma = true;
+			}
+
+			if ((action_mask & ACTION_HOST) == ACTION_HOST) {
+				if (comma)
+					sb.append(',');
+				sb.append(HOST);
+				comma = true;
+			}
+
+			if ((action_mask & ACTION_FRAGMENT) == ACTION_FRAGMENT) {
+				if (comma)
+					sb.append(',');
+				sb.append(FRAGMENT);
+			}
+
+			actions = result = sb.toString();
+		}
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code BundlePermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new BundlePermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two {@code BundlePermission} objects.
+	 * 
+	 * This method checks that specified bundle has the same bundle symbolic
+	 * name and {@code BundlePermission} actions as this
+	 * {@code BundlePermission} object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code BundlePermission} object.
+	 * @return {@code true} if {@code obj} is a {@code BundlePermission}, and
+	 *         has the same bundle symbolic name and actions as this
+	 *         {@code BundlePermission} object; {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof BundlePermission)) {
+			return false;
+		}
+
+		BundlePermission bp = (BundlePermission) obj;
+
+		return (getActionsMask() == bp.getActionsMask()) && getName().equals(bp.getName());
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of the {@code BundlePermission}
+	 * object to a stream. The actions are serialized, and the superclass takes
+	 * care of the name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of the BundlePermission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(parseActions(actions));
+	}
+}
+
+/**
+ * Stores a set of {@code BundlePermission} permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class BundlePermissionCollection extends PermissionCollection {
+	private static final long						serialVersionUID	= 3258407326846433079L;
+
+	/**
+	 * Table of permissions.
+	 * 
+	 * @GuardedBy this
+	 */
+	private transient Map<String, BundlePermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean									all_allowed;
+
+	/**
+	 * Create an empty BundlePermissions object.
+	 * 
+	 */
+	public BundlePermissionCollection() {
+		permissions = new HashMap<String, BundlePermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Add a permission to this permission collection.
+	 * 
+	 * @param permission The {@code BundlePermission} object to add.
+	 * @throws IllegalArgumentException If the permission is not a
+	 *         {@code BundlePermission} instance.
+	 * @throws SecurityException If this {@code BundlePermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof BundlePermission)) {
+			throw new IllegalArgumentException("invalid permission: " + permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+		}
+		final BundlePermission bp = (BundlePermission) permission;
+		final String name = bp.getName();
+		synchronized (this) {
+			Map<String, BundlePermission> pc = permissions;
+			BundlePermission existing = pc.get(name);
+			if (existing != null) {
+				final int oldMask = existing.getActionsMask();
+				final int newMask = bp.getActionsMask();
+				if (oldMask != newMask) {
+					pc.put(name, new BundlePermission(name, oldMask | newMask));
+
+				}
+			} else {
+				pc.put(name, bp);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*"))
+					all_allowed = true;
+			}
+		}
+	}
+
+	/**
+	 * Determines if the specified permissions implies the permissions expressed
+	 * in {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare with this
+	 *        {@code BundlePermission} object.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof BundlePermission)) {
+			return false;
+		}
+		BundlePermission requested = (BundlePermission) permission;
+		String requestedName = requested.getName();
+		final int desired = requested.getActionsMask();
+		int effective = BundlePermission.ACTION_NONE;
+		BundlePermission bp;
+
+		synchronized (this) {
+			Map<String, BundlePermission> pc = permissions;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				bp = pc.get("*");
+				if (bp != null) {
+					effective |= bp.getActionsMask();
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+			bp = pc.get(requestedName);
+			// strategy:
+			// Check for full match first. Then work our way up the
+			// name looking for matches on a.b.*
+			if (bp != null) {
+				// we have a direct hit!
+				effective |= bp.getActionsMask();
+				if ((effective & desired) == desired) {
+					return true;
+				}
+			}
+			// work our way up the tree...
+			int last;
+			int offset = requestedName.length() - 1;
+			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+				requestedName = requestedName.substring(0, last + 1) + "*";
+				bp = pc.get(requestedName);
+				if (bp != null) {
+					effective |= bp.getActionsMask();
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+				offset = last - 1;
+			}
+			// we don't have to check for "*" as it was already checked
+			// at the top (all_allowed), so we just return false
+			return false;
+		}
+	}
+
+	/**
+	 * Returns an enumeration of all {@code BundlePermission} objects in the
+	 * container.
+	 * 
+	 * @return Enumeration of all {@code BundlePermission} objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, BundlePermission> hashtable = new Hashtable<String, BundlePermission>(permissions);
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", hashtable);
+		pfields.put("all_allowed", all_allowed);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		Hashtable<String, BundlePermission> hashtable = (Hashtable<String, BundlePermission>) gfields.get("permissions", null);
+		permissions = new HashMap<String, BundlePermission>(hashtable);
+		all_allowed = gfields.get("all_allowed", false);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/BundleReference.java b/osgi/framework/src/org/osgi/framework/BundleReference.java
new file mode 100644
index 0000000..97340f7
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/BundleReference.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A reference to a Bundle.
+ * 
+ * @since 1.5
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: e61bd3e020264b04022a430fe09a85ee3aabf1a3 $
+ */
+public interface BundleReference {
+	/**
+	 * Returns the {@code Bundle} object associated with this
+	 * {@code BundleReference}.
+	 * 
+	 * @return The {@code Bundle} object associated with this
+	 *         {@code BundleReference}.
+	 */
+	public Bundle getBundle();
+}
diff --git a/osgi/framework/src/org/osgi/framework/CapabilityPermission.java b/osgi/framework/src/org/osgi/framework/CapabilityPermission.java
new file mode 100644
index 0000000..c27e1ac
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/CapabilityPermission.java
@@ -0,0 +1,775 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A bundle's authority to provide or require a capability.
+ * <ul>
+ * <li>The {@code provide} action allows a bundle to provide a capability
+ * matching the specified filter.
+ * <li>The {@code require} action allows a bundle to require a capability
+ * matching the specified filter.
+ * </ul>
+ * 
+ * @ThreadSafe
+ * @version $Id: b17bcaec959f67c3eae4c4c80c39a0a8716b22dc $
+ * @since 1.6
+ */
+
+public final class CapabilityPermission extends BasicPermission {
+	static final long								serialVersionUID	= -7662148639076511574L;
+	/**
+	 * The action string {@code require}.
+	 */
+	public final static String						REQUIRE				= "require";
+	/**
+	 * The action string {@code provide}.
+	 */
+	public final static String						PROVIDE				= "provide";
+
+	private final static int						ACTION_REQUIRE		= 0x00000001;
+	private final static int						ACTION_PROVIDE		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_REQUIRE | ACTION_PROVIDE;
+	final static int								ACTION_NONE			= 0;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions				= null;
+
+	/**
+	 * The attributes of the requested capability. Must be null if not
+	 * constructed with attributes.
+	 */
+	transient final Map<String, Object>				attributes;
+
+	/**
+	 * The bundle of the requested capability. Must be null if not constructed
+	 * with bundle.
+	 */
+	transient final Bundle							bundle;
+
+	/**
+	 * If this CapabilityPermission was constructed with a filter, this holds a
+	 * Filter matching object used to evaluate the filter in implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * Create a new CapabilityPermission.
+	 * 
+	 * <p>
+	 * The name is specified as a dot-separated string. Wildcards may be used.
+	 * 
+	 * <pre>
+	 * name ::= <namespace> | <namespace ending in ".*"> | *
+	 * </pre>
+	 * 
+	 * Examples:
+	 * 
+	 * <pre>
+	 * com.acme.capability.*
+	 * org.foo.capability
+	 * *
+	 * </pre>
+	 * 
+	 * For the {@code require} action, the name can also be a filter expression.
+	 * The filter gives access to the capability attributes as well as the
+	 * following attributes:
+	 * <ul>
+	 * <li>signer - A Distinguished Name chain used to sign the bundle providing
+	 * the capability. Wildcards in a DN are not matched according to the filter
+	 * string rules, but according to the rules defined for a DN chain.</li>
+	 * <li>location - The location of the bundle providing the capability.</li>
+	 * <li>id - The bundle ID of the bundle providing the capability.</li>
+	 * <li>name - The symbolic name of the bundle providing the capability.</li>
+	 * <li>capability.namespace - The namespace of the required capability.</li>
+	 * </ul>
+	 * Since the above attribute names may conflict with attribute names of a
+	 * capability, you can prefix an attribute name with '@' in the filter
+	 * expression to match against the capability attributes and not one of the
+	 * above attributes. Filter attribute names are processed in a case
+	 * sensitive manner.
+	 * 
+	 * <p>
+	 * There are two possible actions: {@code require} and {@code provide}. The
+	 * {@code require} permission allows the owner of this permission to require
+	 * a capability matching the attributes. The {@code provide} permission
+	 * allows the bundle to provide a capability in the specified capability
+	 * namespace.
+	 * 
+	 * @param name The capability namespace or a filter over the attributes.
+	 * @param actions {@code require},{@code provide} (canonical order)
+	 * @throws IllegalArgumentException If the specified name is a filter
+	 *         expression and either the specified action is not {@code require}
+	 *         or the filter has an invalid syntax.
+	 */
+	public CapabilityPermission(String name, String actions) {
+		this(name, parseActions(actions));
+		if ((this.filter != null) && ((action_mask & ACTION_ALL) != ACTION_REQUIRE)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
+		}
+	}
+
+	/**
+	 * Creates a new requested {@code CapabilityPermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code require}
+	 * action. {@code CapabilityPermission} objects created with this
+	 * constructor cannot be added to a {@code CapabilityPermission} permission
+	 * collection.
+	 * 
+	 * @param namespace The requested capability namespace.
+	 * @param attributes The requested capability attributes.
+	 * @param providingBundle The bundle providing the requested capability.
+	 * @param actions The action {@code require}.
+	 * @throws IllegalArgumentException If the specified action is not
+	 *         {@code require} or attributes or providingBundle are {@code null}
+	 *         .
+	 */
+	public CapabilityPermission(String namespace, Map<String, ?> attributes, Bundle providingBundle, String actions) {
+		super(namespace);
+		setTransients(namespace, parseActions(actions));
+		if (attributes == null) {
+			throw new IllegalArgumentException("attributes must not be null");
+		}
+		if (providingBundle == null) {
+			throw new IllegalArgumentException("bundle must not be null");
+		}
+		this.attributes = new HashMap<String, Object>(attributes);
+		this.bundle = providingBundle;
+		if ((action_mask & ACTION_ALL) != ACTION_REQUIRE) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+	}
+
+	/**
+	 * Package private constructor used by CapabilityPermissionCollection.
+	 * 
+	 * @param name class name
+	 * @param mask action mask
+	 */
+	CapabilityPermission(String name, int mask) {
+		super(name);
+		setTransients(name, mask);
+		this.attributes = null;
+		this.bundle = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask action mask
+	 */
+	private void setTransients(String name, int mask) {
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		action_mask = mask;
+		filter = parseFilter(name);
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
+					&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+					&& (a[i - 4] == 'q' || a[i - 4] == 'Q')
+					&& (a[i - 3] == 'u' || a[i - 3] == 'U')
+					&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+					&& (a[i - 1] == 'r' || a[i - 1] == 'R')
+					&& (a[i] == 'e' || a[i] == 'E')) {
+				matchlen = 7;
+				mask |= ACTION_REQUIRE;
+			} else
+				if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
+						&& (a[i - 5] == 'r' || a[i - 5] == 'R')
+						&& (a[i - 4] == 'o' || a[i - 4] == 'O')
+						&& (a[i - 3] == 'v' || a[i - 3] == 'V')
+						&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+						&& (a[i - 1] == 'd' || a[i - 1] == 'D')
+						&& (a[i] == 'e' || a[i] == 'E')) {
+					matchlen = 7;
+					mask |= ACTION_PROVIDE;
+				} else {
+					// parse error
+					throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfprovide". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle. If the specified filterString is not a
+	 *         filter expression, then {@code null} is returned.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		filterString = filterString.trim();
+		if (filterString.charAt(0) != '(') {
+			return null;
+		}
+
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if a {@code CapabilityPermission} object "implies" the
+	 * specified permission.
+	 * 
+	 * @param p The target permission to check.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof CapabilityPermission)) {
+			return false;
+		}
+		CapabilityPermission requested = (CapabilityPermission) p;
+		if (bundle != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested CapabilityPermission which has already be
+	 *        validated as a proper argument. The requested CapabilityPermission
+	 *        must not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(CapabilityPermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+		/* Get filter if any */
+		Filter f = filter;
+		if (f == null) {
+			return super.implies(requested);
+		}
+		return f.matches(requested.getProperties());
+	}
+
+	/**
+	 * Returns the canonical string representation of the actions. Always
+	 * returns present actions in the following order: {@code require},
+	 * {@code provide}.
+	 * 
+	 * @return The canonical string representation of the actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+
+			int mask = action_mask;
+			if ((mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
+				sb.append(REQUIRE);
+				comma = true;
+			}
+
+			if ((mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
+				if (comma)
+					sb.append(',');
+				sb.append(PROVIDE);
+			}
+
+			actions = result = sb.toString();
+		}
+
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object for storing
+	 * {@code CapabilityPermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object suitable for storing
+	 *         {@code CapabilityPermission} objects.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new CapabilityPermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two CapabilityPermission objects.
+	 * 
+	 * Checks that specified object has the same name and action as this
+	 * {@code CapabilityPermission}.
+	 * 
+	 * @param obj The object to test for equality.
+	 * @return true if obj is a {@code CapabilityPermission}, and has the same
+	 *         name and actions as this {@code CapabilityPermission} object;
+	 *         {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof CapabilityPermission)) {
+			return false;
+		}
+
+		CapabilityPermission cp = (CapabilityPermission) obj;
+
+		return (action_mask == cp.action_mask) && getName().equals(cp.getName()) && ((attributes == cp.attributes) || ((attributes != null) && (attributes.equals(cp.attributes))))
+				&& ((bundle == cp.bundle) || ((bundle != null) && bundle.equals(cp.bundle)));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (attributes != null) {
+			h = 31 * h + attributes.hashCode();
+		}
+		if (bundle != null) {
+			h = 31 * h + bundle.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission to a stream.
+	 * The actions are serialized, and the superclass takes care of the name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		if (bundle != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(getName(), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code <@link CapabilityPermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
+	 * 
+	 * @return a map of properties for this permission.
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		final Map<String, Object> props = new HashMap<String, Object>(5);
+		props.put("capability.namespace", getName());
+		if (bundle == null) {
+			return properties = props;
+		}
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			public Object run() {
+				props.put("id", new Long(bundle.getBundleId()));
+				props.put("location", bundle.getLocation());
+				String name = bundle.getSymbolicName();
+				if (name != null) {
+					props.put("name", name);
+				}
+				SignerProperty signer = new SignerProperty(bundle);
+				if (signer.isBundleSigned()) {
+					props.put("signer", signer);
+				}
+				return null;
+			}
+		});
+		return properties = new Properties(props, attributes);
+	}
+
+	static private final class Properties extends AbstractMap<String, Object> {
+		private final Map<String, Object>							properties;
+		private final Map<String, Object>							attributes;
+		private transient volatile Set<Map.Entry<String, Object>>	entries;
+
+		Properties(Map<String, Object> properties, Map<String, Object> attributes) {
+			this.properties = properties;
+			this.attributes = attributes;
+			entries = null;
+		}
+
+		public Object get(Object k) {
+			if (!(k instanceof String)) {
+				return null;
+			}
+			String key = (String) k;
+			if (key.charAt(0) == '@') {
+				return attributes.get(key.substring(1));
+			}
+			Object value = properties.get(key);
+			if (value != null) { // fall back to service properties
+				return value;
+			}
+			return attributes.get(key);
+		}
+
+		public Set<Map.Entry<String, Object>> entrySet() {
+			if (entries != null) {
+				return entries;
+			}
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(attributes.size() + properties.size());
+			all.addAll(attributes.entrySet());
+			all.addAll(properties.entrySet());
+			return entries = Collections.unmodifiableSet(all);
+		}
+	}
+}
+
+/**
+ * Stores a set of CapabilityPermission permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class CapabilityPermissionCollection extends PermissionCollection {
+	static final long							serialVersionUID	= -615322242639008920L;
+
+	/**
+	 * Table of permissions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, CapabilityPermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean								all_allowed;
+
+	/**
+	 * Table of permissions with filter expressions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, CapabilityPermission>	filterPermissions;
+
+	/**
+	 * Creates an empty CapabilityPermissionCollection object.
+	 */
+	public CapabilityPermissionCollection() {
+		permissions = new HashMap<String, CapabilityPermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The Permission object to add.
+	 * @throws IllegalArgumentException If the specified permission is not a
+	 *         CapabilityPermission object.
+	 * @throws SecurityException If this {@code CapabilityPermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof CapabilityPermission)) {
+			throw new IllegalArgumentException("invalid permission: " + permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+		}
+
+		final CapabilityPermission cp = (CapabilityPermission) permission;
+		if (cp.bundle != null) {
+			throw new IllegalArgumentException("cannot add to collection: " + cp);
+		}
+
+		final String name = cp.getName();
+		final Filter f = cp.filter;
+		synchronized (this) {
+			/* select the bucket for the permission */
+			Map<String, CapabilityPermission> pc;
+			if (f != null) {
+				pc = filterPermissions;
+				if (pc == null) {
+					filterPermissions = pc = new HashMap<String, CapabilityPermission>();
+				}
+			} else {
+				pc = permissions;
+			}
+			final CapabilityPermission existing = pc.get(name);
+
+			if (existing != null) {
+				final int oldMask = existing.action_mask;
+				final int newMask = cp.action_mask;
+				if (oldMask != newMask) {
+					pc.put(name, new CapabilityPermission(name, oldMask | newMask));
+				}
+			} else {
+				pc.put(name, cp);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if a set of permissions implies the permissions expressed in
+	 * {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof CapabilityPermission)) {
+			return false;
+		}
+		final CapabilityPermission requested = (CapabilityPermission) permission;
+		/* if requested permission has a filter, then it is an invalid argument */
+		if (requested.filter != null) {
+			return false;
+		}
+
+		String requestedName = requested.getName();
+		final int desired = requested.action_mask;
+		int effective = CapabilityPermission.ACTION_NONE;
+
+		Collection<CapabilityPermission> perms;
+		synchronized (this) {
+			Map<String, CapabilityPermission> pc = permissions;
+			CapabilityPermission cp;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				cp = pc.get("*");
+				if (cp != null) {
+					effective |= cp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+
+			/*
+			 * strategy: Check for full match first. Then work our way up the
+			 * name looking for matches on a.b.*
+			 */
+			cp = pc.get(requestedName);
+			if (cp != null) {
+				/* we have a direct hit! */
+				effective |= cp.action_mask;
+				if ((effective & desired) == desired) {
+					return true;
+				}
+			}
+			/* work our way up the tree... */
+			int last;
+			int offset = requestedName.length() - 1;
+			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+				requestedName = requestedName.substring(0, last + 1) + "*";
+				cp = pc.get(requestedName);
+				if (cp != null) {
+					effective |= cp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+				offset = last - 1;
+			}
+			/*
+			 * we don't have to check for "*" as it was already checked before
+			 * we were called.
+			 */
+			pc = filterPermissions;
+			if (pc == null) {
+				return false;
+			}
+			perms = pc.values();
+		}
+		/* iterate one by one over filteredPermissions */
+		for (CapabilityPermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns an enumeration of all the {@code CapabilityPermission} objects in
+	 * the container.
+	 * 
+	 * @return Enumeration of all the CapabilityPermission objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		Map<String, CapabilityPermission> pc = filterPermissions;
+		if (pc != null) {
+			all.addAll(pc.values());
+		}
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", HashMap.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
+			new ObjectStreamField("filterPermissions", HashMap.class)	};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", permissions);
+		pfields.put("all_allowed", all_allowed);
+		pfields.put("filterPermissions", filterPermissions);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		HashMap<String, CapabilityPermission> p = (HashMap<String, CapabilityPermission>) gfields.get("permissions", null);
+		permissions = p;
+		all_allowed = gfields.get("all_allowed", false);
+		HashMap<String, CapabilityPermission> fp = (HashMap<String, CapabilityPermission>) gfields.get("filterPermissions", null);
+		filterPermissions = fp;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/Configurable.java b/osgi/framework/src/org/osgi/framework/Configurable.java
new file mode 100644
index 0000000..5fa08c4
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/Configurable.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * Supports a configuration object.
+ * 
+ * <p>
+ * {@code Configurable} is an interface that should be used by a bundle
+ * developer in support of a configurable service. Bundles that need to
+ * configure a service may test to determine if the service object is an
+ * {@code instanceof Configurable}.
+ * 
+ * @deprecated As of 1.2. Please use Configuration Admin service.
+ * @version $Id: 1018601ae90d2d16ec34136db4b04dca3ccf8e65 $
+ */
+public interface Configurable {
+	/**
+	 * Returns this service's configuration object.
+	 * 
+	 * <p>
+	 * Services implementing {@code Configurable} should take care when
+	 * returning a service configuration object since this object is probably
+	 * sensitive.
+	 * <p>
+	 * If the Java Runtime Environment supports permissions, it is recommended
+	 * that the caller is checked for some appropriate permission before
+	 * returning the configuration object.
+	 * 
+	 * @return The configuration object for this service.
+	 * @throws SecurityException If the caller does not have an appropriate
+	 *         permission and the Java Runtime Environment supports permissions.
+	 * @deprecated As of 1.2. Please use Configuration Admin service.
+	 */
+	public Object getConfigurationObject();
+}
diff --git a/osgi/framework/src/org/osgi/framework/Constants.java b/osgi/framework/src/org/osgi/framework/Constants.java
new file mode 100644
index 0000000..10618a1
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/Constants.java
@@ -0,0 +1,1703 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import org.osgi.framework.hooks.bundle.CollisionHook;
+import org.osgi.framework.launch.Framework;
+
+/**
+ * Defines standard names for the OSGi environment system properties, service
+ * properties, and Manifest header attribute keys.
+ * 
+ * <p>
+ * The values associated with these keys are of type {@code String}, unless
+ * otherwise indicated.
+ * 
+ * @since 1.1
+ * @noimplement
+ * @version $Id: 6d07a4c3e29a5cd93b3daf0f9fcdab5472b357f6 $
+ */
+
+public interface Constants {
+	/**
+	 * Location identifier of the OSGi <i>system bundle </i>, which is defined
+	 * to be "System Bundle".
+	 */
+	String	SYSTEM_BUNDLE_LOCATION					= "System Bundle";
+
+	/**
+	 * Alias for the symbolic name of the OSGi <i>system bundle </i>. It is
+	 * defined to be "system.bundle".
+	 * 
+	 * @since 1.3
+	 */
+	String	SYSTEM_BUNDLE_SYMBOLICNAME				= "system.bundle";
+
+	/**
+	 * Manifest header identifying the bundle's category.
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_CATEGORY							= "Bundle-Category";
+
+	/**
+	 * Manifest header identifying a list of directories and embedded JAR files,
+	 * which are bundle resources used to extend the bundle's classpath.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_CLASSPATH						= "Bundle-ClassPath";
+
+	/**
+	 * Manifest header identifying the bundle's copyright information.
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_COPYRIGHT						= "Bundle-Copyright";
+
+	/**
+	 * Manifest header containing a brief description of the bundle's
+	 * functionality.
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_DESCRIPTION						= "Bundle-Description";
+
+	/**
+	 * Manifest header identifying the bundle's name.
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_NAME								= "Bundle-Name";
+
+	/**
+	 * Manifest header identifying a number of hardware environments and the
+	 * native language code libraries that the bundle is carrying for each of
+	 * these environments.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_NATIVECODE						= "Bundle-NativeCode";
+
+	/**
+	 * Manifest header identifying the packages that the bundle offers to the
+	 * Framework for export.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	EXPORT_PACKAGE							= "Export-Package";
+
+	/**
+	 * Manifest header identifying the fully qualified class names of the
+	 * services that the bundle may register (used for informational purposes
+	 * only).
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @deprecated As of 1.2.
+	 */
+	String	EXPORT_SERVICE							= "Export-Service";
+
+	/**
+	 * Manifest header identifying the packages on which the bundle depends.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	IMPORT_PACKAGE							= "Import-Package";
+
+	/**
+	 * Manifest header identifying the packages that the bundle may dynamically
+	 * import during execution.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.2
+	 */
+	String	DYNAMICIMPORT_PACKAGE					= "DynamicImport-Package";
+
+	/**
+	 * Manifest header identifying the fully qualified class names of the
+	 * services that the bundle requires (used for informational purposes only).
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @deprecated As of 1.2.
+	 */
+	String	IMPORT_SERVICE							= "Import-Service";
+
+	/**
+	 * Manifest header identifying the bundle's vendor.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_VENDOR							= "Bundle-Vendor";
+
+	/**
+	 * Manifest header identifying the bundle's version.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_VERSION							= "Bundle-Version";
+
+	/**
+	 * Manifest header identifying the bundle's documentation URL, from which
+	 * further information about the bundle may be obtained.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_DOCURL							= "Bundle-DocURL";
+
+	/**
+	 * Manifest header identifying the contact address where problems with the
+	 * bundle may be reported; for example, an email address.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_CONTACTADDRESS					= "Bundle-ContactAddress";
+
+	/**
+	 * Manifest header attribute identifying the bundle's activator class.
+	 * 
+	 * <p>
+	 * If present, this header specifies the name of the bundle resource class
+	 * that implements the {@code BundleActivator} interface and whose
+	 * {@code start} and {@code stop} methods are called by the Framework when
+	 * the bundle is started and stopped, respectively.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_ACTIVATOR						= "Bundle-Activator";
+
+	/**
+	 * Manifest header identifying the location from which a new bundle version
+	 * is obtained during a bundle update operation.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 */
+	String	BUNDLE_UPDATELOCATION					= "Bundle-UpdateLocation";
+
+	/**
+	 * Manifest header attribute identifying the version of a package specified
+	 * in the Export-Package or Import-Package manifest header.
+	 * 
+	 * @deprecated As of 1.3. This has been replaced by
+	 *             {@link #VERSION_ATTRIBUTE}.
+	 */
+	String	PACKAGE_SPECIFICATION_VERSION			= "specification-version";
+
+	/**
+	 * Manifest header attribute identifying the processor required to run
+	 * native bundle code specified in the Bundle-NativeCode manifest header).
+	 * 
+	 * <p>
+	 * The attribute value is encoded in the Bundle-NativeCode manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-NativeCode: http.so ; processor=x86 ...
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_NATIVECODE
+	 */
+	String	BUNDLE_NATIVECODE_PROCESSOR				= "processor";
+
+	/**
+	 * Manifest header attribute identifying the operating system required to
+	 * run native bundle code specified in the Bundle-NativeCode manifest
+	 * header).
+	 * <p>
+	 * The attribute value is encoded in the Bundle-NativeCode manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-NativeCode: http.so ; osname=Linux ...
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_NATIVECODE
+	 */
+	String	BUNDLE_NATIVECODE_OSNAME				= "osname";
+
+	/**
+	 * Manifest header attribute identifying the operating system version
+	 * required to run native bundle code specified in the Bundle-NativeCode
+	 * manifest header).
+	 * <p>
+	 * The attribute value is encoded in the Bundle-NativeCode manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-NativeCode: http.so ; osversion="2.34" ...
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_NATIVECODE
+	 */
+	String	BUNDLE_NATIVECODE_OSVERSION				= "osversion";
+
+	/**
+	 * Manifest header attribute identifying the language in which the native
+	 * bundle code is written specified in the Bundle-NativeCode manifest
+	 * header. See ISO 639 for possible values.
+	 * <p>
+	 * The attribute value is encoded in the Bundle-NativeCode manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-NativeCode: http.so ; language=nl_be ...
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_NATIVECODE
+	 */
+	String	BUNDLE_NATIVECODE_LANGUAGE				= "language";
+
+	/**
+	 * Manifest header identifying the required execution environment for the
+	 * bundle. The service platform may run this bundle if any of the execution
+	 * environments named in this header matches one of the execution
+	 * environments it implements.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.2
+	 * @deprecated As of 1.6. Replaced by the {@code osgi.ee} capability.
+	 */
+	String	BUNDLE_REQUIREDEXECUTIONENVIRONMENT		= "Bundle-RequiredExecutionEnvironment";
+
+	/**
+	 * Manifest header identifying the bundle's symbolic name.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	BUNDLE_SYMBOLICNAME						= "Bundle-SymbolicName";
+
+	/**
+	 * Manifest header directive identifying whether a bundle is a singleton.
+	 * The default value is {@code false}.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Bundle-SymbolicName manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-SymbolicName: com.acme.module.test; singleton:=true
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_SYMBOLICNAME
+	 * @since 1.3
+	 */
+	String	SINGLETON_DIRECTIVE						= "singleton";
+
+	/**
+	 * Manifest header directive identifying if and when a fragment may attach
+	 * to a host bundle. The default value is
+	 * {@link #FRAGMENT_ATTACHMENT_ALWAYS always}.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Bundle-SymbolicName manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="never"
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_SYMBOLICNAME
+	 * @see #FRAGMENT_ATTACHMENT_ALWAYS
+	 * @see #FRAGMENT_ATTACHMENT_RESOLVETIME
+	 * @see #FRAGMENT_ATTACHMENT_NEVER
+	 * @since 1.3
+	 */
+	String	FRAGMENT_ATTACHMENT_DIRECTIVE			= "fragment-attachment";
+
+	/**
+	 * Manifest header directive value identifying a fragment attachment type of
+	 * always. A fragment attachment type of always indicates that fragments are
+	 * allowed to attach to the host bundle at any time (while the host is
+	 * resolved or during the process of resolving the host bundle).
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Bundle-SymbolicName manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="always"
+	 * </pre>
+	 * 
+	 * @see #FRAGMENT_ATTACHMENT_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	FRAGMENT_ATTACHMENT_ALWAYS				= "always";
+
+	/**
+	 * Manifest header directive value identifying a fragment attachment type of
+	 * resolve-time. A fragment attachment type of resolve-time indicates that
+	 * fragments are allowed to attach to the host bundle only during the
+	 * process of resolving the host bundle.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Bundle-SymbolicName manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="resolve-time"
+	 * </pre>
+	 * 
+	 * @see #FRAGMENT_ATTACHMENT_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	FRAGMENT_ATTACHMENT_RESOLVETIME			= "resolve-time";
+
+	/**
+	 * Manifest header directive value identifying a fragment attachment type of
+	 * never. A fragment attachment type of never indicates that no fragments
+	 * are allowed to attach to the host bundle at any time.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Bundle-SymbolicName manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Bundle-SymbolicName: com.acme.module.test; fragment-attachment:="never"
+	 * </pre>
+	 * 
+	 * @see #FRAGMENT_ATTACHMENT_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	FRAGMENT_ATTACHMENT_NEVER				= "never";
+
+	/**
+	 * Manifest header identifying the base name of the bundle's localization
+	 * entries.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @see #BUNDLE_LOCALIZATION_DEFAULT_BASENAME
+	 * @since 1.3
+	 */
+	String	BUNDLE_LOCALIZATION						= "Bundle-Localization";
+
+	/**
+	 * Default value for the {@code Bundle-Localization} manifest header.
+	 * 
+	 * @see #BUNDLE_LOCALIZATION
+	 * @since 1.3
+	 */
+	String	BUNDLE_LOCALIZATION_DEFAULT_BASENAME	= "OSGI-INF/l10n/bundle";
+
+	/**
+	 * Manifest header identifying the symbolic names of other bundles required
+	 * by the bundle.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	REQUIRE_BUNDLE							= "Require-Bundle";
+
+	/**
+	 * Manifest header attribute identifying a range of versions for a bundle
+	 * specified in the {@code Require-Bundle} or {@code Fragment-Host} manifest
+	 * headers. The default value is {@code 0.0.0}.
+	 * 
+	 * <p>
+	 * The attribute value is encoded in the Require-Bundle manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Require-Bundle: com.acme.module.test; bundle-version="1.1"
+	 *     Require-Bundle: com.acme.module.test; bundle-version="[1.0,2.0)"
+	 * </pre>
+	 * 
+	 * <p>
+	 * The bundle-version attribute value uses a mathematical interval notation
+	 * to specify a range of bundle versions. A bundle-version attribute value
+	 * specified as a single version means a version range that includes any
+	 * bundle version greater than or equal to the specified version.
+	 * 
+	 * @see #REQUIRE_BUNDLE
+	 * @since 1.3
+	 */
+	String	BUNDLE_VERSION_ATTRIBUTE				= "bundle-version";
+
+	/**
+	 * Manifest header identifying the symbolic name of another bundle for which
+	 * that the bundle is a fragment.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	FRAGMENT_HOST							= "Fragment-Host";
+
+	/**
+	 * Manifest header attribute is used for selection by filtering based upon
+	 * system properties.
+	 * 
+	 * <p>
+	 * The attribute value is encoded in manifest headers like:
+	 * 
+	 * <pre>
+	 *     Bundle-NativeCode: libgtk.so; selection-filter="(ws=gtk)"; ...
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_NATIVECODE
+	 * @since 1.3
+	 */
+	String	SELECTION_FILTER_ATTRIBUTE				= "selection-filter";
+
+	/**
+	 * Manifest header identifying the bundle manifest version. A bundle
+	 * manifest may express the version of the syntax in which it is written by
+	 * specifying a bundle manifest version. Bundles exploiting OSGi Release 4,
+	 * or later, syntax must specify a bundle manifest version.
+	 * <p>
+	 * The bundle manifest version defined by OSGi Release 4 or, more
+	 * specifically, by version 1.3 of the OSGi Core Specification is "2".
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	BUNDLE_MANIFESTVERSION					= "Bundle-ManifestVersion";
+
+	/**
+	 * Manifest header attribute identifying the version of a package specified
+	 * in the Export-Package or Import-Package manifest header.
+	 * 
+	 * <p>
+	 * The attribute value is encoded in the Export-Package or Import-Package
+	 * manifest header like:
+	 * 
+	 * <pre>
+	 *     Export-Package: org.osgi.framework; version="1.1"
+	 * </pre>
+	 * 
+	 * @see #EXPORT_PACKAGE
+	 * @see #IMPORT_PACKAGE
+	 * @since 1.3
+	 */
+	String	VERSION_ATTRIBUTE						= "version";
+
+	/**
+	 * Manifest header attribute identifying the symbolic name of a bundle that
+	 * exports a package specified in the Import-Package manifest header.
+	 * 
+	 * <p>
+	 * The attribute value is encoded in the Import-Package manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Import-Package: org.osgi.framework; bundle-symbolic-name="com.acme.module.test"
+	 * </pre>
+	 * 
+	 * @see #IMPORT_PACKAGE
+	 * @since 1.3
+	 */
+	String	BUNDLE_SYMBOLICNAME_ATTRIBUTE			= "bundle-symbolic-name";
+
+	/**
+	 * Manifest header directive identifying the resolution type in the
+	 * Import-Package, Require-Bundle or Require-Capability manifest header. The
+	 * default value is {@link #RESOLUTION_MANDATORY mandatory}.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Import-Package, Require-Bundle or
+	 * Require-Capability manifest header like:
+	 * 
+	 * <pre>
+	 *     Import-Package: org.osgi.framework; resolution:="optional"
+	 *     Require-Bundle: com.acme.module.test; resolution:="optional"
+	 *     Require-Capability: com.acme.capability; resolution:="optional"
+	 * </pre>
+	 * 
+	 * @see #IMPORT_PACKAGE
+	 * @see #REQUIRE_BUNDLE
+	 * @see #REQUIRE_CAPABILITY
+	 * @see #RESOLUTION_MANDATORY
+	 * @see #RESOLUTION_OPTIONAL
+	 * @since 1.3
+	 */
+	String	RESOLUTION_DIRECTIVE					= "resolution";
+
+	/**
+	 * Manifest header directive value identifying a mandatory resolution type.
+	 * A mandatory resolution type indicates that the import package, require
+	 * bundle or require capability must be resolved when the bundle is
+	 * resolved. If such an import, require bundle or require capability cannot
+	 * be resolved, the module fails to resolve.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Import-Package, Require-Bundle or
+	 * Require-Capability manifest header like:
+	 * 
+	 * <pre>
+	 *     Import-Package: org.osgi.framework; resolution:="mandatory"
+	 *     Require-Bundle: com.acme.module.test; resolution:="mandatory"
+	 *     Require-Capability: com.acme.capability; resolution:="mandatory"
+	 * </pre>
+	 * 
+	 * @see #RESOLUTION_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	RESOLUTION_MANDATORY					= "mandatory";
+
+	/**
+	 * Manifest header directive value identifying an optional resolution type.
+	 * An optional resolution type indicates that the import, require bundle or
+	 * require capability is optional and the bundle may be resolved without the
+	 * import, require bundle or require capability being resolved. If the
+	 * import, require bundle or require capability is not resolved when the
+	 * bundle is resolved, the import, require bundle or require capability may
+	 * not be resolved until the bundle is refreshed.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Import-Package, Require-Bundle or
+	 * Require-Capability manifest header like:
+	 * 
+	 * <pre>
+	 *     Import-Package: org.osgi.framework; resolution:="optional"
+	 *     Require-Bundle: com.acme.module.test; resolution:="optional"
+	 *     Require-Capability: com.acme.capability; resolution:="optional"
+	 * </pre>
+	 * 
+	 * @see #RESOLUTION_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	RESOLUTION_OPTIONAL						= "optional";
+
+	/**
+	 * Manifest header directive identifying a list of packages that an exported
+	 * package or provided capability uses.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Export-Package or
+	 * Provide-Capability manifest header like:
+	 * 
+	 * <pre>
+	 *     Export-Package: org.osgi.util.tracker; uses:="org.osgi.framework"
+	 *     Provide-Capability: com.acme.capability; uses:="com.acme.service"
+	 * </pre>
+	 * 
+	 * @see #EXPORT_PACKAGE
+	 * @see #PROVIDE_CAPABILITY
+	 * @since 1.3
+	 */
+	String	USES_DIRECTIVE							= "uses";
+
+	/**
+	 * Manifest header directive identifying a list of classes to include in the
+	 * exported package.
+	 * 
+	 * <p>
+	 * This directive is used by the Export-Package manifest header to identify
+	 * a list of classes of the specified package which must be allowed to be
+	 * exported. The directive value is encoded in the Export-Package manifest
+	 * header like:
+	 * 
+	 * <pre>
+	 *     Export-Package: org.osgi.framework; include:="MyClass*"
+	 * </pre>
+	 * 
+	 * <p>
+	 * This directive is also used by the Bundle-ActivationPolicy manifest
+	 * header to identify the packages from which class loads will trigger lazy
+	 * activation. The directive value is encoded in the Bundle-ActivationPolicy
+	 * manifest header like:
+	 * 
+	 * <pre>
+	 *     Bundle-ActivationPolicy: lazy; include:="org.osgi.framework"
+	 * </pre>
+	 * 
+	 * @see #EXPORT_PACKAGE
+	 * @see #BUNDLE_ACTIVATIONPOLICY
+	 * @since 1.3
+	 */
+	String	INCLUDE_DIRECTIVE						= "include";
+
+	/**
+	 * Manifest header directive identifying a list of classes to exclude in the
+	 * exported package..
+	 * <p>
+	 * This directive is used by the Export-Package manifest header to identify
+	 * a list of classes of the specified package which must not be allowed to
+	 * be exported. The directive value is encoded in the Export-Package
+	 * manifest header like:
+	 * 
+	 * <pre>
+	 *     Export-Package: org.osgi.framework; exclude:="*Impl"
+	 * </pre>
+	 * 
+	 * <p>
+	 * This directive is also used by the Bundle-ActivationPolicy manifest
+	 * header to identify the packages from which class loads will not trigger
+	 * lazy activation. The directive value is encoded in the
+	 * Bundle-ActivationPolicy manifest header like:
+	 * 
+	 * <pre>
+	 *     Bundle-ActivationPolicy: lazy; exclude:="org.osgi.framework"
+	 * </pre>
+	 * 
+	 * @see #EXPORT_PACKAGE
+	 * @see #BUNDLE_ACTIVATIONPOLICY
+	 * @since 1.3
+	 */
+	String	EXCLUDE_DIRECTIVE						= "exclude";
+
+	/**
+	 * Manifest header directive identifying names of matching attributes which
+	 * must be specified by matching Import-Package statements in the
+	 * Export-Package manifest header.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Export-Package manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Export-Package: org.osgi.framework; mandatory:="bundle-symbolic-name"
+	 * </pre>
+	 * 
+	 * @see #EXPORT_PACKAGE
+	 * @since 1.3
+	 */
+	String	MANDATORY_DIRECTIVE						= "mandatory";
+
+	/**
+	 * Manifest header directive identifying the visibility of a required bundle
+	 * in the Require-Bundle manifest header. The default value is
+	 * {@link #VISIBILITY_PRIVATE private}.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Require-Bundle manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Require-Bundle: com.acme.module.test; visibility:="reexport"
+	 * </pre>
+	 * 
+	 * @see #REQUIRE_BUNDLE
+	 * @see #VISIBILITY_PRIVATE
+	 * @see #VISIBILITY_REEXPORT
+	 * @since 1.3
+	 */
+	String	VISIBILITY_DIRECTIVE					= "visibility";
+
+	/**
+	 * Manifest header directive value identifying a private visibility type. A
+	 * private visibility type indicates that any packages that are exported by
+	 * the required bundle are not made visible on the export signature of the
+	 * requiring bundle.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Require-Bundle manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Require-Bundle: com.acme.module.test; visibility:="private"
+	 * </pre>
+	 * 
+	 * @see #VISIBILITY_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	VISIBILITY_PRIVATE						= "private";
+
+	/**
+	 * Manifest header directive value identifying a reexport visibility type. A
+	 * reexport visibility type indicates any packages that are exported by the
+	 * required bundle are re-exported by the requiring bundle. Any arbitrary
+	 * arbitrary matching attributes with which they were exported by the
+	 * required bundle are deleted.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Require-Bundle manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Require-Bundle: com.acme.module.test; visibility:="reexport"
+	 * </pre>
+	 * 
+	 * @see #VISIBILITY_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	VISIBILITY_REEXPORT						= "reexport";
+
+	/**
+	 * Manifest header directive identifying the type of the extension fragment.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Fragment-Host manifest header like:
+	 * 
+	 * <pre>
+	 *     Fragment-Host: system.bundle; extension:="framework"
+	 * </pre>
+	 * 
+	 * @see #FRAGMENT_HOST
+	 * @see #EXTENSION_FRAMEWORK
+	 * @see #EXTENSION_BOOTCLASSPATH
+	 * @since 1.3
+	 */
+	String	EXTENSION_DIRECTIVE						= "extension";
+
+	/**
+	 * Manifest header directive value identifying the type of extension
+	 * fragment. An extension fragment type of framework indicates that the
+	 * extension fragment is to be loaded by the framework's class loader.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Fragment-Host manifest header like:
+	 * 
+	 * <pre>
+	 *     Fragment-Host: system.bundle; extension:="framework"
+	 * </pre>
+	 * 
+	 * @see #EXTENSION_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	EXTENSION_FRAMEWORK						= "framework";
+
+	/**
+	 * Manifest header directive value identifying the type of extension
+	 * fragment. An extension fragment type of bootclasspath indicates that the
+	 * extension fragment is to be loaded by the boot class loader.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Fragment-Host manifest header like:
+	 * 
+	 * <pre>
+	 *     Fragment-Host: system.bundle; extension:="bootclasspath"
+	 * </pre>
+	 * 
+	 * @see #EXTENSION_DIRECTIVE
+	 * @since 1.3
+	 */
+	String	EXTENSION_BOOTCLASSPATH					= "bootclasspath";
+
+	/**
+	 * Manifest header identifying the bundle's activation policy.
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.4
+	 * @see #ACTIVATION_LAZY
+	 * @see #INCLUDE_DIRECTIVE
+	 * @see #EXCLUDE_DIRECTIVE
+	 */
+	String	BUNDLE_ACTIVATIONPOLICY					= "Bundle-ActivationPolicy";
+
+	/**
+	 * Bundle activation policy declaring the bundle must be activated when the
+	 * first class load is made from the bundle.
+	 * <p>
+	 * A bundle with the lazy activation policy that is started with the
+	 * {@link Bundle#START_ACTIVATION_POLICY START_ACTIVATION_POLICY} option
+	 * will wait in the {@link Bundle#STARTING STARTING} state until the first
+	 * class load from the bundle occurs. The bundle will then be activated
+	 * before the class is returned to the requester.
+	 * <p>
+	 * The activation policy value is specified as in the
+	 * Bundle-ActivationPolicy manifest header like:
+	 * 
+	 * <pre>
+	 *       Bundle-ActivationPolicy: lazy
+	 * </pre>
+	 * 
+	 * @see #BUNDLE_ACTIVATIONPOLICY
+	 * @see Bundle#start(int)
+	 * @see Bundle#START_ACTIVATION_POLICY
+	 * @since 1.4
+	 */
+	String	ACTIVATION_LAZY							= "lazy";
+
+	/**
+	 * Framework environment property identifying the Framework version.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 */
+	String	FRAMEWORK_VERSION						= "org.osgi.framework.version";
+
+	/**
+	 * Framework environment property identifying the Framework implementation
+	 * vendor.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 */
+	String	FRAMEWORK_VENDOR						= "org.osgi.framework.vendor";
+
+	/**
+	 * Framework launching property identifying the Framework implementation
+	 * language (see ISO 639 for possible values).
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 */
+	String	FRAMEWORK_LANGUAGE						= "org.osgi.framework.language";
+
+	/**
+	 * Framework launching property identifying the Framework host-computer's
+	 * operating system.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 */
+	String	FRAMEWORK_OS_NAME						= "org.osgi.framework.os.name";
+
+	/**
+	 * Framework launching property identifying the Framework host-computer's
+	 * operating system version number.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 */
+	String	FRAMEWORK_OS_VERSION					= "org.osgi.framework.os.version";
+
+	/**
+	 * Framework launching property identifying the Framework host-computer's
+	 * processor name.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 */
+	String	FRAMEWORK_PROCESSOR						= "org.osgi.framework.processor";
+
+	/**
+	 * Framework launching property identifying execution environments provided
+	 * by the Framework.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.2
+	 * @deprecated As of 1.6. Replaced by the {@code osgi.ee} capability.
+	 */
+	String	FRAMEWORK_EXECUTIONENVIRONMENT			= "org.osgi.framework.executionenvironment";
+
+	/**
+	 * Framework launching property identifying packages for which the Framework
+	 * must delegate class loading to the parent class loader of the bundle.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @see #FRAMEWORK_BUNDLE_PARENT
+	 * @since 1.3
+	 */
+	String	FRAMEWORK_BOOTDELEGATION				= "org.osgi.framework.bootdelegation";
+
+	/**
+	 * Framework launching property identifying packages which the system bundle
+	 * must export.
+	 * 
+	 * <p>
+	 * If this property is not specified then the framework must calculate a
+	 * reasonable default value for the current execution environment.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	FRAMEWORK_SYSTEMPACKAGES				= "org.osgi.framework.system.packages";
+
+	/**
+	 * Framework launching property identifying extra packages which the system
+	 * bundle must export from the current execution environment.
+	 * 
+	 * <p>
+	 * This property is useful for configuring extra system packages in addition
+	 * to the system packages calculated by the framework.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @see #FRAMEWORK_SYSTEMPACKAGES
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_SYSTEMPACKAGES_EXTRA			= "org.osgi.framework.system.packages.extra";
+
+	/**
+	 * Framework environment property identifying whether the Framework supports
+	 * framework extension bundles.
+	 * 
+	 * <p>
+	 * As of version 1.4, the value of this property must be {@code true}. The
+	 * Framework must support framework extension bundles.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	SUPPORTS_FRAMEWORK_EXTENSION			= "org.osgi.supports.framework.extension";
+
+	/**
+	 * Framework environment property identifying whether the Framework supports
+	 * bootclasspath extension bundles.
+	 * 
+	 * <p>
+	 * If the value of this property is {@code true}, then the Framework
+	 * supports bootclasspath extension bundles. The default value is
+	 * {@code false}.
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	SUPPORTS_BOOTCLASSPATH_EXTENSION		= "org.osgi.supports.bootclasspath.extension";
+
+	/**
+	 * Framework environment property identifying whether the Framework supports
+	 * fragment bundles.
+	 * 
+	 * <p>
+	 * As of version 1.4, the value of this property must be {@code true}. The
+	 * Framework must support fragment bundles.
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	SUPPORTS_FRAMEWORK_FRAGMENT				= "org.osgi.supports.framework.fragment";
+
+	/**
+	 * Framework environment property identifying whether the Framework supports
+	 * the {@link #REQUIRE_BUNDLE Require-Bundle} manifest header.
+	 * 
+	 * <p>
+	 * As of version 1.4, the value of this property must be {@code true}. The
+	 * Framework must support the {@code Require-Bundle} manifest header.
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.3
+	 */
+	String	SUPPORTS_FRAMEWORK_REQUIREBUNDLE		= "org.osgi.supports.framework.requirebundle";
+
+	/**
+	 * Framework launching property specifying the type of security manager the
+	 * framework must use. If not specified then the framework will not set the
+	 * VM security manager.
+	 * 
+	 * @see #FRAMEWORK_SECURITY_OSGI
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_SECURITY						= "org.osgi.framework.security";
+
+	/**
+	 * Specifies that a security manager that supports all security aspects of
+	 * the OSGi core specification including postponed conditions must be
+	 * installed.
+	 * 
+	 * <p>
+	 * If this value is specified and there is a security manager already
+	 * installed, then a {@code SecurityException} must be thrown when the
+	 * Framework is initialized.
+	 * 
+	 * @see #FRAMEWORK_SECURITY
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_SECURITY_OSGI					= "osgi";
+
+	/**
+	 * Framework launching property specifying the persistent storage area used
+	 * by the framework. The value of this property must be a valid file path in
+	 * the file system to a directory. If the specified directory does not exist
+	 * then the framework will create the directory. If the specified path
+	 * exists but is not a directory or if the framework fails to create the
+	 * storage directory, then framework initialization must fail. The framework
+	 * is free to use this directory as it sees fit. This area can not be shared
+	 * with anything else.
+	 * <p>
+	 * If this property is not set, the framework should use a reasonable
+	 * platform default for the persistent storage area.
+	 * 
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_STORAGE						= "org.osgi.framework.storage";
+
+	/**
+	 * Framework launching property specifying if and when the persistent
+	 * storage area for the framework should be cleaned. If this property is not
+	 * set, then the framework storage area must not be cleaned.
+	 * 
+	 * @see #FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_STORAGE_CLEAN					= "org.osgi.framework.storage.clean";
+
+	/**
+	 * Specifies that the framework storage area must be cleaned before the
+	 * framework is initialized for the first time. Subsequent inits, starts or
+	 * updates of the framework will not result in cleaning the framework
+	 * storage area.
+	 * 
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT		= "onFirstInit";
+
+	/**
+	 * Framework launching property specifying a comma separated list of
+	 * additional library file extensions that must be used when a bundle's
+	 * class loader is searching for native libraries. If this property is not
+	 * set, then only the library name returned by
+	 * {@code System.mapLibraryName(String)} will be used to search. This is
+	 * needed for certain operating systems which allow more than one extension
+	 * for a library. For example, AIX allows library extensions of {@code .a}
+	 * and {@code .so}, but {@code System.mapLibraryName(String)} will only
+	 * return names with the {@code .a} extension.
+	 * 
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_LIBRARY_EXTENSIONS			= "org.osgi.framework.library.extensions";
+
+	/**
+	 * Framework launching property specifying an optional OS specific command
+	 * to set file permissions on extracted native code. On some operating
+	 * systems, it is required that native libraries be set to executable. This
+	 * optional property allows you to specify the command. For example, on a
+	 * UNIX style OS, this property could have the following value.
+	 * 
+	 * <pre>
+	 * chmod +rx ${abspath}
+	 * </pre>
+	 * 
+	 * The <code>${abspath}</code> is used by the framework to substitute the
+	 * actual absolute file path.
+	 * 
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_EXECPERMISSION				= "org.osgi.framework.command.execpermission";
+
+	/**
+	 * Specified the substitution string for the absolute path of a file.
+	 * 
+	 * @see #FRAMEWORK_EXECPERMISSION
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_COMMAND_ABSPATH				= "abspath";
+
+	/**
+	 * Framework launching property specifying the trust repositories used by
+	 * the framework. The value is a {@code java.io.File.pathSeparator}
+	 * separated list of valid file paths to files that contain key stores. Key
+	 * stores of type {@code JKS} must be supported and other key store types
+	 * may be supported. The framework will use the key stores as trust
+	 * repositories to authenticate certificates of trusted signers. The key
+	 * stores are only used as read-only trust repositories to access public
+	 * keys. No passwords are required to access the key stores' public keys.
+	 * <p>
+	 * Note that framework implementations are allowed to use other trust
+	 * repositories in addition to the trust repositories specified by this
+	 * property. How these other trust repositories are configured and populated
+	 * is implementation specific.
+	 * 
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_TRUST_REPOSITORIES			= "org.osgi.framework.trust.repositories";
+
+	/**
+	 * Framework launching property specifying the current windowing system. The
+	 * framework should provide a reasonable default if this is not set.
+	 * 
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_WINDOWSYSTEM					= "org.osgi.framework.windowsystem";
+
+	/**
+	 * Framework launching property specifying the beginning start level of the
+	 * framework.
+	 * 
+	 * @see "Core Specification, Starting the Framework."
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_BEGINNING_STARTLEVEL			= "org.osgi.framework.startlevel.beginning";
+
+	/**
+	 * Framework launching property specifying the parent class loader type for
+	 * all bundle class loaders. Default value is
+	 * {@link #FRAMEWORK_BUNDLE_PARENT_BOOT boot}.
+	 * 
+	 * @see #FRAMEWORK_BUNDLE_PARENT_BOOT
+	 * @see #FRAMEWORK_BUNDLE_PARENT_EXT
+	 * @see #FRAMEWORK_BUNDLE_PARENT_APP
+	 * @see #FRAMEWORK_BUNDLE_PARENT_FRAMEWORK
+	 * @since 1.5
+	 */
+	String	FRAMEWORK_BUNDLE_PARENT					= "org.osgi.framework.bundle.parent";
+
+	/**
+	 * Specifies to use of the boot class loader as the parent class loader for
+	 * all bundle class loaders.
+	 * 
+	 * @since 1.5
+	 * @see #FRAMEWORK_BUNDLE_PARENT
+	 */
+	String	FRAMEWORK_BUNDLE_PARENT_BOOT			= "boot";
+
+	/**
+	 * Specifies to use the extension class loader as the parent class loader
+	 * for all bundle class loaders.
+	 * 
+	 * @since 1.5
+	 * @see #FRAMEWORK_BUNDLE_PARENT
+	 */
+	String	FRAMEWORK_BUNDLE_PARENT_EXT				= "ext";
+
+	/**
+	 * Specifies to use the application class loader as the parent class loader
+	 * for all bundle class loaders. Depending on how the framework is launched,
+	 * this may refer to the same class loader as
+	 * {@link #FRAMEWORK_BUNDLE_PARENT_FRAMEWORK}.
+	 * 
+	 * @since 1.5
+	 * @see #FRAMEWORK_BUNDLE_PARENT
+	 */
+	String	FRAMEWORK_BUNDLE_PARENT_APP				= "app";
+
+	/**
+	 * Specifies to use the framework class loader as the parent class loader
+	 * for all bundle class loaders. The framework class loader is the class
+	 * loader used to load the framework implementation. Depending on how the
+	 * framework is launched, this may refer to the same class loader as
+	 * {@link #FRAMEWORK_BUNDLE_PARENT_APP}.
+	 * 
+	 * @since 1.5
+	 * @see #FRAMEWORK_BUNDLE_PARENT
+	 */
+	String	FRAMEWORK_BUNDLE_PARENT_FRAMEWORK		= "framework";
+
+	/*
+	 * Service properties.
+	 */
+
+	/**
+	 * Service property identifying all of the class names under which a service
+	 * was registered in the Framework. The value of this property must be of
+	 * type {@code String[]}.
+	 * 
+	 * <p>
+	 * This property is set by the Framework when a service is registered.
+	 */
+	String	OBJECTCLASS								= "objectClass";
+
+	/**
+	 * Service property identifying a service's registration number. The value
+	 * of this property must be of type {@code Long}.
+	 * 
+	 * <p>
+	 * The value of this property is assigned by the Framework when a service is
+	 * registered. The Framework assigns a unique value that is larger than all
+	 * previously assigned values since the Framework was started. These values
+	 * are NOT persistent across restarts of the Framework.
+	 */
+	String	SERVICE_ID								= "service.id";
+
+	/**
+	 * Service property identifying a service's persistent identifier.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * <p>
+	 * A service's persistent identifier uniquely identifies the service and
+	 * persists across multiple Framework invocations.
+	 * 
+	 * <p>
+	 * By convention, every bundle has its own unique namespace, starting with
+	 * the bundle's identifier (see {@link Bundle#getBundleId()}) and followed
+	 * by a dot (.). A bundle may use this as the prefix of the persistent
+	 * identifiers for the services it registers.
+	 */
+	String	SERVICE_PID								= "service.pid";
+
+	/**
+	 * Service property identifying a service's ranking number.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties
+	 * Dictionary} object passed to the {@code BundleContext.registerService}
+	 * method. The value of this property must be of type {@code Integer}.
+	 * 
+	 * <p>
+	 * The service ranking is used by the Framework to determine the <i>natural
+	 * order</i> of services, see {@link ServiceReference#compareTo(Object)},
+	 * and the <i>default</i> service to be returned from a call to the
+	 * {@link BundleContext#getServiceReference(Class)} or
+	 * {@link BundleContext#getServiceReference(String)} method.
+	 * 
+	 * <p>
+	 * The default ranking is zero (0). A service with a ranking of
+	 * {@code Integer.MAX_VALUE} is very likely to be returned as the default
+	 * service, whereas a service with a ranking of {@code Integer.MIN_VALUE} is
+	 * very unlikely to be returned.
+	 * 
+	 * <p>
+	 * If the supplied property value is not of type {@code Integer}, it is
+	 * deemed to have a ranking value of zero.
+	 */
+	String	SERVICE_RANKING							= "service.ranking";
+
+	/**
+	 * Service property identifying a service's vendor.
+	 * 
+	 * <p>
+	 * This property may be supplied in the properties {@code Dictionary} object
+	 * passed to the {@code BundleContext.registerService} method.
+	 */
+	String	SERVICE_VENDOR							= "service.vendor";
+
+	/**
+	 * Service property identifying a service's description.
+	 * 
+	 * <p>
+	 * This property may be supplied in the properties {@code Dictionary} object
+	 * passed to the {@code BundleContext.registerService} method.
+	 */
+	String	SERVICE_DESCRIPTION						= "service.description";
+
+	/**
+	 * Framework environment property identifying the Framework's universally
+	 * unique identifier (UUID). A UUID represents a 128-bit value. A new UUID
+	 * is generated by the {@link Framework#init()} method each time a framework
+	 * is initialized. The value of this property must conform to the UUID
+	 * string representation specified in <a
+	 * href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_UUID							= "org.osgi.framework.uuid";
+
+	/**
+	 * Service property identifying the configuration types supported by a
+	 * distribution provider. Registered by the distribution provider on one of
+	 * its services to indicate the supported configuration types.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	REMOTE_CONFIGS_SUPPORTED				= "remote.configs.supported";
+
+	/**
+	 * Service property identifying the intents supported by a distribution
+	 * provider. Registered by the distribution provider on one of its services
+	 * to indicate the vocabulary of implemented intents.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	REMOTE_INTENTS_SUPPORTED				= "remote.intents.supported";
+
+	/**
+	 * Service property identifying the configuration types that should be used
+	 * to export the service. Each configuration type represents the
+	 * configuration parameters for an endpoint. A distribution provider should
+	 * create an endpoint for each configuration type that it supports.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_CONFIGS				= "service.exported.configs";
+
+	/**
+	 * Service property identifying the intents that the distribution provider
+	 * must implement to distribute the service. Intents listed in this property
+	 * are reserved for intents that are critical for the code to function
+	 * correctly, for example, ordering of messages. These intents should not be
+	 * configurable.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_INTENTS				= "service.exported.intents";
+
+	/**
+	 * Service property identifying the extra intents that the distribution
+	 * provider must implement to distribute the service. This property is
+	 * merged with the {@code service.exported.intents} property before the
+	 * distribution provider interprets the listed intents; it has therefore the
+	 * same semantics but the property should be configurable so the
+	 * administrator can choose the intents based on the topology. Bundles
+	 * should therefore make this property configurable, for example through the
+	 * Configuration Admin service.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_INTENTS_EXTRA			= "service.exported.intents.extra";
+
+	/**
+	 * Service property marking the service for export. It defines the
+	 * interfaces under which this service can be exported. This list must be a
+	 * subset of the types under which the service was registered. The single
+	 * value of an asterisk ({@code '*'} \u002A) indicates all the interface
+	 * types under which the service was registered excluding the non-interface
+	 * types. It is strongly recommended to only export interface types and not
+	 * concrete classes due to the complexity of creating proxies for some type
+	 * of concrete classes.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_INTERFACES				= "service.exported.interfaces";
+
+	/**
+	 * Service property identifying the service as imported. This service
+	 * property must be set by a distribution provider to any value when it
+	 * registers the endpoint proxy as an imported service. A bundle can use
+	 * this property to filter out imported services.
+	 * 
+	 * <p>
+	 * The value of this property may be of any type.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_IMPORTED						= "service.imported";
+
+	/**
+	 * Service property identifying the configuration types used to import the
+	 * service. Any associated properties for this configuration types must be
+	 * properly mapped to the importing system. For example, a URL in these
+	 * properties must point to a valid resource when used in the importing
+	 * framework. If multiple configuration types are listed in this property,
+	 * then they must be synonyms for exactly the same remote endpoint that is
+	 * used to export this service.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 * @see #SERVICE_EXPORTED_CONFIGS
+	 */
+	String	SERVICE_IMPORTED_CONFIGS				= "service.imported.configs";
+
+	/**
+	 * Service property identifying the intents that this service implement.
+	 * This property has a dual purpose:
+	 * <ul>
+	 * <li>A bundle can use this service property to notify the distribution
+	 * provider that these intents are already implemented by the exported
+	 * service object.</li>
+	 * <li>A distribution provider must use this property to convey the combined
+	 * intents of: the exporting service, the intents that the exporting
+	 * distribution provider adds, and the intents that the importing
+	 * distribution provider adds.</li>
+	 * </ul>
+	 * 
+	 * To export a service, a distribution provider must expand any qualified
+	 * intents. Both the exporting and importing distribution providers must
+	 * recognize all intents before a service can be distributed.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_INTENTS							= "service.intents";
+
+	/**
+	 * Manifest header identifying the capabilities that the bundle offers to
+	 * provide to other bundles.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	PROVIDE_CAPABILITY						= "Provide-Capability";
+
+	/**
+	 * Manifest header identifying the capabilities on which the bundle depends.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	REQUIRE_CAPABILITY						= "Require-Capability";
+
+	/**
+	 * Manifest header directive identifying the effective time of the provided
+	 * capability. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Provide-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Provide-Capability: com.acme.capability; effective:="resolve"
+	 * </pre>
+	 * 
+	 * @see #PROVIDE_CAPABILITY
+	 * @see #EFFECTIVE_RESOLVE
+	 * @see #EFFECTIVE_ACTIVE
+	 * @since 1.6
+	 */
+	String	EFFECTIVE_DIRECTIVE						= "effective";
+
+	/**
+	 * Manifest header directive value identifying a capability that is
+	 * effective at resolve time. Capabilities with an effective time of resolve
+	 * are the only capabilities which are processed by the resolver.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Provide-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Provide-Capability: com.acme.capability; effective:="resolve"
+	 * </pre>
+	 * 
+	 * @see #EFFECTIVE_DIRECTIVE
+	 * @since 1.6
+	 */
+	String	EFFECTIVE_RESOLVE						= "resolve";
+
+	/**
+	 * Manifest header directive value identifying a capability that is
+	 * effective at active time. Capabilities with an effective time of active
+	 * are ignored by the resolver.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Provide-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Provide-Capability: com.acme.capability; effective:="active"
+	 * </pre>
+	 * 
+	 * @see #EFFECTIVE_DIRECTIVE
+	 * @since 1.6
+	 */
+	String	EFFECTIVE_ACTIVE						= "active";
+
+	/**
+	 * Manifest header directive identifying the capability filter specified in
+	 * the Require-Capability manifest header.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Require-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Require-Capability: com.acme.capability; filter:="(someattr=somevalue)"
+	 * </pre>
+	 * 
+	 * @see #REQUIRE_CAPABILITY
+	 * @since 1.6
+	 */
+	String	FILTER_DIRECTIVE						= "filter";
+
+	/**
+	 * Framework launching property identifying capabilities which the system
+	 * bundle must provide.
+	 * 
+	 * <p>
+	 * If this property is not specified then the framework must calculate a
+	 * reasonable default value for the current execution environment.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_SYSTEMCAPABILITIES			= "org.osgi.framework.system.capabilities";
+
+	/**
+	 * Framework launching property identifying extra capabilities which the
+	 * system bundle must additionally provide.
+	 * 
+	 * <p>
+	 * This property is useful for configuring extra system capabilities in
+	 * addition to the system capabilities calculated by the framework.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @see #FRAMEWORK_SYSTEMCAPABILITIES
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_SYSTEMCAPABILITIES_EXTRA		= "org.osgi.framework.system.capabilities.extra";
+
+	/**
+	 * Framework launching property specifying whether multiple bundles having
+	 * the same {@link #BUNDLE_SYMBOLICNAME symbolic name} and
+	 * {@link #BUNDLE_VERSION version} may be installed.
+	 * 
+	 * <p>
+	 * Default value is {@link #FRAMEWORK_BSNVERSION_MANAGED managed} in this
+	 * release of the specification. This default may change in a future
+	 * specification release. Therefore, code must not assume the default
+	 * behavior is {@code managed} and should interrogate the value of this
+	 * property to determine the behavior.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @see #FRAMEWORK_BSNVERSION_MULTIPLE
+	 * @see #FRAMEWORK_BSNVERSION_SINGLE
+	 * @see #FRAMEWORK_BSNVERSION_MANAGED
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_BSNVERSION					= "org.osgi.framework.bsnversion";
+
+	/**
+	 * Specifies the framework will allow multiple bundles to be installed
+	 * having the same symbolic name and version.
+	 * 
+	 * @since 1.6
+	 * @see #FRAMEWORK_BSNVERSION
+	 */
+	String	FRAMEWORK_BSNVERSION_MULTIPLE			= "multiple";
+
+	/**
+	 * Specifies the framework will only allow a single bundle to be installed
+	 * for a given symbolic name and version. It will be an error to install a
+	 * bundle or update a bundle to have the same symbolic name and version as
+	 * another installed bundle.
+	 * 
+	 * @since 1.6
+	 * @see #FRAMEWORK_BSNVERSION
+	 * @see BundleException#DUPLICATE_BUNDLE_ERROR
+	 */
+	String	FRAMEWORK_BSNVERSION_SINGLE				= "single";
+
+	/**
+	 * Specifies the framework must consult the {@link CollisionHook bundle
+	 * collision hook} services to determine if it will be an error to install a
+	 * bundle or update a bundle to have the same symbolic name and version as
+	 * another installed bundle. If no bundle collision hook services are
+	 * registered, then it will be an error to install a bundle or update a
+	 * bundle to have the same symbolic name and version as another installed
+	 * bundle.
+	 * 
+	 * @since 1.7
+	 * @see #FRAMEWORK_BSNVERSION
+	 * @see BundleException#DUPLICATE_BUNDLE_ERROR
+	 */
+	String	FRAMEWORK_BSNVERSION_MANAGED			= "managed";
+}
diff --git a/osgi/framework/src/org/osgi/framework/Filter.java b/osgi/framework/src/org/osgi/framework/Filter.java
new file mode 100644
index 0000000..230a6e9
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/Filter.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.Dictionary;
+import java.util.Map;
+
+/**
+ * An <a href="http://www.ietf.org/rfc/rfc1960.txt">RFC 1960</a>-based Filter.
+ * <p>
+ * {@code Filter}s can be created by calling
+ * {@link BundleContext#createFilter(String)} or
+ * {@link FrameworkUtil#createFilter(String)} with a filter string.
+ * <p>
+ * A {@code Filter} can be used numerous times to determine if the match
+ * argument matches the filter string that was used to create the {@code Filter}.
+ * <p>
+ * Some examples of LDAP filters are:
+ * 
+ * <pre>
+ *  "(cn=Babs Jensen)"
+ *  "(!(cn=Tim Howes))"
+ *  "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
+ *  "(o=univ*of*mich*)"
+ * </pre>
+ * 
+ * @since 1.1
+ * @see "Core Specification, Filters, for a description of the filter string syntax."
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 807a04ac07c3230b8f4d4e0f9588a35fbdc41e18 $
+ */
+public interface Filter {
+	/**
+	 * Filter using a service's properties.
+	 * <p>
+	 * This {@code Filter} is executed using the keys and values of the
+	 * referenced service's properties. The keys are looked up in a case
+	 * insensitive manner.
+	 * 
+	 * @param reference The reference to the service whose properties are used
+	 *        in the match.
+	 * @return {@code true} if the service's properties match this
+	 *         {@code Filter}; {@code false} otherwise.
+	 */
+	boolean match(ServiceReference<?> reference);
+
+	/**
+	 * Filter using a {@code Dictionary} with case insensitive key lookup. This
+	 * {@code Filter} is executed using the specified {@code Dictionary}'s keys
+	 * and values. The keys are looked up in a case insensitive manner.
+	 * 
+	 * @param dictionary The {@code Dictionary} whose key/value pairs are used
+	 *        in the match.
+	 * @return {@code true} if the {@code Dictionary}'s values match this
+	 *         filter; {@code false} otherwise.
+	 * @throws IllegalArgumentException If {@code dictionary} contains case
+	 *         variants of the same key name.
+	 */
+	boolean match(Dictionary<String, ?> dictionary);
+
+	/**
+	 * Returns this {@code Filter}'s filter string.
+	 * <p>
+	 * The filter string is normalized by removing whitespace which does not
+	 * affect the meaning of the filter.
+	 * 
+	 * @return This {@code Filter}'s filter string.
+	 */
+	String toString();
+
+	/**
+	 * Compares this {@code Filter} to another {@code Filter}.
+	 * 
+	 * <p>
+	 * This implementation returns the result of calling
+	 * {@code this.toString().equals(obj.toString())}.
+	 * 
+	 * @param obj The object to compare against this {@code Filter}.
+	 * @return If the other object is a {@code Filter} object, then returns the
+	 *         result of calling {@code this.toString().equals(obj.toString())};
+	 *         {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode for this {@code Filter}.
+	 * 
+	 * <p>
+	 * This implementation returns the result of calling
+	 * {@code this.toString().hashCode()}.
+	 * 
+	 * @return The hashCode of this {@code Filter}.
+	 */
+	int hashCode();
+
+	/**
+	 * Filter using a {@code Dictionary}. This {@code Filter} is executed using
+	 * the specified {@code Dictionary}'s keys and values. The keys are looked
+	 * up in a normal manner respecting case.
+	 * 
+	 * @param dictionary The {@code Dictionary} whose key/value pairs are used
+	 *        in the match.
+	 * @return {@code true} if the {@code Dictionary}'s values match this
+	 *         filter; {@code false} otherwise.
+	 * @since 1.3
+	 */
+	boolean matchCase(Dictionary<String, ?> dictionary);
+
+	/**
+	 * Filter using a {@code Map}. This {@code Filter} is executed using the
+	 * specified {@code Map}'s keys and values. The keys are looked up in a
+	 * normal manner respecting case.
+	 * 
+	 * @param map The {@code Map} whose key/value pairs are used in the match.
+	 *        Maps with {@code null} key or values are not supported. A
+	 *        {@code null} value is considered not present to the filter.
+	 * @return {@code true} if the {@code Map}'s values match this filter;
+	 *         {@code false} otherwise.
+	 * @since 1.6
+	 */
+	boolean matches(Map<String, ?> map);
+}
diff --git a/osgi/framework/src/org/osgi/framework/FrameworkEvent.java b/osgi/framework/src/org/osgi/framework/FrameworkEvent.java
new file mode 100644
index 0000000..59fa92e
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/FrameworkEvent.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.EventObject;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/**
+ * A general event from the Framework.
+ * 
+ * <p>
+ * {@code FrameworkEvent} objects are delivered to {@code FrameworkListener}s
+ * when a general event occurs within the OSGi environment. A type code is used
+ * to identify the event type for future extendability.
+ * 
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of event types.
+ * 
+ * @Immutable
+ * @see FrameworkListener
+ * @version $Id: f679c7581879a2e6006ecdd317a5dd5f735764e3 $
+ */
+
+public class FrameworkEvent extends EventObject {
+	static final long		serialVersionUID				= 207051004521261705L;
+	/**
+	 * Bundle related to the event.
+	 */
+	private final Bundle	bundle;
+
+	/**
+	 * Exception related to the event.
+	 */
+	private final Throwable	throwable;
+
+	/**
+	 * Type of event.
+	 */
+	private final int		type;
+
+	/**
+	 * The Framework has started.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework has started after all installed
+	 * bundles that are marked to be started have been started and the Framework
+	 * has reached the initial start level. The source of this event is the
+	 * System Bundle.
+	 * 
+	 * @see "The Start Level Specification"
+	 */
+	public final static int	STARTED							= 0x00000001;
+
+	/**
+	 * An error has occurred.
+	 * 
+	 * <p>
+	 * There was an error associated with a bundle.
+	 */
+	public final static int	ERROR							= 0x00000002;
+
+	/**
+	 * A FrameworkWiring.refreshBundles operation has completed.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework has completed the refresh bundles
+	 * operation initiated by a call to the FrameworkWiring.refreshBundles
+	 * method. The source of this event is the System Bundle.
+	 * 
+	 * @since 1.2
+	 * @see FrameworkWiring#refreshBundles(java.util.Collection,
+	 *      FrameworkListener...)
+	 */
+	public final static int	PACKAGES_REFRESHED				= 0x00000004;
+
+	/**
+	 * A FrameworkStartLevel.setStartLevel operation has completed.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework has completed changing the active
+	 * start level initiated by a call to the StartLevel.setStartLevel method.
+	 * The source of this event is the System Bundle.
+	 * 
+	 * @since 1.2
+	 * @see FrameworkStartLevel#setStartLevel(int, FrameworkListener...)
+	 */
+	public final static int	STARTLEVEL_CHANGED				= 0x00000008;
+
+	/**
+	 * A warning has occurred.
+	 * 
+	 * <p>
+	 * There was a warning associated with a bundle.
+	 * 
+	 * @since 1.3
+	 */
+	public final static int	WARNING							= 0x00000010;
+
+	/**
+	 * An informational event has occurred.
+	 * 
+	 * <p>
+	 * There was an informational event associated with a bundle.
+	 * 
+	 * @since 1.3
+	 */
+	public final static int	INFO							= 0x00000020;
+
+	/**
+	 * The Framework has stopped.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework has been stopped because of a stop
+	 * operation on the system bundle. The source of this event is the System
+	 * Bundle.
+	 * 
+	 * @since 1.5
+	 */
+	public final static int	STOPPED							= 0x00000040;
+
+	/**
+	 * The Framework has stopped during update.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework has been stopped because of an
+	 * update operation on the system bundle. The Framework will be restarted
+	 * after this event is fired. The source of this event is the System Bundle.
+	 * 
+	 * @since 1.5
+	 */
+	public final static int	STOPPED_UPDATE					= 0x00000080;
+
+	/**
+	 * The Framework has stopped and the boot class path has changed.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework has been stopped because of a stop
+	 * operation on the system bundle and a bootclasspath extension bundle has
+	 * been installed or updated. The source of this event is the System Bundle.
+	 * 
+	 * @since 1.5
+	 */
+	public final static int	STOPPED_BOOTCLASSPATH_MODIFIED	= 0x00000100;
+
+	/**
+	 * The Framework did not stop before the wait timeout expired.
+	 * 
+	 * <p>
+	 * This event is fired when the Framework did not stop before the wait
+	 * timeout expired. The source of this event is the System Bundle.
+	 * 
+	 * @since 1.5
+	 */
+	public final static int	WAIT_TIMEDOUT					= 0x00000200;
+
+	/**
+	 * Creates a Framework event.
+	 * 
+	 * @param type The event type.
+	 * @param source The event source object. This may not be {@code null}.
+	 * @deprecated As of 1.2. This constructor is deprecated in favor of using
+	 *             the other constructor with the System Bundle as the event
+	 *             source.
+	 */
+	public FrameworkEvent(int type, Object source) {
+		super(source);
+		this.type = type;
+		this.bundle = null;
+		this.throwable = null;
+	}
+
+	/**
+	 * Creates a Framework event regarding the specified bundle.
+	 * 
+	 * @param type The event type.
+	 * @param bundle The event source.
+	 * @param throwable The related exception. This argument may be {@code null}
+	 *        if there is no related exception.
+	 */
+	public FrameworkEvent(int type, Bundle bundle, Throwable throwable) {
+		super(bundle);
+		this.type = type;
+		this.bundle = bundle;
+		this.throwable = throwable;
+	}
+
+	/**
+	 * Returns the exception related to this event.
+	 * 
+	 * @return The related exception or {@code null} if none.
+	 */
+	public Throwable getThrowable() {
+		return throwable;
+	}
+
+	/**
+	 * Returns the bundle associated with the event. This bundle is also the
+	 * source of the event.
+	 * 
+	 * @return The bundle associated with the event.
+	 */
+	public Bundle getBundle() {
+		return bundle;
+	}
+
+	/**
+	 * Returns the type of framework event.
+	 * <p>
+	 * The type values are:
+	 * <ul>
+	 * <li>{@link #STARTED}
+	 * <li>{@link #ERROR}
+	 * <li>{@link #WARNING}
+	 * <li>{@link #INFO}
+	 * <li>{@link #PACKAGES_REFRESHED}
+	 * <li>{@link #STARTLEVEL_CHANGED}
+	 * <li>{@link #STOPPED}
+	 * <li>{@link #STOPPED_BOOTCLASSPATH_MODIFIED}
+	 * <li>{@link #STOPPED_UPDATE}
+	 * <li>{@link #WAIT_TIMEDOUT}
+	 * </ul>
+	 * 
+	 * @return The type of state change.
+	 */
+
+	public int getType() {
+		return type;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/FrameworkListener.java b/osgi/framework/src/org/osgi/framework/FrameworkListener.java
new file mode 100644
index 0000000..7e1e813
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/FrameworkListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.EventListener;
+
+/**
+ * A {@code FrameworkEvent} listener. {@code FrameworkListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
+ * {@code FrameworkEvent} is fired, it is asynchronously delivered to a
+ * {@code FrameworkListener}. The Framework delivers {@code FrameworkEvent}
+ * objects to a {@code FrameworkListener} in order and must not concurrently
+ * call a {@code FrameworkListener}.
+ * 
+ * <p>
+ * A {@code FrameworkListener} object is registered with the Framework using the
+ * {@link BundleContext#addFrameworkListener(FrameworkListener)} method.
+ * {@code FrameworkListener} objects are called with a {@code FrameworkEvent}
+ * objects when the Framework starts and when asynchronous errors occur.
+ * 
+ * @see FrameworkEvent
+ * @NotThreadSafe
+ * @version $Id: ad7f563bd13b60e2b8a378f147057ca7f0accae2 $
+ */
+
+public interface FrameworkListener extends EventListener {
+
+	/**
+	 * Receives notification of a general {@code FrameworkEvent} object.
+	 * 
+	 * @param event The {@code FrameworkEvent} object.
+	 */
+	public void frameworkEvent(FrameworkEvent event);
+}
diff --git a/osgi/framework/src/org/osgi/framework/FrameworkUtil.java b/osgi/framework/src/org/osgi/framework/FrameworkUtil.java
new file mode 100644
index 0000000..ab0af92
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/FrameworkUtil.java
@@ -0,0 +1,2121 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2013). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * Framework Utility class.
+ * 
+ * <p>
+ * This class contains utility methods which access Framework functions that may
+ * be useful to bundles.
+ * 
+ * @since 1.3
+ * @ThreadSafe
+ * @author $Id: e93d15cef98c0e7f425f3b076d317c46ebb9a52a $
+ */
+public class FrameworkUtil {
+	/**
+	 * FrameworkUtil objects may not be constructed.
+	 */
+	private FrameworkUtil() {
+		// private empty constructor to prevent construction
+	}
+
+	/**
+	 * Creates a {@code Filter} object. This {@code Filter} object may be used
+	 * to match a {@code ServiceReference} object or a {@code Dictionary}
+	 * object.
+	 * 
+	 * <p>
+	 * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
+	 * thrown with a human readable message where the filter became unparsable.
+	 * 
+	 * <p>
+	 * This method returns a Filter implementation which may not perform as well
+	 * as the framework implementation-specific Filter implementation returned
+	 * by {@link BundleContext#createFilter(String)}.
+	 * 
+	 * @param filter The filter string.
+	 * @return A {@code Filter} object encapsulating the filter string.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
+	 *         filter string that cannot be parsed.
+	 * @throws NullPointerException If {@code filter} is null.
+	 * 
+	 * @see Filter
+	 */
+	public static Filter createFilter(String filter) throws InvalidSyntaxException {
+		return FilterImpl.newInstance(filter);
+	}
+
+	/**
+	 * Match a Distinguished Name (DN) chain against a pattern. DNs can be
+	 * matched using wildcards. A wildcard ({@code '*'} \u002A) replaces all
+	 * possible values. Due to the structure of the DN, the comparison is more
+	 * complicated than string-based wildcard matching.
+	 * <p>
+	 * A wildcard can stand for zero or more DNs in a chain, a number of
+	 * relative distinguished names (RDNs) within a DN, or the value of a single
+	 * RDN. The DNs in the chain and the matching pattern are canonicalized
+	 * before processing. This means, among other things, that spaces must be
+	 * ignored, except in values.
+	 * <p>
+	 * The format of a wildcard match pattern is:
+	 * 
+	 * <pre>
+	 * matchPattern ::= dn-match ( ';' dn-match ) *
+	 * dn-match     ::= ( '*' | rdn-match ) ( ',' rdn-match ) * | '-'
+	 * rdn-match    ::= name '=' value-match
+	 * value-match  ::= '*' | value-star
+	 * value-star   ::= < value, requires escaped '*' and '-' >
+	 * </pre>
+	 * <p>
+	 * The most simple case is a single wildcard; it must match any DN. A
+	 * wildcard can also replace the first list of RDNs of a DN. The first RDNs
+	 * are the least significant. Such lists of matched RDNs can be empty.
+	 * <p>
+	 * For example, a match pattern with a wildcard that matches all DNs that
+	 * end with RDNs of o=ACME and c=US would look like this:
+	 * 
+	 * <pre>
+	 * *, o=ACME, c=US
+	 * </pre>
+	 * 
+	 * This match pattern would match the following DNs:
+	 * 
+	 * <pre>
+	 * cn = Bugs Bunny, o = ACME, c = US
+	 * ou = Carrots, cn=Daffy Duck, o=ACME, c=US
+	 * street = 9C\, Avenue St. Drézéry, o=ACME, c=US
+	 * dc=www, dc=acme, dc=com, o=ACME, c=US
+	 * o=ACME, c=US
+	 * </pre>
+	 * 
+	 * The following DNs would not match:
+	 * 
+	 * <pre>
+	 * street = 9C\, Avenue St. Drézéry, o=ACME, c=FR
+	 * dc=www, dc=acme, dc=com, c=US
+	 * </pre>
+	 * 
+	 * If a wildcard is used for a value of an RDN, the value must be exactly *.
+	 * The wildcard must match any value, and no substring matching must be
+	 * done. For example:
+	 * 
+	 * <pre>
+	 * cn=*,o=ACME,c=*
+	 * </pre>
+	 * 
+	 * This match pattern with wildcard must match the following DNs:
+	 * 
+	 * <pre>
+	 * cn=Bugs Bunny,o=ACME,c=US
+	 * cn = Daffy Duck , o = ACME , c = US
+	 * cn=Road Runner, o=ACME, c=NL
+	 * </pre>
+	 * 
+	 * But not:
+	 * 
+	 * <pre>
+	 * o=ACME, c=NL
+	 * dc=acme.com, cn=Bugs Bunny, o=ACME, c=US
+	 * </pre>
+	 * 
+	 * <p>
+	 * A match pattern may contain a chain of DN match patterns. The semicolon(
+	 * {@code ';'} \u003B) must be used to separate DN match patterns in a
+	 * chain. Wildcards can also be used to match against a complete DN within a
+	 * chain.
+	 * <p>
+	 * The following example matches a certificate signed by Tweety Inc. in the
+	 * US.
+	 * </p>
+	 * 
+	 * <pre>
+	 * * ; ou=S & V, o=Tweety Inc., c=US
+	 * </pre>
+	 * <p>
+	 * The wildcard ('*') matches zero or one DN in the chain, however,
+	 * sometimes it is necessary to match a longer chain. The minus sign (
+	 * {@code '-'} \u002D) represents zero or more DNs, whereas the asterisk
+	 * only represents a single DN. For example, to match a DN where the Tweety
+	 * Inc. is in the DN chain, use the following expression:
+	 * </p>
+	 * 
+	 * <pre>
+	 * - ; *, o=Tweety Inc., c=US
+	 * </pre>
+	 * 
+	 * @param matchPattern The pattern against which to match the DN chain.
+	 * @param dnChain The DN chain to match against the specified pattern. Each
+	 *        element of the chain must be of type {@code String} and use the
+	 *        format defined in <a
+	 *        href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
+	 * @return {@code true} If the pattern matches the DN chain; otherwise
+	 *         {@code false} is returned.
+	 * @throws IllegalArgumentException If the specified match pattern or DN
+	 *         chain is invalid.
+	 * @since 1.5
+	 */
+	public static boolean matchDistinguishedNameChain(String matchPattern, List<String> dnChain) {
+		return DNChainMatching.match(matchPattern, dnChain);
+	}
+
+	/**
+	 * Return a {@code Bundle} for the specified bundle class. The returned
+	 * {@code Bundle} is the bundle associated with the bundle class loader
+	 * which defined the specified class.
+	 * 
+	 * @param classFromBundle A class defined by a bundle class loader.
+	 * @return A {@code Bundle} for the specified bundle class or {@code null}
+	 *         if the specified class was not defined by a bundle class loader.
+	 * @since 1.5
+	 */
+	public static Bundle getBundle(final Class<?> classFromBundle) {
+		// We use doPriv since the caller may not have permission
+		// to call getClassLoader.
+		Object cl = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			public Object run() {
+				return classFromBundle.getClassLoader();
+			}
+		});
+
+		if (cl instanceof BundleReference) {
+			return ((BundleReference) cl).getBundle();
+		}
+		return null;
+	}
+
+	/**
+	 * RFC 1960-based Filter. Filter objects can be created by calling the
+	 * constructor with the desired filter string. A Filter object can be called
+	 * numerous times to determine if the match argument matches the filter
+	 * string that was used to create the Filter object.
+	 * 
+	 * <p>
+	 * The syntax of a filter string is the string representation of LDAP search
+	 * filters as defined in RFC 1960: <i>A String Representation of LDAP Search
+	 * Filters</i> (available at http://www.ietf.org/rfc/rfc1960.txt). It should
+	 * be noted that RFC 2254: <i>A String Representation of LDAP Search
+	 * Filters</i> (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes
+	 * RFC 1960 but only adds extensible matching and is not applicable for this
+	 * API.
+	 * 
+	 * <p>
+	 * The string representation of an LDAP search filter is defined by the
+	 * following grammar. It uses a prefix format.
+	 * 
+	 * <pre>
+	 *   <filter> ::= '(' <filtercomp> ')'
+	 *   <filtercomp> ::= <and> | <or> | <not> | <item>
+	 *   <and> ::= '&' <filterlist>
+	 *   <or> ::= '|' <filterlist>
+	 *   <not> ::= '!' <filter>
+	 *   <filterlist> ::= <filter> | <filter> <filterlist>
+	 *   <item> ::= <simple> | <present> | <substring>
+	 *   <simple> ::= <attr> <filtertype> <value>
+	 *   <filtertype> ::= <equal> | <approx> | <greater> | <less>
+	 *   <equal> ::= '='
+	 *   <approx> ::= '˜='
+	 *   <greater> ::= '>='
+	 *   <less> ::= '<='
+	 *   <present> ::= <attr> '=*'
+	 *   <substring> ::= <attr> '=' <initial> <any> <final>
+	 *   <initial> ::= NULL | <value>
+	 *   <any> ::= '*' <starval>
+	 *   <starval> ::= NULL | <value> '*' <starval>
+	 *   <final> ::= NULL | <value>
+	 * </pre>
+	 * 
+	 * {@code <attr>} is a string representing an attribute, or key, in
+	 * the properties objects of the registered services. Attribute names are
+	 * not case sensitive; that is cn and CN both refer to the same attribute.
+	 * {@code <value>} is a string representing the value, or part of one,
+	 * of a key in the properties objects of the registered services. If a
+	 * {@code <value>} must contain one of the characters ' {@code *}' or
+	 * '{@code (}' or '{@code )}', these characters should be escaped by
+	 * preceding them with the backslash '{@code \}' character. Note that
+	 * although both the {@code <substring>} and {@code <present>}
+	 * productions can produce the {@code 'attr=*'} construct, this construct is
+	 * used only to denote a presence filter.
+	 * 
+	 * <p>
+	 * Examples of LDAP filters are:
+	 * 
+	 * <pre>
+	 *   "(cn=Babs Jensen)"
+	 *   "(!(cn=Tim Howes))"
+	 *   "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
+	 *   "(o=univ*of*mich*)"
+	 * </pre>
+	 * 
+	 * <p>
+	 * The approximate match ({@code ~=}) is implementation specific but should
+	 * at least ignore case and white space differences. Optional are codes like
+	 * soundex or other smart "closeness" comparisons.
+	 * 
+	 * <p>
+	 * Comparison of values is not straightforward. Strings are compared
+	 * differently than numbers and it is possible for a key to have multiple
+	 * values. Note that that keys in the match argument must always be strings.
+	 * The comparison is defined by the object type of the key's value. The
+	 * following rules apply for comparison:
+	 * 
+	 * <blockquote>
+	 * <TABLE BORDER=0>
+	 * <TR>
+	 * <TD><b>Property Value Type </b></TD>
+	 * <TD><b>Comparison Type</b></TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>String</TD>
+	 * <TD>String comparison</TD>
+	 * </TR>
+	 * <TR valign=top>
+	 * <TD>Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimal</TD>
+	 * <TD>numerical comparison</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Character</TD>
+	 * <TD>character comparison</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Boolean</TD>
+	 * <TD>equality comparisons only</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>[] (array)</TD>
+	 * <TD>recursively applied to values</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Collection</TD>
+	 * <TD>recursively applied to values</TD>
+	 * </TR>
+	 * </TABLE>
+	 * Note: arrays of primitives are also supported. </blockquote>
+	 * 
+	 * A filter matches a key that has multiple values if it matches at least
+	 * one of those values. For example,
+	 * 
+	 * <pre>
+	 * Dictionary d = new Hashtable();
+	 * d.put("cn", new String[] {"a", "b", "c"});
+	 * </pre>
+	 * 
+	 * d will match {@code (cn=a)} and also {@code (cn=b)}
+	 * 
+	 * <p>
+	 * A filter component that references a key having an unrecognizable data
+	 * type will evaluate to {@code false} .
+	 */
+	static private final class FilterImpl implements Filter {
+		/* filter operators */
+		private static final int	EQUAL		= 1;
+		private static final int	APPROX		= 2;
+		private static final int	GREATER		= 3;
+		private static final int	LESS		= 4;
+		private static final int	PRESENT		= 5;
+		private static final int	SUBSTRING	= 6;
+		private static final int	AND			= 7;
+		private static final int	OR			= 8;
+		private static final int	NOT			= 9;
+
+		/** filter operation */
+		private final int			op;
+		/** filter attribute or null if operation AND, OR or NOT */
+		private final String		attr;
+		/** filter operands */
+		private final Object		value;
+
+		/* normalized filter string for Filter object */
+		private transient String	filterString;
+
+		/**
+		 * Constructs a {@link FilterImpl} object. This filter object may be
+		 * used to match a {@link ServiceReference} or a Dictionary.
+		 * 
+		 * <p>
+		 * If the filter cannot be parsed, an {@link InvalidSyntaxException}
+		 * will be thrown with a human readable message where the filter became
+		 * unparsable.
+		 * 
+		 * @param filterString the filter string.
+		 * @throws InvalidSyntaxException If the filter parameter contains an
+		 *         invalid filter string that cannot be parsed.
+		 */
+		static FilterImpl newInstance(String filterString) throws InvalidSyntaxException {
+			return new Parser(filterString).parse();
+		}
+
+		FilterImpl(int operation, String attr, Object value) {
+			this.op = operation;
+			this.attr = attr;
+			this.value = value;
+			filterString = null;
+		}
+
+		/**
+		 * Filter using a service's properties.
+		 * <p>
+		 * This {@code Filter} is executed using the keys and values of the
+		 * referenced service's properties. The keys are looked up in a case
+		 * insensitive manner.
+		 * 
+		 * @param reference The reference to the service whose properties are
+		 *        used in the match.
+		 * @return {@code true} if the service's properties match this
+		 *         {@code Filter}; {@code false} otherwise.
+		 */
+		public boolean match(ServiceReference<?> reference) {
+			return matches(new ServiceReferenceMap(reference));
+		}
+
+		/**
+		 * Filter using a {@code Dictionary} with case insensitive key lookup.
+		 * This {@code Filter} is executed using the specified
+		 * {@code Dictionary}'s keys and values. The keys are looked up in a
+		 * case insensitive manner.
+		 * 
+		 * @param dictionary The {@code Dictionary} whose key/value pairs are
+		 *        used in the match.
+		 * @return {@code true} if the {@code Dictionary}'s values match this
+		 *         filter; {@code false} otherwise.
+		 * @throws IllegalArgumentException If {@code dictionary} contains case
+		 *         variants of the same key name.
+		 */
+		public boolean match(Dictionary<String, ?> dictionary) {
+			return matches(new CaseInsensitiveMap(dictionary));
+		}
+
+		/**
+		 * Filter using a {@code Dictionary}. This {@code Filter} is executed
+		 * using the specified {@code Dictionary}'s keys and values. The keys
+		 * are looked up in a normal manner respecting case.
+		 * 
+		 * @param dictionary The {@code Dictionary} whose key/value pairs are
+		 *        used in the match.
+		 * @return {@code true} if the {@code Dictionary}'s values match this
+		 *         filter; {@code false} otherwise.
+		 * @since 1.3
+		 */
+		public boolean matchCase(Dictionary<String, ?> dictionary) {
+			switch (op) {
+				case AND : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (!f.matchCase(dictionary)) {
+							return false;
+						}
+					}
+					return true;
+				}
+
+				case OR : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (f.matchCase(dictionary)) {
+							return true;
+						}
+					}
+					return false;
+				}
+
+				case NOT : {
+					FilterImpl filter = (FilterImpl) value;
+					return !filter.matchCase(dictionary);
+				}
+
+				case SUBSTRING :
+				case EQUAL :
+				case GREATER :
+				case LESS :
+				case APPROX : {
+					Object prop = (dictionary == null) ? null : dictionary.get(attr);
+					return compare(op, prop, value);
+				}
+
+				case PRESENT : {
+					Object prop = (dictionary == null) ? null : dictionary.get(attr);
+					return prop != null;
+				}
+			}
+
+			return false;
+		}
+
+		/**
+		 * Filter using a {@code Map}. This {@code Filter} is executed using the
+		 * specified {@code Map}'s keys and values. The keys are looked up in a
+		 * normal manner respecting case.
+		 * 
+		 * @param map The {@code Map} whose key/value pairs are used in the
+		 *        match. Maps with {@code null} key or values are not supported.
+		 *        A {@code null} value is considered not present to the filter.
+		 * @return {@code true} if the {@code Map}'s values match this filter;
+		 *         {@code false} otherwise.
+		 * @since 1.6
+		 */
+		public boolean matches(Map<String, ?> map) {
+			switch (op) {
+				case AND : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (!f.matches(map)) {
+							return false;
+						}
+					}
+					return true;
+				}
+
+				case OR : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (f.matches(map)) {
+							return true;
+						}
+					}
+					return false;
+				}
+
+				case NOT : {
+					FilterImpl filter = (FilterImpl) value;
+					return !filter.matches(map);
+				}
+
+				case SUBSTRING :
+				case EQUAL :
+				case GREATER :
+				case LESS :
+				case APPROX : {
+					Object prop = (map == null) ? null : map.get(attr);
+					return compare(op, prop, value);
+				}
+
+				case PRESENT : {
+					Object prop = (map == null) ? null : map.get(attr);
+					return prop != null;
+				}
+			}
+
+			return false;
+		}
+
+		/**
+		 * Returns this {@code Filter}'s filter string.
+		 * <p>
+		 * The filter string is normalized by removing whitespace which does not
+		 * affect the meaning of the filter.
+		 * 
+		 * @return This {@code Filter}'s filter string.
+		 */
+		@Override
+		public String toString() {
+			String result = filterString;
+			if (result == null) {
+				filterString = result = normalize().toString();
+			}
+			return result;
+		}
+
+		/**
+		 * Returns this {@code Filter}'s normalized filter string.
+		 * <p>
+		 * The filter string is normalized by removing whitespace which does not
+		 * affect the meaning of the filter.
+		 * 
+		 * @return This {@code Filter}'s filter string.
+		 */
+		private StringBuffer normalize() {
+			StringBuffer sb = new StringBuffer();
+			sb.append('(');
+
+			switch (op) {
+				case AND : {
+					sb.append('&');
+
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						sb.append(f.normalize());
+					}
+
+					break;
+				}
+
+				case OR : {
+					sb.append('|');
+
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						sb.append(f.normalize());
+					}
+
+					break;
+				}
+
+				case NOT : {
+					sb.append('!');
+					FilterImpl filter = (FilterImpl) value;
+					sb.append(filter.normalize());
+
+					break;
+				}
+
+				case SUBSTRING : {
+					sb.append(attr);
+					sb.append('=');
+
+					String[] substrings = (String[]) value;
+
+					for (String substr : substrings) {
+						if (substr == null) /* * */{
+							sb.append('*');
+						} else /* xxx */{
+							sb.append(encodeValue(substr));
+						}
+					}
+
+					break;
+				}
+				case EQUAL : {
+					sb.append(attr);
+					sb.append('=');
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case GREATER : {
+					sb.append(attr);
+					sb.append(">=");
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case LESS : {
+					sb.append(attr);
+					sb.append("<=");
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case APPROX : {
+					sb.append(attr);
+					sb.append("~=");
+					sb.append(encodeValue(approxString((String) value)));
+
+					break;
+				}
+
+				case PRESENT : {
+					sb.append(attr);
+					sb.append("=*");
+
+					break;
+				}
+			}
+
+			sb.append(')');
+
+			return sb;
+		}
+
+		/**
+		 * Compares this {@code Filter} to another {@code Filter}.
+		 * 
+		 * <p>
+		 * This implementation returns the result of calling
+		 * {@code this.toString().equals(obj.toString()}.
+		 * 
+		 * @param obj The object to compare against this {@code Filter}.
+		 * @return If the other object is a {@code Filter} object, then returns
+		 *         the result of calling
+		 *         {@code this.toString().equals(obj.toString()}; {@code false}
+		 *         otherwise.
+		 */
+		@Override
+		public boolean equals(Object obj) {
+			if (obj == this) {
+				return true;
+			}
+
+			if (!(obj instanceof Filter)) {
+				return false;
+			}
+
+			return this.toString().equals(obj.toString());
+		}
+
+		/**
+		 * Returns the hashCode for this {@code Filter}.
+		 * 
+		 * <p>
+		 * This implementation returns the result of calling
+		 * {@code this.toString().hashCode()}.
+		 * 
+		 * @return The hashCode of this {@code Filter}.
+		 */
+		@Override
+		public int hashCode() {
+			return this.toString().hashCode();
+		}
+
+		/**
+		 * Encode the value string such that '(', '*', ')' and '\' are escaped.
+		 * 
+		 * @param value unencoded value string.
+		 * @return encoded value string.
+		 */
+		private static String encodeValue(String value) {
+			boolean encoded = false;
+			int inlen = value.length();
+			int outlen = inlen << 1; /* inlen 2 */
+
+			char[] output = new char[outlen];
+			value.getChars(0, inlen, output, inlen);
+
+			int cursor = 0;
+			for (int i = inlen; i < outlen; i++) {
+				char c = output[i];
+
+				switch (c) {
+					case '(' :
+					case '*' :
+					case ')' :
+					case '\\' : {
+						output[cursor] = '\\';
+						cursor++;
+						encoded = true;
+
+						break;
+					}
+				}
+
+				output[cursor] = c;
+				cursor++;
+			}
+
+			return encoded ? new String(output, 0, cursor) : value;
+		}
+
+		private boolean compare(int operation, Object value1, Object value2) {
+			if (value1 == null) {
+				return false;
+			}
+			if (value1 instanceof String) {
+				return compare_String(operation, (String) value1, value2);
+			}
+
+			Class<?> clazz = value1.getClass();
+			if (clazz.isArray()) {
+				Class<?> type = clazz.getComponentType();
+				if (type.isPrimitive()) {
+					return compare_PrimitiveArray(operation, type, value1, value2);
+				}
+				return compare_ObjectArray(operation, (Object[]) value1, value2);
+			}
+			if (value1 instanceof Collection<?>) {
+				return compare_Collection(operation, (Collection<?>) value1, value2);
+			}
+			if (value1 instanceof Integer) {
+				return compare_Integer(operation, ((Integer) value1).intValue(), value2);
+			}
+			if (value1 instanceof Long) {
+				return compare_Long(operation, ((Long) value1).longValue(), value2);
+			}
+			if (value1 instanceof Byte) {
+				return compare_Byte(operation, ((Byte) value1).byteValue(), value2);
+			}
+			if (value1 instanceof Short) {
+				return compare_Short(operation, ((Short) value1).shortValue(), value2);
+			}
+			if (value1 instanceof Character) {
+				return compare_Character(operation, ((Character) value1).charValue(), value2);
+			}
+			if (value1 instanceof Float) {
+				return compare_Float(operation, ((Float) value1).floatValue(), value2);
+			}
+			if (value1 instanceof Double) {
+				return compare_Double(operation, ((Double) value1).doubleValue(), value2);
+			}
+			if (value1 instanceof Boolean) {
+				return compare_Boolean(operation, ((Boolean) value1).booleanValue(), value2);
+			}
+			if (value1 instanceof Comparable<?>) {
+				@SuppressWarnings("unchecked")
+				Comparable<Object> comparable = (Comparable<Object>) value1;
+				return compare_Comparable(operation, comparable, value2);
+			}
+			return compare_Unknown(operation, value1, value2);
+		}
+
+		private boolean compare_Collection(int operation, Collection<?> collection, Object value2) {
+			for (Object value1 : collection) {
+				if (compare(operation, value1, value2)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_ObjectArray(int operation, Object[] array, Object value2) {
+			for (Object value1 : array) {
+				if (compare(operation, value1, value2)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_PrimitiveArray(int operation, Class<?> type, Object primarray, Object value2) {
+			if (Integer.TYPE.isAssignableFrom(type)) {
+				int[] array = (int[]) primarray;
+				for (int value1 : array) {
+					if (compare_Integer(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Long.TYPE.isAssignableFrom(type)) {
+				long[] array = (long[]) primarray;
+				for (long value1 : array) {
+					if (compare_Long(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Byte.TYPE.isAssignableFrom(type)) {
+				byte[] array = (byte[]) primarray;
+				for (byte value1 : array) {
+					if (compare_Byte(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Short.TYPE.isAssignableFrom(type)) {
+				short[] array = (short[]) primarray;
+				for (short value1 : array) {
+					if (compare_Short(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Character.TYPE.isAssignableFrom(type)) {
+				char[] array = (char[]) primarray;
+				for (char value1 : array) {
+					if (compare_Character(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Float.TYPE.isAssignableFrom(type)) {
+				float[] array = (float[]) primarray;
+				for (float value1 : array) {
+					if (compare_Float(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Double.TYPE.isAssignableFrom(type)) {
+				double[] array = (double[]) primarray;
+				for (double value1 : array) {
+					if (compare_Double(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Boolean.TYPE.isAssignableFrom(type)) {
+				boolean[] array = (boolean[]) primarray;
+				for (boolean value1 : array) {
+					if (compare_Boolean(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			return false;
+		}
+
+		private boolean compare_String(int operation, String string, Object value2) {
+			switch (operation) {
+				case SUBSTRING : {
+					String[] substrings = (String[]) value2;
+					int pos = 0;
+					for (int i = 0, size = substrings.length; i < size; i++) {
+						String substr = substrings[i];
+
+						if (i + 1 < size) /* if this is not that last substr */{
+							if (substr == null) /* * */{
+								String substr2 = substrings[i + 1];
+
+								if (substr2 == null) /* ** */
+									continue; /* ignore first star */
+								/* xxx */
+								int index = string.indexOf(substr2, pos);
+								if (index == -1) {
+									return false;
+								}
+
+								pos = index + substr2.length();
+								if (i + 2 < size) // if there are more
+									// substrings, increment
+									// over the string we just
+									// matched; otherwise need
+									// to do the last substr
+									// check
+									i++;
+							} else /* xxx */{
+								int len = substr.length();
+								if (string.regionMatches(pos, substr, 0, len)) {
+									pos += len;
+								} else {
+									return false;
+								}
+							}
+						} else /* last substr */{
+							if (substr == null) /* * */{
+								return true;
+							}
+							/* xxx */
+							return string.endsWith(substr);
+						}
+					}
+
+					return true;
+				}
+				case EQUAL : {
+					return string.equals(value2);
+				}
+				case APPROX : {
+					string = approxString(string);
+					String string2 = approxString((String) value2);
+
+					return string.equalsIgnoreCase(string2);
+				}
+				case GREATER : {
+					return string.compareTo((String) value2) >= 0;
+				}
+				case LESS : {
+					return string.compareTo((String) value2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Integer(int operation, int intval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			int intval2;
+			try {
+				intval2 = Integer.parseInt(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return intval == intval2;
+				}
+				case GREATER : {
+					return intval >= intval2;
+				}
+				case LESS : {
+					return intval <= intval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Long(int operation, long longval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			long longval2;
+			try {
+				longval2 = Long.parseLong(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return longval == longval2;
+				}
+				case GREATER : {
+					return longval >= longval2;
+				}
+				case LESS : {
+					return longval <= longval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Byte(int operation, byte byteval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			byte byteval2;
+			try {
+				byteval2 = Byte.parseByte(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return byteval == byteval2;
+				}
+				case GREATER : {
+					return byteval >= byteval2;
+				}
+				case LESS : {
+					return byteval <= byteval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Short(int operation, short shortval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			short shortval2;
+			try {
+				shortval2 = Short.parseShort(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return shortval == shortval2;
+				}
+				case GREATER : {
+					return shortval >= shortval2;
+				}
+				case LESS : {
+					return shortval <= shortval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Character(int operation, char charval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			char charval2;
+			try {
+				charval2 = ((String) value2).charAt(0);
+			} catch (IndexOutOfBoundsException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case EQUAL : {
+					return charval == charval2;
+				}
+				case APPROX : {
+					return (charval == charval2) || (Character.toUpperCase(charval) == Character.toUpperCase(charval2)) || (Character.toLowerCase(charval) == Character.toLowerCase(charval2));
+				}
+				case GREATER : {
+					return charval >= charval2;
+				}
+				case LESS : {
+					return charval <= charval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Boolean(int operation, boolean boolval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			boolean boolval2 = Boolean.valueOf(((String) value2).trim()).booleanValue();
+			switch (operation) {
+				case APPROX :
+				case EQUAL :
+				case GREATER :
+				case LESS : {
+					return boolval == boolval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Float(int operation, float floatval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			float floatval2;
+			try {
+				floatval2 = Float.parseFloat(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return Float.compare(floatval, floatval2) == 0;
+				}
+				case GREATER : {
+					return Float.compare(floatval, floatval2) >= 0;
+				}
+				case LESS : {
+					return Float.compare(floatval, floatval2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Double(int operation, double doubleval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			double doubleval2;
+			try {
+				doubleval2 = Double.parseDouble(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return Double.compare(doubleval, doubleval2) == 0;
+				}
+				case GREATER : {
+					return Double.compare(doubleval, doubleval2) >= 0;
+				}
+				case LESS : {
+					return Double.compare(doubleval, doubleval2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private static Object valueOf(Class<?> target, String value2) {
+			do {
+				Method method;
+				try {
+					method = target.getMethod("valueOf", String.class);
+				} catch (NoSuchMethodException e) {
+					break;
+				}
+				if (Modifier.isStatic(method.getModifiers()) && target.isAssignableFrom(method.getReturnType())) {
+					setAccessible(method);
+					try {
+						return method.invoke(null, value2.trim());
+					} catch (IllegalAccessException e) {
+						return null;
+					} catch (InvocationTargetException e) {
+						return null;
+					}
+				}
+			} while (false);
+
+			do {
+				Constructor<?> constructor;
+				try {
+					constructor = target.getConstructor(String.class);
+				} catch (NoSuchMethodException e) {
+					break;
+				}
+				setAccessible(constructor);
+				try {
+					return constructor.newInstance(value2.trim());
+				} catch (IllegalAccessException e) {
+					return null;
+				} catch (InvocationTargetException e) {
+					return null;
+				} catch (InstantiationException e) {
+					return null;
+				}
+			} while (false);
+
+			return null;
+		}
+
+		private static void setAccessible(AccessibleObject accessible) {
+			if (!accessible.isAccessible()) {
+				AccessController.doPrivileged(new SetAccessibleAction(accessible));
+			}
+		}
+
+		private boolean compare_Comparable(int operation, Comparable<Object> value1, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			value2 = valueOf(value1.getClass(), (String) value2);
+			if (value2 == null) {
+				return false;
+			}
+			try {
+				switch (operation) {
+					case APPROX :
+					case EQUAL : {
+						return value1.compareTo(value2) == 0;
+					}
+					case GREATER : {
+						return value1.compareTo(value2) >= 0;
+					}
+					case LESS : {
+						return value1.compareTo(value2) <= 0;
+					}
+				}
+			} catch (Exception e) {
+				// if the compareTo method throws an exception; return false
+				return false;
+			}
+			return false;
+		}
+
+		private boolean compare_Unknown(int operation, Object value1, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			value2 = valueOf(value1.getClass(), (String) value2);
+			if (value2 == null) {
+				return false;
+			}
+			try {
+				switch (operation) {
+					case APPROX :
+					case EQUAL :
+					case GREATER :
+					case LESS : {
+						return value1.equals(value2);
+					}
+				}
+			} catch (Exception e) {
+				// if the equals method throws an exception; return false
+				return false;
+			}
+			return false;
+		}
+
+		/**
+		 * Map a string for an APPROX (~=) comparison.
+		 * 
+		 * This implementation removes white spaces. This is the minimum
+		 * implementation allowed by the OSGi spec.
+		 * 
+		 * @param input Input string.
+		 * @return String ready for APPROX comparison.
+		 */
+		private static String approxString(String input) {
+			boolean changed = false;
+			char[] output = input.toCharArray();
+			int cursor = 0;
+			for (char c : output) {
+				if (Character.isWhitespace(c)) {
+					changed = true;
+					continue;
+				}
+
+				output[cursor] = c;
+				cursor++;
+			}
+
+			return changed ? new String(output, 0, cursor) : input;
+		}
+
+		/**
+		 * Parser class for OSGi filter strings. This class parses the complete
+		 * filter string and builds a tree of Filter objects rooted at the
+		 * parent.
+		 */
+		static private final class Parser {
+			private final String	filterstring;
+			private final char[]	filterChars;
+			private int				pos;
+
+			Parser(String filterstring) {
+				this.filterstring = filterstring;
+				filterChars = filterstring.toCharArray();
+				pos = 0;
+			}
+
+			FilterImpl parse() throws InvalidSyntaxException {
+				FilterImpl filter;
+				try {
+					filter = parse_filter();
+				} catch (ArrayIndexOutOfBoundsException e) {
+					throw new InvalidSyntaxException("Filter ended abruptly", filterstring, e);
+				}
+
+				if (pos != filterChars.length) {
+					throw new InvalidSyntaxException("Extraneous trailing characters: " + filterstring.substring(pos), filterstring);
+				}
+				return filter;
+			}
+
+			private FilterImpl parse_filter() throws InvalidSyntaxException {
+				FilterImpl filter;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring);
+				}
+
+				pos++;
+
+				filter = parse_filtercomp();
+
+				skipWhiteSpace();
+
+				if (filterChars[pos] != ')') {
+					throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring);
+				}
+
+				pos++;
+
+				skipWhiteSpace();
+
+				return filter;
+			}
+
+			private FilterImpl parse_filtercomp() throws InvalidSyntaxException {
+				skipWhiteSpace();
+
+				char c = filterChars[pos];
+
+				switch (c) {
+					case '&' : {
+						pos++;
+						return parse_and();
+					}
+					case '|' : {
+						pos++;
+						return parse_or();
+					}
+					case '!' : {
+						pos++;
+						return parse_not();
+					}
+				}
+				return parse_item();
+			}
+
+			private FilterImpl parse_and() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
+
+				while (filterChars[pos] == '(') {
+					FilterImpl child = parse_filter();
+					operands.add(child);
+				}
+
+				return new FilterImpl(FilterImpl.AND, null, operands.toArray(new FilterImpl[operands.size()]));
+			}
+
+			private FilterImpl parse_or() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
+
+				while (filterChars[pos] == '(') {
+					FilterImpl child = parse_filter();
+					operands.add(child);
+				}
+
+				return new FilterImpl(FilterImpl.OR, null, operands.toArray(new FilterImpl[operands.size()]));
+			}
+
+			private FilterImpl parse_not() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				FilterImpl child = parse_filter();
+
+				return new FilterImpl(FilterImpl.NOT, null, child);
+			}
+
+			private FilterImpl parse_item() throws InvalidSyntaxException {
+				String attr = parse_attr();
+
+				skipWhiteSpace();
+
+				switch (filterChars[pos]) {
+					case '~' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.APPROX, attr, parse_value());
+						}
+						break;
+					}
+					case '>' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.GREATER, attr, parse_value());
+						}
+						break;
+					}
+					case '<' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.LESS, attr, parse_value());
+						}
+						break;
+					}
+					case '=' : {
+						if (filterChars[pos + 1] == '*') {
+							int oldpos = pos;
+							pos += 2;
+							skipWhiteSpace();
+							if (filterChars[pos] == ')') {
+								return new FilterImpl(FilterImpl.PRESENT, attr, null);
+							}
+							pos = oldpos;
+						}
+
+						pos++;
+						Object string = parse_substring();
+
+						if (string instanceof String) {
+							return new FilterImpl(FilterImpl.EQUAL, attr, string);
+						}
+						return new FilterImpl(FilterImpl.SUBSTRING, attr, string);
+					}
+				}
+
+				throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring);
+			}
+
+			private String parse_attr() throws InvalidSyntaxException {
+				skipWhiteSpace();
+
+				int begin = pos;
+				int end = pos;
+
+				char c = filterChars[pos];
+
+				while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') {
+					pos++;
+
+					if (!Character.isWhitespace(c)) {
+						end = pos;
+					}
+
+					c = filterChars[pos];
+				}
+
+				int length = end - begin;
+
+				if (length == 0) {
+					throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring);
+				}
+
+				return new String(filterChars, begin, length);
+			}
+
+			private String parse_value() throws InvalidSyntaxException {
+				StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+				parseloop: while (true) {
+					char c = filterChars[pos];
+
+					switch (c) {
+						case ')' : {
+							break parseloop;
+						}
+
+						case '(' : {
+							throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring);
+						}
+
+						case '\\' : {
+							pos++;
+							c = filterChars[pos];
+							/* fall through into default */
+						}
+
+						default : {
+							sb.append(c);
+							pos++;
+							break;
+						}
+					}
+				}
+
+				if (sb.length() == 0) {
+					throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring);
+				}
+
+				return sb.toString();
+			}
+
+			private Object parse_substring() throws InvalidSyntaxException {
+				StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+				List<String> operands = new ArrayList<String>(10);
+
+				parseloop: while (true) {
+					char c = filterChars[pos];
+
+					switch (c) {
+						case ')' : {
+							if (sb.length() > 0) {
+								operands.add(sb.toString());
+							}
+
+							break parseloop;
+						}
+
+						case '(' : {
+							throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring);
+						}
+
+						case '*' : {
+							if (sb.length() > 0) {
+								operands.add(sb.toString());
+							}
+
+							sb.setLength(0);
+
+							operands.add(null);
+							pos++;
+
+							break;
+						}
+
+						case '\\' : {
+							pos++;
+							c = filterChars[pos];
+							/* fall through into default */
+						}
+
+						default : {
+							sb.append(c);
+							pos++;
+							break;
+						}
+					}
+				}
+
+				int size = operands.size();
+
+				if (size == 0) {
+					return "";
+				}
+
+				if (size == 1) {
+					Object single = operands.get(0);
+
+					if (single != null) {
+						return single;
+					}
+				}
+
+				return operands.toArray(new String[size]);
+			}
+
+			private void skipWhiteSpace() {
+				for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) {
+					pos++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * This Map is used for case-insensitive key lookup during filter
+	 * evaluation. This Map implementation only supports the get operation using
+	 * a String key as no other operations are used by the Filter
+	 * implementation.
+	 */
+	static private final class CaseInsensitiveMap extends AbstractMap<String, Object> implements Map<String, Object> {
+		private final Dictionary<String, ?>	dictionary;
+		private final String[]				keys;
+
+		/**
+		 * Create a case insensitive map from the specified dictionary.
+		 * 
+		 * @param dictionary
+		 * @throws IllegalArgumentException If {@code dictionary} contains case
+		 *         variants of the same key name.
+		 */
+		CaseInsensitiveMap(Dictionary<String, ?> dictionary) {
+			if (dictionary == null) {
+				this.dictionary = null;
+				this.keys = new String[0];
+				return;
+			}
+			this.dictionary = dictionary;
+			List<String> keyList = new ArrayList<String>(dictionary.size());
+			for (Enumeration<?> e = dictionary.keys(); e.hasMoreElements();) {
+				Object k = e.nextElement();
+				if (k instanceof String) {
+					String key = (String) k;
+					for (String i : keyList) {
+						if (key.equalsIgnoreCase(i)) {
+							throw new IllegalArgumentException();
+						}
+					}
+					keyList.add(key);
+				}
+			}
+			this.keys = keyList.toArray(new String[keyList.size()]);
+		}
+
+		@Override
+		public Object get(Object o) {
+			String k = (String) o;
+			for (String key : keys) {
+				if (key.equalsIgnoreCase(k)) {
+					return dictionary.get(key);
+				}
+			}
+			return null;
+		}
+
+		public Set<java.util.Map.Entry<String, Object>> entrySet() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	/**
+	 * This Map is used for key lookup from a ServiceReference during filter
+	 * evaluation. This Map implementation only supports the get operation using
+	 * a String key as no other operations are used by the Filter
+	 * implementation.
+	 */
+	static private final class ServiceReferenceMap extends AbstractMap<String, Object> implements Map<String, Object> {
+		private final ServiceReference<?>	reference;
+
+		ServiceReferenceMap(ServiceReference<?> reference) {
+			this.reference = reference;
+		}
+
+		@Override
+		public Object get(Object key) {
+			if (reference == null) {
+				return null;
+			}
+			return reference.getProperty((String) key);
+		}
+
+		public Set<java.util.Map.Entry<String, Object>> entrySet() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	static private final class SetAccessibleAction implements PrivilegedAction<Void> {
+		private final AccessibleObject	accessible;
+
+		SetAccessibleAction(AccessibleObject accessible) {
+			this.accessible = accessible;
+		}
+
+		public Void run() {
+			accessible.setAccessible(true);
+			return null;
+		}
+	}
+
+	/**
+	 * This class contains a method to match a distinguished name (DN) chain
+	 * against and DN chain pattern.
+	 * <p>
+	 * The format of DNs are given in RFC 2253. We represent a signature chain
+	 * for an X.509 certificate as a semicolon separated list of DNs. This is
+	 * what we refer to as the DN chain. Each DN is made up of relative
+	 * distinguished names (RDN) which in turn are made up of key value pairs.
+	 * For example:
+	 * 
+	 * <pre>
+	 *   cn=ben+ou=research,o=ACME,c=us;ou=Super CA,c=CA
+	 * </pre>
+	 * 
+	 * is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us} " and "
+	 * {@code ou=Super CA,c=CA} ". The first DN is made of of three RDNs: "
+	 * {@code cn=ben+ou=research}" and "{@code o=ACME}" and " {@code c=us}
+	 * ". The first RDN has two name value pairs: " {@code cn=ben}" and "
+	 * {@code ou=research}".
+	 * <p>
+	 * A chain pattern makes use of wildcards ('*' or '-') to match against DNs,
+	 * and wildcards ('*') to match againts DN prefixes, and value. If a DN in a
+	 * match pattern chain is made up of a wildcard ("*"), that wildcard will
+	 * match zero or one DNs in the chain. If a DN in a match pattern chain is
+	 * made up of a wildcard ("-"), that wildcard will match zero or more DNs in
+	 * the chain. If the first RDN of a DN is the wildcard ("*"), that DN will
+	 * match any other DN with the same suffix (the DN with the wildcard RDN
+	 * removed). If a value of a name/value pair is a wildcard ("*"), the value
+	 * will match any value for that name.
+	 */
+	static private final class DNChainMatching {
+		private static final String	MINUS_WILDCARD	= "-";
+		private static final String	STAR_WILDCARD	= "*";
+
+		/**
+		 * Check the name/value pairs of the rdn against the pattern.
+		 * 
+		 * @param rdn List of name value pairs for a given RDN.
+		 * @param rdnPattern List of name value pattern pairs.
+		 * @return true if the list of name value pairs match the pattern.
+		 */
+		private static boolean rdnmatch(List<?> rdn, List<?> rdnPattern) {
+			if (rdn.size() != rdnPattern.size()) {
+				return false;
+			}
+			for (int i = 0; i < rdn.size(); i++) {
+				String rdnNameValue = (String) rdn.get(i);
+				String patNameValue = (String) rdnPattern.get(i);
+				int rdnNameEnd = rdnNameValue.indexOf('=');
+				int patNameEnd = patNameValue.indexOf('=');
+				if (rdnNameEnd != patNameEnd || !rdnNameValue.regionMatches(0, patNameValue, 0, rdnNameEnd)) {
+					return false;
+				}
+				String patValue = patNameValue.substring(patNameEnd);
+				String rdnValue = rdnNameValue.substring(rdnNameEnd);
+				if (!rdnValue.equals(patValue) && !patValue.equals("=*") && !patValue.equals("=#16012a")) {
+					return false;
+				}
+			}
+			return true;
+		}
+
+		private static boolean dnmatch(List<?> dn, List<?> dnPattern) {
+			int dnStart = 0;
+			int patStart = 0;
+			int patLen = dnPattern.size();
+			if (patLen == 0) {
+				return false;
+			}
+			if (dnPattern.get(0).equals(STAR_WILDCARD)) {
+				patStart = 1;
+				patLen--;
+			}
+			if (dn.size() < patLen) {
+				return false;
+			} else {
+				if (dn.size() > patLen) {
+					if (!dnPattern.get(0).equals(STAR_WILDCARD)) {
+						// If the number of rdns do not match we must have a
+						// prefix map
+						return false;
+					}
+					// The rdnPattern and rdn must have the same number of
+					// elements
+					dnStart = dn.size() - patLen;
+				}
+			}
+			for (int i = 0; i < patLen; i++) {
+				if (!rdnmatch((List<?>) dn.get(i + dnStart), (List<?>) dnPattern.get(i + patStart))) {
+					return false;
+				}
+			}
+			return true;
+		}
+
+		/**
+		 * Parses a distinguished name chain pattern and returns a List where
+		 * each element represents a distinguished name (DN) in the chain of
+		 * DNs. Each element will be either a String, if the element represents
+		 * a wildcard ("*" or "-"), or a List representing an RDN. Each element
+		 * in the RDN List will be a String, if the element represents a
+		 * wildcard ("*"), or a List of Strings, each String representing a
+		 * name/value pair in the RDN.
+		 * 
+		 * @param pattern
+		 * @return a list of DNs.
+		 * @throws IllegalArgumentException
+		 */
+		private static List<Object> parseDNchainPattern(String pattern) {
+			if (pattern == null) {
+				throw new IllegalArgumentException("The pattern must not be null.");
+			}
+			List<Object> parsed = new ArrayList<Object>();
+			final int length = pattern.length();
+			char c = ';'; // start with semi-colon to detect empty pattern
+			for (int startIndex = skipSpaces(pattern, 0); startIndex < length;) {
+				int cursor = startIndex;
+				int endIndex = startIndex;
+				out: for (boolean inQuote = false; cursor < length; cursor++) {
+					c = pattern.charAt(cursor);
+					switch (c) {
+						case '"' :
+							inQuote = !inQuote;
+							break;
+						case '\\' :
+							cursor++; // skip the escaped char
+							if (cursor == length) {
+								throw new IllegalArgumentException("unterminated escape");
+							}
+							break;
+						case ';' :
+							if (!inQuote) {
+								break out; // end of pattern
+							}
+							break;
+					}
+					if (c != ' ') { // ignore trailing whitespace
+						endIndex = cursor + 1;
+					}
+				}
+				parsed.add(pattern.substring(startIndex, endIndex));
+				startIndex = skipSpaces(pattern, cursor + 1);
+			}
+			if (c == ';') { // last non-whitespace character was a semi-colon
+				throw new IllegalArgumentException("empty pattern");
+			}
+
+			// Now we have parsed into a list of strings, lets make List of rdn
+			// out of them
+			for (int i = 0; i < parsed.size(); i++) {
+				String dn = (String) parsed.get(i);
+				if (dn.equals(STAR_WILDCARD) || dn.equals(MINUS_WILDCARD)) {
+					continue;
+				}
+				List<Object> rdns = new ArrayList<Object>();
+				if (dn.charAt(0) == '*') {
+					int index = skipSpaces(dn, 1);
+					if (dn.charAt(index) != ',') {
+						throw new IllegalArgumentException("invalid wildcard prefix");
+					}
+					rdns.add(STAR_WILDCARD);
+					dn = new X500Principal(dn.substring(index + 1)).getName(X500Principal.CANONICAL);
+				} else {
+					dn = new X500Principal(dn).getName(X500Principal.CANONICAL);
+				}
+				// Now dn is a nice CANONICAL DN
+				parseDN(dn, rdns);
+				parsed.set(i, rdns);
+			}
+			return parsed;
+		}
+
+		private static List<Object> parseDNchain(List<String> chain) {
+			if (chain == null) {
+				throw new IllegalArgumentException("DN chain must not be null.");
+			}
+			List<Object> result = new ArrayList<Object>(chain.size());
+			// Now we parse is a list of strings, lets make List of rdn out
+			// of them
+			for (String dn : chain) {
+				dn = new X500Principal(dn).getName(X500Principal.CANONICAL);
+				// Now dn is a nice CANONICAL DN
+				List<Object> rdns = new ArrayList<Object>();
+				parseDN(dn, rdns);
+				result.add(rdns);
+			}
+			if (result.size() == 0) {
+				throw new IllegalArgumentException("empty DN chain");
+			}
+			return result;
+		}
+
+		/**
+		 * Increment startIndex until the end of dnChain is hit or until it is
+		 * the index of a non-space character.
+		 */
+		private static int skipSpaces(String dnChain, int startIndex) {
+			while (startIndex < dnChain.length() && dnChain.charAt(startIndex) == ' ') {
+				startIndex++;
+			}
+			return startIndex;
+		}
+
+		/**
+		 * Takes a distinguished name in canonical form and fills in the
+		 * rdnArray with the extracted RDNs.
+		 * 
+		 * @param dn the distinguished name in canonical form.
+		 * @param rdn the list to fill in with RDNs extracted from the dn
+		 * @throws IllegalArgumentException if a formatting error is found.
+		 */
+		private static void parseDN(String dn, List<Object> rdn) {
+			int startIndex = 0;
+			char c = '\0';
+			List<String> nameValues = new ArrayList<String>();
+			while (startIndex < dn.length()) {
+				int endIndex;
+				for (endIndex = startIndex; endIndex < dn.length(); endIndex++) {
+					c = dn.charAt(endIndex);
+					if (c == ',' || c == '+') {
+						break;
+					}
+					if (c == '\\') {
+						endIndex++; // skip the escaped char
+					}
+				}
+				if (endIndex > dn.length()) {
+					throw new IllegalArgumentException("unterminated escape " + dn);
+				}
+				nameValues.add(dn.substring(startIndex, endIndex));
+				if (c != '+') {
+					rdn.add(nameValues);
+					if (endIndex != dn.length()) {
+						nameValues = new ArrayList<String>();
+					} else {
+						nameValues = null;
+					}
+				}
+				startIndex = endIndex + 1;
+			}
+			if (nameValues != null) {
+				throw new IllegalArgumentException("improperly terminated DN " + dn);
+			}
+		}
+
+		/**
+		 * This method will return an 'index' which points to a non-wildcard DN
+		 * or the end-of-list.
+		 */
+		private static int skipWildCards(List<Object> dnChainPattern, int dnChainPatternIndex) {
+			int i;
+			for (i = dnChainPatternIndex; i < dnChainPattern.size(); i++) {
+				Object dnPattern = dnChainPattern.get(i);
+				if (dnPattern instanceof String) {
+					if (!dnPattern.equals(STAR_WILDCARD) && !dnPattern.equals(MINUS_WILDCARD)) {
+						throw new IllegalArgumentException("expected wildcard in DN pattern");
+					}
+					// otherwise continue skipping over wild cards
+				} else {
+					if (dnPattern instanceof List<?>) {
+						// if its a list then we have our 'non-wildcard' DN
+						break;
+					} else {
+						// unknown member of the DNChainPattern
+						throw new IllegalArgumentException("expected String or List in DN Pattern");
+					}
+				}
+			}
+			// i either points to end-of-list, or to the first
+			// non-wildcard pattern after dnChainPatternIndex
+			return i;
+		}
+
+		/**
+		 * recursively attempt to match the DNChain, and the DNChainPattern
+		 * where DNChain is of the format: "DN;DN;DN;" and DNChainPattern is of
+		 * the format: "DNPattern;*;DNPattern" (or combinations of this)
+		 */
+		private static boolean dnChainMatch(List<Object> dnChain, int dnChainIndex, List<Object> dnChainPattern, int dnChainPatternIndex) throws IllegalArgumentException {
+			if (dnChainIndex >= dnChain.size()) {
+				return false;
+			}
+			if (dnChainPatternIndex >= dnChainPattern.size()) {
+				return false;
+			}
+			// check to see what the pattern starts with
+			Object dnPattern = dnChainPattern.get(dnChainPatternIndex);
+			if (dnPattern instanceof String) {
+				if (!dnPattern.equals(STAR_WILDCARD) && !dnPattern.equals(MINUS_WILDCARD)) {
+					throw new IllegalArgumentException("expected wildcard in DN pattern");
+				}
+				// here we are processing a wild card as the first DN
+				// skip all wildcard DN's
+				if (dnPattern.equals(MINUS_WILDCARD)) {
+					dnChainPatternIndex = skipWildCards(dnChainPattern, dnChainPatternIndex);
+				} else {
+					dnChainPatternIndex++; // only skip the '*' wildcard
+				}
+				if (dnChainPatternIndex >= dnChainPattern.size()) {
+					// return true iff the wild card is '-' or if we are at the
+					// end of the chain
+					return dnPattern.equals(MINUS_WILDCARD) ? true : dnChain.size() - 1 == dnChainIndex;
+				}
+				//
+				// we will now recursively call to see if the rest of the
+				// DNChainPattern matches increasingly smaller portions of the
+				// rest of the DNChain
+				//
+				if (dnPattern.equals(STAR_WILDCARD)) {
+					// '*' option: only wildcard on 0 or 1
+					return dnChainMatch(dnChain, dnChainIndex, dnChainPattern, dnChainPatternIndex) || dnChainMatch(dnChain, dnChainIndex + 1, dnChainPattern, dnChainPatternIndex);
+				}
+				for (int i = dnChainIndex; i < dnChain.size(); i++) {
+					// '-' option: wildcard 0 or more
+					if (dnChainMatch(dnChain, i, dnChainPattern, dnChainPatternIndex)) {
+						return true;
+					}
+				}
+				// if we are here, then we didn't find a match.. fall through to
+				// failure
+			} else {
+				if (dnPattern instanceof List<?>) {
+					// here we have to do a deeper check for each DN in the
+					// pattern until we hit a wild card
+					do {
+						if (!dnmatch((List<?>) dnChain.get(dnChainIndex), (List<?>) dnPattern)) {
+							return false;
+						}
+						// go to the next set of DN's in both chains
+						dnChainIndex++;
+						dnChainPatternIndex++;
+						// if we finished the pattern then it all matched
+						if ((dnChainIndex >= dnChain.size()) && (dnChainPatternIndex >= dnChainPattern.size())) {
+							return true;
+						}
+						// if the DN Chain is finished, but the pattern isn't
+						// finished then if the rest of the pattern is not
+						// wildcard then we are done
+						if (dnChainIndex >= dnChain.size()) {
+							dnChainPatternIndex = skipWildCards(dnChainPattern, dnChainPatternIndex);
+							// return TRUE iff the pattern index moved past the
+							// list-size (implying that the rest of the pattern
+							// is all wildcards)
+							return dnChainPatternIndex >= dnChainPattern.size();
+						}
+						// if the pattern finished, but the chain continues then
+						// we have a mis-match
+						if (dnChainPatternIndex >= dnChainPattern.size()) {
+							return false;
+						}
+						// get the next DN Pattern
+						dnPattern = dnChainPattern.get(dnChainPatternIndex);
+						if (dnPattern instanceof String) {
+							if (!dnPattern.equals(STAR_WILDCARD) && !dnPattern.equals(MINUS_WILDCARD)) {
+								throw new IllegalArgumentException("expected wildcard in DN pattern");
+							}
+							// if the next DN is a 'wildcard', then we will
+							// recurse
+							return dnChainMatch(dnChain, dnChainIndex, dnChainPattern, dnChainPatternIndex);
+						} else {
+							if (!(dnPattern instanceof List<?>)) {
+								throw new IllegalArgumentException("expected String or List in DN Pattern");
+							}
+						}
+						// if we are here, then we will just continue to the
+						// match the next set of DN's from the DNChain, and the
+						// DNChainPattern since both are lists
+					} while (true);
+					// should never reach here?
+				} else {
+					throw new IllegalArgumentException("expected String or List in DN Pattern");
+				}
+			}
+			// if we get here, the the default return is 'mis-match'
+			return false;
+		}
+
+		/**
+		 * Matches a distinguished name chain against a pattern of a
+		 * distinguished name chain.
+		 * 
+		 * @param dnChain
+		 * @param pattern the pattern of distinguished name (DN) chains to match
+		 *        against the dnChain. Wildcards ("*" or "-") can be used in
+		 *        three cases:
+		 *        <ol>
+		 *        <li>As a DN. In this case, the DN will consist of just the "*"
+		 *        or "-". When "*" is used it will match zero or one DNs. When
+		 *        "-" is used it will match zero or more DNs. For example,
+		 *        "cn=me,c=US;*;cn=you" will match
+		 *        "cn=me,c=US";cn=you" and "cn=me,c=US;cn=her;cn=you". The
+		 *        pattern "cn=me,c=US;-;cn=you" will match "cn=me,c=US";cn=you"
+		 *        and "cn=me,c=US;cn=her;cn=him;cn=you".</li>
+		 *        <li>As a DN prefix. In this case, the DN must start with "*,".
+		 *        The wild card will match zero or more RDNs at the start of a
+		 *        DN. For example, "*,cn=me,c=US;cn=you" will match
+		 *        "cn=me,c=US";cn=you" and
+		 *        "ou=my org unit,o=my org,cn=me,c=US;cn=you"</li>
+		 *        <li>As a value. In this case the value of a name value pair in
+		 *        an RDN will be a "*". The wildcard will match any value for
+		 *        the given name. For example, "cn=*,c=US;cn=you" will match
+		 *        "cn=me,c=US";cn=you" and "cn=her,c=US;cn=you", but it will not
+		 *        match "ou=my org unit,c=US;cn=you". If the wildcard does not
+		 *        occur by itself in the value, it will not be used as a
+		 *        wildcard. In other words, "cn=m*,c=US;cn=you" represents the
+		 *        common name of "m*" not any common name starting with "m".</li>
+		 *        </ol>
+		 * @return true if dnChain matches the pattern.
+		 * @throws IllegalArgumentException
+		 */
+		static boolean match(String pattern, List<String> dnChain) {
+			List<Object> parsedDNChain;
+			List<Object> parsedDNPattern;
+			try {
+				parsedDNChain = parseDNchain(dnChain);
+			} catch (RuntimeException e) {
+				IllegalArgumentException iae = new IllegalArgumentException("Invalid DN chain: " + toString(dnChain));
+				iae.initCause(e);
+				throw iae;
+			}
+			try {
+				parsedDNPattern = parseDNchainPattern(pattern);
+			} catch (RuntimeException e) {
+				IllegalArgumentException iae = new IllegalArgumentException("Invalid match pattern: " + pattern);
+				iae.initCause(e);
+				throw iae;
+			}
+			return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 0);
+		}
+
+		private static String toString(List<?> dnChain) {
+			if (dnChain == null) {
+				return null;
+			}
+			StringBuffer sb = new StringBuffer();
+			for (Iterator<?> iChain = dnChain.iterator(); iChain.hasNext();) {
+				sb.append(iChain.next());
+				if (iChain.hasNext()) {
+					sb.append("; ");
+				}
+			}
+			return sb.toString();
+		}
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/InvalidSyntaxException.java b/osgi/framework/src/org/osgi/framework/InvalidSyntaxException.java
new file mode 100644
index 0000000..e2296c0
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/InvalidSyntaxException.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A Framework exception used to indicate that a filter string has an invalid
+ * syntax.
+ * 
+ * <p>
+ * An {@code InvalidSyntaxException} object indicates that a filter string
+ * parameter has an invalid syntax and cannot be parsed. See {@link Filter} for
+ * a description of the filter string syntax.
+ * 
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ * 
+ * @version $Id: 8820ca2db85b557cef8da09ee861249dfb5ee914 $
+ */
+
+public class InvalidSyntaxException extends Exception {
+	static final long		serialVersionUID	= -4295194420816491875L;
+	/**
+	 * The invalid filter string.
+	 */
+	private final String	filter;
+
+	/**
+	 * Creates an exception of type {@code InvalidSyntaxException}.
+	 * 
+	 * <p>
+	 * This method creates an {@code InvalidSyntaxException} object with the
+	 * specified message and the filter string which generated the exception.
+	 * 
+	 * @param msg The message.
+	 * @param filter The invalid filter string.
+	 */
+	public InvalidSyntaxException(String msg, String filter) {
+		super(message(msg, filter));
+		this.filter = filter;
+	}
+
+	/**
+	 * Creates an exception of type {@code InvalidSyntaxException}.
+	 * 
+	 * <p>
+	 * This method creates an {@code InvalidSyntaxException} object with the
+	 * specified message and the filter string which generated the exception.
+	 * 
+	 * @param msg The message.
+	 * @param filter The invalid filter string.
+	 * @param cause The cause of this exception.
+	 * @since 1.3
+	 */
+	public InvalidSyntaxException(String msg, String filter, Throwable cause) {
+		super(message(msg, filter), cause);
+		this.filter = filter;
+	}
+
+	/**
+	 * Return message string for super constructor.
+	 */
+	private static String message(String msg, String filter) {
+		if ((msg == null) || (filter == null) || msg.indexOf(filter) >= 0) {
+			return msg;
+		}
+		return msg + ": " + filter;
+	}
+
+	/**
+	 * Returns the filter string that generated the
+	 * {@code InvalidSyntaxException} object.
+	 * 
+	 * @return The invalid filter string.
+	 * @see BundleContext#getServiceReferences(Class, String)
+	 * @see BundleContext#getServiceReferences(String, String)
+	 * @see BundleContext#addServiceListener(ServiceListener,String)
+	 */
+	public String getFilter() {
+		return filter;
+	}
+
+	/**
+	 * Returns the cause of this exception or {@code null} if no cause was set.
+	 * 
+	 * @return The cause of this exception or {@code null} if no cause was set.
+	 * @since 1.3
+	 */
+	public Throwable getCause() {
+		return super.getCause();
+	}
+
+	/**
+	 * Initializes the cause of this exception to the specified value.
+	 * 
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
+	 * @since 1.3
+	 */
+	public Throwable initCause(Throwable cause) {
+		return super.initCause(cause);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/PackagePermission.java b/osgi/framework/src/org/osgi/framework/PackagePermission.java
new file mode 100644
index 0000000..62d0d8d
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/PackagePermission.java
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A bundle's authority to import or export a package.
+ * 
+ * <p>
+ * A package is a dot-separated string that defines a fully qualified Java
+ * package.
+ * <p>
+ * For example:
+ * 
+ * <pre>
+ * org.osgi.service.http
+ * </pre>
+ * 
+ * <p>
+ * {@code PackagePermission} has three actions: {@code exportonly},
+ * {@code import} and {@code export}. The {@code export} action, which is
+ * deprecated, implies the {@code import} action.
+ * 
+ * @ThreadSafe
+ * @version $Id: e993fbc36b6bff84182a8594af5af3cad8c4e2a3 $
+ */
+
+public final class PackagePermission extends BasicPermission {
+	static final long								serialVersionUID	= -5107705877071099135L;
+
+	/**
+	 * The action string {@code export}. The {@code export} action implies the
+	 * {@code import} action.
+	 * 
+	 * @deprecated Since 1.5. Use {@code exportonly} instead.
+	 */
+	public final static String						EXPORT				= "export";
+
+	/**
+	 * The action string {@code exportonly}. The {@code exportonly} action does
+	 * not imply the {@code import} action.
+	 * 
+	 * @since 1.5
+	 */
+	public final static String						EXPORTONLY			= "exportonly";
+
+	/**
+	 * The action string {@code import}.
+	 */
+	public final static String						IMPORT				= "import";
+
+	private final static int						ACTION_EXPORT		= 0x00000001;
+	private final static int						ACTION_IMPORT		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_EXPORT | ACTION_IMPORT;
+	final static int								ACTION_NONE			= 0;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions				= null;
+
+	/**
+	 * The bundle used by this PackagePermission.
+	 */
+	transient final Bundle							bundle;
+
+	/**
+	 * If this PackagePermission was constructed with a filter, this holds a
+	 * Filter matching object used to evaluate the filter in implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * Creates a new {@code PackagePermission} object.
+	 * 
+	 * <p>
+	 * The name is specified as a normal Java package name: a dot-separated
+	 * string. Wildcards may be used.
+	 * 
+	 * <pre>
+	 * name ::= <package name> | <package name ending in ".*"> | *
+	 * </pre>
+	 * 
+	 * Examples:
+	 * 
+	 * <pre>
+	 * org.osgi.service.http
+	 * javax.servlet.*
+	 * *
+	 * </pre>
+	 * 
+	 * For the {@code import} action, the name can also be a filter expression.
+	 * The filter gives access to the following attributes:
+	 * <ul>
+	 * <li>signer - A Distinguished Name chain used to sign the exporting
+	 * bundle. Wildcards in a DN are not matched according to the filter string
+	 * rules, but according to the rules defined for a DN chain.</li>
+	 * <li>location - The location of the exporting bundle.</li>
+	 * <li>id - The bundle ID of the exporting bundle.</li>
+	 * <li>name - The symbolic name of the exporting bundle.</li>
+	 * <li>package.name - The name of the requested package.</li>
+	 * </ul>
+	 * Filter attribute names are processed in a case sensitive manner.
+	 * 
+	 * <p>
+	 * Package Permissions are granted over all possible versions of a package.
+	 * 
+	 * A bundle that needs to export a package must have the appropriate
+	 * {@code PackagePermission} for that package; similarly, a bundle that
+	 * needs to import a package must have the appropriate
+	 * {@code PackagePermssion} for that package.
+	 * <p>
+	 * Permission is granted for both classes and resources.
+	 * 
+	 * @param name Package name or filter expression. A filter expression can
+	 *        only be specified if the specified action is {@code import}.
+	 * @param actions {@code exportonly},{@code import} (canonical order).
+	 * @throws IllegalArgumentException If the specified name is a filter
+	 *         expression and either the specified action is not {@code import}
+	 *         or the filter has an invalid syntax.
+	 */
+	public PackagePermission(String name, String actions) {
+		this(name, parseActions(actions));
+		if ((filter != null) && ((action_mask & ACTION_ALL) != ACTION_IMPORT)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
+		}
+	}
+
+	/**
+	 * Creates a new requested {@code PackagePermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code import}
+	 * action. {@code PackagePermission} objects created with this constructor
+	 * cannot be added to a {@code PackagePermission} permission collection.
+	 * 
+	 * @param name The name of the requested package to import.
+	 * @param exportingBundle The bundle exporting the requested package.
+	 * @param actions The action {@code import}.
+	 * @throws IllegalArgumentException If the specified action is not
+	 *         {@code import} or the name is a filter expression.
+	 * @since 1.5
+	 */
+	public PackagePermission(String name, Bundle exportingBundle, String actions) {
+		super(name);
+		setTransients(name, parseActions(actions));
+		this.bundle = exportingBundle;
+		if (exportingBundle == null) {
+			throw new IllegalArgumentException("bundle must not be null");
+		}
+		if (filter != null) {
+			throw new IllegalArgumentException("invalid name");
+		}
+		if ((action_mask & ACTION_ALL) != ACTION_IMPORT) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+	}
+
+	/**
+	 * Package private constructor used by PackagePermissionCollection.
+	 * 
+	 * @param name package name
+	 * @param mask action mask
+	 */
+	PackagePermission(String name, int mask) {
+		super(name);
+		setTransients(name, mask);
+		this.bundle = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask action mask
+	 */
+	private void setTransients(String name, int mask) {
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		action_mask = mask;
+		filter = parseFilter(name);
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 5 && (a[i - 5] == 'i' || a[i - 5] == 'I')
+					&& (a[i - 4] == 'm' || a[i - 4] == 'M')
+					&& (a[i - 3] == 'p' || a[i - 3] == 'P')
+					&& (a[i - 2] == 'o' || a[i - 2] == 'O')
+					&& (a[i - 1] == 'r' || a[i - 1] == 'R')
+					&& (a[i] == 't' || a[i] == 'T')) {
+				matchlen = 6;
+				mask |= ACTION_IMPORT;
+
+			} else
+				if (i >= 5 && (a[i - 5] == 'e' || a[i - 5] == 'E')
+						&& (a[i - 4] == 'x' || a[i - 4] == 'X')
+						&& (a[i - 3] == 'p' || a[i - 3] == 'P')
+						&& (a[i - 2] == 'o' || a[i - 2] == 'O')
+						&& (a[i - 1] == 'r' || a[i - 1] == 'R')
+						&& (a[i] == 't' || a[i] == 'T')) {
+					matchlen = 6;
+					mask |= ACTION_EXPORT | ACTION_IMPORT;
+
+				} else {
+					if (i >= 9 && (a[i - 9] == 'e' || a[i - 9] == 'E')
+							&& (a[i - 8] == 'x' || a[i - 8] == 'X')
+							&& (a[i - 7] == 'p' || a[i - 7] == 'P')
+							&& (a[i - 6] == 'o' || a[i - 6] == 'O')
+							&& (a[i - 5] == 'r' || a[i - 5] == 'R')
+							&& (a[i - 4] == 't' || a[i - 4] == 'T')
+							&& (a[i - 3] == 'o' || a[i - 3] == 'O')
+							&& (a[i - 2] == 'n' || a[i - 2] == 'N')
+							&& (a[i - 1] == 'l' || a[i - 1] == 'L')
+							&& (a[i] == 'y' || a[i] == 'Y')) {
+						matchlen = 10;
+						mask |= ACTION_EXPORT;
+
+					} else {
+						// parse error
+						throw new IllegalArgumentException("invalid permission: " + actions);
+					}
+				}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfimport". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle. If the specified filterString is not a
+	 *         filter expression, then {@code null} is returned.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		filterString = filterString.trim();
+		if (filterString.charAt(0) != '(') {
+			return null;
+		}
+
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if the specified permission is implied by this object.
+	 * 
+	 * <p>
+	 * This method checks that the package name of the target is implied by the
+	 * package name of this object. The list of {@code PackagePermission}
+	 * actions must either match or allow for the list of the target object to
+	 * imply the target {@code PackagePermission} action.
+	 * <p>
+	 * The permission to export a package implies the permission to import the
+	 * named package.
+	 * 
+	 * <pre>
+	 * x.y.*,"export" -> x.y.z,"export" is true
+	 * *,"import" -> x.y, "import"      is true
+	 * *,"export" -> x.y, "import"      is true
+	 * x.y,"export" -> x.y.z, "export"  is false
+	 * </pre>
+	 * 
+	 * @param p The requested permission.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof PackagePermission)) {
+			return false;
+		}
+		PackagePermission requested = (PackagePermission) p;
+		if (bundle != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested PackagePermission which has already be
+	 *        validated as a proper argument. The requested PackagePermission
+	 *        must not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(PackagePermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+		/* Get filter if any */
+		Filter f = filter;
+		if (f == null) {
+			return super.implies(requested);
+		}
+		return f.matches(requested.getProperties());
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * {@code PackagePermission} actions.
+	 * 
+	 * <p>
+	 * Always returns present {@code PackagePermission} actions in the following
+	 * order: {@code EXPORTONLY},{@code IMPORT}.
+	 * 
+	 * @return Canonical string representation of the {@code PackagePermission}
+	 *         actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+
+			int mask = action_mask;
+			if ((mask & ACTION_EXPORT) == ACTION_EXPORT) {
+				sb.append(EXPORTONLY);
+				comma = true;
+			}
+
+			if ((mask & ACTION_IMPORT) == ACTION_IMPORT) {
+				if (comma)
+					sb.append(',');
+				sb.append(IMPORT);
+			}
+
+			actions = result = sb.toString();
+		}
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code PackagePermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new PackagePermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two {@code PackagePermission} objects.
+	 * 
+	 * This method checks that specified package has the same package name and
+	 * {@code PackagePermission} actions as this {@code PackagePermission}
+	 * object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code PackagePermission} object.
+	 * @return {@code true} if {@code obj} is a {@code PackagePermission}, and
+	 *         has the same package name and actions as this
+	 *         {@code PackagePermission} object; {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof PackagePermission)) {
+			return false;
+		}
+
+		PackagePermission pp = (PackagePermission) obj;
+
+		return (action_mask == pp.action_mask) && getName().equals(pp.getName()) && ((bundle == pp.bundle) || ((bundle != null) && bundle.equals(pp.bundle)));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (bundle != null) {
+			h = 31 * h + bundle.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission object to a
+	 * stream. The actions are serialized, and the superclass takes care of the
+	 * name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		if (bundle != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(getName(), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code <@link PackagePermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
+	 * 
+	 * @return a map of properties for this permission.
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		final Map<String, Object> map = new HashMap<String, Object>(5);
+		map.put("package.name", getName());
+		if (bundle != null) {
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				public Object run() {
+					map.put("id", new Long(bundle.getBundleId()));
+					map.put("location", bundle.getLocation());
+					String name = bundle.getSymbolicName();
+					if (name != null) {
+						map.put("name", name);
+					}
+					SignerProperty signer = new SignerProperty(bundle);
+					if (signer.isBundleSigned()) {
+						map.put("signer", signer);
+					}
+					return null;
+				}
+			});
+		}
+		return properties = map;
+	}
+}
+
+/**
+ * Stores a set of {@code PackagePermission} permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class PackagePermissionCollection extends PermissionCollection {
+	static final long									serialVersionUID	= -3350758995234427603L;
+	/**
+	 * Table of permissions with names.
+	 * 
+	 * @GuardedBy this
+	 */
+	private transient Map<String, PackagePermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean										all_allowed;
+
+	/**
+	 * Table of permissions with filter expressions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, PackagePermission>				filterPermissions;
+
+	/**
+	 * Create an empty PackagePermissions object.
+	 */
+	public PackagePermissionCollection() {
+		permissions = new HashMap<String, PackagePermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The {@code PackagePermission} object to add.
+	 * @throws IllegalArgumentException If the specified permission is not a
+	 *         {@code PackagePermission} instance or was constructed with a
+	 *         Bundle object.
+	 * @throws SecurityException If this {@code PackagePermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof PackagePermission)) {
+			throw new IllegalArgumentException("invalid permission: " + permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+		}
+
+		final PackagePermission pp = (PackagePermission) permission;
+		if (pp.bundle != null) {
+			throw new IllegalArgumentException("cannot add to collection: " + pp);
+		}
+
+		final String name = pp.getName();
+		final Filter f = pp.filter;
+		synchronized (this) {
+			/* select the bucket for the permission */
+			Map<String, PackagePermission> pc;
+			if (f != null) {
+				pc = filterPermissions;
+				if (pc == null) {
+					filterPermissions = pc = new HashMap<String, PackagePermission>();
+				}
+			} else {
+				pc = permissions;
+			}
+
+			final PackagePermission existing = pc.get(name);
+			if (existing != null) {
+				final int oldMask = existing.action_mask;
+				final int newMask = pp.action_mask;
+				if (oldMask != newMask) {
+					pc.put(name, new PackagePermission(name, oldMask | newMask));
+
+				}
+			} else {
+				pc.put(name, pp);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if the specified permissions implies the permissions expressed
+	 * in {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare with this
+	 *        {@code PackagePermission} object.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof PackagePermission)) {
+			return false;
+		}
+		final PackagePermission requested = (PackagePermission) permission;
+		/* if requested permission has a filter, then it is an invalid argument */
+		if (requested.filter != null) {
+			return false;
+		}
+		String requestedName = requested.getName();
+		final int desired = requested.action_mask;
+		int effective = PackagePermission.ACTION_NONE;
+
+		Collection<PackagePermission> perms;
+		synchronized (this) {
+			Map<String, PackagePermission> pc = permissions;
+			PackagePermission pp;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				pp = pc.get("*");
+				if (pp != null) {
+					effective |= pp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+			/*
+			 * strategy: Check for full match first. Then work our way up the
+			 * name looking for matches on a.b.*
+			 */
+			pp = pc.get(requestedName);
+			if (pp != null) {
+				/* we have a direct hit! */
+				effective |= pp.action_mask;
+				if ((effective & desired) == desired) {
+					return true;
+				}
+			}
+			/* work our way up the tree... */
+			int last;
+			int offset = requestedName.length() - 1;
+			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+				requestedName = requestedName.substring(0, last + 1) + "*";
+				pp = pc.get(requestedName);
+				if (pp != null) {
+					effective |= pp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+				offset = last - 1;
+			}
+			/*
+			 * we don't have to check for "*" as it was already checked before
+			 * we were called.
+			 */
+			pc = filterPermissions;
+			if (pc == null) {
+				return false;
+			}
+			perms = pc.values();
+		}
+		/* iterate one by one over filteredPermissions */
+		for (PackagePermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns an enumeration of all {@code PackagePermission} objects in the
+	 * container.
+	 * 
+	 * @return Enumeration of all {@code PackagePermission} objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		Map<String, PackagePermission> pc = filterPermissions;
+		if (pc != null) {
+			all.addAll(pc.values());
+		}
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
+			new ObjectStreamField("filterPermissions", HashMap.class)	};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, PackagePermission> hashtable = new Hashtable<String, PackagePermission>(permissions);
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", hashtable);
+		pfields.put("all_allowed", all_allowed);
+		pfields.put("filterPermissions", filterPermissions);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		Hashtable<String, PackagePermission> hashtable = (Hashtable<String, PackagePermission>) gfields.get("permissions", null);
+		permissions = new HashMap<String, PackagePermission>(hashtable);
+		all_allowed = gfields.get("all_allowed", false);
+		HashMap<String, PackagePermission> fp = (HashMap<String, PackagePermission>) gfields.get("filterPermissions", null);
+		filterPermissions = fp;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServiceEvent.java b/osgi/framework/src/org/osgi/framework/ServiceEvent.java
new file mode 100644
index 0000000..2a59fe8
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServiceEvent.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.Dictionary;
+import java.util.EventObject;
+
+/**
+ * An event from the Framework describing a service lifecycle change.
+ * <p>
+ * {@code ServiceEvent} objects are delivered to {@code ServiceListener}s and
+ * {@code AllServiceListener}s when a change occurs in this service's lifecycle.
+ * A type code is used to identify the event type for future extendability.
+ * 
+ * <p>
+ * OSGi Alliance reserves the right to extend the set of types.
+ * 
+ * @Immutable
+ * @see ServiceListener
+ * @see AllServiceListener
+ * @version $Id: 49e34e0ad5564d6f4ca0ab0053b272c22b9fb917 $
+ */
+
+public class ServiceEvent extends EventObject {
+	static final long					serialVersionUID	= 8792901483909409299L;
+	/**
+	 * Reference to the service that had a change occur in its lifecycle.
+	 */
+	private final ServiceReference<?>	reference;
+
+	/**
+	 * Type of service lifecycle change.
+	 */
+	private final int					type;
+
+	/**
+	 * This service has been registered.
+	 * <p>
+	 * This event is synchronously delivered <strong>after</strong> the service
+	 * has been registered with the Framework.
+	 * 
+	 * @see BundleContext#registerService(String[],Object,Dictionary)
+	 */
+	public final static int				REGISTERED			= 0x00000001;
+
+	/**
+	 * The properties of a registered service have been modified.
+	 * <p>
+	 * This event is synchronously delivered <strong>after</strong> the service
+	 * properties have been modified.
+	 * 
+	 * @see ServiceRegistration#setProperties(Dictionary)
+	 */
+	public final static int				MODIFIED			= 0x00000002;
+
+	/**
+	 * This service is in the process of being unregistered.
+	 * <p>
+	 * This event is synchronously delivered <strong>before</strong> the service
+	 * has completed unregistering.
+	 * 
+	 * <p>
+	 * If a bundle is using a service that is {@code UNREGISTERING}, the bundle
+	 * should release its use of the service when it receives this event. If the
+	 * bundle does not release its use of the service when it receives this
+	 * event, the Framework will automatically release the bundle's use of the
+	 * service while completing the service unregistration operation.
+	 * 
+	 * @see ServiceRegistration#unregister()
+	 * @see BundleContext#ungetService(ServiceReference)
+	 */
+	public final static int				UNREGISTERING		= 0x00000004;
+
+	/**
+	 * The properties of a registered service have been modified and the new
+	 * properties no longer match the listener's filter.
+	 * <p>
+	 * This event is synchronously delivered <strong>after</strong> the service
+	 * properties have been modified. This event is only delivered to listeners
+	 * which were added with a non-{@code null} filter where the filter matched
+	 * the service properties prior to the modification but the filter does not
+	 * match the modified service properties.
+	 * 
+	 * @see ServiceRegistration#setProperties(Dictionary)
+	 * @since 1.5
+	 */
+	public final static int				MODIFIED_ENDMATCH	= 0x00000008;
+
+	/**
+	 * Creates a new service event object.
+	 * 
+	 * @param type The event type.
+	 * @param reference A {@code ServiceReference} object to the service that
+	 *        had a lifecycle change.
+	 */
+	public ServiceEvent(int type, ServiceReference<?> reference) {
+		super(reference);
+		this.reference = reference;
+		this.type = type;
+	}
+
+	/**
+	 * Returns a reference to the service that had a change occur in its
+	 * lifecycle.
+	 * <p>
+	 * This reference is the source of the event.
+	 * 
+	 * @return Reference to the service that had a lifecycle change.
+	 */
+	public ServiceReference<?> getServiceReference() {
+		return reference;
+	}
+
+	/**
+	 * Returns the type of event. The event type values are:
+	 * <ul>
+	 * <li>{@link #REGISTERED}</li>
+	 * <li>{@link #MODIFIED}</li>
+	 * <li>{@link #MODIFIED_ENDMATCH}</li>
+	 * <li>{@link #UNREGISTERING}</li>
+	 * </ul>
+	 * 
+	 * @return Type of service lifecycle change.
+	 */
+
+	public int getType() {
+		return type;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServiceException.java b/osgi/framework/src/org/osgi/framework/ServiceException.java
new file mode 100644
index 0000000..de90784
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServiceException.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A service exception used to indicate that a service problem occurred.
+ * 
+ * <p>
+ * A {@code ServiceException} object is created by the Framework or service
+ * implementation to denote an exception condition in the service. A type code
+ * is used to identify the exception type for future extendability. Service
+ * implementations may also create subclasses of {@code ServiceException}. When
+ * subclassing, the subclass should set the type to {@link #SUBCLASSED} to
+ * indicate that {@code ServiceException} has been subclassed.
+ * 
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ * 
+ * @version $Id: 9f763412635f59585bb615cbc449fc7ab72b7103 $
+ * @since 1.5
+ */
+
+public class ServiceException extends RuntimeException {
+	static final long		serialVersionUID	= 3038963223712959631L;
+
+	/**
+	 * Type of service exception.
+	 */
+	private final int		type;
+
+	/**
+	 * No exception type is unspecified.
+	 */
+	public static final int	UNSPECIFIED			= 0;
+	/**
+	 * The service has been unregistered.
+	 */
+	public static final int	UNREGISTERED		= 1;
+	/**
+	 * The service factory produced an invalid service object.
+	 */
+	public static final int	FACTORY_ERROR		= 2;
+	/**
+	 * The service factory threw an exception.
+	 */
+	public static final int	FACTORY_EXCEPTION	= 3;
+	/**
+	 * The exception is a subclass of ServiceException. The subclass should be
+	 * examined for the type of the exception.
+	 */
+	public static final int	SUBCLASSED			= 4;
+	/**
+	 * An error occurred invoking a remote service.
+	 */
+	public static final int	REMOTE				= 5;
+	/**
+	 * The service factory resulted in a recursive call to itself for the
+	 * requesting bundle.
+	 * 
+	 * @since 1.6
+	 */
+	public static final int	FACTORY_RECURSION	= 6;
+
+	/**
+	 * Creates a {@code ServiceException} with the specified message and
+	 * exception cause.
+	 * 
+	 * @param msg The associated message.
+	 * @param cause The cause of this exception.
+	 */
+	public ServiceException(String msg, Throwable cause) {
+		this(msg, UNSPECIFIED, cause);
+	}
+
+	/**
+	 * Creates a {@code ServiceException} with the specified message.
+	 * 
+	 * @param msg The message.
+	 */
+	public ServiceException(String msg) {
+		this(msg, UNSPECIFIED);
+	}
+
+	/**
+	 * Creates a {@code ServiceException} with the specified message, type and
+	 * exception cause.
+	 * 
+	 * @param msg The associated message.
+	 * @param type The type for this exception.
+	 * @param cause The cause of this exception.
+	 */
+	public ServiceException(String msg, int type, Throwable cause) {
+		super(msg, cause);
+		this.type = type;
+	}
+
+	/**
+	 * Creates a {@code ServiceException} with the specified message and type.
+	 * 
+	 * @param msg The message.
+	 * @param type The type for this exception.
+	 */
+	public ServiceException(String msg, int type) {
+		super(msg);
+		this.type = type;
+	}
+
+	/**
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the type
+	 * was unspecified or unknown.
+	 * 
+	 * @return The type of this exception.
+	 */
+	public int getType() {
+		return type;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServiceFactory.java b/osgi/framework/src/org/osgi/framework/ServiceFactory.java
new file mode 100644
index 0000000..4b52fee
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServiceFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * Allows services to provide customized service objects in the OSGi
+ * environment.
+ * 
+ * <p>
+ * When registering a service, a {@code ServiceFactory} object can be used
+ * instead of a service object, so that the bundle developer can gain control of
+ * the specific service object granted to a bundle that is using the service.
+ * 
+ * <p>
+ * When this happens, the {@code BundleContext.getService(ServiceReference)}
+ * method calls the {@code ServiceFactory.getService} method to create a service
+ * object specifically for the requesting bundle. The service object returned by
+ * the {@code ServiceFactory} is cached by the Framework until the bundle
+ * releases its use of the service.
+ * 
+ * <p>
+ * When the bundle's use count for the service is decremented to zero (including
+ * the bundle stopping or the service being unregistered), the
+ * {@code ServiceFactory.ungetService} method is called.
+ * 
+ * <p>
+ * {@code ServiceFactory} objects are only used by the Framework and are not
+ * made available to other bundles in the OSGi environment. The Framework may
+ * concurrently call a {@code ServiceFactory}.
+ * 
+ * @param <S> Type of Service
+ * @see BundleContext#getService(ServiceReference)
+ * @ThreadSafe
+ * @version $Id: 535776e702ec5ace54f577218ff8f7920741558b $
+ */
+
+public interface ServiceFactory<S> {
+	/**
+	 * Creates a new service object.
+	 * 
+	 * <p>
+	 * The Framework invokes this method the first time the specified
+	 * {@code bundle} requests a service object using the
+	 * {@code BundleContext.getService(ServiceReference)} method. The service
+	 * factory can then return a specific service object for each bundle.
+	 * 
+	 * <p>
+	 * The Framework must check that the returned service object is valid. If
+	 * the returned service object is {@code null} or is not an
+	 * {@code instanceof} all the classes named when the service was registered,
+	 * a framework event of type {@link FrameworkEvent#ERROR} is fired
+	 * containing a service exception of type
+	 * {@link ServiceException#FACTORY_ERROR} and {@code null} is returned to
+	 * the bundle. If this method throws an exception, a framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+	 * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
+	 * as the cause and {@code null} is returned to the bundle. If this method
+	 * is recursively called for the specified bundle, a framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+	 * type {@link ServiceException#FACTORY_RECURSION} and {@code null} is
+	 * returned to the bundle.
+	 * 
+	 * <p>
+	 * The Framework caches the valid service object and will return the same
+	 * service object on any future call to {@code BundleContext.getService} for
+	 * the specified bundle. This means the Framework must not allow this method
+	 * to be concurrently called for the specified bundle.
+	 * 
+	 * @param bundle The bundle requesting the service.
+	 * @param registration The {@code ServiceRegistration} object for the
+	 *        requested service.
+	 * @return A service object that <strong>must</strong> be an instance of all
+	 *         the classes named when the service was registered.
+	 * @see BundleContext#getService(ServiceReference)
+	 */
+	public S getService(Bundle bundle, ServiceRegistration<S> registration);
+
+	/**
+	 * Releases a service object.
+	 * 
+	 * <p>
+	 * The Framework invokes this method when a service has been released by a
+	 * bundle. The service object may then be destroyed.
+	 * 
+	 * <p>
+	 * If this method throws an exception, a framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+	 * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
+	 * as the cause.
+	 * 
+	 * @param bundle The bundle releasing the service.
+	 * @param registration The {@code ServiceRegistration} object for the
+	 *        service being released.
+	 * @param service The service object returned by a previous call to the
+	 *        {@link #getService(Bundle, ServiceRegistration) getService}
+	 *        method.
+	 * @see BundleContext#ungetService(ServiceReference)
+	 */
+	public void ungetService(Bundle bundle, ServiceRegistration<S> registration, S service);
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServiceListener.java b/osgi/framework/src/org/osgi/framework/ServiceListener.java
new file mode 100644
index 0000000..839c1bc
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServiceListener.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.EventListener;
+
+/**
+ * A {@code ServiceEvent} listener. {@code ServiceListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
+ * {@code ServiceEvent} is fired, it is synchronously delivered to a
+ * {@code ServiceListener}. The Framework may deliver {@code ServiceEvent}
+ * objects to a {@code ServiceListener} out of order and may concurrently call
+ * and/or reenter a {@code ServiceListener}.
+ * 
+ * <p>
+ * A {@code ServiceListener} object is registered with the Framework using the
+ * {@code BundleContext.addServiceListener} method. {@code ServiceListener}
+ * objects are called with a {@code ServiceEvent} object when a service is
+ * registered, modified, or is in the process of unregistering.
+ * 
+ * <p>
+ * {@code ServiceEvent} object delivery to {@code ServiceListener} objects is
+ * filtered by the filter specified when the listener was registered. If the
+ * Java Runtime Environment supports permissions, then additional filtering is
+ * done. {@code ServiceEvent} objects are only delivered to the listener if the
+ * bundle which defines the listener object's class has the appropriate
+ * {@code ServicePermission} to get the service using at least one of the named
+ * classes under which the service was registered.
+ * 
+ * <p>
+ * {@code ServiceEvent} object delivery to {@code ServiceListener} objects is
+ * further filtered according to package sources as defined in
+ * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+ * 
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @ThreadSafe
+ * @version $Id: 601dfda6183ab7f18cd3916958a39734ea141c25 $
+ */
+
+public interface ServiceListener extends EventListener {
+	/**
+	 * Receives notification that a service has had a lifecycle change.
+	 * 
+	 * @param event The {@code ServiceEvent} object.
+	 */
+	public void serviceChanged(ServiceEvent event);
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServicePermission.java b/osgi/framework/src/org/osgi/framework/ServicePermission.java
new file mode 100644
index 0000000..23ecfba
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServicePermission.java
@@ -0,0 +1,910 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A bundle's authority to register or get a service.
+ * <ul>
+ * <li>The {@code register} action allows a bundle to register a service on the
+ * specified names.
+ * <li>The {@code get} action allows a bundle to detect a service and get it.
+ * </ul>
+ * Permission to get a service is required in order to detect events regarding
+ * the service. Untrusted bundles should not be able to detect the presence of
+ * certain services unless they have the appropriate {@code ServicePermission}
+ * to get the specific service.
+ * 
+ * @ThreadSafe
+ * @version $Id: 96438ad164d7f0f4273787226298bf8208cf0034 $
+ */
+
+public final class ServicePermission extends BasicPermission {
+	static final long								serialVersionUID	= -7662148639076511574L;
+	/**
+	 * The action string {@code get}.
+	 */
+	public final static String						GET					= "get";
+	/**
+	 * The action string {@code register}.
+	 */
+	public final static String						REGISTER			= "register";
+
+	private final static int						ACTION_GET			= 0x00000001;
+	private final static int						ACTION_REGISTER		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_GET | ACTION_REGISTER;
+	final static int								ACTION_NONE			= 0;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions				= null;
+
+	/**
+	 * The service used by this ServicePermission. Must be null if not
+	 * constructed with a service.
+	 */
+	transient final ServiceReference<?>				service;
+
+	/**
+	 * The object classes for this ServicePermission. Must be null if not
+	 * constructed with a service.
+	 */
+	transient final String[]						objectClass;
+
+	/**
+	 * If this ServicePermission was constructed with a filter, this holds a
+	 * Filter matching object used to evaluate the filter in implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * True if constructed with a name and the name is "*" or ends with ".*".
+	 */
+	private transient boolean						wildcard;
+
+	/**
+	 * If constructed with a name and the name ends with ".*", this contains the
+	 * name without the final "*".
+	 */
+	private transient String						prefix;
+
+	/**
+	 * Create a new ServicePermission.
+	 * 
+	 * <p>
+	 * The name of the service is specified as a fully qualified class name.
+	 * Wildcards may be used.
+	 * 
+	 * <pre>
+	 * name ::= <class name> | <class name ending in ".*"> | *
+	 * </pre>
+	 * 
+	 * Examples:
+	 * 
+	 * <pre>
+	 * org.osgi.service.http.HttpService
+	 * org.osgi.service.http.*
+	 * *
+	 * </pre>
+	 * 
+	 * For the {@code get} action, the name can also be a filter expression. The
+	 * filter gives access to the service properties as well as the following
+	 * attributes:
+	 * <ul>
+	 * <li>signer - A Distinguished Name chain used to sign the bundle
+	 * publishing the service. Wildcards in a DN are not matched according to
+	 * the filter string rules, but according to the rules defined for a DN
+	 * chain.</li>
+	 * <li>location - The location of the bundle publishing the service.</li>
+	 * <li>id - The bundle ID of the bundle publishing the service.</li>
+	 * <li>name - The symbolic name of the bundle publishing the service.</li>
+	 * </ul>
+	 * Since the above attribute names may conflict with service property names
+	 * used by a service, you can prefix an attribute name with '@' in the
+	 * filter expression to match against the service property and not one of
+	 * the above attributes. Filter attribute names are processed in a case
+	 * sensitive manner unless the attribute references a service property.
+	 * Service properties names are case insensitive.
+	 * 
+	 * <p>
+	 * There are two possible actions: {@code get} and {@code register}. The
+	 * {@code get} permission allows the owner of this permission to obtain a
+	 * service with this name. The {@code register} permission allows the bundle
+	 * to register a service under that name.
+	 * 
+	 * @param name The service class name
+	 * @param actions {@code get},{@code register} (canonical order)
+	 * @throws IllegalArgumentException If the specified name is a filter
+	 *         expression and either the specified action is not {@code get} or
+	 *         the filter has an invalid syntax.
+	 */
+	public ServicePermission(String name, String actions) {
+		this(name, parseActions(actions));
+		if ((filter != null) && ((action_mask & ACTION_ALL) != ACTION_GET)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
+		}
+	}
+
+	/**
+	 * Creates a new requested {@code ServicePermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code get}
+	 * action. {@code ServicePermission} objects created with this constructor
+	 * cannot be added to a {@code ServicePermission} permission collection.
+	 * 
+	 * @param reference The requested service.
+	 * @param actions The action {@code get}.
+	 * @throws IllegalArgumentException If the specified action is not
+	 *         {@code get} or reference is {@code null}.
+	 * @since 1.5
+	 */
+	public ServicePermission(ServiceReference<?> reference, String actions) {
+		super(createName(reference));
+		setTransients(null, parseActions(actions));
+		this.service = reference;
+		this.objectClass = (String[]) reference.getProperty(Constants.OBJECTCLASS);
+		if ((action_mask & ACTION_ALL) != ACTION_GET) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+	}
+
+	/**
+	 * Create a permission name from a ServiceReference
+	 * 
+	 * @param reference ServiceReference to use to create permission name.
+	 * @return permission name.
+	 */
+	private static String createName(ServiceReference<?> reference) {
+		if (reference == null) {
+			throw new IllegalArgumentException("reference must not be null");
+		}
+		StringBuffer sb = new StringBuffer("(service.id=");
+		sb.append(reference.getProperty(Constants.SERVICE_ID));
+		sb.append(")");
+		return sb.toString();
+	}
+
+	/**
+	 * Package private constructor used by ServicePermissionCollection.
+	 * 
+	 * @param name class name
+	 * @param mask action mask
+	 */
+	ServicePermission(String name, int mask) {
+		super(name);
+		setTransients(parseFilter(name), mask);
+		this.service = null;
+		this.objectClass = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask action mask
+	 */
+	private void setTransients(Filter f, int mask) {
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		action_mask = mask;
+		filter = f;
+		if (f == null) {
+			String name = getName();
+			int l = name.length();
+			/* if "*" or endsWith ".*" */
+			wildcard = ((name.charAt(l - 1) == '*') && ((l == 1) || (name.charAt(l - 2) == '.')));
+			if (wildcard && (l > 1)) {
+				prefix = name.substring(0, l - 1);
+			}
+		}
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
+					&& (a[i - 1] == 'e' || a[i - 1] == 'E')
+					&& (a[i] == 't' || a[i] == 'T')) {
+				matchlen = 3;
+				mask |= ACTION_GET;
+
+			} else
+				if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
+						&& (a[i - 6] == 'e' || a[i - 6] == 'E')
+						&& (a[i - 5] == 'g' || a[i - 5] == 'G')
+						&& (a[i - 4] == 'i' || a[i - 4] == 'I')
+						&& (a[i - 3] == 's' || a[i - 3] == 'S')
+						&& (a[i - 2] == 't' || a[i - 2] == 'T')
+						&& (a[i - 1] == 'e' || a[i - 1] == 'E')
+						&& (a[i] == 'r' || a[i] == 'R')) {
+					matchlen = 8;
+					mask |= ACTION_REGISTER;
+
+				} else {
+					// parse error
+					throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfregister". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException("invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle. If the specified filterString is not a
+	 *         filter expression, then {@code null} is returned.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		filterString = filterString.trim();
+		if (filterString.charAt(0) != '(') {
+			return null;
+		}
+
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if a {@code ServicePermission} object "implies" the specified
+	 * permission.
+	 * 
+	 * @param p The target permission to check.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof ServicePermission)) {
+			return false;
+		}
+		ServicePermission requested = (ServicePermission) p;
+		if (service != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested ServicePermission which has already be
+	 *        validated as a proper argument. The requested ServicePermission
+	 *        must not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(ServicePermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+		/* we have name of "*" */
+		if (wildcard && (prefix == null)) {
+			return true;
+		}
+		/* if we have a filter */
+		Filter f = filter;
+		if (f != null) {
+			return f.matches(requested.getProperties());
+		}
+		/* if requested permission not created with ServiceReference */
+		String[] requestedNames = requested.objectClass;
+		if (requestedNames == null) {
+			return super.implies(requested);
+		}
+		/* requested permission created with ServiceReference */
+		if (wildcard) {
+			int pl = prefix.length();
+			for (int i = 0, l = requestedNames.length; i < l; i++) {
+				String requestedName = requestedNames[i];
+				if ((requestedName.length() > pl) && requestedName.startsWith(prefix)) {
+					return true;
+				}
+			}
+		} else {
+			String name = getName();
+			for (int i = 0, l = requestedNames.length; i < l; i++) {
+				if (requestedNames[i].equals(name)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the canonical string representation of the actions. Always
+	 * returns present actions in the following order: {@code get},
+	 * {@code register}.
+	 * 
+	 * @return The canonical string representation of the actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+
+			int mask = action_mask;
+			if ((mask & ACTION_GET) == ACTION_GET) {
+				sb.append(GET);
+				comma = true;
+			}
+
+			if ((mask & ACTION_REGISTER) == ACTION_REGISTER) {
+				if (comma)
+					sb.append(',');
+				sb.append(REGISTER);
+			}
+
+			actions = result = sb.toString();
+		}
+
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object for storing
+	 * {@code ServicePermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object suitable for storing
+	 *         {@code ServicePermission} objects.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new ServicePermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two ServicePermission objects.
+	 * 
+	 * Checks that specified object has the same class name and action as this
+	 * {@code ServicePermission}.
+	 * 
+	 * @param obj The object to test for equality.
+	 * @return true if obj is a {@code ServicePermission}, and has the same
+	 *         class name and actions as this {@code ServicePermission} object;
+	 *         {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof ServicePermission)) {
+			return false;
+		}
+
+		ServicePermission sp = (ServicePermission) obj;
+
+		return (action_mask == sp.action_mask) && getName().equals(sp.getName()) && ((service == sp.service) || ((service != null) && (service.compareTo(sp.service) == 0)));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (service != null) {
+			h = 31 * h + service.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission to a stream.
+	 * The actions are serialized, and the superclass takes care of the name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+		if (service != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(parseFilter(getName()), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code <@link ServicePermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
+	 * 
+	 * @return a map of properties for this permission.
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		if (service == null) {
+			result = new HashMap<String, Object>(1);
+			result.put(Constants.OBJECTCLASS, new String[] {getName()});
+			return properties = result;
+		}
+		final Map<String, Object> props = new HashMap<String, Object>(4);
+		final Bundle bundle = service.getBundle();
+		if (bundle != null) {
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				public Object run() {
+					props.put("id", new Long(bundle.getBundleId()));
+					props.put("location", bundle.getLocation());
+					String name = bundle.getSymbolicName();
+					if (name != null) {
+						props.put("name", name);
+					}
+					SignerProperty signer = new SignerProperty(bundle);
+					if (signer.isBundleSigned()) {
+						props.put("signer", signer);
+					}
+					return null;
+				}
+			});
+		}
+		return properties = new Properties(props, service);
+	}
+
+	static private final class Properties extends AbstractMap<String, Object> {
+		private final Map<String, Object>							properties;
+		private final ServiceReference<?>							service;
+		private transient volatile Set<Map.Entry<String, Object>>	entries;
+
+		Properties(Map<String, Object> properties, ServiceReference<?> service) {
+			this.properties = properties;
+			this.service = service;
+			entries = null;
+		}
+
+		public Object get(Object k) {
+			if (!(k instanceof String)) {
+				return null;
+			}
+			String key = (String) k;
+			if (key.charAt(0) == '@') {
+				return service.getProperty(key.substring(1));
+			}
+			Object value = properties.get(key);
+			if (value != null) { // fall back to service properties
+				return value;
+			}
+			return service.getProperty(key);
+		}
+
+		public Set<Map.Entry<String, Object>> entrySet() {
+			if (entries != null) {
+				return entries;
+			}
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(properties.entrySet());
+			add: for (String key : service.getPropertyKeys()) {
+				for (String k : properties.keySet()) {
+					if (key.equalsIgnoreCase(k)) {
+						continue add;
+					}
+				}
+				all.add(new Entry(key, service.getProperty(key)));
+			}
+			return entries = Collections.unmodifiableSet(all);
+		}
+
+		static private final class Entry implements Map.Entry<String, Object> {
+			private final String	k;
+			private final Object	v;
+
+			Entry(String key, Object value) {
+				this.k = key;
+				this.v = value;
+			}
+
+			public String getKey() {
+				return k;
+			}
+
+			public Object getValue() {
+				return v;
+			}
+
+			public Object setValue(Object value) {
+				throw new UnsupportedOperationException();
+			}
+
+			public String toString() {
+				return k + "=" + v;
+			}
+
+			public int hashCode() {
+				return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
+			}
+
+			public boolean equals(Object obj) {
+				if (obj == this) {
+					return true;
+				}
+				if (!(obj instanceof Map.Entry)) {
+					return false;
+				}
+				Map.Entry<?, ?> e = (Map.Entry<?, ?>) obj;
+				final Object key = e.getKey();
+				if ((k == key) || ((k != null) && k.equals(key))) {
+					final Object value = e.getValue();
+					if ((v == value) || ((v != null) && v.equals(value))) {
+						return true;
+					}
+				}
+				return false;
+			}
+		}
+	}
+}
+
+/**
+ * Stores a set of ServicePermission permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class ServicePermissionCollection extends PermissionCollection {
+	static final long									serialVersionUID	= 662615640374640621L;
+	/**
+	 * Table of permissions.
+	 * 
+	 * @GuardedBy this
+	 */
+	private transient Map<String, ServicePermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean										all_allowed;
+
+	/**
+	 * Table of permissions with filter expressions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, ServicePermission>				filterPermissions;
+
+	/**
+	 * Creates an empty ServicePermissions object.
+	 */
+	public ServicePermissionCollection() {
+		permissions = new HashMap<String, ServicePermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The Permission object to add.
+	 * @throws IllegalArgumentException If the specified permission is not a
+	 *         ServicePermission object.
+	 * @throws SecurityException If this {@code ServicePermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof ServicePermission)) {
+			throw new IllegalArgumentException("invalid permission: " + permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+		}
+
+		final ServicePermission sp = (ServicePermission) permission;
+		if (sp.service != null) {
+			throw new IllegalArgumentException("cannot add to collection: " + sp);
+		}
+
+		final String name = sp.getName();
+		final Filter f = sp.filter;
+		synchronized (this) {
+			/* select the bucket for the permission */
+			Map<String, ServicePermission> pc;
+			if (f != null) {
+				pc = filterPermissions;
+				if (pc == null) {
+					filterPermissions = pc = new HashMap<String, ServicePermission>();
+				}
+			} else {
+				pc = permissions;
+			}
+			final ServicePermission existing = pc.get(name);
+
+			if (existing != null) {
+				final int oldMask = existing.action_mask;
+				final int newMask = sp.action_mask;
+				if (oldMask != newMask) {
+					pc.put(name, new ServicePermission(name, oldMask | newMask));
+				}
+			} else {
+				pc.put(name, sp);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if a set of permissions implies the permissions expressed in
+	 * {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof ServicePermission)) {
+			return false;
+		}
+		final ServicePermission requested = (ServicePermission) permission;
+		/* if requested permission has a filter, then it is an invalid argument */
+		if (requested.filter != null) {
+			return false;
+		}
+
+		int effective = ServicePermission.ACTION_NONE;
+		Collection<ServicePermission> perms;
+		synchronized (this) {
+			final int desired = requested.action_mask;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				ServicePermission sp = permissions.get("*");
+				if (sp != null) {
+					effective |= sp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+
+			String[] requestedNames = requested.objectClass;
+			/* if requested permission not created with ServiceReference */
+			if (requestedNames == null) {
+				effective |= effective(requested.getName(), desired, effective);
+				if ((effective & desired) == desired) {
+					return true;
+				}
+			}
+			/* requested permission created with ServiceReference */
+			else {
+				for (int i = 0, l = requestedNames.length; i < l; i++) {
+					if ((effective(requestedNames[i], desired, effective) & desired) == desired) {
+						return true;
+					}
+				}
+			}
+			Map<String, ServicePermission> pc = filterPermissions;
+			if (pc == null) {
+				return false;
+			}
+			perms = pc.values();
+		}
+
+		/* iterate one by one over filteredPermissions */
+		for (ServicePermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Consult permissions map to compute the effective permission for the
+	 * requested permission name.
+	 * 
+	 * @param requestedName The requested service name.
+	 * @param desired The desired actions.
+	 * @param effective The effective actions.
+	 * @return The new effective actions.
+	 */
+	private int effective(String requestedName, final int desired, int effective) {
+		final Map<String, ServicePermission> pc = permissions;
+		ServicePermission sp = pc.get(requestedName);
+		// strategy:
+		// Check for full match first. Then work our way up the
+		// name looking for matches on a.b.*
+		if (sp != null) {
+			// we have a direct hit!
+			effective |= sp.action_mask;
+			if ((effective & desired) == desired) {
+				return effective;
+			}
+		}
+		// work our way up the tree...
+		int last;
+		int offset = requestedName.length() - 1;
+		while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+			requestedName = requestedName.substring(0, last + 1) + "*";
+			sp = pc.get(requestedName);
+			if (sp != null) {
+				effective |= sp.action_mask;
+				if ((effective & desired) == desired) {
+					return effective;
+				}
+			}
+			offset = last - 1;
+		}
+		/*
+		 * we don't have to check for "*" as it was already checked before we
+		 * were called.
+		 */
+		return effective;
+	}
+
+	/**
+	 * Returns an enumeration of all the {@code ServicePermission} objects in
+	 * the container.
+	 * 
+	 * @return Enumeration of all the ServicePermission objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		Map<String, ServicePermission> pc = filterPermissions;
+		if (pc != null) {
+			all.addAll(pc.values());
+		}
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
+			new ObjectStreamField("filterPermissions", HashMap.class)	};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(permissions);
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", hashtable);
+		pfields.put("all_allowed", all_allowed);
+		pfields.put("filterPermissions", filterPermissions);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields.get("permissions", null);
+		permissions = new HashMap<String, ServicePermission>(hashtable);
+		all_allowed = gfields.get("all_allowed", false);
+		HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields.get("filterPermissions", null);
+		filterPermissions = fp;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServiceReference.java b/osgi/framework/src/org/osgi/framework/ServiceReference.java
new file mode 100644
index 0000000..7541517
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServiceReference.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.Dictionary;
+
+/**
+ * A reference to a service.
+ * 
+ * <p>
+ * The Framework returns {@code ServiceReference} objects from the
+ * {@code BundleContext.getServiceReference} and
+ * {@code BundleContext.getServiceReferences} methods.
+ * <p>
+ * A {@code ServiceReference} object may be shared between bundles and can be
+ * used to examine the properties of the service and to get the service object.
+ * <p>
+ * Every service registered in the Framework has a unique
+ * {@code ServiceRegistration} object and may have multiple, distinct
+ * {@code ServiceReference} objects referring to it. {@code ServiceReference}
+ * objects associated with a {@code ServiceRegistration} object have the same
+ * {@code hashCode} and are considered equal (more specifically, their
+ * {@code equals()} method will return {@code true} when compared).
+ * <p>
+ * If the same service object is registered multiple times,
+ * {@code ServiceReference} objects associated with different
+ * {@code ServiceRegistration} objects are not equal.
+ * 
+ * @param <S> Type of Service.
+ * @see BundleContext#getServiceReference(Class)
+ * @see BundleContext#getServiceReference(String)
+ * @see BundleContext#getServiceReferences(Class, String)
+ * @see BundleContext#getServiceReferences(String, String)
+ * @see BundleContext#getService(ServiceReference)
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 75352193f9f11a2c19692890153c6ff91611023b $
+ */
+
+public interface ServiceReference<S> extends Comparable<Object> {
+	/**
+	 * Returns the property value to which the specified property key is mapped
+	 * in the properties {@code Dictionary} object of the service referenced by
+	 * this {@code ServiceReference} object.
+	 * 
+	 * <p>
+	 * Property keys are case-insensitive.
+	 * 
+	 * <p>
+	 * This method must continue to return property values after the service has
+	 * been unregistered. This is so references to unregistered services (for
+	 * example, {@code ServiceReference} objects stored in the log) can still be
+	 * interrogated.
+	 * 
+	 * @param key The property key.
+	 * @return The property value to which the key is mapped; {@code null} if
+	 *         there is no property named after the key.
+	 */
+	public Object getProperty(String key);
+
+	/**
+	 * Returns an array of the keys in the properties {@code Dictionary} object
+	 * of the service referenced by this {@code ServiceReference} object.
+	 * 
+	 * <p>
+	 * This method will continue to return the keys after the service has been
+	 * unregistered. This is so references to unregistered services (for
+	 * example, {@code ServiceReference} objects stored in the log) can still be
+	 * interrogated.
+	 * 
+	 * <p>
+	 * This method is <i>case-preserving </i>; this means that every key in the
+	 * returned array must have the same case as the corresponding key in the
+	 * properties {@code Dictionary} that was passed to the
+	 * {@link BundleContext#registerService(String[],Object,Dictionary)} or
+	 * {@link ServiceRegistration#setProperties(Dictionary)} methods.
+	 * 
+	 * @return An array of property keys.
+	 */
+	public String[] getPropertyKeys();
+
+	/**
+	 * Returns the bundle that registered the service referenced by this
+	 * {@code ServiceReference} object.
+	 * 
+	 * <p>
+	 * This method must return {@code null} when the service has been
+	 * unregistered. This can be used to determine if the service has been
+	 * unregistered.
+	 * 
+	 * @return The bundle that registered the service referenced by this
+	 *         {@code ServiceReference} object; {@code null} if that service has
+	 *         already been unregistered.
+	 * @see BundleContext#registerService(String[],Object,Dictionary)
+	 */
+	public Bundle getBundle();
+
+	/**
+	 * Returns the bundles that are using the service referenced by this
+	 * {@code ServiceReference} object. Specifically, this method returns the
+	 * bundles whose usage count for that service is greater than zero.
+	 * 
+	 * @return An array of bundles whose usage count for the service referenced
+	 *         by this {@code ServiceReference} object is greater than zero;
+	 *         {@code null} if no bundles are currently using that service.
+	 * 
+	 * @since 1.1
+	 */
+	public Bundle[] getUsingBundles();
+
+	/**
+	 * Tests if the bundle that registered the service referenced by this
+	 * {@code ServiceReference} and the specified bundle use the same source for
+	 * the package of the specified class name.
+	 * <p>
+	 * This method performs the following checks:
+	 * <ol>
+	 * <li>Get the package name from the specified class name.</li>
+	 * <li>For the bundle that registered the service referenced by this
+	 * {@code ServiceReference} (registrant bundle); find the source for the
+	 * package. If no source is found then return {@code true} if the registrant
+	 * bundle is equal to the specified bundle; otherwise return {@code false}.</li>
+	 * <li>If the package source of the registrant bundle is equal to the
+	 * package source of the specified bundle then return {@code true};
+	 * otherwise return {@code false}.</li>
+	 * </ol>
+	 * 
+	 * @param bundle The {@code Bundle} object to check.
+	 * @param className The class name to check.
+	 * @return {@code true} if the bundle which registered the service
+	 *         referenced by this {@code ServiceReference} and the specified
+	 *         bundle use the same source for the package of the specified class
+	 *         name. Otherwise {@code false} is returned.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was not
+	 *         created by the same framework instance as this
+	 *         {@code ServiceReference}.
+	 * @since 1.3
+	 */
+	public boolean isAssignableTo(Bundle bundle, String className);
+
+	/**
+	 * Compares this {@code ServiceReference} with the specified
+	 * {@code ServiceReference} for order.
+	 * 
+	 * <p>
+	 * If this {@code ServiceReference} and the specified
+	 * {@code ServiceReference} have the same {@link Constants#SERVICE_ID
+	 * service id} they are equal. This {@code ServiceReference} is less than
+	 * the specified {@code ServiceReference} if it has a lower
+	 * {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
+	 * higher service ranking. Otherwise, if this {@code ServiceReference} and
+	 * the specified {@code ServiceReference} have the same
+	 * {@link Constants#SERVICE_RANKING service ranking}, this
+	 * {@code ServiceReference} is less than the specified
+	 * {@code ServiceReference} if it has a higher {@link Constants#SERVICE_ID
+	 * service id} and greater if it has a lower service id.
+	 * 
+	 * @param reference The {@code ServiceReference} to be compared.
+	 * @return Returns a negative integer, zero, or a positive integer if this
+	 *         {@code ServiceReference} is less than, equal to, or greater than
+	 *         the specified {@code ServiceReference}.
+	 * @throws IllegalArgumentException If the specified
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code ServiceReference}.
+	 * @since 1.4
+	 */
+	public int compareTo(Object reference);
+}
diff --git a/osgi/framework/src/org/osgi/framework/ServiceRegistration.java b/osgi/framework/src/org/osgi/framework/ServiceRegistration.java
new file mode 100644
index 0000000..702e918
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/ServiceRegistration.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.Dictionary;
+
+/**
+ * A registered service.
+ * 
+ * <p>
+ * The Framework returns a {@code ServiceRegistration} object when a
+ * {@code BundleContext.registerService} method invocation is successful. The
+ * {@code ServiceRegistration} object is for the private use of the registering
+ * bundle and should not be shared with other bundles.
+ * <p>
+ * The {@code ServiceRegistration} object may be used to update the properties
+ * of the service or to unregister the service.
+ * 
+ * @param <S> Type of Service.
+ * @see BundleContext#registerService(String[],Object,Dictionary)
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: a84248da0db0538708d2394a9478153e06b8afb9 $
+ */
+
+public interface ServiceRegistration<S> {
+	/**
+	 * Returns a {@code ServiceReference} object for a service being registered.
+	 * <p>
+	 * The {@code ServiceReference} object may be shared with other bundles.
+	 * 
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @return {@code ServiceReference} object.
+	 */
+	public ServiceReference<S> getReference();
+
+	/**
+	 * Updates the properties associated with a service.
+	 * 
+	 * <p>
+	 * The {@link Constants#OBJECTCLASS} and {@link Constants#SERVICE_ID} keys
+	 * cannot be modified by this method. These values are set by the Framework
+	 * when the service is registered in the OSGi environment.
+	 * 
+	 * <p>
+	 * The following steps are required to modify service properties:
+	 * <ol>
+	 * <li>The service's properties are replaced with the provided properties.
+	 * <li>A service event of type {@link ServiceEvent#MODIFIED} is fired.
+	 * </ol>
+	 * 
+	 * @param properties The properties for this service. See {@link Constants}
+	 *        for a list of standard service property keys. Changes should not
+	 *        be made to this object after calling this method. To update the
+	 *        service's properties this method should be called again.
+	 * 
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @throws IllegalArgumentException If {@code properties} contains case
+	 *         variants of the same key name.
+	 */
+	public void setProperties(Dictionary<String, ?> properties);
+
+	/**
+	 * Unregisters a service. Remove a {@code ServiceRegistration} object from
+	 * the Framework service registry. All {@code ServiceReference} objects
+	 * associated with this {@code ServiceRegistration} object can no longer be
+	 * used to interact with the service once unregistration is complete.
+	 * 
+	 * <p>
+	 * The following steps are required to unregister a service:
+	 * <ol>
+	 * <li>The service is removed from the Framework service registry so that it
+	 * can no longer be obtained.
+	 * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is fired
+	 * so that bundles using this service can release their use of the service.
+	 * Once delivery of the service event is complete, the
+	 * {@code ServiceReference} objects for the service may no longer be used to
+	 * get a service object for the service.
+	 * <li>For each bundle whose use count for this service is greater than
+	 * zero: <br>
+	 * The bundle's use count for this service is set to zero. <br>
+	 * If the service was registered with a {@link ServiceFactory} object, the
+	 * {@code ServiceFactory.ungetService} method is called to release the
+	 * service object for the bundle.
+	 * </ol>
+	 * 
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @see BundleContext#ungetService(ServiceReference)
+	 * @see ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)
+	 */
+	public void unregister();
+}
diff --git a/osgi/framework/src/org/osgi/framework/SignerProperty.java b/osgi/framework/src/org/osgi/framework/SignerProperty.java
new file mode 100644
index 0000000..9236dfa
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/SignerProperty.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Package private class used by permissions for filter matching on signer key
+ * during filter expression evaluation in the permission implies method.
+ * 
+ * @Immutable
+ * @version $Id: 94eea19050b84907f1257d7a12ebf8ab404f4473 $
+ */
+final class SignerProperty {
+	private final Bundle	bundle;
+	private final String	pattern;
+
+	/**
+	 * String constructor used by the filter matching algorithm to construct a
+	 * SignerProperty from the attribute value in a filter expression.
+	 * 
+	 * @param pattern Attribute value in the filter expression.
+	 */
+	public SignerProperty(String pattern) {
+		this.pattern = pattern;
+		this.bundle = null;
+	}
+
+	/**
+	 * Used by the permission implies method to build the properties for a
+	 * filter match.
+	 * 
+	 * @param bundle The bundle whose signers are to be matched.
+	 */
+	SignerProperty(Bundle bundle) {
+		this.bundle = bundle;
+		this.pattern = null;
+	}
+
+	/**
+	 * Used by the filter matching algorithm. This methods does NOT satisfy the
+	 * normal equals contract. Since the class is only used in filter expression
+	 * evaluations, it only needs to support comparing an instance created with
+	 * a Bundle to an instance created with a pattern string from the filter
+	 * expression.
+	 * 
+	 * @param o SignerProperty to compare against.
+	 * @return true if the DN name chain matches the pattern.
+	 */
+	public boolean equals(Object o) {
+		if (!(o instanceof SignerProperty))
+			return false;
+		SignerProperty other = (SignerProperty) o;
+		Bundle matchBundle = bundle != null ? bundle : other.bundle;
+		String matchPattern = bundle != null ? other.pattern : pattern;
+		Map<X509Certificate, List<X509Certificate>> signers = matchBundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		for (List<X509Certificate> signerCerts : signers.values()) {
+			List<String> dnChain = new ArrayList<String>(signerCerts.size());
+			for (X509Certificate signerCert : signerCerts) {
+				dnChain.add(signerCert.getSubjectDN().getName());
+			}
+			try {
+				if (FrameworkUtil.matchDistinguishedNameChain(matchPattern, dnChain)) {
+					return true;
+				}
+			} catch (IllegalArgumentException e) {
+				continue; // bad pattern
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Since the equals method does not obey the general equals contract, this
+	 * method cannot generate hash codes which obey the equals contract.
+	 */
+	public int hashCode() {
+		return 31;
+	}
+
+	/**
+	 * Check if the bundle is signed.
+	 * 
+	 * @return true if constructed with a bundle that is signed.
+	 */
+	boolean isBundleSigned() {
+		if (bundle == null) {
+			return false;
+		}
+		Map<X509Certificate, List<X509Certificate>> signers = bundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		return !signers.isEmpty();
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/SynchronousBundleListener.java b/osgi/framework/src/org/osgi/framework/SynchronousBundleListener.java
new file mode 100644
index 0000000..ee8474c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/SynchronousBundleListener.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+/**
+ * A synchronous {@code BundleEvent} listener. {@code SynchronousBundleListener}
+ * is a listener interface that may be implemented by a bundle developer. When a
+ * {@code BundleEvent} is fired, it is synchronously delivered to a
+ * {@code SynchronousBundleListener}. The Framework may deliver
+ * {@code BundleEvent} objects to a {@code SynchronousBundleListener} out of
+ * order and may concurrently call and/or reenter a
+ * {@code SynchronousBundleListener}.
+ * 
+ * <p>
+ * For {@code BundleEvent} types {@link BundleEvent#STARTED STARTED} and
+ * {@link BundleEvent#LAZY_ACTIVATION LAZY_ACTIVATION}, the Framework must not
+ * hold the referenced bundle's "state change" lock when the
+ * {@code BundleEvent} is delivered to a {@code SynchronousBundleListener}. For
+ * the other {@code BundleEvent} types, the Framework must hold the referenced
+ * bundle's "state change" lock when the {@code BundleEvent} is
+ * delivered to a {@code SynchronousBundleListener}. A
+ * {@code SynchronousBundleListener} cannot directly call life cycle methods on
+ * the referenced bundle when the Framework is holding the referenced bundle's
+ * "state change" lock.
+ * 
+ * <p>
+ * A {@code SynchronousBundleListener} object is registered with the Framework
+ * using the {@link BundleContext#addBundleListener(BundleListener)} method.
+ * {@code SynchronousBundleListener} objects are called with a
+ * {@code BundleEvent} object when a bundle has been installed, resolved,
+ * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
+ * <p>
+ * Unlike normal {@code BundleListener} objects,
+ * {@code SynchronousBundleListener}s are synchronously called during bundle
+ * lifecycle processing. The bundle lifecycle processing will not proceed until
+ * all {@code SynchronousBundleListener}s have completed.
+ * {@code SynchronousBundleListener} objects will be called prior to
+ * {@code BundleListener} objects.
+ * <p>
+ * {@code AdminPermission[bundle,LISTENER]} is required to add or remove a
+ * {@code SynchronousBundleListener} object.
+ * 
+ * @since 1.1
+ * @see BundleEvent
+ * @ThreadSafe
+ * @version $Id: 74246f4ceeba7f9a5ee198048522f93d4691c51a $
+ */
+
+public interface SynchronousBundleListener extends BundleListener {
+	// This is a marker interface
+}
diff --git a/osgi/framework/src/org/osgi/framework/UnfilteredServiceListener.java b/osgi/framework/src/org/osgi/framework/UnfilteredServiceListener.java
new file mode 100644
index 0000000..d712fcf
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/UnfilteredServiceListener.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import org.osgi.framework.hooks.service.ListenerHook;
+
+/**
+ * A {@code ServiceEvent} listener that does <i>not</i> filter based upon any
+ * filter string specified to
+ * {@link BundleContext#addServiceListener(ServiceListener, String)}. Using an
+ * {@code UnfilteredServiceListener} and specifying a filter string to
+ * {@link BundleContext#addServiceListener(ServiceListener, String)} allows the
+ * listener to receive all {@code ServiceEvent} objects while still advising
+ * {@link ListenerHook} implementation of the service interests in the filter
+ * string.
+ * 
+ * For example, an implementation of Declarative Services would add an
+ * {@code UnfilteredServiceListener} with a filter string listing all the
+ * services referenced by all the service components. The Declarative Services
+ * implementation would receive all {@code ServiceEvent} objects for internal
+ * processing and a Remote Services discovery service implementation can observe
+ * the service interests of the service components using a {@link ListenerHook}.
+ * When the set of service components being processed changes, the Declarative
+ * Services implementation would re-add the {@code UnfilteredServiceListener}
+ * with an updated filter string.
+ * 
+ * <p>
+ * When a {@code ServiceEvent} is fired, it is synchronously delivered to an
+ * {@code UnfilteredServiceListener}. The Framework may deliver
+ * {@code ServiceEvent} objects to an {@code UnfilteredServiceListener} out of
+ * order and may concurrently call and/or reenter an
+ * {@code UnfilteredServiceListener}.
+ * 
+ * <p>
+ * An {@code UnfilteredServiceListener} object is registered with the Framework
+ * using the {@code BundleContext.addServiceListener} method.
+ * {@code UnfilteredServiceListener} objects are called with a
+ * {@code ServiceEvent} object when a service is registered, modified, or is in
+ * the process of unregistering.
+ * 
+ * <p>
+ * {@code ServiceEvent} object delivery to {@code UnfilteredServiceListener}
+ * objects are <i>not</i> filtered by the filter specified when the listener was
+ * registered. If the Java Runtime Environment supports permissions, then some
+ * filtering is done. {@code ServiceEvent} objects are only delivered to the
+ * listener if the bundle which defines the listener object's class has the
+ * appropriate {@code ServicePermission} to get the service using at least one
+ * of the named classes under which the service was registered.
+ * 
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @ThreadSafe
+ * @since 1.7
+ * @version $Id: 543a345802f8dc7a49d29e8fb7aee7004ee2b329 $
+ */
+
+public interface UnfilteredServiceListener extends ServiceListener {
+	// This is a marker interface
+}
diff --git a/osgi/framework/src/org/osgi/framework/Version.java b/osgi/framework/src/org/osgi/framework/Version.java
new file mode 100644
index 0000000..02f6ddd
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/Version.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * Version identifier for capabilities such as bundles and packages.
+ * 
+ * <p>
+ * Version identifiers have four components.
+ * <ol>
+ * <li>Major version. A non-negative integer.</li>
+ * <li>Minor version. A non-negative integer.</li>
+ * <li>Micro version. A non-negative integer.</li>
+ * <li>Qualifier. A text string. See {@code Version(String)} for the format of
+ * the qualifier string.</li>
+ * </ol>
+ * 
+ * <p>
+ * {@code Version} objects are immutable.
+ * 
+ * @since 1.3
+ * @Immutable
+ * @version $Id: a0b5a865f7fbf2b3dcb77a13b2e99da0b64702bb $
+ */
+
+public class Version implements Comparable<Version> {
+	private final int			major;
+	private final int			minor;
+	private final int			micro;
+	private final String		qualifier;
+	private static final String	SEPARATOR		= ".";
+	private transient String	versionString /* default to null */;
+	private transient int		hash /* default to 0 */;
+
+	/**
+	 * The empty version "0.0.0".
+	 */
+	public static final Version	emptyVersion	= new Version(0, 0, 0);
+
+	/**
+	 * Creates a version identifier from the specified numerical components.
+	 * 
+	 * <p>
+	 * The qualifier is set to the empty string.
+	 * 
+	 * @param major Major component of the version identifier.
+	 * @param minor Minor component of the version identifier.
+	 * @param micro Micro component of the version identifier.
+	 * @throws IllegalArgumentException If the numerical components are
+	 *         negative.
+	 */
+	public Version(int major, int minor, int micro) {
+		this(major, minor, micro, null);
+	}
+
+	/**
+	 * Creates a version identifier from the specified components.
+	 * 
+	 * @param major Major component of the version identifier.
+	 * @param minor Minor component of the version identifier.
+	 * @param micro Micro component of the version identifier.
+	 * @param qualifier Qualifier component of the version identifier. If
+	 *        {@code null} is specified, then the qualifier will be set to the
+	 *        empty string.
+	 * @throws IllegalArgumentException If the numerical components are negative
+	 *         or the qualifier string is invalid.
+	 */
+	public Version(int major, int minor, int micro, String qualifier) {
+		if (qualifier == null) {
+			qualifier = "";
+		}
+
+		this.major = major;
+		this.minor = minor;
+		this.micro = micro;
+		this.qualifier = qualifier;
+		validate();
+	}
+
+	/**
+	 * Creates a version identifier from the specified string.
+	 * 
+	 * <p>
+	 * Version string grammar:
+	 * 
+	 * <pre>
+	 * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
+	 * major ::= digit+
+	 * minor ::= digit+
+	 * micro ::= digit+
+	 * qualifier ::= (alpha|digit|'_'|'-')+
+	 * digit ::= [0..9]
+	 * alpha ::= [a..zA..Z]
+	 * </pre>
+	 * 
+	 * @param version String representation of the version identifier. There
+	 *        must be no whitespace in the argument.
+	 * @throws IllegalArgumentException If {@code version} is improperly
+	 *         formatted.
+	 */
+	public Version(String version) {
+		int maj = 0;
+		int min = 0;
+		int mic = 0;
+		String qual = "";
+
+		try {
+			StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
+			maj = parseInt(st.nextToken(), version);
+
+			if (st.hasMoreTokens()) { // minor
+				st.nextToken(); // consume delimiter
+				min = parseInt(st.nextToken(), version);
+
+				if (st.hasMoreTokens()) { // micro
+					st.nextToken(); // consume delimiter
+					mic = parseInt(st.nextToken(), version);
+
+					if (st.hasMoreTokens()) { // qualifier separator
+						st.nextToken(); // consume delimiter
+						qual = st.nextToken(""); // remaining string
+
+						if (st.hasMoreTokens()) { // fail safe
+							throw new IllegalArgumentException("invalid version \"" + version + "\": invalid format");
+						}
+					}
+				}
+			}
+		} catch (NoSuchElementException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid version \"" + version + "\": invalid format");
+			iae.initCause(e);
+			throw iae;
+		}
+
+		major = maj;
+		minor = min;
+		micro = mic;
+		qualifier = qual;
+		validate();
+	}
+
+	/**
+	 * Parse numeric component into an int.
+	 * 
+	 * @param value Numeric component
+	 * @param version Complete version string for exception message, if any
+	 * @return int value of numeric component
+	 */
+	private static int parseInt(String value, String version) {
+		try {
+			return Integer.parseInt(value);
+		} catch (NumberFormatException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid version \"" + version + "\": non-numeric \"" + value + "\"");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Called by the Version constructors to validate the version components.
+	 * 
+	 * @throws IllegalArgumentException If the numerical components are negative
+	 *         or the qualifier string is invalid.
+	 */
+	private void validate() {
+		if (major < 0) {
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + major + "\"");
+		}
+		if (minor < 0) {
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + minor + "\"");
+		}
+		if (micro < 0) {
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + micro + "\"");
+		}
+		for (char ch : qualifier.toCharArray()) {
+			if (('A' <= ch) && (ch <= 'Z')) {
+				continue;
+			}
+			if (('a' <= ch) && (ch <= 'z')) {
+				continue;
+			}
+			if (('0' <= ch) && (ch <= '9')) {
+				continue;
+			}
+			if ((ch == '_') || (ch == '-')) {
+				continue;
+			}
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": invalid qualifier \"" + qualifier + "\"");
+		}
+	}
+
+	/**
+	 * Parses a version identifier from the specified string.
+	 * 
+	 * <p>
+	 * See {@code Version(String)} for the format of the version string.
+	 * 
+	 * @param version String representation of the version identifier. Leading
+	 *        and trailing whitespace will be ignored.
+	 * @return A {@code Version} object representing the version identifier. If
+	 *         {@code version} is {@code null} or the empty string then
+	 *         {@code emptyVersion} will be returned.
+	 * @throws IllegalArgumentException If {@code version} is improperly
+	 *         formatted.
+	 */
+	public static Version parseVersion(String version) {
+		if (version == null) {
+			return emptyVersion;
+		}
+
+		version = version.trim();
+		if (version.length() == 0) {
+			return emptyVersion;
+		}
+
+		return new Version(version);
+	}
+
+	/**
+	 * Returns the major component of this version identifier.
+	 * 
+	 * @return The major component.
+	 */
+	public int getMajor() {
+		return major;
+	}
+
+	/**
+	 * Returns the minor component of this version identifier.
+	 * 
+	 * @return The minor component.
+	 */
+	public int getMinor() {
+		return minor;
+	}
+
+	/**
+	 * Returns the micro component of this version identifier.
+	 * 
+	 * @return The micro component.
+	 */
+	public int getMicro() {
+		return micro;
+	}
+
+	/**
+	 * Returns the qualifier component of this version identifier.
+	 * 
+	 * @return The qualifier component.
+	 */
+	public String getQualifier() {
+		return qualifier;
+	}
+
+	/**
+	 * Returns the string representation of this version identifier.
+	 * 
+	 * <p>
+	 * The format of the version string will be {@code major.minor.micro} if
+	 * qualifier is the empty string or {@code major.minor.micro.qualifier}
+	 * otherwise.
+	 * 
+	 * @return The string representation of this version identifier.
+	 */
+	public String toString() {
+		return toString0();
+	}
+
+	/**
+	 * Internal toString behavior
+	 * 
+	 * @return The string representation of this version identifier.
+	 */
+	String toString0() {
+		if (versionString != null) {
+			return versionString;
+		}
+		int q = qualifier.length();
+		StringBuffer result = new StringBuffer(20 + q);
+		result.append(major);
+		result.append(SEPARATOR);
+		result.append(minor);
+		result.append(SEPARATOR);
+		result.append(micro);
+		if (q > 0) {
+			result.append(SEPARATOR);
+			result.append(qualifier);
+		}
+		return versionString = result.toString();
+	}
+
+	/**
+	 * Returns a hash code value for the object.
+	 * 
+	 * @return An integer which is a hash code value for this object.
+	 */
+	public int hashCode() {
+		if (hash != 0) {
+			return hash;
+		}
+		int h = 31 * 17;
+		h = 31 * h + major;
+		h = 31 * h + minor;
+		h = 31 * h + micro;
+		h = 31 * h + qualifier.hashCode();
+		return hash = h;
+	}
+
+	/**
+	 * Compares this {@code Version} object to another object.
+	 * 
+	 * <p>
+	 * A version is considered to be <b>equal to </b> another version if the
+	 * major, minor and micro components are equal and the qualifier component
+	 * is equal (using {@code String.equals}).
+	 * 
+	 * @param object The {@code Version} object to be compared.
+	 * @return {@code true} if {@code object} is a {@code Version} and is equal
+	 *         to this object; {@code false} otherwise.
+	 */
+	public boolean equals(Object object) {
+		if (object == this) { // quicktest
+			return true;
+		}
+
+		if (!(object instanceof Version)) {
+			return false;
+		}
+
+		Version other = (Version) object;
+		return (major == other.major) && (minor == other.minor) && (micro == other.micro) && qualifier.equals(other.qualifier);
+	}
+
+	/**
+	 * Compares this {@code Version} object to another {@code Version}.
+	 * 
+	 * <p>
+	 * A version is considered to be <b>less than</b> another version if its
+	 * major component is less than the other version's major component, or the
+	 * major components are equal and its minor component is less than the other
+	 * version's minor component, or the major and minor components are equal
+	 * and its micro component is less than the other version's micro component,
+	 * or the major, minor and micro components are equal and it's qualifier
+	 * component is less than the other version's qualifier component (using
+	 * {@code String.compareTo}).
+	 * 
+	 * <p>
+	 * A version is considered to be <b>equal to</b> another version if the
+	 * major, minor and micro components are equal and the qualifier component
+	 * is equal (using {@code String.compareTo}).
+	 * 
+	 * @param other The {@code Version} object to be compared.
+	 * @return A negative integer, zero, or a positive integer if this version
+	 *         is less than, equal to, or greater than the specified
+	 *         {@code Version} object.
+	 * @throws ClassCastException If the specified object is not a
+	 *         {@code Version} object.
+	 */
+	public int compareTo(Version other) {
+		if (other == this) { // quicktest
+			return 0;
+		}
+
+		int result = major - other.major;
+		if (result != 0) {
+			return result;
+		}
+
+		result = minor - other.minor;
+		if (result != 0) {
+			return result;
+		}
+
+		result = micro - other.micro;
+		if (result != 0) {
+			return result;
+		}
+
+		return qualifier.compareTo(other.qualifier);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/VersionRange.java b/osgi/framework/src/org/osgi/framework/VersionRange.java
new file mode 100644
index 0000000..0589a75
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/VersionRange.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * Version range. A version range is an interval describing a set of
+ * {@link Version versions}.
+ * 
+ * <p>
+ * A range has a left (lower) endpoint and a right (upper) endpoint. Each
+ * endpoint can be open (excluded from the set) or closed (included in the set).
+ * 
+ * <p>
+ * {@code VersionRange} objects are immutable.
+ * 
+ * @since 1.7
+ * @Immutable
+ * @version $Id: d0c21e6a5015a7fa0b33179a29122ea7d137145a $
+ */
+
+public class VersionRange {
+	/**
+	 * The left endpoint is open and is excluded from the range.
+	 * <p>
+	 * The value of {@code LEFT_OPEN} is {@code '('}.
+	 */
+	public static final char	LEFT_OPEN				= '(';
+	/**
+	 * The left endpoint is closed and is included in the range.
+	 * <p>
+	 * The value of {@code LEFT_CLOSED} is {@code '['}.
+	 */
+	public static final char	LEFT_CLOSED				= '[';
+	/**
+	 * The right endpoint is open and is excluded from the range.
+	 * <p>
+	 * The value of {@code RIGHT_OPEN} is {@code ')'}.
+	 */
+	public static final char	RIGHT_OPEN				= ')';
+	/**
+	 * The right endpoint is closed and is included in the range.
+	 * <p>
+	 * The value of {@code RIGHT_CLOSED} is {@code ']'}.
+	 */
+	public static final char	RIGHT_CLOSED			= ']';
+
+	private final boolean		leftClosed;
+	private final Version		left;
+	private final Version		right;
+	private final boolean		rightClosed;
+	private final boolean		empty;
+
+	private transient String	versionRangeString /* default to null */;
+	private transient int		hash /* default to 0 */;
+
+	private static final String	LEFT_OPEN_DELIMITER		= "(";
+	private static final String	LEFT_CLOSED_DELIMITER	= "[";
+	private static final String	LEFT_DELIMITERS			= LEFT_CLOSED_DELIMITER + LEFT_OPEN_DELIMITER;
+	private static final String	RIGHT_OPEN_DELIMITER	= ")";
+	private static final String	RIGHT_CLOSED_DELIMITER	= "]";
+	private static final String	RIGHT_DELIMITERS		= RIGHT_OPEN_DELIMITER + RIGHT_CLOSED_DELIMITER;
+	private static final String	ENDPOINT_DELIMITER		= ",";
+
+	/**
+	 * Creates a version range from the specified versions.
+	 * 
+	 * @param leftType Must be either {@link #LEFT_CLOSED} or {@link #LEFT_OPEN}
+	 *        .
+	 * @param leftEndpoint Left endpoint of range. Must not be {@code null}.
+	 * @param rightEndpoint Right endpoint of range. May be {@code null} to
+	 *        indicate the right endpoint is <i>Infinity</i>.
+	 * @param rightType Must be either {@link #RIGHT_CLOSED} or
+	 *        {@link #RIGHT_OPEN}.
+	 * @throws IllegalArgumentException If the arguments are invalid.
+	 */
+	public VersionRange(char leftType, Version leftEndpoint, Version rightEndpoint, char rightType) {
+		if ((leftType != LEFT_CLOSED) && (leftType != LEFT_OPEN)) {
+			throw new IllegalArgumentException("invalid leftType \"" + leftType + "\"");
+		}
+		if ((rightType != RIGHT_OPEN) && (rightType != RIGHT_CLOSED)) {
+			throw new IllegalArgumentException("invalid rightType \"" + rightType + "\"");
+		}
+		if (leftEndpoint == null) {
+			throw new IllegalArgumentException("null leftEndpoint argument");
+		}
+		leftClosed = leftType == LEFT_CLOSED;
+		rightClosed = rightType == RIGHT_CLOSED;
+		left = leftEndpoint;
+		right = rightEndpoint;
+		empty = isEmpty0();
+	}
+
+	/**
+	 * Creates a version range from the specified string.
+	 * 
+	 * <p>
+	 * Version range string grammar:
+	 * 
+	 * <pre>
+	 * range ::= interval | atleast
+	 * interval ::= ( '[' | '(' ) left ',' right ( ']' | ')' )
+	 * left ::= version
+	 * right ::= version
+	 * atleast ::= version
+	 * </pre>
+	 * 
+	 * @param range String representation of the version range. The versions in
+	 *        the range must contain no whitespace. Other whitespace in the
+	 *        range string is ignored.
+	 * @throws IllegalArgumentException If {@code range} is improperly
+	 *         formatted.
+	 */
+	public VersionRange(String range) {
+		boolean closedLeft;
+		boolean closedRight;
+		Version endpointLeft;
+		Version endpointRight;
+
+		try {
+			StringTokenizer st = new StringTokenizer(range, LEFT_DELIMITERS, true);
+			String token = st.nextToken().trim(); // whitespace or left delim
+			if (token.length() == 0) { // leading whitespace
+				token = st.nextToken(); // left delim
+			}
+			closedLeft = LEFT_CLOSED_DELIMITER.equals(token);
+			if (!closedLeft && !LEFT_OPEN_DELIMITER.equals(token)) {
+				// first token is not a delimiter, so it must be "atleast"
+				if (st.hasMoreTokens()) { // there must be no more tokens
+					throw new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+				}
+				leftClosed = true;
+				rightClosed = false;
+				left = parseVersion(token, range);
+				right = null;
+				empty = false;
+				return;
+			}
+			String version = st.nextToken(ENDPOINT_DELIMITER);
+			endpointLeft = parseVersion(version, range);
+			token = st.nextToken(); // consume comma
+			version = st.nextToken(RIGHT_DELIMITERS);
+			token = st.nextToken(); // right delim
+			closedRight = RIGHT_CLOSED_DELIMITER.equals(token);
+			if (!closedRight && !RIGHT_OPEN_DELIMITER.equals(token)) {
+				throw new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+			}
+			endpointRight = parseVersion(version, range);
+
+			if (st.hasMoreTokens()) { // any more tokens have to be whitespace
+				token = st.nextToken("").trim();
+				if (token.length() != 0) { // trailing whitespace
+					throw new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+				}
+			}
+		} catch (NoSuchElementException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+			iae.initCause(e);
+			throw iae;
+		}
+
+		leftClosed = closedLeft;
+		rightClosed = closedRight;
+		left = endpointLeft;
+		right = endpointRight;
+		empty = isEmpty0();
+	}
+
+	/**
+	 * Parse version component into a Version.
+	 * 
+	 * @param version version component string
+	 * @param range Complete range string for exception message, if any
+	 * @return Version
+	 */
+	private static Version parseVersion(String version, String range) {
+		try {
+			return Version.parseVersion(version);
+		} catch (IllegalArgumentException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid range \"" + range + "\": " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Returns the left endpoint of this version range.
+	 * 
+	 * @return The left endpoint.
+	 */
+	public Version getLeft() {
+		return left;
+	}
+
+	/**
+	 * Returns the right endpoint of this version range.
+	 * 
+	 * @return The right endpoint. May be {@code null} which indicates the right
+	 *         endpoint is <i>Infinity</i>.
+	 */
+	public Version getRight() {
+		return right;
+	}
+
+	/**
+	 * Returns the type of the left endpoint of this version range.
+	 * 
+	 * @return {@link #LEFT_CLOSED} if the left endpoint is closed or
+	 *         {@link #LEFT_OPEN} if the left endpoint is open.
+	 */
+	public char getLeftType() {
+		return leftClosed ? LEFT_CLOSED : LEFT_OPEN;
+	}
+
+	/**
+	 * Returns the type of the right endpoint of this version range.
+	 * 
+	 * @return {@link #RIGHT_CLOSED} if the right endpoint is closed or
+	 *         {@link #RIGHT_OPEN} if the right endpoint is open.
+	 */
+	public char getRightType() {
+		return rightClosed ? RIGHT_CLOSED : RIGHT_OPEN;
+	}
+
+	/**
+	 * Returns whether this version range includes the specified version.
+	 * 
+	 * @param version The version to test for inclusion in this version range.
+	 * @return {@code true} if the specified version is included in this version
+	 *         range; {@code false} otherwise.
+	 */
+	public boolean includes(Version version) {
+		if (empty) {
+			return false;
+		}
+		if (left.compareTo(version) >= (leftClosed ? 1 : 0)) {
+			return false;
+		}
+		if (right == null) {
+			return true;
+		}
+		return right.compareTo(version) >= (rightClosed ? 0 : 1);
+	}
+
+	/**
+	 * Returns the intersection of this version range with the specified version
+	 * ranges.
+	 * 
+	 * @param ranges The version ranges to intersect with this version range.
+	 * @return A version range representing the intersection of this version
+	 *         range and the specified version ranges. If no version ranges are
+	 *         specified, then this version range is returned.
+	 */
+	public VersionRange intersection(VersionRange... ranges) {
+		if ((ranges == null) || (ranges.length == 0)) {
+			return this;
+		}
+		// prime with data from this version range
+		boolean closedLeft = leftClosed;
+		boolean closedRight = rightClosed;
+		Version endpointLeft = left;
+		Version endpointRight = right;
+
+		for (VersionRange range : ranges) {
+			int comparison = endpointLeft.compareTo(range.left);
+			if (comparison == 0) {
+				closedLeft = closedLeft && range.leftClosed;
+			} else {
+				if (comparison < 0) { // move endpointLeft to the right
+					endpointLeft = range.left;
+					closedLeft = range.leftClosed;
+				}
+			}
+			if (range.right != null) {
+				if (endpointRight == null) {
+					endpointRight = range.right;
+					closedRight = range.rightClosed;
+				} else {
+					comparison = endpointRight.compareTo(range.right);
+					if (comparison == 0) {
+						closedRight = closedRight && range.rightClosed;
+					} else {
+						if (comparison > 0) { // move endpointRight to the left
+							endpointRight = range.right;
+							closedRight = range.rightClosed;
+						}
+					}
+				}
+			}
+		}
+
+		return new VersionRange(closedLeft ? LEFT_CLOSED : LEFT_OPEN, endpointLeft, endpointRight, closedRight ? RIGHT_CLOSED : RIGHT_OPEN);
+	}
+
+	/**
+	 * Returns whether this version range is empty. A version range is empty if
+	 * the set of versions defined by the interval is empty.
+	 * 
+	 * @return {@code true} if this version range is empty; {@code false}
+	 *         otherwise.
+	 */
+	public boolean isEmpty() {
+		return empty;
+	}
+
+	/**
+	 * Internal isEmpty behavior.
+	 * 
+	 * @return {@code true} if this version range is empty; {@code false}
+	 *         otherwise.
+	 */
+	private boolean isEmpty0() {
+		if (right == null) { // infinity
+			return false;
+		}
+		int comparison = left.compareTo(right);
+		if (comparison == 0) { // endpoints equal
+			return !leftClosed || !rightClosed;
+		}
+		return comparison > 0; // true if left > right
+	}
+
+	/**
+	 * Returns whether this version range contains only a single version.
+	 * 
+	 * @return {@code true} if this version range contains only a single
+	 *         version; {@code false} otherwise.
+	 */
+	public boolean isExact() {
+		if (empty || (right == null)) {
+			return false;
+		}
+		if (leftClosed) {
+			if (rightClosed) {
+				// [l,r]: exact if l == r
+				return left.equals(right);
+			} else {
+				// [l,r): exact if l++ >= r
+				Version adjacent1 = new Version(left.getMajor(), left.getMinor(), left.getMicro(), left.getQualifier() + "-");
+				return adjacent1.compareTo(right) >= 0;
+			}
+		} else {
+			if (rightClosed) {
+				// (l,r] is equivalent to [l++,r]: exact if l++ == r
+				Version adjacent1 = new Version(left.getMajor(), left.getMinor(), left.getMicro(), left.getQualifier() + "-");
+				return adjacent1.equals(right);
+			} else {
+				// (l,r) is equivalent to [l++,r): exact if (l++)++ >=r
+				Version adjacent2 = new Version(left.getMajor(), left.getMinor(), left.getMicro(), left.getQualifier() + "--");
+				return adjacent2.compareTo(right) >= 0;
+			}
+		}
+	}
+
+	/**
+	 * Returns the string representation of this version range.
+	 * 
+	 * <p>
+	 * The format of the version range string will be a version string if the
+	 * right end point is <i>Infinity</i> ({@code null}) or an interval string.
+	 * 
+	 * @return The string representation of this version range.
+	 */
+	public String toString() {
+		if (versionRangeString != null) {
+			return versionRangeString;
+		}
+		String leftVersion = left.toString();
+		if (right == null) {
+			StringBuffer result = new StringBuffer(leftVersion.length() + 1);
+			result.append(left.toString0());
+			return versionRangeString = result.toString();
+		}
+		String rightVerion = right.toString();
+		StringBuffer result = new StringBuffer(leftVersion.length() + rightVerion.length() + 5);
+		result.append(leftClosed ? LEFT_CLOSED : LEFT_OPEN);
+		result.append(left.toString0());
+		result.append(ENDPOINT_DELIMITER);
+		result.append(right.toString0());
+		result.append(rightClosed ? RIGHT_CLOSED : RIGHT_OPEN);
+		return versionRangeString = result.toString();
+	}
+
+	/**
+	 * Returns a hash code value for the object.
+	 * 
+	 * @return An integer which is a hash code value for this object.
+	 */
+	public int hashCode() {
+		if (hash != 0) {
+			return hash;
+		}
+		if (empty) {
+			return hash = 31;
+		}
+		int h = 31 + (leftClosed ? 7 : 5);
+		h = 31 * h + left.hashCode();
+		if (right != null) {
+			h = 31 * h + right.hashCode();
+			h = 31 * h + (rightClosed ? 7 : 5);
+		}
+		return hash = h;
+	}
+
+	/**
+	 * Compares this {@code VersionRange} object to another object.
+	 * 
+	 * <p>
+	 * A version range is considered to be <b>equal to </b> another version
+	 * range if both the endpoints and their types are equal or if both version
+	 * ranges are {@link #isEmpty() empty}.
+	 * 
+	 * @param object The {@code VersionRange} object to be compared.
+	 * @return {@code true} if {@code object} is a {@code VersionRange} and is
+	 *         equal to this object; {@code false} otherwise.
+	 */
+	public boolean equals(Object object) {
+		if (object == this) { // quicktest
+			return true;
+		}
+		if (!(object instanceof VersionRange)) {
+			return false;
+		}
+		VersionRange other = (VersionRange) object;
+		if (empty && other.empty) {
+			return true;
+		}
+		if (right == null) {
+			return (leftClosed == other.leftClosed) && (other.right == null) && left.equals(other.left);
+		}
+		return (leftClosed == other.leftClosed) && (rightClosed == other.rightClosed) && left.equals(other.left) && right.equals(other.right);
+	}
+
+	/**
+	 * Returns the filter string for this version range using the specified
+	 * attribute name.
+	 * 
+	 * @param attributeName The attribute name to use in the returned filter
+	 *        string.
+	 * @return A filter string for this version range using the specified
+	 *         attribute name.
+	 * @throws IllegalArgumentException If the specified attribute name is not a
+	 *         valid attribute name.
+	 * 
+	 * @see "Core Specification, Filters, for a description of the filter string syntax."
+	 */
+	public String toFilterString(String attributeName) {
+		if (attributeName.length() == 0) {
+			throw new IllegalArgumentException("invalid attributeName \"" + attributeName + "\"");
+		}
+		for (char ch : attributeName.toCharArray()) {
+			if ((ch == '=') || (ch == '>') || (ch == '<') || (ch == '~') || (ch == '(') || (ch == ')')) {
+				throw new IllegalArgumentException("invalid attributeName \"" + attributeName + "\"");
+			}
+		}
+
+		StringBuffer result = new StringBuffer(128);
+		if (right != null) {
+			result.append("(&");
+		}
+		if (leftClosed) {
+			result.append('(');
+			result.append(attributeName);
+			result.append(">=");
+			result.append(left.toString0());
+			result.append(')');
+		} else {
+			result.append("(!(");
+			result.append(attributeName);
+			result.append("<=");
+			result.append(left.toString0());
+			result.append("))");
+		}
+		if (right != null) {
+			if (rightClosed) {
+				result.append('(');
+				result.append(attributeName);
+				result.append("<=");
+				result.append(right.toString0());
+				result.append(')');
+			} else {
+				result.append("(!(");
+				result.append(attributeName);
+				result.append(">=");
+				result.append(right.toString0());
+				result.append("))");
+			}
+			result.append(')');
+		}
+
+		return result.toString();
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/bundle/CollisionHook.java b/osgi/framework/src/org/osgi/framework/hooks/bundle/CollisionHook.java
new file mode 100644
index 0000000..37446ff
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/bundle/CollisionHook.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.bundle;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * OSGi Framework Bundle Collision Hook Service.
+ * 
+ * <p>
+ * If the framework was launched with the {@link Constants#FRAMEWORK_BSNVERSION
+ * org.osgi.framework.bsnversion} framework launching property set to
+ * {@link Constants#FRAMEWORK_BSNVERSION_MANAGED managed}, then all registered
+ * collision hook services will be called during framework bundle install and
+ * update operations to determine if an install or update operation will result
+ * in a bundle symbolic name and version collision.
+ * 
+ * @ThreadSafe
+ * @version $Id: a1a25ee0432f210a56e911246f477f19edc28bc1 $
+ */
+public interface CollisionHook {
+
+	/**
+	 * Specifies a bundle install operation is being performed.
+	 */
+	int	INSTALLING	= 1;
+
+	/**
+	 * Specifies a bundle update operation is being performed.
+	 */
+	int	UPDATING	= 2;
+
+	/**
+	 * Filter bundle collisions hook method. This method is called during the
+	 * install or update operation. The operation type will be
+	 * {@link #INSTALLING installing} or {@link #UPDATING updating}. Depending
+	 * on the operation type the target bundle and the collision candidate
+	 * collection are the following:
+	 * <ul>
+	 * <li> {@link #INSTALLING installing} - The target is the bundle associated
+	 * with the {@link BundleContext} used to call one of the
+	 * {@link BundleContext#installBundle(String) install} methods. The
+	 * collision candidate collection contains the existing bundles installed
+	 * which have the same symbolic name and version as the bundle being
+	 * installed.
+	 * <li> {@link #UPDATING updating} - The target is the bundle used to call
+	 * one of the {@link Bundle#update() update} methods. The collision
+	 * candidate collection contains the existing bundles installed which have
+	 * the same symbolic name and version as the content the target bundle is
+	 * being updated to.
+	 * </ul>
+	 * This method can filter the collection of collision candidates by removing
+	 * potential collisions. For the specified operation to succeed, the
+	 * collection of collision candidates must be empty after all registered
+	 * collision hook services have been called.
+	 * 
+	 * @param operationType The operation type. Must be the value of
+	 *        {@link #INSTALLING installing} or {@link #UPDATING updating}.
+	 * @param target The target bundle used to determine what collision
+	 *        candidates to filter.
+	 * @param collisionCandidates The collection of collision candidates. The
+	 *        collection supports all the optional {@code Collection} operations
+	 *        except {@code add} and {@code addAll}. Attempting to add to the
+	 *        collection will result in an {@code UnsupportedOperationException}
+	 *        . The collection is not synchronized.
+	 */
+	void filterCollisions(int operationType, Bundle target, Collection<Bundle> collisionCandidates);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/bundle/EventHook.java b/osgi/framework/src/org/osgi/framework/hooks/bundle/EventHook.java
new file mode 100644
index 0000000..e66a20e
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/bundle/EventHook.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.bundle;
+
+import java.util.Collection;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+
+/**
+ * OSGi Framework Bundle Event Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework lifecycle
+ * (install, start, stop, update, and uninstall bundle) operations.
+ * 
+ * @ThreadSafe
+ * @version $Id: e1471b36491a02bd8598a30d05c889ee58edc760 $
+ */
+public interface EventHook {
+
+	/**
+	 * Bundle event hook method. This method is called prior to bundle event
+	 * delivery when a bundle is installed, resolved, started, stopped,
+	 * unresolved, or uninstalled. This method can filter the bundles which
+	 * receive the event.
+	 * <p>
+	 * This method must be called by the framework one and only one time for
+	 * each bundle event generated, this included bundle events which are
+	 * generated when there are no bundle listeners registered. This method must
+	 * be called on the same thread that is performing the action which
+	 * generated the specified event. The specified collection includes bundle
+	 * contexts with synchronous and asynchronous bundle listeners registered
+	 * with them.
+	 * 
+	 * @param event The bundle event to be delivered
+	 * @param contexts A collection of Bundle Contexts for bundles which have
+	 *        listeners to which the specified event will be delivered. The
+	 *        implementation of this method may remove bundle contexts from the
+	 *        collection to prevent the event from being delivered to the
+	 *        associated bundles. The collection supports all the optional
+	 *        {@code Collection} operations except {@code add} and
+	 *        {@code addAll}. Attempting to add to the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
+	 */
+	void event(BundleEvent event, Collection<BundleContext> contexts);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/bundle/FindHook.java b/osgi/framework/src/org/osgi/framework/hooks/bundle/FindHook.java
new file mode 100644
index 0000000..af556ea
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/bundle/FindHook.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.bundle;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+/**
+ * OSGi Framework Bundle Context Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework bundle find
+ * (get bundles) operations.
+ * 
+ * @ThreadSafe
+ * @version $Id: ae6bf5fc5cf999ac39dfc195c99ef7e223e3b847 $
+ */
+public interface FindHook {
+	/**
+	 * Find hook method. This method is called for the following:
+	 * <ul>
+	 * <li>Bundle find operations using {@link BundleContext#getBundle(long)}
+	 * and {@link BundleContext#getBundles()} methods. The find method can
+	 * filter the result of the find operation. Note that a find operation using
+	 * the {@link BundleContext#getBundle(String)} method does not cause the
+	 * find method to be called.</li>
+	 * <li>Bundle install operations when an existing bundle is already
+	 * installed at a given location. In this case, the find method is called to
+	 * determine if the context performing the install operation is able to find
+	 * the bundle. If the context cannot find the existing bundle then the
+	 * install operation must fail with a
+	 * {@link BundleException#REJECTED_BY_HOOK} exception.</li>
+	 * </ul>
+	 * 
+	 * @param context The bundle context of the bundle performing the find
+	 *        operation.
+	 * @param bundles A collection of Bundles to be returned as a result of the
+	 *        find operation. The implementation of this method may remove
+	 *        bundles from the collection to prevent the bundles from being
+	 *        returned to the bundle performing the find operation. The
+	 *        collection supports all the optional {@code Collection} operations
+	 *        except {@code add} and {@code addAll}. Attempting to add to the
+	 *        collection will result in an {@code UnsupportedOperationException}
+	 *        . The collection is not synchronized.
+	 */
+	void find(BundleContext context, Collection<Bundle> bundles);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/bundle/package-info.java b/osgi/framework/src/org/osgi/framework/hooks/bundle/package-info.java
new file mode 100644
index 0000000..744cde9
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/bundle/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Bundle Hooks Package Version 1.1.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.hooks.bundle; version="[1.1,2.0)"}
+ * 
+ * @version $Id: 0f53749f486ffe21404f4601fcc67c956f25ca6f $
+ */
+
+package org.osgi.framework.hooks.bundle;
+
diff --git a/osgi/framework/src/org/osgi/framework/hooks/bundle/packageinfo b/osgi/framework/src/org/osgi/framework/hooks/bundle/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/bundle/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/osgi/framework/src/org/osgi/framework/hooks/resolver/ResolverHook.java b/osgi/framework/src/org/osgi/framework/hooks/resolver/ResolverHook.java
new file mode 100644
index 0000000..51c46ec
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/resolver/ResolverHook.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.resolver;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/**
+ * OSGi Framework Resolver Hook instances are obtained from the OSGi
+ * {@link ResolverHookFactory Framework Resolver Hook Factory} service.
+ * 
+ * <p>
+ * A Resolver Hook instance is called by the framework during a resolve process.
+ * A resolver hook may influence the outcome of a resolve process by removing
+ * entries from shrinkable collections that are passed to the hook during a
+ * resolve process. A shrinkable collection is a {@code Collection} that
+ * supports all remove operations. Any other attempts to modify a shrinkable
+ * collection will result in an {@code UnsupportedOperationException} being
+ * thrown.
+ * 
+ * <p>
+ * The following steps outline the way a framework uses the resolver hooks
+ * during a resolve process.
+ * <ol>
+ * <li>Collect a snapshot of registered resolver hook factories that will be
+ * called during the current resolve process. Any hook factories registered
+ * after the snapshot is taken must not be called during the current resolve
+ * process. A resolver hook factory contained in the snapshot may become
+ * unregistered during the resolve process. The framework should handle this and
+ * stop calling the resolver hook instance provided by the unregistered hook
+ * factory and the current resolve process must fail. If possible, an exception
+ * must be thrown to the caller of the API which triggered the resolve process.
+ * In cases where the the caller is not available a framework event of type
+ * error should be fired.</li>
+ * 
+ * <li>For each registered hook factory call the
+ * {@link ResolverHookFactory#begin(Collection)} method to inform the hooks
+ * about a resolve process beginning and to obtain a Resolver Hook instance that
+ * will be used for the duration of the resolve process.</li>
+ * 
+ * <li>Determine the collection of unresolved bundle revisions that may be
+ * considered for resolution during the current resolution process and place
+ * each of the bundle revisions in a shrinkable collection {@code Resolvable}.
+ * For each resolver hook call the {@link #filterResolvable(Collection)} method
+ * with the shrinkable collection {@code Resolvable}.</li>
+ * <li>The shrinkable collection {@code Resolvable} now contains all the
+ * unresolved bundle revisions that may end up as resolved at the end of the
+ * current resolve process. Any other bundle revisions that got removed from the
+ * shrinkable collection {@code Resolvable} must not end up as resolved at the
+ * end of the current resolve process.</li>
+ * <li>For each bundle revision {@code B} left in the shrinkable collection
+ * {@code Resolvable} and any bundle revision {@code B} which is currently
+ * resolved that represents a singleton bundle do the following:
+ * <p/>
+ * Determine the collection of available capabilities that have a namespace of
+ * {@link IdentityNamespace osgi.identity}, are singletons, and have the same
+ * symbolic name as the singleton bundle revision {@code B} and place each of
+ * the matching capabilities into a shrinkable collection {@code Collisions}.
+ * <p/>
+ * Remove the {@link IdentityNamespace osgi.identity} capability provided by
+ * bundle revision {@code B} from shrinkable collection {@code Collisions}. A
+ * singleton bundle cannot collide with itself.
+ * <p/>
+ * For each resolver hook call the
+ * {@link #filterSingletonCollisions(BundleCapability, Collection)} with the
+ * {@link IdentityNamespace osgi.identity} capability provided by bundle
+ * revision {@code B} and the shrinkable collection {@code Collisions}
+ * <p/>
+ * The shrinkable collection {@code Collisions} now contains all singleton
+ * {@link IdentityNamespace osgi.identity} capabilities that can influence the
+ * ability of bundle revision {@code B} to resolve.
+ * <p/>
+ * If the bundle revision {@code B} is already resolved then any resolvable
+ * bundle revision contained in the collection {@code Collisions} is not allowed
+ * to resolve.</li>
+ * <li>During a resolve process a framework is free to attempt to resolve any or
+ * all bundles contained in shrinkable collection {@code Resolvable}. For each
+ * bundle revision {@code B} left in the shrinkable collection
+ * {@code Resolvable} which the framework attempts to resolve the following
+ * steps must be followed:
+ * <p/>
+ * For each requirement {@code R} specified by bundle revision {@code B}
+ * determine the collection of capabilities that satisfy (or match) the
+ * requirement and place each matching capability into a shrinkable collection
+ * {@code Candidates}. A capability is considered to match a particular
+ * requirement if its attributes satisfy a specified requirement and the
+ * requirer bundle has permission to access the capability.
+ * 
+ * <p/>
+ * For each resolver hook call the
+ * {@link #filterMatches(BundleRequirement, Collection)} with the requirement
+ * {@code R} and the shrinkable collection {@code Candidates}.
+ * 
+ * <p/>
+ * The shrinkable collection {@code Candidates} now contains all the
+ * capabilities that may be used to satisfy the requirement {@code R}. Any other
+ * capabilities that got removed from the shrinkable collection
+ * {@code Candidates} must not be used to satisfy requirement {@code R}.</li>
+ * <li>For each resolver hook call the {@link #end()} method to inform the hooks
+ * about a resolve process ending.</li>
+ * </ol>
+ * In all cases, the order in which the resolver hooks are called is the reverse
+ * compareTo ordering of their Service References. That is, the service with the
+ * highest ranking number must be called first. In cases where a shrinkable
+ * collection becomes empty the framework is required to call the remaining
+ * registered hooks.
+ * <p>
+ * Resolver hooks are low level. Implementations of the resolver hook must be
+ * careful not to create an unresolvable state which is very hard for a
+ * developer or a provisioner to diagnose. Resolver hooks also must not be
+ * allowed to start another synchronous resolve process (e.g. by calling
+ * {@link Bundle#start()} or {@link FrameworkWiring#resolveBundles(Collection)}
+ * ). The framework must detect this and throw an {@link IllegalStateException}.
+ * 
+ * @see ResolverHookFactory
+ * @NotThreadSafe
+ * @version $Id: 9d3ef6240aead0952b5a47b793780c1c0589089a $
+ */
+public interface ResolverHook {
+	/**
+	 * Filter resolvable candidates hook method. This method may be called
+	 * multiple times during a single resolve process. This method can filter
+	 * the collection of candidates by removing potential candidates. Removing a
+	 * candidate will prevent the candidate from resolving during the current
+	 * resolve process.
+	 * 
+	 * @param candidates the collection of resolvable candidates available
+	 *        during a resolve process.
+	 */
+	void filterResolvable(Collection<BundleRevision> candidates);
+
+	/**
+	 * Filter singleton collisions hook method. This method is called during the
+	 * resolve process for the specified singleton. The specified singleton
+	 * represents a singleton capability and the specified collection represent
+	 * a collection of singleton capabilities which are considered collision
+	 * candidates. The singleton capability and the collection of collision
+	 * candidates must all use the same namespace.
+	 * <p>
+	 * Currently only capabilities with the namespace of {@link BundleNamespace
+	 * osgi.wiring.bundle} and {@link IdentityNamespace osgi.identity} can be
+	 * singletons. The collision candidates will all have the same namespace, be
+	 * singletons, and have the same symbolic name as the specified singleton
+	 * capability.
+	 * <p>
+	 * In the future, capabilities in other namespaces may support the singleton
+	 * concept. Hook implementations should be prepared to receive calls to this
+	 * method for capabilities in namespaces other than {@link BundleNamespace
+	 * osgi.wiring.bundle} or {@link IdentityNamespace osgi.identity}.
+	 * <p>
+	 * This method can filter the list of collision candidates by removing
+	 * potential collisions. Removing a collision candidate will allow the
+	 * specified singleton to resolve regardless of the resolution state of the
+	 * removed collision candidate.
+	 * 
+	 * @param singleton the singleton involved in a resolve process
+	 * @param collisionCandidates a collection of singleton collision candidates
+	 */
+	void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates);
+
+	/**
+	 * Filter matches hook method. This method is called during the resolve
+	 * process for the specified requirement. The collection of candidates match
+	 * the specified requirement. This method can filter the collection of
+	 * matching candidates by removing candidates from the collection. Removing
+	 * a candidate will prevent the resolve process from choosing the removed
+	 * candidate to satisfy the requirement.
+	 * <p>
+	 * All of the candidates will have the same namespace and will match the
+	 * specified requirement.
+	 * <p>
+	 * If the Java Runtime Environment supports permissions then the collection
+	 * of candidates will only contain candidates for which the requirer has
+	 * permission to access.
+	 * 
+	 * @param requirement the requirement to filter candidates for
+	 * @param candidates a collection of candidates that match the requirement
+	 */
+	void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates);
+
+	/**
+	 * This method is called once at the end of the resolve process. After the
+	 * end method is called the resolve process has ended. The framework must
+	 * not hold onto this resolver hook instance after end has been called.
+	 */
+	void end();
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/resolver/ResolverHookFactory.java b/osgi/framework/src/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
new file mode 100644
index 0000000..91ce5f7
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.resolver;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/**
+ * OSGi Framework Resolver Hook Factory Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called by the framework during a
+ * bundle resolver process to obtain a {@link ResolverHook resolver hook}
+ * instance which will be used for the duration of a resolve process.
+ * 
+ * @ThreadSafe
+ * @see ResolverHook
+ * @version $Id: e0a2f3ad081c31bbb682fa366c15a3080bf6da2b $
+ */
+public interface ResolverHookFactory {
+	/**
+	 * This method is called by the framework each time a resolve process begins
+	 * to obtain a {@link ResolverHook resolver hook} instance. This resolver
+	 * hook instance will be used for the duration of the resolve process. At
+	 * the end of the resolve process the method {@link ResolverHook#end()} must
+	 * be called by the framework and the framework must not hold any references
+	 * of the resolver hook instance.
+	 * <p>
+	 * The triggers represent the collection of bundles which triggered the
+	 * resolve process. This collection may be empty if the triggers cannot be
+	 * determined by the framework. In most cases the triggers can easily be
+	 * determined. Calling certain methods on {@link Bundle bundle} when a
+	 * bundle is in the {@link Bundle#INSTALLED INSTALLED} state will cause the
+	 * framework to begin a resolve process in order to resolve the bundle. The
+	 * following methods will start a resolve process in this case:
+	 * <ul>
+	 * <li>{@link Bundle#start() start}</li>
+	 * <li>{@link Bundle#loadClass(String) loadClass}</li>
+	 * <li>{@link Bundle#findEntries(String, String, boolean) findEntries}</li>
+	 * <li>{@link Bundle#getResource(String) getResource}</li>
+	 * <li>{@link Bundle#getResources(String) getResources}</li>
+	 * </ul>
+	 * In such cases the collection will contain the single bundle which the
+	 * framework is trying to resolve. Other cases will cause multiple bundles
+	 * to be included in the trigger bundles collection. When
+	 * {@link FrameworkWiring#resolveBundles(Collection) resolveBundles} is
+	 * called the collection of triggers must include all the current bundle
+	 * revisions for bundles passed to resolveBundles which are in the
+	 * {@link Bundle#INSTALLED INSTALLED} state.
+	 * <p>
+	 * When
+	 * {@link FrameworkWiring#refreshBundles(Collection, org.osgi.framework.FrameworkListener...)}
+	 * is called the collection of triggers is determined with the following
+	 * steps:
+	 * <ul>
+	 * <li>If the collection of bundles passed is null then
+	 * {@link FrameworkWiring#getRemovalPendingBundles()} is called to get the
+	 * initial collection of bundles.</li>
+	 * <li>The equivalent of calling
+	 * {@link FrameworkWiring#getDependencyClosure(Collection)} is called with
+	 * the initial collection of bundles to get the dependency closure
+	 * collection of the bundles being refreshed.</li>
+	 * <li>Remove any non-active bundles from the dependency closure collection.
+	 * </li>
+	 * <li>For each bundle remaining in the dependency closure collection get
+	 * the current bundle revision and add it to the collection of triggers.</li>
+	 * </ul>
+	 * <p>
+	 * As described above, a resolve process is typically initiated as a result
+	 * of calling API that causes the framework to attempt to resolve one or
+	 * more bundles. The framework is free to start a resolve process at any
+	 * time for reasons other than calls to framework API. For example, a
+	 * resolve process may be used by the framework for diagnostic purposes and
+	 * result in no bundles actually becoming resolved at the end of the
+	 * process. Resolver hook implementations must be prepared for resolve
+	 * processes that are initiated for other reasons besides calls to framework
+	 * API.
+	 * 
+	 * @param triggers an unmodifiable collection of bundles which triggered the
+	 *        resolve process. This collection may be empty if the collection of
+	 *        trigger bundles cannot be determined.
+	 * @return a resolver hook instance to be used for the duration of the
+	 *         resolve process. A {@code null} value may be returned which
+	 *         indicates this resolver hook factory abstains from the resolve
+	 *         process.
+	 */
+	ResolverHook begin(Collection<BundleRevision> triggers);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/resolver/package-info.java b/osgi/framework/src/org/osgi/framework/hooks/resolver/package-info.java
new file mode 100644
index 0000000..34fa0d0
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/resolver/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Resolver Hooks Package Version 1.0.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.hooks.resolver; version="[1.0,2.0)"}
+ * 
+ * @version $Id: 3621469ed02ccc323f6d8e1715f74537ec58e6df $
+ */
+
+package org.osgi.framework.hooks.resolver;
+
diff --git a/osgi/framework/src/org/osgi/framework/hooks/resolver/packageinfo b/osgi/framework/src/org/osgi/framework/hooks/resolver/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/resolver/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/osgi/framework/src/org/osgi/framework/hooks/service/EventHook.java b/osgi/framework/src/org/osgi/framework/hooks/service/EventHook.java
new file mode 100644
index 0000000..03a84d4
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/service/EventHook.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.service;
+
+import java.util.Collection;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+
+/**
+ * OSGi Framework Service Event Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework service
+ * (register, modify, and unregister service) operations.
+ * 
+ * @ThreadSafe
+ * @deprecated As of 1.1. Replaced by {@link EventListenerHook}.
+ * @version $Id: 84757a5f719db4d7671e81a76af2b320404ae0f5 $
+ */
+
+public interface EventHook {
+	/**
+	 * Event hook method. This method is called prior to service event delivery
+	 * when a publishing bundle registers, modifies or unregisters a service.
+	 * This method can filter the bundles which receive the event.
+	 * 
+	 * @param event The service event to be delivered.
+	 * @param contexts A collection of Bundle Contexts for bundles which have
+	 *        listeners to which the specified event will be delivered. The
+	 *        implementation of this method may remove bundle contexts from the
+	 *        collection to prevent the event from being delivered to the
+	 *        associated bundles. The collection supports all the optional
+	 *        {@code Collection} operations except {@code add} and
+	 *        {@code addAll}. Attempting to add to the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
+	 */
+	void event(ServiceEvent event, Collection<BundleContext> contexts);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/service/EventListenerHook.java b/osgi/framework/src/org/osgi/framework/hooks/service/EventListenerHook.java
new file mode 100644
index 0000000..534efc5
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/service/EventListenerHook.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.service;
+
+import java.util.Collection;
+import java.util.Map;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.hooks.service.ListenerHook.ListenerInfo;
+
+/**
+ * OSGi Framework Service Event Listener Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework service
+ * (register, modify, and unregister service) operations.
+ * 
+ * @ThreadSafe
+ * @since 1.1
+ * @version $Id: b0b99b29206f272ad479fa08ffcd5ef5fda909b8 $
+ */
+
+public interface EventListenerHook {
+	/**
+	 * Event listener hook method. This method is called prior to service event
+	 * delivery when a publishing bundle registers, modifies or unregisters a
+	 * service. This method can filter the listeners which receive the event.
+	 * 
+	 * @param event The service event to be delivered.
+	 * @param listeners A map of Bundle Contexts to a collection of Listener
+	 *        Infos for the bundle's listeners to which the specified event will
+	 *        be delivered. The implementation of this method may remove bundle
+	 *        contexts from the map and listener infos from the collection
+	 *        values to prevent the event from being delivered to the associated
+	 *        listeners. The map supports all the optional {@code Map}
+	 *        operations except {@code put} and {@code putAll}. Attempting to
+	 *        add to the map will result in an
+	 *        {@code UnsupportedOperationException}. The collection values in
+	 *        the map supports all the optional {@code Collection} operations
+	 *        except {@code add} and {@code addAll}. Attempting to add to a
+	 *        collection will result in an {@code UnsupportedOperationException}
+	 *        . The map and the collections are not synchronized.
+	 */
+	void event(ServiceEvent event, Map<BundleContext, Collection<ListenerInfo>> listeners);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/service/FindHook.java b/osgi/framework/src/org/osgi/framework/hooks/service/FindHook.java
new file mode 100644
index 0000000..4cd467c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/service/FindHook.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.service;
+
+import java.util.Collection;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * OSGi Framework Service Find Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework service find
+ * (get service references) operations.
+ * 
+ * @ThreadSafe
+ * @version $Id: 45612d6a10a25ca0b40ba695eb8dba21c2c78c24 $
+ */
+
+public interface FindHook {
+	/**
+	 * Find hook method. This method is called during the service find operation
+	 * (for example, {@link BundleContext#getServiceReferences(String, String)}
+	 * ). This method can filter the result of the find operation.
+	 * 
+	 * @param context The bundle context of the bundle performing the find
+	 *        operation.
+	 * @param name The class name of the services to find or {@code null} to
+	 *        find all services.
+	 * @param filter The filter criteria of the services to find or {@code null}
+	 *        for no filter criteria.
+	 * @param allServices {@code true} if the find operation is the result of a
+	 *        call to
+	 *        {@link BundleContext#getAllServiceReferences(String, String)}
+	 * @param references A collection of Service References to be returned as a
+	 *        result of the find operation. The implementation of this method
+	 *        may remove service references from the collection to prevent the
+	 *        references from being returned to the bundle performing the find
+	 *        operation. The collection supports all the optional
+	 *        {@code Collection} operations except {@code add} and
+	 *        {@code addAll}. Attempting to add to the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
+	 */
+	void find(BundleContext context, String name, String filter, boolean allServices, Collection<ServiceReference<?>> references);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/service/ListenerHook.java b/osgi/framework/src/org/osgi/framework/hooks/service/ListenerHook.java
new file mode 100644
index 0000000..ef933c3
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/service/ListenerHook.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.service;
+
+import java.util.Collection;
+import org.osgi.framework.BundleContext;
+
+/**
+ * OSGi Framework Service Listener Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during service listener
+ * addition and removal.
+ * 
+ * @ThreadSafe
+ * @version $Id: 94029e2b70119793b3e7d77d6e1d5052d9ee1723 $
+ */
+
+public interface ListenerHook {
+	/**
+	 * Added listeners hook method. This method is called to provide the hook
+	 * implementation with information on newly added service listeners. This
+	 * method will be called as service listeners are added while this hook is
+	 * registered. Also, immediately after registration of this hook, this
+	 * method will be called to provide the current collection of service
+	 * listeners which had been added prior to the hook being registered.
+	 * 
+	 * @param listeners A collection of {@link ListenerInfo}s for newly added
+	 *        service listeners which are now listening to service events.
+	 *        Attempting to add to or remove from the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
+	 */
+	void added(Collection<ListenerInfo> listeners);
+
+	/**
+	 * Removed listeners hook method. This method is called to provide the hook
+	 * implementation with information on newly removed service listeners. This
+	 * method will be called as service listeners are removed while this hook is
+	 * registered.
+	 * 
+	 * @param listeners A collection of {@link ListenerInfo}s for newly removed
+	 *        service listeners which are no longer listening to service events.
+	 *        Attempting to add to or remove from the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
+	 */
+	void removed(Collection<ListenerInfo> listeners);
+
+	/**
+	 * Information about a Service Listener. This interface describes the bundle
+	 * which added the Service Listener and the filter with which it was added.
+	 * 
+	 * @ThreadSafe
+	 * @noimplement
+	 */
+	public interface ListenerInfo {
+		/**
+		 * Return the context of the bundle which added the listener.
+		 * 
+		 * @return The context of the bundle which added the listener.
+		 */
+		BundleContext getBundleContext();
+
+		/**
+		 * Return the filter string with which the listener was added.
+		 * 
+		 * @return The filter string with which the listener was added. This may
+		 *         be {@code null} if the listener was added without a filter.
+		 */
+		String getFilter();
+
+		/**
+		 * Return the state of the listener for this addition and removal life
+		 * cycle. Initially this method will return {@code false} indicating the
+		 * listener has been added but has not been removed. After the listener
+		 * has been removed, this method must always return {@code true}.
+		 * 
+		 * <p>
+		 * There is an extremely rare case in which removed notification to
+		 * {@link ListenerHook}s can be made before added notification if two
+		 * threads are racing to add and remove the same service listener.
+		 * Because {@link ListenerHook}s are called synchronously during service
+		 * listener addition and removal, the Framework cannot guarantee
+		 * in-order delivery of added and removed notification for a given
+		 * service listener. This method can be used to detect this rare
+		 * occurrence.
+		 * 
+		 * @return {@code false} if the listener has not been been removed,
+		 *         {@code true} otherwise.
+		 */
+		boolean isRemoved();
+
+		/**
+		 * Compares this {@code ListenerInfo} to another {@code ListenerInfo}.
+		 * Two {@code ListenerInfo}s are equals if they refer to the same
+		 * listener for a given addition and removal life cycle. If the same
+		 * listener is added again, it must have a different
+		 * {@code ListenerInfo} which is not equal to this {@code ListenerInfo}.
+		 * 
+		 * @param obj The object to compare against this {@code ListenerInfo}.
+		 * @return {@code true} if the other object is a {@code ListenerInfo}
+		 *         object and both objects refer to the same listener for a
+		 *         given addition and removal life cycle.
+		 */
+		boolean equals(Object obj);
+
+		/**
+		 * Returns the hash code for this {@code ListenerInfo}.
+		 * 
+		 * @return The hash code of this {@code ListenerInfo}.
+		 */
+		int hashCode();
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/service/package-info.java b/osgi/framework/src/org/osgi/framework/hooks/service/package-info.java
new file mode 100644
index 0000000..bda04f7
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/service/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Service Hooks Package Version 1.1.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.hooks.service; version="[1.1,2.0)"}
+ * 
+ * @version $Id: 80468eff0eb0820494b56e05605e5cb1b6087c24 $
+ */
+
+package org.osgi.framework.hooks.service;
+
diff --git a/osgi/framework/src/org/osgi/framework/hooks/service/packageinfo b/osgi/framework/src/org/osgi/framework/hooks/service/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/service/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/osgi/framework/src/org/osgi/framework/hooks/weaving/WeavingException.java b/osgi/framework/src/org/osgi/framework/hooks/weaving/WeavingException.java
new file mode 100644
index 0000000..8842797
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/weaving/WeavingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.weaving;
+
+/**
+ * A weaving exception used to indicate that the class load should be failed but
+ * the weaving hook must not be blacklisted by the framework.
+ * 
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ * 
+ * @version $Id: eb38b85f6ed66ec445fb2f0ee7143df021327a9a $
+ */
+
+public class WeavingException extends RuntimeException {
+	private static final long	serialVersionUID	= 1L;
+
+	/**
+	 * Creates a {@code WeavingException} with the specified message and
+	 * exception cause.
+	 * 
+	 * @param msg The associated message.
+	 * @param cause The cause of this exception.
+	 */
+	public WeavingException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+
+	/**
+	 * Creates a {@code WeavingException} with the specified message.
+	 * 
+	 * @param msg The message.
+	 */
+	public WeavingException(String msg) {
+		super(msg);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/weaving/WeavingHook.java b/osgi/framework/src/org/osgi/framework/hooks/weaving/WeavingHook.java
new file mode 100644
index 0000000..be57658
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/weaving/WeavingHook.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.weaving;
+
+/**
+ * OSGi Framework Weaving Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework class
+ * loading operations. Weaving hook services are called when a class is being
+ * loaded by the framework and have an opportunity to transform the class file
+ * bytes that represents the class being loaded. Weaving hooks may also ask the
+ * framework to wire in additional dynamic imports to the bundle.
+ * 
+ * <p>
+ * When a class is being loaded, the framework will create a {@link WovenClass}
+ * object for the class and pass it to each registered weaving hook service for
+ * possible modification. The first weaving hook called will see the original
+ * class file bytes. Subsequently called weaving hooks will see the class file
+ * bytes as modified by previously called weaving hooks.
+ * 
+ * @ThreadSafe
+ * @version $Id: d1985029024baba2db1c56aab1e06ee953fd6365 $
+ */
+
+public interface WeavingHook {
+	/**
+	 * Weaving hook method.
+	 * 
+	 * This method can modify the specified woven class object to weave the
+	 * class being defined.
+	 * 
+	 * <p>
+	 * If this method throws any exception, the framework must log the exception
+	 * and fail the class load in progress. This weaving hook service must be
+	 * blacklisted by the framework and must not be called again. The
+	 * blacklisting of this weaving hook service must expire when this weaving
+	 * hook service is unregistered. However, this method can throw a
+	 * {@link WeavingException} to deliberately fail the class load in progress
+	 * without being blacklisted by the framework.
+	 * 
+	 * @param wovenClass The {@link WovenClass} object that represents the data
+	 *        that will be used to define the class.
+	 * @throws WeavingException If this weaving hook wants to deliberately fail
+	 *         the class load in progress without being blacklisted by the
+	 *         framework
+	 */
+	public void weave(WovenClass wovenClass);
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/weaving/WovenClass.java b/osgi/framework/src/org/osgi/framework/hooks/weaving/WovenClass.java
new file mode 100644
index 0000000..697a435
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/weaving/WovenClass.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.weaving;
+
+import java.security.ProtectionDomain;
+import java.util.List;
+import org.osgi.framework.wiring.BundleWiring;
+
+/**
+ * A class being woven.
+ * 
+ * This object represents a class being woven and is passed to each
+ * {@link WeavingHook} for possible modification. It allows access to the most
+ * recently transformed class file bytes and to any additional packages that
+ * should be added to the bundle as dynamic imports.
+ * 
+ * <p>
+ * After weaving is {@link #isWeavingComplete() complete}, this object becomes
+ * effectively immutable.
+ * 
+ * @NotThreadSafe
+ * @noimplement
+ * @version $Id: 549caef41027c8f0d0fdb4deae756eae6b69d1ee $
+ */
+public interface WovenClass {
+
+	/**
+	 * Returns the class file bytes to be used to define the
+	 * {@link WovenClass#getClassName() named} class.
+	 * 
+	 * <p>
+	 * While weaving is not {@link #isWeavingComplete() complete}, this method
+	 * returns a reference to the class files byte array contained in this
+	 * object. After weaving is {@link #isWeavingComplete() complete}, this
+	 * object becomes effectively immutable and a copy of the class file byte
+	 * array is returned.
+	 * 
+	 * @return The bytes to be used to define the
+	 *         {@link WovenClass#getClassName() named} class.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,WEAVE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	public byte[] getBytes();
+
+	/**
+	 * Set the class file bytes to be used to define the
+	 * {@link WovenClass#getClassName() named} class. This method must not be
+	 * called outside invocations of the {@link WeavingHook#weave(WovenClass)
+	 * weave} method by the framework.
+	 * 
+	 * <p>
+	 * While weaving is not {@link #isWeavingComplete() complete}, this method
+	 * replaces the reference to the array contained in this object with the
+	 * specified array. After weaving is {@link #isWeavingComplete() complete},
+	 * this object becomes effectively immutable and this method will throw an
+	 * {@link IllegalStateException}.
+	 * 
+	 * @param newBytes The new classfile that will be used to define the
+	 *        {@link WovenClass#getClassName() named} class. The specified array
+	 *        is retained by this object and the caller must not modify the
+	 *        specified array.
+	 * @throws NullPointerException If newBytes is {@code null}.
+	 * @throws IllegalStateException If weaving is {@link #isWeavingComplete()
+	 *         complete}.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,WEAVE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	public void setBytes(byte[] newBytes);
+
+	/**
+	 * Returns the list of dynamic import package descriptions to add to the
+	 * {@link #getBundleWiring() bundle wiring} for this woven class. Changes
+	 * made to the returned list will be visible to later {@link WeavingHook
+	 * weaving hooks} called with this object. The returned list must not be
+	 * modified outside invocations of the {@link WeavingHook#weave(WovenClass)
+	 * weave} method by the framework.
+	 * 
+	 * <p>
+	 * After weaving is {@link #isWeavingComplete() complete}, this object
+	 * becomes effectively immutable and the returned list will be unmodifiable.
+	 * 
+	 * <p>
+	 * If the Java runtime environment supports permissions, the caller must
+	 * have {@code AdminPermission[bundle,WEAVE]} to modify the returned list.
+	 * 
+	 * @return A list containing zero or more dynamic import package
+	 *         descriptions to add to the bundle wiring for this woven class.
+	 *         This list must throw {@code IllegalArgumentException} if a
+	 *         malformed dynamic import package description is added.
+	 * @see "Core Specification, Dynamic Import Package, for the syntax of a dynamic import package description."
+	 */
+	public List<String> getDynamicImports();
+
+	/**
+	 * Returns whether weaving is complete in this woven class. Weaving is
+	 * complete after the last {@link WeavingHook weaving hook} is called and
+	 * the class is defined.
+	 * 
+	 * <p>
+	 * After weaving is complete, this object becomes effectively immutable.
+	 * 
+	 * @return {@code true} weaving is complete, {@code false} otherwise.
+	 */
+	public boolean isWeavingComplete();
+
+	/**
+	 * Returns the fully qualified name of the class being woven.
+	 * 
+	 * @return The fully qualified name of the class being woven.
+	 */
+	public String getClassName();
+
+	/**
+	 * Returns the protection domain to which the woven class will be assigned
+	 * when it is defined.
+	 * 
+	 * @return The protection domain to which the woven class will be assigned
+	 *         when it is defined, or {@code null} if no protection domain will
+	 *         be assigned.
+	 */
+	public ProtectionDomain getProtectionDomain();
+
+	/**
+	 * Returns the class defined by this woven class. During weaving, this
+	 * method will return {@code null}. Once weaving is
+	 * {@link #isWeavingComplete() complete}, this method will return the class
+	 * object if this woven class was used to define the class.
+	 * 
+	 * @return The class associated with this woven class, or {@code null} if
+	 *         weaving is not complete, the class definition failed or this
+	 *         woven class was not used to define the class.
+	 */
+	public Class<?> getDefinedClass();
+
+	/**
+	 * Returns the bundle wiring whose class loader will define the woven class.
+	 * 
+	 * @return The bundle wiring whose class loader will define the woven class.
+	 */
+	public BundleWiring getBundleWiring();
+}
diff --git a/osgi/framework/src/org/osgi/framework/hooks/weaving/package-info.java b/osgi/framework/src/org/osgi/framework/hooks/weaving/package-info.java
new file mode 100644
index 0000000..e529707
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/weaving/package-info.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Weaving Hooks Package Version 1.0.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * </p>
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * </p>
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.hooks.weaving; version="[1.0,2.0)"}
+ * </p>
+ * @version $Id: 8b788094aec5fd8ca4d2dfe6a8e4afc04a461290 $
+ */
+
+package org.osgi.framework.hooks.weaving;
+
diff --git a/osgi/framework/src/org/osgi/framework/hooks/weaving/packageinfo b/osgi/framework/src/org/osgi/framework/hooks/weaving/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/hooks/weaving/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/osgi/framework/src/org/osgi/framework/launch/Framework.java b/osgi/framework/src/org/osgi/framework/launch/Framework.java
new file mode 100644
index 0000000..54d599b
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/launch/Framework.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.launch;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+
+/**
+ * A Framework instance. A Framework is also known as a System Bundle.
+ * 
+ * <p>
+ * Framework instances are created using a {@link FrameworkFactory}. The methods
+ * of this interface can be used to manage and control the created framework
+ * instance.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: e76240d5de584d1666880d9bc358571a76cbd8fb $
+ */
+public interface Framework extends Bundle {
+
+	/**
+	 * Initialize this Framework. After calling this method, this Framework
+	 * must:
+	 * <ul>
+	 * <li>Have generated a new {@link Constants#FRAMEWORK_UUID framework UUID}.
+	 * </li>
+	 * <li>Be in the {@link #STARTING} state.</li>
+	 * <li>Have a valid Bundle Context.</li>
+	 * <li>Be at start level 0.</li>
+	 * <li>Have event handling enabled.</li>
+	 * <li>Have reified Bundle objects for all installed bundles.</li>
+	 * <li>Have registered any framework services. For example,
+	 * {@code ConditionalPermissionAdmin}.</li>
+	 * <li>Be {@link #adapt(Class) adaptable} to the OSGi defined types to which
+	 * a system bundle can be adapted.</li>
+	 * </ul>
+	 * 
+	 * <p>
+	 * This Framework will not actually be started until {@link #start() start}
+	 * is called.
+	 * 
+	 * <p>
+	 * This method does nothing if called when this Framework is in the
+	 * {@link #STARTING}, {@link #ACTIVE} or {@link #STOPPING} states.
+	 * 
+	 * @throws BundleException If this Framework could not be initialized.
+	 * @throws SecurityException If the Java Runtime Environment supports
+	 *         permissions and the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]} or if there is a security
+	 *         manager already installed and the
+	 *         {@link Constants#FRAMEWORK_SECURITY} configuration property is
+	 *         set.
+	 * 
+	 */
+	void init() throws BundleException;
+
+	/**
+	 * Wait until this Framework has completely stopped. The {@code stop} and
+	 * {@code update} methods on a Framework performs an asynchronous stop of
+	 * the Framework. This method can be used to wait until the asynchronous
+	 * stop of this Framework has completed. This method will only wait if
+	 * called when this Framework is in the {@link #STARTING}, {@link #ACTIVE},
+	 * or {@link #STOPPING} states. Otherwise it will return immediately.
+	 * <p>
+	 * A Framework Event is returned to indicate why this Framework has stopped.
+	 * 
+	 * @param timeout Maximum number of milliseconds to wait until this
+	 *        Framework has completely stopped. A value of zero will wait
+	 *        indefinitely.
+	 * @return A Framework Event indicating the reason this method returned. The
+	 *         following {@code FrameworkEvent} types may be returned by this
+	 *         method.
+	 *         <ul>
+	 *         <li>{@link FrameworkEvent#STOPPED STOPPED} - This Framework has
+	 *         been stopped. </li>
+	 * 
+	 *         <li>{@link FrameworkEvent#STOPPED_UPDATE STOPPED_UPDATE} - This
+	 *         Framework has been updated which has shutdown and will now
+	 *         restart.</li>
+	 * 
+	 *         <li> {@link FrameworkEvent#STOPPED_BOOTCLASSPATH_MODIFIED
+	 *         STOPPED_BOOTCLASSPATH_MODIFIED} - This Framework has been stopped
+	 *         and a bootclasspath extension bundle has been installed or
+	 *         updated. The VM must be restarted in order for the changed boot
+	 *         class path to take effect. </li>
+	 * 
+	 *         <li>{@link FrameworkEvent#ERROR ERROR} - The Framework
+	 *         encountered an error while shutting down or an error has occurred
+	 *         which forced the framework to shutdown. </li>
+	 * 
+	 *         <li> {@link FrameworkEvent#WAIT_TIMEDOUT WAIT_TIMEDOUT} - This
+	 *         method has timed out and returned before this Framework has
+	 *         stopped.</li>
+	 *         </ul>
+	 * @throws InterruptedException If another thread interrupted the current
+	 *         thread before or while the current thread was waiting for this
+	 *         Framework to completely stop. The <i>interrupted status</i> of
+	 *         the current thread is cleared when this exception is thrown.
+	 * @throws IllegalArgumentException If the value of timeout is negative.
+	 */
+	FrameworkEvent waitForStop(long timeout) throws InterruptedException;
+
+	/**
+	 * Start this Framework.
+	 * 
+	 * <p>
+	 * The following steps are taken to start this Framework:
+	 * <ol>
+	 * <li>If this Framework is not in the {@link #STARTING} state,
+	 * {@link #init() initialize} this Framework.</li>
+	 * <li>All installed bundles must be started in accordance with each
+	 * bundle's persistent <i>autostart setting</i>. This means some bundles
+	 * will not be started, some will be started with <i>eager activation</i>
+	 * and some will be started with their <i>declared activation</i> policy.
+	 * The start level of this Framework is moved to the start level specified
+	 * by the {@link Constants#FRAMEWORK_BEGINNING_STARTLEVEL beginning start
+	 * level} framework property, as described in the <i>Start Level
+	 * Specification</i>. If this framework property is not specified, then the
+	 * start level of this Framework is moved to start level one (1). Any
+	 * exceptions that occur during bundle starting must be wrapped in a
+	 * {@link BundleException} and then published as a framework event of type
+	 * {@link FrameworkEvent#ERROR}</li>
+	 * <li>This Framework's state is set to {@link #ACTIVE}.</li>
+	 * <li>A framework event of type {@link FrameworkEvent#STARTED} is fired</li>
+	 * </ol>
+	 * 
+	 * @throws BundleException If this Framework could not be started.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see "Start Level Specification"
+	 */
+	void start() throws BundleException;
+
+	/**
+	 * Start this Framework.
+	 * 
+	 * <p>
+	 * Calling this method is the same as calling {@link #start()}. There are no
+	 * start options for the Framework.
+	 * 
+	 * @param options Ignored. There are no start options for the Framework.
+	 * @throws BundleException If this Framework could not be started.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see #start()
+	 */
+	void start(int options) throws BundleException;
+
+	/**
+	 * Stop this Framework.
+	 * 
+	 * <p>
+	 * The method returns immediately to the caller after initiating the
+	 * following steps to be taken on another thread.
+	 * <ol>
+	 * <li>This Framework's state is set to {@link #STOPPING}.</li>
+	 * <li>All installed bundles must be stopped without changing each bundle's
+	 * persistent <i>autostart setting</i>. The start level of this Framework is
+	 * moved to start level zero (0), as described in the <i>Start Level
+	 * Specification</i>. Any exceptions that occur during bundle stopping must
+	 * be wrapped in a {@link BundleException} and then published as a framework
+	 * event of type {@link FrameworkEvent#ERROR}</li>
+	 * <li>Unregister all services registered by this Framework.</li>
+	 * <li>Event handling is disabled.</li>
+	 * <li>This Framework's state is set to {@link #RESOLVED}.</li>
+	 * <li>All resources held by this Framework are released. This includes
+	 * threads, bundle class loaders, open files, etc.</li>
+	 * <li>Notify all threads that are waiting at {@link #waitForStop(long)
+	 * waitForStop} that the stop operation has completed.</li>
+	 * </ol>
+	 * <p>
+	 * After being stopped, this Framework may be discarded, initialized or
+	 * started.
+	 * 
+	 * @throws BundleException If stopping this Framework could not be
+	 *         initiated.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see "Start Level Specification"
+	 */
+	void stop() throws BundleException;
+
+	/**
+	 * Stop this Framework.
+	 * 
+	 * <p>
+	 * Calling this method is the same as calling {@link #stop()}. There are no
+	 * stop options for the Framework.
+	 * 
+	 * @param options Ignored. There are no stop options for the Framework.
+	 * @throws BundleException If stopping this Framework could not be
+	 *         initiated.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see #stop()
+	 */
+	void stop(int options) throws BundleException;
+
+	/**
+	 * The Framework cannot be uninstalled.
+	 * 
+	 * <p>
+	 * This method always throws a BundleException.
+	 * 
+	 * @throws BundleException This Framework cannot be uninstalled.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 */
+	void uninstall() throws BundleException;
+
+	/**
+	 * Stop and restart this Framework.
+	 * 
+	 * <p>
+	 * The method returns immediately to the caller after initiating the
+	 * following steps to be taken on another thread.
+	 * <ol>
+	 * <li>Perform the steps in the {@link #stop()} method to stop this
+	 * Framework.</li>
+	 * <li>Perform the steps in the {@link #start()} method to start this
+	 * Framework.</li>
+	 * </ol>
+	 * 
+	 * @throws BundleException If stopping and restarting this Framework could
+	 *         not be initiated.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 */
+	void update() throws BundleException;
+
+	/**
+	 * Stop and restart this Framework.
+	 * 
+	 * <p>
+	 * Calling this method is the same as calling {@link #update()} except that
+	 * any provided InputStream is immediately closed.
+	 * 
+	 * @param in Any provided InputStream is immediately closed before returning
+	 *        from this method and otherwise ignored.
+	 * @throws BundleException If stopping and restarting this Framework could
+	 *         not be initiated.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 */
+	void update(InputStream in) throws BundleException;
+
+	/**
+	 * Returns the Framework unique identifier. This Framework is assigned the
+	 * unique identifier zero (0) since this Framework is also a System Bundle.
+	 * 
+	 * @return 0.
+	 * @see Bundle#getBundleId()
+	 */
+	long getBundleId();
+
+	/**
+	 * Returns the Framework location identifier. This Framework is assigned the
+	 * unique location "{@code System Bundle}" since this Framework is
+	 * also a System Bundle.
+	 * 
+	 * @return The string "{@code System Bundle}".
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @see Bundle#getLocation()
+	 * @see Constants#SYSTEM_BUNDLE_LOCATION
+	 */
+	String getLocation();
+
+	/**
+	 * Returns the symbolic name of this Framework. The symbolic name is unique
+	 * for the implementation of the framework. However, the symbolic name
+	 * "{@code system.bundle}" must be recognized as an alias to the
+	 * implementation-defined symbolic name since this Framework is also a
+	 * System Bundle.
+	 * 
+	 * @return The symbolic name of this Framework.
+	 * @see Bundle#getSymbolicName()
+	 * @see Constants#SYSTEM_BUNDLE_SYMBOLICNAME
+	 */
+	String getSymbolicName();
+
+	/**
+	 * Returns {@code null} as a framework implementation does not have a proper
+	 * bundle from which to return entry paths.
+	 * 
+	 * @param path Ignored.
+	 * @return {@code null} as a framework implementation does not have a proper
+	 *         bundle from which to return entry paths.
+	 */
+	Enumeration<String> getEntryPaths(String path);
+
+	/**
+	 * Returns {@code null} as a framework implementation does not have a proper
+	 * bundle from which to return an entry.
+	 * 
+	 * @param path Ignored.
+	 * @return {@code null} as a framework implementation does not have a proper
+	 *         bundle from which to return an entry.
+	 */
+	URL getEntry(String path);
+
+	/**
+	 * Returns {@code null} as a framework implementation does not have a proper
+	 * bundle from which to return entries.
+	 * 
+	 * @param path Ignored.
+	 * @param filePattern Ignored.
+	 * @param recurse Ignored.
+	 * @return {@code null} as a framework implementation does not have a proper
+	 *         bundle from which to return entries.
+	 */
+	Enumeration<URL> findEntries(String path, String filePattern, boolean recurse);
+
+	/**
+	 * Adapt this Framework to the specified type.
+	 * 
+	 * <p>
+	 * Adapting this Framework to the specified type may require certain checks,
+	 * including security checks, to succeed. If a check does not succeed, then
+	 * this Framework cannot be adapted and {@code null} is returned. If this
+	 * Framework is not {@link #init() initialized}, then {@code null} is
+	 * returned if the specified type is one of the OSGi defined types to which
+	 * a system bundle can be adapted.
+	 * 
+	 * @param <A> The type to which this Framework is to be adapted.
+	 * @param type Class object for the type to which this Framework is to be
+	 *        adapted.
+	 * @return The object, of the specified type, to which this Framework has
+	 *         been adapted or {@code null} if this Framework cannot be adapted
+	 */
+	<A> A adapt(Class<A> type);
+}
diff --git a/osgi/framework/src/org/osgi/framework/launch/FrameworkFactory.java b/osgi/framework/src/org/osgi/framework/launch/FrameworkFactory.java
new file mode 100644
index 0000000..bac0183
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/launch/FrameworkFactory.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.launch;
+
+import java.util.Map;
+import org.osgi.framework.Bundle;
+
+/**
+ * A factory for creating {@link Framework} instances.
+ * 
+ * <p>
+ * A framework implementation jar must contain the following resource:
+ * 
+ * <pre>
+ * /META-INF/services/org.osgi.framework.launch.FrameworkFactory
+ * </pre>
+ * 
+ * This UTF-8 encoded resource must contain the name of the framework
+ * implementation's FrameworkFactory implementation class. Space and tab
+ * characters, including blank lines, in the resource must be ignored. The
+ * number sign ({@code '#'} \u0023) and all characters following it on each
+ * line are a comment and must be ignored.
+ * 
+ * <p>
+ * Launchers can find the name of the FrameworkFactory implementation class in
+ * the resource and then load and construct a FrameworkFactory object for the
+ * framework implementation. The FrameworkFactory implementation class must have
+ * a public, no-argument constructor. Java™ SE 6 introduced the
+ * {@code ServiceLoader} class which can create a FrameworkFactory instance from
+ * the resource.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 1684e14aa98a1f6e1ff3e0f3afa2c55982210f72 $
+ */
+public interface FrameworkFactory {
+
+	/**
+	 * Create a new {@link Framework} instance.
+	 * 
+	 * @param configuration The framework properties to configure the new
+	 *        framework instance. If framework properties are not provided by
+	 *        the configuration argument, the created framework instance must
+	 *        use some reasonable default configuration appropriate for the
+	 *        current VM. For example, the system packages for the current
+	 *        execution environment should be properly exported. The specified
+	 *        configuration argument may be {@code null}. The created framework
+	 *        instance must copy any information needed from the specified
+	 *        configuration argument since the configuration argument can be
+	 *        changed after the framework instance has been created.
+	 * @return A new, configured {@link Framework} instance. The framework
+	 *         instance must be in the {@link Bundle#INSTALLED} state.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}, and the Java Runtime Environment supports
+	 *         permissions.
+	 */
+	Framework newFramework(Map<String, String> configuration);
+}
diff --git a/osgi/framework/src/org/osgi/framework/launch/package-info.java b/osgi/framework/src/org/osgi/framework/launch/package-info.java
new file mode 100644
index 0000000..a1c54d4
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/launch/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Launch Package Version 1.1.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.launch; version="[1.1,2.0)"}
+ *
+ * @version $Id: f1e5d25386dfcda77fb66659963a62209c4f6d60 $
+ */
+
+package org.osgi.framework.launch;
+
diff --git a/osgi/framework/src/org/osgi/framework/launch/packageinfo b/osgi/framework/src/org/osgi/framework/launch/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/launch/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/osgi/framework/src/org/osgi/framework/namespace/AbstractWiringNamespace.java b/osgi/framework/src/org/osgi/framework/namespace/AbstractWiringNamespace.java
new file mode 100644
index 0000000..52563e2
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/AbstractWiringNamespace.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Wiring Capability and Requirement Namespaces base class.
+ * 
+ * <p>
+ * This class is the common class shared by all OSGi defined wiring namespaces.
+ * It defines the names for the common attributes and directives for the OSGi
+ * specified wiring namespaces.
+ * 
+ * <p>
+ * The values associated with these keys are of type {@code String}, unless
+ * otherwise indicated.
+ * 
+ * @Immutable
+ * @version $Id: 383e84df9190757ce6bb6fb722e80a3b7d6b68da $
+ */
+public abstract class AbstractWiringNamespace extends Namespace {
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * mandatory attributes which must be specified in the
+	 * {@link Namespace#REQUIREMENT_FILTER_DIRECTIVE filter} of a requirement in
+	 * order for the capability to match the requirement.
+	 */
+	public final static String	CAPABILITY_MANDATORY_DIRECTIVE		= "mandatory";
+
+	/**
+	 * The capability attribute contains the {@code Version} of the resource
+	 * providing the capability if one is specified or {@code 0.0.0} if not
+	 * specified. The value of this attribute must be of type {@code Version}.
+	 */
+	public static final String	CAPABILITY_BUNDLE_VERSION_ATTRIBUTE	= "bundle-version";
+
+	AbstractWiringNamespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/namespace/BundleNamespace.java b/osgi/framework/src/org/osgi/framework/namespace/BundleNamespace.java
new file mode 100644
index 0000000..84b6700
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/BundleNamespace.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Bundle Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Unless otherwise noted, all directives specified on the
+ * {@code Bundle-SymbolicName} header are visible in the capability and all
+ * directives specified on the {@code Require-Bundle} header are visible in the
+ * requirement.
+ * 
+ * <ul>
+ * <li>The {@link Namespace#CAPABILITY_USES_DIRECTIVE uses} directive must be
+ * ignored. A {@code uses} directive specified on the
+ * {@code Bundle-SymbolicName} header must be ignored. A {@code uses} directive
+ * must not be present in the capability.</li>
+ * <li>The {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE effective}
+ * {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE directives} must be ignored.
+ * This namespace is only effective at {@link Namespace#EFFECTIVE_RESOLVE
+ * resolve} time. An {@code effective} directive specified on the
+ * {@code Bundle-SymbolicName} or {@code Require-Bundle} headers must be
+ * ignored. An {@code effective} directive must not be present in a capability
+ * or requirement.</li>
+ * <li>The {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE cardinality}
+ * directive must be ignored. A {@code cardinality} directive specified on the
+ * {@code Require-Bundle} header must be ignored. A {@code cardinality}
+ * directive must not be present in a requirement.</li>
+ * </ul>
+ * 
+ * <p>
+ * A non-fragment resource with the {@link IdentityNamespace#TYPE_BUNDLE
+ * osgi.bundle} type {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ * identity} provides exactly one<sup>†</sup> bundle capability (that is,
+ * the bundle can be required by another bundle). A fragment resource with the
+ * {@link IdentityNamespace#TYPE_FRAGMENT osgi.fragment} type
+ * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} must not declare
+ * a bundle capability. A resource requires zero or more bundle requirements
+ * (that is, required bundles).
+ * <p>
+ * † A resource with no symbolic name must not provide a bundle
+ * capability.
+ * 
+ * @Immutable
+ * @version $Id: 339f1204725aa9d9c2463b1224b2e38e505024e9 $
+ */
+public final class BundleNamespace extends AbstractWiringNamespace {
+
+	/**
+	 * Namespace name for bundle capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the symbolic name of the
+	 * bundle.
+	 */
+	public static final String	BUNDLE_NAMESPACE							= "osgi.wiring.bundle";
+
+	/**
+	 * The capability directive identifying if the resource is a singleton. A
+	 * {@code String} value of "{@code true}" indicates the resource
+	 * is a singleton; any other value or {@code null} indicates the resource is
+	 * not a singleton.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link IdentityNamespace
+	 * identity} namespace.
+	 * 
+	 * @see IdentityNamespace#CAPABILITY_SINGLETON_DIRECTIVE
+	 */
+	public static final String	CAPABILITY_SINGLETON_DIRECTIVE				= "singleton";
+
+	/**
+	 * The capability directive identifying if and when a fragment may attach to
+	 * a host bundle.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link HostNamespace host}
+	 * namespace.
+	 * 
+	 * @see HostNamespace#CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE	= "fragment-attachment";
+
+	/**
+	 * The requirement directive used to specify the type of the extension
+	 * fragment.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link HostNamespace host}
+	 * namespace.
+	 * 
+	 * @see HostNamespace#REQUIREMENT_EXTENSION_DIRECTIVE
+	 */
+	public final static String	REQUIREMENT_EXTENSION_DIRECTIVE				= "extension";
+
+	/**
+	 * The requirement directive used to specify the visibility type for a
+	 * requirement. The default value is {@link #VISIBILITY_PRIVATE private}.
+	 * 
+	 * @see #VISIBILITY_PRIVATE private
+	 * @see #VISIBILITY_REEXPORT reexport
+	 */
+	public final static String	REQUIREMENT_VISIBILITY_DIRECTIVE			= "visibility";
+
+	/**
+	 * The directive value identifying a private
+	 * {@link #REQUIREMENT_VISIBILITY_DIRECTIVE visibility} type. A private
+	 * visibility type indicates that any {@link PackageNamespace packages} that
+	 * are exported by the required bundle are not made visible on the export
+	 * signature of the requiring bundle. .
+	 * 
+	 * @see #REQUIREMENT_VISIBILITY_DIRECTIVE
+	 */
+	public final static String	VISIBILITY_PRIVATE							= "private";
+
+	/**
+	 * The directive value identifying a reexport
+	 * {@link #REQUIREMENT_VISIBILITY_DIRECTIVE visibility} type. A reexport
+	 * visibility type indicates any {@link PackageNamespace packages} that are
+	 * exported by the required bundle are re-exported by the requiring bundle.
+	 * 
+	 * @see #REQUIREMENT_VISIBILITY_DIRECTIVE
+	 */
+	public final static String	VISIBILITY_REEXPORT							= "reexport";
+
+	private BundleNamespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/namespace/ExecutionEnvironmentNamespace.java b/osgi/framework/src/org/osgi/framework/namespace/ExecutionEnvironmentNamespace.java
new file mode 100644
index 0000000..5328cae
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/ExecutionEnvironmentNamespace.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Execution Environment Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * @Immutable
+ * @version $Id: e1c30aac8efacc1b21ab20ffebcc1af30a1054a8 $
+ */
+public final class ExecutionEnvironmentNamespace extends Namespace {
+
+	/**
+	 * Namespace name for execution environment capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the name of the execution
+	 * environment.
+	 */
+	public static final String	EXECUTION_ENVIRONMENT_NAMESPACE	= "osgi.ee";
+
+	/**
+	 * The capability attribute contains the versions of the execution
+	 * environment. The value of this attribute must be of type
+	 * {@code List<Version>}.
+	 */
+	public final static String	CAPABILITY_VERSION_ATTRIBUTE	= "version";
+
+	private ExecutionEnvironmentNamespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/namespace/HostNamespace.java b/osgi/framework/src/org/osgi/framework/namespace/HostNamespace.java
new file mode 100644
index 0000000..5964cf5
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/HostNamespace.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Host Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Unless otherwise noted, all directives specified on the
+ * {@code Bundle-SymbolicName} header are visible in the capability and all
+ * directives specified on the {@code Fragment-Host} header are visible in the
+ * requirement.
+ * 
+ * <ul>
+ * <li>The {@link Namespace#CAPABILITY_USES_DIRECTIVE uses} directive must be
+ * ignored. A {@code uses} directive specified on the
+ * {@code Bundle-SymbolicName} header must be ignored. A {@code uses} directive
+ * must not be present in the capability.</li>
+ * <li>The {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE effective}
+ * {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE directives} must be ignored.
+ * This namespace is only effective at {@link Namespace#EFFECTIVE_RESOLVE
+ * resolve} time. An {@code effective} directive specified on the
+ * {@code Bundle-SymbolicName} or {@code Fragment-Host} headers must be ignored.
+ * An {@code effective} directive must not be present in a capability or
+ * requirement.</li>
+ * <li>The {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE cardinality}
+ * directive has limited applicability to this namespace. A {@code cardinality}
+ * directive specified on the {@code Fragment-Host} header must be ignored. All
+ * requirements must have the {@code cardinality} directive set to
+ * {@link Namespace#CARDINALITY_MULTIPLE multiple}.</li>
+ * </ul>
+ * 
+ * <p>
+ * A non-fragment resource with the with the
+ * {@link IdentityNamespace#TYPE_BUNDLE osgi.bundle} type
+ * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} provides zero or
+ * one<sup>†</sup> host capabilities. A fragment resource with the
+ * {@link IdentityNamespace#TYPE_FRAGMENT osgi.fragment} type
+ * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} must not declare
+ * a host capability and must declare exactly one host requirement.
+ * <p>
+ * † A resource with no bundle symbolic name must not provide a host
+ * capability.
+ * 
+ * @Immutable
+ * @version $Id: aa3cc744c7b9c21d908260f456567ab8a6de1430 $
+ */
+public final class HostNamespace extends AbstractWiringNamespace {
+
+	/**
+	 * Namespace name for host capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the symbolic name of the
+	 * host.
+	 * 
+	 */
+	public static final String	HOST_NAMESPACE								= "osgi.wiring.host";
+
+	/**
+	 * The capability directive identifying if the resource is a singleton. A
+	 * {@code String} value of "{@code true}" indicates the resource
+	 * is a singleton; any other value or {@code null} indicates the resource is
+	 * not a singleton.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link IdentityNamespace
+	 * identity} namespace.
+	 * 
+	 * @see IdentityNamespace#CAPABILITY_SINGLETON_DIRECTIVE
+	 */
+	public static final String	CAPABILITY_SINGLETON_DIRECTIVE				= "singleton";
+
+	/**
+	 * The capability directive identifying if and when a fragment may attach to
+	 * a host bundle. The default value is {@link #FRAGMENT_ATTACHMENT_ALWAYS
+	 * always}.
+	 * 
+	 * @see #FRAGMENT_ATTACHMENT_ALWAYS
+	 * @see #FRAGMENT_ATTACHMENT_RESOLVETIME
+	 * @see #FRAGMENT_ATTACHMENT_NEVER
+	 */
+	public static final String	CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE	= "fragment-attachment";
+
+	/**
+	 * The directive value indicating that fragments are allowed to attach to
+	 * the host bundle at any time (while the host is resolved or during the
+	 * process of resolving the host bundle).
+	 * 
+	 * @see #CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	FRAGMENT_ATTACHMENT_ALWAYS					= "always";
+
+	/**
+	 * The directive value indicating that fragments are allowed to attach to
+	 * the host bundle only during the process of resolving the host bundle.
+	 * 
+	 * @see #CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	FRAGMENT_ATTACHMENT_RESOLVETIME				= "resolve-time";
+
+	/**
+	 * The directive value indicating that no fragments are allowed to attach to
+	 * the host bundle at any time.
+	 * 
+	 * @see #CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	FRAGMENT_ATTACHMENT_NEVER					= "never";
+
+	/**
+	 * The requirement directive used to specify the type of the extension
+	 * fragment.
+	 * 
+	 * @see #EXTENSION_FRAMEWORK
+	 * @see #EXTENSION_BOOTCLASSPATH
+	 */
+	public final static String	REQUIREMENT_EXTENSION_DIRECTIVE				= "extension";
+
+	/**
+	 * The directive value indicating that the extension fragment is to be
+	 * loaded by the framework's class loader.
+	 * 
+	 * 
+	 * @see #REQUIREMENT_EXTENSION_DIRECTIVE
+	 */
+	public final static String	EXTENSION_FRAMEWORK							= "framework";
+
+	/**
+	 * The directive value indicating that the extension fragment is to be
+	 * loaded by the boot class loader.
+	 * 
+	 * @see #REQUIREMENT_EXTENSION_DIRECTIVE
+	 */
+	public final static String	EXTENSION_BOOTCLASSPATH						= "bootclasspath";
+
+	/**
+	 * The requirement directive used to specify the visibility type for a
+	 * requirement.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link BundleNamespace
+	 * bundle} namespace.
+	 * 
+	 * @see BundleNamespace#REQUIREMENT_VISIBILITY_DIRECTIVE
+	 */
+	public final static String	REQUIREMENT_VISIBILITY_DIRECTIVE			= "visibility";
+
+	private HostNamespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/namespace/IdentityNamespace.java b/osgi/framework/src/org/osgi/framework/namespace/IdentityNamespace.java
new file mode 100644
index 0000000..c925e5a
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/IdentityNamespace.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Identity Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Each resource provides exactly one<sup>†</sup> identity capability that
+ * can be used to identify the resource.
+ * 
+ * <p>
+ * The bundle wiring for the bundle revision provides exactly
+ * one<sup>†</sup> identity capability.
+ * 
+ * <p>
+ * † A resource with no symbolic name must not provide an identity
+ * capability.
+ * 
+ * @Immutable
+ * @version $Id: e34dcaba1f828326a0db13b3d811b2d170ff97a5 $
+ */
+public final class IdentityNamespace extends Namespace {
+
+	/**
+	 * Namespace name for identity capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the symbolic name of the
+	 * resource.
+	 */
+	public static final String	IDENTITY_NAMESPACE					= "osgi.identity";
+
+	/**
+	 * The capability directive identifying if the resource is a singleton. A
+	 * {@code String} value of "true" indicates the resource is a
+	 * singleton; any other value or {@code null} indicates the resource is not
+	 * a singleton.
+	 */
+	public static final String	CAPABILITY_SINGLETON_DIRECTIVE		= "singleton";
+
+	/**
+	 * The capability attribute identifying the {@code Version} of the resource
+	 * if one is specified or {@code 0.0.0} if not specified. The value of this
+	 * attribute must be of type {@code Version}.
+	 */
+	public static final String	CAPABILITY_VERSION_ATTRIBUTE		= "version";
+
+	/**
+	 * The capability attribute identifying the resource type. If the resource
+	 * has no type then the value {@link #TYPE_UNKNOWN unknown} must be used for
+	 * the attribute.
+	 * 
+	 * @see #TYPE_BUNDLE
+	 * @see #TYPE_FRAGMENT
+	 * @see #TYPE_UNKNOWN
+	 */
+	public static final String	CAPABILITY_TYPE_ATTRIBUTE			= "type";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi bundle.
+	 * 
+	 * @see #CAPABILITY_TYPE_ATTRIBUTE
+	 */
+	public static final String	TYPE_BUNDLE							= "osgi.bundle";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi fragment.
+	 * 
+	 * @see #CAPABILITY_TYPE_ATTRIBUTE
+	 */
+	public static final String	TYPE_FRAGMENT						= "osgi.fragment";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #CAPABILITY_TYPE_ATTRIBUTE type} as unknown.
+	 * 
+	 * @see #CAPABILITY_TYPE_ATTRIBUTE
+	 */
+	public static final String	TYPE_UNKNOWN						= "unknown";
+
+	/**
+	 * The capability attribute that contains a human readable copyright notice
+	 * for the resource. See the {@code Bundle-Copyright} manifest header.
+	 */
+	public static final String	CAPABILITY_COPYRIGHT_ATTRIBUTE		= "copyright";
+
+	/**
+	 * The capability attribute that contains a human readable description for
+	 * the resource. See the {@code Bundle-Description} manifest header.
+	 */
+	public static final String	CAPABILITY_DESCRIPTION_ATTRIBUTE	= "description";
+
+	/**
+	 * The capability attribute that contains the URL to documentation for the
+	 * resource. See the {@code Bundle-DocURL} manifest header.
+	 */
+	public static final String	CAPABILITY_DOCUMENTATION_ATTRIBUTE	= "documentation";
+
+	/**
+	 * The capability attribute that contains the URL to the license for the
+	 * resource. See the {@code name} portion of the {@code Bundle-License}
+	 * manifest header.
+	 */
+	public static final String	CAPABILITY_LICENSE_ATTRIBUTE		= "license";
+
+	/**
+	 * The requirement directive that classifies the relationship with another
+	 * resource.
+	 * 
+	 * @see #CLASSIFIER_SOURCES
+	 * @see #CLASSIFIER_JAVADOC
+	 */
+	public static final String	REQUIREMENT_CLASSIFIER_DIRECTIVE	= "classifier";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #REQUIREMENT_CLASSIFIER_DIRECTIVE classifier} as an archive
+	 * containing the source code in the same directory layout as the resource.
+	 * 
+	 * @see #REQUIREMENT_CLASSIFIER_DIRECTIVE
+	 */
+
+	public static final String	CLASSIFIER_SOURCES					= "sources";
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #REQUIREMENT_CLASSIFIER_DIRECTIVE classifier} as an archive
+	 * containing the javadoc in the same directory layout as the resource.
+	 * 
+	 * @see #REQUIREMENT_CLASSIFIER_DIRECTIVE
+	 */
+	public static final String	CLASSIFIER_JAVADOC					= "javadoc";
+
+	private IdentityNamespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/namespace/PackageNamespace.java b/osgi/framework/src/org/osgi/framework/namespace/PackageNamespace.java
new file mode 100644
index 0000000..2d1cbc3
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/PackageNamespace.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Package Capability and Requirement Namespace.
+ * 
+ * <p>
+ * A resource provides zero or more package capabilities (this is, exported
+ * packages) and requires zero or more package requirements (that is, imported
+ * packages).
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Unless otherwise noted, all directives specified on the
+ * {@code Export-Package} header are visible in the capability and all
+ * directives specified on the {@code Import-Package} and
+ * {@code DynamicImport-Package} headers are visible in the requirement.
+ * 
+ * <ul>
+ * <li>The {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE effective}
+ * {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE directives} must be ignored.
+ * This namespace is only effective at {@link Namespace#EFFECTIVE_RESOLVE
+ * resolve} time. An {@code effective} directive specified on the
+ * {@code Export-Package}, {@code Import-Package} or
+ * {@code DynamicImport-Package} headers must be ignored. An {@code effective}
+ * directive must not be present in a capability or requirement.</li>
+ * <li>The {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE cardinality}
+ * directive has limited applicability to this namespace. A {@code cardinality}
+ * directive specified on the {@code Import-Package} or
+ * {@code DynamicImport-Package} headers must be ignored. Only requirements with
+ * {@link Namespace#REQUIREMENT_RESOLUTION_DIRECTIVE resolution} set to
+ * {@link #RESOLUTION_DYNAMIC dynamic} and the package name contains a wildcard
+ * must have the {@code cardinality} directive set to
+ * {@link Namespace#CARDINALITY_MULTIPLE multiple}. Otherwise, a
+ * {@code cardinality} directive must not be present in a requirement.</li>
+ * </ul>
+ * 
+ * @Immutable
+ * @version $Id: 5adc45bd1ae26120cbff3562c7c8cefc01e38bd3 $
+ */
+public final class PackageNamespace extends AbstractWiringNamespace {
+
+	/**
+	 * Namespace name for package capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the name of the package.
+	 */
+	public static final String	PACKAGE_NAMESPACE							= "osgi.wiring.package";
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * classes which must be allowed to be exported.
+	 */
+	public final static String	CAPABILITY_INCLUDE_DIRECTIVE				= "include";
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * classes which must not be allowed to be exported.
+	 */
+	public final static String	CAPABILITY_EXCLUDE_DIRECTIVE				= "exclude";
+
+	/**
+	 * The capability attribute contains the {@code Version} of the package if
+	 * one is specified or {@code 0.0.0} if not specified. The value of this
+	 * attribute must be of type {@code Version}.
+	 */
+	public final static String	CAPABILITY_VERSION_ATTRIBUTE				= "version";
+
+	/**
+	 * The capability attribute contains the symbolic name of the resource
+	 * providing the package.
+	 */
+	public final static String	CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE	= "bundle-symbolic-name";
+
+	/**
+	 * The directive value identifying a dynamic requirement resolution type. A
+	 * dynamic resolution type indicates that the requirement is resolved
+	 * dynamically at runtime (such as a dynamically imported package) and the
+	 * resource will be resolved without the requirement being resolved.
+	 * 
+	 * @see Namespace#REQUIREMENT_RESOLUTION_DIRECTIVE
+	 */
+	public final static String	RESOLUTION_DYNAMIC							= "dynamic";
+
+	private PackageNamespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/framework/namespace/package-info.java b/osgi/framework/src/org/osgi/framework/namespace/package-info.java
new file mode 100644
index 0000000..9eb0ee2
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/package-info.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Namespace Package Version 1.0.
+ * 
+ * <p>
+ * Bundles should not need to import this package at runtime since all
+ * the types in this package just contain constants for capability and 
+ * requirement namespaces specified by the OSGi Alliance.
+ * 
+ * @version $Id: e40cb47c153c5bd53a1a5c9f7cedf047f8b31cf5 $
+ */
+
+package org.osgi.framework.namespace;
+
diff --git a/osgi/framework/src/org/osgi/framework/namespace/packageinfo b/osgi/framework/src/org/osgi/framework/namespace/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/namespace/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/osgi/framework/src/org/osgi/framework/package-info.java b/osgi/framework/src/org/osgi/framework/package-info.java
new file mode 100644
index 0000000..0b154a0
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Package Version 1.7.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework; version="[1.7,2.0)"}
+ * 
+ * @version $Id: a11d8e2964dacf128f21fef1e72f8cbaf0ce0ab3 $
+ */
+
+package org.osgi.framework;
+
diff --git a/osgi/framework/src/org/osgi/framework/packageinfo b/osgi/framework/src/org/osgi/framework/packageinfo
new file mode 100644
index 0000000..5d21e63
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/packageinfo
@@ -0,0 +1 @@
+version 1.7
diff --git a/osgi/framework/src/org/osgi/framework/startlevel/BundleStartLevel.java b/osgi/framework/src/org/osgi/framework/startlevel/BundleStartLevel.java
new file mode 100644
index 0000000..d22d3ef
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/startlevel/BundleStartLevel.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.startlevel;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * Query and modify the start level information for a bundle. The start level
+ * object for a bundle can be obtained by calling {@link Bundle#adapt(Class)
+ * bundle.adapt(BundleStartLevel.class)} on the bundle.
+ * 
+ * <p>
+ * The bundle associated with this BundleStartLevel object can be obtained by
+ * calling {@link BundleReference#getBundle()}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 9a000be191fe3cb4ae82535a30940db0340d5356 $
+ */
+public interface BundleStartLevel extends BundleReference {
+	/**
+	 * Return the assigned start level value for the bundle.
+	 * 
+	 * @return The start level value of the bundle.
+	 * @see #setStartLevel(int)
+	 * @throws IllegalStateException If the bundle has been uninstalled.
+	 */
+	int getStartLevel();
+
+	/**
+	 * Assign a start level value to the bundle.
+	 * 
+	 * <p>
+	 * The bundle will be assigned the specified start level. The start level
+	 * value assigned to the bundle will be persistently recorded by the
+	 * Framework.
+	 * <p>
+	 * If the new start level for the bundle is lower than or equal to the
+	 * active start level of the Framework and the bundle's autostart setting
+	 * indicates this bundle must be started, the Framework will start the
+	 * bundle as described in the {@link Bundle#start(int)} method using the
+	 * {@link Bundle#START_TRANSIENT} option. The
+	 * {@link Bundle#START_ACTIVATION_POLICY} option must also be used if
+	 * {@link #isActivationPolicyUsed()} returns {@code true}. The actual
+	 * starting of the bundle must occur asynchronously.
+	 * <p>
+	 * If the new start level for the bundle is higher than the active start
+	 * level of the Framework, the Framework will stop the bundle as described
+	 * in the {@link Bundle#stop(int)} method using the
+	 * {@link Bundle#STOP_TRANSIENT} option. The actual stopping of the bundle
+	 * must occur asynchronously.
+	 * 
+	 * @param startlevel The new start level for the bundle.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero, or if the bundle is the system bundle.
+	 * @throws IllegalStateException If the bundle has been uninstalled.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,EXECUTE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	void setStartLevel(int startlevel);
+
+	/**
+	 * Returns whether the bundle's autostart setting indicates it must be
+	 * started.
+	 * <p>
+	 * The autostart setting of a bundle indicates whether the bundle is to be
+	 * started when its start level is reached.
+	 * 
+	 * @return {@code true} if the autostart setting of the bundle indicates it
+	 *         is to be started. {@code false} otherwise.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @see Bundle#START_TRANSIENT
+	 */
+	boolean isPersistentlyStarted();
+
+	/**
+	 * Returns whether the bundle's autostart setting indicates that the
+	 * activation policy declared in the bundle manifest must be used.
+	 * <p>
+	 * The autostart setting of a bundle indicates whether the bundle's declared
+	 * activation policy is to be used when the bundle is started.
+	 * 
+	 * @return {@code true} if the bundle's autostart setting indicates the
+	 *         activation policy declared in the manifest must be used.
+	 *         {@code false} if the bundle must be eagerly activated.
+	 * @throws IllegalStateException If the bundle has been uninstalled.
+	 * @see Bundle#START_ACTIVATION_POLICY
+	 */
+	boolean isActivationPolicyUsed();
+}
diff --git a/osgi/framework/src/org/osgi/framework/startlevel/FrameworkStartLevel.java b/osgi/framework/src/org/osgi/framework/startlevel/FrameworkStartLevel.java
new file mode 100644
index 0000000..11a8049
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/startlevel/FrameworkStartLevel.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.startlevel;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.FrameworkListener;
+
+/**
+ * Query and modify the start level information for the framework. The start
+ * level object for the framework can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt(FrameworkStartLevel.class)} on the
+ * system bundle. Only the system bundle can be adapted to a FrameworkStartLevel
+ * object.
+ * 
+ * <p>
+ * The system bundle associated with this FrameworkStartLevel object can be
+ * obtained by calling {@link BundleReference#getBundle()}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 12c6f60842df994c7de2cc3cfd02f791b95fc35b $
+ */
+public interface FrameworkStartLevel extends BundleReference {
+	/**
+	 * Return the active start level value of the Framework.
+	 * 
+	 * If the Framework is in the process of changing the start level this
+	 * method must return the active start level if this differs from the
+	 * requested start level.
+	 * 
+	 * @return The active start level value of the Framework.
+	 */
+	int getStartLevel();
+
+	/**
+	 * Modify the active start level of the Framework and notify when complete.
+	 * 
+	 * <p>
+	 * The Framework will move to the requested start level. This method will
+	 * return immediately to the caller and the start level change will occur
+	 * asynchronously on another thread. The specified {@code FrameworkListener}
+	 * s are notified, in the order specified, when the start level change is
+	 * complete. When the start level change completes normally, each specified
+	 * {@code FrameworkListener} will be called with a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED}. If the start level change does
+	 * not complete normally, each specified {@code FrameworkListener} will be
+	 * called with a Framework event of type {@code FrameworkEvent.ERROR}.
+	 * 
+	 * <p>
+	 * If the specified start level is higher than the active start level, the
+	 * Framework will continue to increase the start level until the Framework
+	 * has reached the specified start level.
+	 * 
+	 * At each intermediate start level value on the way to and including the
+	 * target start level, the Framework must:
+	 * <ol>
+	 * <li>Change the active start level to the intermediate start level value.
+	 * <li>Start bundles at the intermediate start level whose autostart setting
+	 * indicate they must be started. They are started as described in the
+	 * {@link Bundle#start(int)} method using the {@link Bundle#START_TRANSIENT}
+	 * option. The {@link Bundle#START_ACTIVATION_POLICY} option must also be
+	 * used if {@link BundleStartLevel#isActivationPolicyUsed()} returns
+	 * {@code true} for the bundle.
+	 * </ol>
+	 * When this process completes after the specified start level is reached,
+	 * the Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved to the
+	 * specified start level.
+	 * 
+	 * <p>
+	 * If the specified start level is lower than the active start level, the
+	 * Framework will continue to decrease the start level until the Framework
+	 * has reached the specified start level.
+	 * 
+	 * At each intermediate start level value on the way to and including the
+	 * specified start level, the framework must:
+	 * <ol>
+	 * <li>Stop bundles at the intermediate start level as described in the
+	 * {@link Bundle#stop(int)} method using the {@link Bundle#STOP_TRANSIENT}
+	 * option.
+	 * <li>Change the active start level to the intermediate start level value.
+	 * </ol>
+	 * When this process completes after the specified start level is reached,
+	 * the Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved to the
+	 * specified start level.
+	 * 
+	 * <p>
+	 * If the specified start level is equal to the active start level, then no
+	 * bundles are started or stopped, however, the Framework must fire a
+	 * Framework event of type {@code FrameworkEvent.STARTLEVEL_CHANGED} to
+	 * announce it has finished moving to the specified start level. This event
+	 * may arrive before this method returns.
+	 * 
+	 * @param startlevel The requested start level for the Framework.
+	 * @param listeners Zero or more listeners to be notified when the start
+	 *        level change has been completed. The specified listeners do not
+	 *        need to be otherwise registered with the framework. If a specified
+	 *        listener is already registered with the framework, it will be
+	 *        notified twice.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	void setStartLevel(int startlevel, FrameworkListener... listeners);
+
+	/**
+	 * Return the initial start level value that is assigned to a Bundle when it
+	 * is first installed.
+	 * 
+	 * @return The initial start level value for Bundles.
+	 * @see #setInitialBundleStartLevel(int)
+	 */
+	int getInitialBundleStartLevel();
+
+	/**
+	 * Set the initial start level value that is assigned to a Bundle when it is
+	 * first installed.
+	 * 
+	 * <p>
+	 * The initial bundle start level will be set to the specified start level.
+	 * The initial bundle start level value will be persistently recorded by the
+	 * Framework.
+	 * 
+	 * <p>
+	 * When a Bundle is installed via {@code BundleContext.installBundle}, it is
+	 * assigned the initial bundle start level value.
+	 * 
+	 * <p>
+	 * The default initial bundle start level value is 1 unless this method has
+	 * been called to assign a different initial bundle start level value.
+	 * 
+	 * <p>
+	 * This method does not change the start level values of installed bundles.
+	 * 
+	 * @param startlevel The initial start level for newly installed bundles.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	void setInitialBundleStartLevel(int startlevel);
+}
diff --git a/osgi/framework/src/org/osgi/framework/startlevel/package-info.java b/osgi/framework/src/org/osgi/framework/startlevel/package-info.java
new file mode 100644
index 0000000..028fa60
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/startlevel/package-info.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Start Level Package Version 1.0.
+ * 
+ * <p>
+ * The Framework Start Level package allows management agents to manage a start
+ * level assigned to each bundle and the active start level of the Framework.
+ * This package is a replacement for the now deprecated
+ * {@code org.osgi.service.startlevel} package.
+ * 
+ * <p>
+ * A start level is defined to be a state of execution in which the Framework
+ * exists. Start level values are defined as unsigned integers with 0 (zero)
+ * being the state where the Framework is not launched. Progressively higher
+ * integral values represent progressively higher start levels. For example, 2
+ * is a higher start level than 1.
+ * 
+ * <p>
+ * {@code AdminPermission} is required to modify start level information.
+ * 
+ * <p>
+ * Start Level support in the Framework includes the ability to modify the
+ * active start level of the Framework and to assign a specific start level to a
+ * bundle. The beginning start level of a Framework is specified via the
+ * {@link org.osgi.framework.Constants#FRAMEWORK_BEGINNING_STARTLEVEL} framework
+ * property when configuring a framework.
+ * 
+ * <p>
+ * When the Framework is first started it must be at start level zero. In this
+ * state, no bundles are running. This is the initial state of the Framework
+ * before it is launched. When the Framework is launched, the Framework will
+ * enter start level one and all bundles which are assigned to start level one
+ * and whose autostart setting indicates the bundle should be started are
+ * started as described in the {@link org.osgi.framework.Bundle#start(int)}
+ * method. The Framework will continue to increase the start level, starting
+ * bundles at each start level, until the Framework has reached a beginning
+ * start level. At this point the Framework has completed starting bundles and
+ * will then fire a Framework event of type
+ * {@link org.osgi.framework.FrameworkEvent#STARTED} to announce it has
+ * completed its launch.
+ * 
+ * <p>
+ * Within a start level, bundles may be started in an order defined by the
+ * Framework implementation. This may be something like ascending
+ * {@link org.osgi.framework.Bundle#getBundleId()} order or an order based upon
+ * dependencies between bundles. A similar but reversed order may be used when
+ * stopping bundles within a start level.
+ * 
+ * <p>
+ * The Framework Start Level package can be used by management bundles to alter
+ * the active start level of the framework.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. For example:
+ * 
+ * <pre>
+ * Import-Package: org.osgi.framework.startlevel; version="[1.0,2.0)"
+ * </pre>
+ * 
+ * @version $Id: 78bab33a230f0d6ee1de30fcac7ff6eaa04f0a52 $
+ */
+
+package org.osgi.framework.startlevel;
+
diff --git a/osgi/framework/src/org/osgi/framework/startlevel/packageinfo b/osgi/framework/src/org/osgi/framework/startlevel/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/startlevel/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/osgi/framework/src/org/osgi/framework/wiring/BundleCapability.java b/osgi/framework/src/org/osgi/framework/wiring/BundleCapability.java
new file mode 100644
index 0000000..19d7a67
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/BundleCapability.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.Map;
+import org.osgi.framework.namespace.AbstractWiringNamespace;
+import org.osgi.resource.Capability;
+
+/**
+ * A capability that has been declared from a {@link BundleRevision bundle
+ * revision}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 39086f7e6086c2b3d83fbcb976a011cf69483ad8 $
+ */
+public interface BundleCapability extends Capability {
+
+	/**
+	 * Returns the bundle revision declaring this capability.
+	 * 
+	 * @return The bundle revision declaring this capability.
+	 */
+	BundleRevision getRevision();
+
+	/**
+	 * Returns the namespace of this capability.
+	 * 
+	 * @return The namespace of this capability.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this capability.
+	 * 
+	 * <p>
+	 * All capability directives not specified by the
+	 * {@link AbstractWiringNamespace wiring namespaces} have no specified
+	 * semantics and are considered extra user defined information.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this capability, or an empty map if this capability has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this capability.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this capability, or an empty map if this capability has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the resource declaring this capability.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRevision()}.
+	 * 
+	 * @return The resource declaring this capability.
+	 * @since 1.1
+	 */
+	BundleRevision getResource();
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/BundleRequirement.java b/osgi/framework/src/org/osgi/framework/wiring/BundleRequirement.java
new file mode 100644
index 0000000..bb26c5d
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/BundleRequirement.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.Map;
+import org.osgi.framework.namespace.AbstractWiringNamespace;
+import org.osgi.resource.Requirement;
+
+/**
+ * A requirement that has been declared from a {@link BundleRevision bundle
+ * revision}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 212ffb64f724d982db86ff7e49ed64ea530e670a $
+ */
+public interface BundleRequirement extends Requirement {
+	/**
+	 * Returns the bundle revision declaring this requirement.
+	 * 
+	 * @return The bundle revision declaring this requirement.
+	 */
+	BundleRevision getRevision();
+
+	/**
+	 * Returns whether the specified capability matches this requirement.
+	 * 
+	 * @param capability The capability to match to this requirement.
+	 * @return {@code true} if the specified capability has the same
+	 *         {@link #getNamespace() namespace} as this requirement and the
+	 *         filter for this requirement matches the
+	 *         {@link BundleCapability#getAttributes() attributes of the
+	 *         specified capability}; {@code false} otherwise.
+	 */
+	boolean matches(BundleCapability capability);
+
+	/**
+	 * Returns the namespace of this requirement.
+	 * 
+	 * @return The namespace of this requirement.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this requirement.
+	 * 
+	 * <p>
+	 * All requirement directives not specified by the
+	 * {@link AbstractWiringNamespace wiring namespaces} have no specified
+	 * semantics and are considered extra user defined information.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this requirement.
+	 * 
+	 * <p>
+	 * Requirement attributes have no specified semantics and are considered
+	 * extra user defined information.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the resource declaring this requirement.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRevision()}.
+	 * 
+	 * @return The resource declaring this requirement. This can be {@code null}
+	 *         if this requirement is synthesized.
+	 * @since 1.1
+	 */
+	BundleRevision getResource();
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/BundleRevision.java b/osgi/framework/src/org/osgi/framework/wiring/BundleRevision.java
new file mode 100644
index 0000000..1ba9365
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/BundleRevision.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.List;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+/**
+ * Bundle Revision. When a bundle is installed and each time a bundle is
+ * updated, a new bundle revision of the bundle is created. Since a bundle
+ * update can change the entries in a bundle, different bundle wirings for the
+ * same bundle can be associated with different bundle revisions.
+ * 
+ * <p>
+ * For a bundle that has not been uninstalled, the most recent bundle revision
+ * is defined to be the current bundle revision. A bundle in the UNINSTALLED
+ * state does not have a current revision. The current bundle revision for a
+ * bundle can be obtained by calling {@link Bundle#adapt(Class) bundle.adapt}
+ * (BundleRevision.class). Since a bundle in the UNINSTALLED state does not have
+ * a current revision, adapting such a bundle returns {@code null}.
+ * 
+ * <p>
+ * The framework defines namespaces for {@link PackageNamespace package},
+ * {@link BundleNamespace bundle} and {@link HostNamespace host} capabilities
+ * and requirements. These namespaces are defined only to express wiring
+ * information by the framework. They must not be used in
+ * {@link Constants#PROVIDE_CAPABILITY Provide-Capability} and
+ * {@link Constants#REQUIRE_CAPABILITY Require-Capability} manifest headers.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: e68e01a670f0ae9d6eb736414f875c8b216ed1bc $
+ */
+public interface BundleRevision extends BundleReference, Resource {
+	/**
+	 * Returns the symbolic name for this bundle revision.
+	 * 
+	 * @return The symbolic name for this bundle revision.
+	 * @see Bundle#getSymbolicName()
+	 */
+	String getSymbolicName();
+
+	/**
+	 * Returns the version for this bundle revision.
+	 * 
+	 * @return The version for this bundle revision, or
+	 *         {@link Version#emptyVersion} if this bundle revision has no
+	 *         version information.
+	 * @see Bundle#getVersion()
+	 */
+	Version getVersion();
+
+	/**
+	 * Returns the capabilities declared by this bundle revision.
+	 * 
+	 * @param namespace The namespace of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared
+	 *         {@link BundleCapability}s from the specified namespace. The
+	 *         returned list will be empty if this bundle revision declares no
+	 *         capabilities in the specified namespace. The list contains the
+	 *         declared capabilities in the order they are specified in the
+	 *         manifest.
+	 */
+	List<BundleCapability> getDeclaredCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements declared by this bundle revision.
+	 * 
+	 * @param namespace The namespace of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared
+	 *         {@link BundleRequirement}s from the specified namespace. The
+	 *         returned list will be empty if this bundle revision declares no
+	 *         requirements in the specified namespace. The list contains the
+	 *         declared requirements in the order they are specified in the
+	 *         manifest.
+	 */
+	List<BundleRequirement> getDeclaredRequirements(String namespace);
+
+	/**
+	 * Namespace for package capabilities and requirements.
+	 * 
+	 * <p>
+	 * The name of the package is stored in the capability attribute of the same
+	 * name as this namespace (osgi.wiring.package). The other directives and
+	 * attributes of the package, from the {@link Constants#EXPORT_PACKAGE
+	 * Export-Package} manifest header, can be found in the cabability's
+	 * {@link BundleCapability#getDirectives() directives} and
+	 * {@link BundleCapability#getAttributes() attributes}. The
+	 * {@link Constants#VERSION_ATTRIBUTE version} capability attribute must
+	 * contain the {@link Version} of the package if one is specified or
+	 * {@link Version#emptyVersion} if not specified. The
+	 * {@link Constants#BUNDLE_SYMBOLICNAME_ATTRIBUTE bundle-symbolic-name}
+	 * capability attribute must contain the
+	 * {@link BundleRevision#getSymbolicName() symbolic name} of the provider if
+	 * one is specified. The {@link Constants#BUNDLE_VERSION_ATTRIBUTE
+	 * bundle-version} capability attribute must contain the
+	 * {@link BundleRevision#getVersion() version} of the provider if one is
+	 * specified or {@link Version#emptyVersion} if not specified.
+	 * 
+	 * <p>
+	 * The package capabilities provided by the system bundle, that is the
+	 * bundle with id zero, must include the package specified by the
+	 * {@link Constants#FRAMEWORK_SYSTEMPACKAGES} and
+	 * {@link Constants#FRAMEWORK_SYSTEMPACKAGES_EXTRA} framework properties as
+	 * well as any other package exported by the framework implementation.
+	 * 
+	 * <p>
+	 * A bundle revision {@link BundleRevision#getDeclaredCapabilities(String)
+	 * declares} zero or more package capabilities (this is, exported packages)
+	 * and {@link BundleRevision#getDeclaredRequirements(String) declares} zero
+	 * or more package requirements.
+	 * <p>
+	 * A bundle wiring {@link BundleWiring#getCapabilities(String) provides}
+	 * zero or more resolved package capabilities (that is, exported packages)
+	 * and {@link BundleWiring#getRequiredWires(String) requires} zero or more
+	 * resolved package requirements (that is, imported packages). The number of
+	 * package wires required by a bundle wiring may change as the bundle wiring
+	 * may dynamically import additional packages.
+	 * 
+	 * @see PackageNamespace
+	 */
+	String	PACKAGE_NAMESPACE	= PackageNamespace.PACKAGE_NAMESPACE;
+
+	/**
+	 * Namespace for bundle capabilities and requirements.
+	 * 
+	 * <p>
+	 * The bundle symbolic name of the bundle is stored in the capability
+	 * attribute of the same name as this namespace (osgi.wiring.bundle). The
+	 * other directives and attributes of the bundle, from the
+	 * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
+	 * header, can be found in the cabability's
+	 * {@link BundleCapability#getDirectives() directives} and
+	 * {@link BundleCapability#getAttributes() attributes}. The
+	 * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
+	 * attribute must contain the {@link Version} of the bundle from the
+	 * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
+	 * specified or {@link Version#emptyVersion} if not specified.
+	 * 
+	 * <p>
+	 * A non-fragment revision
+	 * {@link BundleRevision#getDeclaredCapabilities(String) declares} exactly
+	 * one<sup>†</sup> bundle capability (that is, the bundle can be
+	 * required by another bundle). A fragment revision must not declare a
+	 * bundle capability.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision
+	 * {@link BundleWiring#getCapabilities(String) provides} exactly
+	 * one<sup>†</sup> bundle capability (that is, the bundle can be
+	 * required by another bundle) and
+	 * {@link BundleWiring#getRequiredWires(String) requires} zero or more
+	 * bundle capabilities (that is, requires other bundles).
+	 * 
+	 * <p>
+	 * † A bundle with no bundle symbolic name (that is, a bundle with
+	 * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
+	 * {@literal <} 2) must not provide a bundle capability.
+	 * 
+	 * @see BundleNamespace
+	 */
+	String	BUNDLE_NAMESPACE	= BundleNamespace.BUNDLE_NAMESPACE;
+
+	/**
+	 * Namespace for host capabilities and requirements.
+	 * 
+	 * <p>
+	 * The bundle symbolic name of the bundle is stored in the capability
+	 * attribute of the same name as this namespace (osgi.wiring.host). The
+	 * other directives and attributes of the bundle, from the
+	 * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
+	 * header, can be found in the cabability's
+	 * {@link BundleCapability#getDirectives() directives} and
+	 * {@link BundleCapability#getAttributes() attributes}. The
+	 * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
+	 * attribute must contain the {@link Version} of the bundle from the
+	 * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
+	 * specified or {@link Version#emptyVersion} if not specified.
+	 * 
+	 * <p>
+	 * A non-fragment revision
+	 * {@link BundleRevision#getDeclaredCapabilities(String) declares} zero or
+	 * one<sup>†</sup> host capability if the bundle
+	 * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
+	 * attached}. A fragment revision must
+	 * {@link BundleRevision#getDeclaredRequirements(String) declare} exactly
+	 * one host requirement.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision
+	 * {@link BundleWiring#getCapabilities(String) provides} zero or
+	 * one<sup>†</sup> host capability if the bundle
+	 * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
+	 * attached}. A bundle wiring for a fragment revision
+	 * {@link BundleWiring#getRequiredWires(String) requires} a host capability
+	 * for each host to which it is attached.
+	 * 
+	 * <p>
+	 * † A bundle with no bundle symbolic name (that is, a bundle with
+	 * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
+	 * {@literal <} 2) must not provide a host capability.
+	 * 
+	 * @see HostNamespace
+	 */
+	String	HOST_NAMESPACE		= HostNamespace.HOST_NAMESPACE;
+
+	/**
+	 * Returns the special types of this bundle revision. The bundle revision
+	 * type values are:
+	 * <ul>
+	 * <li>{@link #TYPE_FRAGMENT}
+	 * </ul>
+	 * 
+	 * A bundle revision may be more than one type at a time. A type code is
+	 * used to identify the bundle revision type for future extendability.
+	 * 
+	 * <p>
+	 * If this bundle revision is not one or more of the defined types then 0 is
+	 * returned.
+	 * 
+	 * @return The special types of this bundle revision. The type values are
+	 *         ORed together.
+	 */
+	int getTypes();
+
+	/**
+	 * Bundle revision type indicating the bundle revision is a fragment.
+	 * 
+	 * @see #getTypes()
+	 */
+	int	TYPE_FRAGMENT	= 0x00000001;
+
+	/**
+	 * Returns the bundle wiring which is using this bundle revision.
+	 * 
+	 * @return The bundle wiring which is using this bundle revision or
+	 *         {@code null} if no bundle wiring is using this bundle revision.
+	 * @see BundleWiring#getRevision()
+	 */
+	BundleWiring getWiring();
+
+	/**
+	 * Returns the capabilities declared by this resource.
+	 * 
+	 * <p>
+	 * This method returns the same value as
+	 * {@link #getDeclaredCapabilities(String)}.
+	 * 
+	 * @param namespace The namespace of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Capability}s
+	 *         from the specified namespace. The returned list will be empty if
+	 *         this resource declares no capabilities in the specified
+	 *         namespace.
+	 * @since 1.1
+	 */
+	List<Capability> getCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements declared by this bundle resource.
+	 * 
+	 * <p>
+	 * This method returns the same value as
+	 * {@link #getDeclaredRequirements(String)}.
+	 * 
+	 * @param namespace The namespace of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Requirement}
+	 *         s from the specified namespace. The returned list will be empty
+	 *         if this resource declares no requirements in the specified
+	 *         namespace.
+	 * @since 1.1
+	 */
+	List<Requirement> getRequirements(String namespace);
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/BundleRevisions.java b/osgi/framework/src/org/osgi/framework/wiring/BundleRevisions.java
new file mode 100644
index 0000000..f0d03ff
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/BundleRevisions.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.List;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * The {@link BundleRevision bundle revisions} of a bundle. When a bundle is
+ * installed and each time a bundle is updated, a new bundle revision of the
+ * bundle is created. For a bundle that has not been uninstalled, the most
+ * recent bundle revision is defined to be the current bundle revision. A bundle
+ * in the UNINSTALLED state does not have a current revision. An in use bundle
+ * revision is associated with an {@link BundleWiring#isInUse() in use}
+ * {@link BundleWiring}. The current bundle revision, if there is one, and all
+ * in use bundle revisions are returned.
+ * 
+ * <p>
+ * The bundle revisions for a bundle can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt}({@link BundleRevisions}.class).
+ * {@link #getRevisions()} on the bundle.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 8423242078417873faf0f8979e153e3c1f3a0e4b $
+ */
+public interface BundleRevisions extends BundleReference {
+	/**
+	 * Return the bundle revisions for the {@link BundleReference#getBundle()
+	 * referenced} bundle.
+	 * 
+	 * <p>
+	 * The result is a list containing the current bundle revision, if there is
+	 * one, and all in use bundle revisions. The list may also contain
+	 * intermediate bundle revisions which are not in use.
+	 * 
+	 * <p>
+	 * The list is ordered in reverse chronological order such that the first
+	 * item is the most recent bundle revision and last item is the oldest
+	 * bundle revision.
+	 * 
+	 * <p>
+	 * Generally the list will have at least one bundle revision for the bundle:
+	 * the current bundle revision. However, for an uninstalled bundle with no
+	 * in use bundle revisions, the list may be empty.
+	 * 
+	 * @return A list containing a snapshot of the {@link BundleRevision}s for
+	 *         the referenced bundle.
+	 */
+	List<BundleRevision> getRevisions();
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/BundleWire.java b/osgi/framework/src/org/osgi/framework/wiring/BundleWire.java
new file mode 100644
index 0000000..d14829a
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/BundleWire.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import org.osgi.resource.Wire;
+
+/**
+ * A wire connecting a {@link BundleCapability} to a {@link BundleRequirement}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 02e7cd6ec0fa9fdb73f782a6890984d5d4e7ca21 $
+ */
+public interface BundleWire extends Wire {
+	/**
+	 * Returns the {@link BundleCapability} for this wire.
+	 * 
+	 * @return The {@link BundleCapability} for this wire.
+	 */
+	BundleCapability getCapability();
+
+	/**
+	 * Return the {@link BundleRequirement} for this wire.
+	 * 
+	 * @return The {@link BundleRequirement} for this wire.
+	 */
+	BundleRequirement getRequirement();
+
+	/**
+	 * Returns the bundle wiring {@link BundleWiring#getProvidedWires(String)
+	 * providing} the {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The bundle revision referenced by the returned bundle wiring may differ
+	 * from the bundle revision referenced by the {@link #getCapability()
+	 * capability}.
+	 * 
+	 * @return The bundle wiring providing the capability. If the bundle wiring
+	 *         providing the capability is not {@link BundleWiring#isInUse() in
+	 *         use}, {@code null} will be returned.
+	 */
+	BundleWiring getProviderWiring();
+
+	/**
+	 * Returns the bundle wiring who
+	 * {@link BundleWiring#getRequiredWires(String) requires} the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The bundle revision referenced by the returned bundle wiring may differ
+	 * from the bundle revision referenced by the {@link #getRequirement()
+	 * requirement}.
+	 * 
+	 * @return The bundle wiring whose requirement is wired to the capability.
+	 *         If the bundle wiring requiring the capability is not
+	 *         {@link BundleWiring#isInUse() in use}, {@code null} will be
+	 *         returned.
+	 */
+	BundleWiring getRequirerWiring();
+
+	/**
+	 * Returns the resource providing the {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getProviderWiring()}.
+	 * {@link BundleWiring#getRevision() getRevision()}.
+	 * 
+	 * @return The resource providing the capability.
+	 * @since 1.1
+	 */
+	BundleRevision getProvider();
+
+	/**
+	 * Returns the resource who {@link #getRequirement() requires} the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getRequirement() requirement}.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRequirerWiring()}.
+	 * {@link BundleWiring#getRevision() getRevision()}.
+	 * 
+	 * @return The resource who requires the capability.
+	 * @since 1.1
+	 */
+	BundleRevision getRequirer();
+
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/BundleWiring.java b/osgi/framework/src/org/osgi/framework/wiring/BundleWiring.java
new file mode 100644
index 0000000..b234c38
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/BundleWiring.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+
+/**
+ * A wiring for a bundle. Each time a bundle is resolved, a new bundle wiring
+ * for the bundle is created. A bundle wiring is associated with a bundle
+ * revision and represents the dependencies with other bundle wirings.
+ * 
+ * <p>
+ * The bundle wiring for a bundle is the {@link #isCurrent() current} bundle
+ * wiring if it is the most recent bundle wiring for the current bundle
+ * revision. A bundle wiring is {@link #isInUse() in use} if it is the current
+ * bundle wiring or if some other in use bundle wiring is dependent upon it. For
+ * example, another bundle wiring is wired to a capability provided by the
+ * bundle wiring. An in use bundle wiring for a non-fragment bundle has a class
+ * loader. All bundles with non-current, in use bundle wirings are considered
+ * removal pending. Once a bundle wiring is no longer in use, it is considered
+ * stale and is discarded by the framework.
+ * 
+ * <p>
+ * The current bundle wiring for a bundle can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt}(BundleWiring.class). A bundle in the
+ * INSTALLED or UNINSTALLED state does not have a current wiring, adapting such
+ * a bundle returns {@code null}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: a3b3fd7ad7d289a5bfc6e4e02c875bc42a34df89 $
+ */
+public interface BundleWiring extends BundleReference, Wiring {
+	/**
+	 * Returns {@code true} if this bundle wiring is the current bundle wiring.
+	 * The bundle wiring for a bundle is the current bundle wiring if it is the
+	 * most recent bundle wiring for the current bundle revision. All bundles
+	 * with non-current, in use bundle wirings are considered
+	 * {@link FrameworkWiring#getRemovalPendingBundles() removal pending}.
+	 * 
+	 * @return {@code true} if this bundle wiring is the current bundle wiring;
+	 *         {@code false} otherwise.
+	 */
+	boolean isCurrent();
+
+	/**
+	 * Returns {@code true} if this bundle wiring is in use. A bundle wiring is
+	 * in use if it is the {@link #isCurrent() current} wiring or if some other
+	 * in use bundle wiring is dependent upon it. Once a bundle wiring is no
+	 * longer in use, it is considered stale and is discarded by the framework.
+	 * 
+	 * @return {@code true} if this bundle wiring is in use; {@code false}
+	 *         otherwise.
+	 */
+	boolean isInUse();
+
+	/**
+	 * Returns the capabilities provided by this bundle wiring.
+	 * 
+	 * <p>
+	 * Only capabilities considered by the resolver are returned. For example,
+	 * capabilities with {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A capability may not be required by any bundle wiring and thus there may
+	 * be no {@link #getProvidedWires(String) wires} for the capability.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision provides a subset of the
+	 * declared capabilities from the bundle revision and all attached fragment
+	 * revisions<sup>†</sup>. Not all declared capabilities may be
+	 * provided since some may be discarded. For example, if a package is
+	 * declared to be both exported and imported, only one is selected and the
+	 * other is discarded.
+	 * <p>
+	 * A bundle wiring for a fragment revision with a symbolic name must provide
+	 * exactly one {@link IdentityNamespace identity} capability.
+	 * <p>
+	 * † The {@link IdentityNamespace identity} capability provided by
+	 * attached fragment revisions must not be included in the capabilities of
+	 * the host bundle wiring.
+	 * 
+	 * @param namespace The namespace of the capabilities to return or
+	 *        {@code null} to return the capabilities from all namespaces.
+	 * @return A list containing a snapshot of the {@link BundleCapability}s, or
+	 *         an empty list if this bundle wiring provides no capabilities in
+	 *         the specified namespace. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given namespace, the list contains the wires in the order the
+	 *         capabilities were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached
+	 *         fragments<sup>†</sup> of this bundle wiring. There is no
+	 *         ordering defined between capabilities in different namespaces.
+	 */
+	List<BundleCapability> getCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements of this bundle wiring.
+	 * 
+	 * <p>
+	 * Only requirements considered by the resolver are returned. For example,
+	 * requirements with {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision has a subset of the declared
+	 * requirements from the bundle revision and all attached fragment
+	 * revisions. Not all declared requirements may be present since some may be
+	 * discarded. For example, if a package is declared to be optionally
+	 * imported and is not actually imported, the requirement must be discarded.
+	 * 
+	 * @param namespace The namespace of the requirements to return or
+	 *        {@code null} to return the requirements from all namespaces.
+	 * @return A list containing a snapshot of the {@link BundleRequirement}s,
+	 *         or an empty list if this bundle wiring uses no requirements in
+	 *         the specified namespace. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given namespace, the list contains the wires in the order the
+	 *         requirements were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 */
+	List<BundleRequirement> getRequirements(String namespace);
+
+	/**
+	 * Returns the {@link BundleWire}s to the provided {@link BundleCapability
+	 * capabilities} of this bundle wiring.
+	 * 
+	 * @param namespace The namespace of the capabilities for which to return
+	 *        wires or {@code null} to return the wires for the capabilities in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link BundleWire}s for the
+	 *         {@link BundleCapability capabilities} of this bundle wiring, or
+	 *         an empty list if this bundle wiring has no capabilities in the
+	 *         specified namespace. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given namespace, the list contains the wires in the order the
+	 *         capabilities were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         capabilities in different namespaces.
+	 */
+	List<BundleWire> getProvidedWires(String namespace);
+
+	/**
+	 * Returns the {@link BundleWire}s to the {@link BundleRequirement
+	 * requirements} in use by this bundle wiring.
+	 * 
+	 * <p>
+	 * This method may return different results if this bundle wiring adds wires
+	 * to more requirements. For example, dynamically importing a package will
+	 * establish a new wire to the dynamically imported package.
+	 * 
+	 * @param namespace The namespace of the requirements for which to return
+	 *        wires or {@code null} to return the wires for the requirements in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link BundleWire}s for the
+	 *         {@link BundleRequirement requirements} of this bundle wiring, or
+	 *         an empty list if this bundle wiring has no requirements in the
+	 *         specified namespace. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given namespace, the list contains the wires in the order the
+	 *         requirements were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 */
+	List<BundleWire> getRequiredWires(String namespace);
+
+	/**
+	 * Returns the bundle revision for the bundle in this bundle wiring. Since a
+	 * bundle update can change the entries in a bundle, different bundle
+	 * wirings for the same bundle can have different bundle revisions.
+	 * 
+	 * <p>
+	 * The bundle object {@link BundleReference#getBundle() referenced} by the
+	 * returned {@code BundleRevision} may return different information than the
+	 * returned {@code BundleRevision} since the returned {@code BundleRevision}
+	 * may refer to an older revision of the bundle.
+	 * 
+	 * @return The bundle revision for this bundle wiring.
+	 * @see BundleRevision#getWiring()
+	 */
+	BundleRevision getRevision();
+
+	/**
+	 * Returns the class loader for this bundle wiring. Since a bundle refresh
+	 * creates a new bundle wiring for a bundle, different bundle wirings for
+	 * the same bundle will have different class loaders.
+	 * 
+	 * @return The class loader for this bundle wiring. If this bundle wiring is
+	 *         not {@link #isInUse() in use} or this bundle wiring is for a
+	 *         fragment revision, {@code null} will be returned.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code RuntimePermission("getClassLoader")}, and the Java Runtime
+	 *         Environment supports permissions.
+	 */
+	ClassLoader getClassLoader();
+
+	/**
+	 * Returns entries in this bundle wiring's {@link #getRevision() bundle
+	 * revision} and its attached fragment revisions. This bundle wiring's class
+	 * loader is not used to search for entries. Only the contents of this
+	 * bundle wiring's bundle revision and its attached fragment revisions are
+	 * searched for the specified entries.
+	 * 
+	 * <p>
+	 * This method takes into account that the "contents" of this
+	 * bundle wiring can have attached fragments. This "bundle space"
+	 * is not a namespace with unique members; the same entry name can be
+	 * present multiple times. This method therefore returns a list of URL
+	 * objects. These URLs can come from different JARs but have the same path
+	 * name. This method can either return only entries in the specified path or
+	 * recurse into subdirectories returning entries in the directory tree
+	 * beginning at the specified path.
+	 * 
+	 * <p>
+	 * URLs for directory entries must have their path end with "/".
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * URLs to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param path The path name in which to look. The path is always relative
+	 *        to the root of this bundle wiring and may begin with
+	 *        "/". A path value of "/" indicates the root of
+	 *        this bundle wiring.
+	 * @param filePattern The file name pattern for selecting entries in the
+	 *        specified path. The pattern is only matched against the last
+	 *        element of the entry path. If the entry is a directory then the
+	 *        trailing "/" is not used for pattern matching. Substring
+	 *        matching is supported, as specified in the Filter specification,
+	 *        using the wildcard character ("*"). If {@code null} is
+	 *        specified, this is equivalent to "*" and matches all
+	 *        files.
+	 * @param options The options for listing resource names. See
+	 *        {@link #FINDENTRIES_RECURSE}. The method must ignore unrecognized
+	 *        options.
+	 * @return An unmodifiable list of URL objects for each matching entry, or
+	 *         an empty list if no matching entry could be found, if this bundle
+	 *         wiring is for a fragment revision or if the caller does not have
+	 *         the appropriate {@code AdminPermission[bundle,RESOURCE]} and the
+	 *         Java Runtime Environment supports permissions. The list is
+	 *         ordered such that entries from the {@link #getRevision() bundle
+	 *         revision} are returned first followed by the entries from
+	 *         attached fragment revisions in attachment order. If this bundle
+	 *         wiring is not {@link #isInUse() in use}, {@code null} must be
+	 *         returned.
+	 * @see Bundle#findEntries(String, String, boolean)
+	 */
+	List<URL> findEntries(String path, String filePattern, int options);
+
+	/**
+	 * The find entries operation must recurse into subdirectories.
+	 * 
+	 * <p>
+	 * This bit may be set when calling
+	 * {@link #findEntries(String, String, int)} to specify the result must
+	 * include the matching entries from the specified path and its
+	 * subdirectories. If this bit is not set, then the result must only include
+	 * matching entries from the specified path.
+	 * 
+	 * @see #findEntries(String, String, int)
+	 */
+	int	FINDENTRIES_RECURSE	= 0x00000001;
+
+	/**
+	 * Returns the names of resources visible to this bundle wiring's
+	 * {@link #getClassLoader() class loader}. The returned names can be used to
+	 * access the resources via this bundle wiring's class loader.
+	 * 
+	 * <ul>
+	 * <li>Only the resource names for resources in bundle wirings will be
+	 * returned. The names of resources visible to a bundle wiring's parent
+	 * class loader, such as the bootstrap class loader, must not be included in
+	 * the result.
+	 * <li>Only established wires will be examined for resources. This method
+	 * must not cause new wires for dynamic imports to be established.
+	 * </ul>
+	 * 
+	 * @param path The path name in which to look. The path is always relative
+	 *        to the root of this bundle wiring's class loader and may begin
+	 *        with "/". A path value of "/" indicates the
+	 *        root of this bundle wiring's class loader.
+	 * @param filePattern The file name pattern for selecting resource names in
+	 *        the specified path. The pattern is only matched against the last
+	 *        element of the resource path. If the resource is a directory then
+	 *        the trailing "/" is not used for pattern matching.
+	 *        Substring matching is supported, as specified in the Filter
+	 *        specification, using the wildcard character ("*"). If
+	 *        {@code null} is specified, this is equivalent to "*" and
+	 *        matches all files.
+	 * @param options The options for listing resource names. See
+	 *        {@link #LISTRESOURCES_LOCAL} and {@link #LISTRESOURCES_RECURSE}.
+	 *        This method must ignore unrecognized options.
+	 * @return An unmodifiable collection of resource names for each matching
+	 *         resource, or an empty collection if no matching resource could be
+	 *         found, if this bundle wiring is for a fragment revision or if the
+	 *         caller does not have the appropriate
+	 *         {@code AdminPermission[bundle,RESOURCE]} and the Java Runtime
+	 *         Environment supports permissions. The collection is unordered and
+	 *         must contain no duplicate resource names. If this bundle wiring
+	 *         is not {@link #isInUse() in use}, {@code null} must be returned.
+	 */
+	Collection<String> listResources(String path, String filePattern, int options);
+
+	/**
+	 * The list resource names operation must recurse into subdirectories.
+	 * 
+	 * <p>
+	 * This bit may be set when calling
+	 * {@link #listResources(String, String, int)} to specify the result must
+	 * include the names of matching resources from the specified path and its
+	 * subdirectories. If this bit is not set, then the result must only include
+	 * names of matching resources from the specified path.
+	 * 
+	 * @see #listResources(String, String, int)
+	 */
+	int	LISTRESOURCES_RECURSE	= 0x00000001;
+
+	/**
+	 * The list resource names operation must limit the result to the names of
+	 * matching resources contained in this bundle wiring's
+	 * {@link #getRevision() bundle revision} and its attached fragment
+	 * revisions. The result must not include resource names for resources in
+	 * {@link PackageNamespace package} names which are
+	 * {@link #getRequiredWires(String) imported} by this wiring.
+	 * 
+	 * <p>
+	 * This bit may be set when calling
+	 * {@link #listResources(String, String, int)} to specify the result must
+	 * only include the names of matching resources contained in this bundle
+	 * wiring's bundle revision and its attached fragment revisions. If this bit
+	 * is not set, then the result must include the names of matching resources
+	 * reachable from this bundle wiring's class loader which may include the
+	 * names of matching resources contained in imported packages and required
+	 * bundles.
+	 * 
+	 * @see #listResources(String, String, int)
+	 */
+	int	LISTRESOURCES_LOCAL		= 0x00000002;
+
+	/**
+	 * Returns the capabilities provided by this wiring.
+	 * 
+	 * <p>
+	 * Only capabilities considered by the resolver are returned. For example,
+	 * capabilities with {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A capability may not be required by any wiring and thus there may be no
+	 * {@link #getProvidedResourceWires(String) wires} for the capability.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource provides a subset of the declared
+	 * capabilities from the resource and all attached fragment
+	 * resources<sup>†</sup>. Not all declared capabilities may be
+	 * provided since some may be discarded. For example, if a package is
+	 * declared to be both exported and imported, only one is selected and the
+	 * other is discarded.
+	 * <p>
+	 * A wiring for a fragment resource with a symbolic name must provide
+	 * exactly one {@code osgi.identity} capability.
+	 * <p>
+	 * † The {@code osgi.identity} capability provided by attached
+	 * fragment resource must not be included in the capabilities of the host
+	 * wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getCapabilities(String)}.
+	 * 
+	 * @param namespace The namespace of the capabilities to return or
+	 *        {@code null} to return the capabilities from all namespaces.
+	 * @return A list containing a snapshot of the {@link Capability}s, or an
+	 *         empty list if this wiring provides no capabilities in the
+	 *         specified namespace. For a given namespace, the list contains the
+	 *         wires in the order the capabilities were specified in the
+	 *         manifests of the {@link #getResource() resource} and the attached
+	 *         fragment resources<sup>†</sup> of this wiring. There is no
+	 *         ordering defined between capabilities in different namespaces.
+	 * @since 1.1
+	 */
+	List<Capability> getResourceCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements of this wiring.
+	 * 
+	 * <p>
+	 * Only requirements considered by the resolver are returned. For example,
+	 * requirements with {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource has a subset of the declared
+	 * requirements from the resource and all attached fragment resources. Not
+	 * all declared requirements may be present since some may be discarded. For
+	 * example, if a package is declared to be optionally imported and is not
+	 * actually imported, the requirement must be discarded.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRequirements(String)}.
+	 * 
+	 * @param namespace The namespace of the requirements to return or
+	 *        {@code null} to return the requirements from all namespaces.
+	 * @return A list containing a snapshot of the {@link Requirement}s, or an
+	 *         empty list if this wiring uses no requirements in the specified
+	 *         namespace. For a given namespace, the list contains the wires in
+	 *         the order the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 * @since 1.1
+	 */
+	List<Requirement> getResourceRequirements(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the provided {@link Capability capabilities}
+	 * of this wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getProvidedWires(String)}.
+	 * 
+	 * @param namespace The namespace of the capabilities for which to return
+	 *        wires or {@code null} to return the wires for the capabilities in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Capability capabilities} of this wiring, or an empty list
+	 *         if this wiring has no capabilities in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the capabilities were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         capabilities in different namespaces.
+	 * @since 1.1
+	 */
+	List<Wire> getProvidedResourceWires(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the {@link Requirement requirements} in use
+	 * by this wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRequiredWires(String)}.
+	 * 
+	 * @param namespace The namespace of the requirements for which to return
+	 *        wires or {@code null} to return the wires for the requirements in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Requirement requirements} of this wiring, or an empty list
+	 *         if this wiring has no requirements in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 * @since 1.1
+	 */
+	List<Wire> getRequiredResourceWires(String namespace);
+
+	/**
+	 * Returns the resource associated with this wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRevision()}.
+	 * 
+	 * @return The resource associated with this wiring.
+	 * @since 1.1
+	 */
+	BundleRevision getResource();
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/FrameworkWiring.java b/osgi/framework/src/org/osgi/framework/wiring/FrameworkWiring.java
new file mode 100644
index 0000000..ce9952c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/FrameworkWiring.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.FrameworkListener;
+
+/**
+ * Query and modify wiring information for the framework. The framework wiring
+ * object for the framework can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt(FrameworkWiring.class)} on the system
+ * bundle. Only the system bundle can be adapted to a FrameworkWiring object.
+ * 
+ * <p>
+ * The system bundle associated with this FrameworkWiring object can be obtained
+ * by calling {@link BundleReference#getBundle()}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: bff4cdf85c632e2946e18c1640a86e80c069dd37 $
+ */
+public interface FrameworkWiring extends BundleReference {
+	/**
+	 * Refreshes the specified bundles. This forces the update (replacement) or
+	 * removal of packages exported by the specified bundles.
+	 * 
+	 * <p>
+	 * The technique by which the framework refreshes bundles may vary among
+	 * different framework implementations. A permissible implementation is to
+	 * stop and restart the framework.
+	 * 
+	 * <p>
+	 * This method returns to the caller immediately and then performs the
+	 * following steps on a separate thread:
+	 * 
+	 * <ol>
+	 * <li>Compute the {@link #getDependencyClosure(Collection) dependency
+	 * closure} of the specified bundles. If no bundles are specified, compute
+	 * the dependency closure of the {@link #getRemovalPendingBundles() removal
+	 * pending} bundles.
+	 * 
+	 * <li>Each bundle in the dependency closure that is in the {@code ACTIVE}
+	 * state will be stopped as described in the {@code Bundle.stop} method.
+	 * 
+	 * <li>Each bundle in the dependency closure that is in the {@code RESOLVED}
+	 * state is unresolved and thus moved to the {@code INSTALLED} state. The
+	 * effect of this step is that bundles in the dependency closure are no
+	 * longer {@code RESOLVED}.
+	 * 
+	 * <li>Each bundle in the dependency closure that is in the
+	 * {@code UNINSTALLED} state is removed from the dependency closure and is
+	 * now completely removed from the Framework.
+	 * 
+	 * <li>Each bundle in the dependency closure that was in the {@code ACTIVE}
+	 * state prior to Step 2 is started as described in the {@code Bundle.start}
+	 * method, causing all bundles required for the restart to be resolved. It
+	 * is possible that, as a result of the previous steps, packages that were
+	 * previously exported no longer are. Therefore, some bundles may be
+	 * unresolvable until bundles satisfying the dependencies have been
+	 * installed in the Framework.
+	 * </ol>
+	 * 
+	 * <p>
+	 * For any exceptions that are thrown during any of these steps, a framework
+	 * event of type {@code FrameworkEvent.ERROR} is fired containing the
+	 * exception. The source bundle for these events should be the specific
+	 * bundle to which the exception is related. If no specific bundle can be
+	 * associated with the exception then the System Bundle must be used as the
+	 * source bundle for the event. All framework events fired by this method
+	 * are also delivered to the specified {@code FrameworkListener}s in the
+	 * order they are specified.
+	 * 
+	 * <p>
+	 * When this process completes after the bundles are refreshed, the
+	 * Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.PACKAGES_REFRESHED} to announce it has completed
+	 * the bundle refresh. The specified {@code FrameworkListener}s are notified
+	 * in the order specified. Each specified {@code FrameworkListener} will be
+	 * called with a Framework event of type
+	 * {@code FrameworkEvent.PACKAGES_REFRESHED}.
+	 * 
+	 * @param bundles The bundles to be refreshed, or {@code null} to refresh
+	 *        the {@link #getRemovalPendingBundles() removal pending} bundles.
+	 * @param listeners Zero or more listeners to be notified when the bundle
+	 *        refresh has been completed. The specified listeners do not need to
+	 *        be otherwise registered with the framework. If a specified
+	 *        listener is already registered with the framework, it will be
+	 *        notified twice.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s were
+	 *         not created by the same framework instance associated with this
+	 *         FrameworkWiring.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	void refreshBundles(Collection<Bundle> bundles, FrameworkListener... listeners);
+
+	/**
+	 * Resolves the specified bundles. The Framework must attempt to resolve the
+	 * specified bundles that are unresolved. Additional bundles that are not
+	 * included in the specified bundles may be resolved as a result of calling
+	 * this method. A permissible implementation of this method is to attempt to
+	 * resolve all unresolved bundles installed in the framework.
+	 * 
+	 * <p>
+	 * If no bundles are specified, then the Framework will attempt to resolve
+	 * all unresolved bundles. This method must not cause any bundle to be
+	 * refreshed, stopped, or started. This method will not return until the
+	 * operation has completed.
+	 * 
+	 * @param bundles The bundles to resolve or {@code null} to resolve all
+	 *        unresolved bundles installed in the Framework.
+	 * @return {@code true} if all specified bundles are resolved; {@code false}
+	 *         otherwise.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s were
+	 *         not created by the same framework instance associated with this
+	 *         FrameworkWiring.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	boolean resolveBundles(Collection<Bundle> bundles);
+
+	/**
+	 * Returns the bundles that have {@link BundleWiring#isCurrent()
+	 * non-current}, {@link BundleWiring#isInUse() in use} bundle wirings. This
+	 * is typically the bundles which have been updated or uninstalled since the
+	 * last call to {@link #refreshBundles(Collection, FrameworkListener...)}.
+	 * 
+	 * @return A collection containing a snapshot of the {@code Bundle}s which
+	 *         have non-current, in use {@code BundleWiring}s, or an empty
+	 *         collection if there are no such bundles.
+	 */
+	Collection<Bundle> getRemovalPendingBundles();
+
+	/**
+	 * Returns the dependency closure for the specified bundles.
+	 * 
+	 * <p>
+	 * A graph of bundles is computed starting with the specified bundles. The
+	 * graph is expanded by adding any bundle that is either wired to a package
+	 * that is currently exported by a bundle in the graph or requires a bundle
+	 * in the graph. The graph is fully constructed when there is no bundle
+	 * outside the graph that is wired to a bundle in the graph. The graph may
+	 * contain {@code UNINSTALLED} bundles that are
+	 * {@link #getRemovalPendingBundles() removal pending}.
+	 * 
+	 * @param bundles The initial bundles for which to generate the dependency
+	 *        closure.
+	 * @return A collection containing a snapshot of the dependency closure of
+	 *         the specified bundles, or an empty collection if there were no
+	 *         specified bundles.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s were
+	 *         not created by the same framework instance associated with this
+	 *         FrameworkWiring.
+	 */
+	Collection<Bundle> getDependencyClosure(Collection<Bundle> bundles);
+}
diff --git a/osgi/framework/src/org/osgi/framework/wiring/package-info.java b/osgi/framework/src/org/osgi/framework/wiring/package-info.java
new file mode 100644
index 0000000..9d0fdf7
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/package-info.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Framework Wiring Package Version 1.1.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. For example:
+ * 
+ * <pre>
+ * Import-Package: org.osgi.framework.wiring; version="[1.1,2.0)"
+ * </pre>
+ * 
+ * @version $Id: 6f5c519e9ff1ee6ebc7a2564006e97385bb972ca $
+ */
+
+package org.osgi.framework.wiring;
+
diff --git a/osgi/framework/src/org/osgi/framework/wiring/packageinfo b/osgi/framework/src/org/osgi/framework/wiring/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/framework/wiring/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/osgi/framework/src/org/osgi/resource/Capability.java b/osgi/framework/src/org/osgi/resource/Capability.java
new file mode 100644
index 0000000..bda0ce6
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/Capability.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.Map;
+
+/**
+ * A capability that has been declared from a {@link Resource}.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: 5f40514f7bf45f6dce59651e8812b0922580e77e $
+ */
+public interface Capability {
+
+	/**
+	 * Returns the namespace of this capability.
+	 * 
+	 * @return The namespace of this capability.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this capability.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this capability, or an empty map if this capability has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this capability.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this capability, or an empty map if this capability has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the resource declaring this capability.
+	 * 
+	 * @return The resource declaring this capability.
+	 */
+	Resource getResource();
+
+	/**
+	 * Compares this {@code Capability} to another {@code Capability}.
+	 * 
+	 * <p>
+	 * This {@code Capability} is equal to another {@code Capability} if they
+	 * have the same namespace, directives and attributes and are declared by
+	 * the same resource.
+	 * 
+	 * @param obj The object to compare against this {@code Capability}.
+	 * @return {@code true} if this {@code Capability} is equal to the other
+	 *         object; {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Capability}.
+	 * 
+	 * @return The hashCode of this {@code Capability}.
+	 */
+	int hashCode();
+}
diff --git a/osgi/framework/src/org/osgi/resource/Namespace.java b/osgi/framework/src/org/osgi/resource/Namespace.java
new file mode 100644
index 0000000..abda616
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/Namespace.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+/**
+ * Capability and Requirement Namespaces base class.
+ * 
+ * <p>
+ * This class is the common class shared by all OSGi defined namespaces. It
+ * defines the names for the common attributes and directives for the OSGi
+ * specified namespaces.
+ * 
+ * <p>
+ * The OSGi Alliance reserves the right to extend the set of directives and
+ * attributes which have specified semantics for all of the specified
+ * namespaces.
+ * 
+ * <p>
+ * The values associated with these keys are of type {@code String}, unless
+ * otherwise indicated.
+ * 
+ * @Immutable
+ * @version $Id: 43c9ff5cea19546d71c4703db71a2b5070a3f2fa $
+ */
+public abstract class Namespace {
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * package names used by a capability.
+	 */
+	public final static String	CAPABILITY_USES_DIRECTIVE			= "uses";
+
+	/**
+	 * The capability directive used to specify the effective time for the
+	 * capability. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
+	 * 
+	 * @see #EFFECTIVE_RESOLVE resolve
+	 * @see #EFFECTIVE_ACTIVE active
+	 */
+	public final static String	CAPABILITY_EFFECTIVE_DIRECTIVE		= "effective";
+
+	/**
+	 * The requirement directive used to specify a capability filter. This
+	 * filter is used to match against a capability's attributes.
+	 */
+	public final static String	REQUIREMENT_FILTER_DIRECTIVE		= "filter";
+
+	/**
+	 * The requirement directive used to specify the resolution type for a
+	 * requirement. The default value is {@link #RESOLUTION_MANDATORY mandatory}
+	 * .
+	 * 
+	 * @see #RESOLUTION_MANDATORY mandatory
+	 * @see #RESOLUTION_OPTIONAL optional
+	 */
+	public final static String	REQUIREMENT_RESOLUTION_DIRECTIVE	= "resolution";
+
+	/**
+	 * The directive value identifying a mandatory requirement resolution type.
+	 * A mandatory resolution type indicates that the requirement must be
+	 * resolved when the resource is resolved. If such a requirement cannot be
+	 * resolved, the resource fails to resolve.
+	 * 
+	 * @see #REQUIREMENT_RESOLUTION_DIRECTIVE
+	 */
+	public final static String	RESOLUTION_MANDATORY				= "mandatory";
+
+	/**
+	 * The directive value identifying an optional requirement resolution type.
+	 * An optional resolution type indicates that the requirement is optional
+	 * and the resource may be resolved without the requirement being resolved.
+	 * 
+	 * @see #REQUIREMENT_RESOLUTION_DIRECTIVE
+	 */
+	public final static String	RESOLUTION_OPTIONAL					= "optional";
+
+	/**
+	 * The requirement directive used to specify the effective time for the
+	 * requirement. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
+	 * 
+	 * @see #EFFECTIVE_RESOLVE resolve
+	 * @see #EFFECTIVE_ACTIVE active
+	 */
+	public final static String	REQUIREMENT_EFFECTIVE_DIRECTIVE		= "effective";
+
+	/**
+	 * The directive value identifying a {@link #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * capability} or {@link #REQUIREMENT_EFFECTIVE_DIRECTIVE requirement} that
+	 * is effective at resolve time. Capabilities and requirements with an
+	 * effective time of resolve are the only capabilities which are processed
+	 * while resolving a resource.
+	 * 
+	 * @see #REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * @see #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 */
+	public final static String	EFFECTIVE_RESOLVE					= "resolve";
+
+	/**
+	 * The directive value identifying a {@link #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * capability} or {@link #REQUIREMENT_EFFECTIVE_DIRECTIVE requirement} that
+	 * is effective at active time. Capabilities and requirements with an
+	 * effective time of active are ignored while resolving a resource.
+	 * 
+	 * @see #REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * @see #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 */
+	public final static String	EFFECTIVE_ACTIVE					= "active";
+
+	/**
+	 * The requirement directive used to specify the cardinality for a
+	 * requirement. The default value is {@link #CARDINALITY_SINGLE single}.
+	 * 
+	 * @see #CARDINALITY_MULTIPLE multiple
+	 * @see #CARDINALITY_SINGLE single
+	 */
+	public final static String	REQUIREMENT_CARDINALITY_DIRECTIVE	= "cardinality";
+
+	/**
+	 * The directive value identifying a multiple
+	 * {@link #REQUIREMENT_CARDINALITY_DIRECTIVE cardinality} type.
+	 * 
+	 * @see #REQUIREMENT_CARDINALITY_DIRECTIVE
+	 */
+	public final static String	CARDINALITY_MULTIPLE				= "multiple";
+
+	/**
+	 * The directive value identifying a
+	 * {@link #REQUIREMENT_CARDINALITY_DIRECTIVE cardinality} type of single.
+	 * 
+	 * @see #REQUIREMENT_CARDINALITY_DIRECTIVE
+	 */
+	public final static String	CARDINALITY_SINGLE					= "single";
+
+	/**
+	 * Protected constructor for Namespace sub-types.
+	 */
+	protected Namespace() {
+		// empty
+	}
+}
diff --git a/osgi/framework/src/org/osgi/resource/Requirement.java b/osgi/framework/src/org/osgi/resource/Requirement.java
new file mode 100644
index 0000000..cf931bf
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/Requirement.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.Map;
+
+/**
+ * A requirement that has been declared from a {@link Resource} .
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: 212b26179910f98fd2c59c3e1e7dd0d086f42b5d $
+ */
+public interface Requirement {
+	/**
+	 * Returns the namespace of this requirement.
+	 * 
+	 * @return The namespace of this requirement.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this requirement.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this requirement.
+	 * 
+	 * <p>
+	 * Requirement attributes have no specified semantics and are considered
+	 * extra user defined information.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the resource declaring this requirement.
+	 * 
+	 * @return The resource declaring this requirement. This can be {@code null}
+	 *         if this requirement is synthesized.
+	 */
+	Resource getResource();
+
+	/**
+	 * Compares this {@code Requirement} to another {@code Requirement}.
+	 * 
+	 * <p>
+	 * This {@code Requirement} is equal to another {@code Requirement} if they
+	 * have the same namespace, directives and attributes and are declared by
+	 * the same resource.
+	 * 
+	 * @param obj The object to compare against this {@code Requirement}.
+	 * @return {@code true} if this {@code Requirement} is equal to the other
+	 *         object; {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Requirement}.
+	 * 
+	 * @return The hashCode of this {@code Requirement}.
+	 */
+	int hashCode();
+}
diff --git a/osgi/framework/src/org/osgi/resource/Resource.java b/osgi/framework/src/org/osgi/resource/Resource.java
new file mode 100644
index 0000000..455d891
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/Resource.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.List;
+
+/**
+ * A resource is the representation of a uniquely identified and typed data. A
+ * resource declares requirements that need to be satisfied by capabilities
+ * before it can provide its capabilities.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: 40958d5777ee269d27d58e9f646a4c91bcc6daa4 $
+ */
+public interface Resource {
+	/**
+	 * Returns the capabilities declared by this resource.
+	 * 
+	 * @param namespace The namespace of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Capability}s
+	 *         from the specified namespace. The returned list will be empty if
+	 *         this resource declares no capabilities in the specified
+	 *         namespace.
+	 */
+	List<Capability> getCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements declared by this bundle resource.
+	 * 
+	 * @param namespace The namespace of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Requirement}
+	 *         s from the specified namespace. The returned list will be empty
+	 *         if this resource declares no requirements in the specified
+	 *         namespace.
+	 */
+	List<Requirement> getRequirements(String namespace);
+
+	/**
+	 * Compares this {@code Resource} to another {@code Resource}.
+	 * 
+	 * <p>
+	 * This {@code Resource} is equal to another {@code Resource} if both have
+	 * the same content and come from the same location. Location may be defined
+	 * as the bundle location if the resource is an installed bundle or the
+	 * repository location if the resource is in a repository.
+	 * 
+	 * @param obj The object to compare against this {@code Resource}.
+	 * @return {@code true} if this {@code Resource} is equal to the other
+	 *         object; {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Resource}.
+	 * 
+	 * @return The hashCode of this {@code Resource}.
+	 */
+	int hashCode();
+}
diff --git a/osgi/framework/src/org/osgi/resource/Wire.java b/osgi/framework/src/org/osgi/resource/Wire.java
new file mode 100644
index 0000000..18feab8
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/Wire.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+/**
+ * A wire connecting a {@link Capability} to a {@link Requirement}.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: d7ca9a5d3e8dd2277f8243a750e40fbcf79185bd $
+ */
+public interface Wire {
+	/**
+	 * Returns the {@link Capability} for this wire.
+	 * 
+	 * @return The {@link Capability} for this wire.
+	 */
+	Capability getCapability();
+
+	/**
+	 * Returns the {@link Requirement} for this wire.
+	 * 
+	 * @return The {@link Requirement} for this wire.
+	 */
+	Requirement getRequirement();
+
+	/**
+	 * Returns the resource providing the {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * @return The resource providing the capability.
+	 */
+	Resource getProvider();
+
+	/**
+	 * Returns the resource who {@link #getRequirement() requires} the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getRequirement() requirement}.
+	 * 
+	 * @return The resource who requires the capability.
+	 */
+	Resource getRequirer();
+
+	/**
+	 * Compares this {@code Wire} to another {@code Wire}.
+	 * 
+	 * <p>
+	 * This {@code Wire} is equal to another {@code Wire} if they have the same
+	 * capability, requirement, provider and requirer.
+	 * 
+	 * @param obj The object to compare against this {@code Wire}.
+	 * @return {@code true} if this {@code Wire} is equal to the other object;
+	 *         {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Wire}.
+	 * 
+	 * @return The hashCode of this {@code Wire}.
+	 */
+	int hashCode();
+}
diff --git a/osgi/framework/src/org/osgi/resource/Wiring.java b/osgi/framework/src/org/osgi/resource/Wiring.java
new file mode 100644
index 0000000..230fef0
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/Wiring.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.List;
+
+/**
+ * A wiring for a resource. A wiring is associated with a resource and
+ * represents the dependencies with other wirings.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: b65dec3887cfa1d5731e860db558a01503c0f47d $
+ */
+public interface Wiring {
+	/**
+	 * Returns the capabilities provided by this wiring.
+	 * 
+	 * <p>
+	 * Only capabilities considered by the resolver are returned. For example,
+	 * capabilities with {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A capability may not be required by any wiring and thus there may be no
+	 * {@link #getProvidedResourceWires(String) wires} for the capability.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource provides a subset of the declared
+	 * capabilities from the resource and all attached fragment
+	 * resources<sup>†</sup>. Not all declared capabilities may be
+	 * provided since some may be discarded. For example, if a package is
+	 * declared to be both exported and imported, only one is selected and the
+	 * other is discarded.
+	 * <p>
+	 * A wiring for a fragment resource with a symbolic name must provide
+	 * exactly one {@code osgi.identity} capability.
+	 * <p>
+	 * † The {@code osgi.identity} capability provided by attached
+	 * fragment resource must not be included in the capabilities of the host
+	 * wiring.
+	 * 
+	 * @param namespace The namespace of the capabilities to return or
+	 *        {@code null} to return the capabilities from all namespaces.
+	 * @return A list containing a snapshot of the {@link Capability}s, or an
+	 *         empty list if this wiring provides no capabilities in the
+	 *         specified namespace. For a given namespace, the list contains the
+	 *         wires in the order the capabilities were specified in the
+	 *         manifests of the {@link #getResource() resource} and the attached
+	 *         fragment resources<sup>†</sup> of this wiring. There is no
+	 *         ordering defined between capabilities in different namespaces.
+	 */
+	List<Capability> getResourceCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements of this wiring.
+	 * 
+	 * <p>
+	 * Only requirements considered by the resolver are returned. For example,
+	 * requirements with {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource has a subset of the declared
+	 * requirements from the resource and all attached fragment resources. Not
+	 * all declared requirements may be present since some may be discarded. For
+	 * example, if a package is declared to be optionally imported and is not
+	 * actually imported, the requirement must be discarded.
+	 * 
+	 * @param namespace The namespace of the requirements to return or
+	 *        {@code null} to return the requirements from all namespaces.
+	 * @return A list containing a snapshot of the {@link Requirement}s, or an
+	 *         empty list if this wiring uses no requirements in the specified
+	 *         namespace. For a given namespace, the list contains the wires in
+	 *         the order the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 */
+	List<Requirement> getResourceRequirements(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the provided {@link Capability capabilities}
+	 * of this wiring.
+	 * 
+	 * @param namespace The namespace of the capabilities for which to return
+	 *        wires or {@code null} to return the wires for the capabilities in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Capability capabilities} of this wiring, or an empty list
+	 *         if this wiring has no capabilities in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the capabilities were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         capabilities in different namespaces.
+	 */
+	List<Wire> getProvidedResourceWires(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the {@link Requirement requirements} in use
+	 * by this wiring.
+	 * 
+	 * @param namespace The namespace of the requirements for which to return
+	 *        wires or {@code null} to return the wires for the requirements in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Requirement requirements} of this wiring, or an empty list
+	 *         if this wiring has no requirements in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 */
+	List<Wire> getRequiredResourceWires(String namespace);
+
+	/**
+	 * Returns the resource associated with this wiring.
+	 * 
+	 * @return The resource associated with this wiring.
+	 */
+	Resource getResource();
+}
diff --git a/osgi/framework/src/org/osgi/resource/package-info.java b/osgi/framework/src/org/osgi/resource/package-info.java
new file mode 100644
index 0000000..a81d655
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/package-info.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Resource Package Version 1.0.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. For example:
+ * 
+ * <pre>
+ * Import-Package: org.osgi.resource; version="[1.0,2.0)"
+ * </pre>
+ * 
+ * @version $Id: d0272f91b8f76d63729dc851569da04b2ea88092 $
+ */
+
+package org.osgi.resource;
+
diff --git a/osgi/framework/src/org/osgi/resource/packageinfo b/osgi/framework/src/org/osgi/resource/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/osgi/framework/src/org/osgi/resource/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/BundleLocationCondition.java b/osgi/framework/src/org/osgi/service/condpermadmin/BundleLocationCondition.java
new file mode 100644
index 0000000..71b95e2
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/BundleLocationCondition.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Condition to test if the location of a bundle matches or does not match a
+ * pattern. Since the bundle's location cannot be changed, this condition is
+ * immutable.
+ * 
+ * <p>
+ * Pattern matching is done according to the filter string matching rules.
+ * 
+ * @ThreadSafe
+ * @version $Id: 43b6af515f7f92b5fe8fde94cc0b03dc7044807b $
+ */
+public class BundleLocationCondition {
+	private static final String	CONDITION_TYPE	= "org.osgi.service.condpermadmin.BundleLocationCondition";
+
+	/**
+	 * Constructs a condition that tries to match the passed Bundle's location
+	 * to the location pattern.
+	 * 
+	 * @param bundle The Bundle being evaluated.
+	 * @param info The ConditionInfo from which to construct the condition. The
+	 *        ConditionInfo must specify one or two arguments. The first
+	 *        argument of the ConditionInfo specifies the location pattern
+	 *        against which to match the bundle location. Matching is done
+	 *        according to the filter string matching rules. Any '*' characters
+	 *        in the first argument are used as wildcards when matching bundle
+	 *        locations unless they are escaped with a '\' character. The
+	 *        Condition is satisfied if the bundle location matches the pattern.
+	 *        The second argument of the ConditionInfo is optional. If a second
+	 *        argument is present and equal to "!", then the satisfaction of the
+	 *        Condition is negated. That is, the Condition is satisfied if the
+	 *        bundle location does NOT match the pattern. If the second argument
+	 *        is present but does not equal "!", then the second argument is
+	 *        ignored.
+	 * @return Condition object for the requested condition.
+	 */
+	static public Condition getCondition(final Bundle bundle, final ConditionInfo info) {
+		if (!CONDITION_TYPE.equals(info.getType()))
+			throw new IllegalArgumentException("ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+		String[] args = info.getArgs();
+		if (args.length != 1 && args.length != 2)
+			throw new IllegalArgumentException("Illegal number of args: " + args.length);
+		String bundleLocation = AccessController.doPrivileged(new PrivilegedAction<String>() {
+			public String run() {
+				return bundle.getLocation();
+			}
+		});
+		Filter filter = null;
+		try {
+			filter = FrameworkUtil.createFilter("(location=" + escapeLocation(args[0]) + ")");
+		} catch (InvalidSyntaxException e) {
+			// this should never happen, but just in case
+			throw new RuntimeException("Invalid filter: " + e.getFilter(), e);
+		}
+		Dictionary<String, String> matchProps = new Hashtable<String, String>(2);
+		matchProps.put("location", bundleLocation);
+		boolean negate = (args.length == 2) ? "!".equals(args[1]) : false;
+		return (negate ^ filter.match(matchProps)) ? Condition.TRUE : Condition.FALSE;
+	}
+
+	private BundleLocationCondition() {
+		// private constructor to prevent objects of this type
+	}
+
+	/**
+	 * Escape the value string such that '(', ')' and '\' are escaped. The '\'
+	 * char is only escaped if it is not followed by a '*'.
+	 * 
+	 * @param value unescaped value string.
+	 * @return escaped value string.
+	 */
+	private static String escapeLocation(final String value) {
+		boolean escaped = false;
+		int inlen = value.length();
+		int outlen = inlen << 1; /* inlen * 2 */
+
+		char[] output = new char[outlen];
+		value.getChars(0, inlen, output, inlen);
+
+		int cursor = 0;
+		for (int i = inlen; i < outlen; i++) {
+			char c = output[i];
+			switch (c) {
+				case '\\' :
+					if (i + 1 < outlen && output[i + 1] == '*')
+						break;
+				case '(' :
+				case ')' :
+					output[cursor] = '\\';
+					cursor++;
+					escaped = true;
+					break;
+			}
+
+			output[cursor] = c;
+			cursor++;
+		}
+
+		return escaped ? new String(output, 0, cursor) : value;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/BundleSignerCondition.java b/osgi/framework/src/org/osgi/service/condpermadmin/BundleSignerCondition.java
new file mode 100644
index 0000000..884faec
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/BundleSignerCondition.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Condition to test if the signer of a bundle matches or does not match a
+ * pattern. Since the bundle's signer can only change when the bundle is
+ * updated, this condition is immutable.
+ * <p>
+ * The condition expressed using a single String that specifies a Distinguished
+ * Name (DN) chain to match bundle signers against. DN's are encoded using IETF
+ * RFC 2253. Usually signers use certificates that are issued by certificate
+ * authorities, which also have a corresponding DN and certificate. The
+ * certificate authorities can form a chain of trust where the last DN and
+ * certificate is known by the framework. The signer of a bundle is expressed as
+ * signers DN followed by the DN of its issuer followed by the DN of the next
+ * issuer until the DN of the root certificate authority. Each DN is separated
+ * by a semicolon.
+ * <p>
+ * A bundle can satisfy this condition if one of its signers has a DN chain that
+ * matches the DN chain used to construct this condition. Wildcards (`*') can be
+ * used to allow greater flexibility in specifying the DN chains. Wildcards can
+ * be used in place of DNs, RDNs, or the value in an RDN. If a wildcard is used
+ * for a value of an RDN, the value must be exactly "*" and will match any value
+ * for the corresponding type in that RDN. If a wildcard is used for a RDN, it
+ * must be the first RDN and will match any number of RDNs (including zero
+ * RDNs).
+ * 
+ * @ThreadSafe
+ * @version $Id: 8f8619a999cf2afba3d9c1e52e3fc0df2cde636c $
+ */
+public class BundleSignerCondition {
+	private static final String	CONDITION_TYPE	= "org.osgi.service.condpermadmin.BundleSignerCondition";
+
+	/**
+	 * Constructs a Condition that tries to match the passed Bundle's location
+	 * to the location pattern.
+	 * 
+	 * @param bundle The Bundle being evaluated.
+	 * @param info The ConditionInfo from which to construct the condition. The
+	 *        ConditionInfo must specify one or two arguments. The first
+	 *        argument of the ConditionInfo specifies the chain of distinguished
+	 *        names pattern to match against the signer of the bundle. The
+	 *        Condition is satisfied if the signer of the bundle matches the
+	 *        pattern. The second argument of the ConditionInfo is optional. If
+	 *        a second argument is present and equal to "!", then the
+	 *        satisfaction of the Condition is negated. That is, the Condition
+	 *        is satisfied if the signer of the bundle does NOT match the
+	 *        pattern. If the second argument is present but does not equal "!",
+	 *        then the second argument is ignored.
+	 * @return A Condition which checks the signers of the specified bundle.
+	 */
+	public static Condition getCondition(final Bundle bundle, final ConditionInfo info) {
+		if (!CONDITION_TYPE.equals(info.getType()))
+			throw new IllegalArgumentException("ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
+		String[] args = info.getArgs();
+		if (args.length != 1 && args.length != 2)
+			throw new IllegalArgumentException("Illegal number of args: " + args.length);
+
+		Map<X509Certificate, List<X509Certificate>> signers = bundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		boolean match = false;
+		for (List<X509Certificate> signerCerts : signers.values()) {
+			List<String> dnChain = new ArrayList<String>(signerCerts.size());
+			for (X509Certificate signer : signerCerts) {
+				dnChain.add(signer.getSubjectDN().getName());
+			}
+			if (FrameworkUtil.matchDistinguishedNameChain(args[0], dnChain)) {
+				match = true;
+				break;
+			}
+		}
+
+		boolean negate = (args.length == 2) ? "!".equals(args[1]) : false;
+		return negate ^ match ? Condition.TRUE : Condition.FALSE;
+	}
+
+	private BundleSignerCondition() {
+		// private constructor to prevent objects of this type
+	}
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/Condition.java b/osgi/framework/src/org/osgi/service/condpermadmin/Condition.java
new file mode 100644
index 0000000..bcf9a30
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/Condition.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.util.Dictionary;
+
+/**
+ * The interface implemented by a Condition. Conditions are bound to Permissions
+ * using Conditional Permission Info. The Permissions of a ConditionalPermission
+ * Info can only be used if the associated Conditions are satisfied.
+ * 
+ * @ThreadSafe
+ * @version $Id: ae2500276f1204a47a981347579f5b53cc8a7e4f $
+ */
+public interface Condition {
+	/**
+	 * A Condition object that will always evaluate to true and that is never
+	 * postponed.
+	 */
+	public final static Condition	TRUE	= new BooleanCondition(true);
+
+	/**
+	 * A Condition object that will always evaluate to false and that is never
+	 * postponed.
+	 */
+	public final static Condition	FALSE	= new BooleanCondition(false);
+
+	/**
+	 * Returns whether the evaluation must be postponed until the end of the
+	 * permission check. If this method returns {@code false} (or this Condition
+	 * is immutable), then this Condition must be able to directly answer the
+	 * {@link #isSatisfied()} method. In other words, isSatisfied() will return
+	 * very quickly since no external sources, such as for example users or
+	 * networks, need to be consulted. <br/>
+	 * This method must always return the same value whenever it is called so
+	 * that the Conditional Permission Admin can cache its result.
+	 * 
+	 * @return {@code true} to indicate the evaluation must be postponed.
+	 *         Otherwise, {@code false} if the evaluation can be performed
+	 *         immediately.
+	 */
+	boolean isPostponed();
+
+	/**
+	 * Returns whether the Condition is satisfied. This method is only called
+	 * for immediate Condition objects or immutable postponed conditions, and
+	 * must always be called inside a permission check. Mutable postponed
+	 * Condition objects will be called with the grouped version
+	 * {@link #isSatisfied(Condition[],Dictionary)} at the end of the permission
+	 * check.
+	 * 
+	 * @return {@code true} to indicate the Conditions is satisfied. Otherwise,
+	 *         {@code false} if the Condition is not satisfied.
+	 */
+	boolean isSatisfied();
+
+	/**
+	 * Returns whether the Condition is mutable. A Condition can go from mutable
+	 * ({@code true}) to immutable ({@code false}) over time but never from
+	 * immutable ({@code false}) to mutable ({@code true}).
+	 * 
+	 * @return {@code true} {@link #isSatisfied()} can change. Otherwise,
+	 *         {@code false} if the value returned by {@link #isSatisfied()}
+	 *         will not change for this condition.
+	 */
+	boolean isMutable();
+
+	/**
+	 * Returns whether the specified set of Condition objects are satisfied.
+	 * Although this method is not static, it must be implemented as if it were
+	 * static. All of the passed Condition objects will be of the same type and
+	 * will correspond to the class type of the object on which this method is
+	 * invoked. This method must be called inside a permission check only.
+	 * 
+	 * @param conditions The array of Condition objects, which must all be of
+	 *        the same class and mutable. The receiver must be one of those
+	 *        Condition objects.
+	 * @param context A Dictionary object that implementors can use to track
+	 *        state. If this method is invoked multiple times in the same
+	 *        permission check, the same Dictionary will be passed multiple
+	 *        times. The SecurityManager treats this Dictionary as an opaque
+	 *        object and simply creates an empty dictionary and passes it to
+	 *        subsequent invocations if multiple invocations are needed.
+	 * @return {@code true} if all the Condition objects are satisfied.
+	 *         Otherwise, {@code false} if one of the Condition objects is not
+	 *         satisfied.
+	 */
+	boolean isSatisfied(Condition conditions[], Dictionary<Object, Object> context);
+}
+
+/**
+ * Package private class used to define the {@link Condition#FALSE} and
+ * {@link Condition#TRUE} constants.
+ * 
+ * @Immutable
+ */
+final class BooleanCondition implements Condition {
+	private final boolean	satisfied;
+
+	BooleanCondition(boolean satisfied) {
+		this.satisfied = satisfied;
+	}
+
+	public boolean isPostponed() {
+		return false;
+	}
+
+	public boolean isSatisfied() {
+		return satisfied;
+	}
+
+	public boolean isMutable() {
+		return false;
+	}
+
+	public boolean isSatisfied(Condition[] conds, Dictionary<Object, Object> context) {
+		for (int i = 0, length = conds.length; i < length; i++) {
+			if (!conds[i].isSatisfied())
+				return false;
+		}
+		return true;
+	}
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/ConditionInfo.java b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionInfo.java
new file mode 100644
index 0000000..b11c5f1
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionInfo.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Condition representation used by the Conditional Permission Admin service.
+ * 
+ * <p>
+ * This class encapsulates two pieces of information: a Condition <i>type</i>
+ * (class name), which must implement {@code Condition}, and the arguments
+ * passed to its constructor.
+ * 
+ * <p>
+ * In order for a Condition represented by a {@code ConditionInfo} to be
+ * instantiated and considered during a permission check, its Condition class
+ * must be available from the system classpath.
+ * 
+ * <p>
+ * The Condition class must either:
+ * <ul>
+ * <li>Declare a public static {@code getCondition} method that takes a
+ * {@code Bundle} object and a {@code ConditionInfo} object as arguments. That
+ * method must return an object that implements the {@code Condition} interface.
+ * </li>
+ * <li>Implement the {@code Condition} interface and define a public constructor
+ * that takes a {@code Bundle} object and a {@code ConditionInfo} object as
+ * arguments.
+ * </ul>
+ * 
+ * @Immutable
+ * @version $Id: c2497fefba5a0011a141f9548c3d383b34d3dc8d $
+ */
+public class ConditionInfo {
+	private final String	type;
+	private final String[]	args;
+
+	/**
+	 * Constructs a {@code ConditionInfo} from the specified type and args.
+	 * 
+	 * @param type The fully qualified class name of the Condition represented
+	 *        by this {@code ConditionInfo}.
+	 * @param args The arguments for the Condition. These arguments are
+	 *        available to the newly created Condition by calling the
+	 *        {@link #getArgs()} method.
+	 * @throws NullPointerException If {@code type} is {@code null}.
+	 */
+	public ConditionInfo(String type, String[] args) {
+		this.type = type;
+		this.args = (args != null) ? args.clone() : new String[0];
+		if (type == null) {
+			throw new NullPointerException("type is null");
+		}
+	}
+
+	/**
+	 * Constructs a {@code ConditionInfo} object from the specified encoded
+	 * {@code ConditionInfo} string. White space in the encoded
+	 * {@code ConditionInfo} string is ignored.
+	 * 
+	 * @param encodedCondition The encoded {@code ConditionInfo}.
+	 * @see #getEncoded()
+	 * @throws IllegalArgumentException If the specified
+	 *         {@code encodedCondition} is not properly formatted.
+	 */
+	public ConditionInfo(String encodedCondition) {
+		if (encodedCondition == null) {
+			throw new NullPointerException("missing encoded condition");
+		}
+		if (encodedCondition.length() == 0) {
+			throw new IllegalArgumentException("empty encoded condition");
+		}
+		try {
+			char[] encoded = encodedCondition.toCharArray();
+			int length = encoded.length;
+			int pos = 0;
+
+			/* skip whitespace */
+			while (Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+
+			/* the first character must be '[' */
+			if (encoded[pos] != '[') {
+				throw new IllegalArgumentException("expecting open bracket");
+			}
+			pos++;
+
+			/* skip whitespace */
+			while (Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+
+			/* type is not quoted or encoded */
+			int begin = pos;
+			while (!Character.isWhitespace(encoded[pos]) && (encoded[pos] != ']')) {
+				pos++;
+			}
+			if (pos == begin || encoded[begin] == '"') {
+				throw new IllegalArgumentException("expecting type");
+			}
+			this.type = new String(encoded, begin, pos - begin);
+
+			/* skip whitespace */
+			while (Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+
+			/* type may be followed by args which are quoted and encoded */
+			List<String> argsList = new ArrayList<String>();
+			while (encoded[pos] == '"') {
+				pos++;
+				begin = pos;
+				while (encoded[pos] != '"') {
+					if (encoded[pos] == '\\') {
+						pos++;
+					}
+					pos++;
+				}
+				argsList.add(unescapeString(encoded, begin, pos));
+				pos++;
+
+				if (Character.isWhitespace(encoded[pos])) {
+					/* skip whitespace */
+					while (Character.isWhitespace(encoded[pos])) {
+						pos++;
+					}
+				}
+			}
+			this.args = argsList.toArray(new String[argsList.size()]);
+
+			/* the final character must be ']' */
+			char c = encoded[pos];
+			pos++;
+			while ((pos < length) && Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+			if ((c != ']') || (pos != length)) {
+				throw new IllegalArgumentException("expecting close bracket");
+			}
+		} catch (ArrayIndexOutOfBoundsException e) {
+			throw new IllegalArgumentException("parsing terminated abruptly");
+		}
+	}
+
+	/**
+	 * Returns the string encoding of this {@code ConditionInfo} in a form
+	 * suitable for restoring this {@code ConditionInfo}.
+	 * 
+	 * <p>
+	 * The encoded format is:
+	 * 
+	 * <pre>
+	 *   [type "arg0" "arg1" ...]
+	 * </pre>
+	 * 
+	 * where <i>argN</i> are strings that must be encoded for proper parsing.
+	 * Specifically, the {@code "}, {@code \}, carriage return, and line
+	 * feed characters must be escaped using {@code \"}, {@code \\},
+	 * {@code \r}, and {@code \n}, respectively.
+	 * 
+	 * <p>
+	 * The encoded string contains no leading or trailing whitespace characters.
+	 * A single space character is used between type and "<i>arg0</i>"
+	 * and between the arguments.
+	 * 
+	 * @return The string encoding of this {@code ConditionInfo}.
+	 */
+	public final String getEncoded() {
+		StringBuffer output = new StringBuffer();
+		output.append('[');
+		output.append(type);
+
+		for (int i = 0; i < args.length; i++) {
+			output.append(" \"");
+			escapeString(args[i], output);
+			output.append('\"');
+		}
+
+		output.append(']');
+
+		return output.toString();
+	}
+
+	/**
+	 * Returns the string representation of this {@code ConditionInfo}. The
+	 * string is created by calling the {@code getEncoded} method on this
+	 * {@code ConditionInfo}.
+	 * 
+	 * @return The string representation of this {@code ConditionInfo}.
+	 */
+	public String toString() {
+		return getEncoded();
+	}
+
+	/**
+	 * Returns the fully qualified class name of the condition represented by
+	 * this {@code ConditionInfo}.
+	 * 
+	 * @return The fully qualified class name of the condition represented by
+	 *         this {@code ConditionInfo}.
+	 */
+	public final String getType() {
+		return type;
+	}
+
+	/**
+	 * Returns arguments of this {@code ConditionInfo}.
+	 * 
+	 * @return The arguments of this {@code ConditionInfo}. An empty array is
+	 *         returned if the {@code ConditionInfo} has no arguments.
+	 */
+	public final String[] getArgs() {
+		return args.clone();
+	}
+
+	/**
+	 * Determines the equality of two {@code ConditionInfo} objects.
+	 * 
+	 * This method checks that specified object has the same type and args as
+	 * this {@code ConditionInfo} object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code ConditionInfo} object.
+	 * @return {@code true} if {@code obj} is a {@code ConditionInfo}, and has
+	 *         the same type and args as this {@code ConditionInfo} object;
+	 *         {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof ConditionInfo)) {
+			return false;
+		}
+
+		ConditionInfo other = (ConditionInfo) obj;
+
+		if (!type.equals(other.type) || args.length != other.args.length)
+			return false;
+
+		for (int i = 0; i < args.length; i++) {
+			if (!args[i].equals(other.args[i]))
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 */
+
+	public int hashCode() {
+		int h = 31 * 17 + type.hashCode();
+		for (int i = 0; i < args.length; i++) {
+			h = 31 * h + args[i].hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * This escapes the quotes, backslashes, \n, and \r in the string using a
+	 * backslash and appends the newly escaped string to a StringBuffer.
+	 */
+	private static void escapeString(String str, StringBuffer output) {
+		int len = str.length();
+		for (int i = 0; i < len; i++) {
+			char c = str.charAt(i);
+			switch (c) {
+				case '"' :
+				case '\\' :
+					output.append('\\');
+					output.append(c);
+					break;
+				case '\r' :
+					output.append("\\r");
+					break;
+				case '\n' :
+					output.append("\\n");
+					break;
+				default :
+					output.append(c);
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Takes an encoded character array and decodes it into a new String.
+	 */
+	private static String unescapeString(char[] str, int begin, int end) {
+		StringBuffer output = new StringBuffer(end - begin);
+		for (int i = begin; i < end; i++) {
+			char c = str[i];
+			if (c == '\\') {
+				i++;
+				if (i < end) {
+					c = str[i];
+					switch (c) {
+						case '"' :
+						case '\\' :
+							break;
+						case 'r' :
+							c = '\r';
+							break;
+						case 'n' :
+							c = '\n';
+							break;
+						default :
+							c = '\\';
+							i--;
+							break;
+					}
+				}
+			}
+			output.append(c);
+		}
+
+		return output.toString();
+	}
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java
new file mode 100644
index 0000000..89db261
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionAdmin.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.security.AccessControlContext;
+import java.util.Enumeration;
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+/**
+ * Framework service to administer Conditional Permissions. Conditional
+ * Permissions can be added to, retrieved from, and removed from the framework.
+ * Conditional Permissions are conceptually managed in an ordered table called
+ * the Conditional Permission Table.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 5be9948e8181bdf55154f25af1462a9d84990d93 $
+ */
+public interface ConditionalPermissionAdmin {
+	/**
+	 * Create a new Conditional Permission Info in the Conditional Permission
+	 * Table.
+	 * <p>
+	 * The Conditional Permission Info will be given a unique, never reused
+	 * name. This entry will be added at the beginning of the Conditional
+	 * Permission Table with an access decision of
+	 * {@link ConditionalPermissionInfo#ALLOW ALLOW}.
+	 * <p>
+	 * Since this method changes the Conditional Permission Table any
+	 * {@link ConditionalPermissionUpdate}s that were created prior to calling
+	 * this method can no longer be committed.
+	 * 
+	 * @param conditions The conditions that need to be satisfied to enable the
+	 *        specified permissions. This argument can be {@code null} or an
+	 *        empty array indicating the specified permissions are not guarded
+	 *        by any conditions.
+	 * @param permissions The permissions that are enabled when the specified
+	 *        conditions, if any, are satisfied. This argument must not be
+	 *        {@code null} and must specify at least one permission.
+	 * @return The ConditionalPermissionInfo for the specified Conditions and
+	 *         Permissions.
+	 * @throws IllegalArgumentException If no permissions are specified.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}.
+	 * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+	 *             instead.
+	 */
+	ConditionalPermissionInfo addConditionalPermissionInfo(ConditionInfo[] conditions, PermissionInfo[] permissions);
+
+	/**
+	 * Set or create a Conditional Permission Info with a specified name in the
+	 * Conditional Permission Table.
+	 * <p>
+	 * If the specified name is {@code null}, a new Conditional Permission Info
+	 * must be created and will be given a unique, never reused name. If there
+	 * is currently no Conditional Permission Info with the specified name, a
+	 * new Conditional Permission Info must be created with the specified name.
+	 * Otherwise, the Conditional Permission Info with the specified name must
+	 * be updated with the specified Conditions and Permissions. If a new entry
+	 * was created in the Conditional Permission Table it will be added at the
+	 * beginning of the table with an access decision of
+	 * {@link ConditionalPermissionInfo#ALLOW ALLOW}.
+	 * <p>
+	 * Since this method changes the underlying permission table any
+	 * {@link ConditionalPermissionUpdate}s that were created prior to calling
+	 * this method can no longer be committed.
+	 * 
+	 * @param name The name of the Conditional Permission Info, or {@code null}.
+	 * @param conditions The conditions that need to be satisfied to enable the
+	 *        specified permissions. This argument can be {@code null} or an
+	 *        empty array indicating the specified permissions are not guarded
+	 *        by any conditions.
+	 * @param permissions The permissions that are enabled when the specified
+	 *        conditions, if any, are satisfied. This argument must not be
+	 *        {@code null} and must specify at least one permission.
+	 * @return The ConditionalPermissionInfo for the specified name, Conditions
+	 *         and Permissions.
+	 * @throws IllegalArgumentException If no permissions are specified.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}.
+	 * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+	 *             instead.
+	 */
+	ConditionalPermissionInfo setConditionalPermissionInfo(String name, ConditionInfo[] conditions, PermissionInfo[] permissions);
+
+	/**
+	 * Returns the Conditional Permission Infos from the Conditional Permission
+	 * Table.
+	 * <p>
+	 * The returned Enumeration will return elements in the order they are kept
+	 * in the Conditional Permission Table.
+	 * <p>
+	 * The Enumeration returned is based on a copy of the Conditional Permission
+	 * Table and therefore will not throw exceptions if the Conditional
+	 * Permission Table is changed during the course of reading elements from
+	 * the Enumeration.
+	 * 
+	 * @return An enumeration of the Conditional Permission Infos that are
+	 *         currently in the Conditional Permission Table.
+	 * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+	 *             instead.
+	 */
+	Enumeration<ConditionalPermissionInfo> getConditionalPermissionInfos();
+
+	/**
+	 * Return the Conditional Permission Info with the specified name.
+	 * 
+	 * @param name The name of the Conditional Permission Info to be returned.
+	 * @return The Conditional Permission Info with the specified name or
+	 *         {@code null} if no Conditional Permission Info with the specified
+	 *         name exists in the Conditional Permission Table.
+	 * @deprecated Since 1.1. Use {@link #newConditionalPermissionUpdate()}
+	 *             instead.
+	 */
+	ConditionalPermissionInfo getConditionalPermissionInfo(String name);
+
+	/**
+	 * Returns the Access Control Context that corresponds to the specified
+	 * signers.
+	 * 
+	 * The returned Access Control Context must act as if its protection domain
+	 * came from a bundle that has the following characteristics:
+	 * <ul>
+	 * <li>It is signed by all of the given signers</li>
+	 * <li>It has a bundle id of -1</li>
+	 * <li>Its location is the empty string</li>
+	 * <li>Its state is UNINSTALLED</li>
+	 * <li>It has no headers</li>
+	 * <li>It has the empty version (0.0.0)</li>
+	 * <li>Its last modified time=0</li>
+	 * <li>Many methods will throw {@code IllegalStateException} because the
+	 * state is UNINSTALLED</li>
+	 * <li>All other methods return a {@code null}</li>
+	 * </ul>
+	 * 
+	 * @param signers The signers for which to return an Access Control Context.
+	 * @return An {@code AccessControlContext} that has the Permissions
+	 *         associated with the signer.
+	 */
+	AccessControlContext getAccessControlContext(String[] signers);
+
+	/**
+	 * Creates a new update for the Conditional Permission Table. The update is
+	 * a working copy of the current Conditional Permission Table. If the
+	 * running Conditional Permission Table is modified before commit is called
+	 * on the returned update, then the call to commit on the returned update
+	 * will fail. That is, the commit method will return false and no change
+	 * will be made to the running Conditional Permission Table. There is no
+	 * requirement that commit is eventually called on the returned update.
+	 * 
+	 * @return A new update for the Conditional Permission Table.
+	 * @since 1.1
+	 */
+	ConditionalPermissionUpdate newConditionalPermissionUpdate();
+
+	/**
+	 * Creates a new ConditionalPermissionInfo with the specified fields
+	 * suitable for insertion into a {@link ConditionalPermissionUpdate}. The
+	 * {@code delete} method on {@code ConditionalPermissionInfo} objects
+	 * created with this method must throw UnsupportedOperationException.
+	 * 
+	 * @param name The name of the created {@code ConditionalPermissionInfo} or
+	 *        {@code null} to have a unique name generated when the returned
+	 *        {@code ConditionalPermissionInfo} is committed in an update to the
+	 *        Conditional Permission Table.
+	 * @param conditions The conditions that need to be satisfied to enable the
+	 *        specified permissions. This argument can be {@code null} or an
+	 *        empty array indicating the specified permissions are not guarded
+	 *        by any conditions.
+	 * @param permissions The permissions that are enabled when the specified
+	 *        conditions, if any, are satisfied. This argument must not be
+	 *        {@code null} and must specify at least one permission.
+	 * @param access Access decision. Must be one of the following values:
+	 *        <ul>
+	 *        <li>{@link ConditionalPermissionInfo#ALLOW allow}</li>
+	 *        <li>{@link ConditionalPermissionInfo#DENY deny}</li>
+	 *        </ul>
+	 *        The specified access decision value must be evaluated case
+	 *        insensitively.
+	 * @return A {@code ConditionalPermissionInfo} object suitable for insertion
+	 *         into a {@link ConditionalPermissionUpdate}.
+	 * @throws IllegalArgumentException If no permissions are specified or if
+	 *         the specified access decision is not a valid value.
+	 * @since 1.1
+	 */
+	ConditionalPermissionInfo newConditionalPermissionInfo(String name, ConditionInfo[] conditions, PermissionInfo[] permissions, String access);
+
+	/**
+	 * Creates a new {@code ConditionalPermissionInfo} from the specified
+	 * encoded {@code ConditionalPermissionInfo} string suitable for insertion
+	 * into a {@link ConditionalPermissionUpdate}. The {@code delete} method on
+	 * {@code ConditionalPermissionInfo} objects created with this method must
+	 * throw UnsupportedOperationException.
+	 * 
+	 * @param encodedConditionalPermissionInfo The encoded
+	 *        {@code ConditionalPermissionInfo}. White space in the encoded
+	 *        {@code ConditionalPermissionInfo} is ignored. The access decision
+	 *        value in the encoded {@code ConditionalPermissionInfo} must be
+	 *        evaluated case insensitively. If the encoded
+	 *        {@code ConditionalPermissionInfo} does not contain the optional
+	 *        name, {@code null} must be used for the name and a unique name
+	 *        will be generated when the returned
+	 *        {@code ConditionalPermissionInfo} is committed in an update to the
+	 *        Conditional Permission Table.
+	 * @return A {@code ConditionalPermissionInfo} object suitable for insertion
+	 *         into a {@link ConditionalPermissionUpdate}.
+	 * @throws IllegalArgumentException If the specified
+	 *         {@code encodedConditionalPermissionInfo} is not properly
+	 *         formatted.
+	 * @see ConditionalPermissionInfo#getEncoded()
+	 * @since 1.1
+	 */
+	ConditionalPermissionInfo newConditionalPermissionInfo(String encodedConditionalPermissionInfo);
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java
new file mode 100644
index 0000000..220f7ef
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionInfo.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import org.osgi.service.permissionadmin.PermissionInfo;
+
+/**
+ * A list of Permissions guarded by a list of conditions with an access
+ * decision. Instances of this interface are obtained from the Conditional
+ * Permission Admin service.
+ * 
+ * @Immutable
+ * @noimplement
+ * @version $Id: c4222b04d7ab4f8ccdb5def2bf5423c2e1d31f20 $
+ */
+public interface ConditionalPermissionInfo {
+	/**
+	 * This string is used to indicate that a row in the Conditional Permission
+	 * Table should return an access decision of "allow" if the
+	 * conditions are all satisfied and at least one of the permissions is
+	 * implied.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String	ALLOW	= "allow";
+
+	/**
+	 * This string is used to indicate that a row in the Conditional Permission
+	 * Table should return an access decision of "deny" if the
+	 * conditions are all satisfied and at least one of the permissions is
+	 * implied.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String	DENY	= "deny";
+
+	/**
+	 * Returns the Condition Infos for the Conditions that must be satisfied to
+	 * enable the Permissions.
+	 * 
+	 * @return The Condition Infos for the Conditions in this Conditional
+	 *         Permission Info.
+	 */
+	ConditionInfo[] getConditionInfos();
+
+	/**
+	 * Returns the Permission Infos for the Permissions in this Conditional
+	 * Permission Info.
+	 * 
+	 * @return The Permission Infos for the Permissions in this Conditional
+	 *         Permission Info.
+	 */
+	PermissionInfo[] getPermissionInfos();
+
+	/**
+	 * Removes this Conditional Permission Info from the Conditional Permission
+	 * Table.
+	 * <p>
+	 * Since this method changes the underlying permission table, any
+	 * {@link ConditionalPermissionUpdate}s that were created prior to calling
+	 * this method can no longer be committed.
+	 * 
+	 * @throws UnsupportedOperationException If this object was created by
+	 *         {@link ConditionalPermissionAdmin#newConditionalPermissionInfo(String)}
+	 *         or
+	 *         {@link ConditionalPermissionAdmin#newConditionalPermissionInfo(String, ConditionInfo[] , PermissionInfo[] , String)}
+	 *         or obtained from a {@link ConditionalPermissionUpdate}. This
+	 *         method only functions if this object was obtained from one of the
+	 *         {@link ConditionalPermissionAdmin} methods deprecated in version
+	 *         1.1.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}.
+	 * @deprecated Since 1.1. Use
+	 *             {@link ConditionalPermissionAdmin#newConditionalPermissionUpdate()}
+	 *             instead to manage the Conditional Permissions.
+	 */
+	void delete();
+
+	/**
+	 * Returns the name of this Conditional Permission Info.
+	 * 
+	 * @return The name of this Conditional Permission Info. This can be
+	 *         {@code null} if this Conditional Permission Info was created
+	 *         without a name.
+	 */
+	String getName();
+
+	/**
+	 * Returns the access decision for this Conditional Permission Info.
+	 * 
+	 * @return One of the following values:
+	 *         <ul>
+	 *         <li>{@link #ALLOW allow} - The access decision is
+	 *         "allow".</li>
+	 *         <li>{@link #DENY deny} - The access decision is "deny".
+	 *         </li>
+	 *         </ul>
+	 * @since 1.1
+	 */
+	String getAccessDecision();
+
+	/**
+	 * Returns the string encoding of this {@code ConditionalPermissionInfo} in
+	 * a form suitable for restoring this {@code ConditionalPermissionInfo}.
+	 * 
+	 * <p>
+	 * The encoded format is:
+	 * 
+	 * <pre>
+	 *   access {conditions permissions} name
+	 * </pre>
+	 * 
+	 * where <i>access</i> is the access decision, <i>conditions</i> is zero or
+	 * more {@link ConditionInfo#getEncoded() encoded conditions},
+	 * <i>permissions</i> is one or more {@link PermissionInfo#getEncoded()
+	 * encoded permissions} and <i>name</i> is the name of the
+	 * {@code ConditionalPermissionInfo}.
+	 * 
+	 * <p>
+	 * <i>name</i> is optional. If <i>name</i> is present in the encoded string,
+	 * it must quoted, beginning and ending with {@code "}. The <i>name</i>
+	 * value must be encoded for proper parsing. Specifically, the
+	 * {@code "}, {@code \}, carriage return, and line feed characters must
+	 * be escaped using {@code \"}, {@code \\}, {@code \r}, and {@code \n},
+	 * respectively.
+	 * 
+	 * <p>
+	 * The encoded string contains no leading or trailing whitespace characters.
+	 * A single space character is used between <i>access</i> and <code>{</code>
+	 * and between <code>}</code> and <i>name</i>, if <i>name</i> is present.
+	 * All encoded conditions and permissions are separated by a single space
+	 * character.
+	 * 
+	 * @return The string encoding of this {@code ConditionalPermissionInfo}.
+	 * @since 1.1
+	 */
+	String getEncoded();
+
+	/**
+	 * Returns the string representation of this
+	 * {@code ConditionalPermissionInfo}. The string is created by calling the
+	 * {@code getEncoded} method on this {@code ConditionalPermissionInfo}.
+	 * 
+	 * @return The string representation of this
+	 *         {@code ConditionalPermissionInfo}.
+	 * @since 1.1
+	 */
+	String toString();
+
+	/**
+	 * Determines the equality of two {@code ConditionalPermissionInfo} objects.
+	 * 
+	 * This method checks that specified object has the same access decision,
+	 * conditions, permissions and name as this
+	 * {@code ConditionalPermissionInfo} object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code ConditionalPermissionInfo} object.
+	 * @return {@code true} if {@code obj} is a
+	 *         {@code ConditionalPermissionInfo}, and has the same access
+	 *         decision, conditions, permissions and name as this
+	 *         {@code ConditionalPermissionInfo} object; {@code false}
+	 *         otherwise.
+	 * @since 1.1
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 * @since 1.1
+	 */
+	int hashCode();
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java
new file mode 100644
index 0000000..6d52c47
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/ConditionalPermissionUpdate.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.condpermadmin;
+
+import java.util.List;
+
+/**
+ * Update the Conditional Permission Table. There may be many update objects in
+ * the system at one time. If commit is called and the Conditional Permission
+ * Table has been modified since this update was created, then the call to
+ * commit will fail and this object should be discarded.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 7487aa7d2558f34c0115b924180ed17e6e13e22e $
+ * @since 1.1
+ */
+public interface ConditionalPermissionUpdate {
+	/**
+	 * This method returns the list of {@link ConditionalPermissionInfo}s for
+	 * this update. This list is originally based on the Conditional Permission
+	 * Table at the time this update was created. The list returned by this
+	 * method will be replace the Conditional Permission Table if commit is
+	 * called and is successful.
+	 * <p>
+	 * The {@link ConditionalPermissionInfo#delete() delete} method of the
+	 * ConditionalPermissionInfos in the list must throw
+	 * UnsupportedOperationException.
+	 * <p>
+	 * The list returned by this method is ordered and the most significant
+	 * table entry is the first entry in the list.
+	 * 
+	 * @return A {@code List} of the {@link ConditionalPermissionInfo}s which
+	 *         represent the Conditional Permissions maintained by this update.
+	 *         Modifications to this list will not affect the Conditional
+	 *         Permission Table until successfully committed. The list may be
+	 *         empty if the Conditional Permission Table was empty when this
+	 *         update was created.
+	 */
+	List<ConditionalPermissionInfo> getConditionalPermissionInfos();
+
+	/**
+	 * Commit this update. If no changes have been made to the Conditional
+	 * Permission Table since this update was created, then this method will
+	 * replace the Conditional Permission Table with this update's Conditional
+	 * Permissions. This method may only be successfully called once on this
+	 * object.
+	 * <p>
+	 * If any of the {@link ConditionalPermissionInfo}s in the update list has
+	 * {@code null} as a name it will be replaced with a new
+	 * {@link ConditionalPermissionInfo} object that has a generated name which
+	 * is unique within the list.
+	 * <p>
+	 * No two entries in this update's Conditional Permissions may have the same
+	 * name. Other consistency checks may also be performed. If this update's
+	 * Conditional Permissions are determined to be inconsistent in some way
+	 * then an {@code IllegalStateException} will be thrown.
+	 * <p>
+	 * This method returns {@code false} if the commit did not occur because the
+	 * Conditional Permission Table has been modified since the creation of this
+	 * update.
+	 * 
+	 * @return {@code true} if the commit was successful. {@code false} if the
+	 *         commit did not occur because the Conditional Permission Table has
+	 *         been modified since the creation of this update.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}.
+	 * @throws IllegalStateException If this update's Conditional Permissions
+	 *         are not valid or inconsistent. For example, this update has two
+	 *         Conditional Permissions in it with the same name.
+	 */
+	boolean commit();
+}
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/package-info.java b/osgi/framework/src/org/osgi/service/condpermadmin/package-info.java
new file mode 100644
index 0000000..783a07e
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Conditional Permission Admin Package Version 1.1.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.condpermadmin; version="[1.1,2.0)"}
+ * 
+ * @version $Id: 233676a532c6248ff670390f6a25ba6d8399f4ff $
+ */
+
+package org.osgi.service.condpermadmin;
+
diff --git a/osgi/framework/src/org/osgi/service/condpermadmin/packageinfo b/osgi/framework/src/org/osgi/service/condpermadmin/packageinfo
new file mode 100644
index 0000000..bb27c60
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/condpermadmin/packageinfo
@@ -0,0 +1 @@
+version 1.1.1
diff --git a/osgi/framework/src/org/osgi/service/packageadmin/ExportedPackage.java b/osgi/framework/src/org/osgi/service/packageadmin/ExportedPackage.java
new file mode 100644
index 0000000..4dd3a3a
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/packageadmin/ExportedPackage.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.packageadmin;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * An exported package.
+ * 
+ * Objects implementing this interface are created by the Package Admin service.
+ * 
+ * <p>
+ * The term <i>exported package</i> refers to a package that has been exported
+ * from a resolved bundle. This package may or may not be currently wired to
+ * other bundles.
+ * 
+ * <p>
+ * The information about an exported package provided by this object may change.
+ * An {@code ExportedPackage} object becomes stale if the package it
+ * references has been updated or removed as a result of calling
+ * {@code PackageAdmin.refreshPackages()}.
+ * 
+ * If this object becomes stale, its {@code getName()} and
+ * {@code getVersion()} methods continue to return their original values,
+ * {@code isRemovalPending()} returns {@code true}, and
+ * {@code getExportingBundle()} and {@code getImportingBundles()}
+ * return {@code null}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @deprecated The PackageAdmin service has been replaced by the
+ *             <code>org.osgi.framework.wiring</code> package.
+ * @version $Id: 22ce5e8e388107b04edba3aea2f3036b8026798d $
+ */
+public interface ExportedPackage {
+	/**
+	 * Returns the name of the package associated with this exported package.
+	 * 
+	 * @return The name of this exported package.
+	 */
+	public String getName();
+
+	/**
+	 * Returns the bundle exporting the package associated with this exported
+	 * package.
+	 * 
+	 * @return The exporting bundle, or {@code null} if this
+	 *         {@code ExportedPackage} object has become stale.
+	 */
+	public Bundle getExportingBundle();
+
+	/**
+	 * Returns the resolved bundles that are currently wired to this exported
+	 * package.
+	 * 
+	 * <p>
+	 * Bundles which require the exporting bundle associated with this exported
+	 * package are considered to be wired to this exported package are included
+	 * in the returned array. See {@link RequiredBundle#getRequiringBundles()}.
+	 * 
+	 * @return The array of resolved bundles currently wired to this exported
+	 *         package, or {@code null} if this
+	 *         {@code ExportedPackage} object has become stale. The array
+	 *         will be empty if no bundles are wired to this exported package.
+	 */
+	public Bundle[] getImportingBundles();
+
+	/**
+	 * Returns the version of this exported package.
+	 * 
+	 * @return The version of this exported package, or {@code null} if no
+	 *         version information is available.
+	 * @deprecated As of 1.2, replaced by {@link #getVersion()}.
+	 */
+	public String getSpecificationVersion();
+
+	/**
+	 * Returns the version of this exported package.
+	 * 
+	 * @return The version of this exported package, or
+	 *         {@link Version#emptyVersion} if no version information is
+	 *         available.
+	 * @since 1.2
+	 */
+	public Version getVersion();
+
+	/**
+	 * Returns {@code true} if the package associated with this
+	 * {@code ExportedPackage} object has been exported by a bundle that
+	 * has been updated or uninstalled.
+	 * 
+	 * @return {@code true} if the associated package is being exported
+	 *         by a bundle that has been updated or uninstalled, or if this
+	 *         {@code ExportedPackage} object has become stale;
+	 *         {@code false} otherwise.
+	 */
+	public boolean isRemovalPending();
+}
diff --git a/osgi/framework/src/org/osgi/service/packageadmin/PackageAdmin.java b/osgi/framework/src/org/osgi/service/packageadmin/PackageAdmin.java
new file mode 100644
index 0000000..2c57890
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/packageadmin/PackageAdmin.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.packageadmin;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Framework service which allows bundle programmers to inspect the package
+ * wiring state of bundles in the Framework as well as other functions related
+ * to the class loader network among bundles.
+ * 
+ * <p>
+ * If present, there will only be a single instance of this service registered
+ * with the Framework.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: a268c3bdc986080fa16bdb2f56ba1d3800d030dd $
+ * @deprecated This service has been replaced by the
+ *             <code>org.osgi.framework.wiring</code> package.
+ * @see org.osgi.service.packageadmin.ExportedPackage
+ * @see org.osgi.service.packageadmin.RequiredBundle
+ */
+public interface PackageAdmin {
+	/**
+	 * Gets the exported packages for the specified bundle.
+	 * 
+	 * @param bundle The bundle whose exported packages are to be returned, or
+	 *        {@code null} if all exported packages are to be returned. If
+	 *        the specified bundle is the system bundle (that is, the bundle
+	 *        with id zero), this method returns all the packages known to be
+	 *        exported by the system bundle. This will include the package
+	 *        specified by the {@code org.osgi.framework.system.packages}
+	 *        system property as well as any other package exported by the
+	 *        framework implementation.
+	 * 
+	 * @return An array of exported packages, or {@code null} if the
+	 *         specified bundle has no exported packages.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
+	 *         not created by the same framework instance that registered this
+	 *         {@code PackageAdmin} service.
+	 */
+	public ExportedPackage[] getExportedPackages(Bundle bundle);
+
+	/**
+	 * Gets the exported packages for the specified package name.
+	 * 
+	 * @param name The name of the exported packages to be returned.
+	 * 
+	 * @return An array of the exported packages, or {@code null} if no
+	 *         exported packages with the specified name exists.
+	 * @since 1.2
+	 */
+	public ExportedPackage[] getExportedPackages(String name);
+
+	/**
+	 * Gets the exported package for the specified package name.
+	 * 
+	 * <p>
+	 * If there are multiple exported packages with specified name, the exported
+	 * package with the highest version will be returned.
+	 * 
+	 * @param name The name of the exported package to be returned.
+	 * 
+	 * @return The exported package, or {@code null} if no exported
+	 *         package with the specified name exists.
+	 * @see #getExportedPackages(String)
+	 */
+	public ExportedPackage getExportedPackage(String name);
+
+	/**
+	 * Forces the update (replacement) or removal of packages exported by the
+	 * specified bundles.
+	 * 
+	 * <p>
+	 * If no bundles are specified, this method will update or remove any
+	 * packages exported by any bundles that were previously updated or
+	 * uninstalled since the last call to this method. The technique by which
+	 * this is accomplished may vary among different Framework implementations.
+	 * One permissible implementation is to stop and restart the Framework.
+	 * 
+	 * <p>
+	 * This method returns to the caller immediately and then performs the
+	 * following steps on a separate thread:
+	 * 
+	 * <ol>
+	 * <li>Compute a graph of bundles starting with the specified bundles. If no
+	 * bundles are specified, compute a graph of bundles starting with bundle
+	 * updated or uninstalled since the last call to this method. Add to the
+	 * graph any bundle that is wired to a package that is currently exported by
+	 * a bundle in the graph. The graph is fully constructed when there is no
+	 * bundle outside the graph that is wired to a bundle in the graph. The
+	 * graph may contain {@code UNINSTALLED} bundles that are currently
+	 * still exporting packages.
+	 * 
+	 * <li>Each bundle in the graph that is in the {@code ACTIVE} state
+	 * will be stopped as described in the {@code Bundle.stop} method.
+	 * 
+	 * <li>Each bundle in the graph that is in the {@code RESOLVED} state
+	 * is unresolved and thus moved to the {@code INSTALLED} state. The
+	 * effect of this step is that bundles in the graph are no longer
+	 * {@code RESOLVED}.
+	 * 
+	 * <li>Each bundle in the graph that is in the {@code UNINSTALLED}
+	 * state is removed from the graph and is now completely removed from the
+	 * Framework.
+	 * 
+	 * <li>Each bundle in the graph that was in the {@code ACTIVE} state
+	 * prior to Step 2 is started as described in the {@code Bundle.start}
+	 * method, causing all bundles required for the restart to be resolved. It
+	 * is possible that, as a result of the previous steps, packages that were
+	 * previously exported no longer are. Therefore, some bundles may be
+	 * unresolvable until another bundle offering a compatible package for
+	 * export has been installed in the Framework.
+	 * <li>A framework event of type
+	 * {@code FrameworkEvent.PACKAGES_REFRESHED} is fired.
+	 * </ol>
+	 * 
+	 * <p>
+	 * For any exceptions that are thrown during any of these steps, a
+	 * {@code FrameworkEvent} of type {@code ERROR} is fired
+	 * containing the exception. The source bundle for these events should be
+	 * the specific bundle to which the exception is related. If no specific
+	 * bundle can be associated with the exception then the System Bundle must
+	 * be used as the source bundle for the event.
+	 * 
+	 * @param bundles The bundles whose exported packages are to be updated or
+	 *        removed, or {@code null} for all bundles updated or
+	 *        uninstalled since the last call to this method.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+	 *         runtime environment supports permissions.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s
+	 *         were not created by the same framework instance that registered
+	 *         this {@code PackageAdmin} service.
+	 */
+	public void refreshPackages(Bundle[] bundles);
+
+	/**
+	 * Resolve the specified bundles. The Framework must attempt to resolve the
+	 * specified bundles that are unresolved. Additional bundles that are not
+	 * included in the specified bundles may be resolved as a result of calling
+	 * this method. A permissible implementation of this method is to attempt to
+	 * resolve all unresolved bundles installed in the framework.
+	 * 
+	 * <p>
+	 * If {@code null} is specified then the Framework will attempt to
+	 * resolve all unresolved bundles. This method must not cause any bundle to
+	 * be refreshed, stopped, or started. This method will not return until the
+	 * operation has completed.
+	 * 
+	 * @param bundles The bundles to resolve or {@code null} to resolve all
+	 *        unresolved bundles installed in the Framework.
+	 * @return {@code true} if all specified bundles are resolved;
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+	 *         runtime environment supports permissions.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s
+	 *         were not created by the same framework instance that registered
+	 *         this {@code PackageAdmin} service.
+	 * @since 1.2
+	 */
+	public boolean resolveBundles(Bundle[] bundles);
+
+	/**
+	 * Returns an array of required bundles having the specified symbolic name.
+	 * 
+	 * <p>
+	 * If {@code null} is specified, then all required bundles will be
+	 * returned.
+	 * 
+	 * @param symbolicName The bundle symbolic name or {@code null} for
+	 *        all required bundles.
+	 * @return An array of required bundles or {@code null} if no
+	 *         required bundles exist for the specified symbolic name.
+	 * @since 1.2
+	 */
+	public RequiredBundle[] getRequiredBundles(String symbolicName);
+
+	/**
+	 * Returns the bundles with the specified symbolic name whose bundle version
+	 * is within the specified version range. If no bundles are installed that
+	 * have the specified symbolic name, then {@code null} is returned.
+	 * If a version range is specified, then only the bundles that have the
+	 * specified symbolic name and whose bundle versions belong to the specified
+	 * version range are returned. The returned bundles are ordered by version
+	 * in descending version order so that the first element of the array
+	 * contains the bundle with the highest version.
+	 * 
+	 * @see org.osgi.framework.Constants#BUNDLE_VERSION_ATTRIBUTE
+	 * @param symbolicName The symbolic name of the desired bundles.
+	 * @param versionRange The version range of the desired bundles, or
+	 *        {@code null} if all versions are desired.
+	 * @return An array of bundles with the specified name belonging to the
+	 *         specified version range ordered in descending version order, or
+	 *         {@code null} if no bundles are found.
+	 * @since 1.2
+	 */
+	public Bundle[] getBundles(String symbolicName, String versionRange);
+
+	/**
+	 * Returns an array of attached fragment bundles for the specified bundle.
+	 * If the specified bundle is a fragment then {@code null} is returned.
+	 * If no fragments are attached to the specified bundle then
+	 * {@code null} is returned.
+	 * <p>
+	 * This method does not attempt to resolve the specified bundle. If the
+	 * specified bundle is not resolved then {@code null} is returned.
+	 * 
+	 * @param bundle The bundle whose attached fragment bundles are to be
+	 *        returned.
+	 * @return An array of fragment bundles or {@code null} if the bundle
+	 *         does not have any attached fragment bundles or the bundle is not
+	 *         resolved.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
+	 *         not created by the same framework instance that registered this
+	 *         {@code PackageAdmin} service.
+	 * @since 1.2
+	 */
+	public Bundle[] getFragments(Bundle bundle);
+
+	/**
+	 * Returns the host bundles to which the specified fragment bundle is
+	 * attached.
+	 * 
+	 * @param bundle The fragment bundle whose host bundles are to be returned.
+	 * @return An array containing the host bundles to which the specified
+	 *         fragment is attached or {@code null} if the specified bundle
+	 *         is not a fragment or is not attached to any host bundles.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
+	 *         not created by the same framework instance that registered this
+	 *         {@code PackageAdmin} service.
+	 * @since 1.2
+	 */
+	public Bundle[] getHosts(Bundle bundle);
+
+	/**
+	 * Returns the bundle from which the specified class is loaded. The class
+	 * loader of the returned bundle must have been used to load the specified
+	 * class. If the class was not loaded by a bundle class loader then
+	 * {@code null} is returned.
+	 * 
+	 * @param clazz The class object from which to locate the bundle.
+	 * @return The bundle from which the specified class is loaded or
+	 *         {@code null} if the class was not loaded by a bundle class
+	 *         loader created by the same framework instance that registered
+	 *         this {@code PackageAdmin} service.
+	 * @since 1.2
+	 */
+	public Bundle getBundle(Class clazz);
+
+	/**
+	 * Bundle type indicating the bundle is a fragment bundle.
+	 * 
+	 * <p>
+	 * The value of {@code BUNDLE_TYPE_FRAGMENT} is 0x00000001.
+	 * 
+	 * @since 1.2
+	 */
+	public static final int	BUNDLE_TYPE_FRAGMENT	= 0x00000001;
+
+	/**
+	 * Returns the special type of the specified bundle. The bundle type values
+	 * are:
+	 * <ul>
+	 * <li>{@link #BUNDLE_TYPE_FRAGMENT}
+	 * </ul>
+	 * 
+	 * A bundle may be more than one type at a time. A type code is used to
+	 * identify the bundle type for future extendability.
+	 * 
+	 * <p>
+	 * If a bundle is not one or more of the defined types then 0x00000000 is
+	 * returned.
+	 * 
+	 * @param bundle The bundle for which to return the special type.
+	 * @return The special type of the bundle.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
+	 *         not created by the same framework instance that registered this
+	 *         {@code PackageAdmin} service.
+	 * @since 1.2
+	 */
+	public int getBundleType(Bundle bundle);
+}
diff --git a/osgi/framework/src/org/osgi/service/packageadmin/RequiredBundle.java b/osgi/framework/src/org/osgi/service/packageadmin/RequiredBundle.java
new file mode 100644
index 0000000..34c0b08
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/packageadmin/RequiredBundle.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.packageadmin;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * A required bundle.
+ * 
+ * Objects implementing this interface are created by the Package Admin service.
+ * 
+ * <p>
+ * The term <i>required bundle</i> refers to a resolved bundle that has a bundle
+ * symbolic name and is not a fragment. That is, a bundle that may be required
+ * by other bundles. This bundle may or may not be currently required by other
+ * bundles.
+ * 
+ * <p>
+ * The information about a required bundle provided by this object may change. A
+ * {@code RequiredBundle} object becomes stale if an exported package of
+ * the bundle it references has been updated or removed as a result of calling
+ * {@code PackageAdmin.refreshPackages()}).
+ * 
+ * If this object becomes stale, its {@code getSymbolicName()} and
+ * {@code getVersion()} methods continue to return their original values,
+ * {@code isRemovalPending()} returns true, and {@code getBundle()}
+ * and {@code getRequiringBundles()} return {@code null}.
+ * 
+ * @since 1.2
+ * @ThreadSafe
+ * @noimplement
+ * @deprecated The PackageAdmin service has been replaced by the
+ *             <code>org.osgi.framework.wiring</code> package.
+ * @version $Id: 1606b0422cae6769b7eedc2d565df61841da1e22 $
+ */
+public interface RequiredBundle {
+	/**
+	 * Returns the symbolic name of this required bundle.
+	 * 
+	 * @return The symbolic name of this required bundle.
+	 */
+	public String getSymbolicName();
+
+	/**
+	 * Returns the bundle associated with this required bundle.
+	 * 
+	 * @return The bundle, or {@code null} if this
+	 *         {@code RequiredBundle} object has become stale.
+	 */
+	public Bundle getBundle();
+
+	/**
+	 * Returns the bundles that currently require this required bundle.
+	 * 
+	 * <p>
+	 * If this required bundle is required and then re-exported by another
+	 * bundle then all the requiring bundles of the re-exporting bundle are
+	 * included in the returned array.
+	 * 
+	 * @return An array of bundles currently requiring this required bundle, or
+	 *         {@code null} if this {@code RequiredBundle} object
+	 *         has become stale. The array will be empty if no bundles require
+	 *         this required package.
+	 */
+	public Bundle[] getRequiringBundles();
+
+	/**
+	 * Returns the version of this required bundle.
+	 * 
+	 * @return The version of this required bundle, or
+	 *         {@link Version#emptyVersion} if no version information is
+	 *         available.
+	 */
+	public Version getVersion();
+
+	/**
+	 * Returns {@code true} if the bundle associated with this
+	 * {@code RequiredBundle} object has been updated or uninstalled.
+	 * 
+	 * @return {@code true} if the required bundle has been updated or
+	 *         uninstalled, or if the {@code RequiredBundle} object has
+	 *         become stale; {@code false} otherwise.
+	 */
+	public boolean isRemovalPending();
+}
diff --git a/osgi/framework/src/org/osgi/service/packageadmin/package-info.java b/osgi/framework/src/org/osgi/service/packageadmin/package-info.java
new file mode 100644
index 0000000..9d9804d
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/packageadmin/package-info.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package Admin Package Version 1.2.
+ * 
+ * <p>
+ * <b>Deprecated.</b>
+ * <i>This package is deprecated and has been replaced by the
+ * {@code org.osgi.framework.wiring} package.</i>
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.packageadmin; version="[1.2,2.0)"}
+ * 
+ * @version $Id: b1c7db22b9c84e48d3c6c711f0ed976e825053c9 $
+ */
+
+package org.osgi.service.packageadmin;
diff --git a/osgi/framework/src/org/osgi/service/packageadmin/packageinfo b/osgi/framework/src/org/osgi/service/packageadmin/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/packageadmin/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/osgi/framework/src/org/osgi/service/permissionadmin/PermissionAdmin.java b/osgi/framework/src/org/osgi/service/permissionadmin/PermissionAdmin.java
new file mode 100644
index 0000000..e27f74f
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/permissionadmin/PermissionAdmin.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.permissionadmin;
+
+/**
+ * The Permission Admin service allows management agents to manage the
+ * permissions of bundles. There is at most one Permission Admin service present
+ * in the OSGi environment.
+ * <p>
+ * Access to the Permission Admin service is protected by corresponding
+ * {@code ServicePermission}. In addition {@code AdminPermission} is required to
+ * actually set permissions.
+ * 
+ * <p>
+ * Bundle permissions are managed using a permission table. A bundle's location
+ * serves as the key into this permission table. The value of a table entry is
+ * the set of permissions (of type {@code PermissionInfo}) granted to the bundle
+ * named by the given location. A bundle may have an entry in the permission
+ * table prior to being installed in the Framework.
+ * 
+ * <p>
+ * The permissions specified in {@code setDefaultPermissions} are used as the
+ * default permissions which are granted to all bundles that do not have an
+ * entry in the permission table.
+ * 
+ * <p>
+ * Any changes to a bundle's permissions in the permission table will take
+ * effect no later than when bundle's {@code java.security.ProtectionDomain} is
+ * next involved in a permission check, and will be made persistent.
+ * 
+ * <p>
+ * Only permission classes on the system classpath or from an exported package
+ * are considered during a permission check. Additionally, only permission
+ * classes that are subclasses of {@code java.security.Permission} and define a
+ * 2-argument constructor that takes a <i>name </i> string and an <i>actions
+ * </i> string can be used.
+ * <p>
+ * Permissions implicitly granted by the Framework (for example, a bundle's
+ * permission to access its persistent storage area) cannot be changed, and are
+ * not reflected in the permissions returned by {@code getPermissions} and
+ * {@code getDefaultPermissions}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 846b7ff8d3e9f03d2a6ee75d2dcc9ab52d959754 $
+ */
+public interface PermissionAdmin {
+	/**
+	 * Gets the permissions assigned to the bundle with the specified location.
+	 * 
+	 * @param location The location of the bundle whose permissions are to be
+	 *        returned.
+	 * 
+	 * @return The permissions assigned to the bundle with the specified
+	 *         location, or {@code null} if that bundle has not been assigned
+	 *         any permissions.
+	 */
+	PermissionInfo[] getPermissions(String location);
+
+	/**
+	 * Assigns the specified permissions to the bundle with the specified
+	 * location.
+	 * 
+	 * @param location The location of the bundle that will be assigned the
+	 *        permissions.
+	 * @param permissions The permissions to be assigned, or {@code null} if the
+	 *        specified location is to be removed from the permission table.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}.
+	 */
+	void setPermissions(String location, PermissionInfo[] permissions);
+
+	/**
+	 * Returns the bundle locations that have permissions assigned to them, that
+	 * is, bundle locations for which an entry exists in the permission table.
+	 * 
+	 * @return The locations of bundles that have been assigned any permissions,
+	 *         or {@code null} if the permission table is empty.
+	 */
+	String[] getLocations();
+
+	/**
+	 * Gets the default permissions.
+	 * 
+	 * <p>
+	 * These are the permissions granted to any bundle that does not have
+	 * permissions assigned to its location.
+	 * 
+	 * @return The default permissions, or {@code null} if no default
+	 *         permissions are set.
+	 */
+	PermissionInfo[] getDefaultPermissions();
+
+	/**
+	 * Sets the default permissions.
+	 * 
+	 * <p>
+	 * These are the permissions granted to any bundle that does not have
+	 * permissions assigned to its location.
+	 * 
+	 * @param permissions The default permissions, or {@code null} if the
+	 *        default permissions are to be removed from the permission table.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AllPermission}.
+	 */
+	void setDefaultPermissions(PermissionInfo[] permissions);
+}
diff --git a/osgi/framework/src/org/osgi/service/permissionadmin/PermissionInfo.java b/osgi/framework/src/org/osgi/service/permissionadmin/PermissionInfo.java
new file mode 100644
index 0000000..371dede
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/permissionadmin/PermissionInfo.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.permissionadmin;
+
+/**
+ * Permission representation used by the Permission Admin service.
+ * 
+ * <p>
+ * This class encapsulates three pieces of information: a Permission <i>type
+ * </i> (class name), which must be a subclass of
+ * {@code java.security.Permission}, and the <i>name</i> and <i>actions</i>
+ * arguments passed to its constructor.
+ * 
+ * <p>
+ * In order for a permission represented by a {@code PermissionInfo} to be
+ * instantiated and considered during a permission check, its Permission class
+ * must be available from the system classpath or an exported package. This
+ * means that the instantiation of a permission represented by a
+ * {@code PermissionInfo} may be delayed until the package containing its
+ * Permission class has been exported by a bundle.
+ * 
+ * @Immutable
+ * @version $Id: d904a01a7ff64b702e8d92071d063ff6927bef14 $
+ */
+public class PermissionInfo {
+	private final String	type;
+	private final String	name;
+	private final String	actions;
+
+	/**
+	 * Constructs a {@code PermissionInfo} from the specified type, name, and
+	 * actions.
+	 * 
+	 * @param type The fully qualified class name of the permission represented
+	 *        by this {@code PermissionInfo}. The class must be a subclass of
+	 *        {@code java.security.Permission} and must define a 2-argument
+	 *        constructor that takes a <i>name</i> string and an <i>actions</i>
+	 *        string.
+	 * 
+	 * @param name The permission name that will be passed as the first argument
+	 *        to the constructor of the {@code Permission} class identified by
+	 *        {@code type}.
+	 * 
+	 * @param actions The permission actions that will be passed as the second
+	 *        argument to the constructor of the {@code Permission} class
+	 *        identified by {@code type}.
+	 * 
+	 * @throws NullPointerException If {@code type} is {@code null}.
+	 * @throws IllegalArgumentException If {@code action} is not {@code null}
+	 *         and {@code name} is {@code null}.
+	 */
+	public PermissionInfo(String type, String name, String actions) {
+		this.type = type;
+		this.name = name;
+		this.actions = actions;
+		if (type == null) {
+			throw new NullPointerException("type is null");
+		}
+		if ((name == null) && (actions != null)) {
+			throw new IllegalArgumentException("name missing");
+		}
+	}
+
+	/**
+	 * Constructs a {@code PermissionInfo} object from the specified encoded
+	 * {@code PermissionInfo} string. White space in the encoded
+	 * {@code PermissionInfo} string is ignored.
+	 * 
+	 * 
+	 * @param encodedPermission The encoded {@code PermissionInfo}.
+	 * @see #getEncoded()
+	 * @throws IllegalArgumentException If the specified
+	 *         {@code encodedPermission} is not properly formatted.
+	 */
+	public PermissionInfo(String encodedPermission) {
+		if (encodedPermission == null) {
+			throw new NullPointerException("missing encoded permission");
+		}
+		if (encodedPermission.length() == 0) {
+			throw new IllegalArgumentException("empty encoded permission");
+		}
+		String parsedType = null;
+		String parsedName = null;
+		String parsedActions = null;
+		try {
+			char[] encoded = encodedPermission.toCharArray();
+			int length = encoded.length;
+			int pos = 0;
+
+			/* skip whitespace */
+			while (Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+
+			/* the first character must be '(' */
+			if (encoded[pos] != '(') {
+				throw new IllegalArgumentException("expecting open parenthesis");
+			}
+			pos++;
+
+			/* skip whitespace */
+			while (Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+
+			/* type is not quoted or encoded */
+			int begin = pos;
+			while (!Character.isWhitespace(encoded[pos]) && (encoded[pos] != ')')) {
+				pos++;
+			}
+			if (pos == begin || encoded[begin] == '"') {
+				throw new IllegalArgumentException("expecting type");
+			}
+			parsedType = new String(encoded, begin, pos - begin);
+
+			/* skip whitespace */
+			while (Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+
+			/* type may be followed by name which is quoted and encoded */
+			if (encoded[pos] == '"') {
+				pos++;
+				begin = pos;
+				while (encoded[pos] != '"') {
+					if (encoded[pos] == '\\') {
+						pos++;
+					}
+					pos++;
+				}
+				parsedName = unescapeString(encoded, begin, pos);
+				pos++;
+
+				if (Character.isWhitespace(encoded[pos])) {
+					/* skip whitespace */
+					while (Character.isWhitespace(encoded[pos])) {
+						pos++;
+					}
+
+					/*
+					 * name may be followed by actions which is quoted and
+					 * encoded
+					 */
+					if (encoded[pos] == '"') {
+						pos++;
+						begin = pos;
+						while (encoded[pos] != '"') {
+							if (encoded[pos] == '\\') {
+								pos++;
+							}
+							pos++;
+						}
+						parsedActions = unescapeString(encoded, begin, pos);
+						pos++;
+
+						/* skip whitespace */
+						while (Character.isWhitespace(encoded[pos])) {
+							pos++;
+						}
+					}
+				}
+			}
+
+			/* the final character must be ')' */
+			char c = encoded[pos];
+			pos++;
+			while ((pos < length) && Character.isWhitespace(encoded[pos])) {
+				pos++;
+			}
+			if ((c != ')') || (pos != length)) {
+				throw new IllegalArgumentException("expecting close parenthesis");
+			}
+		} catch (ArrayIndexOutOfBoundsException e) {
+			throw new IllegalArgumentException("parsing terminated abruptly");
+		}
+
+		type = parsedType;
+		name = parsedName;
+		actions = parsedActions;
+	}
+
+	/**
+	 * Returns the string encoding of this {@code PermissionInfo} in a form
+	 * suitable for restoring this {@code PermissionInfo}.
+	 * 
+	 * <p>
+	 * The encoded format is:
+	 * 
+	 * <pre>
+	 * (type)
+	 * </pre>
+	 * 
+	 * or
+	 * 
+	 * <pre>
+	 * (type "name")
+	 * </pre>
+	 * 
+	 * or
+	 * 
+	 * <pre>
+	 * (type "name" "actions")
+	 * </pre>
+	 * 
+	 * where <i>name</i> and <i>actions</i> are strings that must be encoded for
+	 * proper parsing. Specifically, the {@code "},{@code \}, carriage
+	 * return, and line feed characters must be escaped using {@code \"},
+	 * {@code \\},{@code \r}, and {@code \n}, respectively.
+	 * 
+	 * <p>
+	 * The encoded string contains no leading or trailing whitespace characters.
+	 * A single space character is used between <i>type</i> and
+	 * "<i>name</i>" and between "<i>name</i>" and
+	 * "<i>actions</i>".
+	 * 
+	 * @return The string encoding of this {@code PermissionInfo}.
+	 */
+	public final String getEncoded() {
+		StringBuffer output = new StringBuffer(8 + type.length() + ((((name == null) ? 0 : name.length()) + ((actions == null) ? 0 : actions.length())) << 1));
+		output.append('(');
+		output.append(type);
+		if (name != null) {
+			output.append(" \"");
+			escapeString(name, output);
+			if (actions != null) {
+				output.append("\" \"");
+				escapeString(actions, output);
+			}
+			output.append('\"');
+		}
+		output.append(')');
+		return output.toString();
+	}
+
+	/**
+	 * Returns the string representation of this {@code PermissionInfo}. The
+	 * string is created by calling the {@code getEncoded} method on this
+	 * {@code PermissionInfo}.
+	 * 
+	 * @return The string representation of this {@code PermissionInfo}.
+	 */
+	public String toString() {
+		return getEncoded();
+	}
+
+	/**
+	 * Returns the fully qualified class name of the permission represented by
+	 * this {@code PermissionInfo}.
+	 * 
+	 * @return The fully qualified class name of the permission represented by
+	 *         this {@code PermissionInfo}.
+	 */
+	public final String getType() {
+		return type;
+	}
+
+	/**
+	 * Returns the name of the permission represented by this
+	 * {@code PermissionInfo}.
+	 * 
+	 * @return The name of the permission represented by this
+	 *         {@code PermissionInfo}, or {@code null} if the permission does
+	 *         not have a name.
+	 */
+	public final String getName() {
+		return name;
+	}
+
+	/**
+	 * Returns the actions of the permission represented by this
+	 * {@code PermissionInfo}.
+	 * 
+	 * @return The actions of the permission represented by this
+	 *         {@code PermissionInfo}, or {@code null} if the permission does
+	 *         not have any actions associated with it.
+	 */
+	public final String getActions() {
+		return actions;
+	}
+
+	/**
+	 * Determines the equality of two {@code PermissionInfo} objects.
+	 * 
+	 * This method checks that specified object has the same type, name and
+	 * actions as this {@code PermissionInfo} object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code PermissionInfo} object.
+	 * @return {@code true} if {@code obj} is a {@code PermissionInfo}, and has
+	 *         the same type, name and actions as this {@code PermissionInfo}
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+		if (!(obj instanceof PermissionInfo)) {
+			return false;
+		}
+		PermissionInfo other = (PermissionInfo) obj;
+		if (!type.equals(other.type) || ((name == null) ^ (other.name == null)) || ((actions == null) ^ (other.actions == null))) {
+			return false;
+		}
+		if (name != null) {
+			if (actions != null) {
+				return name.equals(other.name) && actions.equals(other.actions);
+			} else {
+				return name.equals(other.name);
+			}
+		} else {
+			return true;
+		}
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + type.hashCode();
+		if (name != null) {
+			h = 31 * h + name.hashCode();
+			if (actions != null) {
+				h = 31 * h + actions.hashCode();
+			}
+		}
+		return h;
+	}
+
+	/**
+	 * This escapes the quotes, backslashes, \n, and \r in the string using a
+	 * backslash and appends the newly escaped string to a StringBuffer.
+	 */
+	private static void escapeString(String str, StringBuffer output) {
+		int len = str.length();
+		for (int i = 0; i < len; i++) {
+			char c = str.charAt(i);
+			switch (c) {
+				case '"' :
+				case '\\' :
+					output.append('\\');
+					output.append(c);
+					break;
+				case '\r' :
+					output.append("\\r");
+					break;
+				case '\n' :
+					output.append("\\n");
+					break;
+				default :
+					output.append(c);
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Takes an encoded character array and decodes it into a new String.
+	 */
+	private static String unescapeString(char[] str, int begin, int end) {
+		StringBuffer output = new StringBuffer(end - begin);
+		for (int i = begin; i < end; i++) {
+			char c = str[i];
+			if (c == '\\') {
+				i++;
+				if (i < end) {
+					c = str[i];
+					switch (c) {
+						case '"' :
+						case '\\' :
+							break;
+						case 'r' :
+							c = '\r';
+							break;
+						case 'n' :
+							c = '\n';
+							break;
+						default :
+							c = '\\';
+							i--;
+							break;
+					}
+				}
+			}
+			output.append(c);
+		}
+
+		return output.toString();
+	}
+}
diff --git a/osgi/framework/src/org/osgi/service/permissionadmin/package-info.java b/osgi/framework/src/org/osgi/service/permissionadmin/package-info.java
new file mode 100644
index 0000000..7a06853
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/permissionadmin/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Permission Admin Package Version 1.2.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.permissionadmin; version="[1.2,2.0)"}
+ * 
+ * @version $Id: 735e3020913649e9606caf0ad3b6bfee690f2b8a $
+ */
+
+package org.osgi.service.permissionadmin;
+
diff --git a/osgi/framework/src/org/osgi/service/permissionadmin/packageinfo b/osgi/framework/src/org/osgi/service/permissionadmin/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/permissionadmin/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/osgi/framework/src/org/osgi/service/startlevel/StartLevel.java b/osgi/framework/src/org/osgi/service/startlevel/StartLevel.java
new file mode 100644
index 0000000..b4b8816
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/startlevel/StartLevel.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.startlevel;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * The StartLevel service allows management agents to manage a start level
+ * assigned to each bundle and the active start level of the Framework. There is
+ * at most one StartLevel service present in the OSGi environment.
+ * 
+ * <p>
+ * A start level is defined to be a state of execution in which the Framework
+ * exists. StartLevel values are defined as unsigned integers with 0 (zero)
+ * being the state where the Framework is not launched. Progressively higher
+ * integral values represent progressively higher start levels. e.g. 2 is a
+ * higher start level than 1.
+ * <p>
+ * Access to the StartLevel service is protected by corresponding
+ * {@code ServicePermission}. In addition {@code AdminPermission}
+ * is required to actually modify start level information.
+ * <p>
+ * Start Level support in the Framework includes the ability to control the
+ * beginning start level of the Framework, to modify the active start level of
+ * the Framework and to assign a specific start level to a bundle. How the
+ * beginning start level of a Framework is specified is implementation
+ * dependent. It may be a command line argument when invoking the Framework
+ * implementation.
+ * <p>
+ * When the Framework is first started it must be at start level zero. In this
+ * state, no bundles are running. This is the initial state of the Framework
+ * before it is launched.
+ * 
+ * When the Framework is launched, the Framework will enter start level one and
+ * all bundles which are assigned to start level one and whose autostart setting
+ * indicates the bundle should be started are started as described in the
+ * {@code Bundle.start} method. The Framework will continue to increase
+ * the start level, starting bundles at each start level, until the Framework
+ * has reached a beginning start level. At this point the Framework has
+ * completed starting bundles and will then fire a Framework event of type
+ * {@code FrameworkEvent.STARTED} to announce it has completed its
+ * launch.
+ * 
+ * <p>
+ * Within a start level, bundles may be started in an order defined by the
+ * Framework implementation. This may be something like ascending
+ * {@code Bundle.getBundleId} order or an order based upon dependencies
+ * between bundles. A similar but reversed order may be used when stopping
+ * bundles within a start level.
+ * 
+ * <p>
+ * The StartLevel service can be used by management bundles to alter the active
+ * start level of the framework.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: ec0295bdf246c0258261374b3ac0e4aef11f7315 $
+ * @deprecated This service has been replaced by the
+ *             <code>org.osgi.framework.startlevel</code> package.
+ */
+public interface StartLevel {
+	/**
+	 * Return the active start level value of the Framework.
+	 * 
+	 * If the Framework is in the process of changing the start level this
+	 * method must return the active start level if this differs from the
+	 * requested start level.
+	 * 
+	 * @return The active start level value of the Framework.
+	 */
+	public int getStartLevel();
+
+	/**
+	 * Modify the active start level of the Framework.
+	 * 
+	 * <p>
+	 * The Framework will move to the requested start level. This method will
+	 * return immediately to the caller and the start level change will occur
+	 * asynchronously on another thread.
+	 * 
+	 * <p>
+	 * If the specified start level is higher than the active start level, the
+	 * Framework will continue to increase the start level until the Framework
+	 * has reached the specified start level.
+	 * 
+	 * At each intermediate start level value on the way to and including the
+	 * target start level, the Framework must:
+	 * <ol>
+	 * <li>Change the active start level to the intermediate start level value.
+	 * <li>Start bundles at the intermediate start level whose autostart
+	 * setting indicate they must be started. They are started as described in
+	 * the {@link Bundle#start(int)} method using the
+	 * {@link Bundle#START_TRANSIENT} option. The
+	 * {@link Bundle#START_ACTIVATION_POLICY} option must also be used if
+	 * {@link #isBundleActivationPolicyUsed(Bundle)} returns {@code true}
+	 * for the bundle.
+	 * </ol>
+	 * When this process completes after the specified start level is reached,
+	 * the Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved
+	 * to the specified start level.
+	 * 
+	 * <p>
+	 * If the specified start level is lower than the active start level, the
+	 * Framework will continue to decrease the start level until the Framework
+	 * has reached the specified start level.
+	 * 
+	 * At each intermediate start level value on the way to and including the
+	 * specified start level, the framework must:
+	 * <ol>
+	 * <li>Stop bundles at the intermediate start level as described in the
+	 * {@link Bundle#stop(int)} method using the {@link Bundle#STOP_TRANSIENT}
+	 * option.
+	 * <li>Change the active start level to the intermediate start level value.
+	 * </ol>
+	 * When this process completes after the specified start level is reached,
+	 * the Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved
+	 * to the specified start level.
+	 * 
+	 * <p>
+	 * If the specified start level is equal to the active start level, then no
+	 * bundles are started or stopped, however, the Framework must fire a
+	 * Framework event of type {@code FrameworkEvent.STARTLEVEL_CHANGED}
+	 * to announce it has finished moving to the specified start level. This
+	 * event may arrive before this method return.
+	 * 
+	 * @param startlevel The requested start level for the Framework.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the
+	 *         Java runtime environment supports permissions.
+	 */
+	public void setStartLevel(int startlevel);
+
+	/**
+	 * Return the assigned start level value for the specified Bundle.
+	 * 
+	 * @param bundle The target bundle.
+	 * @return The start level value of the specified Bundle.
+	 * @throws java.lang.IllegalArgumentException If the specified bundle has
+	 *         been uninstalled or if the specified bundle was not created by
+	 *         the same framework instance that registered this
+	 *         {@code StartLevel} service.
+	 */
+	public int getBundleStartLevel(Bundle bundle);
+
+	/**
+	 * Assign a start level value to the specified Bundle.
+	 * 
+	 * <p>
+	 * The specified bundle will be assigned the specified start level. The
+	 * start level value assigned to the bundle will be persistently recorded by
+	 * the Framework.
+	 * <p>
+	 * If the new start level for the bundle is lower than or equal to the
+	 * active start level of the Framework and the bundle's autostart setting
+	 * indicates the bundle must be started, the Framework will start the
+	 * specified bundle as described in the {@link Bundle#start(int)} method
+	 * using the {@link Bundle#START_TRANSIENT} option. The
+	 * {@link Bundle#START_ACTIVATION_POLICY} option must also be used if
+	 * {@link #isBundleActivationPolicyUsed(Bundle)} returns {@code true}
+	 * for the bundle. The actual starting of this bundle must occur
+	 * asynchronously.
+	 * <p>
+	 * If the new start level for the bundle is higher than the active start
+	 * level of the Framework, the Framework will stop the specified bundle as
+	 * described in the {@link Bundle#stop(int)} method using the
+	 * {@link Bundle#STOP_TRANSIENT} option. The actual stopping of this bundle
+	 * must occur asynchronously.
+	 * 
+	 * @param bundle The target bundle.
+	 * @param startlevel The new start level for the specified Bundle.
+	 * @throws IllegalArgumentException If the specified bundle has been
+	 *         uninstalled, or if the specified start level is less than or
+	 *         equal to zero, or if the specified bundle is the system bundle,
+	 *         or if the specified bundle was not created by the same framework
+	 *         instance that registered this {@code StartLevel} service.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,EXECUTE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	public void setBundleStartLevel(Bundle bundle, int startlevel);
+
+	/**
+	 * Return the initial start level value that is assigned to a Bundle when it
+	 * is first installed.
+	 * 
+	 * @return The initial start level value for Bundles.
+	 * @see #setInitialBundleStartLevel(int)
+	 */
+	public int getInitialBundleStartLevel();
+
+	/**
+	 * Set the initial start level value that is assigned to a Bundle when it is
+	 * first installed.
+	 * 
+	 * <p>
+	 * The initial bundle start level will be set to the specified start level.
+	 * The initial bundle start level value will be persistently recorded by the
+	 * Framework.
+	 * 
+	 * <p>
+	 * When a Bundle is installed via {@code BundleContext.installBundle},
+	 * it is assigned the initial bundle start level value.
+	 * 
+	 * <p>
+	 * The default initial bundle start level value is 1 unless this method has
+	 * been called to assign a different initial bundle start level value.
+	 * 
+	 * <p>
+	 * This method does not change the start level values of installed bundles.
+	 * 
+	 * @param startlevel The initial start level for newly installed bundles.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the
+	 *         Java runtime environment supports permissions.
+	 */
+	public void setInitialBundleStartLevel(int startlevel);
+
+	/**
+	 * Returns whether the specified bundle's autostart setting indicates the
+	 * bundle must be started.
+	 * <p>
+	 * The autostart setting of a bundle indicates whether the bundle is to be
+	 * started when its start level is reached.
+	 * 
+	 * @param bundle The bundle whose autostart setting is to be examined.
+	 * @return {@code true} if the autostart setting of the bundle
+	 *         indicates the bundle is to be started. {@code false}
+	 *         otherwise.
+	 * @throws java.lang.IllegalArgumentException If the specified bundle has
+	 *         been uninstalled or if the specified bundle was not created by
+	 *         the same framework instance that registered this
+	 *         {@code StartLevel} service.
+	 * @see Bundle#START_TRANSIENT
+	 */
+	public boolean isBundlePersistentlyStarted(Bundle bundle);
+
+	/**
+	 * Returns whether the specified bundle's autostart setting indicates that
+	 * the activation policy declared in the bundle's manifest must be used.
+	 * <p>
+	 * The autostart setting of a bundle indicates whether the bundle's declared
+	 * activation policy is to be used when the bundle is started.
+	 * 
+	 * @param bundle The bundle whose autostart setting is to be examined.
+	 * @return {@code true} if the bundle's autostart setting indicates the
+	 *         activation policy declared in the manifest must be used.
+	 *         {@code false} if the bundle must be eagerly activated.
+	 * @throws java.lang.IllegalArgumentException If the specified bundle has
+	 *         been uninstalled or if the specified bundle was not created by
+	 *         the same framework instance that registered this
+	 *         {@code StartLevel} service.
+	 * @since 1.1
+	 * @see Bundle#START_ACTIVATION_POLICY
+	 */
+	public boolean isBundleActivationPolicyUsed(Bundle bundle);
+}
diff --git a/osgi/framework/src/org/osgi/service/startlevel/package-info.java b/osgi/framework/src/org/osgi/service/startlevel/package-info.java
new file mode 100644
index 0000000..7e4a908
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/startlevel/package-info.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Start Level Package Version 1.1.
+ * 
+ * <p>
+ * <b>Deprecated.</b>
+ * <i>This package is deprecated and has been replaced by the
+ * {@code org.osgi.framework.startlevel} package.</i>
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.startlevel; version="[1.1,2.0)"}
+ * 
+ * @version $Id: 6e311e6e404688d5f5f88cde403ca2066de7c20b $
+ */
+
+package org.osgi.service.startlevel;
diff --git a/osgi/framework/src/org/osgi/service/startlevel/packageinfo b/osgi/framework/src/org/osgi/service/startlevel/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/startlevel/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/osgi/framework/src/org/osgi/service/url/AbstractURLStreamHandlerService.java b/osgi/framework/src/org/osgi/service/url/AbstractURLStreamHandlerService.java
new file mode 100644
index 0000000..679583c
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/url/AbstractURLStreamHandlerService.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.url;
+
+import java.net.*;
+
+/**
+ * Abstract implementation of the {@code URLStreamHandlerService} interface. All
+ * the methods simply invoke the corresponding methods on
+ * {@code java.net.URLStreamHandler} except for {@code parseURL} and
+ * {@code setURL}, which use the {@code URLStreamHandlerSetter} parameter.
+ * Subclasses of this abstract class should not need to override the
+ * {@code setURL} and {@code parseURL(URLStreamHandlerSetter,...)} methods.
+ * 
+ * @ThreadSafe
+ * @version $Id: b86572a4f13b7bb4a343ac4d6b6fb3487e01bd31 $
+ */
+public abstract class AbstractURLStreamHandlerService extends URLStreamHandler implements URLStreamHandlerService {
+	/**
+	 * @see "java.net.URLStreamHandler.openConnection"
+	 */
+	public abstract URLConnection openConnection(URL u) throws java.io.IOException;
+
+	/**
+	 * The {@code URLStreamHandlerSetter} object passed to the parseURL method.
+	 */
+	protected volatile URLStreamHandlerSetter	realHandler;
+
+	/**
+	 * Parse a URL using the {@code URLStreamHandlerSetter} object. This method
+	 * sets the {@code realHandler} field with the specified
+	 * {@code URLStreamHandlerSetter} object and then calls
+	 * {@code parseURL(URL,String,int,int)}.
+	 * 
+	 * @param realHandler The object on which the {@code setURL} method must be
+	 *        invoked for the specified URL.
+	 * @see "java.net.URLStreamHandler.parseURL"
+	 */
+	public void parseURL(URLStreamHandlerSetter realHandler, URL u, String spec, int start, int limit) {
+		this.realHandler = realHandler;
+		parseURL(u, spec, start, limit);
+	}
+
+	/**
+	 * This method calls {@code super.toExternalForm}.
+	 * 
+	 * @see "java.net.URLStreamHandler.toExternalForm"
+	 */
+	public String toExternalForm(URL u) {
+		return super.toExternalForm(u);
+	}
+
+	/**
+	 * This method calls {@code super.equals(URL,URL)}.
+	 * 
+	 * @see "java.net.URLStreamHandler.equals(URL,URL)"
+	 */
+	public boolean equals(URL u1, URL u2) {
+		return super.equals(u1, u2);
+	}
+
+	/**
+	 * This method calls {@code super.getDefaultPort}.
+	 * 
+	 * @see "java.net.URLStreamHandler.getDefaultPort"
+	 */
+	public int getDefaultPort() {
+		return super.getDefaultPort();
+	}
+
+	/**
+	 * This method calls {@code super.getHostAddress}.
+	 * 
+	 * @see "java.net.URLStreamHandler.getHostAddress"
+	 */
+	public InetAddress getHostAddress(URL u) {
+		return super.getHostAddress(u);
+	}
+
+	/**
+	 * This method calls {@code super.hashCode(URL)}.
+	 * 
+	 * @see "java.net.URLStreamHandler.hashCode(URL)"
+	 */
+	public int hashCode(URL u) {
+		return super.hashCode(u);
+	}
+
+	/**
+	 * This method calls {@code super.hostsEqual}.
+	 * 
+	 * @see "java.net.URLStreamHandler.hostsEqual"
+	 */
+	public boolean hostsEqual(URL u1, URL u2) {
+		return super.hostsEqual(u1, u2);
+	}
+
+	/**
+	 * This method calls {@code super.sameFile}.
+	 * 
+	 * @see "java.net.URLStreamHandler.sameFile"
+	 */
+	public boolean sameFile(URL u1, URL u2) {
+		return super.sameFile(u1, u2);
+	}
+
+	/**
+	 * This method calls
+	 * {@code realHandler.setURL(URL,String,String,int,String,String)}.
+	 * 
+	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
+	 * @deprecated This method is only for compatibility with handlers written
+	 *             for JDK 1.1.
+	 */
+	protected void setURL(URL u, String proto, String host, int port, String file, String ref) {
+		realHandler.setURL(u, proto, host, port, file, ref);
+	}
+
+	/**
+	 * This method calls
+	 * {@code realHandler.setURL(URL,String,String,int,String,String,String,String)}
+	 * .
+	 * 
+	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
+	 */
+	protected void setURL(URL u, String proto, String host, int port, String auth, String user, String path, String query, String ref) {
+		realHandler.setURL(u, proto, host, port, auth, user, path, query, ref);
+	}
+}
diff --git a/osgi/framework/src/org/osgi/service/url/URLConstants.java b/osgi/framework/src/org/osgi/service/url/URLConstants.java
new file mode 100644
index 0000000..493f352
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/url/URLConstants.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.url;
+
+/**
+ * Defines standard names for property keys associated with
+ * {@link URLStreamHandlerService} and {@code java.net.ContentHandler} services.
+ * 
+ * <p>
+ * The values associated with these keys are of type {@code java.lang.String[]}
+ * or {@code java.lang.String}, unless otherwise indicated.
+ * 
+ * @noimplement
+ * @version $Id: ac2b9670972d6e41d989c51067219ff7be459831 $
+ */
+public interface URLConstants {
+	/**
+	 * Service property naming the protocols serviced by a
+	 * URLStreamHandlerService. The property's value is a protocol name or an
+	 * array of protocol names.
+	 */
+	public static final String	URL_HANDLER_PROTOCOL	= "url.handler.protocol";
+	/**
+	 * Service property naming the MIME types serviced by a
+	 * java.net.ContentHandler. The property's value is a MIME type or an array
+	 * of MIME types.
+	 */
+	public static final String	URL_CONTENT_MIMETYPE	= "url.content.mimetype";
+}
diff --git a/osgi/framework/src/org/osgi/service/url/URLStreamHandlerService.java b/osgi/framework/src/org/osgi/service/url/URLStreamHandlerService.java
new file mode 100644
index 0000000..e6dd098
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/url/URLStreamHandlerService.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.url;
+
+import java.net.*;
+
+/**
+ * Service interface with public versions of the protected
+ * {@code java.net.URLStreamHandler} methods.
+ * <p>
+ * The important differences between this interface and the
+ * {@code URLStreamHandler} class are that the {@code setURL} method is absent
+ * and the {@code parseURL} method takes a {@link URLStreamHandlerSetter} object
+ * as the first argument. Classes implementing this interface must call the
+ * {@code setURL} method on the {@code URLStreamHandlerSetter} object received
+ * in the {@code parseURL} method instead of {@code URLStreamHandler.setURL} to
+ * avoid a {@code SecurityException}.
+ * 
+ * @see AbstractURLStreamHandlerService
+ * 
+ * @ThreadSafe
+ * @version $Id: 4a453f61b9acdc6449df389b2a0538d0ccb33ed2 $
+ */
+public interface URLStreamHandlerService {
+	/**
+	 * @see "java.net.URLStreamHandler.openConnection"
+	 */
+	public URLConnection openConnection(URL u) throws java.io.IOException;
+
+	/**
+	 * Parse a URL. This method is called by the {@code URLStreamHandler} proxy,
+	 * instead of {@code java.net.URLStreamHandler.parseURL}, passing a
+	 * {@code URLStreamHandlerSetter} object.
+	 * 
+	 * @param realHandler The object on which {@code setURL} must be invoked for
+	 *        this URL.
+	 * @see "java.net.URLStreamHandler.parseURL"
+	 */
+	public void parseURL(URLStreamHandlerSetter realHandler, URL u, String spec, int start, int limit);
+
+	/**
+	 * @see "java.net.URLStreamHandler.toExternalForm"
+	 */
+	public String toExternalForm(URL u);
+
+	/**
+	 * @see "java.net.URLStreamHandler.equals(URL, URL)"
+	 */
+	public boolean equals(URL u1, URL u2);
+
+	/**
+	 * @see "java.net.URLStreamHandler.getDefaultPort"
+	 */
+	public int getDefaultPort();
+
+	/**
+	 * @see "java.net.URLStreamHandler.getHostAddress"
+	 */
+	public InetAddress getHostAddress(URL u);
+
+	/**
+	 * @see "java.net.URLStreamHandler.hashCode(URL)"
+	 */
+	public int hashCode(URL u);
+
+	/**
+	 * @see "java.net.URLStreamHandler.hostsEqual"
+	 */
+	public boolean hostsEqual(URL u1, URL u2);
+
+	/**
+	 * @see "java.net.URLStreamHandler.sameFile"
+	 */
+	public boolean sameFile(URL u1, URL u2);
+}
diff --git a/osgi/framework/src/org/osgi/service/url/URLStreamHandlerSetter.java b/osgi/framework/src/org/osgi/service/url/URLStreamHandlerSetter.java
new file mode 100644
index 0000000..90feae6
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/url/URLStreamHandlerSetter.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.url;
+
+import java.net.URL;
+
+/**
+ * Interface used by {@code URLStreamHandlerService} objects to call the
+ * {@code setURL} method on the proxy {@code URLStreamHandler} object.
+ * 
+ * <p>
+ * Objects of this type are passed to the
+ * {@link URLStreamHandlerService#parseURL(URLStreamHandlerSetter, URL, String, int, int)}
+ * method. Invoking the {@code setURL} method on the
+ * {@code URLStreamHandlerSetter} object will invoke the {@code setURL} method
+ * on the proxy {@code URLStreamHandler} object that is actually registered with
+ * {@code java.net.URL} for the protocol.
+ * 
+ * @ThreadSafe
+ * @version $Id: 90f25e3961fea2150cfd31117a2237304f1518f9 $
+ */
+public interface URLStreamHandlerSetter {
+	/**
+	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
+	 * 
+	 * @deprecated This method is only for compatibility with handlers written
+	 *             for JDK 1.1.
+	 */
+	public void setURL(URL u, String protocol, String host, int port, String file, String ref);
+
+	/**
+	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
+	 */
+	public void setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref);
+}
diff --git a/osgi/framework/src/org/osgi/service/url/package-info.java b/osgi/framework/src/org/osgi/service/url/package-info.java
new file mode 100644
index 0000000..765d5a9
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/url/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * URL Stream and Content Handlers Package Version 1.0.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.url; version="[1.0,2.0)"}
+ * 
+ * @version $Id: 4dd6b685a79b76ce57708f69487533abe4828943 $
+ */
+
+package org.osgi.service.url;
+
diff --git a/osgi/framework/src/org/osgi/service/url/packageinfo b/osgi/framework/src/org/osgi/service/url/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/osgi/framework/src/org/osgi/service/url/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/osgi/framework/src/org/osgi/util/tracker/AbstractTracked.java b/osgi/framework/src/org/osgi/util/tracker/AbstractTracked.java
new file mode 100644
index 0000000..f3ddddc
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/AbstractTracked.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract class to track items. If a Tracker is reused (closed then reopened),
+ * then a new AbstractTracked object is used. This class acts a map of tracked
+ * item -> customized object. Subclasses of this class will act as the listener
+ * object for the tracker. This class is used to synchronize access to the
+ * tracked items. This is not a public class. It is only for use by the
+ * implementation of the Tracker class.
+ * 
+ * @param <S> The tracked item. It is the key.
+ * @param <T> The value mapped to the tracked item.
+ * @param <R> The reason the tracked item is being tracked or untracked.
+ * @ThreadSafe
+ * @version $Id: 16340086b98d308c2d12f13bcd87fc6467a5a367 $
+ * @since 1.4
+ */
+abstract class AbstractTracked<S, T, R> {
+	/* set this to true to compile in debug messages */
+	static final boolean		DEBUG	= false;
+
+	/**
+	 * Map of tracked items to customized objects.
+	 * 
+	 * @GuardedBy this
+	 */
+	private final Map<S, T>		tracked;
+
+	/**
+	 * Modification count. This field is initialized to zero and incremented by
+	 * modified.
+	 * 
+	 * @GuardedBy this
+	 */
+	private int					trackingCount;
+
+	/**
+	 * List of items in the process of being added. This is used to deal with
+	 * nesting of events. Since events may be synchronously delivered, events
+	 * can be nested. For example, when processing the adding of a service and
+	 * the customizer causes the service to be unregistered, notification to the
+	 * nested call to untrack that the service was unregistered can be made to
+	 * the track method.
+	 * 
+	 * Since the ArrayList implementation is not synchronized, all access to
+	 * this list must be protected by the same synchronized object for
+	 * thread-safety.
+	 * 
+	 * @GuardedBy this
+	 */
+	private final List<S>		adding;
+
+	/**
+	 * true if the tracked object is closed.
+	 * 
+	 * This field is volatile because it is set by one thread and read by
+	 * another.
+	 */
+	volatile boolean			closed;
+
+	/**
+	 * Initial list of items for the tracker. This is used to correctly process
+	 * the initial items which could be modified before they are tracked. This
+	 * is necessary since the initial set of tracked items are not "announced"
+	 * by events and therefore the event which makes the item untracked could be
+	 * delivered before we track the item.
+	 * 
+	 * An item must not be in both the initial and adding lists at the same
+	 * time. An item must be moved from the initial list to the adding list
+	 * "atomically" before we begin tracking it.
+	 * 
+	 * Since the LinkedList implementation is not synchronized, all access to
+	 * this list must be protected by the same synchronized object for
+	 * thread-safety.
+	 * 
+	 * @GuardedBy this
+	 */
+	private final LinkedList<S>	initial;
+
+	/**
+	 * AbstractTracked constructor.
+	 */
+	AbstractTracked() {
+		tracked = new HashMap<S, T>();
+		trackingCount = 0;
+		adding = new ArrayList<S>(6);
+		initial = new LinkedList<S>();
+		closed = false;
+	}
+
+	/**
+	 * Set initial list of items into tracker before events begin to be
+	 * received.
+	 * 
+	 * This method must be called from Tracker's open method while synchronized
+	 * on this object in the same synchronized block as the add listener call.
+	 * 
+	 * @param list The initial list of items to be tracked. {@code null} entries
+	 *        in the list are ignored.
+	 * @GuardedBy this
+	 */
+	void setInitial(S[] list) {
+		if (list == null) {
+			return;
+		}
+		for (S item : list) {
+			if (item == null) {
+				continue;
+			}
+			if (DEBUG) {
+				System.out.println("AbstractTracked.setInitial: " + item); //$NON-NLS-1$
+			}
+			initial.add(item);
+		}
+	}
+
+	/**
+	 * Track the initial list of items. This is called after events can begin to
+	 * be received.
+	 * 
+	 * This method must be called from Tracker's open method while not
+	 * synchronized on this object after the add listener call.
+	 * 
+	 */
+	void trackInitial() {
+		while (true) {
+			S item;
+			synchronized (this) {
+				if (closed || (initial.size() == 0)) {
+					/*
+					 * if there are no more initial items
+					 */
+					return; /* we are done */
+				}
+				/*
+				 * move the first item from the initial list to the adding list
+				 * within this synchronized block.
+				 */
+				item = initial.removeFirst();
+				if (tracked.get(item) != null) {
+					/* if we are already tracking this item */
+					if (DEBUG) {
+						System.out.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
+					}
+					continue; /* skip this item */
+				}
+				if (adding.contains(item)) {
+					/*
+					 * if this item is already in the process of being added.
+					 */
+					if (DEBUG) {
+						System.out.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
+					}
+					continue; /* skip this item */
+				}
+				adding.add(item);
+			}
+			if (DEBUG) {
+				System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
+			}
+			trackAdding(item, null); /*
+									 * Begin tracking it. We call trackAdding
+									 * since we have already put the item in the
+									 * adding list.
+									 */
+		}
+	}
+
+	/**
+	 * Called by the owning Tracker object when it is closed.
+	 */
+	void close() {
+		closed = true;
+	}
+
+	/**
+	 * Begin to track an item.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 */
+	void track(final S item, final R related) {
+		final T object;
+		synchronized (this) {
+			if (closed) {
+				return;
+			}
+			object = tracked.get(item);
+			if (object == null) { /* we are not tracking the item */
+				if (adding.contains(item)) {
+					/* if this item is already in the process of being added. */
+					if (DEBUG) {
+						System.out.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
+					}
+					return;
+				}
+				adding.add(item); /* mark this item is being added */
+			} else { /* we are currently tracking this item */
+				if (DEBUG) {
+					System.out.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
+				}
+				modified(); /* increment modification count */
+			}
+		}
+
+		if (object == null) { /* we are not tracking the item */
+			trackAdding(item, related);
+		} else {
+			/* Call customizer outside of synchronized region */
+			customizerModified(item, related, object);
+			/*
+			 * If the customizer throws an unchecked exception, it is safe to
+			 * let it propagate
+			 */
+		}
+	}
+
+	/**
+	 * Common logic to add an item to the tracker used by track and
+	 * trackInitial. The specified item must have been placed in the adding list
+	 * before calling this method.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 */
+	private void trackAdding(final S item, final R related) {
+		if (DEBUG) {
+			System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
+		}
+		T object = null;
+		boolean becameUntracked = false;
+		/* Call customizer outside of synchronized region */
+		try {
+			object = customizerAdding(item, related);
+			/*
+			 * If the customizer throws an unchecked exception, it will
+			 * propagate after the finally
+			 */
+		} finally {
+			synchronized (this) {
+				if (adding.remove(item) && !closed) {
+					/*
+					 * if the item was not untracked during the customizer
+					 * callback
+					 */
+					if (object != null) {
+						tracked.put(item, object);
+						modified(); /* increment modification count */
+						notifyAll(); /* notify any waiters */
+					}
+				} else {
+					becameUntracked = true;
+				}
+			}
+		}
+		/*
+		 * The item became untracked during the customizer callback.
+		 */
+		if (becameUntracked && (object != null)) {
+			if (DEBUG) {
+				System.out.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
+			}
+			/* Call customizer outside of synchronized region */
+			customizerRemoved(item, related, object);
+			/*
+			 * If the customizer throws an unchecked exception, it is safe to
+			 * let it propagate
+			 */
+		}
+	}
+
+	/**
+	 * Discontinue tracking the item.
+	 * 
+	 * @param item Item to be untracked.
+	 * @param related Action related object.
+	 */
+	void untrack(final S item, final R related) {
+		final T object;
+		synchronized (this) {
+			if (initial.remove(item)) { /*
+										 * if this item is already in the list
+										 * of initial references to process
+										 */
+				if (DEBUG) {
+					System.out.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
+				}
+				return; /*
+						 * we have removed it from the list and it will not be
+						 * processed
+						 */
+			}
+
+			if (adding.remove(item)) { /*
+										 * if the item is in the process of
+										 * being added
+										 */
+				if (DEBUG) {
+					System.out.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
+				}
+				return; /*
+						 * in case the item is untracked while in the process of
+						 * adding
+						 */
+			}
+			object = tracked.remove(item); /*
+											 * must remove from tracker before
+											 * calling customizer callback
+											 */
+			if (object == null) { /* are we actually tracking the item */
+				return;
+			}
+			modified(); /* increment modification count */
+		}
+		if (DEBUG) {
+			System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
+		}
+		/* Call customizer outside of synchronized region */
+		customizerRemoved(item, related, object);
+		/*
+		 * If the customizer throws an unchecked exception, it is safe to let it
+		 * propagate
+		 */
+	}
+
+	/**
+	 * Returns the number of tracked items.
+	 * 
+	 * @return The number of tracked items.
+	 * 
+	 * @GuardedBy this
+	 */
+	int size() {
+		return tracked.size();
+	}
+
+	/**
+	 * Returns if the tracker is empty.
+	 * 
+	 * @return Whether the tracker is empty.
+	 * 
+	 * @GuardedBy this
+	 * @since 1.5
+	 */
+	boolean isEmpty() {
+		return tracked.isEmpty();
+	}
+
+	/**
+	 * Return the customized object for the specified item
+	 * 
+	 * @param item The item to lookup in the map
+	 * @return The customized object for the specified item.
+	 * 
+	 * @GuardedBy this
+	 */
+	T getCustomizedObject(final S item) {
+		return tracked.get(item);
+	}
+
+	/**
+	 * Copy the tracked items into an array.
+	 * 
+	 * @param list An array to contain the tracked items.
+	 * @return The specified list if it is large enough to hold the tracked
+	 *         items or a new array large enough to hold the tracked items.
+	 * @GuardedBy this
+	 */
+	S[] copyKeys(final S[] list) {
+		return tracked.keySet().toArray(list);
+	}
+
+	/**
+	 * Increment the modification count. If this method is overridden, the
+	 * overriding method MUST call this method to increment the tracking count.
+	 * 
+	 * @GuardedBy this
+	 */
+	void modified() {
+		trackingCount++;
+	}
+
+	/**
+	 * Returns the tracking count for this {@code ServiceTracker} object.
+	 * 
+	 * The tracking count is initialized to 0 when this object is opened. Every
+	 * time an item is added, modified or removed from this object the tracking
+	 * count is incremented.
+	 * 
+	 * @GuardedBy this
+	 * @return The tracking count for this object.
+	 */
+	int getTrackingCount() {
+		return trackingCount;
+	}
+
+	/**
+	 * Copy the tracked items and associated values into the specified map.
+	 * 
+	 * @param <M> Type of {@code Map} to hold the tracked items and associated
+	 *        values.
+	 * @param map The map into which to copy the tracked items and associated
+	 *        values. This map must not be a user provided map so that user code
+	 *        is not executed while synchronized on this.
+	 * @return The specified map.
+	 * @GuardedBy this
+	 * @since 1.5
+	 */
+	<M extends Map<? super S, ? super T>> M copyEntries(final M map) {
+		map.putAll(tracked);
+		return map;
+	}
+
+	/**
+	 * Call the specific customizer adding method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 * @return Customized object for the tracked item or {@code null} if the
+	 *         item is not to be tracked.
+	 */
+	abstract T customizerAdding(final S item, final R related);
+
+	/**
+	 * Call the specific customizer modified method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Tracked item.
+	 * @param related Action related object.
+	 * @param object Customized object for the tracked item.
+	 */
+	abstract void customizerModified(final S item, final R related, final T object);
+
+	/**
+	 * Call the specific customizer removed method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Tracked item.
+	 * @param related Action related object.
+	 * @param object Customized object for the tracked item.
+	 */
+	abstract void customizerRemoved(final S item, final R related, final T object);
+}
diff --git a/osgi/framework/src/org/osgi/util/tracker/BundleTracker.java b/osgi/framework/src/org/osgi/util/tracker/BundleTracker.java
new file mode 100644
index 0000000..7e1bb53
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/BundleTracker.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * The {@code BundleTracker} class simplifies tracking bundles much like the
+ * {@code ServiceTracker} simplifies tracking services.
+ * <p>
+ * A {@code BundleTracker} is constructed with state criteria and a
+ * {@code BundleTrackerCustomizer} object. A {@code BundleTracker} can use the
+ * {@code BundleTrackerCustomizer} to select which bundles are tracked and to
+ * create a customized object to be tracked with the bundle. The
+ * {@code BundleTracker} can then be opened to begin tracking all bundles whose
+ * state matches the specified state criteria.
+ * <p>
+ * The {@code getBundles} method can be called to get the {@code Bundle} objects
+ * of the bundles being tracked. The {@code getObject} method can be called to
+ * get the customized object for a tracked bundle.
+ * <p>
+ * The {@code BundleTracker} class is thread-safe. It does not call a
+ * {@code BundleTrackerCustomizer} while holding any locks.
+ * {@code BundleTrackerCustomizer} implementations must also be thread-safe.
+ * 
+ * @param <T> The type of the tracked object.
+ * @ThreadSafe
+ * @version $Id: f21db4fe54284d4810bd9b5fa2528957804e3a21 $
+ * @since 1.4
+ */
+public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
+	/* set this to true to compile in debug messages */
+	static final boolean				DEBUG	= false;
+
+	/**
+	 * The Bundle Context used by this {@code BundleTracker}.
+	 */
+	protected final BundleContext		context;
+
+	/**
+	 * The {@code BundleTrackerCustomizer} object for this tracker.
+	 */
+	final BundleTrackerCustomizer<T>	customizer;
+
+	/**
+	 * Tracked bundles: {@code Bundle} object -> customized Object and
+	 * {@code BundleListener} object
+	 */
+	private volatile Tracked			tracked;
+
+	/**
+	 * Accessor method for the current Tracked object. This method is only
+	 * intended to be used by the unsynchronized methods which do not modify the
+	 * tracked field.
+	 * 
+	 * @return The current Tracked object.
+	 */
+	private Tracked tracked() {
+		return tracked;
+	}
+
+	/**
+	 * State mask for bundles being tracked. This field contains the ORed values
+	 * of the bundle states being tracked.
+	 */
+	final int	mask;
+
+	/**
+	 * Create a {@code BundleTracker} for bundles whose state is present in the
+	 * specified state mask.
+	 * 
+	 * <p>
+	 * Bundles whose state is present on the specified state mask will be
+	 * tracked by this {@code BundleTracker}.
+	 * 
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param stateMask The bit mask of the {@code OR}ing of the bundle states
+	 *        to be tracked.
+	 * @param customizer The customizer object to call when bundles are added,
+	 *        modified, or removed in this {@code BundleTracker}. If customizer
+	 *        is {@code null}, then this {@code BundleTracker} will be used as
+	 *        the {@code BundleTrackerCustomizer} and this {@code BundleTracker}
+	 *        will call the {@code BundleTrackerCustomizer} methods on itself.
+	 * @see Bundle#getState()
+	 */
+	public BundleTracker(BundleContext context, int stateMask, BundleTrackerCustomizer<T> customizer) {
+		this.context = context;
+		this.mask = stateMask;
+		this.customizer = (customizer == null) ? this : customizer;
+	}
+
+	/**
+	 * Open this {@code BundleTracker} and begin tracking bundles.
+	 * 
+	 * <p>
+	 * Bundle which match the state criteria specified when this
+	 * {@code BundleTracker} was created are now tracked by this
+	 * {@code BundleTracker}.
+	 * 
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *         which this {@code BundleTracker} was created is no longer valid.
+	 * @throws java.lang.SecurityException If the caller and this class do not
+	 *         have the appropriate
+	 *         {@code AdminPermission[context bundle,LISTENER]}, and the Java
+	 *         Runtime Environment supports permissions.
+	 */
+	public void open() {
+		final Tracked t;
+		synchronized (this) {
+			if (tracked != null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("BundleTracker.open"); //$NON-NLS-1$
+			}
+			t = new Tracked();
+			synchronized (t) {
+				context.addBundleListener(t);
+				Bundle[] bundles = context.getBundles();
+				if (bundles != null) {
+					int length = bundles.length;
+					for (int i = 0; i < length; i++) {
+						int state = bundles[i].getState();
+						if ((state & mask) == 0) {
+							/* null out bundles whose states are not interesting */
+							bundles[i] = null;
+						}
+					}
+					/* set tracked with the initial bundles */
+					t.setInitial(bundles);
+				}
+			}
+			tracked = t;
+		}
+		/* Call tracked outside of synchronized region */
+		t.trackInitial(); /* process the initial references */
+	}
+
+	/**
+	 * Close this {@code BundleTracker}.
+	 * 
+	 * <p>
+	 * This method should be called when this {@code BundleTracker} should end
+	 * the tracking of bundles.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getBundles()} to get the list of
+	 * tracked bundles to remove.
+	 */
+	public void close() {
+		final Bundle[] bundles;
+		final Tracked outgoing;
+		synchronized (this) {
+			outgoing = tracked;
+			if (outgoing == null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("BundleTracker.close"); //$NON-NLS-1$
+			}
+			outgoing.close();
+			bundles = getBundles();
+			tracked = null;
+			try {
+				context.removeBundleListener(outgoing);
+			} catch (IllegalStateException e) {
+				/* In case the context was stopped. */
+			}
+		}
+		if (bundles != null) {
+			for (int i = 0; i < bundles.length; i++) {
+				outgoing.untrack(bundles[i], null);
+			}
+		}
+	}
+
+	/**
+	 * Default implementation of the
+	 * {@code BundleTrackerCustomizer.addingBundle} method.
+	 * 
+	 * <p>
+	 * This method is only called when this {@code BundleTracker} has been
+	 * constructed with a {@code null BundleTrackerCustomizer} argument.
+	 * 
+	 * <p>
+	 * This implementation simply returns the specified {@code Bundle}.
+	 * 
+	 * <p>
+	 * This method can be overridden in a subclass to customize the object to be
+	 * tracked for the bundle being added.
+	 * 
+	 * @param bundle The {@code Bundle} being added to this
+	 *        {@code BundleTracker} object.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @return The specified bundle.
+	 * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
+	 */
+	public T addingBundle(Bundle bundle, BundleEvent event) {
+		T result = (T) bundle;
+		return result;
+	}
+
+	/**
+	 * Default implementation of the
+	 * {@code BundleTrackerCustomizer.modifiedBundle} method.
+	 * 
+	 * <p>
+	 * This method is only called when this {@code BundleTracker} has been
+	 * constructed with a {@code null BundleTrackerCustomizer} argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param bundle The {@code Bundle} whose state has been modified.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @param object The customized object for the specified Bundle.
+	 * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
+	 */
+	public void modifiedBundle(Bundle bundle, BundleEvent event, T object) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * {@code BundleTrackerCustomizer.removedBundle} method.
+	 * 
+	 * <p>
+	 * This method is only called when this {@code BundleTracker} has been
+	 * constructed with a {@code null BundleTrackerCustomizer} argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param bundle The {@code Bundle} being removed.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @param object The customized object for the specified bundle.
+	 * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
+	 */
+	public void removedBundle(Bundle bundle, BundleEvent event, T object) {
+		/* do nothing */
+	}
+
+	/**
+	 * Return an array of {@code Bundle}s for all bundles being tracked by this
+	 * {@code BundleTracker}.
+	 * 
+	 * @return An array of {@code Bundle}s or {@code null} if no bundles are
+	 *         being tracked.
+	 */
+	public Bundle[] getBundles() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			int length = t.size();
+			if (length == 0) {
+				return null;
+			}
+			return t.copyKeys(new Bundle[length]);
+		}
+	}
+
+	/**
+	 * Returns the customized object for the specified {@code Bundle} if the
+	 * specified bundle is being tracked by this {@code BundleTracker}.
+	 * 
+	 * @param bundle The {@code Bundle} being tracked.
+	 * @return The customized object for the specified {@code Bundle} or
+	 *         {@code null} if the specified {@code Bundle} is not being
+	 *         tracked.
+	 */
+	public T getObject(Bundle bundle) {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			return t.getCustomizedObject(bundle);
+		}
+	}
+
+	/**
+	 * Remove a bundle from this {@code BundleTracker}.
+	 * 
+	 * The specified bundle will be removed from this {@code BundleTracker} . If
+	 * the specified bundle was being tracked then the
+	 * {@code BundleTrackerCustomizer.removedBundle} method will be called for
+	 * that bundle.
+	 * 
+	 * @param bundle The {@code Bundle} to be removed.
+	 */
+	public void remove(Bundle bundle) {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return;
+		}
+		t.untrack(bundle, null);
+	}
+
+	/**
+	 * Return the number of bundles being tracked by this {@code BundleTracker}.
+	 * 
+	 * @return The number of bundles being tracked.
+	 */
+	public int size() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return 0;
+		}
+		synchronized (t) {
+			return t.size();
+		}
+	}
+
+	/**
+	 * Returns the tracking count for this {@code BundleTracker}.
+	 * 
+	 * The tracking count is initialized to 0 when this {@code BundleTracker} is
+	 * opened. Every time a bundle is added, modified or removed from this
+	 * {@code BundleTracker} the tracking count is incremented.
+	 * 
+	 * <p>
+	 * The tracking count can be used to determine if this {@code BundleTracker}
+	 * has added, modified or removed a bundle by comparing a tracking count
+	 * value previously collected with the current tracking count value. If the
+	 * value has not changed, then no bundle has been added, modified or removed
+	 * from this {@code BundleTracker} since the previous tracking count was
+	 * collected.
+	 * 
+	 * @return The tracking count for this {@code BundleTracker} or -1 if this
+	 *         {@code BundleTracker} is not open.
+	 */
+	public int getTrackingCount() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return -1;
+		}
+		synchronized (t) {
+			return t.getTrackingCount();
+		}
+	}
+
+	/**
+	 * Return a {@code Map} with the {@code Bundle}s and customized objects for
+	 * all bundles being tracked by this {@code BundleTracker}.
+	 * 
+	 * @return A {@code Map} with the {@code Bundle}s and customized objects for
+	 *         all services being tracked by this {@code BundleTracker}. If no
+	 *         bundles are being tracked, then the returned map is empty.
+	 * @since 1.5
+	 */
+	public Map<Bundle, T> getTracked() {
+		Map<Bundle, T> map = new HashMap<Bundle, T>();
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return map;
+		}
+		synchronized (t) {
+			return t.copyEntries(map);
+		}
+	}
+
+	/**
+	 * Return if this {@code BundleTracker} is empty.
+	 * 
+	 * @return {@code true} if this {@code BundleTracker} is not tracking any
+	 *         bundles.
+	 * @since 1.5
+	 */
+	public boolean isEmpty() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return true;
+		}
+		synchronized (t) {
+			return t.isEmpty();
+		}
+	}
+
+	/**
+	 * Inner class which subclasses AbstractTracked. This class is the
+	 * {@code SynchronousBundleListener} object for the tracker.
+	 * 
+	 * @ThreadSafe
+	 * @since 1.4
+	 */
+	private final class Tracked extends AbstractTracked<Bundle, T, BundleEvent> implements SynchronousBundleListener {
+		/**
+		 * Tracked constructor.
+		 */
+		Tracked() {
+			super();
+		}
+
+		/**
+		 * {@code BundleListener} method for the {@code BundleTracker} class.
+		 * This method must NOT be synchronized to avoid deadlock potential.
+		 * 
+		 * @param event {@code BundleEvent} object from the framework.
+		 */
+		public void bundleChanged(final BundleEvent event) {
+			/*
+			 * Check if we had a delayed call (which could happen when we
+			 * close).
+			 */
+			if (closed) {
+				return;
+			}
+			final Bundle bundle = event.getBundle();
+			final int state = bundle.getState();
+			if (DEBUG) {
+				System.out.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			if ((state & mask) != 0) {
+				track(bundle, event);
+				/*
+				 * If the customizer throws an unchecked exception, it is safe
+				 * to let it propagate
+				 */
+			} else {
+				untrack(bundle, event);
+				/*
+				 * If the customizer throws an unchecked exception, it is safe
+				 * to let it propagate
+				 */
+			}
+		}
+
+		/**
+		 * Call the specific customizer adding method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Item to be tracked.
+		 * @param related Action related object.
+		 * @return Customized object for the tracked item or {@code null} if the
+		 *         item is not to be tracked.
+		 */
+		T customizerAdding(final Bundle item, final BundleEvent related) {
+			return customizer.addingBundle(item, related);
+		}
+
+		/**
+		 * Call the specific customizer modified method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		void customizerModified(final Bundle item, final BundleEvent related, final T object) {
+			customizer.modifiedBundle(item, related, object);
+		}
+
+		/**
+		 * Call the specific customizer removed method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		void customizerRemoved(final Bundle item, final BundleEvent related, final T object) {
+			customizer.removedBundle(item, related, object);
+		}
+	}
+}
diff --git a/osgi/framework/src/org/osgi/util/tracker/BundleTrackerCustomizer.java b/osgi/framework/src/org/osgi/util/tracker/BundleTrackerCustomizer.java
new file mode 100644
index 0000000..b0bb297
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/BundleTrackerCustomizer.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+
+/**
+ * The {@code BundleTrackerCustomizer} interface allows a {@code BundleTracker}
+ * to customize the {@code Bundle}s that are tracked. A
+ * {@code BundleTrackerCustomizer} is called when a bundle is being added to a
+ * {@code BundleTracker}. The {@code BundleTrackerCustomizer} can then return an
+ * object for the tracked bundle. A {@code BundleTrackerCustomizer} is also
+ * called when a tracked bundle is modified or has been removed from a
+ * {@code BundleTracker}.
+ * 
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * {@code BundleEvent} being received by a {@code BundleTracker}. Since
+ * {@code BundleEvent}s are received synchronously by the {@code BundleTracker},
+ * it is highly recommended that implementations of these methods do not alter
+ * bundle states while being synchronized on any object.
+ * 
+ * <p>
+ * The {@code BundleTracker} class is thread-safe. It does not call a
+ * {@code BundleTrackerCustomizer} while holding any locks.
+ * {@code BundleTrackerCustomizer} implementations must also be thread-safe.
+ * 
+ * @param <T> The type of the tracked object.
+ * @ThreadSafe
+ * @version $Id: 727e757d2fa2940c88c9b74c8d299de6b3a7d0d0 $
+ * @since 1.4
+ */
+public interface BundleTrackerCustomizer<T> {
+	/**
+	 * A bundle is being added to the {@code BundleTracker}.
+	 * 
+	 * <p>
+	 * This method is called before a bundle which matched the search parameters
+	 * of the {@code BundleTracker} is added to the {@code BundleTracker}. This
+	 * method should return the object to be tracked for the specified
+	 * {@code Bundle}. The returned object is stored in the
+	 * {@code BundleTracker} and is available from the
+	 * {@link BundleTracker#getObject(Bundle) getObject} method.
+	 * 
+	 * @param bundle The {@code Bundle} being added to the {@code BundleTracker}
+	 *        .
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @return The object to be tracked for the specified {@code Bundle} object
+	 *         or {@code null} if the specified {@code Bundle} object should not
+	 *         be tracked.
+	 */
+	public T addingBundle(Bundle bundle, BundleEvent event);
+
+	/**
+	 * A bundle tracked by the {@code BundleTracker} has been modified.
+	 * 
+	 * <p>
+	 * This method is called when a bundle being tracked by the
+	 * {@code BundleTracker} has had its state modified.
+	 * 
+	 * @param bundle The {@code Bundle} whose state has been modified.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @param object The tracked object for the specified bundle.
+	 */
+	public void modifiedBundle(Bundle bundle, BundleEvent event, T object);
+
+	/**
+	 * A bundle tracked by the {@code BundleTracker} has been removed.
+	 * 
+	 * <p>
+	 * This method is called after a bundle is no longer being tracked by the
+	 * {@code BundleTracker}.
+	 * 
+	 * @param bundle The {@code Bundle} that has been removed.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @param object The tracked object for the specified bundle.
+	 */
+	public void removedBundle(Bundle bundle, BundleEvent event, T object);
+}
diff --git a/osgi/framework/src/org/osgi/util/tracker/ServiceTracker.java b/osgi/framework/src/org/osgi/util/tracker/ServiceTracker.java
new file mode 100644
index 0000000..0c8022d
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/ServiceTracker.java
@@ -0,0 +1,975 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import java.lang.reflect.Array;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The {@code ServiceTracker} class simplifies using services from the
+ * Framework's service registry.
+ * <p>
+ * A {@code ServiceTracker} object is constructed with search criteria and a
+ * {@code ServiceTrackerCustomizer} object. A {@code ServiceTracker} can use a
+ * {@code ServiceTrackerCustomizer} to customize the service objects to be
+ * tracked. The {@code ServiceTracker} can then be opened to begin tracking all
+ * services in the Framework's service registry that match the specified search
+ * criteria. The {@code ServiceTracker} correctly handles all of the details of
+ * listening to {@code ServiceEvent}s and getting and ungetting services.
+ * <p>
+ * The {@code getServiceReferences} method can be called to get references to
+ * the services being tracked. The {@code getService} and {@code getServices}
+ * methods can be called to get the service objects for the tracked service.
+ * <p>
+ * The {@code ServiceTracker} class is thread-safe. It does not call a
+ * {@code ServiceTrackerCustomizer} while holding any locks.
+ * {@code ServiceTrackerCustomizer} implementations must also be thread-safe.
+ * 
+ * @param <S> The type of the service being tracked.
+ * @param <T> The type of the tracked object.
+ * @ThreadSafe
+ * @version $Id: 21926ad8717a91633face6bbf570febfcd23b1c7 $
+ */
+public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
+	/* set this to true to compile in debug messages */
+	static final boolean					DEBUG	= false;
+	/**
+	 * The Bundle Context used by this {@code ServiceTracker}.
+	 */
+	protected final BundleContext			context;
+	/**
+	 * The Filter used by this {@code ServiceTracker} which specifies the search
+	 * criteria for the services to track.
+	 * 
+	 * @since 1.1
+	 */
+	protected final Filter					filter;
+	/**
+	 * The {@code ServiceTrackerCustomizer} for this tracker.
+	 */
+	final ServiceTrackerCustomizer<S, T>	customizer;
+	/**
+	 * Filter string for use when adding the ServiceListener. If this field is
+	 * set, then certain optimizations can be taken since we don't have a user
+	 * supplied filter.
+	 */
+	final String							listenerFilter;
+	/**
+	 * Class name to be tracked. If this field is set, then we are tracking by
+	 * class name.
+	 */
+	private final String					trackClass;
+	/**
+	 * Reference to be tracked. If this field is set, then we are tracking a
+	 * single ServiceReference.
+	 */
+	private final ServiceReference<S>		trackReference;
+	/**
+	 * Tracked services: {@code ServiceReference} -> customized Object and
+	 * {@code ServiceListener} object
+	 */
+	private volatile Tracked				tracked;
+
+	/**
+	 * Accessor method for the current Tracked object. This method is only
+	 * intended to be used by the unsynchronized methods which do not modify the
+	 * tracked field.
+	 * 
+	 * @return The current Tracked object.
+	 */
+	private Tracked tracked() {
+		return tracked;
+	}
+
+	/**
+	 * Cached ServiceReference for getServiceReference.
+	 * 
+	 * This field is volatile since it is accessed by multiple threads.
+	 */
+	private volatile ServiceReference<S>	cachedReference;
+	/**
+	 * Cached service object for getService.
+	 * 
+	 * This field is volatile since it is accessed by multiple threads.
+	 */
+	private volatile T						cachedService;
+
+	/**
+	 * Create a {@code ServiceTracker} on the specified {@code ServiceReference}
+	 * .
+	 * 
+	 * <p>
+	 * The service referenced by the specified {@code ServiceReference} will be
+	 * tracked by this {@code ServiceTracker}.
+	 * 
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param reference The {@code ServiceReference} for the service to be
+	 *        tracked.
+	 * @param customizer The customizer object to call when services are added,
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is {@code null}, then this {@code ServiceTracker} will be used as
+	 *        the {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
+	 */
+	public ServiceTracker(final BundleContext context, final ServiceReference<S> reference, final ServiceTrackerCustomizer<S, T> customizer) {
+		this.context = context;
+		this.trackReference = reference;
+		this.trackClass = null;
+		this.customizer = (customizer == null) ? this : customizer;
+		this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")";
+		try {
+			this.filter = context.createFilter(listenerFilter);
+		} catch (InvalidSyntaxException e) {
+			/*
+			 * we could only get this exception if the ServiceReference was
+			 * invalid
+			 */
+			IllegalArgumentException iae = new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Create a {@code ServiceTracker} on the specified class name.
+	 * 
+	 * <p>
+	 * Services registered under the specified class name will be tracked by
+	 * this {@code ServiceTracker}.
+	 * 
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param clazz The class name of the services to be tracked.
+	 * @param customizer The customizer object to call when services are added,
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is {@code null}, then this {@code ServiceTracker} will be used as
+	 *        the {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
+	 */
+	public ServiceTracker(final BundleContext context, final String clazz, final ServiceTrackerCustomizer<S, T> customizer) {
+		this.context = context;
+		this.trackReference = null;
+		this.trackClass = clazz;
+		this.customizer = (customizer == null) ? this : customizer;
+		// we call clazz.toString to verify clazz is non-null!
+		this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")";
+		try {
+			this.filter = context.createFilter(listenerFilter);
+		} catch (InvalidSyntaxException e) {
+			/*
+			 * we could only get this exception if the clazz argument was
+			 * malformed
+			 */
+			IllegalArgumentException iae = new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Create a {@code ServiceTracker} on the specified {@code Filter} object.
+	 * 
+	 * <p>
+	 * Services which match the specified {@code Filter} object will be tracked
+	 * by this {@code ServiceTracker}.
+	 * 
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param filter The {@code Filter} to select the services to be tracked.
+	 * @param customizer The customizer object to call when services are added,
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is null, then this {@code ServiceTracker} will be used as the
+	 *        {@code ServiceTrackerCustomizer} and this {@code ServiceTracker}
+	 *        will call the {@code ServiceTrackerCustomizer} methods on itself.
+	 * @since 1.1
+	 */
+	public ServiceTracker(final BundleContext context, final Filter filter, final ServiceTrackerCustomizer<S, T> customizer) {
+		this.context = context;
+		this.trackReference = null;
+		this.trackClass = null;
+		this.listenerFilter = filter.toString();
+		this.filter = filter;
+		this.customizer = (customizer == null) ? this : customizer;
+		if ((context == null) || (filter == null)) {
+			/*
+			 * we throw a NPE here to be consistent with the other constructors
+			 */
+			throw new NullPointerException();
+		}
+	}
+
+	/**
+	 * Create a {@code ServiceTracker} on the specified class.
+	 * 
+	 * <p>
+	 * Services registered under the name of the specified class will be tracked
+	 * by this {@code ServiceTracker}.
+	 * 
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param clazz The class of the services to be tracked.
+	 * @param customizer The customizer object to call when services are added,
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is {@code null}, then this {@code ServiceTracker} will be used as
+	 *        the {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
+	 * @since 1.5
+	 */
+	public ServiceTracker(final BundleContext context, final Class<S> clazz, final ServiceTrackerCustomizer<S, T> customizer) {
+		this(context, clazz.getName(), customizer);
+	}
+
+	/**
+	 * Open this {@code ServiceTracker} and begin tracking services.
+	 * 
+	 * <p>
+	 * This implementation calls {@code open(false)}.
+	 * 
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *         which this {@code ServiceTracker} was created is no longer valid.
+	 * @see #open(boolean)
+	 */
+	public void open() {
+		open(false);
+	}
+
+	/**
+	 * Open this {@code ServiceTracker} and begin tracking services.
+	 * 
+	 * <p>
+	 * Services which match the search criteria specified when this
+	 * {@code ServiceTracker} was created are now tracked by this
+	 * {@code ServiceTracker}.
+	 * 
+	 * @param trackAllServices If {@code true}, then this {@code ServiceTracker}
+	 *        will track all matching services regardless of class loader
+	 *        accessibility. If {@code false}, then this {@code ServiceTracker}
+	 *        will only track matching services which are class loader
+	 *        accessible to the bundle whose {@code BundleContext} is used by
+	 *        this {@code ServiceTracker}.
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *         which this {@code ServiceTracker} was created is no longer valid.
+	 * @since 1.3
+	 */
+	public void open(boolean trackAllServices) {
+		final Tracked t;
+		synchronized (this) {
+			if (tracked != null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("ServiceTracker.open: " + filter);
+			}
+			t = trackAllServices ? new AllTracked() : new Tracked();
+			synchronized (t) {
+				try {
+					context.addServiceListener(t, listenerFilter);
+					ServiceReference<S>[] references = null;
+					if (trackClass != null) {
+						references = getInitialReferences(trackAllServices, trackClass, null);
+					} else {
+						if (trackReference != null) {
+							if (trackReference.getBundle() != null) {
+								ServiceReference<S>[] single = new ServiceReference[] {trackReference};
+								references = single;
+							}
+						} else { /* user supplied filter */
+							references = getInitialReferences(trackAllServices, null, listenerFilter);
+						}
+					}
+					/* set tracked with the initial references */
+					t.setInitial(references);
+				} catch (InvalidSyntaxException e) {
+					throw new RuntimeException("unexpected InvalidSyntaxException: " + e.getMessage(), e);
+				}
+			}
+			tracked = t;
+		}
+		/* Call tracked outside of synchronized region */
+		t.trackInitial(); /* process the initial references */
+	}
+
+	/**
+	 * Returns the list of initial {@code ServiceReference}s that will be
+	 * tracked by this {@code ServiceTracker}.
+	 * 
+	 * @param trackAllServices If {@code true}, use
+	 *        {@code getAllServiceReferences}.
+	 * @param className The class name with which the service was registered, or
+	 *        {@code null} for all services.
+	 * @param filterString The filter criteria or {@code null} for all services.
+	 * @return The list of initial {@code ServiceReference}s.
+	 * @throws InvalidSyntaxException If the specified filterString has an
+	 *         invalid syntax.
+	 */
+	private ServiceReference<S>[] getInitialReferences(boolean trackAllServices, String className, String filterString) throws InvalidSyntaxException {
+		ServiceReference<S>[] result = (ServiceReference<S>[]) ((trackAllServices) ? context.getAllServiceReferences(className, filterString) : context.getServiceReferences(className, filterString));
+		return result;
+	}
+
+	/**
+	 * Close this {@code ServiceTracker}.
+	 * 
+	 * <p>
+	 * This method should be called when this {@code ServiceTracker} should end
+	 * the tracking of services.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of tracked services to remove.
+	 */
+	public void close() {
+		final Tracked outgoing;
+		final ServiceReference<S>[] references;
+		synchronized (this) {
+			outgoing = tracked;
+			if (outgoing == null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("ServiceTracker.close: " + filter);
+			}
+			outgoing.close();
+			references = getServiceReferences();
+			tracked = null;
+			try {
+				context.removeServiceListener(outgoing);
+			} catch (IllegalStateException e) {
+				/* In case the context was stopped. */
+			}
+		}
+		modified(); /* clear the cache */
+		synchronized (outgoing) {
+			outgoing.notifyAll(); /* wake up any waiters */
+		}
+		if (references != null) {
+			for (int i = 0; i < references.length; i++) {
+				outgoing.untrack(references[i], null);
+			}
+		}
+		if (DEBUG) {
+			if ((cachedReference == null) && (cachedService == null)) {
+				System.out.println("ServiceTracker.close[cached cleared]: " + filter);
+			}
+		}
+	}
+
+	/**
+	 * Default implementation of the
+	 * {@code ServiceTrackerCustomizer.addingService} method.
+	 * 
+	 * <p>
+	 * This method is only called when this {@code ServiceTracker} has been
+	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
+	 * 
+	 * <p>
+	 * This implementation returns the result of calling {@code getService} on
+	 * the {@code BundleContext} with which this {@code ServiceTracker} was
+	 * created passing the specified {@code ServiceReference}.
+	 * <p>
+	 * This method can be overridden in a subclass to customize the service
+	 * object to be tracked for the service being added. In that case, take care
+	 * not to rely on the default implementation of
+	 * {@link #removedService(ServiceReference, Object) removedService} to unget
+	 * the service.
+	 * 
+	 * @param reference The reference to the service being added to this
+	 *        {@code ServiceTracker}.
+	 * @return The service object to be tracked for the service added to this
+	 *         {@code ServiceTracker}.
+	 * @see ServiceTrackerCustomizer#addingService(ServiceReference)
+	 */
+	public T addingService(ServiceReference<S> reference) {
+		T result = (T) context.getService(reference);
+		return result;
+	}
+
+	/**
+	 * Default implementation of the
+	 * {@code ServiceTrackerCustomizer.modifiedService} method.
+	 * 
+	 * <p>
+	 * This method is only called when this {@code ServiceTracker} has been
+	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param reference The reference to modified service.
+	 * @param service The service object for the modified service.
+	 * @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
+	 */
+	public void modifiedService(ServiceReference<S> reference, T service) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * {@code ServiceTrackerCustomizer.removedService} method.
+	 * 
+	 * <p>
+	 * This method is only called when this {@code ServiceTracker} has been
+	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
+	 * 
+	 * <p>
+	 * This implementation calls {@code ungetService}, on the
+	 * {@code BundleContext} with which this {@code ServiceTracker} was created,
+	 * passing the specified {@code ServiceReference}.
+	 * <p>
+	 * This method can be overridden in a subclass. If the default
+	 * implementation of {@link #addingService(ServiceReference) addingService}
+	 * method was used, this method must unget the service.
+	 * 
+	 * @param reference The reference to removed service.
+	 * @param service The service object for the removed service.
+	 * @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
+	 */
+	public void removedService(ServiceReference<S> reference, T service) {
+		context.ungetService(reference);
+	}
+
+	/**
+	 * Wait for at least one service to be tracked by this
+	 * {@code ServiceTracker}. This method will also return when this
+	 * {@code ServiceTracker} is closed.
+	 * 
+	 * <p>
+	 * It is strongly recommended that {@code waitForService} is not used during
+	 * the calling of the {@code BundleActivator} methods.
+	 * {@code BundleActivator} methods are expected to complete in a short
+	 * period of time.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getService()} to determine if a service
+	 * is being tracked.
+	 * 
+	 * @param timeout The time interval in milliseconds to wait. If zero, the
+	 *        method will wait indefinitely.
+	 * @return Returns the result of {@link #getService()}.
+	 * @throws InterruptedException If another thread has interrupted the
+	 *         current thread.
+	 * @throws IllegalArgumentException If the value of timeout is negative.
+	 */
+	public T waitForService(long timeout) throws InterruptedException {
+		if (timeout < 0) {
+			throw new IllegalArgumentException("timeout value is negative");
+		}
+
+		T object = getService();
+		if (object != null) {
+			return object;
+		}
+
+		final long endTime = (timeout == 0) ? 0 : (System.currentTimeMillis() + timeout);
+		do {
+			final Tracked t = tracked();
+			if (t == null) { /* if ServiceTracker is not open */
+				return null;
+			}
+			synchronized (t) {
+				if (t.size() == 0) {
+					t.wait(timeout);
+				}
+			}
+			object = getService();
+			if (endTime > 0) { // if we have a timeout
+				timeout = endTime - System.currentTimeMillis();
+				if (timeout <= 0) { // that has expired
+					break;
+				}
+			}
+		} while (object == null);
+		return object;
+	}
+
+	/**
+	 * Return an array of {@code ServiceReference}s for all services being
+	 * tracked by this {@code ServiceTracker}.
+	 * 
+	 * @return Array of {@code ServiceReference}s or {@code null} if no services
+	 *         are being tracked.
+	 */
+	public ServiceReference<S>[] getServiceReferences() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			int length = t.size();
+			if (length == 0) {
+				return null;
+			}
+			ServiceReference<S>[] result = new ServiceReference[length];
+			return t.copyKeys(result);
+		}
+	}
+
+	/**
+	 * Returns a {@code ServiceReference} for one of the services being tracked
+	 * by this {@code ServiceTracker}.
+	 * 
+	 * <p>
+	 * If multiple services are being tracked, the service with the highest
+	 * ranking (as specified in its {@code service.ranking} property) is
+	 * returned. If there is a tie in ranking, the service with the lowest
+	 * service ID (as specified in its {@code service.id} property); that is,
+	 * the service that was registered first is returned. This is the same
+	 * algorithm used by {@code BundleContext.getServiceReference}.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services.
+	 * 
+	 * @return A {@code ServiceReference} or {@code null} if no services are
+	 *         being tracked.
+	 * @since 1.1
+	 */
+	public ServiceReference<S> getServiceReference() {
+		ServiceReference<S> reference = cachedReference;
+		if (reference != null) {
+			if (DEBUG) {
+				System.out.println("ServiceTracker.getServiceReference[cached]: " + filter);
+			}
+			return reference;
+		}
+		if (DEBUG) {
+			System.out.println("ServiceTracker.getServiceReference: " + filter);
+		}
+		ServiceReference<S>[] references = getServiceReferences();
+		int length = (references == null) ? 0 : references.length;
+		if (length == 0) { /* if no service is being tracked */
+			return null;
+		}
+		int index = 0;
+		if (length > 1) { /* if more than one service, select highest ranking */
+			int rankings[] = new int[length];
+			int count = 0;
+			int maxRanking = Integer.MIN_VALUE;
+			for (int i = 0; i < length; i++) {
+				Object property = references[i].getProperty(Constants.SERVICE_RANKING);
+				int ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
+				rankings[i] = ranking;
+				if (ranking > maxRanking) {
+					index = i;
+					maxRanking = ranking;
+					count = 1;
+				} else {
+					if (ranking == maxRanking) {
+						count++;
+					}
+				}
+			}
+			if (count > 1) { /* if still more than one service, select lowest id */
+				long minId = Long.MAX_VALUE;
+				for (int i = 0; i < length; i++) {
+					if (rankings[i] == maxRanking) {
+						long id = ((Long) (references[i].getProperty(Constants.SERVICE_ID))).longValue();
+						if (id < minId) {
+							index = i;
+							minId = id;
+						}
+					}
+				}
+			}
+		}
+		return cachedReference = references[index];
+	}
+
+	/**
+	 * Returns the service object for the specified {@code ServiceReference} if
+	 * the specified referenced service is being tracked by this
+	 * {@code ServiceTracker}.
+	 * 
+	 * @param reference The reference to the desired service.
+	 * @return A service object or {@code null} if the service referenced by the
+	 *         specified {@code ServiceReference} is not being tracked.
+	 */
+	public T getService(ServiceReference<S> reference) {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			return t.getCustomizedObject(reference);
+		}
+	}
+
+	/**
+	 * Return an array of service objects for all services being tracked by this
+	 * {@code ServiceTracker}.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services and then calls
+	 * {@link #getService(ServiceReference)} for each reference to get the
+	 * tracked service object.
+	 * 
+	 * @return An array of service objects or {@code null} if no services are
+	 *         being tracked.
+	 */
+	public Object[] getServices() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			ServiceReference<S>[] references = getServiceReferences();
+			int length = (references == null) ? 0 : references.length;
+			if (length == 0) {
+				return null;
+			}
+			Object[] objects = new Object[length];
+			for (int i = 0; i < length; i++) {
+				objects[i] = getService(references[i]);
+			}
+			return objects;
+		}
+	}
+
+	/**
+	 * Returns a service object for one of the services being tracked by this
+	 * {@code ServiceTracker}.
+	 * 
+	 * <p>
+	 * If any services are being tracked, this implementation returns the result
+	 * of calling {@code getService(getServiceReference())}.
+	 * 
+	 * @return A service object or {@code null} if no services are being
+	 *         tracked.
+	 */
+	public T getService() {
+		T service = cachedService;
+		if (service != null) {
+			if (DEBUG) {
+				System.out.println("ServiceTracker.getService[cached]: " + filter);
+			}
+			return service;
+		}
+		if (DEBUG) {
+			System.out.println("ServiceTracker.getService: " + filter);
+		}
+		ServiceReference<S> reference = getServiceReference();
+		if (reference == null) {
+			return null;
+		}
+		return cachedService = getService(reference);
+	}
+
+	/**
+	 * Remove a service from this {@code ServiceTracker}.
+	 * 
+	 * The specified service will be removed from this {@code ServiceTracker}.
+	 * If the specified service was being tracked then the
+	 * {@code ServiceTrackerCustomizer.removedService} method will be called for
+	 * that service.
+	 * 
+	 * @param reference The reference to the service to be removed.
+	 */
+	public void remove(ServiceReference<S> reference) {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return;
+		}
+		t.untrack(reference, null);
+	}
+
+	/**
+	 * Return the number of services being tracked by this
+	 * {@code ServiceTracker}.
+	 * 
+	 * @return The number of services being tracked.
+	 */
+	public int size() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return 0;
+		}
+		synchronized (t) {
+			return t.size();
+		}
+	}
+
+	/**
+	 * Returns the tracking count for this {@code ServiceTracker}.
+	 * 
+	 * The tracking count is initialized to 0 when this {@code ServiceTracker}
+	 * is opened. Every time a service is added, modified or removed from this
+	 * {@code ServiceTracker}, the tracking count is incremented.
+	 * 
+	 * <p>
+	 * The tracking count can be used to determine if this
+	 * {@code ServiceTracker} has added, modified or removed a service by
+	 * comparing a tracking count value previously collected with the current
+	 * tracking count value. If the value has not changed, then no service has
+	 * been added, modified or removed from this {@code ServiceTracker} since
+	 * the previous tracking count was collected.
+	 * 
+	 * @since 1.2
+	 * @return The tracking count for this {@code ServiceTracker} or -1 if this
+	 *         {@code ServiceTracker} is not open.
+	 */
+	public int getTrackingCount() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return -1;
+		}
+		synchronized (t) {
+			return t.getTrackingCount();
+		}
+	}
+
+	/**
+	 * Called by the Tracked object whenever the set of tracked services is
+	 * modified. Clears the cache.
+	 */
+	/*
+	 * This method must not be synchronized since it is called by Tracked while
+	 * Tracked is synchronized. We don't want synchronization interactions
+	 * between the listener thread and the user thread.
+	 */
+	void modified() {
+		cachedReference = null; /* clear cached value */
+		cachedService = null; /* clear cached value */
+		if (DEBUG) {
+			System.out.println("ServiceTracker.modified: " + filter);
+		}
+	}
+
+	/**
+	 * Return a {@code SortedMap} of the {@code ServiceReference}s and service
+	 * objects for all services being tracked by this {@code ServiceTracker}.
+	 * The map is sorted in reverse natural order of {@code ServiceReference}.
+	 * That is, the first entry is the service with the highest ranking and the
+	 * lowest service id.
+	 * 
+	 * @return A {@code SortedMap} with the {@code ServiceReference}s and
+	 *         service objects for all services being tracked by this
+	 *         {@code ServiceTracker}. If no services are being tracked, then
+	 *         the returned map is empty.
+	 * @since 1.5
+	 */
+	public SortedMap<ServiceReference<S>, T> getTracked() {
+		SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(Collections.reverseOrder());
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return map;
+		}
+		synchronized (t) {
+			return t.copyEntries(map);
+		}
+	}
+
+	/**
+	 * Return if this {@code ServiceTracker} is empty.
+	 * 
+	 * @return {@code true} if this {@code ServiceTracker} is not tracking any
+	 *         services.
+	 * @since 1.5
+	 */
+	public boolean isEmpty() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return true;
+		}
+		synchronized (t) {
+			return t.isEmpty();
+		}
+	}
+
+	/**
+	 * Return an array of service objects for all services being tracked by this
+	 * {@code ServiceTracker}. The runtime type of the returned array is that of
+	 * the specified array.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services and then calls
+	 * {@link #getService(ServiceReference)} for each reference to get the
+	 * tracked service object.
+	 * 
+	 * @param array An array into which the tracked service objects will be
+	 *        stored, if the array is large enough.
+	 * @return An array of service objects being tracked. If the specified array
+	 *         is large enough to hold the result, then the specified array is
+	 *         returned. If the specified array is longer then necessary to hold
+	 *         the result, the array element after the last service object is
+	 *         set to {@code null}. If the specified array is not large enough
+	 *         to hold the result, a new array is created and returned.
+	 * @since 1.5
+	 */
+	public T[] getServices(T[] array) {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			if (array.length > 0) {
+				array[0] = null;
+			}
+			return array;
+		}
+		synchronized (t) {
+			ServiceReference<S>[] references = getServiceReferences();
+			int length = (references == null) ? 0 : references.length;
+			if (length == 0) {
+				if (array.length > 0) {
+					array[0] = null;
+				}
+				return array;
+			}
+			if (length > array.length) {
+				array = (T[]) Array.newInstance(array.getClass().getComponentType(), length);
+			}
+			for (int i = 0; i < length; i++) {
+				array[i] = getService(references[i]);
+			}
+			if (array.length > length) {
+				array[length] = null;
+			}
+			return array;
+		}
+	}
+
+	/**
+	 * Inner class which subclasses AbstractTracked. This class is the
+	 * {@code ServiceListener} object for the tracker.
+	 * 
+	 * @ThreadSafe
+	 */
+	private class Tracked extends AbstractTracked<ServiceReference<S>, T, ServiceEvent> implements ServiceListener {
+		/**
+		 * Tracked constructor.
+		 */
+		Tracked() {
+			super();
+		}
+
+		/**
+		 * {@code ServiceListener} method for the {@code ServiceTracker} class.
+		 * This method must NOT be synchronized to avoid deadlock potential.
+		 * 
+		 * @param event {@code ServiceEvent} object from the framework.
+		 */
+		final public void serviceChanged(final ServiceEvent event) {
+			/*
+			 * Check if we had a delayed call (which could happen when we
+			 * close).
+			 */
+			if (closed) {
+				return;
+			}
+			final ServiceReference<S> reference = (ServiceReference<S>) event.getServiceReference();
+			if (DEBUG) {
+				System.out.println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference);
+			}
+
+			switch (event.getType()) {
+				case ServiceEvent.REGISTERED :
+				case ServiceEvent.MODIFIED :
+					track(reference, event);
+					/*
+					 * If the customizer throws an unchecked exception, it is
+					 * safe to let it propagate
+					 */
+					break;
+				case ServiceEvent.MODIFIED_ENDMATCH :
+				case ServiceEvent.UNREGISTERING :
+					untrack(reference, event);
+					/*
+					 * If the customizer throws an unchecked exception, it is
+					 * safe to let it propagate
+					 */
+					break;
+			}
+		}
+
+		/**
+		 * Increment the tracking count and tell the tracker there was a
+		 * modification.
+		 * 
+		 * @GuardedBy this
+		 */
+		final void modified() {
+			super.modified(); /* increment the modification count */
+			ServiceTracker.this.modified();
+		}
+
+		/**
+		 * Call the specific customizer adding method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Item to be tracked.
+		 * @param related Action related object.
+		 * @return Customized object for the tracked item or {@code null} if the
+		 *         item is not to be tracked.
+		 */
+		final T customizerAdding(final ServiceReference<S> item, final ServiceEvent related) {
+			return customizer.addingService(item);
+		}
+
+		/**
+		 * Call the specific customizer modified method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		final void customizerModified(final ServiceReference<S> item, final ServiceEvent related, final T object) {
+			customizer.modifiedService(item, object);
+		}
+
+		/**
+		 * Call the specific customizer removed method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		final void customizerRemoved(final ServiceReference<S> item, final ServiceEvent related, final T object) {
+			customizer.removedService(item, object);
+		}
+	}
+
+	/**
+	 * Subclass of Tracked which implements the AllServiceListener interface.
+	 * This class is used by the ServiceTracker if open is called with true.
+	 * 
+	 * @since 1.3
+	 * @ThreadSafe
+	 */
+	private class AllTracked extends Tracked implements AllServiceListener {
+		/**
+		 * AllTracked constructor.
+		 */
+		AllTracked() {
+			super();
+		}
+	}
+}
diff --git a/osgi/framework/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/osgi/framework/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java
new file mode 100644
index 0000000..72bec7a
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.util.tracker;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The {@code ServiceTrackerCustomizer} interface allows a
+ * {@code ServiceTracker} to customize the service objects that are tracked. A
+ * {@code ServiceTrackerCustomizer} is called when a service is being added to a
+ * {@code ServiceTracker}. The {@code ServiceTrackerCustomizer} can then return
+ * an object for the tracked service. A {@code ServiceTrackerCustomizer} is also
+ * called when a tracked service is modified or has been removed from a
+ * {@code ServiceTracker}.
+ * 
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * {@code ServiceEvent} being received by a {@code ServiceTracker}. Since
+ * {@code ServiceEvent}s are synchronously delivered by the Framework, it is
+ * highly recommended that implementations of these methods do not register (
+ * {@code BundleContext.registerService}), modify (
+ * {@code ServiceRegistration.setProperties}) or unregister (
+ * {@code ServiceRegistration.unregister}) a service while being synchronized on
+ * any object.
+ * 
+ * <p>
+ * The {@code ServiceTracker} class is thread-safe. It does not call a
+ * {@code ServiceTrackerCustomizer} while holding any locks.
+ * {@code ServiceTrackerCustomizer} implementations must also be thread-safe.
+ * 
+ * @param <S> The type of the service being tracked.
+ * @param <T> The type of the tracked object.
+ * @ThreadSafe
+ * @version $Id: c14b8d47026b6bd4ba1f2db7bf7e755d00fc6f6a $
+ */
+public interface ServiceTrackerCustomizer<S, T> {
+	/**
+	 * A service is being added to the {@code ServiceTracker}.
+	 * 
+	 * <p>
+	 * This method is called before a service which matched the search
+	 * parameters of the {@code ServiceTracker} is added to the
+	 * {@code ServiceTracker}. This method should return the service object to
+	 * be tracked for the specified {@code ServiceReference}. The returned
+	 * service object is stored in the {@code ServiceTracker} and is available
+	 * from the {@code getService} and {@code getServices} methods.
+	 * 
+	 * @param reference The reference to the service being added to the
+	 *        {@code ServiceTracker}.
+	 * @return The service object to be tracked for the specified referenced
+	 *         service or {@code null} if the specified referenced service
+	 *         should not be tracked.
+	 */
+	public T addingService(ServiceReference<S> reference);
+
+	/**
+	 * A service tracked by the {@code ServiceTracker} has been modified.
+	 * 
+	 * <p>
+	 * This method is called when a service being tracked by the
+	 * {@code ServiceTracker} has had it properties modified.
+	 * 
+	 * @param reference The reference to the service that has been modified.
+	 * @param service The service object for the specified referenced service.
+	 */
+	public void modifiedService(ServiceReference<S> reference, T service);
+
+	/**
+	 * A service tracked by the {@code ServiceTracker} has been removed.
+	 * 
+	 * <p>
+	 * This method is called after a service is no longer being tracked by the
+	 * {@code ServiceTracker}.
+	 * 
+	 * @param reference The reference to the service that has been removed.
+	 * @param service The service object for the specified referenced service.
+	 */
+	public void removedService(ServiceReference<S> reference, T service);
+}
diff --git a/osgi/framework/src/org/osgi/util/tracker/package-info.java b/osgi/framework/src/org/osgi/util/tracker/package-info.java
new file mode 100644
index 0000000..9b6077f
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Tracker Package Version 1.5.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.util.tracker; version="[1.5,2.0)"}
+ * 
+ * @version $Id: e24ccaae9b18ecce26ce0add3a47f1fe6dac84bb $
+ */
+
+package org.osgi.util.tracker;
+
diff --git a/osgi/framework/src/org/osgi/util/tracker/packageinfo b/osgi/framework/src/org/osgi/util/tracker/packageinfo
new file mode 100644
index 0000000..1213efd
--- /dev/null
+++ b/osgi/framework/src/org/osgi/util/tracker/packageinfo
@@ -0,0 +1 @@
+version 1.5.1
diff --git a/osgi/headless.xargs b/osgi/headless.xargs
new file mode 100644
index 0000000..6b3356d
--- /dev/null
+++ b/osgi/headless.xargs
@@ -0,0 +1,99 @@
+#
+# Generated from template.xargs
+# Knopflerfish release 5.1.0
+#
+
+# load common properties
+-xargs props.xargs
+
+# Semicolon seprated list of base URLs for searching (completing)
+# bundle URLs in "-install URL" command line options and in the console.
+-Forg.knopflerfish.gosg.jars=file:jars/
+
+# Comma seprated list of OSGi Repository xml URLs for instantiating 
+# RepositoryServices
+-Forg.knopflerfish.repository.xml.urls=file:jars/index.xml,http://www.knopflerfish.org/releases/current/osgi/jars/index.xml
+
+## Basic KF bundles
+-initlevel 1
+-install log/log_all-5.0.0.jar
+-install cm/cm_all-5.0.1.jar
+-install console/console_all-4.0.1.jar
+-install component/component_all-5.0.3.jar
+-install event/event_all-4.0.1.jar
+-install prefs/prefs_all-4.0.2.jar
+#-istart trayicon_fw/trayicon_fw-4.0.0.jar
+
+## Some library bundles
+-initlevel 2
+-install util/util-4.1.0.jar
+-install crimson/crimson-2.1.0.kf4-001.jar
+-install jsdk/jsdk_api-2.5.0.kf3-2.jar
+-install kxml/kxml-2.3.0.kf4-001.jar
+
+# The Bundle repo commands and desktop plugin
+-install repository_xml/repository_xml_all-1.0.2.jar
+-install repositorymanager/repositorymanager_all-1.2.0.jar
+#-install repository_desktop/repository_desktop_all-1.1.1.jar
+
+## More basic KF bundles
+-initlevel 3
+-install device/device_all-4.0.1.jar
+-install useradmin/useradmin_all-4.1.1.jar
+
+-initlevel 4
+-install http/http_all-4.0.5.jar
+
+## console command bundles
+-initlevel 5
+-install frameworkcommands/frameworkcommands-4.0.1.jar
+-install logcommands/logcommands-5.0.0.jar
+-install cm_cmd/cm_cmd-5.0.1.jar
+-install repositorycommands/repositorycommands-1.1.1.jar
+-install scrcommands/scrcommands-4.0.1.jar
+
+-install consoletty/consoletty-4.0.1.jar
+
+-install consoletelnet/consoletelnet-4.0.1.jar
+
+-initlevel 6
+#-install remotefw/remotefw_api-4.0.0.jar
+#-install desktop/desktop_all-5.0.1.jar
+
+
+-initlevel 7
+-install httproot/httproot-4.0.0.jar
+
+
+
+-startlevel 7
+
+
+# Start of these bundles are delayed since this makes start
+# order dependencies much easier
+
+-start log/log_all-5.0.0.jar
+-start crimson/crimson-2.1.0.kf4-001.jar
+-start cm/cm_all-5.0.1.jar
+-start console/console_all-4.0.1.jar
+-start component/component_all-5.0.3.jar
+-start event/event_all-4.0.1.jar
+-start prefs/prefs_all-4.0.2.jar
+-start device/device_all-4.0.1.jar
+-start useradmin/useradmin_all-4.1.1.jar
+-start repository_xml/repository_xml_all-1.0.2.jar
+-start repositorymanager/repositorymanager_all-1.2.0.jar
+#-start repository_desktop/repository_desktop_all-1.1.1.jar
+-start consoletty/consoletty-4.0.1.jar
+-start consoletelnet/consoletelnet-4.0.1.jar
+-start frameworkcommands/frameworkcommands-4.0.1.jar
+-start logcommands/logcommands-5.0.0.jar
+-start cm_cmd/cm_cmd-5.0.1.jar
+-start repositorycommands/repositorycommands-1.1.1.jar
+-start scrcommands/scrcommands-4.0.1.jar
+#-start desktop/desktop_all-5.0.1.jar
+-start http/http_all-4.0.5.jar
+-start httproot/httproot-4.0.0.jar
+
+# Uncomment the following line to add Resolver support
+# -istart http://repo2.maven.org/maven2/org/apache/felix/org.apache.felix.resolver/1.0.0/org.apache.felix.resolver-1.0.0.jar
diff --git a/osgi/init-tests.xargs b/osgi/init-tests.xargs
new file mode 100644
index 0000000..01a8317
--- /dev/null
+++ b/osgi/init-tests.xargs
@@ -0,0 +1,127 @@
+#
+# Startup file for framework testing
+#
+
+# List of test IDs
+#-Forg.knopflerfish.junit_runner.tests=PerformanceRegistryTestSuite
+-Forg.knopflerfish.junit_runner.tests=filter:(objectclass=junit.framework.TestSuite)
+#-Forg.knopflerfish.junit_runner.tests=FrameworkTestSuite ServiceTrackerTestSuite ConstantsTestSuite FilterTestSuite
+
+
+-Forg.knopflerfish.bundle.perf.servicereg.nlisteners=100
+-Forg.knopflerfish.bundle.perf.servicereg.nservices=1000
+
+# true means "quit framework when all tests are run"
+-Forg.knopflerfish.junit_runner.quit=true
+
+# Initial startup verbosity, 0 is low verbosity
+-Dorg.knopflerfish.framework.main.verbosity=0
+
+# Prefix for searching for bundle URLs from console or command line
+-Dorg.knopflerfish.gosg.jars=file:jars/;file:test_jars/
+
+# Various debug flags
+-Forg.knopflerfish.framework.debug.resolver=false
+-Forg.knopflerfish.framework.debug.errors=false
+-Forg.knopflerfish.framework.debug.warnings=false
+-Forg.knopflerfish.framework.debug.classloader=false
+-Forg.knopflerfish.framework.debug.startlevel=false
+-Forg.knopflerfish.framework.debug.ldap=false
+-Forg.knopflerfish.framework.debug.service_reference=false
+-Forg.knopflerfish.framework.debug.bundle_resource=false
+-Forg.knopflerfish.framework.debug.permissions=false
+-Forg.knopflerfish.framework.debug.lazy_activation=false
+-Forg.knopflerfish.framework.debug.framework=false
+-Forg.knopflerfish.framework.debug.certificates=false
+
+# JKSValidator properties
+-Forg.knopflerfish.framework.validator=JKSValidator
+-Forg.knopflerfish.framework.validator.jks.ca_certs=${user.dir}/test_jars/test.castore
+-Forg.knopflerfish.framework.validator.jks.ca_certs_password=catest
+
+# Avoid java verifier bug
+-Forg.knopflerfish.framework.bundlestorage.file.jar_verifier_bug=true
+
+# Comma-separated list of packges exported by system classloader
+-Forg.osgi.framework.system.packages.extra=
+
+# Web server properties
+-Forg.knopflerfish.http.dnslookup=false
+-Forg.osgi.service.http.port=0
+
+-Forg.knopflerfish.startlevel.use=true
+
+# Log service properties
+-Forg.knopflerfish.log.out=false
+-Forg.knopflerfish.log.level=info
+-Forg.knopflerfish.log.grabio=true
+-Forg.knopflerfish.log.file=true
+
+# bootdelegation
+# The test case FRAME163a requires boot delegation for javax.naming
+# to actually check that it works.
+-Forg.osgi.framework.bootdelegation=sun.*,javax.naming
+
+# Shall bc.getService(ServiceReference) return the service while it is
+# in the state unregistering or not.
+-Forg.knopflerfish.servicereference.valid.during.unregistering=true
+
+# Directory to store preferences in.
+-Forg.knopflerfish.prefs.dir=junit_grunt/prefs
+
+# Native code testing
+-Forg.osgi.framework.os.name=linux
+-Forg.osgi.framework.processor=arm_le
+
+-init
+
+-initlevel 1
+-install log/log_all-5.0.0.jar
+-install cm/cm_all-5.0.1.jar
+-install console/console_all-4.0.1.jar
+-install event/event_all-4.0.1.jar
+
+-initlevel 2
+-install util/util-4.1.0.jar
+-install jsdk/jsdk_api-2.5.0.kf3-2.jar
+-istart  junit/junit_all-3.8.1.kf4-001.jar
+-istart  kxml/kxml-2.3.0.kf4-001.jar
+
+-initlevel 4
+-install http/http_all-4.0.5.jar
+-install io/io_all-4.0.0.jar
+-install prefs/prefs_all-4.0.2.jar
+
+# the test cases
+-istart framework_test/framework_test-1.0.3.jar
+-istart filter_test/filter_test-1.0.0.jar
+-istart servicetracker_test/servicetracker_test-1.0.1.jar
+-istart constants_test/constants_test-1.0.0.jar
+-istart registryperformance_test/registryperformance_test-1.0.0.jar
+## eventadmin_tests are disabled because of timing problems on Linux!?
+#-istart eventadmin_test/eventadmin_test-1.0.0.jar
+-istart http_test/http_test-1.0.0.jar
+-istart io_test/io_test-1.0.0.jar
+-istart preferences_test/preferences_test-1.0.0.jar
+-istart startlevel_test/startlevel_test-1.0.0.jar
+-istart condpermadmin_test/condpermadmin_test-1.0.0.jar
+
+# packages required by component_test
+-start  log/log_all-5.0.0.jar
+-start  cm/cm_all-5.0.1.jar
+-istart component/component_all-5.0.3.jar
+-istart component_test/component_test-1.6.0.jar
+
+
+-startlevel 7
+
+-start  http/http_all-4.0.5.jar
+-start  event/event_all-4.0.1.jar
+-start  io/io_all-4.0.0.jar
+-start  prefs/prefs_all-4.0.2.jar
+
+-launch
+
+# the test case runner bundle.
+-istart junit_runner/junit_runner_all-4.0.0.jar
+
diff --git a/osgi/init-tests.xargs.in b/osgi/init-tests.xargs.in
new file mode 100644
index 0000000..df7946f
--- /dev/null
+++ b/osgi/init-tests.xargs.in
@@ -0,0 +1,127 @@
+#
+# Startup file for framework testing
+#
+
+# List of test IDs
+#-Forg.knopflerfish.junit_runner.tests=PerformanceRegistryTestSuite
+-Forg.knopflerfish.junit_runner.tests=filter:(objectclass=junit.framework.TestSuite)
+#-Forg.knopflerfish.junit_runner.tests=FrameworkTestSuite ServiceTrackerTestSuite ConstantsTestSuite FilterTestSuite
+
+
+-Forg.knopflerfish.bundle.perf.servicereg.nlisteners=100
+-Forg.knopflerfish.bundle.perf.servicereg.nservices=1000
+
+# true means "quit framework when all tests are run"
+-Forg.knopflerfish.junit_runner.quit=true
+
+# Initial startup verbosity, 0 is low verbosity
+-Dorg.knopflerfish.framework.main.verbosity=0
+
+# Prefix for searching for bundle URLs from console or command line
+-Dorg.knopflerfish.gosg.jars=$(GOSG_JARS)
+
+# Various debug flags
+-Forg.knopflerfish.framework.debug.resolver=false
+-Forg.knopflerfish.framework.debug.errors=false
+-Forg.knopflerfish.framework.debug.warnings=false
+-Forg.knopflerfish.framework.debug.classloader=false
+-Forg.knopflerfish.framework.debug.startlevel=false
+-Forg.knopflerfish.framework.debug.ldap=false
+-Forg.knopflerfish.framework.debug.service_reference=false
+-Forg.knopflerfish.framework.debug.bundle_resource=false
+-Forg.knopflerfish.framework.debug.permissions=false
+-Forg.knopflerfish.framework.debug.lazy_activation=false
+-Forg.knopflerfish.framework.debug.framework=false
+-Forg.knopflerfish.framework.debug.certificates=false
+
+# JKSValidator properties
+-Forg.knopflerfish.framework.validator=JKSValidator
+-Forg.knopflerfish.framework.validator.jks.ca_certs=$(TESTJARS)/test.castore
+-Forg.knopflerfish.framework.validator.jks.ca_certs_password=catest
+
+# Avoid java verifier bug
+-Forg.knopflerfish.framework.bundlestorage.file.jar_verifier_bug=true
+
+# Comma-separated list of packges exported by system classloader
+-Forg.osgi.framework.system.packages.extra=
+
+# Web server properties
+-Forg.knopflerfish.http.dnslookup=false
+-Forg.osgi.service.http.port=0
+
+-Forg.knopflerfish.startlevel.use=true
+
+# Log service properties
+-Forg.knopflerfish.log.out=false
+-Forg.knopflerfish.log.level=info
+-Forg.knopflerfish.log.grabio=true
+-Forg.knopflerfish.log.file=true
+
+# bootdelegation
+# The test case FRAME163a requires boot delegation for javax.naming
+# to actually check that it works.
+-Forg.osgi.framework.bootdelegation=sun.*,javax.naming
+
+# Shall bc.getService(ServiceReference) return the service while it is
+# in the state unregistering or not.
+-Forg.knopflerfish.servicereference.valid.during.unregistering=true
+
+# Directory to store preferences in.
+-Forg.knopflerfish.prefs.dir=junit_grunt/prefs
+
+# Native code testing
+-Forg.osgi.framework.os.name=linux
+-Forg.osgi.framework.processor=arm_le
+
+-init
+
+-initlevel 1
+-install @log_all-N.N.N.jar@
+-install @cm_all-N.N.N.jar@
+-install @console_all-N.N.N.jar@
+-install @event_all-N.N.N.jar@
+
+-initlevel 2
+-install @util-N.N.N.jar@
+-install @jsdk_api-N.N.N.jar@
+-istart  @junit_all-N.N.N.jar@
+-istart  @kxml-N.N.N.jar@
+
+-initlevel 4
+-install @http_all-N.N.N.jar@
+-install @io_all-N.N.N.jar@
+-install @prefs_all-N.N.N.jar@
+
+# the test cases
+-istart @framework_test-N.N.N.jar@
+-istart @filter_test-N.N.N.jar@
+-istart @servicetracker_test-N.N.N.jar@
+-istart @constants_test-N.N.N.jar@
+-istart @registryperformance_test-N.N.N.jar@
+## eventadmin_tests are disabled because of timing problems on Linux!?
+#-istart @eventadmin_test-N.N.N.jar@
+-istart @http_test-N.N.N.jar@
+-istart @io_test-N.N.N.jar@
+-istart @preferences_test-N.N.N.jar@
+-istart @startlevel_test-N.N.N.jar@
+$(DO_CPA_TEST)-istart @condpermadmin_test-N.N.N.jar@
+
+# packages required by component_test
+-start  @log_all-N.N.N.jar@
+-start  @cm_all-N.N.N.jar@
+-istart @component_all-N.N.N.jar@
+-istart @component_test-N.N.N.jar@
+
+
+-startlevel 7
+
+-start  @http_all-N.N.N.jar@
+-start  @event_all-N.N.N.jar@
+-start  @io_all-N.N.N.jar@
+-start  @prefs_all-N.N.N.jar@
+
+-launch
+
+# the test case runner bundle.
+-istart @junit_runner_all-N.N.N.jar@
+
diff --git a/osgi/init.xargs b/osgi/init.xargs
new file mode 100644
index 0000000..f433dba
--- /dev/null
+++ b/osgi/init.xargs
@@ -0,0 +1,99 @@
+#
+# Generated from template.xargs
+# Knopflerfish release 5.1.0
+#
+
+# load common properties
+-xargs props.xargs
+
+# Semicolon seprated list of base URLs for searching (completing)
+# bundle URLs in "-install URL" command line options and in the console.
+-Forg.knopflerfish.gosg.jars=file:jars/
+
+# Comma seprated list of OSGi Repository xml URLs for instantiating 
+# RepositoryServices
+-Forg.knopflerfish.repository.xml.urls=file:jars/index.xml,      http://www.knopflerfish.org/releases/current/osgi/jars/index.xml
+
+## Basic KF bundles
+-initlevel 1
+-install log/log_all-5.0.0.jar
+-install cm/cm_all-5.0.1.jar
+-install console/console_all-4.0.1.jar
+-install component/component_all-5.0.3.jar
+-install event/event_all-4.0.1.jar
+-install prefs/prefs_all-4.0.2.jar
+-istart trayicon_fw/trayicon_fw-4.0.0.jar
+
+## Some library bundles
+-initlevel 2
+-install util/util-4.1.0.jar
+-install crimson/crimson-2.1.0.kf4-001.jar
+-install jsdk/jsdk_api-2.5.0.kf3-2.jar
+-install kxml/kxml-2.3.0.kf4-001.jar
+
+# The Bundle repo commands and desktop plugin
+-install repository_xml/repository_xml_all-1.0.2.jar
+-install repositorymanager/repositorymanager_all-1.2.0.jar
+-install repository_desktop/repository_desktop_all-1.1.1.jar
+
+## More basic KF bundles
+-initlevel 3
+-install device/device_all-4.0.1.jar
+-install useradmin/useradmin_all-4.1.1.jar
+
+-initlevel 4
+-install http/http_all-4.0.5.jar
+
+## console command bundles
+-initlevel 5
+-install frameworkcommands/frameworkcommands-4.0.1.jar
+-install logcommands/logcommands-5.0.0.jar
+-install cm_cmd/cm_cmd-5.0.1.jar
+-install repositorycommands/repositorycommands-1.1.1.jar
+-install scrcommands/scrcommands-4.0.1.jar
+
+-install consoletty/consoletty-4.0.1.jar
+
+-install consoletelnet/consoletelnet-4.0.1.jar
+
+-initlevel 6
+-install remotefw/remotefw_api-4.0.0.jar
+-install desktop/desktop_all-5.0.1.jar
+
+
+-initlevel 7
+-install httproot/httproot-4.0.0.jar
+
+
+
+-startlevel 7
+
+
+# Start of these bundles are delayed since this makes start
+# order dependencies much easier
+
+-start log/log_all-5.0.0.jar
+-start crimson/crimson-2.1.0.kf4-001.jar
+-start cm/cm_all-5.0.1.jar
+-start console/console_all-4.0.1.jar
+-start component/component_all-5.0.3.jar
+-start event/event_all-4.0.1.jar
+-start prefs/prefs_all-4.0.2.jar
+-start device/device_all-4.0.1.jar
+-start useradmin/useradmin_all-4.1.1.jar
+-start repository_xml/repository_xml_all-1.0.2.jar
+-start repositorymanager/repositorymanager_all-1.2.0.jar
+-start repository_desktop/repository_desktop_all-1.1.1.jar
+-start consoletty/consoletty-4.0.1.jar
+-start consoletelnet/consoletelnet-4.0.1.jar
+-start frameworkcommands/frameworkcommands-4.0.1.jar
+-start logcommands/logcommands-5.0.0.jar
+-start cm_cmd/cm_cmd-5.0.1.jar
+-start repositorycommands/repositorycommands-1.1.1.jar
+-start scrcommands/scrcommands-4.0.1.jar
+-start desktop/desktop_all-5.0.1.jar
+-start http/http_all-4.0.5.jar
+-start httproot/httproot-4.0.0.jar
+
+# Uncomment the following line to add Resolver support
+# -istart http://repo2.maven.org/maven2/org/apache/felix/org.apache.felix.resolver/1.0.0/org.apache.felix.resolver-1.0.0.jar
diff --git a/osgi/kf2 b/osgi/kf2
new file mode 100644
index 0000000..ecbfc48
--- /dev/null
+++ b/osgi/kf2
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+JAVA=java 					# the default java command
+BOOTCLASSPATH_FLAG="-Xbootclasspath/a:"		# the bootclass path flag for the specific
+CLASSPATH_FLAG="-classpath "			# the class path flag for the specific
+
+# constants
+KF_MAIN_CLASS=org.knopflerfish.framework.Main	   # path to main class
+if [ -f framework.jar ] ; then
+    KF_CLASSPATH=framework.jar					   # the class path to use 
+else
+    KF_CLASSPATH=framework_compact.jar			   # the class path to use 
+fi
+
+# args always sent to the JRE
+KF_JRE_ARGS="-Dorg.knopflerfish.framework.usingwrapperscript=true"
+
+EXIT_CODE_RESTART=200				
+
+# Read all the args.
+args_orig="" 		# all -xargs and -init args
+args=""     		# like args excepts for -xargs and -init args
+jre_args="" 		# arguments for the jre
+fwdir="`pwd`/fwdir"	# default framework dir
+init=0			# whether the -init flag has been given or not.
+
+# read the arguments
+while [ -n "$1" ] 
+do
+  case "$1" in
+      "-init"  ) init=1; args_orig=$args_orig" "$1;;
+      "-xargs" ) shift; args_orig=$args_orig" -xargs "$1;;
+      "--" ) shift; break;;
+      "---" ) break;;
+      * ) args=$args" "$1;;
+  esac
+  shift
+done
+# the rest is jre-specific args
+while [ -n "$1" ]
+do
+  case "$1" in
+      "-Dorg.osgi.framework.dir="* ) fwdir=`echo $1 | cut -c26-`;; # store fwdir.
+      "---" ) shift; break ;;
+  esac
+  jre_args=$jre_args" "$1
+  shift
+done
+
+# command line options
+while [ -n "$1" ] 
+do
+  case "$1" in
+      "-java" )  shift; JAVA="$1" ;;
+      "-clean" ) shift; CLEAN_FWDIR=1 ;;
+      "-classpathflag" ) shift; CLASSPATH_FLAG="$1" ;; 	# *	
+      "-bootclasspathflag" ) shift ; BOOTCLASSPATH_FLAG="$1" ;;
+      * ) echo "Error: unknown option: $1"
+          echo "Use option -help to see all options"
+          exit 1 ;;
+  esac
+  shift 
+done
+# *: are these needed? or are they standard?
+
+
+if [ $init = 1 ] ; then
+
+    if [ -d $fwdir ] ; then
+        rm -rf $fwdir 
+        
+        if [ $? = 0 ] ; then
+            echo "Removed existing fwdir $fwdir"
+        else 
+            echo "Failed to remove existing fwdir $fwdir"
+        fi
+    fi
+        
+fi
+
+retval=$EXIT_CODE_RESTART
+while [ "$retval" -eq $EXIT_CODE_RESTART ]
+do
+  if [ -r $fwdir/boot_cp ] ; then
+      bootclasspath=$BOOTCLASSPATH_FLAG`cat $fwdir/boot_cp`
+  fi
+  classpath=$CLASSPATH_FLAG$KF_CLASSPATH:$CLASSPATH
+  $JAVA $bootclasspath $jre_args $KF_JRE_ARGS $classpath $KF_MAIN_CLASS $args_orig $args
+  retval=$?
+  # only use args_orig the first time
+  args_orig=
+done
+
+exit $retval
diff --git a/osgi/minimal.xargs b/osgi/minimal.xargs
new file mode 100644
index 0000000..ef1faa1
--- /dev/null
+++ b/osgi/minimal.xargs
@@ -0,0 +1,22 @@
+-Dorg.knopflerfish.framework.main.verbosity=0
+-Dorg.knopflerfish.gosg.jars=file:jars/
+-Forg.knopflerfish.framework.debug.resolver=false
+-Forg.knopflerfish.framework.debug.errors=true
+-Forg.knopflerfish.framework.debug.classloader=false
+-Forg.osgi.framework.system.packages.extra=
+
+-Forg.knopflerfish.startlevel.use=true
+
+-init
+
+-install log/log_api-5.0.0.jar
+-install console/console_api-4.0.1.jar
+-istart  cm/cm_api-5.0.1.jar
+-istart  log/log-5.0.0.jar
+-istart  console/console-4.0.1.jar
+-istart  consoletty/consoletty-4.0.1.jar
+-istart  frameworkcommands/frameworkcommands-4.0.1.jar
+-istart  logcommands/logcommands-5.0.0.jar
+-istart  useradmin/useradmin_api-4.1.1.jar
+
+-launch
diff --git a/osgi/minimal.xargs.in b/osgi/minimal.xargs.in
new file mode 100644
index 0000000..c0d9f7d
--- /dev/null
+++ b/osgi/minimal.xargs.in
@@ -0,0 +1,22 @@
+-Dorg.knopflerfish.framework.main.verbosity=0
+-Dorg.knopflerfish.gosg.jars=$(GOSG_JARS)
+-Forg.knopflerfish.framework.debug.resolver=false
+-Forg.knopflerfish.framework.debug.errors=true
+-Forg.knopflerfish.framework.debug.classloader=false
+-Forg.osgi.framework.system.packages.extra=
+
+-Forg.knopflerfish.startlevel.use=true
+
+-init
+
+-install @log_api-N.N.N.jar@
+-install @console_api-N.N.N.jar@
+-istart  @cm_api-N.N.N.jar@
+-istart  @log-N.N.N.jar@
+-istart  @console-N.N.N.jar@
+-istart  @consoletty-N.N.N.jar@
+-istart  @frameworkcommands-N.N.N.jar@
+-istart  @logcommands-N.N.N.jar@
+-istart  @useradmin_api-N.N.N.jar@
+
+-launch
diff --git a/osgi/props.xargs b/osgi/props.xargs
new file mode 100644
index 0000000..0ddb68a
--- /dev/null
+++ b/osgi/props.xargs
@@ -0,0 +1,91 @@
+#
+# Common properties used by different init.xargs files
+#
+
+#-Forg.osgi.framework.storage=fwdir
+
+# The Service Platform ID should be used by bundles needing to
+# a unique ID for the platform itself
+-Forg.osgi.provisioning.spid=knopflerfish
+
+# Initial startup verbosity, 0 is low verbosity
+#-Forg.knopflerfish.framework.main.verbosity=0
+
+# Security
+#-Forg.osgi.framework.security=osgi
+#-Forg.knopflerfish.framework.all_signed=false
+#-Forg.knopflerfish.framework.validator=JKSValidator
+
+# File storage properties
+#-Forg.knopflerfish.framework.bundlestorage.file.trusted=false
+#-Forg.knopflerfish.framework.bundlestorage.file.unpack=false
+#-Forg.knopflerfish.framework.bundlestorage.file.always_unpack=true
+-Forg.knopflerfish.framework.bundlestorage.file.reference=true
+
+# JKSValidator properties (JVM default if not set).
+#-Forg.knopflerfish.framework.validator.jks.ca_certs=
+#-Forg.knopflerfish.framework.validator.jks.ca_certs_password=
+
+# Avoid java verifier bug
+#-Forg.knopflerfish.framework.bundlestorage.file.jar_verifier_bug=true
+
+# Various debug flags
+#-Forg.knopflerfish.framework.debug.resolver=true
+-Forg.knopflerfish.framework.debug.errors=true
+#-Forg.knopflerfish.framework.debug.warnings=true
+#-Forg.knopflerfish.framework.debug.classloader=true
+#-Forg.knopflerfish.framework.debug.startlevel=true
+#-Forg.knopflerfish.framework.debug.ldap=true
+#-Forg.knopflerfish.framework.debug.service_reference=true
+#-Forg.knopflerfish.framework.debug.bundle_resource=true
+#-Forg.knopflerfish.framework.debug.permissions=true
+#-Forg.knopflerfish.framework.debug.lazy_activation=true
+#-Forg.knopflerfish.framework.debug.framework=true
+#-Forg.knopflerfish.framework.debug.certificates=true
+
+# Complete comma-separated list of packages exported by the system bundle
+# 
+#-Forg.osgi.framework.system.packages=
+
+# Comma-separated list of packages exported by the system bundle. The
+# osgi packages provided by the framework will be added to this list.
+# Only used when org.osgi.framework.system.packages is not set.
+#
+#-Forg.knopflerfish.framework.system.packages.base=javax.swing,javax.swing.tree, javax.swing.table, javax.swing.plaf.metal, javax.swing.plaf.basic, javax.swing.plaf, javax.swing.filechooser, javax.swing.event, javax.swing.border, javax.accessibility
+
+# Comma-separated list of packages to be added to the set of packages
+# exported by the system bundle.
+#
+#-Forg.osgi.framework.system.packages.extra=
+
+# Comma-separated list of packages that must be loaded by system classloader
+#
+#-Forg.osgi.framework.bootdelegation=*
+
+# If set to true, use strict rules for loading classes from the boot
+# class loader.
+# If false, accept class loading from the boot class path from classes
+# themselves on the boot class.
+# Default is false
+#
+#-Forg.knopflerfish.framework.strictbootclassloading=false
+
+# If set to true, export all framework properties as system properties.
+#
+#-Forg.knopflerfish.framework.main.xargs.writesysprops=false
+
+# Web server properties
+-Forg.knopflerfish.http.dnslookup=false
+-Forg.osgi.service.http.port=8080
+
+# Log service properties
+-Forg.knopflerfish.log.out=false
+-Forg.knopflerfish.log.level=info
+-Forg.knopflerfish.log.grabio=true
+-Forg.knopflerfish.log.file=true
+-Forg.knopflerfish.log.memory.size=250
+
+#consoletelnet properties
+-Forg.knopflerfish.consoletelnet.user=admin
+-Forg.knopflerfish.consoletelnet.pwd=admin
+-Forg.knopflerfish.consoletelnet.port=2323
diff --git a/osgi/remote-init.xargs b/osgi/remote-init.xargs
new file mode 100644
index 0000000..4a4d794
--- /dev/null
+++ b/osgi/remote-init.xargs
@@ -0,0 +1,99 @@
+#
+# Generated from template.xargs
+# Knopflerfish release 5.1.0
+#
+
+# load common properties
+-xargs props.xargs
+
+# Semicolon seprated list of base URLs for searching (completing)
+# bundle URLs in "-install URL" command line options and in the console.
+-Forg.knopflerfish.gosg.jars=http://www.knopflerfish.org/releases/5.1.0/osgi/jars/
+
+# Comma seprated list of OSGi Repository xml URLs for instantiating 
+# RepositoryServices
+-Forg.knopflerfish.repository.xml.urls=file:jars/index.xml,      http://www.knopflerfish.org/releases/current/osgi/jars/index.xml
+
+## Basic KF bundles
+-initlevel 1
+-install log/log_all-5.0.0.jar
+-install cm/cm_all-5.0.1.jar
+-install console/console_all-4.0.1.jar
+-install component/component_all-5.0.3.jar
+-install event/event_all-4.0.1.jar
+-install prefs/prefs_all-4.0.2.jar
+-istart trayicon_fw/trayicon_fw-4.0.0.jar
+
+## Some library bundles
+-initlevel 2
+-install util/util-4.1.0.jar
+-install crimson/crimson-2.1.0.kf4-001.jar
+-install jsdk/jsdk_api-2.5.0.kf3-2.jar
+-install kxml/kxml-2.3.0.kf4-001.jar
+
+# The Bundle repo commands and desktop plugin
+-install repository_xml/repository_xml_all-1.0.2.jar
+-install repositorymanager/repositorymanager_all-1.2.0.jar
+-install repository_desktop/repository_desktop_all-1.1.1.jar
+
+## More basic KF bundles
+-initlevel 3
+-install device/device_all-4.0.1.jar
+-install useradmin/useradmin_all-4.1.1.jar
+
+-initlevel 4
+-install http/http_all-4.0.5.jar
+
+## console command bundles
+-initlevel 5
+-install frameworkcommands/frameworkcommands-4.0.1.jar
+-install logcommands/logcommands-5.0.0.jar
+-install cm_cmd/cm_cmd-5.0.1.jar
+-install repositorycommands/repositorycommands-1.1.1.jar
+-install scrcommands/scrcommands-4.0.1.jar
+
+-install consoletty/consoletty-4.0.1.jar
+
+-install consoletelnet/consoletelnet-4.0.1.jar
+
+-initlevel 6
+-install remotefw/remotefw_api-4.0.0.jar
+-install desktop/desktop_all-5.0.1.jar
+
+
+-initlevel 7
+-install httproot/httproot-4.0.0.jar
+
+
+
+-startlevel 7
+
+
+# Start of these bundles are delayed since this makes start
+# order dependencies much easier
+
+-start log/log_all-5.0.0.jar
+-start crimson/crimson-2.1.0.kf4-001.jar
+-start cm/cm_all-5.0.1.jar
+-start console/console_all-4.0.1.jar
+-start component/component_all-5.0.3.jar
+-start event/event_all-4.0.1.jar
+-start prefs/prefs_all-4.0.2.jar
+-start device/device_all-4.0.1.jar
+-start useradmin/useradmin_all-4.1.1.jar
+-start repository_xml/repository_xml_all-1.0.2.jar
+-start repositorymanager/repositorymanager_all-1.2.0.jar
+-start repository_desktop/repository_desktop_all-1.1.1.jar
+-start consoletty/consoletty-4.0.1.jar
+-start consoletelnet/consoletelnet-4.0.1.jar
+-start frameworkcommands/frameworkcommands-4.0.1.jar
+-start logcommands/logcommands-5.0.0.jar
+-start cm_cmd/cm_cmd-5.0.1.jar
+-start repositorycommands/repositorycommands-1.1.1.jar
+-start scrcommands/scrcommands-4.0.1.jar
+-start desktop/desktop_all-5.0.1.jar
+-start http/http_all-4.0.5.jar
+-start httproot/httproot-4.0.0.jar
+
+# Uncomment the following line to add Resolver support
+# -istart http://repo2.maven.org/maven2/org/apache/felix/org.apache.felix.resolver/1.0.0/org.apache.felix.resolver-1.0.0.jar
diff --git a/osgi/template.xargs.in b/osgi/template.xargs.in
new file mode 100644
index 0000000..0dcab67
--- /dev/null
+++ b/osgi/template.xargs.in
@@ -0,0 +1,99 @@
+#
+# Generated from template.xargs
+# Knopflerfish release $(VERSION)
+#
+
+# load common properties
+-xargs props.xargs
+
+# Semicolon seprated list of base URLs for searching (completing)
+# bundle URLs in "-install URL" command line options and in the console.
+-Forg.knopflerfish.gosg.jars=$(GOSG_JARS)
+
+# Comma seprated list of OSGi Repository xml URLs for instantiating 
+# RepositoryServices
+-Forg.knopflerfish.repository.xml.urls=$(REPOSITORY_XML_URLS)
+
+## Basic KF bundles
+-initlevel 1
+-install @log_all-N.N.N.jar@
+-install @cm_all-N.N.N.jar@
+-install @console_all-N.N.N.jar@
+-install @component_all-N.N.N.jar@
+-install @event_all-N.N.N.jar@
+-install @prefs_all-N.N.N.jar@
+$(AWT)-istart @trayicon_fw-N.N.N.jar@
+
+## Some library bundles
+-initlevel 2
+-install @util-N.N.N.jar@
+-install @crimson-N.N.N.jar@
+-install @jsdk_api-N.N.N.jar@
+-install @kxml-N.N.N.jar@
+
+# The Bundle repo commands and desktop plugin
+-install @repository_xml_all-N.N.N.jar@
+-install @repositorymanager_all-N.N.N.jar@
+$(AWT)-install @repository_desktop_all-N.N.N.jar@
+
+## More basic KF bundles
+-initlevel 3
+-install @device_all-N.N.N.jar@
+-install @useradmin_all-N.N.N.jar@
+
+-initlevel 4
+-install @http_all-N.N.N.jar@
+
+## console command bundles
+-initlevel 5
+-install @frameworkcommands-N.N.N.jar@
+-install @logcommands-N.N.N.jar@
+-install @cm_cmd-N.N.N.jar@
+-install @repositorycommands-N.N.N.jar@
+-install @scrcommands-N.N.N.jar@
+
+-install @consoletty-N.N.N.jar@
+
+-install @consoletelnet-N.N.N.jar@
+
+-initlevel 6
+$(AWT)-install @remotefw_api-N.N.N.jar@
+$(AWT)-install @desktop_all-N.N.N.jar@
+
+
+-initlevel 7
+-install @httproot-N.N.N.jar@
+
+$(OS_ARGS)
+
+-startlevel 7
+
+
+# Start of these bundles are delayed since this makes start
+# order dependencies much easier
+
+-start @log_all-N.N.N.jar@
+-start @crimson-N.N.N.jar@
+-start @cm_all-N.N.N.jar@
+-start @console_all-N.N.N.jar@
+-start @component_all-N.N.N.jar@
+-start @event_all-N.N.N.jar@
+-start @prefs_all-N.N.N.jar@
+-start @device_all-N.N.N.jar@
+-start @useradmin_all-N.N.N.jar@
+-start @repository_xml_all-N.N.N.jar@
+-start @repositorymanager_all-N.N.N.jar@
+$(AWT)-start @repository_desktop_all-N.N.N.jar@
+-start @consoletty-N.N.N.jar@
+-start @consoletelnet-N.N.N.jar@
+-start @frameworkcommands-N.N.N.jar@
+-start @logcommands-N.N.N.jar@
+-start @cm_cmd-N.N.N.jar@
+-start @repositorycommands-N.N.N.jar@
+-start @scrcommands-N.N.N.jar@
+$(AWT)-start @desktop_all-N.N.N.jar@
+-start @http_all-N.N.N.jar@
+-start @httproot-N.N.N.jar@
+
+# Uncomment the following line to add Resolver support
+# -istart http://repo2.maven.org/maven2/org/apache/felix/org.apache.felix.resolver/1.0.0/org.apache.felix.resolver-1.0.0.jar
diff --git a/osgi/test-restart1.xargs b/osgi/test-restart1.xargs
new file mode 100644
index 0000000..2116ed1
--- /dev/null
+++ b/osgi/test-restart1.xargs
@@ -0,0 +1,34 @@
+#
+# Startup file for framework restart testing
+#
+# NOTE: The base URLs for bundles assumes that the current working
+#       directory is the osgi-direcotry when this xargs-file is used.
+#
+
+# List of test IDs
+-Forg.knopflerfish.junit_runner.tests=RestartSetupTestSuite
+
+# true means "quit framework when all tests are run"
+-Forg.knopflerfish.junit_runner.quit=true
+
+# true means wait for complete framework start until run
+-Forg.knopflerfish.junit_runner.wait=true
+
+-Dorg.knopflerfish.gosg.jars=file:jars/;file:test_jars/
+
+-init
+
+-initlevel 1
+-istart junit/junit_all-3.8.1.kf4-001.jar
+
+# the test cases
+-initlevel 5
+-istart restart_test/restart_test-1.0.0.jar
+
+# the test case runner bundle.
+-initlevel 20
+-istart junit_runner/junit_runner_all-4.0.0.jar
+
+-startlevel 20
+
+-launch
diff --git a/osgi/test-restart2.xargs b/osgi/test-restart2.xargs
new file mode 100644
index 0000000..9d8d287
--- /dev/null
+++ b/osgi/test-restart2.xargs
@@ -0,0 +1,19 @@
+#
+# Restart file for framework restart testing
+#
+# NOTE: The base URLs for bundles assumes that the current working
+#       directory is the osgi-direcotry when this xargs-file is used.
+#
+
+# List of test IDs
+-Forg.knopflerfish.junit_runner.tests=RestartTestSuite
+
+# true means "quit framework when all tests are run"
+-Forg.knopflerfish.junit_runner.quit=true
+
+# true means wait for complete framework start until run
+-Forg.knopflerfish.junit_runner.wait=false
+
+-Dorg.knopflerfish.gosg.jars=file:jars/;file:test_jars/
+
+-launch
diff --git a/release_notes.html b/release_notes.html
new file mode 100644
index 0000000..aaaec51
--- /dev/null
+++ b/release_notes.html
@@ -0,0 +1,380 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+
+<!-- This is a generated file. Do not edit. Built by jan on Fri June 13 2014, 08:33:03 -->
+
+<html>
+
+  <head>
+    <meta http-equiv = "Content-Type"
+	  content    = "text/html; charset=ISO-8859-1"/>
+    
+    <meta http-equiv = "CACHE-CONTROL"
+	  content    = "NO-CACHE"/>
+
+    <meta name       = "description"
+	  content    = "Release notes for Knopflerfish OSGi, version 5.1.0 - "/>
+    
+    <meta name       = "title"
+	  content    = "Knopflerfish OSGi, version 5.1.0 -  Release Notes"/>
+
+    <title>Knopflerfish OSGi, version 5.1.0 -  Release Notes</title>
+
+    <style>
+BODY  {
+  background: #ccc;
+}
+
+#main {
+  width: 1000; 
+  background: #fff;
+  border:		1px solid #000;
+  margin: 0px auto;
+  font-family: Lucida Grande, Tahoma, Helvetica, sans-serif;
+  padding: 0px 0px 0px 0px;
+}
+
+#mainblock {
+  margin-left: 20px; 
+  padding-right: 15px;
+  font-family: "Lucida Grande", Tahoma, Lucida Sans, Verdana, Helvetica, sans-serif;
+  font-size: 12.8px;
+}
+
+#footer {
+  clear:both;
+  border-style: solid;
+  border-color: #802060;
+  border-width: 1px 0px 0px 0px;
+  margin:	20px 15px 15px 15px;
+}
+
+#copyright {
+  margin-left: 200px;
+  font-size:10px;
+  color: #000;
+  text-align: right;
+  padding: 5px 10px 0px 0px;
+}	  
+
+H1, H1.kf {
+    font-family: Helvetica Neue, Helvetica, Verdana, Arial, Helvetica, sans-serif;
+    font-size: 2em;
+    font-weight:bold;
+    border-style: solid;
+    border-color: #802060;
+    border-width: 0px 0px 1px 0px;
+    padding-bottom: 2px;
+    margin: 2.0em 0 0.6em 0;
+    color: #444444;
+}
+
+H2.kf  {
+    font-family: Lucida Grande, Verdana, Arial, Helvetica, sans-serif;
+    font-size:	1.3em;
+    font-weight:bold;
+    border-style: solid;
+    color:		#444444;
+    border-style:  solid;
+    border-color:	#ccc;
+    border-width:	1px 0px 1px 0px;
+    background-image: url('../images/shortfadeout_20px.png');
+    background-repeat: repeat-x;
+    padding:	3px 0px 3px 6px;
+    margin: 1.4em 0 0.8em 0;
+}
+
+.note_group {
+    margin: 1.5em 0 0.5em 0;
+}
+
+.note_name {
+    font-weight: bold;
+    color:#333333;
+}
+
+.note_item {
+    display: list-item;
+    margin: 0.5em 0 0.5em 2em;
+}
+a {
+    color:#111111;
+    text-decoration:none;
+}
+    </style>
+
+  </head>
+
+
+  <body>
+    <div id="main">
+      <div id="mainblock">
+	<!-- The first line in this file is used by the desktop to check -->
+<!-- for new releases, i.e., do not change its format.           -->
+<!-- It must contain the word "Knopflerfish" followed by a space -->
+<!-- and then the version followed by another space.             -->
+
+<h1 class="kf">Release Notes Knopflerfish 5.1.0 (OSGi R5)</h1>
+<p>
+
+  Maintenance release of Knopflerfish 5 available from
+  http://www.knopflerfish.org/releases/5.1.0. Released 2014-06-13.
+
+</p>
+<p>
+
+  Knopflerfish 5 is an implementation of the "OSGi Service Platform
+  Release 5". It contains all services specified in the "Core
+  Specification" and most of the non Enterprise Edition related
+  services specified in the "Compendium Specification".
+
+</p>
+
+<p>
+
+  The Release Notes include all new features & changes for
+  Knopflerfish 5.1.0 compared to the release of Knopflerfish
+  5.0.0.
+
+</p>
+
+<h2 class="filled">Knopflerfish Framework - OSGi Core Specification</h2>
+<div class="release_notes">
+
+  <div class="note_group">
+    <div class="note_name">Framework 7.1.2</div>
+    <div class="note_item">
+    Fixed framework restart problem introduced in 7.1.0.
+    </div>
+    <div class="note_item">
+    Relaxed "org.knopflerfish.framework.validator.date" parsing, so that
+    it tries short US locale pattern if default locale parsing fails.
+    </div>
+
+    <div class="note_name">Framework 7.1.1</div>
+    <div class="note_item">
+    Fixed exception when doing BundleWiring.listResources on root directory.
+    </div>
+
+    <div class="note_name">Framework 7.1.0</div>
+    <div class="note_item">
+    Added new URL protocol "fwresource" to access resources from the framework
+    classloader.
+    </div>
+    <div class="note_item">
+    The start class org.knopflerfish.framework.Main now tries to load xargs as a
+    framework resource if the file is not found. This means that we together
+    with the new fwresource protocol can create a single jar that contains the
+    framework, all jars and xargs files that needs to start a complete application.
+    </div>
+    <div class="note_item">
+    Added property "org.knopflerfish.framework.readonly", that puts framework
+    in a read only mode. This means that framework will not write any files
+    in "fwdir". This means that if we are running with the default "file"
+    bundle storage then new bundles must be installed as a referenced file URL.
+    This also implies that no data storage will be available to bundles.
+    </div>
+
+    <div class="note_name">Framework 7.0.2</div>
+    <div class="note_item">
+    Fixed bug that caused IndexOutOfBoundsException when updating large
+    collections of ConditionalPermissionInfos using ConditionalPermissionUpdate.
+    </div>
+    <div class="note_item">
+    Added property "org.knopflerfish.framework.validator.date" to framework
+    for testing certification validation with different dates.
+    </div>
+  </div>
+
+</div>
+
+
+<h2 class="filled">OSGi Compendium Specification</h2>
+<div class="release_notes">
+
+  <div class="note_group">
+    <div class="note_name">UserAdmin 4.1.1</div>
+    <div class="note_item">
+    Now contains and imports/exports org.knopflerfish.service.log
+    in order to be self-contained.
+    </div>
+    <div class="note_item">
+      Changed to use the OSGi defined Bundle-Icon instead of
+      Application-Icon.
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">KF-XML-Metatype 5.0.1</div>
+    <div class="note_item">
+    Fixed bug in handling of designate-element that could cause
+    configurations to be created, deleted or overwritten
+    unintentionally.
+    Refactored handling of standardized OSGi metatype xml and
+    legacy proprietary meta type xml into separate classes.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">CM 5.0.1</div>
+    <div class="note_item">
+    Improved the persistent storage of CM data,
+    made it more robust and fault resilient. 
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">HTTP-Server 4.0.5</div>
+    <div class="note_item">
+    Fixed another bug in the handling of chunked transfer encoding in the
+    Request implementation. The last chunk (with size 0) is not followed
+    by any chunk-data and thus there is no CRLF to consume.
+    </div>
+
+    <div class="note_name">HTTP-Server 4.0.4</div>
+    <div class="note_item">
+    Fixed another bug in the handling of chunked transfer encoding in the
+    Request implementation. A chunk contianing a charter followed by a
+    new line char was not correctly un-chunked.
+    </div>
+
+    <div class="note_name">HTTP-Server 4.0.3</div>
+    <div class="note_item">
+    Fixed a bug in the handling of chunked transfer encoding in the
+    Request implementation. An extra CR-LF was incorrectly added to
+    the end of the decoded data, causing problems when transfering
+    binary data like a zip-file.
+    </div>
+  </div>  
+  
+  <div class="note_group">
+    <div class="note_name">Prefs 4.0.2</div>
+    <div class="note_item">
+      Added bundle icon.
+    </div>
+  </div>
+
+  <div class="note_group">
+    <div class="note_name">Repository XML 1.0.2</div>
+    <div class="note_item">
+    Fixed a bug in RequirementImpl and did some clean up.
+    </div>
+
+    <div class="note_name">Repository XML 1.0.1</div>
+    <div class="note_item">
+    Fixed a bug in CapabilityImpl.
+    </div>
+  </div>
+
+  <div class="note_group">
+    <div class="note_name">SCR(component) 5.0.3</div>
+    <div class="note_item">
+    Fixed missed factory component check in previous version. This miss caused
+    following error:<p/>
+    java.lang.IllegalStateException: Internal error! Factory component only created with newInstance
+    </div>
+
+    <div class="note_name">SCR(component) 5.0.2</div>
+    <div class="note_item">
+    Fixed a bug that caused factory components to be falsely created or
+    missed being created when we use target filters.
+    </div>
+
+    <div class="note_name">SCR(component) 5.0.1</div>
+    <div class="note_item">
+    Fixed a bug that caused problems when adding a CM configuration with
+    a target filter to an unsatisfied component.
+    </div>
+  </div>
+  
+</div>
+
+<h2 class="filled">Knopflerfish Services</h2>
+<div class="release_notes">
+
+   <div class="note_group">
+    <div class="note_name">CM Desktop 5.0.2</div>
+    <div class="note_item">
+    Add requirement for the Meta Type Service.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">KF Resource Analyzer Extensions 1.0.1</div>
+    <div class="note_item">
+    Added proper handling of Bundle-License according to osgi.identity
+    namepsace.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">Repository Commands 1.1.1</div>
+    <div class="note_item">
+    Bug fixes and some refactorings.
+    </div>
+
+    <div class="note_name">Repository Commands 1.1.0</div>
+    <div class="note_item">
+    Added [-r] flag to install command that tries to automatically find and
+    install dependencies along with the specified bundle by using new
+    methods in Repository Manager.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">Repository Desktop 1.1.1</div>
+    <div class="note_item">
+    The dialogue now gives information about exactly what will be installed when asking if a
+    Resolver should be used.
+    </div>
+
+    <div class="note_name">Repository Desktop 1.1.0</div>
+    <div class="note_item">
+    Added support for new methods in Repository Manager to use a Resolver
+    service when available.
+    </div>
+  </div>
+  
+  <div class="note_group">
+    <div class="note_name">Repository Manager 1.2.0</div>
+    <div class="note_item">
+    Added install and resolverAvailable methods to RepositoryManager interface.
+    Embedded Resolver and Repository APIs.
+    </div>
+
+    <div class="note_name">Repository Manager 1.1.0</div>
+    <div class="note_item">
+    Added support for Resolver services and added RepositoryManager.findResolution method.
+    </div>
+  </div>
+
+  <div class="note_group">
+    <div class="note_name">KF-XML-Metatype 5.0.2</div>
+    <div class="note_item">
+    Only build an "all" variant. This makes it possible to correctly install
+    CM-Desktop using the Repository Desktop with the Felix resolver.
+    </div>
+  </div>
+
+</div>
+
+
+<h2 class="filled">Misc, start scripts, build system etc </h2>
+<div class="release_notes">
+
+   <div class="note_group">
+    <div class="note_name">init.xargs</div>
+    <div class="note_item">Added commented out line to install Resolver
+    reference implementation.
+    </div>
+  </div>
+
+</div>
+
+      </div>
+      <div id="footer">
+	<div id="copyright">
+	  Copyright © 2008-2014 The Knopflerfish Project. All rights reserved.
+	</div>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/strings.properties b/strings.properties
new file mode 100644
index 0000000..2ccf1ec
--- /dev/null
+++ b/strings.properties
@@ -0,0 +1,66 @@
+frame_title=Knopflerfish OSGi $(1) installation
+
+page_license_title=Knopflerfish OSGi License
+page_installdir_title=Select installation directory
+page_finish_title=Installing Knopflerfish OSGi
+
+cancel=Cancel
+yes=Yes	
+no=No
+ok=OK
+select=Select
+finish=Finish
+back=Back <<
+forward=Next >>
+browse=Browse...
+
+tt_browse_file=Browse for file
+tt_browse_dir=Browse for directory
+title_select_dir=Browse for directory
+title_select_file=Browse for file
+
+cb_open_dir=Open OSGi directory when done
+
+license_res_name=/license.html
+
+fmt_install_info=<font size\=-1 face\=\"$(3)\">Total installation requires about $(1).\
+<p>\
+The framework can be started by running \
+<tt>framework.jar</tt> in <font size\=-2>$(2)$(sep)osgi</font>\
+<p>\
+It can also be started from a command prompt in that directory by typing<br>\
+<tt>  java -jar framework.jar</tt></font>
+
+
+replace_array4=Yes,"Yes to all",No,Cancel
+
+title_replace_dir=Overwrite directory?
+
+q_replace_dir=\
+The destination folder '$(name)' already exists.\n\
+\n\
+Overwrite directory?
+
+title_replace_file=Replace file?
+
+destfolder_contains=The destination folder already contains a file '$(1)'
+title_origfile=Would you like to replace the existing file
+title_newfile=with this one?
+file_info_fmt=$(1), $(2) bytes
+
+
+cancel_install_title=Cancel installation?
+cancel_install_msg=Are you sure you want to cancel the the installation?
+cancel_install_array2="Yes","No, continue"
+
+page_installselection_title=Select components to install
+install_comp_base=OSGi framework runtime files
+install_comp_src=Java sources and build environment
+install_comp_htdocs=Knopflerfish documentation
+
+install_comp_base_tt=Compiled OSGi framework files.
+install_comp_src_tt=All java sources for the framework and bundles + ant build environment. 
+install_comp_htdocs_tt=Create 'docs'-subdirectory with Knopflerfish documentation
+
+comp_size=Installation requires about $(1).
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/knopflerfish-osgi.git



More information about the pkg-java-commits mailing list