<?xml version="1.0"?>
<!DOCTYPE sdmetrics SYSTEM 'metrics.dtd'>

<!-- metrics.xml

SDMetrics V2.2 metric definitions for the UML2.x default metamodel
Copyright (c) 2002-2011 Juergen Wuest

The MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this SDMetrics project file (the "Project File"), to deal in the Project File 
without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Project File, and to permit persons to whom the Project File is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Project File.

THE PROJECT FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE PROJECT FILE.

Note: this license grant only applies to this Project File, and not to any
other part of SDMetrics.

-->

<sdmetrics version="2.0" ruleexemption="comment" exemptiontag="body">


<!-- class metrics -->
<!-- class size -->

<metric name="NumAttr" domain="class" category="Size">
<description>The number of attributes in the class.((p))

The metric counts all properties regardless of their type (data type,
class or interface), visibility, changeability (read only or not), and
owner scope (class-scope, i.e. static, or instance
attribute).((p))
Not counted are inherited properties, and properties that are members
of an association, i.e., that represent navigable association ends.
((ul))((li))Also known as: NV (Number of Variables per class) ref://LK94/.((/ul))

</description>
<projection relset="ownedattributes" target="property" condition="association=''"/>
</metric>

<metric name="NumOps" domain="class" category="Size">
<description>The number of operations in a class.((p))
Includes all operations in the class that are explicitly modeled
(overriding operations, constructors, destructors), regardless
of their visibility, owner scope (class-scope, i.e., static),
or whether they are abstract or not. Inherited operations are
not counted.
((ul))
((li))Also known as: WMC (Weighted method complexity) where each operation is
assigned unity complexity ref://CK94/.
((li))Also known as: NM (Number of Methods) ref://LK94/.
((/ul))
</description>
<projection relset="ownedoperations" />
</metric>

<metric name="NumPubOps" domain="class" category="Size">
<description>The number of public operations in a class.((p))
Same as metric metric://class/NumOps/, but only counts operations with
public visibility. Measures the size of the class in terms
of its public interface.
((ul))((li))Also known as: NPM (Number of Public Methods)
ref://LK94/.((/ul))
</description>

<projection relset="ownedoperations" condition="visibility='public'"/>

</metric>

<metric name="Setters" domain="class" category="Size">
<description>The number of operations with a name starting with 'set'.((p))
Note that this metric does not always yield accurate results. For example, an
operation ((code))settleAccount((/code)) will be counted as setter method.
((ul))((li))See also: metric://class/Getters/.((/ul))
</description>
<projection relset="ownedoperations" condition="name startswith 'set'" />
</metric>

<metric name="Getters" domain="class" category="Size">
<description>The number of operations with a name starting with 'get', 'is', or
'has'.((p))
Note that this metric does not always yield accurate results. For example, an
operation ((code))isolateNode((/code)) will be counted as getter method.
((ul))((li))See also: metric://class/Setters/.((/ul))
</description>
<projection relset="ownedoperations" sum="GetterName" />
</metric>

<!-- class nesting structure -->
<metric name="Nesting" domain="class">
<description>The nesting level of the class (for inner classes).((p))
Measures how deeply a class is nested within other classes.
Classes not defined in the context of another class have nesting level 0,
their inner classes have nesting level 1, etc.
Nesting levels deeper than 1 are unusual; an excessive nesting structure
is difficult to understand, and should be revised.
</description>
<nesting relation="context" />
</metric>


<!-- class inheritance -->
<metric name="IFImpl" domain="class" category="Inheritance">
<description>The number of interfaces the class implements.((p))
This only counts direct interface realization links from the class to the interface.
For example, if a class ((i))C((/i)) implements an interface ((i))I((/i)),
which extends some other interfaces, only interface ((i))I((/i))
will be counted, but not the interfaces that ((i))I((/i)) extends
(even though class ((i))c((/i)) implements those interfaces, too).</description>
<compoundmetric term="size(ProvidedIF)" />
</metric>

<metric name="NOC" domain="class" category="Inheritance">
<description>The number of children of the class (UML Generalization).((p))
Similar to glossary://Coupling (export)/export coupling/, NOC indicates the potential
influence a class has on the design.
If a class has a large number of children, it may require more testing of the
methods in that class. A large number of child classes may indicate improper
abstraction of the parent class.
((ul))((li))Defined in ref://CK94/.((/ul))
</description>
<projection relation="general" target="generalization" element="context" />
</metric>

<metric name="NumDesc" domain="class" category="Inheritance">
<description>The number of descendents of the class (UML Generalization).((p))
Counts the number of children of the class, their children, and so on.
((ul))
((li))See also: metric://class/NOC/ (Number of Children).
((li))Suggested in ref://LC94/ and ref://TSM92/.
((/ul))
</description>
<compoundmetric term="size(DescSet)" />
</metric>

<metric name="NumAnc" domain="class" category="Inheritance">
<description>The number of ancestors of the class.((p))
Counts the number of parents of the class, their parents, and so on.
If multiple inheritance is not used, the metric yields the same
values as metric://class/DIT/.
((ul))((li))Suggested in ref://LC94/ and ref://TSM92/.((/ul))
</description>
<compoundmetric term="size(AncSet)" />
</metric>

<metric name="DIT" domain="class" category="Inheritance">
<description>The depth of the class in the inheritance hierarchy.((p))
This is calculated as the longest path from the class to the root of
the inheritance tree. The DIT for a class that has no parents is 0.((p))
Classes with high DIT inherit from many classes and thus are more
difficult to understand. Also, classes with high DIT may not be proper
specializations of all of their ancestor classes.
((ul))((li))Defined in ref://CK94/.((/ul))
</description>
<projection relset="generalizations" element="general" eltype="class" nesting="true"/>
</metric>

<metric name="CLD" domain="class" category="Inheritance">
<description>Class to leaf depth. The longest path from the class to a leaf
node in the inheritance hierarchy below the class.
((ul))((li))Defined in ref://TSM92/.
((li))See also: metric://class/NOC/ (Number of Children).((/ul))
</description>
<projection relation="general" element="context" eltype="class" nesting="true"/>
</metric>

<set name="Parents" domain="class">
<description>The set of parents of the class.</description>
<projection relset="generalizations" element="general" eltype="class"/>
</set>

<set name="Children" domain="class">
<description>The set of child classes of the class.</description>
<projection relation="general" element="context" eltype="class"/>
</set>

<set name="AncSet" domain="class">
<description>The set of ancestors of the class.</description>
<projection relset="Parents" recurse="true" />
</set>

<set name="DescSet" domain="class">
<description>The set of descendents of the class.</description>
<projection relation="general" element="context" eltype="class" recurse="true" />
</set>

<metric name="OpsInh" domain="class" category="Inheritance">
<description>The number of inherited operations.((p))
This is calculated as the sum of metric metric://class/NumOps/ taken over
all ancestor classes of the class.
((ul))((li))Also known as NMI ref://LK94/.
((li))See also: metric://class/DIT/.((/ul))
</description>
<projection relset="generalizations" element="general" eltype="class" sum="NumOps" recurse="true"/>
</metric>

<metric name="AttrInh" domain="class" category="Inheritance">
<description>The number of inherited attributes.((p))
This is calculated as the sum of metric metric://class/NumAttr/ taken over
all ancestor classes of the class.
((ul))((li))Loosely based on AIF in ref://AGE95/.((/ul))
</description>
<projection relset="generalizations" element="general" eltype="class" sum="NumAttr" recurse="true"/>
</metric>


<!-- class coupling -->

<set name="RealizedElements" domain="class">
<description>The set of elements the class realizes.</description>
<projection relation="client" target="realization" set="supplier" />
</set>
<set name="ImplInterfaces" domain="class">
<description>The set of interfaces the class realizes.</description>
<projection relset="interfacerealizations" element="contract" />
</set>
<set name="ProvidedIF" domain="class">
<description>The set of interfaces provided by the class.</description>
<projection relset="ImplInterfaces+RealizedElements" target="interface"/>
</set>
<set name="RequiredIF" domain="class">
<description>The set of interfaces required by the class.</description>
<projection relset="DepSuppSet+OutGoingAssoc" target="interface" />
</set>
<set name="InhProvidedIF" domain="class">
<description>The set of provided interfaces of the ancestors of the class.</description>
<projection relset="generalizations" element="general" eltype="class" set="ProvidedIF" recurse="true"/>
</set>
<set name="InhRequiredIF" domain="class">
<description>The set of required interfaces of the ancestors of the class.</description>
<projection relset="generalizations" element="general" eltype="class" set="RequiredIF" recurse="true"/>
</set>

<metric name="Dep_Out" domain="class" category="Coupling (import)">
<description>The number of elements on which this class depends.((p))
This metric counts outgoing plain UML dependencies and usage dependencies
(shown as dashed arrows in class diagrams, usage with 'use' stereotype).</description>
<compoundmetric term="size(DepSuppSet)" />
</metric>

<set name="DepSuppSet" domain="class">
<description>The set of supplier elements to which this class has a dependency or usage link.</description>
<projection relation="client" target="dependency|usage" set="supplier" />
</set>

<set name="DepClientSet" domain="class">
<description>The set of client elements which have a dependency or usage link to this class.</description>
<projection relation="supplier" target="dependency|usage" set="client" />
</set>

<metric name="Dep_In" domain="class" category="Coupling (export)">
<description>The number of elements that depend on this class.((p))
This metric counts incoming plain UML dependencies and usage dependencies
(shown as dashed arrows in class diagrams, usage with 'use' stereotype).
</description>
<compoundmetric term="size(DepClientSet)" />
</metric>

<set name="ends" domain="association">
<description>The properties that constitute the ends of the association.</description>
<projection relset="memberends+ownedends" target="property"/>
</set>
<set name="ends" domain="associationclass">
<description>The properties that constitute the ends of the association class.</description>
<projection relset="memberends+ownedends" target="property"/>
</set>

<set name="assends" domain="association">
	<description>The set of elements that participate in the association.</description>
	<projection relset="ends" element="propertytype"/>
</set>

<set name="assends" domain="associationclass">
	<description>The set of elements that participate in the association class.</description>
	<projection relset="ends" element="propertytype"/>
</set>

<set name="OutGoingAssoc" domain="class" multiset="true">
	<description>The multiset of associated elements via outgoing or bidirectional associations.</description>
	<projection relset="ownedattributes" target="property" targetcondition="association!=''"
	element="association" set="assends" exclude_self="true" />
</set>

<set name="IncomingAssoc" domain="class" multiset="true">
	<description>The multiset of associated elements via incoming or bidirectional associations.</description>
  <projection relation="propertytype" target="property" targetcondition="association!='' and association!=context"
	element="association" set="assends" exclude_self="true" />
</set>

<set name="AssElSet" domain="class">
	<description>The set of elements a class is associated with.</description>
	<projection relset="OutGoingAssoc+IncomingAssoc" exclude_self="true"/>
</set>

<metric name="NumAssEl_ssc" domain="class" category="Coupling">
<description>The number of associated elements in the same scope (namespace)
as the class.((p))
For instance, for a class that is defined in a package ((i))p((/i)),
this counts only associations with classes, interfaces, etc.
in the same package ((i))p((/i)). Such associations are encouraged,
because they do not cross the package boundary, and contribute to the cohesion
of the package.((p))
This metric does not distinguish plain, aggregate, or composite associations,
as well as incoming, outgoing, or bidirectional associations; all such
associations are counted.
</description>
<projection relset="AssElSet" scope="same" />
</metric>

<metric name="NumAssEl_sb" domain="class" category="Coupling">
<description>The number of associated elements in the same scope branch as the
class.((p))
For instance, for a class that is defined in a package ((i))p((/i)),
this metric only counts associations with model elements((ul))
((li))in ((i))p((/i)) itself,
((li))in packages that ((i))p((/i)) contains (subpackages, sub-subpackages
etc. of ((i))p((/i))),
((li))in packages that contain ((i))p((/i)) (packages of which ((i))p((/i))
is a subpackage, sub-subpackage etc).
((/ul))
Such associations cross package boundaries, but one of the packages is nested
within the other. Therefore, a dependency between the packages is expected,
anyway.
((ul))((li))Note: Like metric metric://class/NumAssEl_ssc/, direction and
aggregation of the associations are ignored.((/ul))
</description>
<projection relset="AssElSet" scope="samebranch" />
</metric>

<metric name="NumAssEl_nsb" domain="class" category="Coupling">
<description>The number of associated elements not in the same scope branch as
the class.((p))
For a class that is defined in a package ((i))p((/i)),
this counts only associations with model elements in packages that neither
contain ((i))p((/i)) nor are contained by ((i))p((/i)).
These are the least desirable associations, because they couple otherwise
unrelated packages. Such associations cannot be avoided, but their use should
be minimized.
((ul))((li))Note: Like metric metric://class/NumAssEl_ssc/, direction and
aggregation of the associations are ignored.((/ul))
</description>
<projection relset="AssElSet" scope="notsamebranch" />
</metric>

<metric name="EC_Attr" domain="class" category="Coupling (export)">
<description>The number of times the class is externally used as attribute type.((p))
This is the number of attributes in other classes that have this class as their type.
((ul))((li))Version of: OAEC+AAEC in ref://BDM97/.((/ul))</description>
<projection relation="propertytype" target="property" targetcondition="association=''" scope="notcontainedin"/>
</metric>

<set name="AttrTypeSet" domain="class">
<description>The set of attributes of the class that do not represent association ends.</description>
<projection relset="ownedattributes" target="property" targetcondition="association=''" 
  element="propertytype" eltype="class|interface" />
</set>

<metric name="IC_Attr" domain="class" category="Coupling (import)">
<description>The number of attributes in the class having another class
or interface as their type.
((ul))((li))Version of: OAIC+AAIC in ref://BDM97/.
((li))Also known as: DAC (data abstraction coupling) ref://LH93/.((/ul))</description>
<projection relset="AttrTypeSet" scope="notidem" />
</metric>

<metric name="EC_Par" domain="class" category="Coupling (export)">
<description>The number of times the class is externally used as parameter type.((p))
This is the number of parameters defined outside this class, that have this class
as their type.
((ul))((li))Version of: OMEC+AMEC in ref://BDM97/.((/ul))
</description>
<projection relation="parametertype" target="parameter" scope="notcontainedin"/>
</metric>

<set name="ParaTypeSet" domain="class" multiset="true">
<description>The multiset of classes and interfaces used as parameters of the operations of the class.</description>
<projection relset="ownedoperations" set="ParaTypeSet" />
</set>

<metric name="IC_Par" domain="class" category="Coupling (import)">
<description>The number of parameters in the class having another class or interface
as their type.
((ul))((li))Version of: OMIC+AMIC in ref://BDM97/.((/ul))
</description>
<projection relset="ParaTypeSet" scope="notidem"/>
</metric>

<set name="AttrClients" domain="class" multiset="true">
<description>The multiset of classes and interfaces that have this class as attribute type.</description>
<projection relation="propertytype" target="property" targetcondition="association=''" 
  element="context" eltype="class|interface"/>
</set>

<set name="ParaClients" domain="class" multiset="true">
<description>The multiset of classes and interfaces that have this class as parameter type of one of its methods.</description>
<projection relation="parametertype" target="parameter" element="context.context" eltype="class|interface"/>
</set>

<set name="TheBigDependerSet" domain="class" multiset="true">
	<description>The multiset of elements the class depends upon via UML dependencies,
	associations, generalizations, interface realizations, attribute or parameter types.</description>
	<projection relset="AttrTypeSet+ParaTypeSet+OutGoingAssoc+DepSuppSet+Parents+ImplInterfaces+RealizedElements"/>
</set>

<set name="TheBigClientset" domain="class" multiset="true">
	<description>The multiset of elements that depend on this class via UML dependencies, associations, generalizations, attribute or parameter types.</description>
	<projection relset="AttrClients+ParaClients+IncomingAssoc+DepClientSet+Children"/>
</set>

<metric name="Connectors" domain="class" category="Complexity">
<description>The number of connectors owned by the class.</description>
<compoundmetric term="size(connectors)" />
</metric>


<!-- Port required and provided interfaces -->
<set name="requiredinterfaces" domain="port">
<description>The set of required interfaces of the port.</description>
<projection relset="propertytype.RequiredIF+propertytype.InhRequiredIF" />
</set>
<set name="providedinterfaces" domain="port">
<description>The set of provided interfaces of the port.</description>
<projection relset="propertytype.ProvidedIF+propertytype.InhProvidedIF" />
</set>



<!-- class dynamics -->

<metric name="InstSpec" domain="class">
<description>The number of instance specification where the class is a classifier.((p))
Similar to glossary://Coupling (export)/export coupling/, the more instances of
the class there are, the larger the role of the class in the system.</description>
<projection relation="classifier" target="instancespecification" />
</metric>

<metric name="messageSender" domain="message" internal="true">
<description>The classifier of the lifeline that sends the message.</description>
<compoundmetric term="sendevent.covered.represents.propertytype" />
</metric>
<metric name="messageReceiver" domain="message" internal="true">
<description>The classifier of the lifeline that receives the message.</description>
<compoundmetric term="receiveevent.covered.represents.propertytype" />
</metric>

<set name="LLines" domain="property">
<description>The set of lifelines that represent this property.</description>
<projection relation="represents" target="lifeline" />
</set>
<set name="LLines" domain="class">
<description>The set of lifelines that represent a property of which this class is the type.</description>
<projection relation="propertytype" target="property" set="LLines" />
</set>


<set name="sendMessages" domain="occurrencespec">
<description>The set of messages where this is the send event.</description>
<projection relation="sendevent" target="message" />
</set>
<set name="recvMessages" domain="occurrencespec">
<description>The set of messages where this is the receive event.</description>
<projection relation="receiveevent" target="message" />
</set>

<set name="sendMessages" domain="lifeline">
<description>The set of messages where this lifeline is the sender.</description>
<projection relation="covered" target="occurrencespec" set="sendMessages" />
</set>

<set name="recvMessages" domain="lifeline">
<description>The set of messages where this lifeline is the receiver.</description>
<projection relation="covered" target="occurrencespec" set="recvMessages" />
</set>


<metric name="LLInst" domain="class">
<description>The number of lifelines that represent a property of which this class is the type.((p))
Similar to glossary://Coupling (export)/export coupling/, the more lifelines there
are of the class, the larger the role of the class in the system.</description>
<projection relset="LLines" />
</metric>

<set name="MsgSentSet" domain="class">
<description>The set of messages sent by instances of this class.</description>
<projection relset="LLines" set="sendMessages" />
</set>

<set name="MsgRecvSet" domain="class">
<description>The set of messsages received by instances of this class.</description>
<projection relset="LLines" set="recvMessages" />
</set>

<metric name="MsgSent" domain="class" category="Coupling (import)">
<description>The number of messages sent.((p))
Counts the number of messages that instances of this class send to instances
of other classes, or unclassified instances.
((ul))((li))Version of OMMIC+AMMIC in ref://BDM97/.((/ul))
</description>
<compoundmetric term="MsgSent1+MsgSent2" />
</metric>
<metric name="MsgSent2" domain="class" internal="true">
<description>The number of messages sent to unclassified instances.</description>
<projection relset="MsgSentSet" condition="messageReceiver=''"/>
</metric>
<metric name="MsgSent1" domain="class" internal="true">
<description>The number of messages sent to instances of other classes.</description>
<projection relset="MsgSentSet" element="messageReceiver" scope="notidem"/>
</metric>


<metric name="MsgRecv" domain="class" category="Coupling (export)">
<description>The number of messages received.((p))
Counts the number of messages that instances of this class receive from instances
of other classes or unclassified instances.
((ul))((li))Version of OMMEC+AMMEC in ref://BDM97/.((/ul))
</description>
<compoundmetric term="MsgRecv1+MsgRecv2" />
</metric>
<metric name="MsgRecv2" domain="class" internal="true">
<description>The number of messages sent from unclassified instances.</description>
<projection relset="MsgRecvSet" condition="messageSender=''"/>
</metric>
<metric name="MsgRecv1" domain="class" internal="true">
<description>The number of messages sent from instances of other classes.</description>
<projection relset="MsgRecvSet" element="messageSender" scope="notidem"/>
</metric>


<metric name="MsgSelf" domain="class" category="Complexity">
<description>The number of messages sent to instances of the same class.((p))
Counts the number of messages that instances of this class send to themselves or
to other instances of the same class.
((ul))((li))Version of ICH in ref://LLW95/.((/ul))
</description>
<projection relset="MsgSentSet" element="messageReceiver" scope="idem"/>
</metric>


<!-- interface metrics -->
<metric name="NumOps" domain="interface" category="Size">
<description>The number of operations in the interface.
((ul))((li))See also: metric://class/NumOps/ for classes.((/ul))
</description>
<compoundmetric term="size(ownedoperations)" />
</metric>

<set name="Realizing" domain="interface">
<description>The set of elements that realize this interface.</description>
<projection relation="supplier" target="realization" set="client" />
</set>
<set name="IFRealizing" domain="interface">
<description>The set of elements with an interface realization of this interface.</description>
<projection relation="contract" target="interfacerealization" element="context" />
</set>

<set name="ClientSet" domain="interface">
<description>The set of elements realizing the interface.</description>
<projection relset="Realizing+IFRealizing"/>
</set>

<metric name="EC_Attr" domain="interface" category="Coupling (export)">
<description>The number of times the interface is used as attribute type.
((ul))((li))See also: metric://class/EC_Attr/ for classes.((/ul))
</description>
<projection relation="propertytype" target="property" condition="association=''" />
</metric>

<metric name="EC_Par" domain="interface" category="Coupling (export)">
<description>The number of times the interface is used as parameter type.
((ul))((li))See also: metric://class/EC_Par/ for classes.((/ul))
</description>
<projection relation="parametertype" target="parameter" />
</metric>

<set name="AttrTypeSet" domain="interface" multiset="true">
<description>The multiset of classes and interfaces used as attribute types of the attributes of the interface.</description>
<projection relset="ownedattributes" target="property" targetcondition="association=''"
element="propertytype" eltype="class|interface"/>
</set>

<set name="ParaTypeSet" domain="interface" multiset="true">
	<description>The multiset of classes and interfaces used as parameters of the operations of the interface.</description>
	<projection relset="ownedoperations" set="ParaTypeSet" />
</set>

<metric name="IC_Par" domain="interface" category="Coupling (import)">
<description>The number of parameters in the interface having an interface
or class as their type.
((ul))((li))See also: metric://class/IC_Par/ for classes.((/ul))
</description>
<compoundmetric term="size(ParaTypeSet)"/>
</metric>

<set name="OutgoingAssoc" domain="interface" multiset="true">
	<description>The set of associated elements via outgoing or bidirectional associations.</description>
	<projection relset="ownedattributes" target="property" targetcondition="association!=''"
	element="association" set="assends" exclude_self="true" />
</set>

<set name="IncomingAssoc" domain="interface" multiset="true">
	<description>The set of associated elements via incoming or bidirectional associations.</description>
  <projection relation="propertytype" target="property" targetcondition="association!='' and association!=context"
	element="association" set="assends" exclude_self="true" />
</set>

<metric name="Assoc" domain="interface" category="Coupling">
<description>The number of elements the interface has an association with.((p))
The metric counts incoming, outgoing, or bidirectional associations, aggregations and
compositions to all kinds of elements.((p))
In practice, there should mostly be incoming associations
(see rule://interface/AttrOnIF/), so the metric has 
glossary://Coupling (export)/export coupling/ characteristics.((p))
</description>
<compoundmetric term="flatsize(IncomingAssoc+OutgoingAssoc)" />
</metric>

<metric name="NumDirClients" domain="interface">
<description>The number of elements directly implementing the interface.((p))
This is the number of UML abstractions where this interface is the target.
((ul))((li))See also metric://interface/NumIndClients/.((/ul))
</description>
<compoundmetric term="size(ClientSet)" />
</metric>

<metric name="NumIndClients" domain="interface">
<description>The number of elements implementing a descendent of the interface.((p))
An element implementing an interface is also an implementation of every ancestor
of that interface. This metrics counts how many classes, components, etc., indirectly
implement the interface via a descendent. Together with metric
metric://interface/NumDirClients/, this indicates the total number of
realizations of the interface.
</description>
<projection relation="general" target="generalization" element="context"
eltype="interface" sum="NumDirClients" recurse="true"/>
</metric>

<set name="Parents" domain="interface">
	<description>The set of parents of the interface.</description>
	<projection relset="generalizations" element="general"	eltype="interface"/>
</set>

<set name="Children" domain="interface">
	<description>The set of children of the interface.</description>
	<projection relation="general" target="generalization" element="context"
	eltype="interface"/>
</set>

<set name="DescSet" domain="interface">
	<description>The set of descendents of the interface.</description>
	<projection relation="general" target="generalization" element="context"
	eltype="interface" recurse="true"/>
</set>

<metric name="NumAnc" domain="interface" category="Inheritance">
<description>The number of ancestors of the interface.
((ul))((li))See also: metric://class/NumAnc/ for classes.((/ul))
</description>
<projection relset="generalizations" element="general"	eltype="interface" recurse="true"/>
</metric>

<metric name="NumDesc" domain="interface" category="Inheritance">
<description>The number of descendents of the interface.
((ul))((li))See also: metric://class/NumDesc/ for classes.((/ul))
</description>
<compoundmetric term="size(DescSet)"/>
</metric>

<set name="AttrClients" domain="interface" multiset="true">
	<description>The multiset of classes and interfaces that have this interface as attribute type.</description>
	<projection relation="propertytype" target="property" targetcondition="association=''"
  element="context" eltype="class|interface"/>
</set>

<set name="ParaClients" domain="interface" multiset="true">
	<description>The multiset of classes and interfaces that have this interface as parameter type of one of its methods.</description>
	<projection relation="parametertype" target="parameter" element="context.context" eltype="class|interface"/>
</set>

<set name="TheBigDependerSet" domain="interface" multiset="true">
	<description>The set of elements the interface depends on via associations, generalizations and parameter types.</description>
	<projection relset="Parents+ParaTypeSet+AttrTypeSet+OutgoingAssoc" />
</set>

<set name="TheBigClientset" domain="interface" multiset="true">
	<description>The multiset of elements that depend on this via associations, generalizations, realizations, attribute or parameter types.</description>
	<projection relset="IncomingAssoc+AttrClients+ParaClients+Children+ClientSet"/>
</set>

<!-- operation metrics, internal -->

<set name="ParaTypeSet" domain="operation" multiset="true">
<description>The multiset of classes and interfaces used as types of the parameters of the operations.</description>
<projection relset="ownedparameters" element="parametertype" eltype="class|interface"/>
</set>

<set name="SigParaSet" domain="operation">
<description>The set of parameters of the operation, excluding return types.</description>
<projection relset="ownedparameters" condition="kind!='return'" />
</set>

<metric name="Signature" domain="operation" internal="true">
<description>The signature of the operation</description>
<signature name="name" set="SigParaSet" element="parametertype" />
</metric>

<metric name="GetterName" domain="operation" internal="true">
	<description>1 if name starts with get, is, or has, else 0.</description>
	<compoundmetric condition="(name startswith 'get') | (name startswith 'has') | (name startswith 'is')"/>
</metric>





<!-- package metrics -->

<!-- package size -->
<metric name="NumCls" domain="package" category="Size">
<description>The number of classes in the package.((p))
Counts all classes, regardless of their visibility (public, protected,
private, or package), or abstractness.</description>
<projection relation="context" target="class" />
</metric>

<metric name="NumCls_tc" domain="package" category="Size">
<description>The number of classes in the package, its subpackages, and so on.((p))
This is the sum of metric metric://package/NumCls/ for this package, and all its
direct and indirect subpackages.
</description>
<projection relation="context" target="class" recurse="true"/>
</metric>

<metric name="NumOpsCls" domain="package" category="Size">
<description>The number of operations in the classes of the package.((p))
This is the sum of metric metric://class/NumOps/, taken over all classes in this
package, and more fine-grained measure of the size of the package.
</description>
<projection relation="context" target="class" sum="NumOps"/>
</metric>

<metric name="NumInterf" domain="package" category="Size">
<description>The number of interfaces in the package.((p))
Like metric metric://package/NumCls/, this counts all interfaces, regardless
of their visibility.
</description>
<projection relation="context" target="interface" />
</metric>

<set name="ClsIfSet" domain="package">
<description>The set of classes and interfaces in the package.</description>
<projection relation="context" target="class|interface" />
</set>


<!-- The "Martin Metrics" for packages -->

<metric name="intServers" domain="class" internal="true">
	<description>The number of elements the class depends on that are in the same package as the class.</description>
	<projection relset="TheBigDependerSet" scope="same" />
</metric>
<metric name="intServers" domain="interface" internal="true">
	<description>The number of elements the interface depends on that are in the same package as the interface.</description>
	<projection relset="TheBigDependerSet" scope="same" />
</metric>
<metric name="R" domain="package" category="Complexity">
<description>The number of relationships between classes and interfaces in the package.
There is a dependency from class or interface ((i))C((/i)) to class or
interface ((i))D((/i)) if
((ul))
((li))((i))C((/i)) has an attribute of type ((i))D((/i))
((li))((i))C((/i)) has an operation with a parameter of type ((i))D((/i))
((li))((i))C((/i)) has an association, aggregation, or composition with navigability to ((i))D((/i))
((li))((i))C((/i)) has a UML dependency or usage dependency to ((i))D((/i))((br))
UML dependencies are shown as dashed arrows in the diagrams (usage with stereotype 'use').
((li))((i))C((/i)) is a child of ((i))D((/i))
((li))((i))C((/i)) implements interface ((i))D((/i))
((/ul))
The metric counts all such dependencies between classes and interfaces in the
package. Bidirectional associations are counted twice, because ((i))C((/i))
knows ((i))D((/i)) and vice versa. By convention, associations that indicate no
navigability at either end are considered to be bidirectional.
((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<projection relation="context" target="class|interface" sum="intServers" />
</metric>
<metric name="H" domain="package" category="Cohesion">
<description>Relational cohesion.((p))
This is the average number of internal relationships per class/interface,
and is calculated as the ratio of metric://package/R/+1 to the number of
classes and interfaces in the package.
((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<compoundmetric term="(R+1)/(NumCls+NumInterf)" fallback="0" />
</metric>

<set name="CaSet" domain="package">
<description>Set of elements depending on classes/interfaces in this package.</description>
<projection relation="context" target="class|interface" set="TheBigClientset" />
</set>

<metric name="Ca" domain="package" category="Coupling (export)">
<description>Afferent coupling.((p))
The number of elements outside this package that depend on classes or interfaces
in this package. The dependencies considered are the same ones listed with metric
metric://package/R/.
((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<projection relset="CaSet" element="context" scope="notidem" />
</metric>

<set name="CeSet" domain="package">
	<description>Set of elements that classes/interfaces in this package depend on.</description>
	<projection relation="context" target="class|interface" set="TheBigDependerSet" />
</set>

<metric name="Ce" domain="package" category="Coupling (import)">
<description>Efferent coupling.((p))
The number of elements outside this package that classes or interfaces
in this package depend on. The dependencies considered are the same ones listed
with metric metric://package/R/.
((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<projection relset="CeSet" element="context" scope="notidem" />
</metric>

<metric name="I" domain="package">
<description>Instability or ease of change.((p))
This is the ratio of efferent coupling (metric metric://package/Ce/) to total coupling
(metric://package/Ce/+metric://package/Ce/).

Values of metric I range between 0 and 1.((p))
A value close to 0 indicates a package that does not rely much on other packages,
but is heavily relied upon by other packages. Such a package should be stable,
because it is hard to change: changes to the package potentially have a large impact
on the model ("ripple effects").((p))
A value close to 1 indicates a package that mostly relies on other packages, but that
itself is not much relied upon. Such a package can be instable, because it is
easy to change: changes to the package are not likely to have a large impact on
the model.

((ul))((li))Suggested in ref://Mar03/.
((li))See also: rule rule://package/SDP1/.
((/ul))
</description>
	<compoundmetric term="Ce/(Ca+Ce)" fallback="1" />
	<!-- Ca=Ce=0 is a freak package which should be removed or modified soon => instable => fallback 1 -->
</metric>

<metric name="AbsClasses" domain="package" internal="true">
<description>The number of abstract classes in the package.</description>
<projection relation="context" target="class" condition="abstract='true'" />
</metric>

<metric name="A" domain="package">
<description>Abstractness (or generality) of the package.((p))
This is the ratio of abstract classes and interfaces in the package to the
total number of interfaces and classes in the package.((p))

Values range from 0 to 1. Zero indicates packages without interfaces or abstract
classes, 1 indicates a package consisting only interfaces and abstract classes.

((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<compoundmetric term="(AbsClasses+NumInterf)/(NumCls+NumInterf)" fallback="1" />
<!-- Fallback 1 puts empty packages in the "zone of uselessness", where they belong -->
</metric>

<metric name="D" domain="package">
<description>Distance from the main sequence.

Package design should aim to strike a balance between instability and abstractness
of the packages. A stable package should be abstract, so that changes to the
package are merely extensions that do not affect existing clients of the package.
An instable package is easy to change and can therefore be concrete.((p))

The Stable-Abstractions-Principle (SAP) says that a package should be as abstract
as it is stable. With abstractness measured by metric metric://package/A/, and stability
measured by metric metric://package/I/, the SAP demands that A+I be close to 1.((p))

If you plot A vs. I in a graph, the "main sequence" is the theoretical optimal line
where A+I=1. Metric D is the distance of the package from the main sequence, and is
calculated as (A+I-1)*sqrt(2).((p))

Values range from -sqrt(2) to +sqrt(2). Values close to zero indicate packages
that adhere to the SAP. A large negative value indicates a package
that is concrete and stable (A and I close to 0). Such a package can be
"painful" because it is not extensible and prone to change.
A large positive value indicates a package that is abstract and instable. Such a
package is extensible but has few dependents, and is therefore useless.

((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<compoundmetric term="(A+I-1)*0.707107" />
</metric>

<metric name="DN" domain="package">
<description>Normalized distance D' from the main sequence.((p))
This is a variation of metric metric://package/D/ that has been normalized to range
between 0 and 1. It is calculated as |metric://package/A/+metric://package/I/-1|.
Values close to zero indicate packages that adhere to the SAP (see metric
metric://package/D/).

((ul))((li))Suggested in ref://Mar03/.((/ul))
</description>
<compoundmetric term="abs(A+I-1)" />
</metric>


<!-- package hierachy -->

<metric name="Nesting" domain="package" category="Nesting">
<description>Nesting level of the package in the package hierarchy.((p))
Top level packages have nesting level 0, their subpackages are at level
1, and so on.
</description>
<nesting relation="context" />
</metric>


<!-- package cohesion -->

<metric name="ConnComp" domain="package" category="Cohesion">
<description>The connected components formed by the classes and interfaces
of the package.((p))
The classes and interfaces of a package, and their dependencies, form a graph.
This metric counts the number of connected components of that graph.((p))
Ideally, all classes and interfaces of the package should be related directly
or indirectly, so that there is only one connected component.
If there are two or more connected components, you may consider moving
some classes or interfaces to other packages, or splitting up the package.
((ul))
((li))See metric metric://package/R/ for the list of dependencies considered
between the classes and interfaces.
((li))The graph considered is an undirected graph, directions of dependencies
are ignored.
((li))You can view the connected components in the Graph Structures View.
((/ul))
</description>
<connectedcomponents set="ClsIfSet" nodes="TheBigDependerSet+TheBigClientset"/>
</metric>


<!-- package coupling -->

<metric name="Dep_Out" domain="package" category="Coupling (import)">
<description>The number of UML dependencies where the package is the client.((p))
See also metric://class/Dep_Out/ for classes.</description>
<compoundmetric term="size(DepSuppSet)" />
</metric>

<set name="DepSuppSet" domain="package" multiset="true">
<description>The set of elements to which this package has a dependency link.</description>
<projection relation="client" target="dependency|usage" set="supplier" />
</set>

<metric name="Dep_In" domain="package" category="Coupling (export)">
<description>The number of UML dependencies where the package is the supplier.((p))
See also metric://class/Dep_In/ for classes.</description>
<projection relation="supplier" target="dependency|usage" set="client" />
</metric>

<set name="TheBigDependerSet" domain="package" multiset="true">
	<description>The multiset of elements on which the classes and interfaces of this package depend.</description>
	<projection relation="context" target="class|interface" set="TheBigDependerSet" />
</set>

<set name="DependedPackages" domain="package">
	<description>The set of packages on which classes and interfaces of the package depend.</description>
	<projection relset="TheBigDependerSet+DepSuppSet" target="class|interface" element="context upto (typeof(self)='package')"
		exclude_self="true"/>
</set>

<metric name="DepPack" domain="package" category="Coupling (import)">
<description>The number of packages on which classes and interfaces of this
package depend.((p))
A package ((i))P((/i)) depends on a package ((i))P'((/i)) if
((ul))
((li))a class or interface in ((i))P((/i)) depends on a class or interface
in ((i))P'((/i)) (see metric metric://package/R/ for a description of these
dependencies).
((li))there is a UML dependency (dashed arrow) from ((i))P((/i)) to ((i))P'((/i)).
((/ul))
The more packages ((i))P((/i)) depends on, the more difficult it is to reuse
((i))P((/i)) in a different context.((p))
This metric is similar to metric metric://package/Ce/, the difference is that
Ce counts the individual classes or interfaces that are depended upon.
</description>
<compoundmetric term="size(DependedPackages)" />
</metric>




<set name="MsgSentSet" domain="package">
<description>The set of messages sent by instances of the classes in the package.</description>
<projection relation="context" target="class" set="MsgSentSet" />
</set>

<set name="MsgRecvSet" domain="package">
<description>The set of messages received by instances of the classes in the package.</description>
<projection relation="context" target="class" set="MsgRecvSet" />
</set>

<metric name="MsgSent_Outside" domain="package" category="Coupling (import)">
<description>The number of messages sent to instances of classes outside the package.((p))
The metric counts, for instances of classes of this package, the messages
they send to instances of classes from other packages. That is, outgoing
messages that cross the package boundary. Note that messages to unclassified instances
are not counted here.
</description>
<projection relset="MsgSentSet" target="message" element="messageReceiver.context" scope="notidem" />
</metric>

<metric name="MsgRecv_Outside" domain="package" category="Coupling (export)">
<description>The number of messages received by classifier instances of classes outside
the package.((p))
The metric counts, for instances of classes of this package, the messages they receive
from instances of classes from other packages. That is, incoming messages that cross
the package boundary. Note that messages from unclassified instances are not counted here.
</description>
<projection relset="MsgRecvSet" target="message" element="messageSender.context" scope="notidem" />
</metric>

<metric name="MsgSent_within" domain="package" category="Complexity">
<description>The number of messages sent between classifier instances of classes in
the package.((p))
The metric counts, for instances of classes of this package, the number of messages
they send to themselves or other instances of classes from this package.
Note that messages to unclassified instances are not counted here.
</description>
<projection relset="MsgSentSet" target="message" element="messageReceiver.context" scope="idem" />
</metric>



<!-- use case metrics -->
<set name="OutGoingAssociations" domain="usecase">
	<description>The set of outgoing associations of the use case.</description>
	<projection relset="ownedattributes" target="property" targetcondition="association!=''" element="association" />
</set>

<set name="IncomingAssociations" domain="usecase">
	<description>The set of incoming associations of the use case.</description>
  <projection relation="propertytype" target="property"
	 targetcondition="association!=''" element="association" />
</set>

<set name="Associations" domain="usecase">
	<description>The set of associations the use case participates in.</description>
	<projection relset="OutGoingAssociations+IncomingAssociations" />
</set>

<metric name="NumAss" domain="usecase">
<description>The number of associations the use case participates in.((p))
Counts incoming, outgoing, and bidirectional associations.</description>
<compoundmetric term="size(Associations)" />
</metric>

<metric name="ExtPts" domain="usecase">
<description>The number of extension points of the use case.</description>
<compoundmetric term="size(extensionpoints)" />
</metric>

<set name="IncludedUseCases" domain="usecase">
<description>The set of use cases this one includes.</description>
<projection relation="context" target="usecaseinclude" element="usecaseaddition" eltype="usecase" />
</set>

<metric name="Including" domain="usecase" category="Coupling (import)">
<description>The number of use cases which this one includes.</description>
<compoundmetric term="size(IncludedUseCases)" />
</metric>

<metric name="Included" domain="usecase" category="Coupling (export)">
<description>The number of use cases which include this one.</description>
<projection relation="usecaseaddition" target="usecaseinclude" element="context" eltype="usecase" />
</metric>

<metric name="Extended" domain="usecase">
<description>The number of use cases which extend this one.</description>
<projection relation="extendedcase" target="usecaseextend" element="context" eltype="usecase" />
</metric>

<metric name="Extending" domain="usecase">
<description>The number of use cases which this one extends.</description>
<projection relset="extends" element="extendedcase" eltype="usecase" />
</metric>





<!-- State machine metrics  -->

<set name="StateSet" domain="statemachine">
<description>The set of states, sub-states, subsubstates etc in the statemachine.</description>
<subelements target="state"/>
</set>

<set name="InTrans" domain="state">
<description>The set of incoming transitions of a state.</description>
<projection relation="transtarget" target="transition" />
</set>
<set name="OutTrans" domain="state">
<description>The set of outcoming transitions of a state.</description>
<projection relation="transsource" target="transition" />
</set>

<set name="Transitions" domain="statemachine">
<description>The set of transitions of the state machine.
((ul))((li))Version of NT in ref://MGP03/.((/ul))
</description>
<projection relset="StateSet" set="InTrans+OutTrans" />
</set>

<metric name="Trans" domain="statemachine" category="Complexity">
<description>The number of transitions in the state machine.((p))
Internal transitions are not included in this count.
((ul))((li))Version of NT in ref://MGP03/.((/ul))
</description>
<projection relset="Transitions" condition="kind!='internal'" />
</metric>

<metric name="TEffects" domain="statemachine" category="Complexity">
<description>The number of transitions with an effect in the state machine.</description>
<projection relset="Transitions" condition="effect!=''" />
</metric>

<metric name="TGuard" domain="statemachine" category="Complexity">
<description>The number of transitions with a guard in the state machine.
((ul))((li))Also known as NG in ref://MGP03/.((/ul))
</description>
<projection relset="Transitions" condition="guard!=''" />
</metric>

<metric name="TTrigger" domain="statemachine" category="Complexity">
<description>The number of triggers of the transitions of the state machine.
((ul))((li))Also known as NE in ref://MGP03/.((/ul))
</description>
<projection relset="Transitions" sum="size(triggers)" />
</metric>

<metric name="States" domain="statemachine" category="Size">
<description>The number of states in the state machine.((p))
This includes pseudo states, as well as composite and concurrent states of the
statemachine, and recursively the states they contain, at all levels
of nesting. Submachine states count as "one", the states
in statemachines they reference are not included.
((ul))((li))Corresponds to NSS+NCS in ref://MGP03/.((/ul))
</description>
<projection relset="StateSet" />
</metric>

<metric name="SActivity" domain="statemachine" category="Size">
<description>The number of activities defined for the states of the state machine.((p))
This counts entry, exit, and do activities (or interactions or statemachines) defined 
for the states.
The states considered are those counted by metric metric://statemachine/States/.
((ul))((li))corresponds to NEntry+NExit+NA in ref://MGP03/.((/ul))</description>
<projection relset="StateSet" sum="Activities" />
</metric>

<metric name="CC" domain="statemachine" category="Complexity">
<description>The cyclomatic complexity of the state-transition graph.((p))
This is calculated as metric://statemachine/Trans/-metric://statemachine/States/+2.
((ul))((li))Suggested in ref://MGP03/.((/ul))
</description>
<compoundmetric term="Trans-States+2" />
</metric>


<!-- state metrics, internal -->

<metric name="Activities" domain="state" internal="true">
<description>The number of entry/exit/do activities (or interactions or state machines) defined for the state.</description>
<compoundmetric term="size(entry)+size(exit)+size(doactivity)" />
</metric>

<metric name="Regions" domain="state" internal="true">
<description>The number of regions states in a state.</description>
<projection relation="context" target="region" />
</metric>

<wordlist name="Pseudostates">
	<entry word="choice" />
	<entry word="deepHistory" />
	<entry word="entryPoint" />
	<entry word="exitPoint" />
	<entry word="fork" />
	<entry word="initial" />
	<entry word="join" />
	<entry word="junction" />
	<entry word="shallowHistory" />
	<entry word="terminate" />
</wordlist>

<metric name="Pseudo" domain="state" internal="true">
<description>1 if this is a pseudo state, else zero</description>
<compoundmetric condition="kind onlist Pseudostates" />
</metric>

<metric name="Nesting" domain="state" internal="true">
<description>Nesting level of the state.</description>
<nesting relation="context" />
</metric>

<metric name="Incoming" domain="state" internal="true">
	<description>Number of incoming transitions, not internal.</description>
	<projection relation="transtarget" condition="kind!='internal'" />
</metric>

<metric name="Outgoing" domain="state" internal="true">
	<description>Number of outgoing transitions, not internal.</description>
	<projection relation="transsource" condition="kind!='internal'"/>
</metric>





<!-- Activity metrics  -->

<metric name="Actions" domain="activity" category="Size">
<description>The number of actions of the activity.((p))
Includes actions in all activity groups (partitions, interruptible regions,
expansion regions, structured activities including conditional, loop,
and sequence nodes), and their subgroups, sub-subgroups, etc.
</description> 
<subelements target="action" />
</metric>

<metric name="ObjectNodes" domain="activity" category="Size">
<description>The number of object nodes of the activity.((p))
Counts data store, central buffer, and activity parameter nodes in all
activity groups and their subgroups etc. (see metric://activity/Actions/).
</description> 
<subelements target="objectnode" />
</metric>

<metric name="Pins" domain="activity" category="Size">
<description>The number of pins on nodes of the activity.((p))
Counts all input, output, and value pins on all nodes and groups of the activity.
</description> 
<subelements target="pin" />
</metric>

<metric name="ControlNodes" domain="activity" category="Size">
<description>The number of control nodes of the activity.((p))
Control nodes are initial, activity final, flow final, join, fork, decision, and merge nodes.
The metric also counts control nodes in all activity groups and their subgroups
etc. (see metric://activity/Actions/).
</description> 
<subelements target="controlnode" />
</metric>

<set name="groupSet" domain="activity">
<description>The set of activity groups of the activity.</description>
<subelements target="activitygroup" />
</set>
<metric name="Partitions" domain="activity" category="Size">
<description>The number of activity partitions in the activity.</description> 
<projection relset="groupSet" condition="kind='partition'" />
</metric>
<metric name="Groups" domain="activity" category="Size">
<description>The number of activity groups or regions of the activity.((p))
Counts interruptible and expansion regions, structured activities, conditional, loop,
and sequence nodes, at all levels of nesting.
</description> 
<compoundmetric term="size(groupSet)-Partitions" />
</metric>


<metric name="ControlFlows" domain="activity" category="Complexity">
<description>The number of control flows of the activity.((p))
Includes contained edges in all activity groups and their subgroups
etc. (see metric://activity/Actions/)
</description> 
<subelements target="controlflow" />
</metric>

<metric name="ObjectFlows" domain="activity" category="Complexity">
<description>The number of object flows of the activity.((p))
Includes contained edges in all activity groups and their subgroups
etc. (see metric://activity/Actions/)
</description> 
<subelements target="objectflow" />
</metric>


<metric name="Guards" domain="activity" category="Complexity">
<description>The number of guards defined on object and control flows of the activity.((p))
Includes contained edges in all activity groups and their subgroups
etc. (see metric://activity/Actions/).
</description> 

<subelements target="objectflow|controlflow" condition="guard!=''" />

</metric>


<metric name="ExcHandlers" domain="activity" category="Complexity">
<description>The number of exception handlers of the activity.((p))
Includes exception handlers for all nodes in all activity groups and their subgroups
etc. (see metric://activity/Actions/).
</description> 
<subelements target="exceptionhandler" />
</metric>


<!-- Component metrics  -->

<metric name="NumOps" domain="component" category="Size">
<description>The number of operations of the component.
((ul))((li))See also metric metric://class/NumOps/ for classes.((/ul))</description>
<compoundmetric term="size(ownedoperations)" />
</metric>

<metric name="NumComp" domain="component" category="Size">
<description>The number of subcomponents of the component.((p))
Counts components directly owned by this component; sub-sub-components
etc. are not included in this count.</description>
<projection relation="context" target="component"/>
</metric>

<metric name="NumPack" domain="component" category="Size">
<description>The number of packages of the component.((p))
This only counts packages directly owned by the component; any sub-packages
etc. of these packages are not included in this count.</description>
<projection relation="context" target="package"/>
</metric>

<metric name="NumCls" domain="component" category="Size">
<description>The number of classes of the component.((p))
This only counts classes directly owned by the component; nested classes,
classes in packages, subcomponents, etc. are not included in this count.
((ul))((li))See also metric metric://package/NumCls/ for packages.((/ul))</description>
<projection relation="context" target="class"/>
</metric>

<metric name="NumInterf" domain="component" category="Size">
<description>The number of interfaces of the component.((p))
This only counts interfaces directly owned by the component; 
interfaces in packages, sub-components, etc. are not included
in this count.
((ul))((li))See also metric metric://package/NumInterf/ for packages.((/ul))</description>
<projection relation="context" target="interface"/>
</metric>

<set name="Manifestations" domain="component">
<description>The set of artifacts of which this component is a manifestation.((p))</description>
<projection relation="supplier" target="manifestation" set="client"/>
</set>

<metric name="NumManifest" domain="component">
<description>The number of artifacts of which this component is a manifestation.((p))</description>
<projection relset="Manifestations" target="artifact" />
</metric>

<metric name="Connectors" domain="component" category="Complexity">
<description>The number of connectors owned by the component.</description>
<compoundmetric term="size(connectors)" />
</metric>

<set name="OutGoingAssoc" domain="component">
	<description>The set of associated elements via outgoing or bidirectional associations.</description>
	<projection relset="ownedattributes" target="property" targetcondition="association!=''"
	element="association" set="assends" exclude_self="true" />
</set>

<set name="IncomingAssoc" domain="component">
	<description>The set of associated elements via incoming or bidirectional associations.</description>
  <projection relation="propertytype" target="property" targetcondition="association!='' and association!=context"
	element="association" set="assends" exclude_self="true" />
</set>

<set name="SuppSet" domain="component" multiset="true">
<description>The set of elements that this component depends on.</description>
<projection relation="client" target="dependency|usage" set="supplier" />
</set>

<set name="RealizedElements" domain="component">
<description>The set of elements the component realizes.</description>
<projection relation="client" target="realization" set="supplier" />
</set>
<set name="ImplInterfaces" domain="component">
<description>The set of interfaces the component realizes.</description>
<projection relset="interfacerealizations" element="contract" />
</set>

<set name="PortReqInterfaces" domain="component">
<description>The set of interfaces required by ports of the component.</description>
<projection relset="ownedattributes" target="port" set="requiredinterfaces" />
</set>
<set name="PortProvInterfaces" domain="component">
<description>The set of interfaces provided by ports of the component.</description>
<projection relset="ownedattributes" target="port" set="providedinterfaces" />
</set>

<metric name="ProvidedIF" domain="component" category="Inheritance">
<description>The number of interfaces the component provides.((p))
A component provides an interface if there is a plain or interface
realization to the interface, or if a port of the component provides
the interface.
((ul))((li))See also metric metric://class/IFImpl/ for classes.((/ul))
</description>
<projection relset="ImplInterfaces+RealizedElements+PortProvInterfaces" target="interface"/>
</metric>

<metric name="RequiredIF" domain="component">
<description>The number of interfaces the component requires.((p))
The component requires an interface if there is a dependency, usage dependency,
or an association to the interface, or if a port of the component requires
the interface.
</description>
<projection relset="SuppSet+OutGoingAssoc+PortReqInterfaces" target="interface" />
</metric>

<metric name="Dep_Out" domain="component" category="Coupling (import)">
<description>The number of outgoing UML dependencies (component is the client).((p))
See also metric://class/Dep_Out/ for classes.</description>
<compoundmetric term="size(SuppSet)"/>
</metric>

<metric name="Dep_In" domain="component" category="Coupling (export)">
<description>The number of incoming UML dependencies (component is the supplier).((p))
See also metric://class/Dep_In/ for classes.</description>
<projection relation="supplier" target="dependency|usage" set="client" />
</metric>

<metric name="Assoc_Out" domain="component" category="Coupling (import)">
<description>The number of associated elements via outgoing associations.((p))
Takes associations, aggregations, and compositions with navigability
away from the component into account, i.e., elements the component knows.</description>
<compoundmetric term="size(OutGoingAssoc)" />
</metric>

<metric name="Assoc_In" domain="component" category="Coupling (import)">
<description>The number of associated elements via incoming associations.((p))
Takes associations, aggregations, and compositions with navigability 
to the component into account, i.e., elements that know the component.</description>
<compoundmetric term="size(IncomingAssoc)" />
</metric>

<!-- Node metrics -->
<metric name="Type" domain="node">
<description>The type of node (regular, execution environment, or device).</description>
<attributevalue attr="kind" />
</metric>

<metric name="NumOps" domain="node" category="Size">
<description>The number of operations of the node.
((ul))((li))See also metric metric://class/NumOps/ for classes.((/ul))</description>
<projection relation="context" target="operation"/>
</metric>

<metric name="NumComp" domain="node" category="Size">
<description>The number of components located on the node.((p))
Counts components directly owned by this node; sub-components
etc. are not included in this count.</description>
<projection relation="context" target="component"/>
</metric>

<metric name="NumNodes" domain="node" category="Size">
<description>The number of subnodes of the node.((p))
Counts nodes directly located on this node; sub-sub-nodes etc.
are not included in this count.</description>
<compoundmetric term="size(nestednodes)"/>
</metric>

<set name="ownedArtifacts" domain="node">
<projection relation="context" target="artifact"/>
</set>
<set name="deployedArtifacts" domain="node">
<projection relset="deployments" set="supplier" />
</set>

<metric name="NumArt" domain="node" category="Size">
<description>The number of artifacts deployed on the node.((p))
This metric counts
((ul))
((li))artifacts directly owned by this node; sub-artifacts
etc. are not included,
((li))artifacts with a deployment dependency to the node.
((/ul))</description>
<compoundmetric term="size(ownedArtifacts+deployedArtifacts)" />
</metric>

<metric name="NumPack" domain="node" category="Size">
<description>The number of packages of the node.((p))
This only counts packages directly owned by the node; any sub-packages
etc. of these packages are not included in this count.</description>
<projection relation="context" target="package"/>
</metric>

<set name="OutGoingAssoc" domain="node">
	<description>The set of associated elements via outgoing or bidirectional associations.</description>
	<projection relset="ownedattributes" target="property" targetcondition="association!=''"
	element="association" set="assends" exclude_self="true" />
</set>

<set name="IncomingAssoc" domain="node">
	<description>The set of associated elements via incoming or bidirectional associations.</description>
  <projection relation="propertytype" target="property" targetcondition="association!='' and association!=context"
	element="association" set="assends" exclude_self="true" />
</set>

<metric name="AssEl" domain="node" category="Coupling">
<description>The number of elements the node is associated with.((p))
Takes incoming, outgoing, and bidirectional communication paths, associations,
aggregations, and compositions into account.</description>
<compoundmetric term="size(IncomingAssoc+OutGoingAssoc)"/>
</metric>



<!-- Diagram metrics -->

<metric name="Type" domain="diagram">
<description>The type of diagram (class diagram, sequence diagram, etc.).</description>
<attributevalue attr="type" />
</metric>

<metric name="Elements" domain="diagram" category="Size">
<description>The total number of design elements on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" />
</metric>

<metric name="Classes" domain="diagram" category="Size">
<description>The number of classes on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="class" />
</metric>

<metric name="Interfc" domain="diagram" category="Size">
<description>The number of interfaces on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="interface" />
</metric>

<metric name="Packages" domain="diagram" category="Size">
<description>The number of packages on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="package" />
</metric>

<metric name="Assoc" domain="diagram" category="Complexity">
<description>The number of associations on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="association" />
</metric>

<metric name="Genrs" domain="diagram" category="Complexity">
<description>The number of generalizations on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="generalization" />
</metric>

<metric name="Deps" domain="diagram" category="Complexity">
<description>The number of UML dependencies and UML usage dependencies 
on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="dependency|usage" />
</metric>

<metric name="IfRealize" domain="diagram" category="Complexity">
<description>The number of interface realizations on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="interfacerealization" />
</metric>

<metric name="InstSpec" domain="diagram" category="Size">
<description>The number of instance specifications on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="instancespecification" />
</metric>

<metric name="Lifelines" domain="diagram" category="Size">
<description>The number of lifelines on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="lifeline" />
</metric>

<metric name="Connectors" domain="diagram" category="Complexity">
<description>The number of connectors on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="connector" />
</metric>

<metric name="Messages" domain="diagram" category="Complexity">
<description>The number of messages on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="message" />
</metric>

<metric name="Actors" domain="diagram" category="Size">
<description>The number of actors on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="actor" />
</metric>

<metric name="UseCase" domain="diagram" category="Size">
<description>The number of use cases on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="usecase" />
</metric>

<metric name="ExtPts" domain="diagram" category="Size">
<description>The number of extension points on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="extensionpoint" />
</metric>

<metric name="Extends" domain="diagram" category="Complexity">
<description>The number of use case extensions on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="usecaseextend" />
</metric>

<metric name="Includes" domain="diagram" category="Complexity">
<description>The number of use case includes on the diagram. See glossary://Diagram/diagram metrics/.</description>
<projection relation="context" target="diagramelement" element="element" eltype="usecaseinclude" />
</metric>

<!-- and so forth for other element types you may want to count on the diagram -->


<!-- Diagram metrics for design elements -->

<metric name="Diags" domain="class" category="Diagram">
	<description>The number of times the class appears on a diagram.</description>
	<projection relation="element" target="diagramelement" />
</metric>

<metric name="Diags" domain="package" category="Diagram">
	<description>The number of times the package appears on a diagram.</description>
	<projection relation="element" target="diagramelement" />
</metric>

<metric name="Diags" domain="interface" category="Diagram">
	<description>The number of times the interface appears on a diagram.</description>
	<projection relation="element" target="diagramelement" />
</metric>

<metric name="Diags" domain="component" category="Diagram">
	<description>The number of times the component appears on a diagram.</description>
	<projection relation="element" target="diagramelement" />
</metric>

<metric name="Diags" domain="node" category="Diagram">
	<description>The number of times the node appears on a diagram.</description>
	<projection relation="element" target="diagramelement" />
</metric>

<metric name="Diags" domain="usecase" category="Diagram">
	<description>The number of times the use case appears on a diagram.</description>
	<projection relation="element" target="diagramelement" />
</metric>

<!-- and so forth for other element types you may want to count -->





<!-- Relationship matrices -->

<matrix name="Actor-Usecase" from_row_type="actor" to_col_type="usecase">
<description>Association relationships between actors and use cases.((p))
Shows which actor participates in which use case. A "1" indicates the
actor in that row participates in the use case in that column.
</description>
<projection relset="Associations" />
</matrix>

<matrix name="Class_Gen" from_row_type="class" to_col_type="class">
<description>Generalization relationships between classes (from child to parent).((p))
Shows which class a given class inherits from. A "1" indicates the class
in that row is a child of the class in that column.</description>
<projection relation="context" target="generalization" element="general"/>
</matrix>

<matrix name="Class_Assoc" from_row_type="class" to_col_type="class">
<description>Association relationships between classes.((p))
The numbers indicate how many associations the class in a row has
with classes in the column. All associations (or aggregations
or compositions) with navigability from the row class to the
column class are counted.
</description>
<projection relset="OutGoingAssoc" />
</matrix>

<matrix name="Package_Dependencies" from_row_type="package" to_col_type="package">
<description>Dependencies due to class/interface usage between packages.((p))
Shows on which packages a given package depends on. A "1" indicates the
package in that row has a class or interface that uses a class or interface
of the package in that column.
((ul))((li))See package metric metric://package/R/ for what constitutes
usage between classes and/or interfaces.((/ul))
</description>
<projection relset="DependedPackages" />
</matrix>

<matrix name="Messages_Sent" from_row_type="lifeline" to_col_type="lifeline">
<description>Messages sent between lifelines.((p))
The numbers indicate how many messages the lifeline in a row 
sends to the lifelines in the columns.
</description>
<projection relset="sendMessages" element="receiveevent.covered"/>
</matrix>



<!-- Design rules for UML2.0 -->

<!-- State machine design rules -->

<rule name="NoIncoming" domain="state" category="Completeness" severity="1-high">
<description>State has no incoming transitions.((p))
Without incoming transitions, the state can never be reached. Add one or
more transitions to the state.
((ul))((li))Suggested in ref://Amb03/.((/ul))
</description>
<violation condition="kind!='initial' and kind!='entryPoint' and Regions=0 and Incoming=0" />
</rule>

<rule name="NoOutgoing" domain="state" category="Completeness" severity="1-high">
<description>State has no outgoing transitions.((p))
Without outgoing transitions, the state can never be left. Check if this
is merely an oversight or the actually intended behavior. In the former
case, add the missing outgoing transition(s). In the latter case, consider
adding an outgoing transition to a final state.
((ul))((li))Suggested in ref://Amb03/.((/ul))
</description>
<violation condition="kind!='final' and kind!='exitPoint' and Regions=0 and kind!='deepHistory' and kind!='shallowHistory' and Outgoing=0" />
</rule>

<rule name="IllegalJoin" domain="state" category="Correctness" severity="1-high">
<description>Join states must have two or more incoming and exactly one
outgoing transition.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of incoming and outgoing transitions of the join state.
((/ul))
</description>
<violation condition="kind='join' and ((Outgoing!=1)|(Incoming lt 2))"
					 value="'in: '+Incoming+' out: '+Outgoing"/>
</rule>

<rule name="IllegalFork" domain="state" category="Correctness" severity="1-high">
<description>Fork states must have exactly one incoming and two or
more outgoing transitions.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of incoming and outgoing transitions of the fork state.
((/ul))
</description>
<violation condition="(kind='fork')and((Incoming!=1)|(Outgoing lt 2))"
					 value="'in: '+Incoming+' out: '+Outgoing"/>
</rule>

<rule name="IllegalChoice" domain="state" category="Correctness" severity="1-high">
<description>A choice or junction state must have at least one incoming and one
outgoing transition.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of incoming and outgoing transitions of the choice state.
((/ul))
</description>
<violation condition="(kind='choice' or kind='junction') and (Incoming=0|Outgoing=0)"
					 value="'in: '+Incoming+' out: '+Outgoing"/>
</rule>

<rule name="MissingGuard" domain="state" category="Correctness" severity="1-high">
<description>If there are two or more transitions from a choice state, they
all must have guards.((p))
A choice state realizes a dynamic conditional branch; the guards are required
to evaluate the branch conditions. Check the outgoing transitions and add the
missing guard(s).
((ul))((li))Suggested in ref://Amb03/.
((li))Value returned: name of the target state of the transition without guard.((/ul))
</description>
<projection precondition="kind='choice' and Outgoing>1" relation="transsource"
		target="transition" condition="guard=''" value="transtarget.name"/>
</rule>

<rule name="IllegalInitial" domain="state" category="Correctness" severity="1-high">
<description>An initial state must have no incoming and exactly one outgoing transition.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of incoming and outgoing transitions of the initial state.
((/ul))
</description>
<violation condition="kind='initial' and (Outgoing!=1 or Incoming!=0)"
value="'in: '+Incoming+' out: '+Outgoing"/>
</rule>

<rule name="IllegalFinal1" domain="state" category="Correctness" severity="1-high">
<description>A final state cannot have any outgoing transitions.
Remove the outgoing transitions from the model.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of outgoing transitions of the final state.
((/ul))
</description>
<violation condition="kind='final' and Outgoing!=0" value="'#outgoing trans: '+Outgoing"/>
</rule>

<rule name="IllegalFinal2" domain="state" category="Correctness" severity="1-high">
<description>A final state cannot have any regions or entry/exit/state behavior.((p))
Check the state and remove all regions, entry, exit, and do activities.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of regions and activities of the final state.
((/ul))
</description>
<violation condition="kind='final' and (Activities+Regions)!=0" value="'#reg.: '+Regions+' #act.: '+Activities"/>
</rule>

<rule name="IllegalEntryExit" domain="state" category="Correctness" severity="1-high">
<description>Entry or exit point is not owned by a top-level region.
Move the entry or exit point to the top-level region of the state machine.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<violation condition="(kind='entryPoint' or kind='exitPoint') and (typeof(context)!='region' or typeof(context.context)!='statemachine')" />
</rule>


<metric name="InitStates" domain="region" internal="true">
	<description>Number of initial states in the region.</description>
	<projection relation="context" target="state" condition="kind='initial'" />
</metric>

<metric name="FinalStates" domain="region" internal="true">
	<description>Number of initial states in the region.</description>
	<projection relation="context" target="state" condition="kind='final'" />
</metric>

<metric name="deepHistStates" domain="region" internal="true">
	<description>Number of deep history states for the state machine</description>
	<projection relation="context" target="state" condition="kind='deepHistory'" />
</metric>

<metric name="shallowHistStates" domain="region" internal="true">
	<description>Number of shallow history states for the state machine</description>
	<projection relation="context" target="state" condition="kind='shallowHistory'" />
</metric>

<rule name="TooManyInitialStates" domain="region" category="Correctness" severity="1-high">
<description>The region has two or more initial states.((p))
A region can have at most one initial state. Check the region and remove
the surplus initial states.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of initial states of the region.((/ul))
</description>
<violation condition="InitStates>1" value="'#initial states: '+InitStates"/>
</rule>

<rule name="InitialAndFinalStates" domain="region" category="Style" severity="2-med">
<description>There is no initial or final state for the state machine.((p))
The top-level region of a state machine should have one initial state
and at least one final state so that the state machine has a well-defined
beginning and end.
((ul))((li))Suggested in ref://JRH04/.((/ul))
</description>
<violation condition="typeof(context)!='state' and (InitStates!=1 or FinalStates=0)" />
</rule>

<rule name="DupName" domain="region" category="Correctness" severity="1-high">
<description>The region has two or more states of the same name.((p))
Distinctive states should have distinctive names. Duplicate names can also
cause problems during code generation.
((ul))((li))Suggested in ref://RVR04/.
((li))Value reported: name of the duplicate state.
((/ul))
</description>
<projection relation="context" target="state" condition="name!=''" valueset="name" mincnt="2" />
</rule>


<metric name="Elements" domain="region" internal="true">
<description>The number of elements in the region.</description>
<projection relation="context" />
</metric>

<rule name="EmptyRegion" domain="region" category="Completeness" severity="1-high">
<description>The region has no states.((p))
Add states to the region, or remove the region from the model.</description>
<violation condition="Elements=0" />
</rule>

<rule name="DeepHistory" domain="region" category="Correctness" severity="1-high">
<description>The region has two or more deep history states.((p))
A region can have at most one deep history state. Check the region and delete
the surplus history states.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of deep history states of the region.
((/ul))
</description>
<violation condition="deepHistStates>1" value="'#d.h. states: '+deepHistStates"/>
</rule>

<rule name="ShallowHistory" domain="region" category="Correctness" severity="1-high">
<description>The region has two or more shallow history states.((p))
A region can have at most one shallow history state. Check the region and delete
the surplus history states.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of shallow history states of the region.
((/ul))
</description>
<violation condition="shallowHistStates>1" value="'#s.h. states: '+shallowHistStates"/>
</rule>

<rule name="IllegalHistory" domain="state" category="Correctness" severity="1-high">
<description>The history state has two or more outgoing transitions.((p))
A history state can have at most one outgoing transition. Check the history
state and remove the surplus outgoing transitions.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of outgoing transitions of the history state.
((/ul))
</description>
<violation condition="(kind='deepHistory'|kind='shallowHistory') and Outgoing>1"
					 value="'#outgoing trans: '+Outgoing" />
</rule>

<rule name="Unnamed" domain="state" category="Completeness" severity="3-low">
<description>State has no name.((p))
While the UML allows for anonymous states, adding a descriptive name
to the state increases the readability and understandability of the
diagram.
((ul))
((li))Suggested in ref://Amb03/.
((li))This rule does not check pseudo and final states. Their function is
obvious, so they can be left unnamed.
((/ul))
</description>
<violation condition="name='' and Pseudo=0 and kind!='final'" />
</rule>


<rule name="BadForkOutgoing" domain="state" category="Correctness" severity="1-high">
<description>Transitions from fork states must not have a guard or triggers.
Check the outgoing transitions and remove the guards and triggers.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection precondition="kind='fork'"
	relation="transsource" target="transition" condition="(guard!='')|size(triggers)!=0" />
</rule>

<set name="TargetStateOwners" domain="state">
<description>The set of regions of the states that this state has transitions to.</description>
<projection relation="transsource" target="transition" element="transtarget.context"
 eltype="region" />
</set>

<set name="TargetStateOwnerOwners" domain="state">
<description>The set of owners of the regions of the states that this state has transitions to.</description>
<projection relset="TargetStateOwners" element="context" />
</set>

<rule name="ForkTargetStates1" domain="state" category="Correctness" severity="1-high">
<description>Fork state has transitions to states in identical regions.((p))
The transitions from a fork state must target
states of different regions of a concurrent state. Check the outgoing transitions
and make sure they all target different regions.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="kind='fork' and size(TargetStateOwners)!=Outgoing" />
</rule>

<rule name="ForkTargetStates2" domain="state" category="Correctness" severity="1-high">
<description>Fork state has transitions to states in different concurrent states.((p))
The transitions from a fork state in a state machine must target regions of
the same concurrent state. Check the outgoing transitions and make sure they all target
the same concurrent state. 
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="kind='fork' and size(TargetStateOwnerOwners)!=1" />
</rule>

<set name="SourceStateOwners" domain="state">
<description>The set of owners of the states that this state has transitions to.</description>
<projection relation="transtarget" target="transition" element="transsource.context"
 eltype="region" />
</set>

<set name="SourceStateOwnerOwners" domain="state">
<description>The set of owners of the owners of the states that this state has transitions to.</description>
<projection relset="SourceStateOwners" target="region" element="context" />
</set>

<rule name="JoinSourceStates1" domain="state" category="Correctness" severity="1-high">
<description>Join state has transitions from states in identical regions.((p))
The transitions to a join state must originate from
states of different regions of a concurrent state. Check the incoming transitions
and make sure they all come from different regions.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="kind='join' and size(SourceStateOwners)!=Incoming" />
</rule>

<rule name="JoinSourceStates2" domain="state" category="Correctness" severity="1-high">
<description>Join state has transitions from states in different concurrent states.((p))
The transitions to a join state in a state machine must originate from regions of
the same concurrent state. Check the incoming transitions
and make sure they all come from the same concurrent state.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="kind='join' and size(SourceStateOwnerOwners)!=1" />
</rule>

<rule name="BadForkTarget" domain="state" category="Correctness" severity="1-high">
<description>Transitions from fork states in a state machine must not target a
pseudo state. Check the outgoing transitions and make sure they do not
point to any pseudo states.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection precondition="kind='fork'" relation="transsource" target="transition" 
  condition="transtarget.Pseudo!=0"/>
</rule>

<rule name="BadJoinSource" domain="state" category="Correctness" severity="1-high">
<description>Transitions to join states in a state machine must not originate
from a pseudo state.
Check the incoming transitions and make sure they do not come from pseudo states.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection precondition="kind='join'"	relation="transtarget" target="transition" 
  condition="transsource.Pseudo!=0" />
</rule>

<rule name="BadIncoming" domain="state" category="Correctness" severity="1-high">
<description>Transitions to join states must not have triggers or guards.
Check the incoming transitions and remove all triggers and guards.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection precondition="kind='join'" relation="transtarget" target="transition"
		condition="size(triggers)!=0|guard!=''" />
</rule>

<rule name="BadOutgoing" domain="state" category="Correctness" severity="1-high">
<description>Transitions from pseudo states must not have any triggers.
Check the outgoing transitions and remove all triggers and guards.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection precondition="Pseudo!=0 and kind!='initial'"
	relation="transsource" target="transition" condition="size(triggers)!=0" />
</rule>

<rule name="MissingTarget" domain="state" category="Correctness" severity="1-high">
<description>State has an outgoing transition not attached to a target state.
Check the outgoing transitions of the state and attach any loose ends to the proper
target states.
((ul))((li))Suggested in ref://JRH04/.((/ul))</description>
<projection relation="transsource" target="transition" condition="transtarget=''" />
</rule>

<rule name="MissingSource" domain="state" category="Correctness" severity="1-high">
<description>State has an incoming transition not attached to a source state.
Check the incoming transitions of the state and attach any loose ends to the proper
source states.
((ul))((li))Suggested in ref://JRH04/.((/ul))
</description>
<projection relation="transtarget" target="transition" condition="transsource=''" />
</rule>

<!-- protocol state machine rules -->

<rule name="RegularTransition" domain="statemachine" category="Correctness" severity="1-high">
<description>The protocol state machine contains a transition that is not a protocol transition.((p))
Protocol state machines can only contain protocol transitions. Check the transitions
and make sure they are all protocol transitions.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: name of the source and target states of the transition.
((/ul))
</description>
<projection precondition="isprotocol='true'" relset="Transitions" condition="isprotocol!='true'" 
  value="'from state:'+transsource.name+' to state: '+transtarget.name"/>
</rule>
<rule name="ProtocolTransition" domain="statemachine" category="Correctness" severity="1-high">
<description>The state machine contains a protocol transition.((p))
Protocol transitions can only occur in protocol state machines. Check the transitions
and make sure they are all regular transitions.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: name of the source and target states of the transition.
((/ul))
</description>
<projection precondition="isprotocol='false'" relset="Transitions" condition="isprotocol!='false'" 
value="'from state:'+transsource.name+' to state: '+transtarget.name"/>
</rule>
<rule name="HistoryState" domain="statemachine" category="Correctness" severity="1-high">
<description>The protocol state machine contains a history state.((p))
Protocol state machine cannot have deep or shallow history states. Check the
state machine and remove all history states.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: name of the history state.
((/ul))
</description>
<projection precondition="isprotocol='true'" relset="StateSet" 
  condition="kind='shallowHistory' or kind='deepHistory'" value="name"/>
</rule>
<rule name="StatesWithActivities" domain="statemachine" category="Correctness" severity="1-high">
<description>The protocol state machine contains states with entry/exit/doactivities.((p))
States in protocol state machines must not have any entry, exit, or do activities.
Check the states and remove the activities.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the name of the state with activities.
((/ul))
</description>
<projection precondition="isprotocol='true'" relset="StateSet" condition="Activities!=0" 
value="name" />
</rule>
<rule name="TransWithEffects" domain="statemachine" category="Correctness" severity="1-high">
<description>The protocol state machine contains transitions with effects.((p))
Transitions in protocol state machines must not have any effects. Check the transitions
and remove the effects.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: name of the source and target states of the transition.
((/ul))
</description>
<projection precondition="isprotocol='true'" relset="Transitions" condition="effect!=''" 
value="'from state:'+transsource.name+' to state: '+transtarget.name" />
</rule>



<!-- Class rules -->

<rule name="Unnamed" domain="class" category="Completeness" severity="1-high">
<description>Class has no name.((p))
Give the class a descriptive name that reflects its purpose. Unnamed classes
will cause problems during code generation.
((ul))((li))Suggested in ref://RVR04/.((/ul))</description>
<violation condition="name=''" />
</rule>

<rule name="Unused" domain="class" category="Completeness" severity="1-high">
<description>The class is not used anywhere.((p))
The class has no child classes, dependencies, or associations, and it is not used
as parameter or property type. You'll probably still need to model the clients
of the class, or else consider deleting the class from the model.((p))
Note: for models that were reverse-engineered from source code, this rule
may falsely report many classes as "unused". This happens for classes that
are only referenced in method implementations, e.g., via local variables.
((ul))((li))Suggested in ref://Rie96/ (heuristic #3.7 eliminate irrelevant
classes).((/ul))
</description>
<violation condition="NOC+size(AssElSet)+size(DepSuppSet)+size(DepClientSet)+EC_Attr+EC_Par=0" />
</rule>

<rule name="NotCapitalized" domain="class" category="Naming" severity="3-low">
<description>Class names should start with a capital letter.((p))
This naming convention is a recommended style guideline in the UML
standards ref://OMG03/, ref://OMG05/.
</description>
<violation condition="!startswithcapital(name)" />
</rule>

<rule name="GodClass" domain="class" category="Style" severity="2-med">
<description>The class has more than 60 attributes and operations.((p))
Also known as blob classes, large classes are likely maintenance bottlenecks,
sources of unreliability, and indicate a lack of (object-oriented)
architecture and architecture enforcement.((p))
Consider refactoring the class to split it up into smaller classes.
((ul))
((li))Threshold of 60 cited in ref://BMM98/.
((li))See also metrics metric://class/NumOps/ and metric://class/NumAttr/
((li))Also known as "Large Class" code smell ref://Fow99/.
((li))Value reported: number of operations and attributes.
((/ul))
</description>
<violation condition="(NumOps+NumAttr)>60" value="'#ops/attr: '+(NumOps+NumAttr)"/>
</rule>

<rule name="Keyword" domain="class" category="Naming" severity="2-med"
applies_to="design">
<description>Class name is a Java or C++ keyword.
Using programming language keywords for class names will cause problems during
code generation. Find another name for the class. Capitalizing the name
will also help, see rule rule://class/NotCapitalized/.
((ul))((li))Suggested in ref://RVR04/.((/ul))</description>
<violation condition="(name onlist Java_CPP)" />
</rule>

<wordlist name="Java_CPP">
	<entry word="abstract"/>
	<entry word="and"/>
	<entry word="and_eq"/>
	<entry word="asm"/>
	<entry word="auto"/>
	<entry word="bitand"/>
	<entry word="bitor"/>
	<entry word="bool"/>
	<entry word="boolean"/>
	<entry word="break"/>
	<entry word="byte"/>
	<entry word="case"/>
	<entry word="catch"/>
	<entry word="char"/>
	<entry word="class"/>
	<entry word="compl"/>
	<entry word="const"/>
	<entry word="const_cast"/>
	<entry word="continue"/>
	<entry word="default"/>
	<entry word="delegate"/>
	<entry word="delete"/>
	<entry word="do"/>
	<entry word="double"/>
	<entry word="dynamic_cast"/>
	<entry word="else"/>
	<entry word="enum"/>
	<entry word="except"/>
	<entry word="explicit"/>
	<entry word="export"/>
	<entry word="extends"/>
	<entry word="extern"/>
	<entry word="false"/>
	<entry word="final"/>
	<entry word="finally"/>
	<entry word="float"/>
	<entry word="for"/>
	<entry word="friend"/>
	<entry word="goto"/>
	<entry word="if"/>
	<entry word="implements"/>
	<entry word="import"/>
	<entry word="inline"/>
	<entry word="instanceof"/>
	<entry word="int"/>
	<entry word="interface"/>
	<entry word="long"/>
	<entry word="mutable"/>
	<entry word="namespace"/>
	<entry word="native"/>
	<entry word="new"/>
	<entry word="not"/>
	<entry word="not_eq"/>
	<entry word="null"/>
	<entry word="operator"/>
	<entry word="or"/>
	<entry word="or_eq"/>
	<entry word="package"/>
	<entry word="private"/>
	<entry word="protected"/>
	<entry word="public"/>
	<entry word="register"/>
	<entry word="reinterpret_cast"/>
	<entry word="return"/>
	<entry word="short"/>
	<entry word="signed"/>
	<entry word="sizeof"/>
	<entry word="static"/>
	<entry word="static_cast"/>
	<entry word="strictfp"/>
	<entry word="struct"/>
	<entry word="super"/>
	<entry word="switch"/>
	<entry word="synchronized"/>
	<entry word="template"/>
	<entry word="this"/>
	<entry word="throw"/>
	<entry word="throws"/>
	<entry word="transient"/>
	<entry word="true"/>
	<entry word="try"/>
	<entry word="typedef"/>
	<entry word="typeid"/>
	<entry word="typename"/>
	<entry word="union"/>
	<entry word="unsigned"/>
	<entry word="using"/>
	<entry word="virtual"/>
	<entry word="void"/>
	<entry word="volatile"/>
	<entry word="wchar_t"/>
	<entry word="while"/>
	<entry word="xor"/>
	<entry word="xor_eq"/>
</wordlist>

<metric name="NOP" domain="class" internal="true">
	<description>The number of parents of the class (UML Generalization).</description>
	<compoundmetric term="size(Parents)" />
</metric>

<rule name="MultipleInheritance" domain="class" category="Style" severity="3-low">
<description>Use of multiple inheritance - class has more than one parent.((p))
The use of multiple inheritance is controversial. Some OO programming languages
do not support multiple inheritance. Review the class design to confirm that the
use of multiple inheritance is justified.
((ul))((li))Suggested in ref://Rie96/.((/ul))
</description>
<violation condition="NOP>1" value="'#parents: '+NOP"/>
</rule>

<rule name="SpecLeafClass" domain="class" category="Correctness" severity="1-high">
<description>Class is marked as leaf, but it has child classes.((p))
Leaf classes cannot have any child classes. This is a glossary://WFR// of the UML.
</description>
<violation condition="leaf='true' and NOC>0" value="'#children: '+NOC" />
</rule>

<rule name="NoSpec" domain="class" category="Completeness" severity="2-med">
<description>Abstract class has no child classes.((p))
Abstract classes cannot be instantiated. Without specializations that can
be instantiated, the abstract class is useless.
((ul))((li))Suggested in ref://Rie96/.
((li))Violations of this rule would be justified if the class is part of
a framework or library, and is meant to be extended by users of the
framework/library.
((/ul))
</description>
<violation condition="abstract='true' and NOC=0" />
</rule>

<rule name="CyclicInheritance" domain="class" category="Inheritance" severity="1-high">
<description>Class inherits from itself directly or indirectly.((p))
The inheritance graph must be a tree, no cycles are allowed.
((ul))((li))This is a glossary://WFR// of the UML.
((li))You can view the inheritance graph in the graph structures dialog.
((li))Value returned: number of classes in the cycle.
((/ul))
</description>
<cycle nodes="Parents" />
</rule>

<rule name="ConcreteSuper" domain="class" category="Style" severity="1-high">
<description>The abstract class has a parent class that is not abstract.((p))
This is bad design. A child class should be substitutable for the parent
class. Since the parent class can be instantiated, but not the child class,
substitution is not possible anymore.
((ul))((li))Suggested in ref://Lan03/.
((li))Value returned: name of the concrete parent class.
((/ul))
</description>
<projection precondition="abstract='true'" relset="Parents"
		condition="abstract!='true'" value="name"/>
</rule>

<set name="SignatureSet" domain="class" multiset="true">
<description>The set of signatures of the class operations.</description>
<projection relation="context" target="operation" valueset="Signature" />
</set>

<rule name="DupOps" domain="class" category="Correctness" severity="1-high">
<description>Class has duplicate operations.((p))
There are two or more operations with identical signatures (i.e.,
operation name and list of parameter types). Operation signatures
must be unique within the class. 
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value reported: name of the duplicate operation.
((/ul))
</description>
<valueset set="SignatureSet" mincnt="2" />
</rule>


<set name="AttrNameSet" domain="class" multiset="true">
	<description>The multiset of property names of the class.</description>
	<projection relation="context" target="property" valueset="name" />
</set>

<rule name="DupAttrNames" domain="class" category="Correctness" severity="1-high">
<description>The class has two or more properties with identical names.((p))
Attribute names must be unique within the class. 
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value reported: name of the duplicate attribute.
((/ul))
</description>
<valueset set="AttrNameSet" mincnt="2" />
</rule>

<rule name="AttrNameOvr" domain="class" category="Naming" severity="2-med" >
<description>The class defines a property of the same name as an inherited
attribute.((p))
During code generation, this may inadvertently hide the attribute of the parent
class. Consider changing the name of the attribute in the child class.
((ul))((li))Suggested in ref://RVR04/.((/ul))
</description>
<projection relation="context" target="property" condition="Redefining>0" value="name"/>
</rule>

<rule name="DescendentRef" domain="class" category="Style" severity="1-high">
<description>The class references a descendent class via associations, UML
dependencies, attribute or parameter types.((p))
This is poor design. A class ((i))c((/i)) should be oblivious of its descendent
classes. The reference to the descendent class and the inheritance links back to
class ((i))c((/i)) effectively form a dependency cycle between these classes.((p))
Redesign this to eliminate the need for the reference to the descendent class.
((ul))((li))Suggested in ref://RVR04/, ref://Rie96/.
((li))Value reported: name of the referenced descendent class.
((/ul))
</description>
<projection relset="TheBigDependerSet*DescSet" value="name" />
</rule>

<rule name="DepCycle" domain="class" category="Style" severity="2-med">
<description>The class has circular references.((p))
Circular dependencies should be avoided. The classes participating in the
cycle cannot be tested and reused independently. The more classes participate
in the cycle, the worse the problem is, especially if the classes reside in
different packages (see also rule rule://package/DepCycle/ for packages).((p))
Consider revising the design to eliminate the cycle.
((ul))((li))See also: Dependency Inversion Principle ref://Mar03/.
((li))You can view the class dependency graph and its cycles in the 
Graph Structures View.
((li))Value reported: number of classes in the cycle.
((/ul))
</description>
<cycle nodes="TheBigDependerSet" minnodes="2" />
</rule>




<!-- Interface rules -->

<rule name="Unnamed" domain="interface" category="Completeness" severity="1-high">
<description>Interface has no name.
((ul))((li))See rule rule://class/Unnamed/ for classes.((/ul))
</description>
<violation condition="name=''" />
</rule>

<rule name="Unused" domain="interface" category="Completeness" severity="1-high">
<description>The interface is not used anywhere.((p))
The interface is not implemented anywhere, has no associations,
and is not used as parameter or attribute type.
((ul))((li))See also rule rule://class/Unused/ for classes.
((/ul))
</description>
<violation condition="NumDirClients+NumIndClients+Assoc+EC_Attr+EC_Par=0" />
</rule>

<rule name="NotCapitalized" domain="interface" category="Naming" severity="3-low">
<description>Interface names should start with a capital letter.
((ul))((li))See rule rule://class/NotCapitalized/ for classes.((/ul))
</description>
<violation condition="!startswithcapital(name)" />
</rule>

<rule name="Keyword" domain="interface" category="Naming" severity="2-med"  applies_to="design">
<description>Interface name is a Java or C++ keyword; find another name for it.
((ul))((li))See rule rule://class/Keyword/ for classes.((/ul))</description>
<violation condition="(name onlist Java_CPP)" />
</rule>

<metric name="NonPubOps" domain="interface" internal="true">
	<description>The number of non-public operations of the interface.</description>

	<projection relset="ownedoperations" condition="visibility!='public'" />

</metric>
<metric name="NonPubAttr" domain="interface" internal="true">
	<description>The number of non-public properties of the interface.</description>

	<projection relset="ownedattributes" target="property" condition="visibility!='public'" />

</metric>

<rule name="PubOpsOnly" domain="interface" category="Correctness" severity="1-high">
<description>The interface has operations that are not public.((p))
All operations in interfaces must have public visibility.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of non-public operations.((/ul))</description>
<violation condition="NonPubOps!=0" value="'#non-public ops: '+NonPubOps"/>
</rule>

<rule name="PubAttrOnly" domain="interface" category="Correctness" severity="1-high">
<description>The interface has attributes that are not public.((p))
All attributes in interfaces must have public visibility.
((ul))((li))This is a glossary://WFR// of the UML2.
((li))Value returned: number of non-public attributes.((/ul))
</description>
<violation condition="NonPubAttr!=0" value="'#non-public attributes: '+NonPubAttr"/>
</rule>

<rule name="AttrOnIF" domain="interface" category="Style" severity="3-low">
<description>The interface has attributes or outgoing associations.((p))
Interfaces can have attributes and outgoing associations since UML2.0.
This rather appears to be a concession to certain component technologies, 
and should otherwise be avoided.
((ul))((li))Suggested in ref://Oes04/.
((li))Value returned: number of attributes of the interface.((/ul))
</description>
<violation condition="size(ownedattributes)!=0" value="'#Attr: '+size(ownedattributes)" />
</rule>


<!-- Data Type rules -->

<rule name="Unnamed" domain="datatype" category="Completeness" severity="1-high">
<description>The data type has no name.
((ul))((li))See rule rule://class/Unnamed/ for classes.((/ul))
</description>
<violation condition="name=''" />
</rule>
<rule name="Keyword" domain="datatype" category="Naming" severity="2-med"  applies_to="design">
<description>Data type name is a Java or C++ keyword; find another name for it.
((ul))((li))See rule rule://class/Keyword/ for classes.((/ul))</description>
<violation condition="(name onlist Java_CPP)" />
</rule>

<rule name="NoQuery" domain="datatype" category="Correctness" severity="1-high">
<description>The data type has an operation that is not marked as a query.((p))
All operations of a data type must be queries. 
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: name of the operation that should be a query.((/ul))</description>
<projection relset="ownedoperations" condition="isquery!='true'" value="name" />
</rule>

<!-- Attribute rules -->

<rule name="Unnamed" domain="property" category="Completeness" severity="1-high">
<description>The attribute has no name.
((ul))((li))See rule rule://class/Unnamed/ for classes.((/ul))</description>
<violation condition="name=''" />
</rule>

<rule name="Capitalized" domain="property" category="Naming" severity="3-low">
<description>Attribute names should start with a lowercase letter.((p))
This is a recommended style guideline in the UML standards
ref://OMG03/, ref://OMG05/.
((ul))((li))It is common practice in many programming languages to
capitalize constant identifiers, including attributes. Therefore, the
rule does not report read-only attributes that start with an uppercase letter.((/ul))
</description>
<violation condition="!startswithlowercase(name) and isreadonly!='true'" />
</rule>

<rule name="Keyword" domain="property" category="Naming" severity="2-med" applies_to="design">
<description>Attribute name is a Java or C++ keyword.
((ul))((li))See rule rule://operation/Keyword/ for operations.((/ul))</description>
<violation condition="(name onlist Java_CPP)" />
</rule>

<rule name="PublicAttr" domain="property" category="Style" severity="2-med">
<description>Non-constant attribute is public.((p))
External read/write access to attributes violates the information hiding principle.
Allowing external entities to directly modify the state of an object is dangerous.
State changes should only occur through the protocol defined by the interfaces of the
object. Make the attribute private or protected.
((ul))((li))Suggested in ref://Rie96/.((/ul))
</description>

<violation condition="visibility='public' and isreadonly!='true'" />

</rule>

<rule name="NoType" domain="property" category="Completeness" severity="2-med"
	applies_to="design">
<description>The attribute has no specified type.((p))
Without a type, the attribute has no meaning in design, and code generation will not
work. Specify a type for the attribute.
((ul))((li))Suggested in ref://Fra03/.((/ul))
</description>
<violation condition="propertytype=''" />
</rule>

<metric name="Redefining" domain="property" internal="true">
<description>The number of ancestor classes having an attribute with the same name as this one.</description>
<count term="name" set="context.AncSet" target="class" relset="AttrNameSet" />
<!-- 'count' is deprecated; since V2.2 we would write: 
projection relset="context.AncSet" target="class" sum="_principal.name in AttrNameSet" -->
</metric>


<!-- Operation rules -->

<rule name="Unnamed" domain="operation" category="Completeness" severity="1-high">
<description>Operation has no name.
((ul))((li))See also rule rule://class/Unnamed/ for classes.((/ul))</description>
<violation condition="name=''" />
</rule>

<rule name="Capitalized" domain="operation" category="Naming" severity="3-low">
<description>Operation names should start with a lower case letter.
This is a recommended style guideline in the UML standards
ref://OMG03/, ref://OMG05/.((p))
In many programming languages, constructors have the same name as their class,
thus starting with upper case letters. Therefore, operations with the same name
as their class are not reported.
</description>
<violation condition="(!startswithlowercase(name))and(!(name endswith context.name))" />
</rule>

<rule name="Keyword" domain="operation" category="Naming" severity="2-med" applies_to="design">
<description>Operation name is a Java or C++ keyword.((p))
Using programming language keywords as operation names will 
cause problems during code generation. Find another name for the operation.
((ul))((li))Suggested in ref://RVR04/.((/ul))</description>
<violation condition="(name onlist Java_CPP)" />
</rule>

<rule name="AbstractOp" domain="operation" category="Correctness" severity="1-high">
<description>Operation is abstract, but its owner class is not abstract.((p))
In many programming languages, a class is abstract if at least one of its
operations is abstract. Either make the owner class abstract, or provide an
implementation for the operation.
</description>
<violation condition="abstract='true' and typeof(context)='class' and context.abstract!='true'" />
</rule>

<rule name="LongParList" domain="operation" category="Style" severity="2-med">
<description>The operation has a long parameter list with five or more parameters.((p))
Long parameter lists are difficult to use, and likely to change more frequently.
Change the design to pass one or more objects to the operation that encapsulate the
required parameters.
Note: the rule only considers in, out, and inout parameters; the return parameter
(if any) is not counted.
((ul))((li))Suggested in ref://Fow99/.
((li))Value returned: the number of parameters of the operation.
((/ul))
</description>
<violation condition="size(SigParaSet)>=5" value="'#par: '+size(SigParaSet)" />
</rule>

<metric name="NumRetPar" domain="operation" internal="true">
<description>The number of return parameters of the operation.</description>
<projection relset="ownedparameters" condition="kind='return'" />
</metric>
<rule name="MulReturn" domain="operation" category="Correctness" severity="1-high">
<description>The operation has more than one return parameter.((p))
Many programming languages only support one return parameter per operation.
Change some return parameters to out or inout parameters, or return one
object that encapsulates all return parameters.
((ul))((li))This is a glossary://WFR// of the UML2.
((li))Value returned: number of return parameters of the operation.
((/ul))
</description>
<violation condition="NumRetPar>1" value="'#retpar: '+NumRetPar" />
</rule>

<rule name="DupName" domain="operation" category="Naming" severity="1-high">
<description>The operation has two or more parameters with identical names.((p))
Parameters must have unique names to distinguish them. This is a
glossary://WFR// of the UML.
((ul))((li))Value returned: the name of the duplicate parameters.((/ul))
</description>
<projection relset="ownedparameters" valueset="name" mincnt="2" />
</rule>

<rule name="Query" domain="operation" category="Style" severity="2-med">
<description>The operation name indicates a query, but it is not marked as a query.((p))
The operation name suggests this is a getter (see metric://class/Getters/). Mark
the operation as query to indicate that it does not change the owner's state.
</description>
<violation condition="GetterName=1 and isquery!='true'" />
</rule>

<metric name="Overriding" domain="operation" internal="true">
<description>The number of ancestor classes having an operation with the same signature as this one.</description>
<count term="Signature" set="context.AncSet" target="class" relset="SignatureSet" />
<!-- 'count' is deprecated; since V2.2 we would write: 
projection relset="context.AncSet" target="class" sum="_principal.Signature in SignatureSet" -->
</metric>

<metric name="Overridden" domain="operation" internal="true">
<description>The number of ancestor classes having an operation with the same signature as this one.</description>
<count term="Signature" set="context.DescSet" target="class" relset="SignatureSet" />
<!-- 'count' is deprecated; since V2.2 we would write: 
projection relset="context.DescSet" target="class" sum="_principal.Signature in SignatureSet" -->
</metric>


<!-- Parameter rules -->

<rule name="Unnamed" domain="parameter" category="Completeness" severity="1-high">
<description>Parameter has no name.((p))
Note that this rule does not check return parameters, as they are unnamed
in most programming languages.
((ul))((li))See also rule rule://class/Unnamed/ for classes.((/ul))</description>
<violation condition="name=''" />
</rule>

<rule name="NoType" domain="parameter" category="Completeness" severity="2-med">
<description>The parameter has no specified type.
((ul))((li))See also rule rule://property/NoType/ for attributes.((/ul))</description>
<violation condition="parametertype=''" />
</rule>

<rule name="Keyword" domain="parameter" category="Naming" severity="2-med"
	applies_to="design">
<description>Parameter name is a Java or C++ keyword.((p))
Return parameters are not checked, as they are unnamed in many programming
languages. Also, some modeling tools assign the name 'return' as
default name to return parameters.
((ul))((li))See rule rule://operation/Keyword/ for operations.((/ul))</description>
<violation condition="kind!='return' and (name onlist Java_CPP)" />
</rule>



<!-- package rules -->

<rule name="Unnamed" domain="package" category="Completeness" severity="1-high">
<description>Package has no name.
((ul))((li))See rule rule://class/Unnamed/ for classes.((/ul))</description>
<violation condition="name=''" />
</rule>

<rule name="Capitalization" domain="package" category="Naming" severity="3-low">
<description>Package name has upper case letters.
A common naming convention is that package names use all lower case letters.
((ul))((li))Suggested in ref://RVR04/.((/ul))</description>
<violation condition="!islowercase(name)" value="name"/>
</rule>

<rule name="Keyword" domain="package" category="Naming" severity="2-med"
	applies_to="design">
<description>Package name is a Java or C++ keyword.
((ul))((li))See rule rule://operation/Keyword/ for operations.((/ul))</description>
<violation condition="(name onlist Java_CPP)" />
</rule>

<metric name="NumElem" domain="package" internal="true">
	<description>The number of design elements in the package.</description>
	<projection relation="context" />
</metric>

<rule name="EmptyPackage" domain="package" category="Completeness" severity="2-med">
<description>The package has no contents.((p))
Add model elements to the package, or delete it from the design.
</description>
<violation condition="NumElem=0" />
</rule>

<rule name="DupClsName" domain="package" category="Naming" severity="1-high">
<description>The package has two or more classes or interfaces with identical names.((p))
This will cause problems during code generation. Rename the classes or interfaces
so that the names are unique.
((ul))((li))Value returned: name of the duplicate class/interface.((/ul))
</description>
<projection relation="context" target="class|interface"	valueset="name" mincnt="2" />
</rule>

<rule name="DepCycle" domain="package" category="Style" severity="1-high">
<description>The package has circular dependencies to other packages.((p))
Cycles in the package dependency graph should be avoided. The packages participating
in the cycle cannot be tested, reused, or released independently. The more packages
participate in the cycle, the worse the problem is. Other design guidelines
such as the Stable-Dependencies Principle (see rule rule://package/SDP1/)
are also invariably violated.((p))
Revise the design to eliminate the cycle.
((ul))((li))See also: Dependency Inversion Principle ref://Mar03/.
((li))See metric://package/DepPack/ for what constitutes dependencies between packages.
((li))You can view the package dependency graph and its cycles in the 
Graph Structures View.
((li))Value returned: number of packages in the cycle.
((/ul))
</description>
<cycle nodes="DependedPackages" minnodes="2" />
</rule>

<rule name="SDP1" domain="package" category="Style" severity="2-med">
<description>Package violates the Stable-Dependencies Principle (SDP).((p))

The package depends on another package, ((i))P((/i)) that is less stable than
itself (as measured by metric metric://package/I/). Package
((i))P((/i)) is less stable and therefore more liable to change than this package.
A change to ((i))P((/i)) may ripple to this package. This is undesirable because
this package is more stable and therefore harder to change.((p))

Therefore, the Stable-Dependencies Principle says that dependencies should run in
the direction of stabilities.

((ul))((li))Suggested in ref://Mar03/.
((li))See metric://package/DepPack/ for what constitutes dependencies between packages.
((li))Value returned: name of the depended package that is less stable.
((/ul))
</description>
<compare term="I" set="DependedPackages" with="I" comp="term lt with"
value="qualifiedname(self)" />
<!-- Compare is deprecated; since V2.2 we would write: 
projection relset="DependedPackages" condition="_principal.I lt I" value="qualifiedname(self)" -->
</rule>

<rule name="SDP2" domain="package" category="Style" severity="2-med">
<description>Package violates the Stable-Dependencies Principle (SDP).((p))

The package depends on another package that is less abstract than itself.((p))

The Stable-Abstractions-Principle (SAP) says that a package should be as abstract
(as measured by metric metric://package/A/) as it is stable (as measured by
metric metric://package/I/).
The Stable-Dependencies Principle (SDP) says that dependencies should run in
the direction of stabilities.((p))

Therefore, dependencies should run in the direction of abstraction:
a package should be more abstract than the packages it depends on.

((ul))((li))Suggested in ref://Mar03/.
((li))See metric://package/DepPack/ for what constitutes dependencies between packages.
((li))Value returned: name of the depended package that is less abstract.
((/ul))

</description>
<compare term="A" set="DependedPackages" with="A" comp="term gt with" value="qualifiedname(self)" />
<!-- Compare is deprecated; since V2.2 we would write: 
projection relset="DependedPackages" condition="_principal.A gt A" value="qualifiedname(self)" -->
</rule>

<!-- Interaction rule -->
<rule name="Alternatives" domain="interaction" category="Style" severity="3-low">
<description>The interaction models alternative sequences.((p))
The interaction contains a combined fragment with 'alt', 'opt', or 'break'
operator to model alternative execution sequences. The purpose of a sequence
diagram is to show one scenario, not a set of different possible sequences.
Activity diagrams are better suited for that purpose.((p))
Consider using several sequence diagrams showing one scenario each, or
use an activity diagram.
((ul))((li))Suggested in ref://Oes04/.
((li))Value returned: name of the operator of the combined fragment.((/ul))
</description>
<projection relset="fragments" target="combinedfragment" 
   condition="operator='alt' or operator='opt' or operator='break'" value="operator" />
</rule>



<!-- Association rules -->

<metric name="numlooseassends" domain="association" internal="true" >
	<description>The number of association ends of the association with missing end types.</description>
	<projection relset="ends" condition="propertytype=''" />
</metric>

<metric name="numaggends" domain="association" internal="true" >
	<description>The number of aggregate ends (aggregation or composition).</description>
	<projection relset="ends" condition="!(aggregation='none'|aggregation='')" />
</metric>

<rule name="AggEnds" domain="association" category="Correctness" severity="1-high">
<description>The binary association has two composite or shared aggregation ends.((p))
A binary association may have at most one shared (hollow diamond) or composite
(filled diamond) aggregation end. This is a glossary://WFR// of the UML.
</description>
<violation condition="size(ends)=2 and numaggends>1" />
</rule>

<rule name="NaryAggEnds" domain="association" category="Correctness" severity="1-high">
<description>The n-ary association has a composite or shared aggregation end.((p))
Three (or more)- way associations must not indicate shared or composite aggregation.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of shared/composite aggregation ends.
((/ul))
</description>
<violation condition="size(ends)>2 and numaggends!=0" value="'#comp/shared ends: '+numaggends"/>
</rule>

<rule name="NaryNavEnds" domain="association" category="Correctness" severity="1-high">
<description>The n-ary association indicates a navigable association end.((p))
Three (or more)- way associations must not indicate navigability at any of the
association ends.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of navigable association ends.
((/ul))
</description>
<violation condition="size(ends)>2 and !(nav_ends=0|nav_ends=numassends)" value="'#navigable ends: '+nav_ends"/>
</rule>

<rule name="LooseEnd" domain="association" category="Completeness" severity="1-high">
<description>The association has one or more ends not connected to a model
element.((p))
Check the ends of the association, and attach the loose end(s) to the proper model element(s), or
remove the association from the model.
</description>
<violation condition="(size(ends) lt 2)|(numlooseassends!=0)" />
</rule>

<rule name="NaryAgg" domain="association" category="Style" severity="3-low"
applies_to="design">
<description>The association has three or more association ends.((p))
People are often confused by the semantics of n-ary associations.
N-ary associations have no representation in common programming
languages. The suggestion is therefore to remodel the n-ary association
using several plain associations.
((ul))((li))Suggested in ref://Fra03/ and ref://Oes04/.((/ul))
</description>
<violation condition="size(ends)>2" />
</rule>

<rule name="SpecAgg" domain="association" category="Style" severity="3-low" >
<description>The association is a specialization of another association.((p))
People are often confused by the semantics of specialized associations.
The suggestion is therefore to model any restrictions on the parent
association using constraints.
((ul))((li))Suggested in ref://Oes04/.
((li))Value returned: name of the parent association.((/ul))
</description>
<projection relation="context" target="generalization" element="general"
						value="'parent assoc: '+name" />
</rule>

<rule name="AssocClass" domain="associationclass" category="Style"
	severity="3-low" applies_to="design">
<description>Avoid association classes.((p))
Association classes have no representation in common programming languages.
They defer the decision which class(es) eventually will be responsible to
manage the association attributes.((p))
The recommendation is to remodel the association class to only use regular
classes and binary associations.
((ul))((li))Suggested in ref://Fra03/ and ref://Oes04/.((/ul))
</description>
<violation condition="0=0" />
</rule>

<!-- dependency rules -->
<rule name="NoSupplier" domain="dependency" category="Completeness" severity="1-high">
<description>The supplier end of the dependency link is not connected to a
model element.((p))
Check the dependency and attach the supplier end to the proper
model element, or remove the dependency link from the model.
</description>
	<violation condition="size(supplier)=0" />
</rule>

<rule name="NoClient" domain="dependency" category="Completeness" severity="1-high">
<description>The client end of the dependency link is not connected to any model
element.((p))
Check the dependency and attach the client end to the proper model element, or
remove the dependency link from the model.
</description>
	<violation condition="size(client)=0" />
</rule>


<!-- UML interface realization rules -->
<rule name="NoSupplier" domain="interfacerealization" category="Completeness" severity="1-high">
<description>The supplier end of the interface realization is not connected to an interface.((p))
For a loose supplier end, either attach the end to the
proper interface or delete the interface realization from the model.((p))
If the supplier end is connected to anything else but an interface,
connect it to the proper interface, or consider replacing the interface
realization with a plain UML generalization, realization, or dependency.
</description>
<violation condition="contract=''|typeof(contract)!='interface'" />
</rule>

<rule name="NoInterface" domain="interfacerealization" category="Completeness" severity="1-high">
<description>The client end of the interface realization is not connected to a model element.((p))
Check the interface realization and attach the client end to the proper model element, or
remove the interface realization from the model.
</description>
<violation condition="context=''" />
</rule>


<!-- UML generalization rules -->
<rule name="NoChild" domain="generalization" category="Completeness" severity="1-high">
<description>The child end of the generalization is not connected to a model
element.((p))Check the generalization and attach the child end to the proper model element, or
remove the generalization from the model.
</description>
<violation condition="context=''" />
</rule>

<rule name="NoParent" domain="generalization" category="Completeness" severity="1-high">
<description>The parent end of the generalization is not connected to a model
element.((p))Check the generalization and attach the parent end to the proper model element, or
remove the generalization from the model.
</description>
<violation condition="general=''" />
</rule>

<rule name="TypeMismatch" domain="generalization" category="Correctness" severity="1-high">
<description>Parent and child of the generalization are not of the same type.((p))
The child must be of the same type as the parent. This is a glossary://WFR// of the UML.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: types of the parent and child elements.
((/ul))
</description>
<violation condition="typeof(general)!=typeof(context)" value="'parent: '+typeof(general)+' child: '+typeof(context)"/>
</rule>




<!-- activities rules -->

<rule name="Unnamed" domain="objectnode" category="Completeness" severity="3-low">
<description>The object node has no name.
((ul))((li))See rule rule://action/Unnamed/ for actions.((/ul))</description>
<violation condition="name=''" />
</rule>

<rule name="InOrOut" domain="objectnode" category="Correctness" severity="1-high">
<description>The activity parameter node has both incoming and outgoing flows.((p))
Activity parameter nodes must have either only incoming or only outgoing edges,
but not both at the same time. Check the edges on the node and make sure
they're all pointing in the same direction.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="kind='activityparameter' and Incoming!=0 and Outgoing!=0" />
</rule>

<rule name="IsolatedNode" domain="objectnode" category="Completeness" severity="1-high">
<description>The object node has neither incoming nor outgoing edges.
((ul))((li))See rule rule://action/IsolatedAction/ for actions.((/ul))</description>
<violation condition="(Incoming+Outgoing)=0" />
</rule>

<rule name="EmptyGroup" domain="activitygroup" category="Completeness" severity="2-med">
<description>The activity group does not contain any nodes or subgroups.((p))
Add nodes to the activity group, or delete it from the model.</description>
<violation condition="(size(groups)+size(nodes))=0" />
</rule>

<metric name="NumExpNodes" domain="activitygroup" internal="true">
<description>The number of expansion nodes in the group.</description>
<projection relset="nodes" target="objectnode" condition="kind='expansion'" />
</metric>
<rule name="NoExpansionNode" domain="activitygroup" category="Completeness" severity="1-high">
<description>The expansion region has no expansion node.((p))
An expansion region must have at least one input expansion node. This is
a glossary://WFR// of the UML.</description>
<violation condition="kind='expansion' and NumExpNodes=0" />
<!-- Imprecision: regions with outputElements but no inputElements won't be flagged. -->
</rule>


<rule name="DanglingCtrlFlow" domain="controlflow" category="Completeness" severity="1-high">
<description>The control flow has no source or target node, or both.((p))
Check the control flow and attach the proper source and target node, or delete
the edge from the model.
</description>
<violation condition="source=''|target=''" />
</rule>
<rule name="DanglingObjectFlow" domain="objectflow" category="Completeness" severity="1-high">
<description>The object flow has no source or target node, or both.((p))
Check the object flow and attach the proper source and target node, or delete
the edge from the model.
</description>
<violation condition="source=''|target=''" />
</rule>


<rule name="Unnamed" domain="action" category="Completeness" severity="3-low">
<description>Action has no name.((p))
Give the action a descriptive name that describes its purpose.</description>
<violation condition="name=''" />
</rule>

<rule name="IsolatedAction" domain="action" category="Completeness" severity="1-high">
<description>The action has neither incoming nor outgoing edges.((p))
If nothing goes in or comes out of the action, the action is useless.
Add the missing edges, or delete the action.</description>
<violation condition="(Incoming+Outgoing)=0" />
</rule>


<rule name="IllegalInitial" domain="controlnode" category="Correctness" severity="1-high">
<description>The initial node has incoming edges our outgoing object flows.((p))
Check the initial node to make sure it has no incoming edges, and that 
all outgoing edges are control flows.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of incoming edges and outgoing object flows.
((/ul))
</description>
<violation condition="kind='initial' and (Incoming!=0 or ObjOut!=0)" 
  value="'#in: '+Incoming+' #obj out: '+ObjOut"/>
</rule>


<rule name="IllegalFinal" domain="controlnode" category="Correctness" severity="1-high">
<description>Final nodes must not have any outgoing edges. Check the node and remove
the outgoing edges.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of outgoing edges of the final node.
((/ul))
</description>
<violation condition="(kind='activityfinal' or kind='flowfinal') and Outgoing!=0" 
  value="'#out: '+Outgoing"/>
</rule>

<rule name="IllegalJoin1" domain="controlnode" category="Correctness" severity="1-high">
<description>Join nodes must have exactly one outgoing edge.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of outgoing edges of the join node.
((/ul))
</description>
<violation condition="kind='join' and Outgoing!=1" value="'#out: '+Outgoing"/>
</rule>

<rule name="IllegalJoin2" domain="controlnode" category="Correctness" severity="1-high">
<description>Outgoing edge of join is the wrong type.((p))
If all of the join node's incoming edges are control flows, the outgoing edge must
be a control flow. If there is at least one incoming object flow, the outgoing edge
must be an object flow.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="kind='join' and ((ObjIn=0 and CtrlIn!=0 and CtrlOut=0) or (ObjIn!=0 and ObjOut=0))" />
</rule>


<rule name="IllegalFork1" domain="controlnode" category="Correctness" severity="1-high">
<description>Fork nodes must have exactly one incoming edge.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of incoming edges of the fork node.
((/ul))
</description>
<violation condition="kind='fork' and Incoming!=1" value="'#in: '+Incoming"/>
</rule>

<rule name="MixedEdgeTypes" domain="controlnode" category="Correctness" severity="1-high">
<description>Edges from or to decision, merge, or fork nodes must be of the same type.((p))
The incoming and outgoing edges of a decision, merge, or fork node must either be all control
flows or all object flows. A mixture of control and object flows attached to one such node is not
allowed. 
((ul))((li))This is a glossary://WFR// of the UML.((/ul))</description>
<violation condition="(kind='decision' or kind='merge' or kind='fork') and (ObjIn+ObjOut)!=0 and (CtrlIn+CtrlOut)!=0" />
</rule>

<rule name="ForkOut" domain="controlnode" category="Completeness" severity="2-med">
<description>Fork nodes should have two or more outgoing edges. Otherwise, there is no fork.
Check the node and add the missing outgoing edges.
((ul))
((li))Value returned: the number of outgoing edges of the fork node.((/ul))
</description>
<violation condition="kind='fork' and (Outgoing lt 2)" value="'#out: '+Outgoing"/>
</rule>

<rule name="IllegalDecision" domain="controlnode" category="Correctness" severity="1-high">
<description>Decision nodes must have exactly one incoming edge.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of incoming edges of the decision node.
((/ul))
</description>
<violation condition="kind='decision' and Incoming!=1" value="'#in: '+Incoming"/>
</rule>
<metric name="GuardedOut" domain="controlnode" internal="true">
<description>The number of outgoing edges with a guard.</description>

<projection relation="source" target="controlflow|objectflow" condition="guard!=''" />

</metric>
<rule name="DecisionOut" domain="controlnode" category="Completeness" severity="2-med">
<description>Decision nodes should have two or more outgoing edges, each with a guard.((p))
Otherwise, there is no decision. Check the node and add the missing edges and/or guards.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of outgoing edges of the node, and the number of guards
on these edges.
((/ul))
</description>
<violation condition="kind='decision' and ((Outgoing lt 2) or (Outgoing!=GuardedOut))"
  value="'#out: '+Outgoing+' #guards: '+GuardedOut" />
</rule>

<rule name="IllegalMerge" domain="controlnode" category="Correctness" severity="1-high">
<description>Merge nodes must have exactly one outgoing edge.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of outgoing edges of the merge node.
((/ul))
</description>
<violation condition="kind='merge' and Outgoing!=1" value="'#out: '+Outgoing"/>
</rule>
<rule name="NumIncoming" domain="controlnode" category="Completeness" severity="2-med">
<description>Merge and join nodes should have two or more incoming edges.
Otherwise, there is nothing to merge/join. Check the node and add the missing
incoming edges.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the number of incoming edges of the node.
((/ul))
</description>
<violation condition="(kind='merge'|kind='join') and (Incoming lt 2)" value="'#in: '+Incoming"/>
</rule>

<rule name="IsolatedNode" domain="controlnode" category="Completeness" severity="1-high">
<description>The control node has neither incoming nor outgoing edges.
((ul))((li))See rule rule://action/IsolatedAction/ for actions.((/ul))</description>
<violation condition="(Incoming+Outgoing)=0" />
</rule>

<rule name="NoIncoming" domain="pin" category="Completeness" severity="1-high">
<description>The input pin has no incoming edges.((p))
Input pins require incoming edges to provide values to their actions.
Add an incoming edge to the pin.</description>
<violation condition="kind='input' and Incoming=0" />
</rule>

<rule name="NoOutgoing" domain="pin" category="Completeness" severity="1-high">
<description>The output pin has no outgoing edges.((p))
Output pins require outgoing edges to deliver values provided by their actions.
Add in outgoing edge to the pin.</description>
<violation condition="kind='output' and Outgoing=0" />
</rule>

<rule name="IllegalInputPin" domain="pin" category="Correctness" severity="1-high">
<description>The input pin has outgoing edges.((p))
Only input pins on structured activity nodes can have outgoing edges.
Check the pin and remove any outgoing edges.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of outgoing edges of the pin.((/ul))</description>
<violation condition="kind='input' and Outgoing!=0 and typeof(context)='action'"
  value="'#out: '+Outgoing" />
</rule>

<rule name="IllegalOutputPin" domain="pin" category="Correctness" severity="1-high">
<description>The output pin has incoming edges.((p))
Only output pins on structured activity nodes can have incoming edges.
Check the pin and remove any incoming edges.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of incoming edges of the pin.((/ul))</description>
<violation condition="kind='output' and Incoming!=0 and typeof(context)='action'" 
  value="'#in: '+Incoming"/>
</rule>

<rule name="IllegalValuePin" domain="pin" category="Correctness" severity="1-high">
<description>The value pin has an incoming edge.((p))
Value pins provide their actions with constant values and thus require no 
incoming edges. Check the pin and remove any incoming edges.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: number of incoming edges of the pin.((/ul))
</description>
<violation condition="kind='value' and Incoming!=0" value="'#in: '+Incoming"/>
</rule>



<!-- Number of incoming and outgoing object and control flows for actions, object nodes, control nodes, and pins -->

<metric name="CtrlIn" domain="action" internal="true"><projection relation="target" target="controlflow"/></metric>
<metric name="CtrlOut" domain="action" internal="true"><projection relation="source" target="controlflow"/></metric>
<metric name="ObjIn" domain="action" internal="true"><projection relation="target" target="objectflow"/></metric>
<metric name="ObjOut" domain="action" internal="true"><projection relation="source" target="objectflow"/></metric>
<metric name="PinIn" domain="action" internal="true"><projection relset="inputs" target="pin" sum="Incoming"/></metric>
<metric name="PinOut" domain="action" internal="true"><projection relset="outputs" target="pin" sum="Outgoing"/></metric>
<metric name="Incoming" domain="action" internal="true"><compoundmetric term="CtrlIn+ObjIn+PinIn"/></metric>
<metric name="Outgoing" domain="action" internal="true"><compoundmetric term="CtrlOut+ObjOut+PinOut"/></metric>

<metric name="CtrlIn" domain="objectnode" internal="true"><projection relation="target" target="controlflow"/></metric>
<metric name="CtrlOut" domain="objectnode" internal="true"><projection relation="source" target="controlflow"/></metric>
<metric name="ObjIn" domain="objectnode" internal="true"><projection relation="target" target="objectflow"/></metric>
<metric name="ObjOut" domain="objectnode" internal="true"><projection relation="source" target="objectflow"/></metric>
<metric name="ExcIn" domain="objectnode" internal="true"><projection relation="exceptioninput" target="exceptionhandler"/></metric>
<metric name="Incoming" domain="objectnode" internal="true"><compoundmetric term="CtrlIn+ObjIn+ExcIn"/></metric>
<metric name="Outgoing" domain="objectnode" internal="true"><compoundmetric term="CtrlOut+ObjOut"/></metric>

<metric name="CtrlIn" domain="controlnode" internal="true"><projection relation="target" target="controlflow"/></metric>
<metric name="CtrlOut" domain="controlnode" internal="true"><projection relation="source" target="controlflow"/></metric>
<metric name="ObjIn" domain="controlnode" internal="true"><projection relation="target" target="objectflow"/></metric>
<metric name="ObjOut" domain="controlnode" internal="true"><projection relation="source" target="objectflow"/></metric>
<metric name="Incoming" domain="controlnode" internal="true"><compoundmetric term="CtrlIn+ObjIn"/></metric>
<metric name="Outgoing" domain="controlnode" internal="true"><compoundmetric term="CtrlOut+ObjOut"/></metric>

<metric name="CtrlIn" domain="pin" internal="true"><projection relation="target" target="controlflow"/></metric>
<metric name="CtrlOut" domain="pin" internal="true"><projection relation="source" target="controlflow"/></metric>
<metric name="ObjIn" domain="pin" internal="true"><projection relation="target" target="objectflow"/></metric>
<metric name="ObjOut" domain="pin" internal="true"><projection relation="source" target="objectflow"/></metric>
<metric name="ExcIn" domain="pin" internal="true"><projection relation="exceptioninput" target="exceptionhandler"/></metric>
<metric name="Incoming" domain="pin" internal="true"><compoundmetric term="CtrlIn+ObjIn+ExcIn"/></metric>
<metric name="Outgoing" domain="pin" internal="true"><compoundmetric term="CtrlOut+ObjOut"/></metric>




<!-- Use case rules -->
<set name="OutGoingAssociations" domain="actor">
	<description>The set of ougoing associations of the actor.</description>
	<projection relation="context" target="property" targetcondition="association!=''"
	element="association" exclude_self="true"/>
</set>

<set name="AttachedAssociations" domain="actor">
	<description>The set of associations attached to the actor.</description>
  <projection relation="propertytype" target="property" targetcondition="association!=''"
	element="association" exclude_self="true" />
</set>

<set name="Associations" domain="actor">
	<description>The set of associations the actor participates in.</description>
	<projection relset="OutGoingAssociations+AttachedAssociations" />
</set>

<rule name="NoAssoc" domain="actor" category="Completeness" severity="1-high">
<description>The actor is not associated with any use cases, classes, or subsystems.((p))
Without such associations, the actor is useless. Associate the actor
with one or more use cases, or delete it from the model.
((ul))((li))Suggested in ref://Amb03/.((/ul))
</description>
<violation condition="size(Associations)=0" />
</rule>

<rule name="Unused" domain="usecase" category="Completeness" severity="1-high">
<description>The use case is not used.((p))
The use case is not associated with any actors, or included in or extending
other use cases. Such a use case is useless. Associate it with an actor, attach
it to another use case, or delete it from the model.
((ul))((li))Suggested in ref://Amb03/.((/ul))
</description>
<violation condition="(NumAss+Included+Extending)=0" />
</rule>

<rule name="DupExPoint" domain="usecase" category="Correctness" severity="1-high" >
<description>The use case has two or more extension points of the same name.((p))
Rename the extension points so that they all have unique names.
((ul))((li))This is a glossary://WFR// of the UML.
((li))Value returned: the name of the duplicate extension points.((/ul))
</description>
<projection relation="context" target="extensionpoint" valueset="name" mincnt="2" />
</rule>

<rule name="NoName" domain="usecase" category="Completeness" severity="1-high" >
<description>The use case has an extension point without a name.((p))
Check the extension points of the use case and make sure they all have a name.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection relation="context" target="extensionpoint" condition="name=''" />
</rule>

<rule name="NaryAssoc" domain="usecase" category="Correctness" severity="2-med" >
<description>The use case participates in an n-ary association.((p))
A use case can only participate in binary associations.
Replace the n-ary association with several binary associations.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection relset="Associations" condition="size(assends)>2" />
</rule>

<rule name="NaryAssoc" domain="actor" category="Correctness" severity="2-med" >
<description>The actor participates in an n-ary association.((p))
An actor can only participate in binary associations.
Replace the n-ary association with several binary associations.
((ul))((li))This is a glossary://WFR// of the UML.((/ul))
</description>
<projection relset="Associations" condition="size(assends)>2" />
</rule>

<rule name="Unnamed" domain="actor" category="Correctness" severity="1-high">
<description>The actor has no name.
((ul))((li))See rule rule://class/Unnamed/ for classes.((/ul))
</description>
<violation condition="name=''" />
</rule>
<rule name="Unnamed" domain="usecase" category="Correctness" severity="1-high">
<description>The use case has no name.
((ul))((li))See rule rule://class/Unnamed/ for classes.((/ul))
</description>
<violation condition="name=''" />
</rule>

<rule name="CyclicIncludes" domain="usecase" category="Correctness" severity="1-high">
<description>Use case directly or indirectly includes itself.((p))
A use case cannot include use cases that directly or indirectly include it.
Remove some include links to break the cycle.
((ul))
((li))This is a glossary://WFR// of the UML.
((li))You can view the graph of 'use case includes' in the graph structures window.
((li))Value returned: number of use cases participating in the cycle.
((/ul))
</description>
<cycle nodes="IncludedUseCases" />
</rule>

<rule name="FunctionalDecomp" domain="usecase" category="Style" severity="2-med">
<description>Use case both includes and is included in other use cases.((p))
Several levels of include relations between use cases indicate a functional
decomposition, which should not be part of requirements analysis.
((ul))((li))Suggested in ref://Amb03/ to avoid more than two levels of
include relations; this rule flags more than one level.((/ul))</description>
<violation condition="Included!=0 and Including!=0" />
</rule>

<rule name="Extends" domain="usecase" category="Style" severity="3-low">
<description>The use case is extending another use case.((p))
The semantics of the extend relationship between use cases are often
misunderstood, and there are no definite criteria when to use "extend"
and when to use "include" relationships. The suggestion is to avoid
using "extend" relationships in favor of the more intuitive "include".
((ul))((li))Suggested in ref://Amb03/, ref://Oes04/.((/ul))
</description>
<violation condition="Extending!=0" />
</rule>



<!-- The literature references -->

<reference tag="AGE95">F. Abreu, M. Goulao, R. Esteves, "Toward the Design
Quality Evaluation of Object-Oriented Software Systems", 5th International
Conference on Software Quality, Austin, Texas, October 1995.
</reference>
<reference tag="Amb03">S. Ambler, "The Elements of UML Style",
Cambridge University Press, 2003.  ((br))
A comprehensive collection of style guidelines for the UML.
Also available online at www.agilemodeling.com/style
</reference>
<reference tag="BEGR00">S, Benlarbi, K. El Emam, N. Goel, S. Rai,
"Thresholds for Object-Oriented Measures", Proceedings of ISSRE2000,
24-37, 2000.</reference>
<reference tag="BDM97">Briand, Devanbu, Melo, "An Investigation into coupling
measures for object-oriented designs", Proceedings of the 19th International
Conference on Software Engineering, ICSE '97, Boston, 412-421, 1997.
</reference>
<reference tag="BMM98">W. Brown, R. Malveau, H, McCormick, T Mowbray,
"AntiPatterns: Refactoring Software, Architectures, and Projects in Crises",
Wiley, 1998.
</reference>
<reference tag="BMW02">L. Briand, W. Melo, J. Wuest, "Assessing
the Applicability of Fault-Proneness Models Across Object-Oriented
Software Projects", IEEE Transactions on Software Engineering, 28 (7),
706-720, 2002.  ((br))
Also available from http://www.sdmetrics.com/Refs.html
</reference>
<reference tag="BW02">L. Briand, J. Wuest, "Empirical Studies of
Quality Models in Object-Oriented Systems", Advances in Computers
Vol. 59, 97-166, 2002.  ((br))
Also available from http://www.sdmetrics.com/Refs.html
</reference>
<reference tag="BWDP00">L. Briand, J. Wuest, J. Daly, V. Porter,
"A Comprehensive Empirical Validation of Product Measures for
Object-Oriented Systems". Journal of Systems and Software 51,
p. 245-273, 2000.  ((br))
Also available from http://www.sdmetrics.com/Refs.html
</reference>
<reference tag="BWL01">L. Briand, J. Wuest, H. Lounis, "Replicated
Case Studies for Investigating Quality Factors in Object-Oriented
Designs, Empirical Software Engineering: An International Journal, Vol
6, No 1, 11-58, 2001.  ((br))
Also available from http://www.sdmetrics.com/Refs.html
</reference>
<reference tag="CK94">S. Chidamber, C. Kemerer, "A Metrics Suite for Object-Oriented Design",
IEEE Transactions on Software Engineering, 20 (6), 476-493, 1994.
</reference>
<reference tag="CK98">S. Chidamber, D. Darcy, C. Kemerer, "Managerial
use of Metrics for Object-Oriented Software: An Exploratory Analysis",
IEEE Transactions on Software Engineering, 24 (8), 629-639,
1998.</reference>
<reference tag="Fow99">M. Fowler, "Refactoring: Improving the Design of
Existing Code", Addison Wesley, 1999.
</reference>
<reference tag="FP96">N. Fenton, S. Pfleeger, "Software Metrics: A
Practical and Rigorous Approach". International Thompson Computer
Press, 1996.</reference>
<reference tag="Fra03">D. Frankel, "Model Driven Architecture: Applying MDA
to Enterprise Computing", Wiley, 2003.
</reference>
<reference tag="ISO9126">ISO/IEC FCD 9126-1.2, "Information Technology -
Software Product. Quality- Part 1: Quality Model", 1998.</reference>
<reference tag="JRH04">M. Jeckle, C. Rupp, J. Hahn, B. Zengler, S. Queins,
"UML 2 glasklar", Carl Hanser Verlag, 2004.
</reference>
<reference tag="Lan03">C. Lange, "Empirical Investigations in Software Architecture
Completeness", Master's Thesis, Department of Mathematics and Computing Science,
Technical University Eindhoven, 2003.
</reference>
<reference tag="LH93">W. Li, S. Henry, "Object-Oriented Metrics that Predict
Maintainability", J. Systems and Software, 23 (2), 111-122, 1993.
</reference>
<reference tag="LC94">A. Lake, C. Cook, "Use of factor analysis to develop OOP
software complexity metrics", Proc. 6th Annual Oregon Workshop on Software
Metrics, Silver Falls, Oregon, April 1994.
</reference>
<reference tag="LK94">M. Lorenz, J. Kidd, "Object-oriented Software Metrics",
Prentice Hall, 1994.
</reference>
<reference tag="LLW95">Y. Lee, B. Liang, S. Wu, F. Wang, "Measuring Coupling
and Cohesion of an Object-Oriented Program Based On Information Flow",
Proc. International Conference on Software Quality (ICSQ '95), 81-90, 1995.
</reference>
<reference tag="Mar03">R. Martin, "Agile Software Development: Principles,
Patterns, and Practices", Prentice Hall, 2003.
</reference>
<reference tag="McC76">T. McCabe, "A Complexity Measure", IEEE Transactions
on Software Engineering, 2 (12), 308-320, 1976.
</reference>
<reference tag="MGP03">D. Miranda, M. Genero, M. Piattini, "Empirical validation
of metrics for UML statechart diagrams", 5th Internation Conference on Enterprise
Informations Systems (ICEIS03), 1, p. 87-95, 2003.
</reference>
<reference tag="NP98">P. Nesi, T. Querci, "Effort estimation and
prediction of object-oriented systems", Journal of Systems and
Software 42, p. 89-102, 1998.</reference>
<reference tag="Oes04">Bernd Oesterreich, "Die UML 2.0 Kurzreferenz fuer
die Praxis", Oldenbourg Verlag, 2004.
</reference>
<reference tag="OMG03">Object Management Group, "OMG Unified Modeling Language
Specification", Version 1.5, OMG Adopted Formal Specification formal/03-03-01, 2003.
</reference>
<reference tag="OMG05">Object Management Group, "UML 2.0 Superstructure Specification",
OMG Adopted Formal Specification formal/05-07-04, 2005.
</reference>
<reference tag="Rie96">A. Riel, "Object-Oriented Design Heuristics",
Addison Wesley, 1996.
</reference>
<reference tag="RVR04">A. Ramirez, P. Vanpeperstraete, A. Rueckert, K. Odutola,
J. Bennett, L. Tolke, M. van der Wulp, "ArgoUML User Manual v0.16", 2004.  ((br))
Available from http://argouml.tigris.org.
</reference>
<reference tag="TSM92">
D. Tegarden, S. Sheetz, D. Monarchi, "The Effectiveness of Traditional
Software Metrics for Object-Oriented Systems", in: J. Nunamaker Jr, R. Sprague (eds.),
Proceedings of the 25th Hawaii International Conference on Systems Sciences, Vol. IV,
IEEE Computer Society Press, 359-368, Jan. 1992.
</reference>


<!--- The Glossary -->

<term name="Cohesion">
Cohesion is the degree to which the elements in a design unit
(package, class) are logically related, or "belong together". As
such, cohesion is a semantic concept.((p))

Cohesion metrics have been proposed which attempt to approximate this
semantic concept using syntactical criteria. Such metrics quantify the
connectivity (coupling) between elements of the design unit: the
higher the connectivity between elements, the higher the cohesion.((p))

Cohesion metrics often are normalized to have a notion of minimum and
maximum cohesion, usually expressed on a scale from 0 to 1. Minimum
cohesion (0) is assumed when the elements are entirely unconnected,
maximum cohesion (1) is assumed when each element is connected to
every other element.((p))

Not normalized metrics are based on counts of connections between
design elements in a unit (e.g., method calls within a class). As
such, not normalized metrics are conceptually similar to
glossary://Complexity/complexity/ metrics.((p))

((i))Impact on quality((/i))((p))

A low cohesive design element has been assigned many unrelated
responsibilities. Consequently, the design element is more difficult
to understand and therefore also harder to maintain and reuse. Design
elements with low cohesion should be considered for refactoring, for
instance, by extracting parts of the functionality to separate classes
with clearly defined responsibilities.((p))

((i))Empirical results((/i)) ref://BW02/((p))

In practice, cohesion metrics are only of limited usefulness:
((ul))
((li))Not normalized cohesion metrics often are strongly related to size
metrics. This makes sense since, as discussed in the section on
glossary://Size/size/
metrics, large classes or packages may in fact suffer from low
cohesion. Such cohesion metrics then are, of course, good quality
indicators, but they are redundant with size metrics - they
provide no new information about the element.
((li))Normalized cohesion metrics do not consistently have a bearing on
system qualities. I.e., we cannot conclude from a high or low cohesion
value that a class is, e.g., more or less fault-prone. Either, the
theoretical negative impact of low cohesion on system quality is not
always that critical in practice, or, the cohesion metrics simply fail
to identify design elements with unrelated responsibilities.
((/ul))
</term>
<term name="Completeness">Design rules of the "Completeness" category raise
issues that hint at incomplete design. This highlights model elements that still
need some work. For example, empty packages, unused classes, unnamed attributes,
parameters without a type, etc.</term>
<term name="Complexity">
Complexity measures the degree of connectivity between elements of a
design unit. Whereas glossary://Size/size/ counts the elements in a design unit,
complexity is concerned with the relationships/dependencies between
the elements in the design unit. For instance, counting the number
method invocations among the methods within one class can be
considered a measure of class complexity, or the number of transitions
between the states in a state diagram.((p))

((i))Impact on quality((/i))((p))

High complexity of interactions between the elements of a design unit
can lead to decreased understandability and therefore increased
fault-proneness. Also, testing such design units is more difficult.((p))

((i))Empirical results((/i)) ref://BW02/((p))

In practice, complexity metrics are often strongly correlated with
size measures. Large design units that contain many design elements
within are also more likely to have a large number of connections
between the design elements.((p))

Thus, while complexity metrics are good indicators of qualities such
as fault-proneness, they provide no new insights in addition to size
metrics.
</term>
<term name="Correctness">Design rules of the "Correctness" category raise issues
that constitute illegal design. For example, violation of well-formedness rules
(glossary://WFR//) of the UML.</term>
<term name="Coupling">
The degree to which the elements in a design are connected.((p))

((i))Impact on quality((/i))((p))

Coupling connections cause dependencies between design elements, which,
in turn, have an impact on system qualities such as maintainability (a
modification of a design element may require modifications to its connected
elements) or testability (a fault in one design element may cause a failure
in a completely different, connected element). Thus, a common design principle
is to minimize coupling.((p))

Most coupling dependencies are directed - the coupling usually defines a
client-supplier relationship between the design elements. Therefore, it is
useful to distinguish import coupling ("using") and export coupling ("used"):
((ul))((li))See glossary://Coupling (import)// and
glossary://Coupling (export)//.((/ul))

((i))Empirical results((/i)) ref://BW02/((p))

Coupling metrics have consistently been found to be good indicators of
fault-proneness. It seems worthwhile to investigate different dimensions
of coupling: import and export coupling, different coupling mechanisms,
distinguishing coupling to COTS libraries and application-specific
classes/packages. Coupling metrics are suitable to identify design
elements with high fault density. Therefore, coupling metrics greatly
help to identify small parts of a design that contain a large number of faults.

</term>
<term name="Coupling (import)">
Import coupling measures the degree to which an element has knowledge
of, uses, or depends on other design elements.((p))

((i))Impact on quality((/i))

((ul))
((li))Decreased maintainability: changes to the supplier may necessitate
follow-up changes (ripple effects) to the client. The stability of the supplier
is a factor to consider here. High coupling to elements that are not likely to
change is less harmful than coupling to variation points.
((li))Decreased understandability, increased fault-proneness: elements with high
import coupling operate in large context, developers need to know all the services
the element relies on, and how to use them.
((li))Decreased reusability: To reuse a class or package with high import coupling
in a new context, all the required services must also be made available in the
new context.
((/ul))

((i))Empirical results((/i))((p))
See entry for glossary://Coupling/coupling/.
</term>
<term name="Coupling (export)">Export coupling measures the degree to which an
element is used by, depended upon, by other design elements. High export coupling
is often observed for general utility classes (e.g., for string handling or
logging services) that are used pervasively across all layers of the system.
Thus, high export coupling is not necessarily indicative of bad design.((p))

((i))Impact on quality((/i))((p))

High export coupling
elements that are likely to change in the future can have a large impact on the
system if the change affects the interface. Therefore, high export classes
should be reviewed for anticipated changes, to ensure that these changes can
implemented with minimal impact.((p))

((i))Empirical results((/i))((p))
See entry for glossary://Coupling/coupling/.
</term>
<term name="Diagram">
Diagram metrics pertain to the diagrams of the UML model.
There are two types of diagram metrics:
((ol))
((li))Diagram metrics that count how often a class, package, etc. appears
on the diagrams in the model. Similar to
glossary://Coupling (export)/export coupling/, the more often a model element
appears on diagrams, the more important is the role of the model element.((br))
You may also look out for elements which do not appear on any diagrams.
This could indicate that the diagrams are not complete, or they may be
the result of an incomplete delete operation.
((li))Metrics that count the number of model elements on a diagram.
These measure the size of the diagram. You may consider reorganizing
large diagrams into several smaller ones, e.g., based on the 7 +/-2 rule
of the amount of information that people can deal with at a time ref://Amb03/.
((/ol))
On a technical note, many UML modeling tools use a proprietary solution to
store diagram layout information in the XMI file. If you do not obtain
diagram metrics for your model, you need a special XMI transformation file.
Check the SDMetrics website if there is one available for your UML tool.
</term>
<term name="Inheritance">
Inheritance-related metrics are concerned with the use of inheritance
relationships. This includes aspects such as
((ul))
((li))depth/width of the inheritance graph
((li))number of ancestors/descendents of a design element
((li))inherited size
((li))polymorphism, method overriding, etc.
((/ul))

((i))Impact on quality((/i))((p))

Deep inheritance structures are hypothesized to be more fault-prone.
The information needed to fully understand a class situated deep in the
inheritance tree is spread over several ancestor classes, thus more difficult
to overview.((p))

Similar to high export coupling, a modification to a design element with a
large number of descendents can have a large effect on the system. Make sure
the interface of the class is stable, or that anticipated modifications can be
added without affecting the inheritance hierarchy at large.((p))

((i))Empirical results((/i)) ref://BW02/((p))

Empirical studies show that effects of the use of inheritance on system qualities
such as fault-proneness vary greatly. Depending on factors such as developer
experience, system quality can benefit or suffer from the use of inheritance,
or be unaffected by it.((p))

Thus, inheritance metrics should not be relied on for decision making before
their impact on system quality is not demonstrated in a given development
environment. Extant inheritance metrics per se are not suitable to distinguish
proper use of inheritance from improper use.((p))

Also, inheritance is not very frequently used in designs. Typically,
only a small percentage of the classes in a system will participate
in inheritance relationships. As a consequence, inheritance-related
metrics tend to have low variance. Such metrics do not differentiate
design elements very well and therefore are less likely to be useful
quality predictors.
</term>
<term name="Naming">Design rules of the "Naming" category raise issues concerning
the names assigned to model elements. For example, adherence to naming conventions
for capitalization, use of keywords in element names.
</term>
<term name="Severity">The severity of a design rule indicates how critical a
violation is. The rules distinguish three levels of severity:
((ul))
((li))1-high - violation of the rule constitutes illegal design, or poor
design practices with a strong negative impact on system quality.
The issue should be resolved under all circumstances.
((li))2-med - violation of the rule may negatively impact system quality.
The issue should be resolved if there is no justification for the violation.
((li))3-low - violation of the rule is not likely to have severe consequences,
but perfectionists will still want to address the issue.
((/ul))
</term>
<term name="Size">
Design size metrics measure the size of design elements, typically by counting
the elements contained within. For example, the number of operations in a class,
the number of classes in a package, and so on.((p))

((i))Impact on quality((/i))

Size metrics are good candidates for developing cost or effort estimates for
implementation, review, testing, or maintenance activities. Such estimates are
then used as input for project planning purposes and the allocation of personnel.((p))

In addition, large sized design elements (e.g., big classes or packages) may suffer
from poor design. In an iterative development process, more and more functionality
is added to a class or package over time. The danger is that, eventually, many
unrelated responsibilities are assigned to a design element. As a result, it has
low functional glossary://Cohesion/cohesion/. This in turn negatively impacts the
understandability, reusability, and maintainability of the design element.((p))

Therefore, interfaces and implementations of large classes or packages should be
reviewed for functional cohesion. If there is no justification for the large size,
the design element should be considered for refactoring, for instance, extract parts
of the functionality to separate, more cohesive classes.((p))

((i))Empirical results((/i)) ref://BW02/((p))

Empirical studies consistently confirm the importance of size as the main cost
driver in a software project. Size metrics are also consistently good indicators
of fault-proneness: large methods/classes/packages contain more faults. However,
since size metrics systematically identify large design elements as fault-prone,
these metrics alone are not suitable to find elements with high fault density
</term>
<term name="Style">Design rules of the "Style" category raise design issues that
are considered bad practice. While these issues do not indicate illegal design,
they may be detrimental to system quality in the long run. For example,
circular dependencies among packages, a class referencing one of its subclasses,
long parameter lists, etc.</term>
<term name="WFR">Well-formedness rules. The UML standards ref://OMG03/
ref://OMG05/ define a set of well-formedness rules, or constraints,
that any valid UML model must comply with.
</term>


</sdmetrics>
