Business Process Definition - BPDs

The Business Process Definition (BPD) is the the core of an IBM BPM solution. The BPD represents the model of the business process and is captured early on in the design of the solution. It also allows the process to be easily modified as time passes. At a high level, a BPD is a diagram that represents the overall view and flow of the process. It is commonly constructed by the Business Process Analyst in conjunction with discussions and interviews with other members of staff.

Here is an example of a napkin sketch of a trivial business process for approving a loan. We could imagine a meeting room with a white board where the process of how a loan is handled is discussed. The flowchart like blocks could be drawn on a white board.

In IBPM, the exact same process can be captured as a Business Process Definition in the IBPM Process Designer (PD) tooling. It captures the exact same essence of the process. In fact, it is arguably easier to capture the process in IBPM PD as blocks can be moved around without having to erase the picture and redraw it.

We will further see later that participants at the meeting where the process is being sketched can be remote from each other and yet the same process diagram can be seen on each of their screens.

The diagram style of a Business Process Definition conforms to the industry standard Business Process Model and Notation (BPMN) format.

When a Business Process Definition is created it is given a name and lives inside a Process Application solution. A Business Process Definition is created inside the IBPM PD tooling from the library section within the Processes category:

The wizard for the Business Process Definition (BPD) asks for the name of the new BPD which is to be created.

Once created, the main canvas area of the BPD editor is shown:

This main area of the window is called the canvas and is where we visually model the process solution we wish to construct. Icons representing the activities and other elements of the process can be dragged from the palette of available types shown on the right of the window. These icons can be dropped onto the canvas and wired into place using Sequence Lines. Each icon represents a "step" in the process.

The icons conform to the Business Process Model and Notation (BPMN) style and their interpretation is also that of BPMN.

The palette of available icons are:

|| ||Activity – see Activities| ||Lane – see Pools and Lanes| ||Milestone – see Pools and Lanes| ||Decision Gateway – see Gateways, Conditionals and Joins| ||Note| ||Start Event – see Start Event| ||End Event – see End Event| ||Intermediate Event|

Contained within these major palette entries are the other BPMN components:

|| |||Task Types| |||User Task| |||System Task| |||Decision Task| |||Script| |||Subprocess| |||Linked Process| |||Event Process| |||None| |||Gateways| |||Exclusive Gateway| |||Parallel Gateway| |||Inclusive Gateway| |||Event Gateway| |||Start Events| |||None Start Event| |||Message Start Event| |||Ad Hoc Start Event| |||Content Start Event| |||Intermediate Events| |||Message Intermediate Event (Receive)| |||Message Intermediate Event (Send)| |||Timer Intermediate Event| |||Content Intermediate Event| |||Tracking Intermediate Event| |||End Events| |||None End Event| |||Message End Event| |||Error End Event| |||Terminate End Event|

Pools and Lanes

Think of an Olympics swimming competition where multiple swimmers swim against each other for the fastest time. Each swimmer swims in the same swimming pool but is constrained to swim only in their own swimming lane. The canvas drawing area of the BPD also contains such a model. The canvas as a whole represents the pool while multiple lanes can be added to segment the pool into horizontal sections. When an icon is added to the diagram, its vertical position on the diagram means that it "lives" in only one lane. This serves two purposes. First, if we associate a lane with a particular "role" in the process, then we can quickly see simply by looking along the row of the lane which activities are associated with which roles. Conversely, if we assign attributes to a particular lane, then activities found in that lane can inherit those attributes.

Here we see an example of a BPD pool with a couple of lanes:

Additional lanes can be added by dragging a lane icon from the tools palette:

When a lane is added to the diagram we can specify some primary attributes:

Every lane has a Name attribute so we should supply a meaningful name that will remind us of its purpose. A Presentation Color can be assigned which will change the background color of the lane. This can be especially useful if you have many lanes and need to read to the far right in order to see all of the process content. The Name of the lane may not always be immediately visible but if colored correctly, will highlight its intent.

For human services, we can assign the set of users that should be associated with the lane. This set of users is known as a Team. When a human service is added as a step on the lane, if no specific human routing instructions are supplied, then the human service will be routed to the members of the Team associated with the lane.

We can re-order the lanes in a pool from their existing values. By right clicking in a lane, a context menu is shown:

Within that menu we can choose to move the selected lane up or down relative to the other lanes in the pool.

Sequence Lines

The lines which are drawn that connect individual steps in a BPD are called Sequence Lines. A sequence line describes which activities will follow other activities in sequence as the process executes. Sequence lines have an arrow head point to the next activity to be executed. When using PD, the following icon can be used to place the tool into a mode where Sequence Lines can be drawn:

When in sequence line drawing mode, the cursor shape changes to include a "plug" in its visual representation. This is to represent the idea of wiring (or plugging) one component into another. When the cursor is over an element that can be the source or target of a Sequence Line, the element's representation changes to show attachment points.

These attachment points serve as the anchors for the start and end of a Sequence Line. To wire two elements together, enter wiring mode and hover the mouse over the originating element. Pick one of the attachment points and click and release. Next move the cursor (without pressing any further buttons) over the target element. A line will automatically be drawn from the source to the target. When over the target, attachment points will again be shown. Pick the attachment point that is desired and click and release once more. A Sequence Line will now connect the two elements.

You can leave wiring mode by clicking on the icon that looks like:

You can tell which editing mode you are in as the current mode icon has a blue background. Alternatively, when in wiring mode, pressing the Escape key on the keyboard will return you to the default editing mode.

A Sequence Line can have its source or target changed. If the line is selected with a mouse click, either endpoint of the line can be dragged to another element.

From the context menu when a Sequence Line is selected, additional "points" on the line called control points can be added. A control point allows the line to have additional junctions in it to further control its visual layout and appearance. This can be used to make the diagram more attractive. The control point can be dragged with the mouse to re-orient the line.

When selected, we can also edit the properties of a Sequence Line:

Amongst these properties are the Name that can be given to the line. This name can be made visible and shows on the diagram.

Here we see a diagram with the text of the line not visible:

and here is the same diagram with the name visible:

In addition, if the Sequence Line is used as the output of a condition gateway, the name given to the line is seen in the gateway's description of the conditions that are used to select which of the possible alternative paths are to be taken.

The condition associated with a decision gateway can also be seen on the properties of the line.

Finally there is an attribute called Line Type which can have a value of Happy Path or of Exception Path. These values do not alter the operation of the process but are used exclusively during process analysis. Most of the time they can simply be ignored.

BPD Overview settings

The first tab in the BPD editor is titled Overview and provides a host of attributes that can be supplied for the BPD itself.

Exposing the Process

The details of who can start an instance of the process and who has authority to examine the details of an instance is defined in the Exposing section. There are three types of exposable information.


Process Instance Name

Each instance of the process has an optional name. The field called "Instance name" supplies a Java Script expression that is used to build the identity of the process. The default value is the name of the process with the numeric instance ID appended. For example:

"MyProcess:" + tw.system.process.instanceId

Take care when renaming a BPD. Experience has found that the default identity expression that is created when a BPD is created for the first time is not changed when the BPD is renamed. What this means is that if the BPD has the original name "XYZ", then the identity of a process instance may be "XYZ:1234". But if the BPD is renamed to "ABC" and the instance name expression not changed, an instance of "ABC" may be given an instance name that continues to refer to "XYZ".

When ever the identity of the process is obtained, the expression defined here is re-evaluated. What this means is that the name of the process can be dynamic and the value of the variables in the process at the time that the expression is calculated will be used. This can be used to good effect in conjunction with the IBM Process Portal where the names of the process instances surface.

Process Instance Owners Team

Within the Overview settings of a process definition there is an entry called "Instance Owners Team" which is a team that is defined as the "owners" of a process instance.

BPD Views Settings

A tab on the BPD editor for a BPD is called "Views":

Within this section of the BPD editor, BPM Human Services can be declared which will be run within Process Portal when a request to look at the details of an instance of this type of Process is requested.


Activities

Without question, the core items in a process are the activities. These are the declarations that some work is going to be performed. From the palette, the activity icon looks as follows:

When added to the canvas, it looks like:

or like depending upon which type of lane the activity is dropped.

The initial properties of an activity look as follows:

Initially, a newly added activity has no implementation. It is merely a "place holder" or a description that something is going to happen here.

Following the core philosophy of the product that everything about the process is contained within a common or single shared model, information about the implementation of this activity will eventually be entered. IBPM provides a set of defined possibilities for implementing an activity. These are:

None – No implementation is associated with this activity. This is most useful when the diagram is initially being drawn and we are not yet ready to make a decision on how this step will best be implemented.

User Task – Implemented as a Human Service. This step in the process will be performed by a human being. - - Human Service

Decision Task – Implemented as a decision service where rules will be executed to make a business decision -

System Task – Implemented as a technical or straight through step without human interaction - - A system service

Script – Implemented as a piece or snippet of in-line JavaScript code. This is most appropriate for one-time data manipulation such as initialization or simple copies of data from one variable to another.

Sub-process – Implemented as a sequence of additional activities where those activities are contained within this process. Think of the Sub-process activity like a grouping or container.

Linked Process – Implemented as a call to another process defined separately.

Event Sub-process – Implemented as a sequence of steps that will be performed concurrently with the main process when an external event occurs.

Many of the implementation types of an activity in the BPD require them to be associated with further details in the form of a Service implementation. We can perform this step in either a top-down or bottom-up fashion. Top-down means we start with the notion of an activity and then provide an implementation for that activity. Bottom-up means we start with an activity implementation and then associate that with a BPD activity. Either technique is valid.

For the most common types of implementation, a wizard is available to assist with the implementation selection/creation. The Activity wizard can be started by right-clicking on an Activity and selecting Activity Wizard...

The wizard allows us to select which type of service to associate with it and, if necessary, create a new service.

If a new service is to be created, the variables in scope in the process are displayed as potential inputs and outputs to the service.

The table cells under the Input and Output columns are click-able and will toggle between true and false. A value of true means that the variable will be an input and/or output parameter to the service while a value of false means that the variable will not be utilized by that service.

Activity Appearance in the BPD diagram

The name of the Activity is used to provide a label for it on the canvas.

The Presentation field allows the activity's appearance to be changed. This does not change its operation but merely changes how it looks to the user who views the BPD diagram. The color entry allows the developer to choose the color used to represent the activity. This could be used to highlight activities based on a convention. For example, red to indicate an activity that interacts with a secure system.

Default

Red

Orange

Yellow

Green

Blue

Purple

Grey

As an alternative to these colored replacements, an Icon representation can be used. Use this with caution/care. One of the key elements of reading a BPD is visual consistency so that a reader can tell very quickly what a diagram means by knowing the set of icons commonly found on such a diagram. If the icons are changed, the reader may not know as quickly what is intended. By clicking the icon radio button next to Presentation, the file name of a new icon can be supplied.

Data Mapping

Many activities have a Data Mapping section. This is the act of mapping the variables in scope in the BPD to the expected parameters of the service that is to be called by the Activity. This applies to both input parameters and output parameters.

The Data Mapping screen area is split into two columns. One for input mapping (mapping BPD variables to the parameters expected by a service) and the other is for output mapping (mapping returned values from a service to the variables in the BPD). Entry assistance is available to bring up lists of BPD scope variables which can be selected.

Note that the variables defined in the scope of the BPD do not have to have the same names as the actual parameters of the service implementation. However their data types should be compatible with each other.

Conditional Activities

When an Activity is reached in the BPD, it may not always be applicable to execute this activity but instead it can be skipped over. An attribute of the Activity in Process Designer can be set to achieve this effect.

In the Properties of the Activity a tab called Condition can be selected.

In the details associated with this tab, a check box called Is Conditional can be checked to flag the Activity as conditional. Activities that are flagged as conditional have an additional visual decoration added to their representation to indicate them as such. The decoration is a small diamond at bottom/middle of the Activity icon.

A JavaScript fragment can be coded in the Script box in the Condition section. If this JavaScript returns a value of true, the activity is performed. If it returns false, then the activity is skipped.

The Conditional Activities feature has one further overload associated with it and it takes a little bit of patience to get one's mind around it. If an Activity is flagged as conditional and has no associated JavaScript then should it be executed or not? The answer to this is dependent on a system variable called tw.system.process.selectedConditionalActivities. This variable is a list of Strings. If the Activity is to be executed, then its ID value will be found in the list. If the Activity is not to be executed, then its ID value will not be found in the list.

Initially, this list is empty and hence none of the conditional activities that have no JavaScript associated with them will be executed. This variable can be assigned inside the process to add (or remove) activities to be executed. To aid in the population of this variable, another system variable can be used called tw.system.process.conditionalActivities. This variable is a list of all the possible activities in the current BPD that are flagged as conditional. The entries in this list are of type ConditionalActivity. A ConditionalActivity instance contains both the name (as seen in the BPD) and id (GUID for the activity as needed in the tw.system.process.selectedConditionalActivities) variable. Using this list, algorithms can be used to select which activities to enable for execution and which to skip.

A common pattern of usage of this feature would be to present selection to the user to determine which activities should be executed and which not. IBPM provides a pre-built Human Service that performs exactly this function. That Human Service is called lsw Conditional Activity Selection Coach.

Note: Although this is a fully supported feature of the product and can be used in any production environment, experience has shown that very few uses of this capability have been seen. This is mentioned not to dissuade you from using it but rather to alert you to the notion that it is likely not critical that you spend too much time learning this function.

Activity Behavior

With the arrival of the 8.5.5 release, a significant additional feature set was added to BPD modeling. As a whole and within the Process Designer development tooling, these new capabilities are called "Activity Behavior". This name is virtually meaningless and the concept is rather subtle but extremely important so we will take our time to explain it.

First, let us consider a simple process flow that looks as follows:

The way we should interpret this is that when an instance of a process starts, a User Activity called "Task 1" is created and the process then waits for the associated task to be completed. When it does complete, process flow continues on to the end of the process at which point the process instance is considered complete.

Now let us introduce an additional modeling construct. Visually, it looks as follows:

What is different in this diagram is the addition of a second User Activity called "Task 2". However, this activity is considered to be "unwired". What we mean by that is that there is no path leading into the activity and hence it would appear to be non executable. New in 8.5.5, these unwired activities have interesting semantics. The semantics will be described momentarily but first, let us look at the details of the Process Designer implementation tab which is where we will configure the operational attributes for unwired activities:

Within the implementation section, there is a new grouping of configuration properties under the banner of "Activity Behavior" (If anyone can think of a better name for this concept, let me know). These options only appear if the activity is unwired. It is here we will concentrate most of our discussion. However, before we do that, there is a simple piece of housekeeping we need to get out of the way.

Prior to version 8.5.5 activities placed in a BPD but with no input links to them were simply ignored. This meant that activities could be placed within a BPD during testing with no side effects to the operation of the BPD other than potential visual clutter. A developer might leave these unwired artifacts in place for future regression testing or for other purposes. With 8.5.5, unwired artifacts now have new meaning but this could result in BPDs brought in through migration from earlier releases no longer working as expected and that would be disastrous. Fortunately, IBM has provided a solution. Immediately above the Activity Behavior header is a check box labeled "The activity runs even though it does not have an inbound flow". If this box is checked (which is the default) then the new 8.5.5 semantic processing will happen for unwired activities. If the box is not checked, then the activity will be ignored and operation of the process as a whole will behave as though the activity were not present. Migrated BPDs prior to 8.5.5 will have the option unchecked while new BPDs will have the default of checked. Naturally, a person designing a process can manually change the setting as needed.

With that out of the way, we can now start to discuss what it "means" to have an un-wired activity in the process diagram.

In simple terms, it means that the activity will "run" when the process is started and it will run in parallel to the primary entry flow of the process. Naturally, there is more to say about it than this, but one piece at a time. First, let us discuss the notion of an activity "running." When we start a BPD process we consider the flow as following the linkage from one activity to another. An activity is said to be running (or executing) if the control flow of the process is currently at that activity. Activities performed previously are considered finished and activities that may be performed later are simply not spoken about. If we consider that there are loosely two types of activity … those that are User Activities and everything else … then a User Activity is said to be running if a user can see it in the task list and work upon it. A system activity that is running is one which is actively performing computations or integration logic.

We have just said that unwired activities will run when the process instance starts, however, a new state is now available for unwired activities. That state is called "ready". An activity that is ready logically exists but it is not able to run. In order for it to run, it must be explicitly "started". Once it has been started, it may then run when it is able.

So … that’s a lot of words … lets see if we can't make some of it concrete. Within the Activity Behavior section there is a radio button option which says that an un-wired activity may be either started automatically or manually.

Automatically simply means that the activity will immediately enter its runnable state. For a User Activity, this means that it will be a task in the user's task list able to be worked upon. For example, if we run this process and Task 2 is flagged as automatically started, in the task list we will see:

And that makes sense. Both Task 1 and Task 2 are running and hence can be worked upon. If the unwired activity is a different type of activity than a User Activity, it will simply do what it does.

But what if we flag an unwired activity start type as manual?

What this means is the activity will not show up in the user's task list. It isn't runnable. If we flag the activity as being manually started by the user, it is given a new icon decoration:

The small triangle is used to indicate that it is manually started. This now begs the question … how then does one start such an activity? The answer to this is through the Processes tab within Process Portal.

If we drill down to the process instance which contains our tasks, we see the following:

We see that Task 1 is indeed a running task for this process. No surprise there … however we have a new section in the bottom right called "Activities". In there we see an icon for Task 2. The way we should interpret this is that there is a task called "Task 2" that is ready to be started. If we were to start it, it would become runnable and hence appear as a new task for the process as a whole.

If we click on Task 2, a menu of options is shown to us:

From here we can assign it to ourselves, assign it to ourselves and start it, we can assign it to a named user and start it or simply start it as yet unassigned to anyone. Once it is started, the new display looks as follows:

If we contemplate this, we should now start to see that we have control over when the new task is made available for a user to work upon.

Hopefully you are still with me on this story. As mentioned, it is quite subtle and there is still more to discuss.

What if we complete Task 1 without starting Task 2. Does that mean that process is completed? Well … that depends on another setting. An unwired activity can be tagged as either optional or required (the default). A required activity must be completed before the process as a whole is considered completed. This is irrespective of whether or not the unwired activity is started manually or automatically. If the unwired activity is flagged as manual and has not been started yet but the rest of the process completes, the process will not be considered complete until the unwired activity is subsequently started and completed.

Another way to say this is that if an unwired activity is flagged as required then at some time before the process completes, that activity must be run. It may mean that the activity has to be first started but either way, it must be run.

Having just looked at an activity flagged required, now let us look at what the alternative which is optional means. Firstly, a task flagged as optional has a dotted appearance on its border:

This gives us a visual indication as to whether it is required (solid border) or optional (dotted border).

If the unwired and optional activity is flagged as automatically started and the rest of the process ends, the task must still be completed before the process as a whole is considered complete. Because the activity had started, it must be allowed to finish.

If the unwired and optional activity is flagged as manually started something new happens. The process portal looks as follows:

As expected, we see Task 1 running but notice the icon for Task 2. Instead of a green filled icon, it is a white filled icon. This is the visual indication that it is optional. If Task 1 is completed (and hence the rest of the process), the process as a whole does come to an end. Stating it another way, if an unwired and optional activity has not been started then if the process ends there is no need to start (and hence run) that unwired activity. However, if the un-wired and optional activity was started before the process completed, then that activity must complete before the process is considered finished.

We can tabularize this information:

Start Type Completion Must be run
Automatic Required Yes
Automatic Optional Yes
Manual Required Yes
Manual Optional No

But wait … there is even more function in this area. Another option on un-wired activities is whether the task is repeatable.

By default it is unchecked. This means that once an instance of the activity is started, no further instances of it may subsequently be started. However if we flag it as repeatable, then we can start as many parallel instances of the activity as we like. It is important to understand that we do not have to wait for the previous instance to complete before starting another. Each time we start a new instance from process portal, it immediately starts (and hence makes runnable) a new instance of the activity. An activity that is flagged as automatically started can not be flagged as repeatable. The check-box option is unchecked and made disabled for change.

When an activity is flagged as repeatable, the activity icon is updated with a hash ('#') to indicate such. (Not sure why a hash is considered the icon for repeatability … but ok). An activity flagged as repeating looks as follows:

And finally … there is one more consideration to be discussed. There is the notion of a "precondition." A precondition is a true/false valued expression where the expression must evaluate to true before the activity can be performed. Within Process Designer, there is the following control:

By default it is unchecked which means that there is no precondition and the activity will run as per the preceding rules. However, when it is checked, a new set of options become available to us:

Here we can add expressions which will be evaluated. The expressions can be added by clicking the "+" icon on the right side. When clicked, a new row is shown into which the expression can be entered:

The expression can be made up of variables and constants with an operator between them. By clicking on the "JS" icon to the left (JavaScript) then an expression in JavaScript can be supplied.

When an expression is added to an activity, the existence of that expression is indicated in the diagram by a small diamond:

We should assume that the expression is reevaluated when ever a change is made to variables in the process.

Now let us merge in this new notion with what we learned previously.

If an activity is automatically started but has a precondition, then it simply doesn't get to execute until its expression becomes true. When the expression does become true, it immediately runs.

If the activity is flagged as manually started and required but has a precondition, then if the precondition expression is false, it shows as follows in Process Portal.

There is nothing that can be done with it at this point other than Process Portal showing us that it exists. Until its corresponding precondition expression becomes true, it is ineligible to be manually started.

When the condition becomes true, it becomes eligible to be started and the icon changes to:

If the condition becomes false again, then the activity will remain in its ready to be manually started state.

If the activity is flagged as manually started and optional but has a precondition and that expression is false, is shows in Process Portal as follows:

Again, there is nothing further that we can do with this activity at this point until its corresponding expression becomes true. When it does become true, it becomes eligible to be manually started:

Should the expression subsequently become false before it is started, it remains in its ready to be started state.

The Process Portal icons for activities can be summarized as:

Icon Description
Task may be started and is required.
Task may be started but is optional.
Task may not yet be started and is required.
Task may not yet be started but is optional.

Start Event

The Start Event is a starting node that can be used to indicate the starting point of an instance of a process. When added to the canvas, it looks as follows:

By default, when a new BPD diagram is created, a Start Event node is automatically added to the diagram. The Start Event node is used to model the start of a process.

A BPD can only ever have one Start Event contained within it. Although the PD allows us to mechanically add more than one start event, the run-time detects this and flags it as an error.

A Start Event can only have outgoing Sequence Lines from it. It is not permissible to have any incoming links to it.

It is permissible for a process to have no Start Events but instead it must have one or more Start Message Events. These allow the process to be started from an external event such as a UCA.

If a process has no Start Events and is attempted to be started, an exception is thrown which shows a message similar to:

[9/2/11 11:16:52:717 CDT] 00000089 wle E CWLLG2229E: An exception occurred in an EJB call. Error: Cannot start BPD "BPD3". No start event of type None is found

Author: This message frustrates me … "No start event of type None is found". Personally, I would have preferred to see "A start event of type 'None' was not found within the BPD named 'BPD3'".

The Start Event activity can be triggered by additional mechanisms. From the Implementation Tab of the Start Event, alternative choices may be made:

The Message choice will cause an instance of the process to be created through the arrival of a corresponding event (UCA).

The Content choice will cause an instance of the process to be created through a new document instance being created in the Enterprise Content Management (ECM) system.

End Event

The End Event is used to model the end of a process. When added to the canvas, it looks as follows:

An End Event is added to the default BPD diagram when it is created. There can be multiple End Event nodes in a diagram. The process instance will come to an end only when all the concurrently executing branches reach their End Events. Explicitly, the process will not end when any one single branch reaches an End Event.

Message Start Event

The Message Start Event is a starting node that can be used to initiate an instance of a process due to the arrival of an event. Once added to the BPD canvas, it looks as follows:

An instance of the process can be started based on this element when an external event occurs. The association between the process and the mysterious external event happens as a result of an undercover agent (UCA). When the Message Start Event element is added, the properties of that element allow us to define which UCA should be used:

When the UCA fires, the data from the UCA is passed as the starting data to the new instance of the Business Process that is to start.

The Consume Message check box needs some discussion. Within a BPD instance, a Message Start Event step can consume the message. This means that if there are other Message Start Event steps in the same process that are also listening for this same event, only one of them will be started. If the Consume Message check box is not checked, then all the Message Start Event steps for the same event will be started.

The Condition area is a JavaScript boolean valued expression which is a guard on whether an arriving event will be utilized by this process. The data passed with the event is available in the JavaScript name-space called tw.message.

A process can include multiple Message Start Events signifying multiple entry points into the same process. This is illustrated in the following diagram:

The BPD started when a UCA is fired is always the default process app assuming that multiple process app snapshots exist for the same solution. If a specific snapshot is to be used as the one in which the BPD is to be started, consider using the startBPDByName JavaScript function.


Content Start Event

An additional type of start event is called the "Content Start Event". It is triggered by a life cycle event within a content management system which can either be the internal document store or an external ECM. When added to the BPD canvas, it looks like:

It is selected by adding a BPD start event into the diagram and then changing its implementation type:

Associated with a Content Start Event is a UCA flagged as "Content":

By flagging the UCA as a "Content" event, we are saying that it will deliver a Business Object of type "ECMContentEvent".


User Task

The User Task is a step in the BPD that is designed to be performed by a person. The implementation of a User Task is always a Human Service. A User Task is indicated by a human icon in the top left of the activity box:

When a User Task is reached within the process, the process pauses its execution until the task created by this step is completed. This could take some time and as such the process state is always written to the database and the resources being used by the process released. There can be far more process instances in the system waiting on User Tasks to complete than could be accommodated concurrently in memory. How a user works with these tasks is a separate story told in the Process Portal section.

The User Task has a number of associated properties.

The Subject property of the activity allows us to enter a single line of text to act as a summary of the task. This becomes the title of the Human Task that is created.

The Narrative section is a description of the task. This is especially useful if the activity is a human service as this shows up in the Process Portal. If HTML is added to the narrative, that HTML is displayed in the Process Portal and is interpreted.

The Priority attribute associates a priority value with the task. This can be used by a task list interface to sort or otherwise visualize a list of tasks such that those with higher priority are shown first.


The Due In property defines a due date for when the task is expected to be completed. This due date becomes associated with the task such that user interfaces can guide the user on which tasks to work upon first. It is presumed that those with the same priority but sooner due dates would most likely be the next ones to be handled.

The due date is calculated as the addition of a time interval to the time when the activity was started. Time intervals can be supplied as either hours, minutes or days or from a variable or JavaScript.

The Clean State property is documented in the InfoCenter (8.5) as the following:

Select Clean State if you want to clear the runtime execution state of an activity after it is complete. By default, this option is disabled. Enable this option only when you do not want to store execution data (such as variable values) for viewing after the process finished execution.

It isn't quite clear when one would use this or what exactly it means.

Automatic Flow

Consider the following BPD diagram:

It shows two tasks to be executed one after the other. If we assume that the second task has the assignment set to "Last User in Lane" then what we are requesting is that the user who completed Step A will be the user who works upon Step B. We may now wish the process to automatically proceed to show the user (who completed Step A) the screen for Step B. Explicitly, we don't see a need to have the user go back to the task list and manually open the task. We can achieve this by the use of the "Automatically flow to next task" check box set in Step A.

If checked, when Step A is completed, we now show the next task for that user. There are some constraints to this, specifically, the next task for the user in the same process must be available within a finite period of time. The default is three seconds. This is configured by the "autoflow-timeout" parameter set within the 99Local.xml configuration file. Experimentation has shown that almost any activity between one Human Activity and the next will break the association. It appears that only simple decisions will allow auto flow to work.

An interesting use case for the auto flow capability is to place logic between the tasks such as is shown in the next image:

Here we assume that something entered in Step A is used as a determinant as to whether Step B or Step C should be shown next.

Assigning Activities – Mapping staff to work

For user activities, a basic question comes to mind … which users should be eligible to perform the work? Not all employees in an enterprise have the same roles and responsibilities. For example, if I request the purchase of a new laptop within IBM, it should be a member of the procurement department that should handle that request and not, for example, someone in the advertising department.

Assigning work to the correct people not only results in work being responded to in a timely fashion (if at all) but also has important implications with respect to security. For example, if we are bringing a new employee into our company, the request for salary information may be desired to be processed by someone in human resources and the details of that request should not be visible to others (for example staff in the new employee's same team).

Another consideration is that of balancing workload. If a department has three staff members and two are idle while the third has more work requests than they are able to handle, this is also not a good situation.

To provide answers for these considerations, task assignment can be performed through the Assignments tab in the Process Designer section while editing a user activity.

By default, an activity is assigned to the set of users defined in the Team of the lane in which the activity is placed. The selection of assignment for an activity may be modified by changing the Assign To definition of the activity as found in the Assignments tab in the properties view:

The Assign To property is a pull-down list that defines the selection criteria used to select which people are eligible for the activity.


Both the Lane and Team options also have the concept of a "Team Filter Service". This is an optional service which takes as input a Team data structure and returns a new Team data structure.

The input is the selected team members that would otherwise be those assigned to the work. The output is presumed to be a subset of those team members dynamically selected to perform the work. This effectively allows us to filter the team members. If no team filter service is supplied, the original selection of team members will be used.

It is anticipated that the filtering of team members may need additional parameters in order to make its decision. For example, the staff members necessary to perform a procurement may be chosen from the procurement department dependent on whether it is hardware or software that is being ordered. The team filter service can be supplied additional parameters in its definition. If additional parameters are defined, these will be available to be mapped in the Assignments area:

When looking in detail at a Team Filter service, we find that it has an input parameter called "originalTeam" of type Team and it also has an output parameter called "filteredTeam" also of type Team. It is expected that the service will populate the "filteredTeam" structure with the team members to be included in the assignment.

Take care when using the originalTeam as input. The "members" property is a list of Strings describing the members of the team. We don't know if a member is a simple user or a group of users. As such, we may need to code defensively if we wish to iterate over each user to see if they meet a specific criteria. Here is an algorithm that will give us all users in a given team:

 //Create the resulting empty list
 var users = new Array();  
 //Iterate over each member of the team. A member may be a user or it may be a Role (Group)
 for (var i=0; i\<tw.local.team.members.listLength; i++) {
 var currentMember = tw.local.team.members[i];
 // Try and get the member as a user. If we find one, add it to the user list
 var currentUser = tw.system.org.findUserByName(currentMember);
 if (currentUser != null) {
 users.push(currentUser);
 } else {
 //Try and get the member as a Role. If we find a match, add all the users in the role to the user list
 var currentGroup = tw.system.org.findRoleByName(currentMember);
 if (currentGroup == null) {
 log.info("Problem: Unable to find a user or group called " + currentMember);
 } else {
 var allUsers = currentGroup.allUsers;
 for (var j=0; j\<allUsers.listLength; j++) {
 users.push(allUsers[j].name);
 }
 } //We have a good group
 } //Process as a group
 }
 //Return the list of users we found.
 tw.local.users = users;
 // End of script

A second pull-down on the same preferences area available to all the previous types of assignment choices is called "User Distribution". This option determines which users from within a set of users should be immediately assigned the task.

Re-Assigning Tasks and changing group members

Imagine a BPD instance which includes an activity associated with a team. If the team is associated with an external system group then what will happen if the system group's membership changes after the creation of a task but before it is claimed? The answer appears to be that any tasks already created will honor the new group change.

Unfortunately, there does not appear to be a way to change the makeup of a team after the task is created. So if a task is created with a certain set of potential owners those potential owners are fixed to that task (unless they come from a system group).

Assignment Examples

Here are some examples of some of the more interesting assignment uses.

The Four Eyes Example

There are some processes where two staff members have to review or approve some activity. As an example, let us think about hardware procurement at IBM. If I, as an IBM employee, want a new laptop, I can submit my request to my procurement department. Their process says that the request must be reviewed by two procurement specialists. We can imagine this being implemented in IBPM. A Human Service would be executed that assigns the request to anyone in the Procurement group. If the request is approved we now create a second Human Service and assign that also to the Procurement group. Unfortunately, there is a problem in that simple solution. If the first task is assigned to the Procurement group and "Bob" works on it, the second task will also be assigned to the Procurement group and, unfortunately, there is nothing to prevent "Bob" from working upon and claiming that second task as well. The tasks "have" been handled by "someone" in the Procurement group … it just was the same person each time and that is not the intent of our story.

Fortunately, there is a relatively easy solution.

We build a process that looks like this.

The assignment decisions for both tasks use the "List of Users" feature for owner selection. After the first task has completed, we determine the owner of that task and remove them from the list of potential owners for the second task. A suitable fragment of JavaScript to achieve this may look like:

for (var i=0; i<tw.local.users.listLength; i++){
 if (tw.local.users[i].id == tw.local.userName) {
 tw.local.users.removeIndex(i);
 log.info("Found and removing");
 break;
 }
 }
 log.info("Final list: " + tw.local.users.toXMLString());

The key to understanding this fragment is to realize that tw.local.users is an array of the users that are in a particular group and tw.local.userName is the name of the user that was assigned to the first task.

Assigning a task to a single named user

Consider the notion that within a process we know the identity of a specific user to whom we wish to assign a task. How can we achieve that within IBM BPM?

We create a new Team Filter service called "Single User" that has the following signature:

Its implementation is a single Server Script which contains the following logic:

tw.local.filteredTeam = new tw.object.Team();
 tw.local.filteredTeam.name = tw.local.originalTeam.name;
 tw.local.filteredTeam.managerTeam = tw.local.originalTeam.managerTeam;
 tw.local.filteredTeam.members = [ tw.local.owner ];

What this code does is build the resulting Team object from the original Team object but comprises the new team's membership solely from the identity of the passed in user.

In a User Activity's assignment specification, we can now name the service and the user we wish to assign:

The desired owner can be obtained from a string or a variable. If we want the task to be immediately assigned to this single user, choose a "User Distribution" setting.

Assignment based on user attribute

Imagine there is a user attribute called "geo" that is some geography indicator. Perhaps it is a country. Now assume we have a team and we wish to filter that team to only those members who are part of that geography. One possible way to achieve that would be:

var users = [];
 for (var i=0; i\<tw.local.originalTeam.members.listLength; i++) {
 var currentUser = tw.system.org.findUserByName(tw.local.originalTeam.members[i]);
 if (currentUser.attributes.geo === tw.local.geo) {
 users.push(tw.local.originalTeam.members[i]);
 }
 }
 if (users.length == 0) {
 var managersTeam = tw.system.org.findTeamByName(tw.local.originalTeam.managerTeam);
 tw.local.filteredTeam = managersTeam.asTeam();
 } else {
 tw.local.filteredTeam = new tw.object.Team();
 tw.local.filteredTeam.members = users;
 tw.local.filteredTeam.name = tw.local.originalTeam.name;
 tw.local.filteredTeam.managerTeam = tw.local.originalTeam.managerTeam;
 }
 // End of file

Explicit manager assignment

A scenario that comes up from time to time is the notion that when a task is created, the owner of that task is to be explicitly and manually selected by a manager. What we do not want to do is to have the task assigned to a group of potential owners and have them choose amongst themselves. How then can we achieve that goal?

The first pass at this notion might be the creation of an IBM BPM Team which contains the potential owners and also has a related managers team. If we then associate the user activity with the manager's team, the manager can re-assign to one of the potential owners. Unfortunately, that simply does not work.

Assigning the task to the Managers team means that only the members of the Managers team can be potential owners. If the manager tries to assign to the Potential Owners the manager is denied because as far as the task is concerned, the Managers team are the only potential owners. We must discount this possibility.

The next possibility is the notion of two distinct steps in the process. In the first step we assign a task to the manager who can then see the task's details and choose a team member to actually own the task. Once a team member has been chosen, the actual task can then be created and assigned to a dynamically created team containing only the selected user.

This works great and may be all that we need. However, it has been found to suffer a draw back. When the dynamic team has been created to contain only the single selected user, the task can not subsequently be re-assigned to a different user. The reason for this is that when the task was created, the set of potential owners was fixed at that time to be just the single selected user. We effectively informed BPM that there were no other potential owners now and into the future. We are thus prevented from attempting to assign the task to other users that were not in that initial team (of one) when the task was created.

Another possible solution would be the notion that we assign the desired task directly to the team but as soon as the task is created, we immediately assign the task to the manager. This appears to work using the JavaScript API called "reassignTo()" available on the TWTask instance object associated with the task. The semantics of this API start to get blurry. Even though the manager is not explicitly named as a team member, the task can be assigned to the manager. The manager can then re-assign the task at will. This would appear to be a great solution except for one slight curiosity. Once we explicitly assign the task to the manager, the manager then appears to be able to assign the task to anyone. When I say anyone, I literally mean anyone … whether or not they are members of the original team or not. As long as they have a BPM identity, they are potentially the owners of the task if it is assigned to them. Current discussions seem to show that this is by intent although it feels wrong to me (opinion).

To invoke the JavaScript "reassignTo()" logic is a little tricky. Have a look at the following screen shot:

What this shows is that the task to be executed has a timer associated with it that is to be fired zero seconds after the task is created. There may be a slight lag but it appears to be very quick. Associated with the timer is a post-assignment that contains:

This allows us to capture (as a process variable) the task identifier for the current task. We can then use this in the re-assign to script to perform the re-assignment:

var myTask = tw.system.findTaskByID(tw.local.lastTask);
 myTask.reassignTo("user5");

Timer Events

A timer can be added as an attribute on an existing task or can be an element in the BPD diagram in its own right. The icon for this can be seen in the palette and looks as follows:

Once added, its implementation type should be changed to Timer:

It can be dragged and dropped on to the edge of an existing activity. This is called "attaching" a timer event. A link from this timer can then be associated with a different activity. If the timer fires, the linked activity will be called. In the following diagram, an activity called Human Task has had a timer added to it and that is wired to the activity called Log.

A timer has an associated Trigger On attribute. This is an algorithm used to select when the timer will start ticking.


The Before/After Difference field allows us to specify the time interval relative to the Trigger On algorithm selection. The units for this field can be minutes, hours or days.

The Tolerance Interval is an additional time interval associated with the algorithm. If a task has not been claimed by a user, then when the primary interval is reached, the timer fires as expected. However, if the task has already been claimed, then the additional Tolerance Interval value is used to extend the deadline to complete the task before the timer fires.

The Interrupt Activity option causes the activity on which the timer is attached to end when the timer expires. The icon used to represent the Timer changes depending on the setting of Interrupt Activity:

Icon Description
Interrupt Activity: On
Interrupt Activity: Off

If this option is not selected (which of course means the attached activity continues to run), the Repeatable option may be selected to cause the timer to start again after it has already fired. The timer is restarted as though it had just been reached. A little care should be taken here. If we flag a timer as repeatable and the date/time on which the timer is to fire is an absolute and that date/time has passed, then the timer will immediately re-fire over and over again without much of a pause. It is unlikely that this is the desired result.

Multiple timers can be attached to a single activity.

For the fields which can be used for time values, either constants or variables may be used.

Similar to the attachment of timers to activities, timers can also be added in-line between activities.

This has the same Timer Properties as previously discussed. When this Timer is reached, processing delays until the timer expires. This allows for delaying the execution of a process for a period of time.

When a timer fires, its Post-assignment variables are in the scope of the attached activity. This means that we can copy out the Task instance id that had time out on it.

While working on the development and testing of a BPD that uses Timer Events, the Inspector view can be used to manually fire a timer even though the time interval has not yet expired. This can be useful for testing logic paths. If we right click on the token in the Execution State area, a context menu pops up that provides Fire Timer. If selected, it will fire the timer and the system will behave as though the timer had elapsed.

This is a great solution when one is able to attach a Process Designer but that is only available within a development environment. An alternative which can also be used for testing is to use the Process Admin console and switching to the Process Inspector tab. From here we can view the list of processes and make changes to them. Notice the option at the bottom right of the page. Here we find a list of active timers within the process. We can select a timer and cause it to fire immediately thereby bypassing any waits that may be outstanding.

On occasion, the time when the timer is to fire is not a simple fixed value but must instead be calculated. For example, we might want the timer to fire after four business hours instead of four wall-clock hours. To achieve this, we need to explicitly calculate the date/time when the timer is to fire and supply that as a custom time value.

Tracking Intermediate Event

A tracking intermediate event is used to generate a data point used in performance reporting on process instances. When added to the diagram it looks as follows:

When encountered, a record that this point was reached in this instance of the process is made. In the implementation section of the element, a reference is made to a Tracking Group:

We can define which of the tracking group properties will be populated and with what values. Checking the box next to the tracking group property causes that property to be included in the output record. We can also define which variables or values within the process should be mapped to the tracking group property.

Ad-hoc Start Event

Note: This activity has been deprecated (i.e. IBM recommends that it no longer be used in solutions). The replacement in the behavior attributes of an un-wired activity.

The Ad-hoc Start Event is a mechanism that allows us to start a chain of activities in an already existing process instance. When added to the process, a new entry appears in the options for an instance of this process or in the Process Portal. When the steps associated with the Ad-hoc Start Event are invoked, these steps have visibility to the data contained within the process as a whole.

When added into the BPD diagram, an Ad-hoc Start Event step looks as follows:

The name of this concept ("Ad-hoc event") is an odd one and one I find not representative of what the function actually does. What we really have here is the ability to have an optional "event" passed into the process which causes a new flow of control to execute in the same process context.

The implementation properties of this entity are shown below:

By default, the event can arrive at any time during the life span of the process.

When added into the BPD, you can drop the Ad-Hoc start event in any area. We have the option to associate an Ad-Hoc Start Event with a “milestone.” If added to a milestone, the event is only available when the process is within the milestone area. You switch this on with with the check marks in the implementation area of the Ad-Hoc event. By default, the Ad-Hoc event is available in all milestones (and all swimlanes).


Message Intermediate Event

The Message Intermediate Event is an Event listener that is used to listen for incoming events within a process instance that is already running. Contrast this with a Message Start Event which will initiate a new instance of a process when a message arrives.

The Stand alone listener is seen within a BPD as its own diagram element. When it is reached, it suspends further execution of the process until an event is received or the process is terminated elsewhere.

The other type of Message Intermediate Event is called the Attached listener. It is called this because it attaches to an activity. While the activity is running, if an event arrives, a link coming from the Message Event will be followed. An option called "interrupt activity" available on an attached listener determines whether or not the outgoing link from the activity will also be followed when the activity completes. If "interrupt activity" is checked, then if a message arrives, the activity is cancelled.

Because a Message Intermediate Event listener lives within an existing process instance, when an event occurs that event must be matched against the correct instance of the process for which the event is destined. The ability to match the event against this correct process instance is called "correlation".

The Message Intermediate Event is actually watching for the arrival of a UCA. When that UCA arrives, the event is said to have happened. This is the mapping between the logical concept of an event and the actual implementation of an event within the IBPM product.

The settings for an Attached listener are as follows:

The settings for a Stand alone listener look like:

Now, what if the event that would trigger the listener occurs before the listener is reached? This is where the concept of the Durable Subscription comes into play. If this flag is checked, then the arrival of an event before the listener is reached is remembered and when the process reaches the Message Intermediate Event, it is immediately notified that the message is available and the solution can continue. If this flag is not checked, then the event that arrived previously is discarded and the process will wait for a further event.

The Consume Message option is used to indicate that if this event listener is triggered by an event, should a subsequent event listener also be triggered by this same event? If Consume Message is checked then the next occurrence of the listener will not be triggered by this event occurrence.

Consider a message arriving that says "Payment has been received." This is great news and now the process can continue. But wait a moment … we seem to have a problem. Assume that I am a car salesman and I have two separate customers waiting in my office. My finance department calls me and says that the payment has been received and the customer can leave with the car. This by itself is not sufficient. I have two potential recipients of keys … for which customer has the payment cleared?

In IBPM, the challenge is that when an event is to be delivered to a process we must know to which instance of the process should the event be delivered. To resolve this problem, an event must carry with it sufficient information to allow IBPM to uniquely identify to which instance of a process the message should be delivered. This information is called correlation. We need to correlate an incoming message with the process instance to which it is to be sent.

A Message Intermediate Event is always associated with a UCA and a UCA can carry data with it. In the IBPM PD, we can specify a variable who's value must match that of an incoming event's UCA payload in order to be considered a match.

Note that it is vital that each of the UCA Output Correlation fields name a local variable even if they are not to be used for the correlation mapping. Currently, the product only allows the selection of a single variable for correlation matching. If the match requires additional comparison, then a new variable must be defined which will be the concatenation of multiple values. In the UCA associated General Service, the incoming data will also need to be concatenated together to build the matching data.

With this background information in place, we can now look at some potential usage scenarios. The first one we will choose is the idea of the Multi Wake-up. In this scenario, we will have a single process with two parallel Intermediate Message Events both waiting on the same event:

What we desire is for both of these to block and wait for a new event to arrive.


In addition to blocking waiting for a message to arrive, the Message Intermediate Event can also be used to invoke a UCA which is the logical equivalent of generating a new message. A Message Intermediate Event can be visually seen as sending a message rather than waiting for a message because it has a different representation in the BPD diagram. Specifically, it has a black envelope icon:

In the Implementation tab of the activity there is a selection option in which we can define it to be either receiving or sending. Changing it to Sending results in the invoke of a UCA when reached. The name of the UCA is also supplied on this section. Once a UCA has been chosen, any data passed as input into a UCA of that type can be defined in the Data Mapping section.


Message End Event

The Message End Event ends the current path of the process and fires an event. When added onto the canvas, the Message End Event looks as follows:

It's implementation properties are:

When reached, it causes the Event associated with the configured UCA to be fired and then ends this path in the process. This activity is useful for modeling a final outcome of a process flow.

Terminate Event

The terminate event activity looks as follows when added to the canvas. It is added from the End Event palette entry and then changed in its implementation settings.

This activity will cause the immediate termination of a process instance. If there are multiple branches of control within the process, the first branch that reaches a terminate event will cause the immediate termination of all branches. Putting it another way, it will close all outstanding tasks and cancel any timers.

A check box on the implementation section of this event allows us to flag it as terminating the entire process instance or just the process part in which the terminate end event is found. This comes into play when we think about linked or sub-processes.

Error Intermediate Event

An Error Intermediate Event may be attached to an activity. Control is passed to this event handler when an exception is caught within the implementation of that activity. In a typical diagram it may look as follows:

The exception occurrence details are available within the variable called tw.system.step.error. Note that this variable only has a value within the activity that populates it. This means that downstream from the Exception handler, it will have no value. The details of the exception should be copied out of the Intermediate Exception Event to a local variable of type XMLElement in a Post-Assignment expression if they are to be subsequently used.

The exception details can then be retrieved from the XML element variable.

In general, the format of the XML returned is as follows:

\<error type="..." description="..."\>
 \<cause type="..." description="..." /\>
 \<localizedMessage type="..." description="..."\>text\</localizedMessage\>
 \<message type="..." description="..."\>text\</message\>
 \<messageKey type="..." description="..." /\>
 \<stackTrace type="..." description="..."\>
 \<element type="..." description="..."\>text\</element\>
 …
 \</stackTrace\>
 \<toString\>text\</toString\>
 \<stackTrace\>text\</stackTrace\>
 \</error\>

The Implementation section of this activity has additional properties.

Error End Event

If a process detects that an error condition has occurred, it can terminate the remaining and current steps of the process and throw an Exception. This exception can be caught by higher level exception handlers or passed on to the user.

To add this item, drag an End Event activity from the palette and change the implementation type. The resulting icon in the canvas looks as follows:

It has properties that look like:

Here an error code and error data can be supplied that are passed onwards with the exception details.

Gateways, Conditionals and Joins

Gateways are decision points in the BPD. When reached, an expression is evaluated and based on the outcome of that expression, control flows in different paths. In IBPM, the JavaScript language is used to evaluate the decision's outcome.

The simplest gateway is called the Exclusive Gateway. The outcome of the expression is a boolean (true or false) outcome. The output of the decision is always that a single path is taken. On the diagram, it looks as follows:

In an actual BPD usage situation, it may look like:

The inclusion of the decision gateway in this fashion is called an explicit decision gateway because the decision icon is explicitly included in the diagram. An alternative construct called the implicit decision gateway looks as follows:

Here, the decision links come straight from the preceding activity. Although semantically equivalent and hence the visual style is all that separates them, the explicit decision gateway is much more commonly seen than the implicit style.

The second type of gateway is the Parallel Gateway. It does not have an expression associated with it. When reached, all the paths associated are followed in parallel. Each followed path is termed a branch.

To join the paths again, the same primitive can be used as a join

The third type of gateway is called the Inclusive Gateway. Like the simple decision, there are expressions involved but in this case, control can flow from this primitive in one or more directions assuming multiple conditions evaluate to true.

For an Inclusive Gateway and Simple Decision, one path is defined as the default and is taken if none of the expressions associated with the other paths evaluates to true. The default path is visually marked as the default by having a “bar” through it.

Here we see a decision with no visible label on the link connection:

By selecting the link between the decision and the next component, in the properties view, a tab called Line is shown. Now we can give it a name (“Yes” in this case) and check the box that the name should be visible.

The result is that the name is now shown on the line:

This makes the overall diagram much more readable as now one can tell just by looking at a decision box in a diagram the logic associated with a decision outcome.

For gateways that have expressions associated with them, the expression can be entered in the Implementation section in the Properties view:

The expressions are supplied as JavaScript expressions. When expressions are defined, there is always one item that is defined as the default line. This link will be followed if none of the expressions evaluate to true. The order of the expressions is important. For an Exclusive Gateway, only one path is followed. If multiple expressions could evaluate to true, the first expression that is true is the one followed. This means that the order of evaluation has a bearing on the outcome of the logic flow. The expressions can be re-ordered up or down using the arrows to the right of the expressions. The default line is always the last in the list.

The Joins in a process diagram also need some explanation. If we look at the BPD palette we see three possible different types of joins so let us look at how they differ and how they might be used.

The first one we will look at is the exclusive join.

In this case, if either A or B complete, then C will start. There is no synchronization. If one thinks about this, there is a new question to be asked. Obviously, one of A or B will complete first and C will be started … but what happens when the other of A or B then completes? The answer is that a second instance of C will start. From a token perspective, the token from A will pass to C and also the token from B will also to pass to C.

The next join we look at looks like this. This is a synchronizing join. In this instance both A and B must complete before C is allowed to start.

From a token perspective, the tokens from A and B are merged at the join to form a single token which is propagated onwards. With this join, all inputs must be satisfied before C can progress.

Still looking at the same join, give some thought to this pattern:

Notice that only one of A or B will execute as the condition gateway is an either/or. The join expects all inputs to be satisfied before continuing onwards towards C. Since only one of A or B will execute, this is an invalid diagram as the join will never be satisfied.

This brings us to the last type of join.

This join has somewhat "magical" properties. Again, it is a synchronizing join and will wait for all possible inputs to arrive before it continues but the magic here is my use of the word "possible" inputs. In this diagram, it will know that a token will arrive only from one of A or B and when one arrives, it will pass on to "C." However, if there were other diagram structures where other tokens could arrive, it will wait for those. Think about this join as being able to do work to see the bigger picture and know what possible tokens could arrive and for the ones that will come in the future, will wait but if there are no further tokens that will arrive, it will allow control to pass onwards.

There is one final gateway type that is called the Event Gateway. Strictly speaking, this should really be considered an intermediate message event but it is grouped in the gateway section in the PD tooling.

The event gateway waits for a message to arrive but, if a message has not been delivered within a time period, the gateway times out and follows the path associated with the timer. This allows us to wait for a message and, if none has arrived, we can timeout.

In addition to using the expression mechanism described above, one can also use the Decision selection:

In the Decision section, a Decision Service can be mapped to be called. It can be passed any mandatory parameters needed for its execution. This decision service is invoked when the gateway is reached. The resulting output parameters from this decision are available in the variable name-space that starts "tw.decision.*". These values can then be used in the expressions to determine which path the process should follow.

Modeling sub-processes

Within a BPD, we can create a sub-process. A sub-process is simply a grouping together of a set of activities into an aggregate area. For example, consider the following process diagram:

Here we see us take an order, package the order (getting more stock if we are out) and finally shipping the order. What we need to pay attention to is the center part of our diagram. The details of ordering stock (if needed) is perhaps not necessary to understanding the overall flow of our process. Instead, we might want the diagram to look as follows:

Notice the marker on the Build Order step. This indicates that this is a sub-process. If we drill down into this step, we find:

What we have done is nested the steps for the Build Order activity as a grouped/hidden sequence of steps. This sub-process shares the same variables as the parent. In addition, the names of the steps defined in the sub-process must be distinct from those of the parent. It is as though the steps were placed "in-line" in the parent process and have simply been hidden for readability. An important aspect to note is that there is no re-usability of these sub-process steps. Their hiding in a sub-process is for readability only.

Experimentation has shown that if a Terminate Event is met within a sub-process then the sub-process is terminated and control is returned to the step following the sub-process definition.

Modeling Linked Processes

An alternative style of creating sub-processes is the notion of the Linked Process. In this story, a separate BPD is created that contains re-usable BPD activities. Input and Output variables are defined which describe the expected inputs and outputs from the linked process. In the calling process, a Linked Process activity is defined and a reference added to the target BPD that should be invoked when the parent reaches it.

Again we can see the marker that indicates that it contains additional steps. Notice the heavy border around the activity which marks it as distinct from a sub-process.

A step in the process can dynamically choose which linked-process to invoke without explicitly having to define the name of the BPD to be called. To achieve this, create a variable of type String and populate its value with the name of the linked-process to invoke. In the Advanced section of the Implementation area, select that variable as the source of the name of the process. At run-time, the variable will be consulted and a dynamic call to the process with that name will be made.

If parameters are to be passed to a dynamically called process then each process that may be potentially selected to be called must have the same set of parameters. Think of this as the dynamically invoked process having a template.

The BPD that is named as the process to be started must have a Start Event contained within it and this will be the starting point for the new sub-process.

When a parent BPD invokes a child BPD any variables passed in as parameters are passed by reference. What this means is that if a child process changes the values of these passed in variables then the changes will also occur in the parent process. Care must be taken here to watch out for unexpected side effects.

The BPD Process ID of the parent is the same Process ID used for the child.

Modeling Event Sub-processes

For certain types of events, we can create a "sub-process" which will be invoked if such an event is detected but is not otherwise handled elsewhere. For example, if we have a set of steps that we wish to be executed whenever an exception is thrown we don't want to have to wire this code to every activity in our process that may throw an exception. Instead, we create an Exception Event Sub-process that will be invoked when any uncaught exception is thrown.

For example, looking at the following BPD fragment, we see an activity called "Do Something" that presumably does something. Under normal circumstances, "Do Something" will end and that will indicate the end of the process as a whole. But, what if "Do Something" throws an exception? That is where the event sub-process that we called "Exception Handler" comes into play. It contains a set of activities that will be executed whenever an exception event is thrown.

If we double click to expand the Exception Handler, we will see that it itself contains steps:

In this case, it is simply a Script fragment that logs to the console. So, if the parent activity called "Do Something" throws an exception, control will be given to the steps contained within the "Exception Handler" which will log data.

Note that although Process Designer allows us to create multiple Sub-process handlers for the same type of event, it is an error to do so. It isn't clear which of the two will be executed.

Because the Sub-process event handler doesn't have any inputs or outputs, there is no follow-on work from this step.

To gain access to the exception details in an Exception Sub-Process handler, a variable of type XMLElement must be created and assigned from the tw.system.step.error variable in the Post Assignment of the Start node in the diagram:

The Event Sub-process provides handling for event types other than exceptions. Message and Timer events can also be modeled in a similar fashion.

For Event Sub-processes which have starts defined for Message, we have the opportunity to supply a correlation id value to ensure that the correct instance of the process is woken by a corresponding event.

Take extra special care when defining an Event Sub-process which is triggered by the arrival of a message. The parameters called "Interrupt Parent Process?" and "Repeatable" come into play. If "Interrupt Parent Process" is checked, the the arrival of the message causes the container of the Sub-process to be terminated. If the "Repeatable" option is not checked, then messages after the first one will be ignored.

Script Activities

An activity can have an implementation type of Script.

Script allows the programmer to include JavaScript code in-line within the BPD process. The JavaScript can utilize the IBPM supplied JavaScript classes. Although this option is exposed to be used it is unlikely to be a good long term strategy. Code entered here is not re-usable by other activities or services. A better idea would be to build a General Service which includes a Server Script element and invoke the General Service.

External Implementation

When an activity in a BPD is reached, it is associated with and implemented by one of the implementation Service types associated with the IBPM product. These include the common General Service, Integration Service and Human Service types. IBPM provides another type of implementation that is called an "External Implementation." This can be subtle to understand so we will take it slowly. Also note that in previous releases, the External Implementation used to be called an External Activity.

The overall goal of the concept of the External Implementation is that some application or code outside of the IBPM environment is going to perform some work on behalf of the overall execution of the process. This is not an uncommon situation and IBPM provides a variety of ways in which external applications can be called to perform work and return their results. This includes Web Services, REST and other Integration mechanisms. The External Implementation concept though is something different. It is much closer to the concept of a Human Service than it is to an Integration Service.

When an External Implementation is reached in the BPD, a new IBPM Task is created and the BPD process suspends itself until the task completes. Unlike a Human Service task, there are no sets of Coaches or other UI components provided by IBPM associated with this Task. However, the Task still exists and can be queried by the REST API or Web API.


If we think about this for a while, we see that a BPD activity calling an external application through an Integration Service is an explicit invocation of that application while an External Implementation is much more focused on the External Implementation associated application polling and working with the data.

To use external implementations, this capability must first be enabled in IBPM PD.

An External Implementation can be created from the Implementation Category:

A dialog is presented that allows us to enter the name of the activity to be created:

Once done, the properties of the External Implementation can be entered:

To use an External Implementation in a BPD, create an activity and change its implementation type to be User Task. Next, the identity of the external implementation previously defined can be used.

Completing an External Implementation – REST API

When we obtain the data for a TaskInstance object of a task, we can get a property from that object called the ExternalActivityID. If that value is null, then the task does not represent an external activity. However, if it is not null, then its value represents an External Activity identifier. A REST request called

GET /rest/bpm/wle/v1/externalActivity/{externalActivityID}/model[?parts={string}]

can be used to return the model of the external activity. This model describes the possible input and output data types for this activity. Here is an example of what is returned:

{
 "status":"200",
 "data":
 {
 "name":"EA1",
 "customProperties":{},
 "inputs":
 {
 "in1":
 {
 "isList":false,
 "type":"BO1"
 }
 },
 "outputs":
 {
 "out1":
 {
 "isList":false,
 "type":"BO1"
 }
 },
 "validations":
 {
 "BO1":
 {
 "properties":
 {
 "f1":
 {
 "isList":false,
 "type":"String"
 },
 "f2":
 {
 "isList":false,
 "type":"String"
 },
 "f3":
 {

"isList":false,
 "type":"String"
 }
 },
 "type":"object"
 }
 },
 "ID":"60.0b902a52-8df2-44ed-85e2-04bbd980b01d"
 }
 }

Let us look at the inputs and outputs structures to begin with. These correspond to a list of variables where each variable has a "type" attribute. The type attribute matches an entry in the "validations" section.

When it comes time to obtain the input data for the External Activity, that data can be found in the Task Instance details object. To return data as output to an External Activity, use the REST Task Finish method (see: Finishing a Task).

When working with an External Activity, it is a good idea to build a notepad document that looks as follows:

||
|EA1
 
 Inputs:
 order
 customerName String
 orderType String
 amount Decimal
 
 Outputs:
 approval
 approved Boolean
 comments String
 
 For a task input:
 {
 data:
 {
 data:
 {
 variables:
 {
 order:
 {
 customerName:
 orderType:
 amount:
 } 
 }
 }
 }
 }
 
 For task completion:
 {
 approval:
 {
 approved:
 comments:
 }
 }|

This document starts with the name of the External Activity, notes its inputs and outputs and then shows the JSON for a GET request of a task. Finally it shows the response JSON to be passed when the task is completed. Building this notepad document and keeping it handy while designing and coding can save much time and effort.

Completing an External Implementation – Web Service API

One of the most common use cases for an External Activity will be completing it. To understand this part of the story, imagine that a BPD has reached a BPD activity that is defined as an External Activity. This will create an instance of a Task. Assume that by some means, an external application knows the identity (ID) of this task. The external application now wishes to complete the task. This will involve executing a Web API call called completeTask(). The input to this operation are two parameters:

Since in this story, we are already assuming that we know the identity of the task, the missing component is knowledge about what the output variables should be.

When we query and retrieve the Task object for a task, we find it has an attribute called attachedExternalActivity of type ExternalActivityAttachment.

(Note: It is the authors belief that the concept of two names here is confusing. He believes that "attached external activity" is the correct name as the notion is that of external activity being attached (or associated) with a Task.)

This structure looks as follows:

The key to understanding this is that there is an array of Variable objects called data. Each variable consists of a name and a value. If we next look at the input parameters to the Task, we see that those can be found at externalActivity.inputParameters which is an array of Parameter objects. Each parameter consists of a name and type. And here is the tricky/interesting part. For each parameter which has name "X", there is a variable which also has name "X". Thus for each input parameter we can now find its name, type and value. The same is also true for output parameters.

Getting mathematical for a moment if we think of the set of names of input parameters and the set of names of output parameters … the union of these two sets will be the set of names of variables.

For parameters of "simple" types, these are self explanatory consisting of the usual suspects. However, if the parameters are complex types, more discussion is needed.

The data type is defined as a QName which is a qualified name consisting of the namespace of the data type and the name of the data type itself. For example:

{http://www.kolban.com}MyDataType

In Java, the value in the Variables of such a field is a "ComplexValue". This Object is a wrapper for DOM/XML data. It has a property in it called _any which can be retrieved with get_any() and set with set_any(). The data type of this property is a W3 DOM Element.

Here are some useful tips with working with one of these:

To convert to an XML String (in Java), use the following:

ComplexValue complexValue = (ComplexValue)value;
 Element e = (Element)complexValue.getAny();
 DOMImplementation domImplementation = e.getOwnerDocument().getImplementation();
 DOMImplementationLS domImplementationLS = (DOMImplementationLS)domImplementation.getFeature("LS", "3.0");
 LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
 System.out.println(lsSerializer.writeToString(e));

(Note: The DOM "LS" functions are "Load and Save" and are documented at W3 here:

http://www.w3.org/TR/DOM-Level-3-LS/load-save.html

)

To create a new output variable is a little trickier. Remember that a Variable consists of two fields, the name and the value. The value field is an Object. If the output type is a complex type then we need to create a ComplexValue object instance and set the Variable's value field to be the ComplexValue. We also need to set the data into the ComplexValue. Remember that this has a set_any() method which expects a W3 DOM Element.

Let us imagine that we have a data type that looks as follows:

Notice that we have expanded the Advanced Properties so that we can see them in more detail. By clicking on the View XML Schema button we can see the XML Schema for this data type. Now we have all the pieces we need. An example of a good value for BO1 encoded as XML would be:

\<?xml version="1.0" encoding="UTF-16"?\>
 \<ns4:BO1 xmlns:ns4="http://WLEtoSCA"\>
 \<ns4:f1\>f1Value\</ns4:f1\>
 \<ns4:f2\>f2Value\</ns4:f2\>
 \<ns4:f3\>f3Value\</ns4:f3\>
 \</ns4:BO1\>

When we set the ComplexValue's any field, we need to set this to be a W3 DOM Element that represents this piece of XML.

Application Loops

Sometimes it is desirable for an activity to be executed a number of times in a loop. In the General properties of an Activity definition, there is a Loop Type indicator in the Behavior section of the panel:


The default is None which simply means that there will be no looping. There is nothing further to say on that topic.

Simple Looping

With simple looping, the activity is executed a number of times in succession. The number of times the activity is executed is based on the value of the Loop Maximum field which may be an expression or variable resulting in an Integer value. The optional Loop Condition is a boolean expression that is evaluated prior to the next occurrence of the loop. If the condition evaluates to false, the looping terminates early.

When a simple loop has been added to an activity, the icon representing the activity is updated at the bottom left to show that it contains a simple loop:

To pass data into the implementation of the activity, the local variable called tw.system.step.counter contains the current loop index which can be used (if needed) to index into a list. For example, in the Data Mapping section of the properties for the activity, we could code:

to access the current index of a variable array.

Multi-Instance Looping

Multi-instance looping allows for the activities in the loop to execute in parallel with each other. Another way of saying this is that the activities will execute concurrently.

When a Multi Instance loop has been added to an activity, it has an icon that indicates this in its lower left:

The properties of a Multi Instance Loop are shown as follows:

The Start Quantity field defines an expression of how many iterations to execute. The use of this phrase has caused puzzlement to some users. When we think "Start Quantity" we are sometimes drawn to the notion of "How many things do we start with?". What is really meant here is "What is the count (quantity) of things to start in total".

Each iteration of the loop can find its own iteration index through the variable called:

tw.system.step.counter

The ordering mode can be Run in Parallel or Run Sequential. When Run in Parallel is selected, the activities execute concurrently. When Run Sequential, the activities execute one after the other and the loop becomes a simple loop.

When Run in Parallel is selected, the Flow Condition option becomes available. This determines when the activity as a whole is considered completed. The options are:

These options are shown here:

The Wait for All to finish means that all the activities must complete before the activity as a whole is considered complete.

The Conditional Wait requires an expression to be supplied. When an activity completes, the expression is evaluated and the activity as a whole can be determined to have completed or not based on the value of the expression. If the expression is "true" then we end. If the expression evaluates to false, then the loop continues. The way that I like to think of the expression is as the answer to the question "Should we end the loop?".

If all the possible instances have completed, the loop as a whole will also complete irrespective of the outcome of the last condition.

If a completion occurs as a result of the conditional wait expression, the Cancel Remaining Instances check box can be used to terminate any unfinished activities.

When working with looping constructs, the variable called tw.system.step.counter contains the current loop indicator.

The implementation types of a looping activity are as for any activity but not all of them make sense in this context. For example, the Sub-process is no more than a diagramming construct to replace a set of one or more BPD activities with a single BPD activity. The Sub-process executes in the BPD data context/scope and as such, has no differentiated variables associated with it. This means that each instance of a Subprocess started in parallel would have no distinction from others.

Looping through a map data type

We can use a Multi Instance loop to iterate through a Map object (see: Data Type – Map). Assuming that the variable tw.local.myMap is a Map … set the Start Quantity field to be tw.local.myMap.size(). In the Data Mapping section, we pass in the input to each of the service instances or sub-process instances. To supply data to those, use:

tw.local.myMap.valueArray()[tw.system.step.counter]

This line retrieves all of the values of the map and, for each value, starts a service/sub-process to handle the processing of the data item.

BPD Diagram Notes

Notes are documentation items added to the BPD diagram. They appear as yellow rectangles into which text can be entered. They have no operational semantics and do not affect the execution of the process.

Notes can be positioned anywhere on the diagram canvas using the mouse to drag and drop them. They can be re-sized to any desired size. Unfortunately, there are no options to change the background color nor to have the text contained within wrap to the note size.

One interesting way that notes have been seen to have been used is to place them over existing activities. Notes are always shown beneath activities so a note will never obscure an activity or sequence line. If the note is made larger than the activity, the effect can useful and pleasing:

Don't forget that every activity has a Documentation section in which more details of that activity can be recorded. The difference between notes and documentation settings is that with notes, they are always visible while with documentation settings, the user has to explicitly examine the details of an activity to see more information.

Due dates for process and activities

Each process instance has the concept of a due date. This is the date and time when the process instance is desired to be finished. In environments other than IBM BPM, the concept of the "due date" may be said to be the "deadline" and you are free to use those notions interchangably but realize that the product uses "due date". By having this forward date from when the process instance was created, we now know how close we are to risk of it not meeting some desired target.

If the BPD Overview tab, we can set the "Due in" settings as shown next:

Similarly, we also have a corresponding set of details for each User Task in the the process:

The default values for the work schedules are defined in the 99Local configuration file. In 8.5 they are:

\<default-work-schedule\>
 \<time-schedule\>24X7\</time-schedule\>
 \<time-zone\>CST\</time-zone\>
 \<holiday-schedule\>empty holiday\</holiday-schedule\>
 \</default-work-schedule\>

Time and Holiday Schedules

Consider a task being assigned to a user. Assume we say that it takes three hours of work to complete that task. If its 10:00am just now, then we can say that the time we expect the task to be completed will be 1:00pm which is three hours later. This means that the due date will be 1:00pm.

But what if the same task is assigned at 4:00pm? Using simple arithmetic, we might say that the task is due to be complete at 7:00pm. However this does not take into account the business hours of the company. If the office hours are 8:00am to 5:00pm then it would be wrong to ask the staff to complete the task by 7:00pm. To solve this puzzle, we look at an additional BPM concept called "Time Schedule". The Time Schedule defines the working hours of a business. When the Time Schedule is applied to the due date calculation of a task, that due date is no longer a simple arithmetic calculation.

For example, if the Time Schedule declares that our working hours are 8:00am to 5:00pm and a three hour task is started at 4:00pm, we would calculate a due date of 10:00am the next day.

Not only does the Time Schedule contain working hours, but it also describes the working days. For example, a task started at 4:00pm on a Friday may not be due until 10:00am on the following Monday.

Generating Reports

We can generate reports (documentation) based on the content of our Process Applications. From within Process Center we can select a Process Application and navigate to its Snapshots settings. Clicking on the name of the Snapshot takes us to the reports section:

From there we get to see a summary of the major sections of our Process Application:

For each of these we can drill down and see more details and, in certain cases, generate reports for printing or transforming into PDFs for recording.

BPD and BPMN

Originally called the Business Process Modeling Notation, the latest BPMN 2.0 specification has renamed itself to the Business Process Model and Notation. The purpose of this section is to contrast what is contained in the BPMN specification against what is found in the BPD diagrams of the IBPM product. We will not describe BPMN in depth as that would be the subject of its own book (the spec itself is 550 pages) and the reader is referred to one of the many references including the BPMN specification itself.

The BPMN process

<bpmn2:process>

A container for all the steps of a process.

The BPMN startEvent

<bpmn2:startEvent>

The BPMN endEvent

<bpmn2:endEvent>

The BPMN userTask

<bpmn2:userTask>

The BPMN sequenceFlow

<bpmn2:sequenceFlow>

The sequence flow defines a connection between one element and another.


Concept of a Token

As a process runs from its Start to its End, the process executes a sequence of activities. The sequence of executed activities is governed by the Sequence Flow (lines) between the activities. Assuming that there are no parallel branches in the process, at any one time, a single Activity is being performed. To aid in understanding this idea and to be able to discuss in more depth, we introduce the logical concept known as the token. A token is an imaginary item and is not formally part of either the BPMN specification or the IBPM product. A token can be considered to be at exactly one activity in a process and the activity which has the token is available to run or is actually running. When an Activity completes, the token can be thought of as moving along an outgoing Sequence Flow to the next Activity. To help your understanding, you can think of the token as moving instantly from one activity to the next … another way of saying this is that it spend no time traversing the Sequence Flow itself.

Deviations from BPMN

IBPM supports much of the BPMN story but there are some deviations in the implementation of the IBM product that are worthy of note.

Parallel Starts

Here we have a BPMN fragment that shows that when a process starts, in BPMN it will execute two activities in parallel.

If we try and code this in IBPM, it won't work. Only one path or the other will be taken but not both. To achieve the parallelism we desire, we need to add an explicit Parallel Gateway.

Other than stylistic differences, the two are semantically identical.

Looping

BPMN provides the concept of a loop which looks like an activity. If the activity is expanded, we can see the contained activities which are to be executed repeatedly. One common way of using looping is to repeat an activity until something has been "satisfied". Consider a loop that periodically checks that an oven has reached a specific temperature. If it has, we end the loop if not, we check again some time later. This is a loop concept that in Java might have been called a while-do (or do-while) loop. A predicate (boolean valued expression) determines when the loop is to terminate.

Another (but distinct) looping construct in BPMN is the for-each loop. This is a loop which is executed some finite number of times with the activities contained within executed sequentially or in parallel. This looping construct has a distinct appearance from the other loop.

IBPM provides a looping construct that is based on the for-each looping style. However, the visual representation of the IBPM activity is that of the while-do loop style. IBPM does not provide a separate while-do activity style.

XPDL Support

XPDL is an Open Standard describing the exchange of BPMN diagrams as XML documents. IBPM does not support either import or export of XPDL format documents.

Boundary exposes Start Events

A process diagram can have more than one Start Event defined within it if the Start Events are placed on the boundary of the diagram. This allows a single Process to be started at multiple potential start places by its caller.

IBPM does not support this pattern.

Nested terminates

When a parent process calls a child process and the child process executes a Terminate Event, the semantics say that the child process should immediately terminate and the parent process then continue to its next steps. Unfortunately in IBPM, we find that if a child executes a Terminate Event, both the child and its parent are terminated.

Other omitted BPMN items

Other omitted items from the BPMN specification include:


BPD Flow Control

From time to time we may want the path of the process to flow in different directions based on a variety of factors. This section describes some illustrations of this and possible ways to achieve the effect.

Rework a set of steps

Consider a sequence of steps as follows:

While working on a step, a user can say that something is "wrong" that will result in the process as a whole being restarted after some data changes. For example, in "Step B", a user could see something that invalidates the whole process. The user should then be able to press a button that would cause a task to be created that allows someone to modify the process instance data and then we begin again from "Step A".

One solution to this puzzle would look as follows:

Here, after a Step completes, we now realize that it could complete because a rework was requested. After each step we then check if a rework was indeed requested and if it was, we then explicitly go and perform that rework. This is a good solution. It is very visible on the diagram.

Another solution would be to use the concept of exceptions. Now, when a rework is requested, the Step itself throws an exception which might be called "Rework". The diagram may now look like:

Here we are saying that we have an "expected" path and a rework request, although very valid, we call an exception. Within the logic of the Human Service that implements the step, we would now raise the exception:

A third choice would be the use of the sub-process. We would have a top-level process that looks as follows:

The Perform Steps activity is a sub-process that contains:

Each step can throw a Rework exception which is then caught by the container process.

All three of the techniques describes here are equally valid. Which one you choose is as much a matter of taste. The results should be identical. The choice used would be to the taste of the designer as to how best they comprehend the resulting diagrams so that they can be read and understood by others.

No Comments
Back to top