123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- h1(#Gettingstartedtutorial). Getting started
- {toc}
- h2(#InstallingYakinduStatechartTools). Installing Yakindu Statechart Tools
- In order to start working with Yakindu Statechart Tools, you have to install the software on your computer. We are assuming you have downloaded the software package and you have stored it on your machine.
- Yakindu Statechart Tools is based on the Eclipse integrated development environment (IDE) and runs inside Eclipse. The installation process as described below will put a full-fledged Eclipse instance on your computer. It is comprised in the Yakindu Statechart Tools distribution file you downloaded. You will have to unpack and execute Eclipse in order to work with Yakindu Statechart Tools inside of it.
- While Yakindu Statechart Tools is based on Eclipse, the latter in turn is based on Java. In order to use Eclipse, you need a more or less recent Java version on your machine. Depending on what you are going to do with Yakindu Statechart Tools, you either need a Java Runtime Environment (JRE) or a Java Development Kit (JDK). Since a JDK always contains a JRE, it is a safe bet to install the former. However, unless you are going to do some Java development – i. e. create a state machine, turn it into Java source code, and use the latter from your Java client code –, you might get away with a JRE. Installation of Java is beyond the scope of this document. You can find more information and download the software from "https://www.java.com/":https://www.java.com/.
- The chapter "below":getting_started.html#InstallationOnLinux walks through the installation process on Linux machine. The installation procedures are quite similar on other computer architectures, like on a Mac or a Windows PC. They will be described later. If you are working with such a computer, please try to translate the Linux
- h3(#InstallingOnLinux). Installing on Linux
- This chapter describes how to install Yakindu Statechart Tools on a Linux machine using a command-line tool. The installation doesn't require _root_ permissions.
- h4. Unpacking the downloaded file
- Choose a directory for Yakindu Statechart Tools (SCT) – or Eclipse, respectively. The commands below assume you want to install the software in the _/my/software_ directory. Please modify the commands appropriately to suit your needs!
- Go to the installation directory:
- bc(prettyprint).
- cd /my/software/
- Unpack the software distribution file. If the downloaded file is located in _/download/yakindu-sct-luna-R-linux-gtk-x86_64.tar.gz_, use the following command to unpack in the installation directory:
- bc(prettyprint).
- gzip -dc /download/yakindu-sct-luna-R-linux-gtk-x86_64.tar.gz | tar xvfp -
- This will create a folder _eclipse_ in your installation directory, i. e. _/my/software/eclipse_ in our example, as shown in the image below:
- !(img-rounded shadowed)images/linux_install_010_eclipse_folder.png!
- The contents of the _eclipse_ folder looks like this:
- !(img-rounded shadowed)images/linux_install_020_eclipse_contents.png!
- There you are: You have installed the software. Now you should start Eclipse.
- h4. Starting Eclipse
- Start Eclipse by running the _eclipse_ executable.
- To do so, please enter the command
- bc(prettyprint).
- eclipse/eclipse
- in your installation directory. Or issue the command
- bc(prettyprint).
- /my/software/eclipse/eclipse
- if your command shell is in any other working directory.
- From a file browser, you can start Eclipse by clicking on the _eclipse_ symbol, shown as a gear-wheel in the sample screenshot above.
- While Eclipse is starting up, it is showing a splash screen:
- !(img-rounded shadowed)images/linux_install_030_eclipse_splash.png!
- Eclipse needs a _workspace_ directory where it stores its so-called projects along with other data. During the first startup, Eclipse's _Workspace Launcher_ dialog asks you to specify the workspace directory in the _Workspace_ field. Please specify a new and empty one.
- In the example below, we chose the _/my/workspace_ directory as our workspace. We also checked the _"Use this as the default and do not ask again"_ option. This is sensible, because on subsequent startups, Eclipse won't ask for a workspace directory again, but will always use the one we chose once and forever. (You can still change the workspace later via _File → Switch Workspace_ in the Eclipse menu.)
- !(img-rounded shadowed)images/linux_install_040_eclipse_workspace_dialog.png!
- Click on the _OK_ button to proceed.
- On the first start, Eclipse presents a _Welcome_ window:
- !(img-rounded shadowed)images/linux_install_050_eclipse_welcome.png!
- You can browse the material shown here, if you want. When you are done, please close the _Welcome_ tab or click on _Workbench_ at the upper right. Both actions lead to the Eclipse workbench:
- !(img-rounded shadowed)images/linux_install_060_eclipse_workbench.png!
- This is your working environment now. Congratulations, you have just installed Eclipse properly!
- You can "proceed":getting_started.html#Introduction now to create your first Yakindu Statecharts Tools project.
- h3(#InstallingOnWindows). Installing on Windows
- This chapter describes how to install Yakindu Statechart Tools on a Windows 7 machine.
- h4. Unpacking the downloaded file
- Unpack the software distribution file. Use the file explorer to open the directory you downloaded the software distribution file to, right-click on the latter, and select _Extract all_ in the context menu.
- !(img-rounded shadowed)images/windows7_install_010_eclipse_extract_1.png!
- Choose a directory for Yakindu Statechart Tools (SCT) – or Eclipse, respectively. The example below assumes you want to install the software in the _C:\Program Files\yakindu_sct_ directory. Please modify as needed!
- !(img-rounded shadowed)images/windows7_install_020_eclipse_extract_2.png!
- After unpacking, you will find a folder _eclipse_ in your installation directory, i. e. _C:\Program Files\yakindu_sct\eclipse_ in our example, as shown in the image below:
- !(img-rounded shadowed)images/windows7_install_030_eclipse_folder.png!
- The contents of the _eclipse_ folder looks like this:
- !(img-rounded shadowed)images/windows7_install_040_eclipse_contents.png!
- There you are: You have installed the software. Now you should start Eclipse.
- h4. Starting Eclipse
- Start Eclipse by running the _eclipse.exe_ executable.
- To do so, please double-click (or single-click, depending on your Windows settings) on the _eclipse_ symbol, shown as a dark purple circle with three horizontal lines in the sample screenshot above.
- While Eclipse is starting up, it is showing a splash screen:
- !(img-rounded shadowed)images/windows7_install_050_eclipse_splash.png!
- Eclipse needs a _workspace_ directory where it stores its so-called projects along with other data. During the first startup, Eclipse's _Workspace Launcher_ dialog asks you to specify the workspace directory in the _Workspace_ field. Please specify a new and empty one.
- In the example below, we chose the _C:\Users\joedoe\workspace_ directory as our workspace. We also checked the _"Use this as the default and do not ask again"_ option. This is sensible, because on subsequent startups, Eclipse won't ask for a workspace directory again, but will always use the one we chose once and forever. (You can still change the workspace later via _File → Switch Workspace_ in the Eclipse menu.)
- !(img-rounded shadowed)images/windows7_install_060_eclipse_workspace_dialog.png!
- Click on the _OK_ button to proceed.
- On the first start, Eclipse presents a _Welcome_ window:
- !(img-rounded shadowed)images/windows7_install_070_eclipse_welcome.png!
- You can browse the material shown here, if you want. When you are done, please close the _Welcome_ tab or click on _Workbench_ at the upper right. Both actions lead to the Eclipse workbench:
- !(img-rounded shadowed)images/windows7_install_080_eclipse_workbench.png!
- This is your working environment now. Congratulations, you have just installed Eclipse properly!
- You can "proceed":getting_started.html#Introduction now to create your first Yakindu Statecharts Tools project.
- h3. Installing to an existing Eclipse instance
- This chapter describes the steps that are needed to install Yakindu Statechart Tools to an existing Eclipse instance. Let's assume you already have Eclipse up and running and now you want to install Yakindu Statechart Tools as an additional software item (plugin).
- In the the _Help_ menu, select the _Install new software_ menu item:
- !images/eclipse_install_010_eclipse_menu_install_new_software.png!
- The _Install_ wizard opens:
- !images/eclipse_install_020_eclipse_install_wizard.png!
- Click on the _Add…_ button near the upper right corner of the wizard.
- A dialog opens, asking you to specify the update repository you want to install the new software from. If your Eclipse release is _Luna_, please enter @http://updates.yakindu.org/sct/luna/releases/@ into the _Location_ field. Enter some text into the _Name_ field. This text is abitrary in principle, but it should make it easier for you to identify this particular update repository among the other update repositories. The example below the repository's name is @Yakindu Statechart Tools (Luna)@. It describes which piece of software the repository provides (Yakindu Statechart Tools) and which Eclipse release that software is compatible with (Luna, i. e. Eclipse 4.4).
- !images/eclipse_install_030_eclipse_add_repository.png!
- If you want to install Yakindu Statechart Tools not to _Luna_ but to another Eclipse release instead, please replace @luna@ in the repository address by the respective name of your Eclipse release, e. g. @mars@, so that the repository address becomes @http://updates.yakindu.org/sct/mars/releases/@. Please note that Yakindu Statechart Tools might not be available for each Eclipse release. In particular it might take some time to catch up with most recent Eclipse releases.
- If you do not want to install an officially stable Yakindu Statechart Tools release, but rather a more recent milestone release, please replace @releases@ in the repository address by @milestones@. Since milestone builds are newer than stable releases, they generally have more features available and more bugs fixed. However, they might also contain some new bugs that have gone unnoticed by now.
- After entering name and location of the update repository, click _OK_.
- Eclipse establishes a network connection to the update repository, asks it for available software items and shows them in the install wizard:
- !images/eclipse_install_040_eclipse_software_items.png!
- Please check at least _Xtext Integration Utilities_ and – no surprise – _Yakindu SCT 2_. (You can also install the respective source code items. However, unless you want to have a look at that source code or even want to modify it, you don't need them.)
- Click _Next >_.
- Eclipse tries to integrate the new software with the software that is already installed. If it detects any mismatched between requirements and provisions, Eclipse will try to find a solution in order to mitigate this problem. The screenshot below shows such a case:
- !images/eclipse_install_050_eclipse_trouble.png!
- Select the most appropriate solution, then click _Next >_.
- The wizard shows the software to be installed and gives you the opportunity to review the changes:
- !images/eclipse_install_060_eclipse_review.png!
- Click _Next >_.
- The wizard asks you to review and accept the terms of the new software's license agreements.
- !images/eclipse_install_070_eclipse_licenses.png!
- Select the radio button labelled _I accept the terms of the license agreements_ (if you do), then click _Finish_.
- Eclipse starts to download the software and installs it on your computer. This may take some time.
- !images/eclipse_install_080_eclipse_installation.png!
- If the installation was completed successfully, Eclipse needs a restart in order to have the changes take effect. A dialog asks whether you want to restart Eclipse right now or later:
- !images/eclipse_install_090_eclipse_restart.png!
- After the restart, Eclipse displays its _Welcome_ window, now also featuring Yakindu Statechart Tools:
- !images/eclipse_install_100_eclipse_sct_help.png!
- h3. Updating Yakindu Statechart Tools
- To check whether a new Yakindu Statechart Tools release is available and to install it, please select the _Help → Check for Updates_ menu item.
- !images/eclipse_update_010_eclipse_menu_check_for_updates.png!
- If Eclipse finds any software items to be updated – not just Yakindu Statechart Tools –, it will guide you through the process of updating them. Generally Eclipse has to be restarted afterwards to have any changes take effect.
- You can configure Eclipse as follows to automatically check for updates:
- Select the _Window → Preferences_ menu item. The _Preferences_ dialog opens.
- Go to the _Install/Update → Automatic Updates_ section. Here you can configure whether and when Eclipse should check for updates and what to do when it finds any.
- !images/eclipse_update_020_eclipse_automatic_updates.png!
- h2(#Introduction). Introducing Yakindu Statechart Tools
- This tutorial will introduce Yakindu Statechart Tools (SCT). YAKINDU Statechart Tools provides an integrated modeling environment for the specification and development of reactive, event-driven systems based on the concept of state machines or statecharts. It is an easy-to-use tool featuring sophisticated graphical statechart editing, validation and simulation of statecharts as well as code generation.
- In this tutorial you will learn how to create a new statechart model, execute it using the simulation engine and generate Java code to get a fully-working statechart implementation. Please note that this tutorial will not explain statecharts in general, so you should familiarize yourself with the basic concepts of state machines first.[1] Before we get started, make sure you have Yakindu Statechart Tools properly installed. For installation instructions see chapter "Installation":getting_started.html#Installation.
- h2. CallHandling example explained
- p(#Prepareaproject). During this tutorial we will create a system for handling incoming phone calls as a sample application. After startup, the system is in an idle state and is waiting for incoming calls. When a call comes in, the user can either accept the call or dismiss it. If the users accepts the call and opens a connection, the system is tracking the duration of the call and is waiting for the user to hang up. After hanging up, the system displays the total time of call and then returns to its idle state. The complete statechart model is shown below:
- !(img-rounded shadowed)images/example.png!
- h2. Preparing a project
- p(#Createastatechartmodel). The first step is to create a new Eclipse project by selecting _File → New → Project…_. A wizard opens, showing a couple of different project types. Since we want to generate Java code from our statechart model later on, select _Java → Java Project_ from the wizard menu. Give the project a meaningful name, e.g. *CallHandling* and click _Finish_.
- !images/callhandling_create_java_project.png!
- As a result, Eclipse creates the project and establishes a folder _src_ inside of it. Initially this folder is empty. It is indended for user-created Java code.
- !images/callhandling_new_java_project.png!
- However, we won't deal with Java programming right now, but rather create our statechart model first. It is good practice to keep models and source code separate. So, let's create a new folder for the model. Right-click on the project's root, i. e. on *CallHandling*, then select _New → Folder_ from the context menu. Give the model folder a reasonable name by typing e. g. *model* into the _Folder Name_ text field, then click _Finish_. The new _model_ folder appears in the package explorer:
- !images/callhandling_030_model_folder_created.png!
- h2. Creating a statechart model
- p(#UsetheEditor). Next, create the statechart model itself:
- * Right-click the *model* folder. The context menu opens.
- * Select _New → Other_. The _New_ wizard opens.
- * In the _New_ wizard, select _YAKINDU SCT → Statechart model_.<br/>!images/callhandling_040_create_model_new_statechart_model.png!
- * Click _Next_.
- * In the following dialog, the wizard asks for the name the of the model file and for the directory it should be created in. Let's choose *CallHandling.sct* as the file name and *CallHandling/model* as the directory name, i.e. the directory *model* inside the Eclipse project *CallHandling*.<br/>!images/callhandling_050_create_model_specify_name.png!
- * Click _Finish_.
- * Answer the question regarding the perspective switch with _Yes_.<br/>!images/callhandling_060_create_model_modeling_perspective_dialog.png!
- * The statechart editor opens and shows the definition of a very simple statechart. You will notice that the statechart editor flags an error in the model. This is due to the fact that the state does not have a name yet. The error marker will disappear once when have named the state.<br/>!images/callhandling_070_create_model_completed.png!<br/>
- h2. Using the editor
- Within the Eclipse workbench, the area marked by a red rectangle in the image below is the *statechart editor*. The subsequent paragraph will explain how to work with it, how to create and modify the statechart for the _CallHandling_ example.
- !images/callhandling_080_editing_editor.png!
- h3. Creating interfaces
- Statecharts can describe very complex interactions between a multitude of actors and an even bigger multitude of events these actors can receive or trigger. It is therefore good practice to structure those events and associate them with their respective actors. For this purpose Yakindu Statecharts Tools provides the concept of so-called *interfaces*[2].
- In the _CallHandling_ example, we have two actors: the user and the phone. Let's model their communication as two interfaces:
- * The _Phone_ interface provides a single incoming event named _incoming_call_.
- * The _User_ interface comprises two incoming events: _accept_call_ and _dismiss_call_.
- We have to enter the respective definitions in textual form into the statechart editor. Here's how the interface definitions look like:
- bc(prettyprint). interface User:
- in event accept_call
- in event dismiss_call
- bc(prettyprint). interface Phone:
- var duration : integer
- in event incoming_call
- As you can see, _Phone_ interface also has an integer variable _duration_, which will be explained later. This text has to go into the statechart editor's *definition block*, which is the compartment on the statechart editor's left-hand side. To enter the text, double-click on the definition block and start typing.
- Hint: The text editor offers context-sensitive assistance helping you to know what keyword etc. are allowed at the very position the text cursor currently is. Let's assume you have just entered the definition of the _User_ interface and your text cursor is positioned _behind_ that definition.
- # Press @[Ctrl+Space]@. This key combination invokes the *content assist*. A popup window appears showing all keyword alternatives that are allowed here.
- # Single-click on one of the alternatives, say on @interface@, and a help text containing a detailed description with sample code is displayed in a second popup window.
- # Double-click on it, and the keyword is carried over into the text field.
- !images/callhandling_090_editing_interfaces.png!
- h3. Creating states
- Next, rename the initially created state to *Idle* by double-clicking on the name label and entering the new name. The error marker will disappear.
- Statechart validation includes syntactical and semantical checks of the whole statechart. For examples, a statechart is checked for unreachable states, dead ends, or references to unknown events. These validation constraints are checked during editing. In case any constraints are violated, warning or error markers will be shown, attached to the faulty model elements. Thus the user receives direct and immediate feedback on the validation state of his statecharts.
- Now, create the three states *Incoming Call*, *Active Call* and *Dismiss Call* by dragging _States_ symbol from the palette on the right onto the main region thrice and naming the states appropriately.
- h3. Creating transitions
- Connect the states using the _Transition_ tool from the palette as shown in the sample model above. After creating a transition, select the appropriate event (use the content assist @[Ctrl+Space]@ to navigate from interfaces to events) in the direct editing pop-up.
- Finally, create the *Active Call* and *Dismiss Call* states' internal behavior. This can either be done by opening the direct editing text box via double-clicking or by using the property view at the bottom. The text box supports code completion, syntax highlighting and validation.
- If everything went well, the error markers should be gone. Your model should look like the one in the following screenshot:
- !(img-rounded shadowed)images/example_final.png!
- p(#Simulatingthemodel). If something went wrong and you cannot eliminate the problem, you can download the sample project "here":examples/CallHandling.zip.
- h2. Simulating the model
- To start the dynamic simulation of your model, right-click on the model file *CallHandling.sct* in the Eclipse _Project Explorer_, then select _Run As → Statechart Simulation_ in the context menu.
- The perspective changes from _SC Modeling_ to _SC Simulation_. The simulation perspective defines two additional views: The _Debug_ view at the top shows all running statechart instances and allows to select one of them. Please note that SCT allows multiple executions of the same statechart as well as parallel executions of different statecharts at the same time.7
- You can use the _Simulation_ view on the right to raise events and to inspect and modify variables.
-
- When the simulation starts, the *Idle* state becomes active since it is connected to the *Initial State*. An active state is visualized by a red background color in the statechart view.
- Now let's simulate an incoming call. Raise the associated event by clicking at the _incoming_call_ text formatted as a hyperling in the _Simulation_ view on the right. This event will trigger a state transition from *Idle* to *Incoming Call*. Accept the call by raising the _accept_call_ event. Another transition happens, and the state *Active Call* becomes active. For the duration of the call, the variable _duration_ in the _Simulation_ view is incremented every second. When you are done with your phone call, raise the _dismiss_call_ event. The state machine transitions to the *Dismiss Call* state, and two seconds later returns to its *Idle* state.
- If your statechart behaves as expected, we can go one step further now and generate code from it. Before doing so, stop the simulator by clicking at the little red terminate button in the toolbar at the top.
- h2. Generating Java source code
- YAKINDU SCT includes code generators for Java, C, and C++ out of the box. The code generators are following a "code-only" approach and do not need any additional runtime libraries. The generated code provides a well-defined interface and can be integrated easily with any client code. In this tutorial we will generate Java code representing our *CallHandling* example.
- For code generation, SCT uses a textual generator model called SGen. This model allows for customization of the code generation process. To create a new SGen model, select the model folder in the project explorer on the left, and select _New → Code Generator Model_ from the context menu. The _YAKINDU Generator Model_ wizard opens. On the first wizard page, enter *CallHandling.sgen* as the filename, then click _Next_. On the second wizard page, select _Yakindu SCT Java Code Generator_ from the _Generator_ drop-down menu at the top. In the statechart tree beneath, check the *CallHandling.sct* model, then click _Finish_. The SGen Editor opens and shows the following simple generator model:
- bc(prettyprint).
- GeneratorModel for yakindu::java {
- statechart CallHandling {
- feature Outlet {
- targetProject = "CallHandling"
- targetFolder = "src-gen"
- }
- }
- }
- In the listing above, @yakindu::java@ is the unique ID of the code generator. It is followed by a reference to the statechart model we want to generate code for, i.e. @CallHandling@. A statechart reference may contain various configuration features. The @Outlet@ feature specifies target project and folder for the generated artifacts.
- The model is using _after_ and _every_ expressions. That is, we are dealing with timed events and want the generater to provide us with a default implementation of a timer service. In order to achieve this, we have to add the following feature to the generator model:
- bc(prettyprint).
- feature GeneralFeatures {
- TimerService = true
- }
- The generator model is executed by a so-called Eclipse builder. That is, as long as _Project → Build Automatically_ is checked the artifacts are generated automatically with each model change. If you want to execute your generator model manually, select _Generate Statechart Artifacts_ from the @.sgen@ file's context menu in the project explorer.
- p(#Integrationwithclientcode). As a result, you should see a new folder *src-gen* in the project explorer containing the generated Java artifacts. Add the generated artifacts to the Java build path by selecting _Build Path → Use as source folder_ from the *src-gen* folder's context menu.
- h2. Integration with client code
- As the final step, we want to integrate the generated statechart implementation with some client code. Create a new class by selecting _New → Class_ in the context menu of the *src* folder. Give it a meaningful name, for example *CallHandlingClient*, then click _Finish_.
- Next, copy the following code into the created class:
- bc(prettyprint linenums).
- 1 import org.yakindu.scr.TimerService;
- 2 import org.yakindu.scr.callhandling.CallHandlingStatemachine;
- 3 public class CallHandlingClient {
- 4 public static void main(String[] args) throws Exception {
- 5 CallHandlingStatemachine sm = new CallHandlingStatemachine();
- 6 sm.setTimer(new TimerService());
- 7 // enter the sm and active the Idle state
- 8 sm.enter();
- 9 // Raise an incoming call
- 10 sm.getSCIPhone().raiseIncoming_call();
- 11 sm.runCycle();
- 12 // Accept the call
- 13 sm.getSCIUser().raiseAccept_call();
- 14 sm.runCycle();
- 15 for (int i = 0; i < 50; i++) {
- 16 Thread.sleep(200);
- 17 sm.runCycle();
- 18 }
- 19 System.out.println(String.format("The phone call took %d s", +sm
- 20 .getSCIPhone().getDuration()));
- 21 sm.getSCIUser().raiseDismiss_call();
- 22 sm.runCycle();
- 23 }
- 24 }
- Let's have a detailed look at the implementation.
- * First, the code creates a new instance of the state machine by calling the default constructor of @CallHandlingStatemachine@ (line 5).
- * Since we use timed events, the statechart implementation requires an implementation of the @ITimerService@ interface. Since we added the @TimerService@ feature to the generator model, the code generator creates a default implementation that uses the @java.util.Timer@ class. A new instance of the default @TimerService@ is created and set to the state machine (line 6).
- * In line 8, @sm.enter()@ enters the statechart and – via the initial state – activates its *Idle* state.
- * For each interface in the statechart specification block, a getter method has been generated, here @getSCIPhone()@ and @getSCIUser()@. You can access all in events and variables via these interfaces. In line 10, the incoming call event is raised, activating the *Incoming Call* state after the next runcycle has been executed (line 11).
- * In line 13, we raise the _accept_call_ event via the _User_ interface. It activates the *Active Call* state after the next runcycle has been performed (line 17).
- * From line 15 to line 18, the runcycle is executed periodically every 200 milliseconds. After that, the duration is printed to console (lines 19 and 20). Finally, the _dismiss_call_ event is raised, activating the *Dismiss Call* state after the next runcycle.
- You can execute the client code via _Run As → Java Application_ from the class file's context menu.
- h2(#Footnotes). Footnotes
- fn1. "UML state machine":http://en.wikipedia.org/wiki/UML_state_machine
- fn2. Not to be confused with user interfaces.
|