![]() |
![]() |
![]() |
![]() |
![]() |
Identifying the Requirements
What You Will Learn
- To bring in external (requirements) documents into the Organizer
- To identify important concepts
- To use a data dictionary
- To identify actors and use cases and to compile the information gained into textual documents
- To create a textual use case
- To create an MSC use case out of a textual use case
- To make a requirements object model
- To connect important concepts in the different documents with implinks
- To perform consistency checks
Introduction to the Exercise
In this exercise you will perform the tasks associated with the requirements analysis activity. The purpose of the requirements analysis is to:
- Gain understanding of the problem domain - the Access Control system and the environment in which it is going to exist.
- Find and understand all requirements imposed on the Access Control system.
Producing a complete requirements analysis would take too much time in this tutorial. Therefore, you will only perform parts of every required step of the process.
The result will not be a complete requirements structure, but you will have acquired knowledge of how to use the SOMT method in the process of identifying requirements.
Preparing the Exercise
You can use your own document structure from the previous exercise (just move your accesscontrol.sdt file to the ReqA directory), or use a provided solution.
- Open the system file somttutorial/ReqA/accesscontrol.sdt (on UNIX), or somttutorial\reqa\accesscontrol.sdt (in Windows).
- Check that the Source directory is set to somttutorial/ReqA/ (on UNIX), or somttutorial\reqa\ (in Windows), in the same way as you did in the preparation to this tutorial (see Preparations).
Studying the Textual Requirements
Including External Textual Requirements
A textual document with requirements is the input to the Access Control system development project and it will form the base from which the Access Control system is developed. You will later on create implementation links (so called implinks) between the textual requirements document and other models. This is done to make it possible to follow a requirement through a number of models all the way down to code.
The textual requirements document of the Access Control system is contained in a text file. This file should now be included in the Organizer work area.
- Select the module named TextualRequirementsModel in the Requirements Documents chapter.
- Select the Add Existing command in the Edit menu.
- In the Add Existing dialog, change the filter to *.txt and press the Filter button. Select the file TextualRequirements.txt and press OK to add it.
- The TextualRequirements document is now added to the module TextualRequirementsModel in the Organizer and the Text Editor showing the document is opened. The document looks like Example 651.
Example 651 : The textual requirements
The task is to design the software to support a computerized Access Control system. The purpose of the system is to control the accesses to an office.
An entrance leading to an office can have four different security levels:
The security levels of an office entrance can be altered during the day.
Each employee working in the office has a card with a personal code consisting of four digits. To open a door with security level three, the employee enters her card into a card reader and types her personal code on a keypad. The time between consecutive keystrokes when typing the code is not allowed to exceed three seconds. To enter through a door with security level two, the employee just enters her card into a card reader.
Each entrance leading into the office consists of a door with an electric lock as well as a card reader, a keypad and a display on the outside, and an exit button on the inside. The employee needs a card and a code to enter the office. To exit, the employee just presses the exit button and the door is unlocked for ten seconds.
All entrances communicate directly with a central controller which makes sure that a validation of the correctness of cards and codes is performed. The controller has access to a database consisting of all card numbers and their corresponding personal codes. If the card is valid and, in case of security level three, the corresponding code correct, the door is unlocked for ten seconds and the employee may enter. In case of an invalid or unregistered card, access to the office is not allowed. In case of an incorrect code, the employee is informed of this and must try again by entering the card into the card reader and retyping the personal code.
The Access Control system must read its data, consisting of card numbers with their corresponding personal code, from a database. The database is managed by using a separate management system that is not developed within the project. The system operator, who is running the management system, is authorized to register new employees, cards and codes, to change a code if the employee wishes so, to delete employees from the database and to change the security level of an entrance. The system operator is also responsible for initializing the Access Control system. All the actions mentioned above are done using the management system.
The system must be able to recover from computer and connection failures. If a connection between an entrance and the central controller is lost, the door is locked from the outside not permitting anyone to enter (i.e. security level four is set). It is, however, possible to open the door from the inside by means of the exit button.
The system must be extensible to include new functions and be easily maintained.
Creating Textual Endpoints
Now you should study the textual requirements document and mark all concepts (nouns) that you find essential for the problem domain as link endpoints. These marks will be very useful in later stages of the project. In this tutorial most of the endpoints in the textual requirements document have already been created. You task is to add the two missing ones:
- In the second sentence of the textual requirements document locate the word "office" and mark it with the mouse.
- In the Link submenu in the Tools menu, choose Create Endpoint.
- The text will be underlined indicating that the text fragment now is a link endpoint.
- Now, locate the word "entrance" in the third sentence and create an endpoint out of it by repeating the procedure above.
- If you go through the rest of the document you can see that the rest of the important concepts already have been marked as endpoints.
- Save the document.
- Open the Link Manager. This is done by choosing Link Manager in the Link submenu in the Tools menu. You can do this either in the Organizer window or in the Text Editor window; the result will be the same.
- Save the link file from the File menu, giving it the name Links.sli.
- Close the Link Manager window.
Creating the Data Dictionary
A data dictionary is a textual document which should define all important concepts found during the whole development process. It forms a common vocabulary for the members of the project. It is a good idea to:
- Provide each item included in the data dictionary with a name and a brief explanation.
- Categorize the concepts in nouns, verb phrases and relation phrases.
- Sort the concepts alphabetically.
- Have a section in the data dictionary for each activity. This might be a good idea because a certain concept often has different meanings in different activities. For example, a concept can be described by a class in one activity and in the next activity it might be described by a block with a corresponding process.
All the important objects, relations and verbs that you find in the textual requirements should be included in the data dictionary. This has already been done in an existing DataDictionary file, so you do not have to do anything. Just add the existing file:
- Add the existing DataDictionary.txt file to the DataDictionaryModel module in the Organizer. The Text Editor will show the DataDictionary.
- Read through the document to get yourself acquainted with the problem domain vocabulary.
All nouns, relation phrases and verb phrases in the data dictionary are marked as link endpoints. This has been done to make it possible to do entity matches between any model and the data dictionary. An entity match checks that all entities in one model have matching entities in another model. That is, we can check that all entities in a model really are described in the data dictionary. This will be performed in Entity Match.
The example below shows a part of the requirements analysis data dictionary.
Example 652 : A data dictionary
Access control system - A system to control the access rights to an office so that no unauthorized persons can enter without permission.
Card - Each employee working in the office gets a card and a corresponding personal code. By means of this card and code, the employee can get access to the office.
Cardnumber - The number that uniquely defines a card.
Card with code - Each employee in the office has a card with a personal code.
Connection between central controller and entrance - There is a connection between every entrance and the central controller.
Change code - An operation done by the system operator to change the code of a card.
Change Security Level - An operation done by the system operator to alter the security level of an entrance.
Connection is lost - The connection between an entrance and the central controller can sometimes fail. In case of broken connection nobody can enter the office. It is, however, possible to leave the office.
Creating the Use Case Model
The purpose of a use case model is to capture the requirements and present them from the users point of view, thus, making it easier for the intended users to validate the correctness of the requirements analysis.
The use case model consists of:
- A list of actors
- A list of use cases
- A number of MSCs (message sequence charts) and/or textual use cases
The use case model is also a useful source of information when developing the requirements object model, see Creating the Requirements Object Model.
A use case is a sequence of actions showing a possible usage of a system. Use cases developed during the requirements analysis activity should mainly concern the interaction between the system and the users of the system. No message exchanges within the system should be shown.
Users of a system may be people, other systems or objects outside the system border which interact with the system.
An actor is a user taking part in a use case. An actor is not supposed to be an individual user, but rather represents one of the different roles a user can play when interacting with the system.
There are different ways to describe a use case:
- A textual description of the use case
- A description of the use case using an MSC
- A combination of both a textual description and an MSC
Describing use cases using textual descriptions will make it easier to model exceptions and alternative paths of action sequences. Describing use cases using MSCs will make the use cases more formal and easier to verify. Also, as MSCs will be used in the coming activities, it might be a good idea to start using them already in the requirements analysis. The tutorial will use both textual descriptions and MSCs in the requirements analysis activity, and only MSCs in the later activities.
Creating a List of Actors
Now it is time to create a list of actors. The list of actors should list the actors by name, together with their respective responsibility.
- In the Organizer, select the RequirementsUseCaseModel module and choose Add New. In the Add New dialog, set the Text radio button and choose Plain in the corresponding option menu. Name the new document ActorsList and set the toggle button Show in Editor. This will give you a new text document in the Organizer window and an empty Text Editor window will pop up.
- Try to find the actors of the Access Control system by studying the textual requirements in Example 651. For information on how to find actors, see Finding Actors below.
- List the actors by name in the newly created textual document together with a brief description of the actor's role when interacting with the system.
- Mark the actors in the ActorsList as endpoints in the same way as you did in Creating Textual Endpoints.
- Save the document giving it the name ActorsList.txt.
Finding Actors
You will find actors by studying the textual requirements. Useful questions to ask are:
- Which users will need services from the system to perform their tasks?
- Which users are needed by the system to perform its tasks?
- Are there any external systems that use or are being used by our system?
In practise, the activity of defining actors should be performed iteratively. Try to find as many of the actors as possible now. If you do not believe you found them all, start creating some MSC use cases (as having done some MSCs often makes it easier to determine the actors). Then go back and complete the list of actors.
In our case with the Access Control system we find that an employee, who daily interacts with the system, is an obvious candidate for the list of actors. Also, considering the third question above, it is obvious that the management system is being used by our system and therefore should be added to the list. The third actor, the door, may not be so easy to find at a first glance, but when you have created the MSCs it will become more evident that the door is an actor as well. The door's interaction with the system consists of notifying the system every time it is opened or closed.
The example below shows a part of the list of actors.
Example 653 : Part of a list of Actors
Employee - Someone who needs to enter and exit the office. To enter the office, an employee must have a registered card and (depending on the current security level) a corresponding personal code. To exit, the employee must press an exit button to unlock the door.
ManagementSystem - The management system starts and maintains the Access Control system. All changes to the database are handled by the management system. The management system is run by a system operator.
Creating a List of Use Cases
When you have defined the set of actors it is time to describe the way they interact with the system, which is done in use cases. The first step is to create a list of all use cases. The list of use cases should list the use cases by name together with a short description.
- Add a new plain text document in the RequirementsUseCaseModel module. Name it UseCaseList and set the toggle button Show in Editor. Press OK.
- Try to find the normal use cases and list them in the newly created textual document. For information on how to find use cases, see Finding Use Cases.
- To each use case, add a general one-sentence description of its functionality.
- For each normal use case, examine which exceptions that can occur and state these exceptions as well in the list.
- Mark the use case names in the UseCaseList as endpoints.
- Save the document giving it the name UseCaseList.txt.
Finding Use Cases
It is often quite easy to identify use cases by looking at the purpose of the system. To verify that you have identified most of the important use cases you should:
- look at the list of actors, and, for each actor,
- identify the tasks that the actor should be able to perform and the tasks which the system needs the actor to perform. Each such task is a candidate for a new use case. It is often very useful to check the textual requirements document for verb phrases (or you could look directly in the DataDictionary to see which verb phrases that have been stated as important); these are possible candidates for use cases.
Start with the employee actor and try to determine which actions he or she needs to perform. There are different ways to enter an office, either using a card or using both a card and a code. Both ways are obvious candidates for the use case list. Also, the employee must be able to exit the office, this will be yet another use case.
The Management system must inform the Access Control system when there has been a change in security level. This will be our fourth use case.
As for the door actor, the task of notifying the system when a door is opened and closed can be included in the enter/exit office use cases. You should always try to make the use cases as complete as possible, that is, make one complete use case instead of several minor ones.
When you have found the normal use cases, refine them by examining the exceptions that are possible for each use case. Look in the textual requirements document and try to find the exceptions that can occur.
In the case where an employee enters the office, the first thing that can go wrong is that there is a connection failure between the entrance and the central controller. Other possible things that can fail are that the card is invalid, the code is wrong, the time between consequent keystrokes when typing the code is too long, and, finally, the door is never opened even though it was unlocked. All these exceptional cases can be found by studying the textual requirements thoroughly.
The example below shows a part of the use case list.
Example 654 : Part of a Use Case List
- Enter_Office_With_Card - Describes the interaction between an employee and the Access Control system when the employee wants to enter the office through a door with security level two.
- Enter_Office_With_Card_And_Code - Describes the interaction between an employee and the Access Control system when the employee wants to enter the office through a door with security level three.
- Exit_Office - Describes the interaction between an employee and the Access Control system when the employee wants to exit the office.
- ...
- Exc_No_Connection
- Exc_Invalid_Card
- ...
Creating a Textual Use Case
Now that we have a list of the actors to the system as well as a list of use cases, we can start to create a more detailed description of the use cases. A textual use case consists essentially of natural text structured into a number of text fields, see Describing a Textual Use Case. In this exercise we will only create one textual use case, as creating them all takes too much time. The use case we will focus on throughout the rest of the tutorial is the one where an employee enters an office with both a card and a code.
- Add a new textual document in the RequirementsUseCaseModel module and name it Enter_Office_With_Card_And_Code.
- Try to create the textual use case consisting of the fields described in Describing a Textual Use Case.
- Create endpoints of the textual use case name (for consistency use exactly the same name as you used in the list of use cases) and of the actors involved in the use case.
- Save the document giving it the name Enter_Office_With_Card_And_Code.txt.
Describing a Textual Use Case
A textual use case should consists of the following fields:
- Name: The name of the use case.
- Actors: A list of the actors involved in the use case.
- Preconditions: A list of properties that must be true for this use case to take place.
- Postconditions: A list of properties that are true when the use case is finished.
- Description: A textual description of the normal sequence of events that describe the interaction between the actors and the system.
- Exceptions: A list of exceptional interactions that complement the normal flow of events described in the Description field. If an exception leads to different postcondition properties compared to the normal sequence this should be noted.
The description field should thus describe what happens when everything is going as expected. No exceptions should be considered here. They are not described until the exceptions field.
The example below shows a textual description of the use case "Enter office with card and code."
Example 655 : A Textual Use Case
Use case name: Enter_Office_With_Card_And_Code
Preconditions: System is initialized, security level three is set, and the door is closed and locked. The display displays "Enter card".
Postconditions: The door is closed and locked again.
Description: An employee enters a card into the card reader. The display displays "Enter code". The employee enters a code consisting of four digits using the keypad. The door is unlocked and "Please enter" is displayed. The employee opens the door, enters the office and closes the door again. The door is locked and "Enter card" is displayed.
- If the employee enters an invalid or unregistered card, "Invalid card" is displayed for three seconds and then "Enter card" is displayed.
- If the time between consequent keystrokes when typing the code exceeds three seconds, everything is interrupted and "Enter card" is displayed.
- If the employee types the wrong code, "Wrong code" is displayed for three seconds and then "Enter card" is displayed.
- If the employee does not open the door within ten seconds after it has been unlocked the door is locked again and "Enter card" is displayed.
- If there is no connection between the entrance and the central controller and a card is entered, then the text "Connection failure" is displayed for three seconds and then "Enter card" is displayed again.
Creating an MSC Use Case
The second notation for use cases used in SOMT is MSCs. Creating MSCs for all the use cases and their exceptions takes too much time in this tutorial. Therefore you will concentrate on the use case corresponding to the textual description you just created, Enter_Office_With_Card_And_Code, and one of its exceptions, when an employee enters an invalid card.
- Select the module RequirementsUseCaseModel and choose Add New. In the Add New dialog, set the MSC radio button. Name the document Enter_Office_With_Card_And_Code and set the Show in Editor toggle button.
- In the MSC Editor, try to create the MSC. Look at the textual description of the use case and describe it by means of the notations defined for MSCs. Also, make references to exceptions at the points where these can occur. Figure 724 shows an example of the complete MSC.
- Each actor should be represented by a separate instance. The Access Control system itself should also be represented by a separate instance.
- Actions, displayed messages, etc. should be drawn as MSC messages between the instances.
- An exception is drawn by adding an MSC reference symbol, located last in the MSC Editor's symbol menu. An MSC reference symbol is a reference to another MSC, described in a separate MSC diagram. The symbol is added to one of the instance axes. By convention, MSC exceptions are named "exc" followed by the name of the exception. To connect the symbol to all three axes, select Connect from the Edit menu. Press the Global button to connect the reference symbol to all axes.
- Save the MSC diagram giving it the name Enter_Office_With_Card_And_Code.msc.
- Create a new module in the Requirements Documents chapter in the Organizer. Name the module MSC_Exceptions_ReqA.
- Add a new MSC document to the newly created module in the Organizer and name the document Exc_Invalid_Card.
- In the MSC Editor, try to create the exception, i.e. describe what happens when an employee has entered an invalid card.
- Save the diagram giving it the name Exc_Invalid_Card.msc.
- In the Organizer view, select the MSC Exc_Invalid_Card and then choose Associate in the Edit menu. The Associate dialog appears.
- Choose to associate the Exc_Invalid_Card MSC with the Enter_Office_With_Card_And_Code MSC as it is an exception to this use case.
The Requirements Documents chapter should now look like in Figure 726.
In reality you repeat the steps above for all the use cases found and associate each one of them with its exceptions. In this tutorial, however, we will not create the entire use case model as that would take too much time.
Now, when we have our use cases and a data dictionary we will continue the activity with producing a requirements object model. In practise, you should work with all the models in parallel. The activities in SOMT are not supposed to be performed in a sequential order, rather, producing the models is a highly iterative process.
Creating the Requirements Object Model
The requirements object model is intended to capture the objects, the relations between these objects and other concepts of the real world that are of importance for the application we intend to build. There are different types of concepts that can be described in this model. The two major diagram types show the logical structure of the data and information and the context of the system.
Relations between objects in the model will be expressed through associations, aggregations and inheritance.
Creating a Requirements Object Model
Now you should create the requirements object model.
- In the Organizer, select the RequirementsObjectModel module and choose Add New. In the Add New dialog, set the UML radio button and make sure the Object Model option in the UML option menu is set. Name the new document LogicalStructure and set the toggle button Show in Editor. This will pop up an empty OM Editor window.
- Try to find the objects, see Identifying the Objects.
- Enter the classes found into the object model diagram in the OM Editor and give them a suitable name. As you can see, every class is automatically marked as an endpoint.
- Relate the classes by means of associations, aggregations and inheritance, see Identifying the Relations.
- Consider if multiplicity is needed on any of the associations and if so, add it. (Double-click a line to bring up the Line Details dialog.)
- To increase the readability of the model, name the associations or attach role names to the classes. The diagram should look something like in Figure 727 when you are finished.
- Save the diagram giving it the name logicalstructure.som.
- Add yet another object model to the RequirementsObjectModel module in the Organizer. Name it ContextDiagram.
- In the diagram, show the system and the external actors interacting with it. Use collapsed class symbols (select Collapse from the Edit menu). The classes are automatically marked as endpoints.
- Clear the endpoint on the Access_Control_System class as we will not need this. (Select Clear Endpoint from the Link submenu in the Tools menu.)
- Save the diagram giving it the name contextdiagram.som.
Identifying the Objects
The main input sources to the requirements object model are the textual requirements, the use case model and the data dictionary. Other sources of information are domain experts, textbooks etc.
A classical way to find the objects is to study the textual requirements and note all nouns (or look directly in the nouns section in the data dictionary). If a particular noun appears in many places, the concept is probably important for the problem domain and should be modeled in the requirements object model.
The use cases are also helpful for finding the objects. They define the actors that interact with the system and these are obvious object candidates. Other likely object candidates are the entities that are transported in to or out of the system. The use cases are helpful in identifying these concepts as well.
The requirements object model should at least describe all concepts that are visible on the outside of the system. This includes all physical entities that a user can see as well as the knowledge a user must have to use the system. It is, however, not only concepts outside the system that should be modeled in the requirements object model. Concepts inside the system that are so obvious that we know of them already at this stage should be dealt with as well. In our Access Control system, for instance, it is quite easy to see that the system itself is built up of a central control and a number of entrances, each having its own local control. Therefore, in the requirements object model, we do not model the heart of the system as one class, but as two communicating classes.
Identifying the Relations
The information sources when identifying relations between objects are the same as when identifying the objects. Look for relation phrases in the textual requirements (or use the data dictionary as an information source). You may also take a look at each object and ask the questions:
- What services does the object provide?
- Does the object need services from other objects to complete its services?
If the object needs services from other objects, identify these objects and model the relations in the object model.
There are three different types of relations, described below.
The Association Relation
The association relation describes how different classes relate to each other by means of information exchange.
The Aggregation Relation
The aggregation relation is a special case of the association relation and it describes a "consists of" relation. For example: a document consists of paragraphs.
The Inheritance Relation
The inheritance relation describes an "is a" relation. For example: a car is a vehicle.
Entity Match
Now it is time to do some consistency checks between the created models. When you do an entity match you check that all entities in one model have matching entities in another model.
- Open the Link Manager. The window popping up shows all endpoints from the models you have created during the requirements analysis activity.
- To be able to perform an entity match you must be in entity mode (i.e. not in endpoint mode). Press the Show endpoints or entities button in the Tool bar to change to entity mode. (The view in the Link Manager window will look just the same, since one entity corresponds to exactly one endpoint in all our models.)
The first thing we will check is that all important concepts in the textual requirements model are described in the data dictionary.
- Choose Consistency Check in the Tools menu. The Consistency Check dialog appears and you are asked to choose between a link check and an entity match. Set the entity match radio button and press Continue.
- A new dialog appears and you are asked to select the documents representing the from group. Select the TextualRequirementsModel module and press Continue. (As you can see, the text document in the module is also selected when you select the module.)
- Yet another dialog appears asking you to select the documents representing the to group. Select the DataDictionaryModel module and press Check.
- The Link Manager window will show the result of the entity match in a new consistency view. Entities from the from group are shown as normal endpoints and entities from the to group are shown as dashed endpoints. The links shown are temporary links created by the Link Manager to indicate matching entities, see Figure 732.
- As you can see, if you scroll through the Link Manager window, all the concepts from the textual requirements have a matching entity in the data dictionary. (An endpoint from the to group without a matching link from it would have indicated that no corresponding entity could be found in the to group.)
There are a few more consistency checks which you can perform at this point:
- Check that all entities in the requirements object model are described in the data dictionary.
- Check that all important concepts in the textual use cases are described in the data dictionary and in the use case list. Important concepts in a textual use case are the actors and the use case name. The actors should be described in the data dictionary and in the actors list. The use case name should be described in the use case list.
- In this case the from group will be the textual use case, Enter_Office_With_Card_And_Code, and the to group will be the DataDictionary, the ActorsList and the UseCaseList. (You can select any number of individual documents in the list, not only modules.)
- The result shows that the use case name was found in the UseCaseList and that the actors were described both in the data dictionary and in the list of actors.
- Check that all actors in the use cases are modeled in the context diagram and vice versa.
Creating Implinks
Now that we know that all our models are consistent, it is time to add the implinks. Implinks are used to enable traceability between the models.
We will start with creating implinks from the concepts in the textual requirements to the requirements object model, in particular the logical structure diagram.
- Open the Link Manager by selecting it in the submenu Link in the Tools menu if it is not already open.
- Make sure the window shows endpoint view, not entity view or consistency view. If necessary, press the Show endpoint or entities quick button.
- To check that all endpoints are present in the Link Manager window, choose Check Endpoints in the Tools menu.
- The Check Endpoints window will pop up showing if any previously unknown endpoints were found. If so, select these and press Add. Then press Continue.
- Another version of the Check Endpoints window pops up showing if any invalid endpoints were found. In such case you can choose to delete these by pressing Delete. Press OK when you are done and want to close the dialog.
- To be able to create the implinks between the textual requirements and the classes in the logical structure you only need to see the endpoints from these diagrams in the Link Manager window. You do not have to see all the other endpoints. Therefore, choose Filter in the View menu.
- Choose to set the filter for documents and select that the only documents to be shown should be the textual requirements and the logical structure documents.
- Press Apply and then Done.
- In the Link Manager window, highlight the endpoint Text Office by first selecting the endpoint and then clicking the Highlight quick button in the tool bar. The endpoint is highlighted with a frame around it.
- Create an implink to the Class Office by first selecting the class and then pressing the Create Link quick button in the tool bar. The Create Link dialog will open.
- Name the link Implementation Link and press the Create button. A link from the text "office" to the class Office is created.
The rest of the links between the textual requirements and the object model diagram are created in a similar way. You can do this if you want, or go to the next exercise, where this has been done, and check out the result.
Links from the UseCaseList to the different MSCs and their exceptions should also be created. You cannot do this here however, as you have not created all the use cases.
What we aim at here is to create links from the textual requirements, through the object models of the different activities, to the SDL design. Simultaneously we want to create links from the list of use cases, through the use case models in the different activities, to the SDL design. The result of this will be that we can trace a design decision backwards to requirements through either object models or use case models.
Summary
After having completed an entire requirements analysis, the Requirements Document chapter the Organizer view should look like in Figure 733.
http://www.ibm.com/rational |
![]() |
![]() |
![]() |
![]() |