 # Licensed to the Apache Software Foundation (ASF) under one or more
 # contributor license agreements.  See the NOTICE file distributed with
 # this work for additional information regarding copyright ownership.
 # The ASF licenses this file to You 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. 

bundle Bundle
bundle.id Bundle ID
bundle.symbolicName Symbolic name
bundle.version Version
bundle.state State
bundle.location Location

bundle.install Install new bundle

bundle.start Bundle $\{symbolicName\} ($\{bundleId\}) started
bundle.start.fail Can not start bundle, exception occured ${message}

bundle.stop Bundle $\{symbolicName\} ($\{bundleId\}) stopped
bundle.stop.fail Can not stop bundle, exception occured ${message}

bundle.update Bundle $\{symbolicName\} ($\{bundleId\}) updated
bundle.update.fail Can not update bundle: ${message}

bundle.uninstall Bundle $\{symbolicName\} ($\{bundleId\}) uninstalled
bundle.uninstall.fail Can not uninstall bundle, exception occured ${message}

bundle.refresh Bundle $\{symbolicName\} ($\{bundleId\}) refreshed
bundle.refresh.fail Bundle refresh fail: ${message}

bundle.resolve Bundle $\{symbolicName\} ($\{bundleId\}) resolved
bundle.resolve.fail Bundle resolving error: ${message}

package Package

package.imports Imported packages
package.exports Exported packages

service.imports Imported services
service.exports Exported services

package.exporter Exporting bundle
package.importers Importing bundles