© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative...

34
© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions Understanding the Command Framework

Transcript of © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative...

Page 1: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Using Commands and Menu Contributions

Understanding the Command Framework

Page 2: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

2© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

About the Speaker

Paul Webster Senior Software Developer, Platform UI Committer

Works for IBM Rational Software since he joined the EclipseTM Platform UI team in May 2005

Works with part lifecycle, commands/handlers, keybindings, and menu contributions

Page 3: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

3© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Tutorial – Person Information

Everybody needs to exist in a database somewhere! An Eclipse RCP application can help. The Eclipse framework already provides the concepts we need:

Perspective for layout

View (to see the People)

Editor (to update Person data)

Wizard (to add a Person to the database)

Commands (to do *anything*) The implementation is in org.eclipse.ui.examples.contributions.

Page 4: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

4© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Tutorial – Person Information (cont.)

Code: org.eclipse.ui.examples.contributions in 3.4 This can be picked up from the I-build download page (as part of

the examples zip), but not until 3.4 M6. The latest version is available from HEAD in

CVS: :pserver:[email protected]:/cvsroot/eclipse The Info product can be launched by opening the info.product file

and launching it as an eclipse app.

Page 5: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

5© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Command framework

A command is an abstraction of some semantic behaviour. A command is not an implementation of that behaviour. A command is not the visual presentation of that behaviour.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. -->

<command categoryId="org.eclipse.ui.examples.contributions.commands.category" defaultHandler="org.eclipse.ui.examples.contributions.handlers.GlobalMenuHandler" id="org.eclipse.ui.examples.contributions.commands.globalCommand" name="%contributions.commands.globalCommand.name"></command>

Page 6: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

6© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Handlers

A handler implements one behaviour for a command. The active handler controls the command’s enabled state. Handlers most commonly extend AbstractHandler. Handlers are provided an application context in their execute(*)

method.

// © Copyright 2008 IBM Corp. All rights reserved. This source code// is made available under the terms of the Eclipse Public License, v1.0.// GlobalMenuHandler.javapublic Object execute(ExecutionEvent event) throws ExecutionException { IWorkbenchWindow window = HandlerUtil .getActiveWorkbenchWindowChecked(event); MessageDialog.openInformation(window.getShell(), ContributionMessages.SampleHandler_plugin_name, ContributionMessages.SampleHandler_hello_msg); return null;}

Page 7: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

7© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Handlers

The default handler case is useful, but also uninteresting. Multiple handlers can register to handle behaviour for a

command. At any give time there can be either 0 or 1 active handlers for a

command. Handlers can be declaratively or programmatically activated.

// © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms // of the Eclipse Public License, v1.0.// InfoView.javaIHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);countHandler = new AbstractHandler() { public Object execute(ExecutionEvent event) { // counting stuff in this view return null; }};handlerService.activateHandler(VIEW_COUNT_ID, countHandler);

Page 8: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

8© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Handlers – pick one!

Say we want the refresh command to refresh information in the active view:

Refresh RefreshFiles

RefreshConnections

CommandService

HandlerService Source

ApplicationContext

(activePartId == org.e.u.navigator)

(activePartId == org.e.dtp.databases)

activePartId

activePartId

Page 9: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

9© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Handlers – more than one

The three most common handler contribution types are: A default handler – this is a global handler, usually instantiated

once

Handler for a part – this handler will deal with a specific type of view or editor

Handler for a selection – this handler is usually keyed off of the selection type

There are a couple of ways to contribute handlers at the different levels:

Declarative handlers use activeWhen and extract needed state from the application context.

Programmatic handlers are activated with part creation.

Page 10: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

10© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Now that we have commands …

… we need to execute them. A keybinding allows key combinations to execute a command. A number of factors determine if a keybinding is active:

Scheme, contexts, platform, and locale

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --><key commandId="org.eclipse.ui.examples.contributions.view.edit" contextId="org.eclipse.ui.examples.contributions.view.context" sequence="M1+O" schemeId="org.eclipse.ui.examples.contributions.scheme"></key>

Page 11: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

11© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Active Keybindings

Different workflows require that some keys operate differently, and in Eclipse that means execute different commands.

We don’t want our keybindings to be overly dynamic, however. 2 main ways that keybindings change are scheme and contexts:

A scheme is a group of keybindings … very static.

A context scopes a keybinding, and contexts change with the program’s focus.

For example, when editing text CTRL+D deletes a line. But when inputting in the Console view, CTRL+D produces the EOF

Page 12: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

12© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Active Keybindings (cont.)

The IBindingService gets the active contexts from the IContextService.

The IBindingService treats the contexts like an active tree. The IBindingService prunes the tree depending on which

component has focus. This allows the binding service to look up the parameterized

command for a key sequence.

dialogAndWindow

window

textEditorScope javaEditorScope

debugging jdt.debugging

dialog

Page 13: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

13© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Questions

Questions?

Page 14: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

14© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contributions

Menus and Toolbars are also important for executing application functionality.

Menu Contributions create the menu and toolbar structures and insert them into the correct eclipse location.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --> <menuContribution locationURI="menu:org.eclipse.ui.main.menu"> <menu id="file" label="%menu.file.label" mnemonic="%menu.file.mnemonic"> <command commandId="org.eclipse.ui.file.refresh" mnemonic="%command.refresh.mnemonic" style="push"> </command> <separator name="sep1" visible="true“/> <command commandId="org.eclipse.ui.file.exit" mnemonic="%command.exit.mnemonic" style="push"> </command> </menu> <!– more of the main menu structure --> </menuContribution>

Page 15: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

15© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contribution Placement

1. Main Menu2. Main Toolbar3. View Toolbar

4. View Pulldown Menu5. Context Menu6. Trim Area

1

2

3

6

4

5

Page 16: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

16© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contribution Placement (cont.)

We call them Menu Contributions, but in eclipse there are 3 flavours:

menu – the main menu and the view dropdown menus (1 & 4)

popup – the view and editor context menus. These menus have special selection handling (5)

toolbar – view toolbars, the main coolbar, and the trim (2, 3, & 6)

Page 17: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

17© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contributions

The Menu Service and Menu Contributions were designed to deal with JFace based API.

ContributionManagers provide the update and dispose lifecycles for contribution items:

A ToolBarManager and MenuManager represent their corresponding SWT widgets

ContributionItems will render items into the menu or toolbar: See ContributionItem#fill(Menu,int)

See ContributionItem#fill(ToolBar,int) A ContributionItem belongs to only one ContributionManager.

Page 18: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

18© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contributions

Element Type Element Type

menu MenuManager toolbar ToolBarManager

separator GroupMarker or Separator

command CommandContributionItem

dynamic CompoundContributionItem

control WorkbenchWindowControlContribution

org.eclipse.ui.menus elements are currently translated to:

Page 19: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

19© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contributions Lifecycle

Menu Contributions are generated on window creation

Menu Contributions are generated on IViewPart creation

Menu Contributions are generated on context menu SWT.Show

IWorkbenchWindow

ActionBarAdvisorWindow

SlaveMenuServicePluginActionSet

Builder

IWorkbenchWindow

ViewPart/IActionBars

PartSiteSlaveMenuService

ViewActionBuilder

IWorkbenchWindow

WorkbenchPartPartSite

SlaveMenuServiceObjectAction

ContributorManager

Page 20: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

20© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Menu Contribution Visibility

The IMenuService populates the MenuManagers and ToolBarManagers with ContributionItems.

The IMenuService works with the IEvaluationService to keep each ContributionItem’s visibility up to date.

The IEvaluationService is notified when variables change and re-evaluates any core expressions as needed.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --> <visibleWhen> <with variable="activeMenuSelection"> <iterate> <adapt type="org.eclipse.ui.examples.contributions.model.Person“/> </iterate> </with> </visibleWhen>

Page 21: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

21© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Questions

Questions?

Page 22: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

22© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Services

All programmatic interaction with the menu/command framework is done through services.

The services are accessed through an IServiceLocator, which provides a localized access point.

The concept of a service locator was introduced in 3.2. IWorkbench, IWorkbenchWindow, IPartSite, and IPageSite are

all service locators. These are not OSGiTM services.

Page 23: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

23© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Services

Services accessed through service locators usually provide “free” behaviours:

Scope the service provided if required

Clean up the service on dispose

// © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms // of the Eclipse Public License, v1.0.// InfoView.javaprivate void activateContext() { IContextService service = (IContextService) getSite().getService(IContextService.class); service.activateContext(MY_PART_CONTEXT);}

// © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms // of the Eclipse Public License, v1.0.// InfoView.javapublic void createPartControl(Composite parent) { // creating my part as usual // then… IPersonService service = (IPersonService) getSite().getService(IPersonService.class); viewerInput = new ArrayList(service.getPeople()); service.addPersonChangeListener(personListener);}

Page 24: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

24© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Services

In 3.4 services can be contributed declaratively using org.eclipse.ui.services.

Services contributed this way tend to: be hierarchical in nature.

scope aspects of their service to the local level.

clean up contributions at the local level when they are disposed.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --> <serviceFactory factoryClass="org.eclipse.ui.examples.contributions.model.PersonServiceFactory"> <service serviceClass="org.eclipse.ui.examples.contributions.model.IPersonService" /> </serviceFactory>

Page 25: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

25© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Services

The service locator chain provides different service objects at each level:

IWorkbench ServiceLocator ContextService

IWorkbenchWindow

ServiceLocatorSlaveContext

Service

IWorkbenchPart

ServiceLocatorSlaveContext

Service

ContextServiceFactory

WorkbenchWindowExpression

ActivePartExpression

Page 26: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

26© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Services

All programmatic interaction with the menu/command framework is done through services.

Common services used are: IContextService – activate and deactivate contexts

ICommandService – defines and controls the command definitions

IHandlerService – manages handler activation and executes commands

IBindingService – performs lookups between commands and key sequences

IMenuService – populates the contribution managers and controls item visibility

IEvaluationService – public API in 3.4, evaluates core expressions against the application context

Page 27: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

27© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Sources

Variable sources are used in conjunction with core expressions for declarative enablement.

When a variable changes the source notifies any listeners that can then update their state.

In 3.4 source providers can be contributed declaratively using org.eclipse.ui.services.

Most of the workbench source providers are simply converting workbench events to variables.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --> <sourceProvider provider="org.eclipse.ui.examples.contributions.model.UserSourceProvider"> <variable name="org.eclipse.ui.examples.contributions.user" priorityLevel="activeSite"> </variable> </sourceProvider>

Page 28: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

28© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Sources – variable priority level

Variables are assigned a priority level, loosely based on the priorities defined in org.eclipse.ui.ISources.

The IHandlerService uses these variable priorities to resolve conflicts between active handlers.

The general idea is that the most localized handler is appropriate over a more global one:

Global < Context < Active Editor < Active Part < Selection When defining a variable, there are 7 “priority slots” to choose

from.

Page 29: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

29© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Questions

Questions?

Page 30: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

30© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Evaluating Core Expressions

The IEvaluationService takes care of handlers activeWhen and enabledWhen, menus visibleWhen, and activities enabledWhen.

This service is one of the main listeners to source variable changes.

Expressions that use the changing variable are re-evaluated.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --> <visibleWhen checkEnabled="false"> <with variable="activeMenuSelection"> <count value="1" /> <iterate> <adapt type="org.eclipse.core.resources.IFile"> <test property="org.eclipse.core.resources.name" value="*.xml" /> <test property="org.eclipse.core.resources.contentTypeId" value="org.eclipse.ant.core.antBuildFile" /> </adapt> </iterate> </with> </visibleWhen>

Page 31: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

31© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Evaluating Core Expressions

The IEvaluationService fires a PropertyChangeEvent when the result of an expression changes.

In 3.4 expressions that use properties can be re-evaluated. In general write core expressions using <with/>.

<!-- © Copyright 2008 IBM Corp. All rights reserved. This source code is made available under the terms of the Eclipse Public License, v1.0. --> <enabledWhen> <and> <count value="1" /> <iterate> <instanceof value="org.eclipse.ui.examples.contributions.model.Person" /> </iterate> <with variable="org.eclipse.ui.examples.contributions.user"> <test property="org.eclipse.ui.examples.contributions.user.isAdmin" value="true" /> </with> </and> </enabledWhen>

Page 32: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

32© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Evaluating Core Expressions - handlers

Change from an editor to a view; that changes activePart, activePartId, and activeSite.

PropertyChangeEvents update all changed IHandlerActivations. When all changes have been updated, the IHandlerService

resolves conflicts (using variable priority levels).

Refresh RefreshFiles

RefreshConnections

CommandService

HandlerService Source

ApplicationContext

(activePartId == org.e.u.navigator)

(activePartId == org.e.dtp.databases)

activePartId

activePartId

Page 33: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

33© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

The End

Questions?

Page 34: © Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license Using Commands and Menu Contributions.

34© Copyright 2008 IBM Corp. All rights reserved. This presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

Legal Notices

IBM is a registered trademarks of International Business Corp. in the United States and other countries.

OSGi is a trademark or registered trademark of the OSGi Alliance in the United States and other countries.

Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.

Other company, product, or service names may be trademarks or service marks of others This presentation is © Copyright 2008 IBM Corp. ; Source code in this presentation is made

available under the EPL, v1.0, remainder of the presentation is licensed under Creative Commons Att. Nc Nd 2.5 license

THE INFORMATION DISCUSSED IN THIS PRESENTATION IS PROVIDED FOR INFORMATIONAL PURPOSES ONLY. WHILE EFFORTS WERE MADE TO VERIFY THE COMPLETENESS AND ACCURACY OF THE INFORMATION, IT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, AND IBM SHALL NOT BE RESPONSIBLE FOR ANY DAMAGES ARISING OUT OF THE USE OF, OR OTHERWISE RELATED TO, SUCH INFORMATION. ANY INFORMATION CONCERNING IBM'S PRODUCT PLANS OR STRATEGY IS SUBJECT TO CHANGE BY IBM WITHOUT NOTICE.