code:
diff -Nuar umbrello-15.08.1.orig/CMakeLists.txt umbrello-15.08.1/CMakeLists.txt
--- umbrello-15.08.1.orig/CMakeLists.txt	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/CMakeLists.txt	2015-10-08 11:48:59.471089026 +0300
@@ -6,8 +6,8 @@
 set (KDE_APPLICATIONS_VERSION_MICRO "1")

 set(UMBRELLO_VERSION_MAJOR "2")
-set(UMBRELLO_VERSION_MINOR "17")
-set(UMBRELLO_VERSION_PATCH ${KDE_APPLICATIONS_VERSION_MICRO})
+set(UMBRELLO_VERSION_MINOR "18")
+set(UMBRELLO_VERSION_PATCH "99")

 option(BUILD_KF5 "Build for KDE Frameworks 5" OFF)

diff -Nuar umbrello-15.08.1.orig/umbrello/actor.cpp umbrello-15.08.1/umbrello/actor.cpp
--- umbrello-15.08.1.orig/umbrello/actor.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/actor.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,67 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "actor.h"
-
-/**
- * Constructs an Actor.
- *
- * @param name   The name of the Actor.
- * @param id     The unique id to assign to this Actor.
- */
-UMLActor::UMLActor(const QString & name, Uml::ID::Type id)
-  : UMLCanvasObject(name, id)
-{
-    init();
-}
-
-/**
- * Standard destructor.
- */
-UMLActor::~UMLActor()
-{
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLActor::init()
-{
-    m_BaseType = UMLObject::ot_Actor;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLActor::clone() const
-{
-    UMLActor *clone = new UMLActor();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the <UML:Actor> XMI element.
- */
-void UMLActor::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement actorElement = UMLObject::save(QLatin1String("UML:Actor"), qDoc);
-    qElement.appendChild(actorElement);
-}
-
-/**
- * Loads the <UML:Actor> XMI element (empty).
- */
-bool UMLActor::load(QDomElement& element)
-{
-    Q_UNUSED(element);
-    return true;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/actor.h umbrello-15.08.1/umbrello/actor.h
--- umbrello-15.08.1.orig/umbrello/actor.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/actor.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,44 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ACTOR_H
-#define ACTOR_H
-
-#include "umlcanvasobject.h"
-
-/**
- * This class contains the non-graphical information required for a UML Actor.
- * This class inherits from @ref UMLCanvasObject which contains most of the
- * information.
- * The @ref UMLDoc class creates instances of this type.
- *
- * @short Information for a non-graphical UML Actor.
- * @author Paul Hensgen <phensgen@techie.com>
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLActor : public UMLCanvasObject
-{
-    Q_OBJECT
-public:
-    explicit UMLActor(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLActor();
-
-    virtual void init();
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-    bool load(QDomElement & element);
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/artifact.cpp umbrello-15.08.1/umbrello/artifact.cpp
--- umbrello-15.08.1.orig/umbrello/artifact.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/artifact.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,90 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "artifact.h"
-#include "association.h"
-#include "clipboard/idchangelog.h"
-
-#include <KLocalizedString>
-
-/**
- * Sets up an Artifact.
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLArtifact::UMLArtifact(const QString & name, Uml::ID::Type id)
-  : UMLPackage(name, id),
-    m_drawAsType(defaultDraw)
-{
-    m_BaseType = UMLObject::ot_Artifact;
-}
-
-/**
- * Standard deconstructor.
- */
-UMLArtifact::~UMLArtifact()
-{
-}
-
-/**
- * Make a clone of this object.
- * @return the cloned object
- */
-UMLObject* UMLArtifact::clone() const
-{
-    UMLArtifact *clone = new UMLArtifact();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the UML:Artifact element including its operations,
- * attributes and templates
- * @param qDoc       the xml document
- * @param qElement   the xml element
- */
-void UMLArtifact::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement artifactElement = UMLObject::save(QLatin1String("UML:Artifact"), qDoc);
-    artifactElement.setAttribute(QLatin1String("drawas"), m_drawAsType);
-    qElement.appendChild(artifactElement);
-}
-
-/**
- * Loads the UML:Artifact element including its operations,
- * attributes and templates.
- * @param element   the xml element to load
- * @return the success status of the operation
- */
-bool UMLArtifact::load(QDomElement& element)
-{
-    QString drawAs = element.attribute(QLatin1String("drawas"), QLatin1String("0"));
-    m_drawAsType = (Draw_Type)drawAs.toInt();
-    return true;
-}
-
-/**
- * Sets m_drawAsType for which method to draw the artifact as.
- * @param type   the draw type
- */
-void UMLArtifact::setDrawAsType(Draw_Type type)
-{
-    m_drawAsType = type;
-}
-
-/**
- * Returns the value of m_drawAsType.
- * @return the value of the draw type attribute
- */
-UMLArtifact::Draw_Type UMLArtifact::getDrawAsType()
-{
-    return m_drawAsType;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/artifact.h umbrello-15.08.1/umbrello/artifact.h
--- umbrello-15.08.1.orig/umbrello/artifact.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/artifact.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,66 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ARTIFACT_H
-#define ARTIFACT_H
-
-#include "package.h"
-
-/**
- * This class contains the non-graphical information required for a UML
- * Artifact.
- * This class inherits from @ref UMLCanvasObject which contains most of the
- * information.
- *
- * @short Non-graphical information for a Artifact.
- * @author Jonathan Riddell
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLArtifact : public UMLPackage
-{
-    Q_OBJECT
-public:
-
-    /**
-     * Artifacts can be drawn using one of several icons.
-     */
-    enum Draw_Type {
-        defaultDraw,
-        file,
-        library,
-        table
-    };
-
-    explicit UMLArtifact(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLArtifact();
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    void setDrawAsType(Draw_Type type);
-
-    Draw_Type getDrawAsType();
-
-protected:
-
-    bool load(QDomElement & element);
-
-private:
-
-    /**
-     * Artifacts can be drawn as one of several different icons,
-     * this value choosing how to draw them.
-     */
-    Draw_Type m_drawAsType;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/association.cpp umbrello-15.08.1/umbrello/association.cpp
--- umbrello-15.08.1.orig/umbrello/association.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/association.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,742 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "association.h"
-
-// app includes
-#include "debug_utils.h"
-#include "classifier.h"
-#include "classpropertiesdialog.h"
-#include "folder.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umlrole.h"
-#include "uniqueid.h"
-#include "model_utils.h"
-#include "cmds.h"
-
-// kde includes
-#include <KLocalizedString>
-
-// qt includes
-#include <QPointer>
-#include <QRegExp>
-
-using namespace Uml;
-
-DEBUG_REGISTER(UMLAssociation)
-
-/**
- * Sets up an association.
- * A new unique ID is assigned internally.
- * @param type    The AssociationType::Enum to construct.
- * @param roleA   Pointer to the UMLObject in role A.
- * @param roleB   Pointer to the UMLObject in role B.
- */
-UMLAssociation::UMLAssociation(Uml::AssociationType::Enum type,
-                                UMLObject * roleA, UMLObject * roleB)
-  : UMLObject(QString())
-{
-    init(type, roleA, roleB);
-
-    m_pRole[RoleType::A]->setID(UniqueID::gen());
-    m_pRole[RoleType::B]->setID(UniqueID::gen());
-}
-
-/**
- * Constructs an association - for loading only.
- * This constructor should not normally be used as it constructs
- * an incomplete association (i.e. the role objects are missing.)
- * @param type   The AssociationType::Enum to construct.
- *               Default: Unknown.
- */
-UMLAssociation::UMLAssociation(Uml::AssociationType::Enum type)
-  : UMLObject(QString(), Uml::ID::Reserved)
-{
-    init(type, NULL, NULL);
-}
-
-/**
- * Standard destructor.
- */
-UMLAssociation::~UMLAssociation()
-{
-    if (m_pRole[RoleType::A] == NULL) {
-        uError() << "UMLAssociation destructor: m_pRole[A] is NULL already";
-    } else {
-        delete m_pRole[RoleType::A];
-        m_pRole[RoleType::A] = NULL;
-    }
-    if (m_pRole[RoleType::B] == NULL) {
-        uError() << "UMLAssociation destructor: m_pRole[B] is NULL already";
-    } else {
-        delete m_pRole[RoleType::B];
-        m_pRole[RoleType::B] = NULL;
-    }
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLAssociation::operator==(const UMLAssociation &rhs) const
-{
-    if (this == &rhs) {
-        return true;
-    }
-    return (UMLObject::operator== (rhs) &&
-             m_AssocType == rhs.m_AssocType &&
-             m_Name == rhs.m_Name &&
-             m_pRole[RoleType::A] == rhs.m_pRole[RoleType::A] &&
-             m_pRole[RoleType::B] == rhs.m_pRole[RoleType::B]);
-}
-
-/**
- * Returns the AssociationType::Enum of the UMLAssociation.
- * @return  The AssociationType::Enum of the UMLAssociation.
- */
-Uml::AssociationType::Enum UMLAssociation::getAssocType() const
-{
-    return m_AssocType;
-}
-
-/**
- * Returns a String representation of this UMLAssociation.
- */
-QString UMLAssociation::toString() const
-{
-    QString string;
-    if(m_pRole[RoleType::A])
-    {
-        string += m_pRole[RoleType::A]->object()->name();
-        string += QLatin1Char(':');
-        string += m_pRole[RoleType::A]->name();
-    }
-    string += QLatin1Char(':') + Uml::AssociationType::toStringI18n(m_AssocType) + QLatin1Char(':');
-    if(m_pRole[RoleType::B])
-    {
-        string += m_pRole[RoleType::B]->object()->name();
-        string += QLatin1Char(':');
-        string += m_pRole[RoleType::B]->name();
-    }
-    return string;
-}
-
-/**
- * Resolve types. Required when dealing with foreign XMI files.
- * Needs to be called after all UML objects are loaded from file.
- * Overrides the method from UMLObject.
- * Calls resolveRef() for each role.
- * @return  True for success.
- */
-bool UMLAssociation::resolveRef()
-{
-    bool successA = getUMLRole(RoleType::A)->resolveRef();
-    bool successB = getUMLRole(RoleType::B)->resolveRef();
-    if (successA && successB) {
-        UMLObject *objA = getUMLRole(RoleType::A)->object();
-        UMLObject *objB = getUMLRole(RoleType::B)->object();
-        // Check if need to change the assoc type to Realization
-        if (isRealization(objA, objB)) {
-            m_AssocType = Uml::AssociationType::Realization;
-        }
-        m_pUMLPackage->addAssocToConcepts(this);
-        return true;
-    }
-    return false;
-}
-
-/**
- * Creates the <UML:Generalization> or <UML:Association> XMI element
- * including its role objects.
- */
-void UMLAssociation::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    if (m_AssocType == Uml::AssociationType::Generalization) {
-        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Generalization"), qDoc);
-        assocElement.setAttribute(QLatin1String("discriminator"), QString());
-        assocElement.setAttribute(QLatin1String("child"), Uml::ID::toString(getObjectId(RoleType::A)));
-        assocElement.setAttribute(QLatin1String("parent"), Uml::ID::toString(getObjectId(RoleType::B)));
-        qElement.appendChild(assocElement);
-        return;
-    }
-    if (m_AssocType == Uml::AssociationType::Realization) {
-        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Abstraction"), qDoc);
-        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
-        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
-        qElement.appendChild(assocElement);
-        return;
-    }
-    if (m_AssocType == Uml::AssociationType::Dependency) {
-        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Dependency"), qDoc);
-        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
-        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
-        qElement.appendChild(assocElement);
-        return;
-    }
-    if (m_AssocType == Uml::AssociationType::Child2Category) {
-        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Child2Category"), qDoc);
-        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
-        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
-        qElement.appendChild(assocElement);
-        return;
-    }
-    if (m_AssocType == Uml::AssociationType::Category2Parent) {
-        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Category2Parent"), qDoc);
-        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
-        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
-        qElement.appendChild(assocElement);
-        return;
-    }
-
-    QDomElement associationElement = UMLObject::save(QLatin1String("UML:Association"), qDoc);
-    QDomElement connElement = qDoc.createElement(QLatin1String("UML:Association.connection"));
-    getUMLRole(RoleType::A)->saveToXMI (qDoc, connElement);
-    getUMLRole(RoleType::B)->saveToXMI (qDoc, connElement);
-    associationElement.appendChild (connElement);
-    qElement.appendChild(associationElement);
-}
-
-bool UMLAssociation::showPropertiesDialog(QWidget *parent)
-{
-    QPointer<ClassPropertiesDialog> dlg = new ClassPropertiesDialog(parent, this, true);
-    bool modified = false;
-    if (dlg->exec()) {
-        modified = true;
-    }
-    dlg->close();
-    delete dlg;
-    return modified;
-}
-
-/**
- * Creates the <UML:Generalization> or <UML:Association> XMI element
- * including its role objects.
- */
-bool UMLAssociation::load(QDomElement & element)
-{
-    if (id() == Uml::ID::None)
-        return false; // old style XMI file. No real info in this association.
-
-    UMLDoc * doc = UMLApp::app()->document();
-    UMLObject * obj[2] = { NULL, NULL };
-    if (m_AssocType == Uml::AssociationType::Generalization ||
-        m_AssocType == Uml::AssociationType::Realization    ||
-        m_AssocType == Uml::AssociationType::Dependency     ||
-        m_AssocType == Uml::AssociationType::Child2Category ||
-        m_AssocType == Uml::AssociationType::Category2Parent) {
-        QString general = element.attribute(QLatin1String("general"));
-        if (!general.isEmpty()) {
-            UMLClassifier *owningClassifier = dynamic_cast<UMLClassifier*>(m_pUMLPackage);
-            if (owningClassifier == NULL){
-                uWarning() << "Cannot load UML2 generalization: m_pUMLPackage is expected "
-                           << "to be the owning classifier (=client)";
-                return false;
-            }
-            m_pRole[RoleType::A]->setObject(owningClassifier);
-            m_pRole[RoleType::B]->setSecondaryId(general);     // defer resolution to resolveRef()
-            owningClassifier->addAssociationEnd(this);
-            m_pUMLPackage = m_pUMLPackage->umlPackage();       // reparent
-            m_pUMLPackage->addObject(this);
-            return true;
-        }
-        for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
-            const QString fetch = (m_AssocType == Uml::AssociationType::Generalization ?
-                                   r == RoleType::A ? QLatin1String("child") : QLatin1String("parent")
-                       : r == RoleType::A ? QLatin1String("client") : QLatin1String("supplier"));
-            QString roleIdStr = element.attribute(fetch);
-            if (roleIdStr.isEmpty()) {
-                // Might be given as a child node instead - see below.
-                continue;
-            }
-
-            // set umlobject of role if possible (else defer resolution)
-            obj[r] = doc->findObjectById(Uml::ID::fromString(roleIdStr));
-            Uml::RoleType::Enum role = Uml::RoleType::fromInt(r);
-            if (obj[r] == NULL) {
-                m_pRole[role]->setSecondaryId(roleIdStr);  // defer to resolveRef()
-            } else {
-                m_pRole[role]->setObject(obj[r]);
-                if (m_pUMLPackage == NULL) {
-                    Uml::ModelType::Enum mt = Model_Utils::convert_OT_MT(obj[r]->baseType());
-                    m_pUMLPackage = doc->rootFolder(mt);
-                    DEBUG(DBG_SRC) << "assoctype " << m_AssocType
-                        << ": setting model type " << Uml::ModelType::toString(mt);
-                }
-            }
-        }
-        if (obj[RoleType::A] == NULL || obj[RoleType::B] == NULL) {
-            for (QDomNode node = element.firstChild(); !node.isNull();
-                    node = node.nextSibling()) {
-                if (node.isComment())
-                    continue;
-                QDomElement tempElement = node.toElement();
-                QString tag = tempElement.tagName();
-                if (Model_Utils::isCommonXMIAttribute(tag))
-                    continue;
-                // Permitted tag names:
-                //  roleA: "child" "subtype" "client"
-                //  roleB: "parent" "supertype" "supplier"
-                QString idStr = tempElement.attribute(QLatin1String("xmi.id"));
-                if (idStr.isEmpty())
-                    idStr = tempElement.attribute(QLatin1String("xmi.idref"));
-                if (idStr.isEmpty()) {
-                    QDomNode inner = node.firstChild();
-                    QDomElement tmpElem = inner.toElement();
-                    idStr = tmpElem.attribute(QLatin1String("xmi.id"));
-                    if (idStr.isEmpty())
-                        idStr = tmpElem.attribute(QLatin1String("xmi.idref"));
-                }
-                if (idStr.isEmpty()) {
-                    uError() << "type " << m_AssocType
-                        << ", id " << Uml::ID::toString(id()) << ": "
-                        << "xmi id not given for " << tag;
-                    continue;
-                }
-                // Since we know for sure that we're dealing with a non
-                // umbrello file, use deferred resolution unconditionally.
-                if (UMLDoc::tagEq(tag, QLatin1String("child")) ||
-                        UMLDoc::tagEq(tag, QLatin1String("subtype")) ||
-                        UMLDoc::tagEq(tag, QLatin1String("client"))) {
-                    getUMLRole(RoleType::A)->setSecondaryId(idStr);
-                } else {
-                    getUMLRole(RoleType::B)->setSecondaryId(idStr);
-                }
-            }
-        }
-
-        // it is a realization if either endpoint is an interface
-        if (isRealization(obj[RoleType::A], obj[RoleType::B])) {
-            m_AssocType = Uml::AssociationType::Realization;
-        }
-        return true;
-    }
-
-    for (QDomNode node = element.firstChild(); !node.isNull();
-            node = node.nextSibling()) {
-        // uml13.dtd compliant format (new style)
-        if (node.isComment())
-            continue;
-        QDomElement tempElement = node.toElement();
-        QString tag = tempElement.tagName();
-        if (Model_Utils::isCommonXMIAttribute(tag))
-            continue;
-        if (!UMLDoc::tagEq(tag, QLatin1String("Association.connection")) &&
-                !UMLDoc::tagEq(tag, QLatin1String("Association.end")) &&  // Embarcadero's Describe
-                !UMLDoc::tagEq(tag, QLatin1String("Namespace.ownedElement")) &&
-                !UMLDoc::tagEq(tag, QLatin1String("Namespace.contents"))) {
-            uWarning() << "unknown child node " << tag;
-            continue;
-        }
-        // Load role A.
-        QDomNode nodeA = tempElement.firstChild();
-        while (nodeA.isComment())
-            nodeA = nodeA.nextSibling();
-        tempElement = nodeA.toElement();
-        if (tempElement.isNull()) {
-            uWarning() << "UML:Association : element (A) is Null";
-            return false;
-        }
-        tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("NavigableEnd"))) {  // Embarcadero's Describe
-            m_AssocType = Uml::AssociationType::UniAssociation;
-        } else if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
-                   !UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
-            uWarning() << "unknown child (A) tag " << tag;
-            return false;
-        }
-        if (! getUMLRole(RoleType::A)->loadFromXMI(tempElement))
-            return false;
-        // Load role B.
-        QDomNode nodeB = nodeA.nextSibling();
-        while (nodeB.isComment())
-            nodeB = nodeB.nextSibling();
-        tempElement = nodeB.toElement();
-        if (tempElement.isNull()) {
-            uWarning() << "UML:Association : element (B) is Null";
-            return false;
-        }
-        tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("NavigableEnd"))) {  // Embarcadero's Describe
-            m_AssocType = Uml::AssociationType::UniAssociation;
-        } else if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
-                   !UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
-            uWarning() << "unknown child (B) tag " << tag;
-            return false;
-        }
-        if (! getUMLRole(RoleType::B)->loadFromXMI(tempElement))
-            return false;
-
-        if (m_pUMLPackage == NULL) {
-            Uml::ModelType::Enum mt = Model_Utils::convert_OT_MT(getObject(RoleType::B)->baseType());
-            m_pUMLPackage = doc->rootFolder(mt);
-            DEBUG(DBG_SRC) << "setting model type " << Uml::ModelType::toString(mt);
-        }
-
-        // setting the association type:
-        //
-        // In the old days, we could just record this on the association,
-        // and be done with it. But thats not how the UML13.dtd does things.
-        // As a result, we are checking roleA for information about the
-        // parent association (!) which by this point in the parse, should
-        // be set. However, the information that the roles are allowed to have
-        // is not complete, so we need to finish the analysis here.
-
-        // find self-associations
-        if (m_AssocType == Uml::AssociationType::Association && getObjectId(RoleType::A) == getObjectId(RoleType::B))
-            m_AssocType = Uml::AssociationType::Association_Self;
-
-        // fall-back default type
-        if (m_AssocType == Uml::AssociationType::Unknown) {
-            m_AssocType = Uml::AssociationType::Association;
-        }
-
-        return true;
-    }
-
-    // From here on it's old-style stuff.
-    QString assocTypeStr = element.attribute(QLatin1String("assoctype"), QLatin1String("-1"));
-    Uml::AssociationType::Enum assocType = Uml::AssociationType::Unknown;
-    if (assocTypeStr[0] >= QLatin1Char('a') && assocTypeStr[0] <= QLatin1Char('z')) {
-        // In an earlier version, the natural assoctype names were saved.
-        const char *assocTypeString[] = {
-                    "generalization",   // Uml::AssociationType::Generalization
-                    "aggregation",      // Uml::AssociationType::Aggregation
-                    "dependency",       // Uml::AssociationType::Dependency
-                    "association",      // Uml::AssociationType::Association
-                    "associationself",  // Uml::AssociationType::Association_Self
-                    "collmessage",      // Uml::AssociationType::Coll_Message
-                    "seqmessage",       // Uml::AssociationType::Seq_Message
-                    "collmessageself",  // Uml::AssociationType::Coll_Message_Self
-                    "seqmessageself",   // Uml::AssociationType::Seq_Message_Self
-                    "implementation",   // Uml::AssociationType::Implementation
-                    "composition",      // Uml::AssociationType::Composition
-                    "realization",      // Uml::AssociationType::Realization
-                    "uniassociation",   // Uml::AssociationType::UniAssociation
-                    "anchor",           // Uml::AssociationType::Anchor
-                    "state",            // Uml::AssociationType::State
-                    "activity",         // Uml::AssociationType::Activity
-                    "exception",        // Uml::AssociationType::Exception
-                    "category2parent"   // Uml::AssociationType::Category2Parent
-                    "child2category"    // Uml::AssociationType::Child2Category
-                    "relationship"      // Uml::AssociationType::Relationship
-        };
-        const int arraySize = sizeof(assocTypeString) / sizeof(char*);
-        DEBUG(DBG_SRC) << "AssociationType string array size = " << arraySize;
-
-        int index;
-        for (index = 0; index < arraySize; ++index)
-            if (assocTypeStr == QString::fromLatin1(assocTypeString[index]))
-                break;
-        if (index < arraySize)
-            assocType = Uml::AssociationType::fromInt(index);
-    } else {
-        int assocTypeNum = assocTypeStr.toInt();
-        if (assocTypeNum < (int)Uml::AssociationType::Generalization ||   // first enum
-            assocTypeNum >= (int)Uml::AssociationType::Reserved) {     // last enum
-            uWarning() << "bad assoctype of UML:AssociationType::Enum " << Uml::ID::toString(id());
-            return false;
-        }
-        assocType = Uml::AssociationType::fromInt(assocTypeNum);
-    }
-    setAssociationType(assocType);
-
-    Uml::ID::Type roleAObjID = Uml::ID::fromString(element.attribute(QLatin1String("rolea"), QLatin1String("-1")));
-    Uml::ID::Type roleBObjID = Uml::ID::fromString(element.attribute(QLatin1String("roleb"), QLatin1String("-1")));
-    if (assocType == Uml::AssociationType::Aggregation ||
-        assocType == Uml::AssociationType::Composition) {
-        // Flip roles to compensate for changed diamond logic in AssociationLine.
-        // For further explanations see AssociationWidget::loadFromXMI.
-        Uml::ID::Type tmp = roleAObjID;
-        roleAObjID = roleBObjID;
-        roleBObjID = tmp;
-    }
-
-    UMLObject * objA = doc->findObjectById(roleAObjID);
-    UMLObject * objB = doc->findObjectById(roleBObjID);
-
-    if(objA)
-        getUMLRole(RoleType::A)->setObject(objA);
-    else
-        return false;
-
-    if(objB)
-        getUMLRole(RoleType::B)->setObject(objB);
-    else
-        return false;
-
-    setMultiplicity(element.attribute(QLatin1String("multia")), RoleType::A);
-    setMultiplicity(element.attribute(QLatin1String("multib")), RoleType::B);
-
-    setRoleName(element.attribute(QLatin1String("namea")), RoleType::A);
-    setRoleName(element.attribute(QLatin1String("nameb")), RoleType::B);
-
-    setRoleDoc(element.attribute(QLatin1String("doca")), RoleType::A);
-    setRoleDoc(element.attribute(QLatin1String("docb")), RoleType::B);
-
-    // Visibility defaults to Public if it cant set it here..
-    QString visibilityA = element.attribute(QLatin1String("visibilitya"), QLatin1String("0"));
-    QString visibilityB = element.attribute(QLatin1String("visibilityb"), QLatin1String("0"));
-    int vis = visibilityA.toInt();
-    if (vis >= 200)  // bkwd compat.
-        vis -= 200;
-    setVisibility((Uml::Visibility::Enum)vis, RoleType::A);
-    vis = visibilityB.toInt();
-    if (vis >= 200)  // bkwd compat.
-        vis -= 200;
-    setVisibility((Uml::Visibility::Enum)vis, RoleType::B);
-
-    // Changeability defaults to Changeable if it cant set it here..
-    QString changeabilityA = element.attribute(QLatin1String("changeabilitya"), QLatin1String("0"));
-    QString changeabilityB = element.attribute(QLatin1String("changeabilityb"), QLatin1String("0"));
-    if (changeabilityA.toInt() > 0)
-        setChangeability(Uml::Changeability::fromInt(changeabilityA.toInt()), RoleType::A);
-    if (changeabilityB.toInt() > 0)
-        setChangeability(Uml::Changeability::fromInt(changeabilityB.toInt()), RoleType::B);
-
-    return true;
-}
-
-/**
- * Returns the UMLObject assigned to the given role.
- * @return  Pointer to the UMLObject in the given role.
- */
-UMLObject* UMLAssociation::getObject(Uml::RoleType::Enum role) const
-{
-    if (m_pRole[role] == NULL)
-        return NULL;
-    return m_pRole[role]->object();
-}
-
-/**
- * Returns the ID of the UMLObject assigned to the given role.
- * Shorthand for getObject(role)->ID().
- * @return  ID of the UMLObject in the given role.
- */
-Uml::ID::Type UMLAssociation::getObjectId(Uml::RoleType::Enum role) const
-{
-    UMLRole *roleObj = m_pRole[role];
-    if (roleObj == NULL)
-        return Uml::ID::None;
-    UMLObject *o = roleObj->object();
-    if (o == NULL) {
-        QString auxID = roleObj->secondaryId();
-        if (auxID.isEmpty()) {
-            uError() << "role " << role << ": getObject returns NULL";
-            return Uml::ID::None;
-        } else {
-            DEBUG(DBG_SRC) << "role " << role << ": using secondary ID " << auxID;
-            return Uml::ID::fromString(auxID);
-        }
-    }
-    return o->id();
-}
-
-/**
- * Returns the ID of the UMLObject assigned to the given role.
- * CURRENTLY UNUSED.
- * @return  ID of the UMLObject of the given role.
- */
-Uml::ID::Type UMLAssociation::getRoleId(RoleType::Enum role) const
-{
-    return m_pRole[role]->id();
-}
-
-/**
- * Returns the changeability.
- */
-Uml::Changeability::Enum UMLAssociation::changeability(Uml::RoleType::Enum role) const
-{
-    return m_pRole[role]->changeability();
-}
-
-/**
- * Returns the Visibility of the given role.
- * @return  Visibility of the given role.
- */
-Uml::Visibility::Enum UMLAssociation::visibility(Uml::RoleType::Enum role) const
-{
-    return m_pRole[role]->visibility();
-}
-
-/**
- * Returns the multiplicity assigned to the given role.
- * @return  The multiplicity assigned to the given role.
- */
-QString UMLAssociation::getMultiplicity(Uml::RoleType::Enum role) const
-{
-    return m_pRole[role]->multiplicity();
-}
-
-/**
- * Returns the name assigned to the role A.
- * @return  The name assigned to the given role.
- */
-QString UMLAssociation::getRoleName(Uml::RoleType::Enum role) const
-{
-    return m_pRole[role]->name();
-}
-
-/**
- * Returns the documentation assigned to the given role.
- * @return  Documentation text of given role.
- */
-QString UMLAssociation::getRoleDoc(Uml::RoleType::Enum role) const
-{
-    return m_pRole[role]->doc();
-}
-
-/**
- * Get the underlying UMLRole object for the given role.
- * @return  Pointer to the UMLRole object for the given role.
- */
-UMLRole * UMLAssociation::getUMLRole(Uml::RoleType::Enum role) const
-{
-    return m_pRole[role];
-}
-
-/**
- * Set the attribute m_bOldLoadMode.
- * @param value   the new value to set
- */
-void UMLAssociation::setOldLoadMode(bool value /* = true */)
-{
-    m_bOldLoadMode = value;
-}
-
-/**
- * Return the backward compatibility flag for loading files.
- */
-bool UMLAssociation::getOldLoadMode() const
-{
-    return m_bOldLoadMode;
-}
-
-/**
- * Sets the assocType of the UMLAssociation.
- * @param assocType The AssociationType::Enum of the UMLAssociation.
- */
-void UMLAssociation::setAssociationType(Uml::AssociationType::Enum assocType)
-{
-    m_AssocType = assocType;
-    if (m_AssocType == Uml::AssociationType::UniAssociation)
-    {
-        // In this case we need to auto-set the multiplicity/rolenames
-        // of the roles
-#ifdef VERBOSE_DEBUGGING
-        DEBUG(DBG_SRC) << " A new uni-association has been created.";
-#endif
-    }
-    UMLObject::emitModified();
-}
-
-/**
- * Sets the UMLObject playing the given role in the association.
- * @param obj  Pointer to the UMLObject of the given role.
- * @param role The Uml::RoleType::Enum played by the association
- */
-void UMLAssociation::setObject(UMLObject *obj, Uml::RoleType::Enum role)
-{
-    m_pRole[role]->setObject(obj);
-}
-
-/**
- * Sets the visibility of the given role of the UMLAssociation.
- * @param value  Visibility of role.
- * @param role   The Uml::RoleType::Enum to which the visibility is being applied
- */
-void UMLAssociation::setVisibility(Visibility::Enum value, Uml::RoleType::Enum role)
-{
-    m_pRole[role]->setVisibility(value);
-}
-
-/**
- * Sets the changeability of the given role of the UMLAssociation.
- * @param value     Changeability_Type of the given role.
- * @param role      The Uml::RoleType::Enum to which the changeability is being set
- */
-void UMLAssociation::setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role)
-{
-    m_pRole[role]->setChangeability(value);
-}
-
-/**
- * Sets the multiplicity of the given role of the UMLAssociation.
- * @param multi    The multiplicity of the given role.
- * @param role     The Uml::RoleType::Enum to which the multiplicity is being applied
- */
-void UMLAssociation::setMultiplicity(const QString &multi, Uml::RoleType::Enum role)
-{
-    if (m_pRole[role]->multiplicity() != multi) {
-        UMLApp::app()->executeCommand(new CmdChangeMultiplicity(m_pRole[role], multi));
-    }
-}
-
-/**
- * Sets the name of the given role of the UMLAssociation.
- * @param roleName  The name to set for the given role.
- * @param role      The Uml::RoleType::Enum for which to set the name.
- */
-void UMLAssociation::setRoleName(const QString &roleName, Uml::RoleType::Enum role)
-{
-    m_pRole[role]->setName(roleName);
-}
-
-/**
- * Sets the documentation on the given role in the association.
- * @param doc      The string with the documentation.
- * @param role     The Uml::RoleType::Enum to which the documentation is being applied
- */
-void UMLAssociation::setRoleDoc(const QString &doc, Uml::RoleType::Enum role)
-{
-    m_pRole[role]->setDoc(doc);
-}
-
-/**
- * When the association type is "Generalization" and at least one of the
- * given objects an interface, then it is a "Realization".
- * @param objA   UML object as role A
- * @param objB   UML object as role B
- * @return flag whether association is a realization
- */
-bool UMLAssociation::isRealization(UMLObject* objA, UMLObject* objB) const
-{
-    bool aIsInterface = false;
-    if (objA && (objA->baseType() == UMLObject::ot_Interface)) {
-        aIsInterface = true;
-    }
-    bool bIsInterface = false;
-    if (objB && (objB->baseType() == UMLObject::ot_Interface)) {
-        bIsInterface = true;
-    }
-    return (m_AssocType == Uml::AssociationType::Generalization) &&
-           (aIsInterface || bIsInterface);
-}
-
-/**
- * Common initializations at construction time.
- * @param type      The AssociationType::Enum to represent.
- * @param roleAObj  Pointer to the role A UMLObject.
- * @param roleBObj  Pointer to the role B UMLObject.
- */
-void UMLAssociation::init(Uml::AssociationType::Enum type, UMLObject *roleAObj, UMLObject *roleBObj)
-{
-    m_AssocType = type;
-    m_BaseType = ot_Association;
-    m_Name = QString();
-    m_bOldLoadMode = false;
-    nrof_parent_widgets = -1;
-    if (!UMLApp::app()->document()->loading()) {
-        m_pUMLPackage = UMLApp::app()->document()->currentRoot();
-    }
-    m_pRole[RoleType::A] = new UMLRole (this, roleAObj, RoleType::A);
-    m_pRole[RoleType::B] = new UMLRole (this, roleBObj, RoleType::B);
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/association.h umbrello-15.08.1/umbrello/association.h
--- umbrello-15.08.1.orig/umbrello/association.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/association.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,102 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ASSOCIATION_H
-#define ASSOCIATION_H
-
-#include "basictypes.h"
-#include "umlobject.h"
-
-#include <QDomDocument>
-#include <QDomElement>
-
-class UMLRole;
-
-/**
- * This class contains the non-graphic representation of an association.
- * An association can be a generalization, realization, simple association,
- * directed association, aggregation, or composition.
- *
- * @short Sets up association information.
- * @author Oliver Kellogg <okellogg@users.sourceforge.net>
- * @see UMLObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLAssociation : public UMLObject
-{
-    Q_OBJECT
-    friend class AssociationWidget;
-
-public:
-    UMLAssociation(Uml::AssociationType::Enum type, UMLObject *roleA, UMLObject *roleB);
-    explicit UMLAssociation(Uml::AssociationType::Enum type = Uml::AssociationType::Unknown);
-
-    virtual ~UMLAssociation();
-
-    bool operator==(const UMLAssociation &rhs) const;
-
-    QString toString() const;
-
-    UMLRole * getUMLRole(Uml::RoleType::Enum role) const;
-    Uml::ID::Type getObjectId(Uml::RoleType::Enum role) const;
-    Uml::ID::Type getRoleId(Uml::RoleType::Enum role) const;
-
-    void setAssociationType(Uml::AssociationType::Enum assocType);
-    Uml::AssociationType::Enum getAssocType() const;
-
-    void setObject(UMLObject *obj, Uml::RoleType::Enum role);
-    UMLObject* getObject(Uml::RoleType::Enum role) const;
-
-    void setVisibility(Uml::Visibility::Enum value, Uml::RoleType::Enum role);
-    Uml::Visibility::Enum visibility(Uml::RoleType::Enum role) const;
-
-    void setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role);
-    Uml::Changeability::Enum changeability(Uml::RoleType::Enum role) const;
-
-    void setMultiplicity(const QString &multi, Uml::RoleType::Enum role);
-    QString getMultiplicity(Uml::RoleType::Enum role) const;
-
-    void setRoleName(const QString &roleName, Uml::RoleType::Enum role);
-    QString getRoleName(Uml::RoleType::Enum role) const;
-
-    void setRoleDoc(const QString &doc, Uml::RoleType::Enum role);
-    QString getRoleDoc(Uml::RoleType::Enum role) const;
-
-    void setOldLoadMode(bool value = true);
-    bool getOldLoadMode() const;
-
-    virtual UMLObject* clone() const { return NULL; }
-
-    virtual bool resolveRef();
-
-    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    virtual bool showPropertiesDialog(QWidget *parent = 0);
-
-protected:
-
-    bool load(QDomElement& element);
-
-    // keep track of number of parent widgets
-    int nrof_parent_widgets;
-
-    void init(Uml::AssociationType::Enum type, UMLObject *roleAObj, UMLObject *roleBObj);
-
-    UMLRole *                    m_pRole[2];
-    Uml::AssociationType::Enum   m_AssocType;
-    QString                      m_Name;
-    bool                         m_bOldLoadMode;
-
-private:
-
-    bool isRealization(UMLObject* objA, UMLObject* objB) const;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/attribute.cpp umbrello-15.08.1/umbrello/attribute.cpp
--- umbrello-15.08.1.orig/umbrello/attribute.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/attribute.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,424 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "attribute.h"
-
-// app includes
-#include "debug_utils.h"
-#include "classifier.h"
-#include "operation.h"
-#include "umlobject.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "folder.h"
-#include "umlattributedialog.h"
-#include "object_factory.h"
-
-/**
- * Sets up an attribute.
- *
- * @param parent    The parent of this UMLAttribute.
- * @param name      The name of this UMLAttribute.
- * @param id        The unique id given to this UMLAttribute.
- * @param s         The visibility of the UMLAttribute.
- * @param type      The type of this UMLAttribute.
- * @param iv        The initial value of the attribute.
- */
-UMLAttribute::UMLAttribute(UMLObject *parent,
-                           const QString& name, Uml::ID::Type id,
-                           Uml::Visibility::Enum s,
-                           UMLObject *type, const QString& iv)
-  : UMLClassifierListItem(parent, name, id)
-{
-    m_InitialValue = iv;
-    m_BaseType = UMLObject::ot_Attribute;
-    m_visibility = s;
-    m_ParmKind = Uml::ParameterDirection::In;
-    /* CHECK: Do we need this:
-    if (type == NULL) {
-        type = Object_Factory::createUMLObject(Uml::ot_Datatype, "undef");
-    }
-     */
-    m_pSecondary = type;
-}
-
-/**
- * Sets up an attribute.
- *
- * @param parent    The parent of this UMLAttribute.
- */
-UMLAttribute::UMLAttribute(UMLObject *parent) : UMLClassifierListItem(parent)
-{
-    m_BaseType = UMLObject::ot_Attribute;
-    m_visibility = Uml::Visibility::Private;
-    m_ParmKind = Uml::ParameterDirection::In;
-}
-
-/**
- * Destructor.
- */
-UMLAttribute::~UMLAttribute()
-{
-}
-
-/**
- * Reimplementation of method from UMLObject is required as
- * an extra signal, attributeChanged(), is emitted.
- */
-void UMLAttribute::setName(const QString &name)
-{
-    m_name = name;
-    emit attributeChanged();
-    UMLObject::emitModified();
-}
-
-/**
- * Reimplementation of method from UMLObject is required as
- * an extra signal, attributeChanged(), is emitted.
- */
-void UMLAttribute::setVisibility(Uml::Visibility::Enum s)
-{
-    m_visibility = s;
-    emit attributeChanged();
-    UMLObject::emitModified();
-}
-
-/**
- * Returns The initial value of the UMLAttribute.
- *
- * @return  The initial value of the Atrtibute.
- */
-QString UMLAttribute::getInitialValue() const
-{
-    return m_InitialValue;
-}
-
-/**
- * Sets the initial value of the UMLAttribute.
- *
- * @param iv   The initial value of the UMLAttribute.
- */
-void UMLAttribute::setInitialValue(const QString &iv)
-{
-    if(m_InitialValue != iv) {
-        m_InitialValue = iv;
-        UMLObject::emitModified();
-    }
-}
-
-void UMLAttribute::setParmKind (Uml::ParameterDirection::Enum pk)
-{
-    m_ParmKind = pk;
-}
-
-Uml::ParameterDirection::Enum UMLAttribute::getParmKind() const
-{
-    return m_ParmKind;
-}
-
-/**
- * Returns a string representation of the UMLAttribute.
- *
- * @param sig   If true will show the attribute type and initial value.
- * @return  Returns a string representation of the UMLAttribute.
- */
-QString UMLAttribute::toString(Uml::SignatureType::Enum sig)
-{
-    QString s;
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::NoSig) {
-        s = Uml::Visibility::toString(m_visibility, true) + QLatin1Char(' ');
-    }
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
-        // Determine whether the type name needs to be scoped.
-        UMLObject *owningObject = static_cast<UMLObject*>(parent());
-        if (owningObject->baseType() == UMLObject::ot_Operation) {
-            // The immediate parent() is the UMLOperation but we want
-            // the UMLClassifier:
-            owningObject = static_cast<UMLObject*>(owningObject->parent());
-        }
-        UMLClassifier *ownParent = dynamic_cast<UMLClassifier*>(owningObject);
-        if (ownParent == NULL) {
-            uError() << "parent " << owningObject->name()
-                << " is not a UMLClassifier";
-            return QString();
-        }
-        QString typeName;
-        UMLClassifier *type = UMLClassifierListItem::getType();
-        if (type) {
-            UMLPackage *typeScope = type->umlPackage();
-            if (typeScope != ownParent && typeScope != ownParent->umlPackage())
-                typeName = type->fullyQualifiedName();
-            else
-                typeName = type->name();
-        }
-        // The default direction, "in", is not mentioned.
-        // Perhaps we should include a pd_Unspecified in
-        // Uml::ParameterDirection::Enum to have better control over this.
-        if (m_ParmKind == Uml::ParameterDirection::InOut)
-            s += QLatin1String("inout ");
-        else if (m_ParmKind == Uml::ParameterDirection::Out)
-            s += QLatin1String("out ");
-        // Construct the attribute text.
-        QString string = s + name() + QLatin1String(" : ") + typeName;
-        if (m_InitialValue.length() > 0)
-            string += QLatin1String(" = ") + m_InitialValue;
-        return string;
-    }
-    return s + name();
-}
-
-/**
- * Reimplement method from UMLObject.
- */
-QString UMLAttribute::getFullyQualifiedName(const QString& separator,
-                                            bool includeRoot /* = false */) const
-{
-    UMLOperation *op = NULL;
-    UMLObject *owningObject = static_cast<UMLObject*>(parent());
-    if (owningObject->baseType() == UMLObject::ot_Operation) {
-        op = static_cast<UMLOperation*>(owningObject);
-        owningObject = static_cast<UMLObject*>(owningObject->parent());
-    }
-    UMLClassifier *ownParent = dynamic_cast<UMLClassifier*>(owningObject);
-    if (ownParent == NULL) {
-        uError() << name() << ": parent " << owningObject->name()
-            << " is not a UMLClassifier";
-        return QString();
-    }
-    QString tempSeparator = separator;
-    if (tempSeparator.isEmpty())
-        tempSeparator = UMLApp::app()->activeLanguageScopeSeparator();
-    QString fqn = ownParent->fullyQualifiedName(tempSeparator, includeRoot);
-    if (op)
-        fqn.append(tempSeparator + op->name());
-    fqn.append(tempSeparator + name());
-    return fqn;
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLAttribute::operator==(const UMLAttribute &rhs) const
-{
-    if(this == &rhs)
-        return true;
-
-    if(!UMLObject::operator==(rhs))
-        return false;
-
-    // The type name is the only distinguishing criterion.
-    // (Some programming languages might support more, but others don't.)
-    if (m_pSecondary != rhs.m_pSecondary)
-        return false;
-
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the UMLAttribute
- * object.
- */
-void UMLAttribute::copyInto(UMLObject *lhs) const
-{
-    UMLAttribute *target = static_cast<UMLAttribute*>(lhs);
-    // call the parent first.
-    UMLClassifierListItem::copyInto(target);
-
-    // Copy all datamembers
-    target->m_pSecondary = m_pSecondary;
-    target->m_SecondaryId = m_SecondaryId;
-    target->m_InitialValue = m_InitialValue;
-    target->m_ParmKind = m_ParmKind;
-}
-
-/**
- * Make a clone of the UMLAttribute.
- */
-UMLObject* UMLAttribute::clone() const
-{
-    //FIXME: The new attribute should be slaved to the NEW parent not the old.
-    UMLAttribute *clone = new UMLAttribute(static_cast<UMLObject*>(parent()));
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Creates the <UML:Attribute> XMI element.
- */
-void UMLAttribute::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement attributeElement = UMLObject::save(QLatin1String("UML:Attribute"), qDoc);
-    if (m_pSecondary == NULL) {
-        uDebug() << name() << ": m_pSecondary is NULL, m_SecondaryId is '"
-            << m_SecondaryId << "'";
-    } else {
-        attributeElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
-    }
-    if (! m_InitialValue.isEmpty())
-        attributeElement.setAttribute(QLatin1String("initialValue"), m_InitialValue);
-    qElement.appendChild(attributeElement);
-}
-
-/**
- * Loads the <UML:Attribute> XMI element.
- */
-bool UMLAttribute::load(QDomElement & element)
-{
-    m_SecondaryId = element.attribute(QLatin1String("type"));
-    // We use the m_SecondaryId as a temporary store for the xmi.id
-    // of the attribute type model object.
-    // It is resolved later on, when all classes have been loaded.
-    // This deferred resolution is required because the xmi.id may
-    // be a forward reference, i.e. it may identify a model object
-    // that has not yet been loaded.
-    if (m_SecondaryId.isEmpty()) {
-        // Perhaps the type is stored in a child node:
-        QDomNode node = element.firstChild();
-        while (!node.isNull()) {
-            if (node.isComment()) {
-                node = node.nextSibling();
-                continue;
-            }
-            QDomElement tempElement = node.toElement();
-            QString tag = tempElement.tagName();
-            if (!UMLDoc::tagEq(tag, QLatin1String("type"))) {
-                node = node.nextSibling();
-                continue;
-            }
-            m_SecondaryId = Model_Utils::getXmiId(tempElement);
-            if (m_SecondaryId.isEmpty())
-                m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
-            if (m_SecondaryId.isEmpty()) {
-                QString href = tempElement.attribute(QLatin1String("href"));
-                if (href.isEmpty()) {
-                    QDomNode inner = node.firstChild();
-                    QDomElement tmpElem = inner.toElement();
-                    m_SecondaryId = Model_Utils::getXmiId(tmpElem);
-                    if (m_SecondaryId.isEmpty())
-                        m_SecondaryId = tmpElem.attribute(QLatin1String("xmi.idref"));
-                } else {
-                    int hashpos = href.lastIndexOf(QChar(QLatin1Char('#')));
-                    if (hashpos < 0) {
-                        uDebug() << name() << ": cannot find type " << href;
-                    } else {
-                        QString typeName = href.mid(hashpos + 1);
-                        UMLFolder *dtFolder = UMLApp::app()->document()->datatypeFolder();
-                        m_pSecondary = Model_Utils::findUMLObject(dtFolder->containedObjects(),
-                                                                  typeName, UMLObject::ot_Datatype);
-                        if (!m_pSecondary) {
-                            m_pSecondary = Object_Factory::createUMLObject(UMLObject::ot_Datatype,
-                                                                           typeName, dtFolder);
-                        }
-                    }
-                }
-            }
-            break;
-        }
-        if (m_SecondaryId.isEmpty()) {
-            uDebug() << name() << ": cannot find type.";
-        }
-    }
-    m_InitialValue = element.attribute(QLatin1String("initialValue"));
-    if (m_InitialValue.isEmpty()) {
-        // for backward compatibility
-        m_InitialValue = element.attribute(QLatin1String("value"));
-    }
-    return true;
-}
-
-/**
- * Display the properties configuration dialog for the attribute.
- */
-bool UMLAttribute::showPropertiesDialog(QWidget* parent)
-{
-    UMLAttributeDialog dialog(parent, this);
-    return dialog.exec();
-}
-
-/**
- * Puts in the param templateParamList all the template params that are in templateParam
- */
-void UMLAttribute::setTemplateParams(const QString& templateParam, UMLClassifierList &templateParamList)
-{
-    if (templateParam.isEmpty())
-        return;
-    QString type = templateParam.simplified();
-
-    int start = type.indexOf(QLatin1Char('<'));
-    if (start >= 0) {
-        int end = start;
-        int count = 1;
-        int len = type.length();
-        while (count != 0 && ++end < len) {
-            QChar c = type.at(end);
-            if (c == QLatin1Char('<')) {
-                count++;
-            }
-            if (c == QLatin1Char('>')) {
-                count--;
-            }
-        }
-        if (count != 0) {
-            //The template is ill-formated, let's quit
-            return;
-        }
-        setTemplateParams(type.mid(start + 1, end - start - 1), templateParamList);
-        setTemplateParams(type.left(start) + type.right(len - end - 1), templateParamList);
-    } else {
-        QStringList paramsList = type.split(QLatin1Char(','));
-        for (QStringList::Iterator it = paramsList.begin(); it != paramsList.end(); ++it) {
-            QString param = *it;
-            if (!param.isEmpty()) {
-                UMLDoc *pDoc = UMLApp::app()->document();
-                UMLObject* obj = pDoc->findUMLObject(param);
-                if (obj == NULL) {
-                    obj = pDoc->findUMLObject(param.remove(QLatin1Char(' ')));
-                }
-                if (obj != NULL) {
-                    //We want to list only the params that already exist in this document
-                    //If the param doesnt't already exist, we couldn't draw an association anyway
-                    UMLClassifier* tmpClassifier = static_cast<UMLClassifier*>(obj);
-                    if (templateParamList.indexOf(tmpClassifier) == -1) {
-                        templateParamList.append(tmpClassifier);
-                    }
-                }
-            }
-        }
-    }
-}
-
-/**
- * Returns all the template params (if any) that are in the type of this attribute
- */
-UMLClassifierList UMLAttribute::getTemplateParams()
-{
-    UMLClassifierList templateParamList;
-    QString type = getType()->name();
-    QString templateParam;
-    // Handle C++/D/Java template/generic parameters
-    const Uml::ProgrammingLanguage::Enum pl = UMLApp::app()->activeLanguage();
-    if (pl == Uml::ProgrammingLanguage::Cpp  ||
-        pl == Uml::ProgrammingLanguage::Java || pl == Uml::ProgrammingLanguage::D) {
-        int start = type.indexOf(QLatin1Char('<'));
-        if (start >= 0) {
-            int end = type.lastIndexOf(QLatin1Char('>'));
-            if (end > start) {
-                templateParam = type.mid(start + 1, end - start - 1);
-                setTemplateParams(templateParam, templateParamList);
-            }
-        }
-    }
-    return templateParamList;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/attribute.h umbrello-15.08.1/umbrello/attribute.h
--- umbrello-15.08.1.orig/umbrello/attribute.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/attribute.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,84 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ATTRIBUTE_H
-#define ATTRIBUTE_H
-
-#include "basictypes.h"
-#include "classifierlistitem.h"
-#include "umlclassifierlist.h"
-
-/**
- * This class is used to set up information for an attribute.  This is like
- * a programming attribute.  It has a type, name, visibility and initial value.
- *
- * @short Sets up attribute information.
- * @author Paul Hensgen <phensgen@techie.com>
- * @see UMLObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLAttribute : public UMLClassifierListItem
-{
-    Q_OBJECT
-public:
-
-    UMLAttribute(UMLObject *parent, const QString& name,
-                 Uml::ID::Type id = Uml::ID::None,
-                 Uml::Visibility::Enum s = Uml::Visibility::Private,
-                 UMLObject *type = 0, const QString& iv = QString());
-    explicit UMLAttribute(UMLObject *parent);
-
-    bool operator==(const UMLAttribute &rhs) const;
-
-    virtual ~UMLAttribute();
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    void setName(const QString &name);
-
-    void setVisibility(Uml::Visibility::Enum s);
-
-    virtual UMLObject* clone() const;
-
-    QString getInitialValue() const;
-    void setInitialValue(const QString &iv);
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    QString getFullyQualifiedName(const QString& separator = QString(),
-                                  bool includeRoot = false) const;
-
-    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-    void setParmKind(Uml::ParameterDirection::Enum pk);
-    Uml::ParameterDirection::Enum getParmKind() const;
-
-    virtual UMLClassifierList getTemplateParams();
-
-signals:
-
-    void attributeChanged();
-
-protected:
-
-    bool load(QDomElement & element);
-
-    QString m_InitialValue; ///< text for the attribute's initial value.
-    Uml::ParameterDirection::Enum m_ParmKind;
-
-private:
-
-    void setTemplateParams(const QString& templateParam, UMLClassifierList &templateParamList);
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/category.cpp umbrello-15.08.1/umbrello/category.cpp
--- umbrello-15.08.1.orig/umbrello/category.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/category.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,101 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "category.h"
-
-/**
- * Constructs a Category.
- *
- * @param name   The name of the Category.
- * @param id     The unique id to assign to this Category.
- */
-UMLCategory::UMLCategory(const QString & name, Uml::ID::Type id)
-  : UMLCanvasObject(name, id)
-{
-    init();
-}
-
-/**
- * Standard destructor.
- */
-UMLCategory::~UMLCategory()
-{
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLCategory::init()
-{
-    m_BaseType = UMLObject::ot_Category;
-    m_CategoryType = ct_Disjoint_Specialisation;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLCategory::copyInto(UMLObject *lhs) const
-{
-    UMLCategory *target = static_cast<UMLCategory*>(lhs);
-
-    // call the parent first
-    UMLCanvasObject::copyInto(target);
-
-    target->m_CategoryType = m_CategoryType;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLCategory::clone() const
-{
-    UMLCategory *clone = new UMLCategory();
-    copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the <UML:Category> XMI element.
- */
-void UMLCategory::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-     QDomElement categoryElement = UMLObject::save(QLatin1String("UML:Category"), qDoc);
-     categoryElement.setAttribute(QLatin1String("categoryType"), (int)m_CategoryType);
-     qElement.appendChild(categoryElement);
-}
-
-/**
- * Loads the <UML:Category> XMI element (empty.)
- */
-bool UMLCategory::load(QDomElement& element)
-{
-    m_CategoryType = (Category_Type)element.attribute(QLatin1String("categoryType"),
-                                                      QLatin1String("0")).toInt();
-    return true;
-}
-
-/**
- * Get the category type
- */
-UMLCategory::Category_Type UMLCategory::getType()
-{
-    return m_CategoryType;
-}
-
-/**
- * Set the category type
- */
-void UMLCategory::setType(Category_Type type)
-{
-    m_CategoryType = type;
-    emitModified();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/category.h umbrello-15.08.1/umbrello/category.h
--- umbrello-15.08.1.orig/umbrello/category.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/category.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,62 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef CATEGORY_H
-#define CATEGORY_H
-
-#include "umlcanvasobject.h"
-
-/**
- * This class contains the non-graphical information required for a UML Category.
- * This class inherits from @ref UMLCanvasObject which contains most of the
- * information.
- * The @ref UMLDoc class creates instances of this type.
- *
- * @short Information for a non-graphical UML Category.
- * @author Sharan Rao
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLCategory : public UMLCanvasObject {
-    Q_OBJECT
-public:
-
-    enum Category_Type {
-        ct_Disjoint_Specialisation,
-        ct_Overlapping_Specialisation,
-        ct_Union
-    };
-
-    explicit UMLCategory(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    ~UMLCategory();
-
-    virtual void init();
-
-    void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    UMLCategory::Category_Type getType();
-
-    void setType(Category_Type type);
-
-protected:
-
-    bool load(QDomElement & element);
-
-private:
-
-    Category_Type m_CategoryType;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/checkconstraint.cpp umbrello-15.08.1/umbrello/checkconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/checkconstraint.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/checkconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,160 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-//own header
-#include "checkconstraint.h"
-
-// app includes
-#include "debug_utils.h"
-#include "umlcheckconstraintdialog.h"
-
-/**
- * Sets up a constraint.
- *
- * @param parent    The parent of this UMLCheckConstraint.
- * @param name      The name of this UMLCheckConstraint.
- * @param id        The unique id given to this UMLCheckConstraint.
- */
-UMLCheckConstraint::UMLCheckConstraint(UMLObject *parent,
-                          const QString& name, Uml::ID::Type id)
-    : UMLEntityConstraint(parent, name, id)
-{
-    init();
-}
-
-/**
- * Sets up a constraint.
- *
- * @param parent    The parent of this UMLCheckConstraint.
- */
-UMLCheckConstraint::UMLCheckConstraint(UMLObject *parent)
-    : UMLEntityConstraint(parent)
-{
-    init();
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLCheckConstraint::operator==(const UMLCheckConstraint &rhs) const
-{
-    if (this == &rhs)
-        return true;
-
-    if (!UMLObject::operator==(rhs))
-        return false;
-
-    return true;
-}
-
-/**
- * Destructor.
- */
-UMLCheckConstraint::~UMLCheckConstraint()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the UMLCheckConstraint
- * object.
- */
-void UMLCheckConstraint::copyInto(UMLObject *lhs) const
-{
-    UMLCheckConstraint *target = static_cast<UMLCheckConstraint*>(lhs);
-
-    // call the parent first.
-    UMLEntityConstraint::copyInto(target);
-
-    // Copy all datamembers
-    target->m_CheckCondition = m_CheckCondition;
-}
-
-/**
- * Make a clone of the UMLCheckConstraint.
- */
-UMLObject* UMLCheckConstraint::clone() const
-{
-    //FIXME: The new attribute should be slaved to the NEW parent not the old.
-    UMLCheckConstraint *clone = new UMLCheckConstraint(static_cast<UMLObject*>(parent()));
-    copyInto(clone);
-    return clone;
-}
-
-/**
- * Returns a string representation of the UMLCheckConstraint.
- *
- * @param sig   If true will show the attribute type and initial value.
- * @return  Returns a string representation of the UMLAttribute.
- */
-QString UMLCheckConstraint::toString(Uml::SignatureType::Enum sig)
-{
-    QString s;
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
-        s = name() ;
-    }
-
-    return s;
-}
-
-QString UMLCheckConstraint::getFullyQualifiedName(const QString& separator,
-                                                  bool includeRoot) const
-{
-    Q_UNUSED(separator); Q_UNUSED(includeRoot);
-    return this->name();
-}
-
-/**
- * Creates the <UML:UniqueConstraint> XMI element.
- */
-void UMLCheckConstraint::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement checkConstraintElement = UMLObject::save(QLatin1String("UML:CheckConstraint"), qDoc);
-
-    QDomNode checkCondition = qDoc.createTextNode(m_CheckCondition);
-    checkConstraintElement.appendChild(checkCondition);
-
-    qElement.appendChild(checkConstraintElement);
-}
-
-/**
- * Display the properties configuration dialog for the attribute.
- */
-bool UMLCheckConstraint::showPropertiesDialog(QWidget* parent)
-{
-    UMLCheckConstraintDialog dialog(parent, this);
-    return dialog.exec();
-}
-
-/**
- * Loads the <UML:CheckConstraint> XMI element.
- */
-bool UMLCheckConstraint::load(QDomElement & element)
-{
-    QDomNode node = element.firstChild();
-
-    QDomText checkConstraintText = node.toText();
-    if (checkConstraintText.isNull())
-        m_CheckCondition = QString();
-    else
-        m_CheckCondition = checkConstraintText.data();
-
-    return true;
-}
-
-/**
- * Initialises Check Constraint
- */
-void UMLCheckConstraint::init()
-{
-    m_BaseType = UMLObject::ot_CheckConstraint;
-    m_CheckCondition.clear();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/checkconstraint.h umbrello-15.08.1/umbrello/checkconstraint.h
--- umbrello-15.08.1.orig/umbrello/checkconstraint.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/checkconstraint.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,71 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef CHECKCONSTRAINT_H
-#define CHECKCONSTRAINT_H
-
-#include "basictypes.h"
-#include "entityconstraint.h"
-
-/**
- * This class is used to set up information for a unique entity constraint.
- *
- * @short Sets up Check Constraint information for UMLEntities.
- * @author Sharan Rao
- * @see UMLObject UMLClassifierListItem UMLEntityConstraint
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLCheckConstraint : public UMLEntityConstraint
-{
-     Q_OBJECT
-public:
-
-    UMLCheckConstraint(UMLObject *parent, const QString& name,
-                       Uml::ID::Type id = Uml::ID::None);
-    explicit UMLCheckConstraint(UMLObject *parent);
-
-    bool operator==(const UMLCheckConstraint &rhs) const;
-
-    virtual ~UMLCheckConstraint();
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    QString getFullyQualifiedName(const QString& separator = QString(),
-                                  bool includeRoot = false) const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-    QString getCheckCondition() const {
-        return m_CheckCondition;
-    }
-
-    void setCheckCondition(const QString& condition) {
-        m_CheckCondition = condition.trimmed();
-    }
-
-protected:
-
-    bool load(QDomElement & element);
-
-private:
-
-    void init();
-
-    QString m_CheckCondition;   ///< the check condition
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/classifier.cpp umbrello-15.08.1/umbrello/classifier.cpp
--- umbrello-15.08.1.orig/umbrello/classifier.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/classifier.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,1631 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-#include "classifier.h"
-
-// app includes
-#include "association.h"
-#include "debug_utils.h"
-#include "umlassociationlist.h"
-#include "operation.h"
-#include "attribute.h"
-#include "template.h"
-#include "enumliteral.h"
-#include "entityattribute.h"
-#include "enum.h"
-#include "entity.h"
-#include "stereotype.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "uniqueid.h"
-#include "object_factory.h"
-#include "model_utils.h"
-#include "idchangelog.h"
-#include "umloperationdialog.h"
-#include "umlattributedialog.h"
-#include "umltemplatedialog.h"
-#include "optionstate.h"
-#include "icon_utils.h"
-
-// kde includes
-#include <KLocalizedString>
-#include <KMessageBox>
-
-// qt includes
-#include <QPointer>
-
-using namespace Uml;
-
-/**
- * @brief holds set of classifiers for recursive loop detection
- */
-class UMLClassifierSet: public QSet<UMLClassifier *> {
-public:
-    UMLClassifierSet() : level(0)
-    {
-    }
-    int level;
-};
-
-/**
- * Sets up a Classifier.
- *
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLClassifier::UMLClassifier(const QString & name, Uml::ID::Type id)
-  : UMLPackage(name, id)
-{
-    m_BaseType = UMLObject::ot_Class;  // default value
-    m_pClassAssoc = NULL;
-    m_isRef = false;
-}
-
-/**
- * Standard deconstructor.
- */
-UMLClassifier::~UMLClassifier()
-{
-}
-
-/**
- * Reimplementation of method from class UMLObject for controlling the
- * exact type of this classifier: class, interface, or datatype.
- * @param ot   the base type to set
- */
-void UMLClassifier::setBaseType(UMLObject::ObjectType ot)
-{
-    m_BaseType = ot;
-    Icon_Utils::IconType newIcon;
-    switch (ot) {
-        case ot_Interface:
-            UMLObject::setStereotypeCmd(QLatin1String("interface"));
-            UMLObject::m_bAbstract = true;
-            newIcon = Icon_Utils::it_Interface;
-            break;
-        case ot_Class:
-            UMLObject::setStereotypeCmd(QString());
-            UMLObject::m_bAbstract = false;
-            newIcon = Icon_Utils::it_Class;
-            break;
-        case ot_Datatype:
-            UMLObject::setStereotypeCmd(QLatin1String("datatype"));
-            UMLObject::m_bAbstract = false;
-            newIcon = Icon_Utils::it_Datatype;
-            break;
-        case ot_Package:
-            UMLObject::setStereotypeCmd(QLatin1String("package"));
-            UMLObject::m_bAbstract = false;
-            newIcon = Icon_Utils::it_Package;
-            break;
-        default:
-            uError() << "cannot set to type " << ot;
-            return;
-    }
-    Model_Utils::treeViewChangeIcon(this, newIcon);
-}
-
-/**
- * Returns true if this classifier represents an interface.
- */
-bool UMLClassifier::isInterface() const
-{
-    return (m_BaseType == ot_Interface);
-}
-
-/**
- * Returns true if this classifier represents a datatype.
- */
-bool UMLClassifier::isDatatype() const
-{
-    return (m_BaseType == ot_Datatype);
-}
-
-/**
- * Checks whether an operation is valid based on its signature -
- * An operation is "valid" if the operation's name and parameter list
- * are unique in the classifier.
- *
- * @param name      Name of the operation to check.
- * @param opParams  The operation's argument list.
- * @param exemptOp  Pointer to the exempt method (optional.)
- * @return  NULL if the signature is valid (ok), else return a pointer
- *          to the existing UMLOperation that causes the conflict.
- */
-UMLOperation * UMLClassifier::checkOperationSignature(
-        const QString& name,
-        UMLAttributeList opParams,
-        UMLOperation *exemptOp)
-{
-    UMLOperationList list = findOperations(name);
-    if (list.count() == 0) {
-        return NULL;
-    }
-    const int inputParmCount = opParams.count();
-
-    // there is at least one operation with the same name... compare the parameter list
-    foreach (UMLOperation* test, list) {
-        if (test == exemptOp) {
-            continue;
-        }
-        UMLAttributeList testParams = test->getParmList();
-        const int pCount = testParams.count();
-        if (pCount != inputParmCount) {
-            continue;
-        }
-        int i = 0;
-        while (i < pCount) {
-            // The only criterion for equivalence is the parameter types.
-            // (Default values are not considered.)
-            if(testParams.at(i)->getTypeName() != opParams.at(i)->getTypeName())
-                break;
-            i++;
-        }
-        if (i == pCount) { // all parameters matched->the signature is not unique
-            return test;
-        }
-    }
-    // we did not find an exact match, so the signature is unique (acceptable)
-    return NULL;
-}
-
-/**
- * Find an operation of the given name and parameter signature.
- *
- * @param name     The name of the operation to find.
- * @param params   The parameter descriptors of the operation to find.
- *
- * @return  The operation found.  Will return 0 if none found.
- */
-UMLOperation* UMLClassifier::findOperation(const QString& name,
-                                           Model_Utils::NameAndType_List params)
-{
-    UMLOperationList list = findOperations(name);
-    if (list.count() == 0) {
-        return NULL;
-    }
-    // if there are operation(s) with the same name then compare the parameter list
-    const int inputParmCount = params.count();
-
-    foreach (UMLOperation* test, list) {
-        UMLAttributeList testParams = test->getParmList();
-        const int pCount = testParams.count();
-        if (inputParmCount == 0 && pCount == 0)
-            return test;
-        if (inputParmCount != pCount)
-            continue;
-        int i = 0;
-        for (; i < pCount; ++i) {
-            Model_Utils::NameAndType_ListIt nt(params.begin() + i);
-            UMLClassifier *type = dynamic_cast<UMLClassifier*>((*nt).m_type);
-            UMLClassifier *testType = testParams.at(i)->getType();
-            if (type == NULL && testType == NULL) { //no parameter type
-                continue;
-            } else if (type == NULL) {  //template parameter
-                if (testType->name() != QLatin1String("class"))
-                    break;
-            } else if (type != testType)
-                break;
-        }
-        if (i == pCount)
-            return test;  // all parameters matched
-    }
-    return 0;
-}
-
-/**
- * Creates an operation in the current document.
- * The new operation is initialized with name, id, etc.
- * If a method with the given profile already exists in the classifier,
- * no new method is created and the existing operation is returned.
- * If no name is provided, or if the params are NULL, an Operation
- * Dialog is shown to ask the user for a name and parameters.
- * The operation's signature is checked for validity within the parent
- * classifier.
- *
- * @param name           The operation name (will be chosen internally if
- *                       none given.)
- * @param isExistingOp   Optional pointer to bool. If supplied, the bool is
- *                       set to true if an existing operation is returned.
- * @param params         Optional list of parameter names and types.
- *                       If supplied, new operation parameters are
- *                       constructed using this list.
- * @return The new operation, or NULL if the operation could not be
- *         created because for example, the user canceled the dialog
- *         or no appropriate name can be found.
- */
-UMLOperation* UMLClassifier::createOperation(
-        const QString &name /*=QString()*/,
-        bool *isExistingOp  /*=NULL*/,
-        Model_Utils::NameAndType_List *params  /*=NULL*/)
-{
-    bool nameNotSet = (name.isNull() || name.isEmpty());
-    if (! nameNotSet) {
-        Model_Utils::NameAndType_List parList;
-        if (params)
-            parList = *params;
-        UMLOperation* existingOp = findOperation(name, parList);
-        if (existingOp != NULL) {
-            if (isExistingOp != NULL)
-                *isExistingOp = true;
-            return existingOp;
-        }
-    }
-    // we did not find an exact match, so the signature is unique
-    UMLOperation *op = new UMLOperation(this, name);
-    if (params) {
-        for (Model_Utils::NameAndType_ListIt it = params->begin(); it != params->end(); ++it) {
-            const Model_Utils::NameAndType &nt = *it;
-            UMLAttribute *par = new UMLAttribute(op, nt.m_name, Uml::ID::None, Uml::Visibility::Private,
-                                                 nt.m_type, nt.m_initialValue);
-            par->setParmKind(nt.m_direction);
-            op->addParm(par);
-        }
-    }
-
-    // Only show the operation dialog if no name was provided (allows quick-create
-    // from listview)
-    if (nameNotSet) {
-        op->setName(uniqChildName(UMLObject::ot_Operation));
-
-        while (true) {
-            QPointer<UMLOperationDialog> operationDialog = new UMLOperationDialog(0, op);
-            if(operationDialog->exec() != QDialog::Accepted) {
-                delete op;
-                delete operationDialog;
-                return NULL;
-            } else if (checkOperationSignature(op->name(), op->getParmList())) {
-                KMessageBox::information(0,
-                                         i18n("An operation with the same name and signature already exists. You cannot add it again."));
-            } else {
-                break;
-            }
-            delete operationDialog;
-        }
-    }
-
-    // operation name is ok, formally add it to the classifier
-    if (! addOperation(op)) {
-        delete op;
-        return NULL;
-    }
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(op);
-    return op;
-}
-
-/**
- * Appends an operation to the classifier.
- * This function is mainly intended for the clipboard.
- *
- * @param op         Pointer to the UMLOperation to add.
- * @param position   Inserted at the given position.
- * @return           True if the operation was added successfully.
- */
-bool UMLClassifier::addOperation(UMLOperation* op, int position)
-{
-    Q_ASSERT(op);
-    if (m_List.indexOf(op) != -1) {
-        uDebug() << "findRef(" << op->name() << ") finds op (bad)";
-        return false;
-    }
-    if (checkOperationSignature(op->name(), op->getParmList())) {
-        uDebug() << "checkOperationSignature(" << op->name() << ") op is non-unique";
-        return false;
-    }
-
-    if (position >= 0 && position <= m_List.count()) {
-        uDebug() << op->name() << ": inserting at position " << position;
-        m_List.insert(position, op);
-        UMLClassifierListItemList itemList = getFilteredList(UMLObject::ot_Operation);
-        QString buf;
-        foreach (UMLClassifierListItem* currentAtt, itemList) {
-            buf.append(QLatin1Char(' ') + currentAtt->name());
-        }
-        uDebug() << "  list after change: " << buf;
-    }
-    else {
-        m_List.append(op);
-    }
-    emit operationAdded(op);
-    UMLObject::emitModified();
-    connect(op, SIGNAL(modified()), this, SIGNAL(modified()));
-    return true;
-}
-
-/**
- * Appends an operation to the classifier.
- * @see bool addOperation(UMLOperation* Op, int position = -1)
- * This function is mainly intended for the clipboard.
- *
- * @param op    Pointer to the UMLOperation to add.
- * @param log   Pointer to the IDChangeLog.
- * @return      True if the operation was added successfully.
- */
-bool UMLClassifier::addOperation(UMLOperation* op, IDChangeLog* log)
-{
-    if (addOperation(op, -1)) {
-        return true;
-    }
-    else if (log) {
-        log->removeChangeByNewID(op->id());
-    }
-    return false;
-}
-
-/**
- * Remove an operation from the Classifier.
- * The operation is not deleted so the caller is responsible for what
- * happens to it after this.
- *
- * @param op   The operation to remove.
- * @return     Count of the remaining operations after removal, or
- *             -1 if the given operation was not found.
- */
-int UMLClassifier::removeOperation(UMLOperation *op)
-{
-    if (op == NULL) {
-        uDebug() << "called on NULL op";
-        return -1;
-    }
-    if (!m_List.removeAll(op)) {
-        uDebug() << "cannot find op " << op->name() << " in list";
-        return -1;
-    }
-    // disconnection needed.
-    // note that we don't delete the operation, just remove it from the Classifier
-    disconnect(op, SIGNAL(modified()), this, SIGNAL(modified()));
-    emit operationRemoved(op);
-    UMLObject::emitModified();
-    return m_List.count();
-}
-
-/**
- * Create and add a just created template.
- * @param currentName   the name of the template
- * @return              the template or NULL
- */
-UMLObject* UMLClassifier::createTemplate(const QString& currentName /*= QString()*/)
-{
-    QString name = currentName;
-    bool goodName = !name.isEmpty();
-    if (!goodName) {
-        name = uniqChildName(UMLObject::ot_Template);
-    }
-    UMLTemplate* newTemplate = new UMLTemplate(this, name);
-
-    int button = QDialog::Accepted;
-
-    while (button == QDialog::Accepted && !goodName) {
-        QPointer<UMLTemplateDialog> templateDialog = new UMLTemplateDialog(0, newTemplate);
-        button = templateDialog->exec();
-        name = newTemplate->name();
-
-        if (name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        }
-        else if (findChildObject(name) != NULL) {
-            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
-        }
-        else {
-            goodName = true;
-        }
-        delete templateDialog;
-    }
-
-    if (button != QDialog::Accepted) {
-        return NULL;
-    }
-
-    addTemplate(newTemplate);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newTemplate);
-    return newTemplate;
-}
-
-/**
- * Returns the number of attributes for the class.
- *
- * @return  The number of attributes for the class.
- */
-int UMLClassifier::attributes()
-{
-    UMLClassifierListItemList atts = getFilteredList(UMLObject::ot_Attribute);
-    return atts.count();
-}
-
-/**
- * Returns the attributes for the specified scope.
- * @return   List of true attributes for the class.
- */
-UMLAttributeList UMLClassifier::getAttributeList() const
-{
-    UMLAttributeList attributeList;
-    foreach (UMLObject* listItem, m_List) {
-        uIgnoreZeroPointer(listItem);
-        if (listItem->baseType() == UMLObject::ot_Attribute) {
-            attributeList.append(static_cast<UMLAttribute*>(listItem));
-        }
-    }
-    return attributeList;
-}
-
-/**
- * Returns the attributes for the specified scope.
- * @param scope   The scope of the attribute.
- * @return        List of true attributes for the class.
- */
-UMLAttributeList UMLClassifier::getAttributeList(Visibility::Enum scope) const
-{
-    UMLAttributeList list;
-    if (!isInterface())
-    {
-        UMLAttributeList atl = getAttributeList();
-        foreach(UMLAttribute* at, atl)
-        {
-            uIgnoreZeroPointer(at);
-            if (! at->isStatic())
-            {
-                if (scope == Uml::Visibility::Private)
-                {
-                    if ((at->visibility() == Uml::Visibility::Private) ||
-                       (at->visibility() == Uml::Visibility::Implementation))
-                    {
-                        list.append(at);
-                    }
-                }
-                else if (scope == at->visibility())
-                {
-                   list.append(at);
-                }
-            }
-        }
-    }
-    return list;
-}
-
-/**
- * Returns the static attributes for the specified scope.
- *
- * @param scope   The scope of the attribute.
- * @return        List of true attributes for the class.
- */
-UMLAttributeList UMLClassifier::getAttributeListStatic(Visibility::Enum scope) const
-{
-    UMLAttributeList list;
-    if (!isInterface())
-    {
-        UMLAttributeList atl = getAttributeList();
-        foreach(UMLAttribute* at, atl)
-        {
-            uIgnoreZeroPointer(at);
-            if (at->isStatic())
-            {
-                if (scope == Uml::Visibility::Private)
-                {
-                    if ((at->visibility() == Uml::Visibility::Private) ||
-                       (at->visibility() == Uml::Visibility::Implementation))
-                    {
-                        list.append(at);
-                    }
-                }
-                else if (scope == at->visibility())
-                {
-                    list.append(at);
-                }
-            }
-        }
-    }
-    return list;
-}
-
-/**
- * Find a list of operations with the given name.
- *
- * @param n   The name of the operation to find.
- * @return    The list of objects found; will be empty if none found.
- */
-UMLOperationList UMLClassifier::findOperations(const QString &n)
-{
-    const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
-    UMLOperationList list;
-    foreach (UMLObject*  obj, m_List) {
-        uIgnoreZeroPointer(obj);
-        if (obj->baseType() != UMLObject::ot_Operation)
-            continue;
-        UMLOperation *op = static_cast<UMLOperation*>(obj);
-        if (caseSensitive) {
-            if (obj->name() == n)
-                list.append(op);
-        } else if (obj->name().toLower() == n.toLower()) {
-            list.append(op);
-        }
-    }
-    return list;
-}
-
-/**
- * Find the child object by the given id.
- * @param id                  the id of the child object
- * @param considerAncestors   flag whether the ancestors should be considered during search
- * @return                    the found child object or NULL
- */
-UMLObject* UMLClassifier::findChildObjectById(Uml::ID::Type id, bool considerAncestors /* =false */)
-{
-    UMLObject *o = UMLCanvasObject::findChildObjectById(id);
-    if (o) {
-        return o;
-    }
-    if (considerAncestors) {
-        UMLClassifierList ancestors = findSuperClassConcepts();
-        foreach (UMLClassifier *anc, ancestors) {
-            UMLObject *o = anc->findChildObjectById(id);
-            if (o) {
-                return o;
-            }
-        }
-    }
-    return NULL;
-}
-
-/**
- * Returns a list of concepts which inherit from this concept.
- *
- * @param type   The ClassifierType to seek.
- * @return       List of UMLClassifiers that inherit from us.
- */
-UMLClassifierList UMLClassifier::findSubClassConcepts (ClassifierType type)
-{
-    UMLClassifierList list = getSubClasses();
-    UMLAssociationList rlist = getRealizations();
-
-    UMLClassifierList inheritingConcepts;
-    Uml::ID::Type myID = id();
-    foreach(UMLClassifier *c, list) {
-        uIgnoreZeroPointer(c);
-        if (type == ALL || (!c->isInterface() && type == CLASS)
-                || (c->isInterface() && type == INTERFACE)) {
-            inheritingConcepts.append(c);
-        }
-    }
-
-    foreach (UMLAssociation *a, rlist) {
-        uIgnoreZeroPointer(a);
-        if (a->getObjectId(RoleType::A) != myID)
-        {
-            UMLObject* obj = a->getObject(RoleType::A);
-            UMLClassifier *concept = dynamic_cast<UMLClassifier*>(obj);
-            if (concept && (type == ALL || (!concept->isInterface() && type == CLASS)
-                            || (concept->isInterface() && type == INTERFACE))
-                        && (inheritingConcepts.indexOf(concept) == -1))
-            {
-                inheritingConcepts.append(concept);
-            }
-        }
-    }
-
-    return inheritingConcepts;
-}
-
-/**
- * Returns a list of concepts which this concept inherits from.
- *
- * @param type   The ClassifierType to seek.
- * @return       List of UMLClassifiers we inherit from.
- */
-UMLClassifierList UMLClassifier::findSuperClassConcepts (ClassifierType type)
-{
-    UMLClassifierList list = getSuperClasses();
-    UMLAssociationList rlist = getRealizations();
-
-    UMLClassifierList parentConcepts;
-    Uml::ID::Type myID = id();
-    foreach (UMLClassifier *concept, list) {
-        uIgnoreZeroPointer(concept);
-        if (type == ALL || (!concept->isInterface() && type == CLASS)
-                || (concept->isInterface() && type == INTERFACE))
-            parentConcepts.append(concept);
-    }
-
-    foreach (UMLAssociation *a, rlist) {
-        if (a->getObjectId(RoleType::A) == myID)
-        {
-            UMLObject* obj = a->getObject(RoleType::B);
-            UMLClassifier *concept = dynamic_cast<UMLClassifier*>(obj);
-            if (concept && (type == ALL || (!concept->isInterface() && type == CLASS)
-                            || (concept->isInterface() && type == INTERFACE))
-                        && (parentConcepts.indexOf(concept) == -1))
-                parentConcepts.append(concept);
-        }
-    }
-
-    return parentConcepts;
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLClassifier::operator==(const UMLClassifier & rhs) const
-{
-    return UMLCanvasObject::operator==(rhs);
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLClassifier::copyInto(UMLObject *lhs) const
-{
-    UMLClassifier *target = static_cast<UMLClassifier*>(lhs);
-    UMLCanvasObject::copyInto(target);
-    target->setBaseType(m_BaseType);
-    // CHECK: association property m_pClassAssoc is not copied
-    m_List.copyInto(&(target->m_List));
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLClassifier::clone() const
-{
-    UMLClassifier *clone = new UMLClassifier();
-    copyInto(clone);
-    return clone;
-}
-
-/**
- * Needs to be called after all UML objects are loaded from file.
- * Calls the parent resolveRef(), and calls resolveRef() on all
- * UMLClassifierListItems.
- * Overrides the method from UMLObject.
- *
- * @return  true for success.
- */
-bool UMLClassifier::resolveRef()
-{
-    bool success = UMLPackage::resolveRef();
-    // Using reentrant iteration is a bare necessity here:
-    foreach (UMLObject* obj, m_List) {
-        uIgnoreZeroPointer(obj);
-        /**** For reference, here is the non-reentrant iteration scheme -
-              DO NOT USE THIS !
-        for (UMLObject *obj = m_List.first(); obj; obj = m_List.next())
-         {  ....  }
-         ****/
-        if (obj->resolveRef()) {
-            UMLClassifierListItem *cli = static_cast<UMLClassifierListItem*>(obj);
-            switch (cli->baseType()) {
-                case UMLObject::ot_Attribute:
-                    emit attributeAdded(cli);
-                    break;
-                case UMLObject::ot_Operation:
-                    emit operationAdded(cli);
-                    break;
-                case UMLObject::ot_Template:
-                    emit templateAdded(cli);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-    return success;
-}
-
-/**
- * Reimplemented from UMLObject.
- */
-bool UMLClassifier::acceptAssociationType(AssociationType::Enum type)
-{
-    switch(type)
-    {
-        case AssociationType::Generalization:
-        case AssociationType::Aggregation:
-        case AssociationType::Relationship:
-        case AssociationType::Dependency:
-        case AssociationType::Association:
-        case AssociationType::Association_Self:
-        case AssociationType::Containment:
-        case AssociationType::Composition:
-        case AssociationType::Realization:
-        case AssociationType::UniAssociation:
-            return true;
-        default:
-            return false;
-    }
-    return false; //shutup compiler warning
-}
-
-/**
- * Creates an attribute for the class.
- *
- * @param name  An optional name, used by when creating through UMLListView
- * @param type  An optional type, used by when creating through UMLListView
- * @param vis   An optional visibility, used by when creating through UMLListView
- * @param init  An optional initial value, used by when creating through UMLListView
- * @return      The UMLAttribute created
- */
-UMLAttribute* UMLClassifier::createAttribute(const QString &name,
-                                             UMLObject *type,
-                                             Visibility::Enum vis,
-                                             const QString &init)
-{
-    Uml::ID::Type id = UniqueID::gen();
-    QString currentName;
-    if (name.isNull())  {
-        currentName = uniqChildName(UMLObject::ot_Attribute);
-    } else {
-        currentName = name;
-    }
-    UMLAttribute* newAttribute = new UMLAttribute(this, currentName, id, vis, type, init);
-
-    int button = QDialog::Accepted;
-    bool goodName = false;
-
-    //check for name.isNull() stops dialog being shown
-    //when creating attribute via list view
-    while (button == QDialog::Accepted && !goodName && name.isNull()) {
-        QPointer<UMLAttributeDialog> attributeDialog = new UMLAttributeDialog(0, newAttribute);
-        button = attributeDialog->exec();
-        QString name = newAttribute->name();
-
-        if(name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        } else if (findChildObject(name) != NULL) {
-            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
-        } else {
-            goodName = true;
-        }
-        delete attributeDialog;
-    }
-
-    if (button != QDialog::Accepted) {
-        delete newAttribute;
-        return NULL;
-    }
-
-    addAttribute(newAttribute);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newAttribute);
-    return newAttribute;
-}
-
-/**
- * Creates and adds an attribute for the class.
- *
- * @param name  an optional name, used by when creating through UMLListView
- * @param id    an optional id
- * @return      the UMLAttribute created and added
- */
-
-UMLAttribute* UMLClassifier::addAttribute(const QString &name, Uml::ID::Type id /* = Uml::id_None */)
-{
-    foreach (UMLObject* obj, m_List) {
-        uIgnoreZeroPointer(obj);
-        if (obj->baseType() == UMLObject::ot_Attribute && obj->name() == name)
-            return static_cast<UMLAttribute*>(obj);
-    }
-    Uml::Visibility::Enum scope = Settings::optionState().classState.defaultAttributeScope;
-    UMLAttribute *a = new UMLAttribute(this, name, id, scope);
-    m_List.append(a);
-    emit attributeAdded(a);
-    UMLObject::emitModified();
-    connect(a, SIGNAL(modified()), this, SIGNAL(modified()));
-    return a;
-}
-
-/**
- * Adds an already created attribute.
- * The attribute object must not belong to any other concept.
- *
- * @param name    the name of the attribute
- * @param type    the type of the attribute
- * @param scope   the visibility of the attribute
- * @return        the just created and added attribute
- */
-UMLAttribute* UMLClassifier::addAttribute(const QString &name, UMLObject *type, Visibility::Enum scope)
-{
-    UMLAttribute *a = new UMLAttribute(this);
-    a->setName(name);
-    a->setVisibility(scope);
-    a->setID(UniqueID::gen());
-    if (type) {
-        a->setType(type);
-    }
-    m_List.append(a);
-    emit attributeAdded(a);
-    UMLObject::emitModified();
-    connect(a, SIGNAL(modified()), this, SIGNAL(modified()));
-    return a;
-}
-
-/**
- * Adds an already created attribute.
- * The attribute object must not belong to any other concept.
- *
- * @param att        Pointer to the UMLAttribute.
- * @param log        Pointer to the IDChangeLog (optional.)
- * @param position   Position index for the insertion (optional.)
- *                   If the position is omitted, or if it is
- *                   negative or too large, the attribute is added
- *                   to the end of the list.
- * @return           True if the attribute was successfully added.
- */
-bool UMLClassifier::addAttribute(UMLAttribute* att, IDChangeLog* log /* = 0 */,
-                                 int position /* = -1 */)
-{
-    Q_ASSERT(att);
-    if (findChildObject(att->name()) == NULL) {
-        att->setParent(this);
-        if (position >= 0 && position < (int)m_List.count()) {
-            m_List.insert(position, att);
-        }
-        else {
-            m_List.append(att);
-        }
-        emit attributeAdded(att);
-        UMLObject::emitModified();
-        connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    } else if (log) {
-        log->removeChangeByNewID(att->id());
-        delete att;
-    }
-    return false;
-}
-
-/**
- * Removes an attribute from the class.
- *
- * @param att   The attribute to remove.
- * @return      Count of the remaining attributes after removal.
- *              Returns -1 if the given attribute was not found.
- */
-int UMLClassifier::removeAttribute(UMLAttribute* att)
-{
-    if (!m_List.removeAll(att)) {
-        uDebug() << "cannot find att given in list";
-        return -1;
-    }
-    emit attributeRemoved(att);
-    UMLObject::emitModified();
-    // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
-    // for us by QObject. -b.t.
-    // disconnect(att, SIGNAL(modified()), this, SIGNAL(modified()));
-    delete att;
-    return m_List.count();
-}
-
-/**
- * Sets the UMLAssociation for which this class shall act as an
- * association class.
- */
-void UMLClassifier::setClassAssoc(UMLAssociation *assoc)
-{
-    m_pClassAssoc = assoc;
-}
-
-/**
- * Returns the UMLAssociation for which this class acts as an
- * association class. Returns NULL if this class does not act
- * as an association class.
- */
-UMLAssociation *UMLClassifier::getClassAssoc() const
-{
-    return m_pClassAssoc;
-}
-
-/**
- * Return true if this classifier has abstract operations.
- */
-bool UMLClassifier::hasAbstractOps ()
-{
-    UMLOperationList opl(getOpList());
-    foreach(UMLOperation *op, opl) {
-        uIgnoreZeroPointer(op);
-        if (op->isAbstract()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/**
- * Counts the number of operations in the Classifier.
- *
- * @return   The number of operations for the Classifier.
- */
-int UMLClassifier::operations()
-{
-    return getOpList().count();
-}
-
-
-/**
- * Return a list of operations for the Classifier.
- *
- * @param includeInherited   Includes operations from superclasses.
- * @param alreadyTraversed   internal used object to avoid recursive loops
- * @return   The list of operations for the Classifier.
- */
-UMLOperationList UMLClassifier::getOpList(bool includeInherited, UMLClassifierSet *alreadyTraversed)
-{
-    UMLOperationList ops;
-    foreach (UMLObject* li, m_List) {
-        uIgnoreZeroPointer(li);
-        if (li->baseType() == ot_Operation) {
-            ops.append(static_cast<UMLOperation*>(li));
-        }
-    }
-    if (includeInherited) {
-        if (!alreadyTraversed) {
-            alreadyTraversed = new UMLClassifierSet;
-        }
-        else
-            alreadyTraversed->level++;
-
-        if (!alreadyTraversed->contains(this))
-            *alreadyTraversed << this;
-
-        // get a list of parents of this class
-        UMLClassifierList parents = findSuperClassConcepts();
-        foreach(UMLClassifier *c, parents) {
-            if (alreadyTraversed->contains(c)) {
-                uError() << "class " << c->name() << " is starting a dependency loop!";
-                continue;
-            }
-            // get operations for each parent by recursive call
-            UMLOperationList pops = c->getOpList(true, alreadyTraversed);
-            // add these operations to operation list, but only if unique.
-            foreach (UMLOperation *po, pops) {
-                QString po_as_string(po->toString(Uml::SignatureType::SigNoVis));
-                bool breakFlag = false;
-                foreach (UMLOperation* o,  ops) {
-                    if (o->toString(Uml::SignatureType::SigNoVis) == po_as_string) {
-                        breakFlag = true;
-                        break;
-                    }
-                }
-                if (breakFlag == false)
-                    ops.append(po);
-            }
-            // remember this node
-            *alreadyTraversed << c;
-        }
-        if (alreadyTraversed->level-- == 0) {
-            delete alreadyTraversed;
-            alreadyTraversed = 0;
-        }
-    }
-    return ops;
-}
-
-/**
- * Returns the entries in m_List that are of the requested type.
- * If the requested type is UMLObject::ot_UMLObject then all entries
- * are returned.
- * @param ot   the requested object type
- * @return     The list of true operations for the Concept.
- */
-UMLClassifierListItemList UMLClassifier::getFilteredList(UMLObject::ObjectType ot) const
-{
-    UMLClassifierListItemList resultList;
-    foreach (UMLObject* o, m_List) {
-        uIgnoreZeroPointer(o);
-        if (!o || o->baseType() == UMLObject::ot_Association) {
-            continue;
-        }
-        UMLClassifierListItem *listItem = static_cast<UMLClassifierListItem*>(o);
-        if (ot == UMLObject::ot_UMLObject || listItem->baseType() == ot) {
-            resultList.append(listItem);
-        }
-    }
-    return resultList;
-}
-
-/**
- * Adds an already created template.
- * The template object must not belong to any other concept.
- *
- * @param name   the name of the template
- * @param id     the id of the template
- * @return       the added template
- */
-UMLTemplate* UMLClassifier::addTemplate(const QString &name, Uml::ID::Type id)
-{
-    UMLTemplate *templt = findTemplate(name);
-    if (templt) {
-        return templt;
-    }
-    templt = new UMLTemplate(this, name, id);
-    m_List.append(templt);
-    emit templateAdded(templt);
-    UMLObject::emitModified();
-    connect(templt, SIGNAL(modified()), this, SIGNAL(modified()));
-    return templt;
-}
-
-/**
- * Adds an already created template.
- * The template object must not belong to any other concept.
- *
- * @param newTemplate   Pointer to the UMLTemplate object to add.
- * @param log           Pointer to the IDChangeLog.
- * @return              True if the template was successfully added.
- */
-bool UMLClassifier::addTemplate(UMLTemplate* newTemplate, IDChangeLog* log /* = 0*/)
-{
-    QString name = newTemplate->name();
-    if (findChildObject(name) == NULL) {
-        newTemplate->setParent(this);
-        m_List.append(newTemplate);
-        emit templateAdded(newTemplate);
-        UMLObject::emitModified();
-        connect(newTemplate, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    }
-    else if (log) {
-        log->removeChangeByNewID(newTemplate->id());
-        delete newTemplate;
-    }
-    return false;
-}
-
-/**
- * Adds an template to the class.
- * The template object must not belong to any other class.
- * TODO: If the param IDChangeLog from the method above is not being used,
- * give position a default value of -1 and the method can replace the above one.
- * @param templt     Pointer to the UMLTemplate to add.
- * @param position   The position of the template in the list.
- *                   A value of -1 will add the template at the end.
- * @return  True if the template was successfully added.
- */
-bool UMLClassifier::addTemplate(UMLTemplate* templt, int position)
-{
-    Q_ASSERT(templt);
-    QString name = templt->name();
-    if (findChildObject(name) == NULL) {
-        templt->setParent(this);
-        if (position >= 0 && position <= (int)m_List.count()) {
-            m_List.insert(position, templt);
-        }
-        else {
-            m_List.append(templt);
-        }
-        emit templateAdded(templt);
-        UMLObject::emitModified();
-        connect(templt, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    }
-    //else
-    return false;
-}
-
-/**
- * Removes a template from the class.
- *
- * @param umltemplate   The template to remove.
- * @return  Count of the remaining templates after removal.
- *          Returns -1 if the given template was not found.
- */
-int UMLClassifier::removeTemplate(UMLTemplate* umltemplate)
-{
-    if (!m_List.removeAll(umltemplate)) {
-        uWarning() << "cannot find att given in list";
-        return -1;
-    }
-    emit templateRemoved(umltemplate);
-    UMLObject::emitModified();
-    disconnect(umltemplate, SIGNAL(modified()), this, SIGNAL(modified()));
-    return m_List.count();
-}
-
-/**
- * Seeks the template parameter of the given name.
- * @param name   the template name
- * @return       the found template or 0
- */
-UMLTemplate *UMLClassifier::findTemplate(const QString& name)
-{
-    UMLTemplateList templParams = getTemplateList();
-    foreach (UMLTemplate *templt, templParams) {
-        if (templt->name() == name) {
-            return templt;
-        }
-    }
-    return 0;
-}
-
-/**
- * Returns the number of templates for the class.
- *
- * @return  The number of templates for the class.
- */
-int UMLClassifier::templates()
-{
-    UMLClassifierListItemList tempList = getFilteredList(UMLObject::ot_Template);
-    return tempList.count();
-}
-
-/**
- * Returns the templates.
- * Same as UMLClassifier::getFilteredList(ot_Template) but
- * return type is a true UMLTemplateList.
- *
- * @return  Pointer to the list of true templates for the class.
- */
-UMLTemplateList UMLClassifier::getTemplateList() const
-{
-    UMLTemplateList templateList;
-    foreach (UMLObject* listItem, m_List) {
-        uIgnoreZeroPointer(listItem);
-        if (listItem->baseType() == UMLObject::ot_Template) {
-            templateList.append(static_cast<UMLTemplate*>(listItem));
-        }
-    }
-    return templateList;
-}
-
-/**
- * Take and return a subordinate item from this classifier.
- * Ownership of the item is passed to the caller.
- *
- * @param item   Subordinate item to take.
- * @return       Index in m_List of the item taken.
- *               Return -1 if the item is not found in m_List.
- */
-int UMLClassifier::takeItem(UMLClassifierListItem *item)
-{
-    QString buf;
-    foreach (UMLObject* currentAtt, m_List) {
-        uIgnoreZeroPointer(currentAtt);
-        QString txt = currentAtt->name();
-        if (txt.isEmpty()) {
-           txt = QLatin1String("Type-") + QString::number((int) currentAtt->baseType());
-        }
-        buf.append(QLatin1Char(' ') + currentAtt->name());
-    }
-    uDebug() << "  UMLClassifier::takeItem (before): m_List is " << buf;
-
-    int index = m_List.indexOf(item);
-    if (index == -1) {
-        return -1;
-    }
-    switch (item->baseType()) {
-        case UMLObject::ot_Operation: {
-            if (removeOperation(dynamic_cast<UMLOperation*>(item)) < 0) {
-                index = -1;
-            }
-            break;
-        }
-        case UMLObject::ot_Attribute: {
-            UMLAttribute *retval = dynamic_cast<UMLAttribute*>(m_List.takeAt(index).data());
-            if (retval) {
-                emit attributeRemoved(retval);
-                UMLObject::emitModified();
-            } else {
-                index = -1;
-            }
-            break;
-        }
-        case UMLObject::ot_Template: {
-            UMLTemplate *templt = dynamic_cast<UMLTemplate*>(m_List.takeAt(index).data());
-            if (templt) {
-                emit templateRemoved(templt);
-                UMLObject::emitModified();
-            } else {
-                index = -1;
-            }
-            break;
-        }
-        case UMLObject::ot_EnumLiteral: {
-            UMLEnumLiteral *el = dynamic_cast<UMLEnumLiteral*>(m_List.takeAt(index).data());
-            if (el) {
-                UMLEnum *e = static_cast<UMLEnum*>(this);
-                e->signalEnumLiteralRemoved(el);
-                UMLObject::emitModified();
-            } else {
-                index = -1;
-            }
-            break;
-        }
-        case UMLObject::ot_EntityAttribute: {
-            UMLEntityAttribute* el = dynamic_cast<UMLEntityAttribute*>(m_List.takeAt(index).data());
-            if (el) {
-                UMLEntity *e = static_cast<UMLEntity*>(this);
-                e->signalEntityAttributeRemoved(el);
-                UMLObject::emitModified();
-            } else {
-                index = -1;
-            }
-            break;
-        }
-        default:
-            index = -1;
-            break;
-    }
-    return index;
-}
-
-/**
- * Set the origin type (in case of e.g. typedef)
- * @param origType   the origin type to set
- */
-void UMLClassifier::setOriginType(UMLClassifier *origType)
-{
-    m_pSecondary = origType;
-}
-
-/**
- * Get the origin type (in case of e.g. typedef)
- * @return   the origin type
- */
-UMLClassifier * UMLClassifier::originType() const
-{
-    return dynamic_cast<UMLClassifier*>(m_pSecondary.data());
-}
-
-/**
- * Set the m_isRef flag (true when dealing with a pointer type)
- * @param isRef   the flag to set
- */
-void UMLClassifier::setIsReference(bool isRef)
-{
-    m_isRef = isRef;
-}
-
-/**
- * Get the m_isRef flag.
- * @return   true if is reference, otherwise false
- */
-bool UMLClassifier::isReference() const
-{
-    return m_isRef;
-}
-
-/**
- * Return true if this classifier has associations.
- * @return   true if classifier has associations
- */
-bool UMLClassifier::hasAssociations()
-{
-    return getSpecificAssocs(AssociationType::Association).count() > 0
-            || getAggregations().count() > 0
-            || getCompositions().count() > 0
-            || getUniAssociationToBeImplemented().count() > 0;
-}
-
-/**
- * Return true if this classifier has attributes.
- */
-bool UMLClassifier::hasAttributes()
-{
-    return getAttributeList(Uml::Visibility::Public).count() > 0
-            || getAttributeList(Uml::Visibility::Protected).count() > 0
-            || getAttributeList(Uml::Visibility::Private).count() > 0
-            || getAttributeListStatic(Uml::Visibility::Public).count() > 0
-            || getAttributeListStatic(Uml::Visibility::Protected).count() > 0
-            || getAttributeListStatic(Uml::Visibility::Private).count() > 0;
-}
-
-/**
- * Return true if this classifier has static attributes.
- */
-bool UMLClassifier::hasStaticAttributes()
-{
-    return getAttributeListStatic(Uml::Visibility::Public).count() > 0
-            || getAttributeListStatic(Uml::Visibility::Protected).count() > 0
-            || getAttributeListStatic(Uml::Visibility::Private).count() > 0;
-}
-
-/**
- * Return true if this classifier has accessor methods.
- */
-bool UMLClassifier::hasAccessorMethods()
-{
-    return hasAttributes() || hasAssociations();
-}
-
-/**
- * Return true if this classifier has operation methods.
- */
-bool UMLClassifier::hasOperationMethods()
-{
-    return getOpList().last() ? true : false;
-}
-
-/**
- * Return true if this classifier has methods.
- */
-bool UMLClassifier::hasMethods()
-{
-    return hasOperationMethods() || hasAccessorMethods();
-}
-
-// this is a bit too simplistic..some associations are for
-// SINGLE objects, and WONT be declared as Vectors, so this
-// is a bit overly inclusive (I guess that's better than the other way around)
-
-/**
- * Return true if this classifier has vector fields.
- */
-bool UMLClassifier::hasVectorFields()
-{
-    return hasAssociations();
-}
-
-/**
- * Return the list of unidirectional association that should show up in the code
- */
-UMLAssociationList  UMLClassifier::getUniAssociationToBeImplemented()
-{
-    UMLAssociationList associations = getSpecificAssocs(AssociationType::UniAssociation);
-    UMLAssociationList uniAssocListToBeImplemented;
-
-    foreach (UMLAssociation *a, associations) {
-        uIgnoreZeroPointer(a);
-        if (a->getObjectId(RoleType::B) == id()) {
-            continue;  // we need to be at the A side
-        }
-        QString roleNameB = a->getRoleName(RoleType::B);
-        if (!roleNameB.isEmpty()) {
-            UMLAttributeList atl = getAttributeList();
-            bool found = false;
-            //make sure that an attribute with the same name doesn't already exist
-            foreach (UMLAttribute *at, atl) {
-                uIgnoreZeroPointer(a);
-                if (at->name() == roleNameB) {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) {
-                uniAssocListToBeImplemented.append(a);
-            }
-        }
-    }
-    return uniAssocListToBeImplemented;
-}
-
-/**
- * Creates XML tag <UML:Class>, <UML:Interface>, or <UML:DataType>
- * depending on m_BaseType.
- * Saves possible template parameters, generalizations, attributes,
- * operations, and contained objects to the given QDomElement.
- */
-void UMLClassifier::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QString tag;
-    switch (m_BaseType) {
-        case UMLObject::ot_Class:
-            tag = QLatin1String("UML:Class");
-            break;
-        case UMLObject::ot_Interface:
-            tag = QLatin1String("UML:Interface");
-            break;
-        case UMLObject::ot_Datatype:
-            tag = QLatin1String("UML:DataType");
-            break;
-        case UMLObject::ot_Package:
-            UMLPackage::saveToXMI(qDoc, qElement);
-            return;
-            break;
-        default:
-            uError() << "internal error: basetype is " << m_BaseType;
-            return;
-    }
-    QDomElement classifierElement = UMLObject::save(tag, qDoc);
-    if (m_BaseType == UMLObject::ot_Datatype && m_pSecondary != NULL)
-        classifierElement.setAttribute(QLatin1String("elementReference"),
-                                        Uml::ID::toString(m_pSecondary->id()));
-
-    //save templates
-    UMLClassifierListItemList list = getFilteredList(UMLObject::ot_Template);
-    if (list.count()) {
-        QDomElement tmplElement = qDoc.createElement(QLatin1String("UML:ModelElement.templateParameter"));
-        foreach (UMLClassifierListItem *tmpl, list) {
-            tmpl->saveToXMI(qDoc, tmplElement);
-        }
-        classifierElement.appendChild(tmplElement);
-    }
-
-    //save generalizations (we are the subclass, the other end is the superclass)
-    UMLAssociationList generalizations = getSpecificAssocs(AssociationType::Generalization);
-    if (generalizations.count()) {
-        QDomElement genElement = qDoc.createElement(QLatin1String("UML:GeneralizableElement.generalization"));
-        foreach (UMLAssociation *a, generalizations) {
-            // We are the subclass if we are at the role A end.
-            if (m_nId != a->getObjectId(RoleType::A)) {
-                continue;
-            }
-            QDomElement gElem = qDoc.createElement(QLatin1String("UML:Generalization"));
-            gElem.setAttribute(QLatin1String("xmi.idref"), Uml::ID::toString(a->id()));
-            genElement.appendChild(gElem);
-        }
-        if (genElement.hasChildNodes()) {
-            classifierElement.appendChild(genElement);
-        }
-    }
-
-    // save attributes
-    QDomElement featureElement = qDoc.createElement(QLatin1String("UML:Classifier.feature"));
-    UMLClassifierListItemList attList = getFilteredList(UMLObject::ot_Attribute);
-    foreach (UMLClassifierListItem *pAtt, attList) {
-        pAtt->saveToXMI(qDoc, featureElement);
-    }
-
-    // save operations
-    UMLOperationList opList = getOpList();
-    foreach (UMLOperation *pOp, opList) {
-        pOp->saveToXMI(qDoc, featureElement);
-    }
-    if (featureElement.hasChildNodes()) {
-        classifierElement.appendChild(featureElement);
-    }
-
-    // save contained objects
-    if (m_objects.count()) {
-        QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
-        foreach (UMLObject* obj, m_objects) {
-            uIgnoreZeroPointer(obj);
-            obj->saveToXMI (qDoc, ownedElement);
-        }
-        classifierElement.appendChild(ownedElement);
-    }
-    qElement.appendChild(classifierElement);
-}
-
-/**
- * Create a new ClassifierListObject (attribute, operation, template)
- * according to the given XMI tag.
- * Returns NULL if the string given does not contain one of the tags
- * <UML:Attribute>, <UML:Operation>, or <UML:TemplateParameter>.
- * Used by the clipboard for paste operation.
- */
-UMLClassifierListItem* UMLClassifier::makeChildObject(const QString& xmiTag)
-{
-    UMLClassifierListItem* pObject = NULL;
-    if (UMLDoc::tagEq(xmiTag, QLatin1String("Operation")) ||
-        UMLDoc::tagEq(xmiTag, QLatin1String("ownedOperation"))) {
-        pObject = new UMLOperation(this);
-    } else if (UMLDoc::tagEq(xmiTag, QLatin1String("Attribute")) ||
-               UMLDoc::tagEq(xmiTag, QLatin1String("ownedAttribute"))) {
-        if (baseType() != UMLObject::ot_Class)
-            return NULL;
-        pObject = new UMLAttribute(this);
-    } else if (UMLDoc::tagEq(xmiTag, QLatin1String("TemplateParameter"))) {
-        pObject = new UMLTemplate(this);
-    }
-    return pObject;
-}
-
-/**
- * Auxiliary to loadFromXMI:
- * The loading of operations is implemented here.
- * Calls loadSpecialized() for any other tag.
- * Child classes can override the loadSpecialized method
- * to load its additional tags.
- */
-bool UMLClassifier::load(QDomElement& element)
-{
-    UMLClassifierListItem *child = NULL;
-    m_SecondaryId = element.attribute(QLatin1String("elementReference"));
-    if (!m_SecondaryId.isEmpty()) {
-        // @todo We do not currently support composition.
-        m_isRef = true;
-    }
-    bool totalSuccess = true;
-    for (QDomNode node = element.firstChild(); !node.isNull();
-            node = node.nextSibling()) {
-        if (node.isComment())
-            continue;
-        element = node.toElement();
-        QString tag = element.tagName();
-        QString stereotype = element.attribute(QLatin1String("stereotype"));
-        if (UMLDoc::tagEq(tag, QLatin1String("ModelElement.templateParameter")) ||
-                UMLDoc::tagEq(tag, QLatin1String("Classifier.feature")) ||
-                UMLDoc::tagEq(tag, QLatin1String("Namespace.ownedElement")) ||
-                UMLDoc::tagEq(tag, QLatin1String("Element.ownedElement")) ||  // Embarcadero's Describe
-                UMLDoc::tagEq(tag, QLatin1String("Namespace.contents"))) {
-            load(element);
-            // Not evaluating the return value from load()
-            // because we want a best effort.
-
-        } else if ((child = makeChildObject(tag)) != NULL) {
-            if (child->loadFromXMI(element)) {
-                switch (child->baseType()) {
-                    case UMLObject::ot_Template:
-                        addTemplate(static_cast<UMLTemplate*>(child));
-                        break;
-                    case UMLObject::ot_Operation:
-                        if (! addOperation(static_cast<UMLOperation*>(child))) {
-                            uError() << "error from addOperation(op)";
-                            delete child;
-                            totalSuccess = false;
-                        }
-                        break;
-                    case UMLObject::ot_Attribute:
-                        addAttribute(static_cast<UMLAttribute*>(child));
-                        break;
-                    default:
-                        break;
-                }
-            } else {
-                uWarning() << "failed to load " << tag;
-                delete child;
-                totalSuccess = false;
-            }
-        } else if (!Model_Utils::isCommonXMIAttribute(tag)) {
-            UMLObject *pObject = Object_Factory::makeObjectFromXMI(tag, stereotype);
-            if (pObject == NULL) {
-                // Not setting totalSuccess to false
-                // because we want a best effort.
-                continue;
-            }
-            pObject->setUMLPackage(this);
-            if (! pObject->loadFromXMI(element)) {
-                removeObject(pObject);
-                delete pObject;
-                totalSuccess = false;
-            }
-        }
-    }
-    return totalSuccess;
-}
-
-/*
-UMLClassifierList UMLClassifier::getPlainAssocChildClassifierList()
-{
-    UMLAssociationList plainAssociations = getSpecificAssocs(Uml::AssociationType::Association);
-    return findAssocClassifierObjsInRoles(&plainAssociations);
-}
-
-UMLClassifierList UMLClassifier::getAggregateChildClassifierList()
-{
-    UMLAssociationList aggregations = getAggregations();
-    return findAssocClassifierObjsInRoles(&aggregations);
-}
-
-UMLClassifierList UMLClassifier::getCompositionChildClassifierList()
-{
-    UMLAssociationList compositions = getCompositions();
-    return findAssocClassifierObjsInRoles(&compositions);
-}
-
-UMLClassifierList UMLClassifier::findAssocClassifierObjsInRoles (UMLAssociationList * list)
-{
-    UMLClassifierList classifiers;
-
-    for (UMLAssociationListIt alit(*list); alit.hasNext(); ) {
-        UMLAssociation* a = alit.next();
-        // DON'T accept a classifier IF the association role is empty, by
-        // convention, that means to ignore the classifier on that end of
-        // the association.
-        // We also ignore classifiers which are the same as the current one
-        // (e.g. id matches), we only want the "other" classifiers
-        if (a->getObjectId(RoleType::A) == id() && !a->getRoleName(RoleType::B).isEmpty()) {
-            UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(RoleType::B));
-            if(c)
-                classifiers.append(c);
-        } else if (a->getObjectId(RoleType::B) == id() && !a->getRoleName(RoleType::A).isEmpty()) {
-            UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(RoleType::A));
-            if(c)
-                classifiers.append(c);
-        }
-    }
-
-    return classifiers;
-}
-*/
-
-
diff -Nuar umbrello-15.08.1.orig/umbrello/classifier.h umbrello-15.08.1/umbrello/classifier.h
--- umbrello-15.08.1.orig/umbrello/classifier.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/classifier.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,199 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-#ifndef CLASSIFIER_H
-#define CLASSIFIER_H
-
-#include "package.h"
-#include "umlattributelist.h"
-#include "umloperationlist.h"
-#include "umlclassifierlistitemlist.h"
-#include "classifierlistitem.h"
-#include "umltemplatelist.h"
-#include "model_utils.h"
-
-// forward declarations
-class UMLAssociation;
-class IDChangeLog;
-class UMLClassifierSet;
-
-/**
- * This class defines the non-graphical information required for a
- * UML Classifier (ie a class or interface).
- * This class inherits from @ref UMLPackage which allows classifiers
- * to also act as namespaces, i.e. it allows classifiers to nest.
- *
- * NOTE: There is a unit test available for this class.
- *       Please, use and adapt it when necessary.
- *
- * @short Information for a non-graphical Concept/Class.
- * @author Paul Hensgen <phensgen@techie.com>
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLClassifier : public UMLPackage
-{
-    Q_OBJECT
-public:
-
-    /**
-     * Enumeration identifying the type of classifier.
-     */
-    enum ClassifierType { ALL = 0, CLASS, INTERFACE, DATATYPE };
-
-    explicit UMLClassifier(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLClassifier();
-
-    bool operator==(const UMLClassifier & rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    UMLObject* clone() const;
-
-    virtual UMLAttribute* createAttribute(const QString &name = QString(),
-                                          UMLObject *type = 0,
-                                          Uml::Visibility::Enum vis = Uml::Visibility::Private,
-                                          const QString &init = QString());
-
-    UMLAttribute* addAttribute(const QString &name, Uml::ID::Type id = Uml::ID::None);
-    UMLAttribute* addAttribute(const QString &name, UMLObject *type, Uml::Visibility::Enum scope);
-
-    bool addAttribute(UMLAttribute* att, IDChangeLog* log = 0,
-                      int position = -1);
-
-    int removeAttribute(UMLAttribute *att);
-
-    int attributes() ;
-
-    UMLAttributeList getAttributeList() const;
-    UMLAttributeList getAttributeList(Uml::Visibility::Enum scope) const;
-    UMLAttributeList getAttributeListStatic(Uml::Visibility::Enum scope) const;
-
-    UMLOperation* createOperation(const QString &name = QString(),
-                                  bool *isExistingOp = NULL,
-                                  Model_Utils::NameAndType_List *params = NULL);
-
-    bool addOperation(UMLOperation* op, int position = -1);
-    bool addOperation(UMLOperation* op, IDChangeLog* log);
-
-    UMLOperation * checkOperationSignature(const QString& name,
-                                           UMLAttributeList opParams,
-                                           UMLOperation *exemptOp = NULL);
-
-    int removeOperation(UMLOperation *op);
-
-    int operations();
-
-    UMLOperationList getOpList(bool includeInherited = false, UMLClassifierSet *alreadyTraversed = 0);
-
-    UMLObject* createTemplate(const QString& name = QString());
-
-    UMLTemplate* addTemplate(const QString &name, Uml::ID::Type id = Uml::ID::None);
-
-    bool addTemplate(UMLTemplate* newTemplate, IDChangeLog* log = 0);
-    bool addTemplate(UMLTemplate* templt, int position);
-
-    int removeTemplate(UMLTemplate* umltemplate);
-
-    UMLTemplate *findTemplate(const QString& name);
-
-    int templates();
-
-    UMLTemplateList getTemplateList() const;
-
-    int takeItem(UMLClassifierListItem* item);
-
-    virtual UMLClassifierListItemList getFilteredList(UMLObject::ObjectType ot) const;
-
-    virtual bool resolveRef();
-
-    UMLOperationList findOperations(const QString &n);
-
-    virtual UMLObject* findChildObjectById(Uml::ID::Type id, bool considerAncestors = false);
-
-    UMLOperation* findOperation(const QString& name,
-                                Model_Utils::NameAndType_List params);
-
-    UMLClassifierList findSuperClassConcepts(ClassifierType type = ALL);
-
-    UMLClassifierList findSubClassConcepts(ClassifierType type = ALL);
-
-    virtual bool acceptAssociationType(Uml::AssociationType::Enum type);
-
-    void setClassAssoc(UMLAssociation *assoc);
-    UMLAssociation *getClassAssoc() const;
-
-    void setBaseType(UMLObject::ObjectType ot);
-
-    bool isInterface() const;
-
-    bool isDatatype() const;
-
-    void setOriginType(UMLClassifier *origType);
-    UMLClassifier * originType() const;
-
-    void setIsReference(bool isRef = true);
-    bool isReference() const;
-
-    bool hasAbstractOps();
-    bool hasAssociations();
-    bool hasAttributes();
-    bool hasStaticAttributes();
-    bool hasMethods();
-    bool hasAccessorMethods();
-    bool hasOperationMethods();
-    bool hasVectorFields();
-
-    /**
-     * utility functions to allow easy determination of what classifiers
-     * are "owned" by the current one via named association type (e.g.
-     * plain, aggregate or compositions).
-     */
-//    UMLClassifierList getPlainAssocChildClassifierList();
-//    UMLClassifierList getAggregateChildClassifierList();
-//    UMLClassifierList getCompositionChildClassifierList();
-
-    virtual UMLClassifierListItem* makeChildObject(const QString& xmiTag);
-
-    virtual UMLAssociationList  getUniAssociationToBeImplemented();
-
-signals:
-
-    void operationAdded(UMLClassifierListItem *);
-    void operationRemoved(UMLClassifierListItem *);
-
-    void templateAdded(UMLClassifierListItem*);
-    void templateRemoved(UMLClassifierListItem*);
-
-    // only applies when (m_Type == ot_Class)
-    void attributeAdded(UMLClassifierListItem*);
-    void attributeRemoved(UMLClassifierListItem*);
-
-private:
-
-    UMLAssociation *m_pClassAssoc;
-
-    bool m_isRef;
-
-    /**
-     * Utility method called by "get*ChildClassfierList()" methods. It basically
-     * finds all the classifiers named in each association in the given association list
-     * which aren't the current one. Useful for finding which classifiers are "owned" by the
-     * current one via declared associations such as in aggregations/compositions.
-     */
-//    UMLClassifierList findAssocClassifierObjsInRoles (UMLAssociationList * list);
-
-protected:
-
-    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    virtual bool load(QDomElement& element);
-
-};
-
-#endif // CLASSIFIER_H
diff -Nuar umbrello-15.08.1.orig/umbrello/classifierlistitem.cpp umbrello-15.08.1/umbrello/classifierlistitem.cpp
--- umbrello-15.08.1.orig/umbrello/classifierlistitem.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/classifierlistitem.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,159 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "classifierlistitem.h"
-
-// local includes
-#include "debug_utils.h"
-#include "classifier.h"
-#include "model_utils.h"
-#include "object_factory.h"
-#include "uml.h"
-#include "umldoc.h"
-
-// kde includes
-#include <KLocalizedString>
-
-/**
- * Constructor.
- *
- * @param parent   The parent to this operation.
- *          At first sight it would appear that the type of the
- *          parent should be UMLClassifier. However, the class
- *          UMLAttribute is also used for the parameters of
- *          operations, and in this case the UMLOperation is the
- *          parent.
- * @param name    The name of the operation.
- * @param id      The id of the operation.
- */
-UMLClassifierListItem::UMLClassifierListItem(UMLObject *parent,
-                                             const QString& name, Uml::ID::Type id)
-  : UMLObject(parent, name, id)
-{
-    UMLObject *parentObj = const_cast<UMLObject*>(parent);
-    UMLClassifier *pc = dynamic_cast<UMLClassifier*>(parentObj);
-    if (pc)
-        UMLObject::setUMLPackage(pc);
-}
-
-/**
- * Constructor.
- *
- * @param parent    The parent to this operation.
- *          At first sight it would appear that the type of the
- *          parent should be UMLClassifier. However, the class
- *          UMLAttribute is also used for the parameters of
- *          operations, and in this case the UMLOperation is the
- *          parent.
- */
-UMLClassifierListItem::UMLClassifierListItem(UMLObject *parent)
-  : UMLObject(parent)
-{
-    UMLObject *parentObj = const_cast<UMLObject*>(parent);
-    UMLClassifier *pc = dynamic_cast<UMLClassifier*>(parentObj);
-    if (pc)
-        UMLObject::setUMLPackage(pc);
-}
-
-/**
- * Destructor.  Empty.
- */
-UMLClassifierListItem::~UMLClassifierListItem()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLClassifierListItem::copyInto(UMLObject *lhs) const
-{
-    // Call the parent.
-    UMLObject::copyInto(lhs);
-}
-
-/**
- * Returns a string representation of the list item.
- *
- * @param sig   What type of operation string to show.
- * @return  The string representation of the operation.
- */
-QString UMLClassifierListItem::toString(Uml::SignatureType::Enum sig)
-{
-    Q_UNUSED(sig);
-    return name();
-}
-
-/**
- * Returns the type of the UMLClassifierListItem.
- *
- * @return  The type of the UMLClassifierListItem.
- */
-UMLClassifier * UMLClassifierListItem::getType() const
-{
-    return dynamic_cast<UMLClassifier*>(m_pSecondary.data());
-}
-
-/**
- * Returns the type name of the UMLClassifierListItem.
- *
- * @return  The type name of the UMLClassifierListItem.
- */
-QString UMLClassifierListItem::getTypeName() const
-{
-    if (m_pSecondary == NULL)
-        return m_SecondaryId;
-    const UMLPackage *typePkg = m_pSecondary->umlPackage();
-    if (typePkg != NULL && typePkg != m_pUMLPackage)
-        return m_pSecondary->fullyQualifiedName();
-    return m_pSecondary->name();
-}
-
-/**
- * Sets the type of the UMLAttribute.
- *
- * @param type      Pointer to the UMLObject of the type.
- */
-void UMLClassifierListItem::setType(UMLObject *type)
-{
-    if (m_pSecondary != type) {
-        m_pSecondary = type;
-        UMLObject::emitModified();
-    }
-}
-
-/**
- * Sets the type name of the UMLClassifierListItem.
- * DEPRECATED - use setType() instead.
- *
- * @param type      The type name of the UMLClassifierListItem.
- */
-void UMLClassifierListItem::setTypeName(const QString &type)
-{
-    if (type.isEmpty() || type == QLatin1String("void")) {
-        m_pSecondary = NULL;
-        m_SecondaryId.clear();
-        return;
-    }
-    UMLDoc *pDoc = UMLApp::app()->document();
-    m_pSecondary = pDoc->findUMLObject(type);
-    if (m_pSecondary == NULL) {
-        // Make data type for easily identified cases
-        if (Model_Utils::isCommonDataType(type) || type.contains(QLatin1Char('*'))) {
-            m_pSecondary = Object_Factory::createUMLObject(UMLObject::ot_Datatype, type);
-            uDebug() << "created datatype for " << type;
-        } else {
-            m_SecondaryId = type;
-        }
-    }
-    UMLObject::emitModified();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/classifierlistitem.h umbrello-15.08.1/umbrello/classifierlistitem.h
--- umbrello-15.08.1.orig/umbrello/classifierlistitem.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/classifierlistitem.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,58 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef CLASSIFIERLISTITEM_H
-#define CLASSIFIERLISTITEM_H
-
-#include "umlobject.h"
-
-// forward declaration
-class UMLClassifier;
-
-/**
- * Classifiers (classes, interfaces) have lists of operations,
- * attributes, templates and others.  This is a base class for
- * the items in this list.  This abstraction should remove
- * duplication of dialogs and allow for stereotypes in lists.
- *
- * @short A base class for classifier list items (e.g. attributes)
- * @author Jonathan Riddell
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLClassifierListItem : public UMLObject
-{
-    Q_OBJECT
-public:
-
-    UMLClassifierListItem(UMLObject *parent,
-                          const QString& name,
-                          Uml::ID::Type id = Uml::ID::None);
-    explicit UMLClassifierListItem(UMLObject *parent);
-    virtual ~UMLClassifierListItem();
-
-    virtual void setType(UMLObject *type);
-    UMLClassifier * getType() const;
-
-    void setTypeName(const QString &type);
-    virtual QString getTypeName() const;
-
-    virtual QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    /**
-     * The abstract method UMLObject::clone() must be implemented
-     * by the classes inheriting from UMLClassifierListItem.
-     */
-    virtual UMLObject* clone() const = 0;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/CMakeLists.txt umbrello-15.08.1/umbrello/CMakeLists.txt
--- umbrello-15.08.1.orig/umbrello/CMakeLists.txt	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/CMakeLists.txt	2015-10-08 11:48:59.486089026 +0300
@@ -56,7 +56,8 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/docgenerators/
   ${CMAKE_CURRENT_SOURCE_DIR}/finder/
   ${CMAKE_CURRENT_SOURCE_DIR}/refactoring/
-  ${CMAKE_CURRENT_SOURCE_DIR}/widgets/
+  ${CMAKE_CURRENT_SOURCE_DIR}/umlmodel/
+  ${CMAKE_CURRENT_SOURCE_DIR}/umlwidgets/
   ${CMAKE_SOURCE_DIR}/lib/cppparser/
   ${CMAKE_SOURCE_DIR}/lib/interfaces/
 )
@@ -343,47 +344,47 @@
     cmds/widget/cmd_setTxt.cpp
 )

-set(libwidgets_SRCS
-    widgets/activitywidget.cpp
-    widgets/actorwidget.cpp
-    widgets/artifactwidget.cpp
-    widgets/associationline.cpp
-    widgets/associationwidget.cpp
-    widgets/boxwidget.cpp
-    widgets/categorywidget.cpp
-    widgets/classifierwidget.cpp
-    widgets/combinedfragmentwidget.cpp
-    widgets/componentwidget.cpp
-    widgets/datatypewidget.cpp
-    widgets/entitywidget.cpp
-    widgets/enumwidget.cpp
-    widgets/floatingdashlinewidget.cpp
-    widgets/floatingtextwidget.cpp
-    widgets/forkjoinwidget.cpp
-    widgets/layoutgrid.cpp
-    widgets/linkwidget.cpp
-    widgets/messagewidget.cpp
-    widgets/nodewidget.cpp
-    widgets/notewidget.cpp
-    widgets/objectnodewidget.cpp
-    widgets/objectwidget.cpp
-    widgets/packagewidget.cpp
-    widgets/pinportbase.cpp
-    widgets/pinwidget.cpp
-    widgets/portwidget.cpp
-    widgets/preconditionwidget.cpp
-    widgets/regionwidget.cpp
-    widgets/seqlinewidget.cpp
-    widgets/signalwidget.cpp
-    widgets/statewidget.cpp
-    widgets/toolbarstateonewidget.cpp
-    widgets/umlwidget.cpp
-    widgets/usecasewidget.cpp
-    widgets/widget_factory.cpp
-    widgets/widget_utils.cpp
-    widgets/widgetbase.cpp
-    widgets/widgetlist_utils.cpp
-    widgets/statusbartoolbutton.cpp
+set(libumlwidgets_SRCS
+    umlwidgets/activitywidget.cpp
+    umlwidgets/actorwidget.cpp
+    umlwidgets/artifactwidget.cpp
+    umlwidgets/associationline.cpp
+    umlwidgets/associationwidget.cpp
+    umlwidgets/boxwidget.cpp
+    umlwidgets/categorywidget.cpp
+    umlwidgets/classifierwidget.cpp
+    umlwidgets/combinedfragmentwidget.cpp
+    umlwidgets/componentwidget.cpp
+    umlwidgets/datatypewidget.cpp
+    umlwidgets/entitywidget.cpp
+    umlwidgets/enumwidget.cpp
+    umlwidgets/floatingdashlinewidget.cpp
+    umlwidgets/floatingtextwidget.cpp
+    umlwidgets/forkjoinwidget.cpp
+    umlwidgets/layoutgrid.cpp
+    umlwidgets/linkwidget.cpp
+    umlwidgets/messagewidget.cpp
+    umlwidgets/nodewidget.cpp
+    umlwidgets/notewidget.cpp
+    umlwidgets/objectnodewidget.cpp
+    umlwidgets/objectwidget.cpp
+    umlwidgets/packagewidget.cpp
+    umlwidgets/pinportbase.cpp
+    umlwidgets/pinwidget.cpp
+    umlwidgets/portwidget.cpp
+    umlwidgets/preconditionwidget.cpp
+    umlwidgets/regionwidget.cpp
+    umlwidgets/seqlinewidget.cpp
+    umlwidgets/signalwidget.cpp
+    umlwidgets/statewidget.cpp
+    umlwidgets/toolbarstateonewidget.cpp
+    umlwidgets/umlwidget.cpp
+    umlwidgets/usecasewidget.cpp
+    umlwidgets/widget_factory.cpp
+    umlwidgets/widget_utils.cpp
+    umlwidgets/widgetbase.cpp
+    umlwidgets/widgetlist_utils.cpp
+    umlwidgets/statusbartoolbutton.cpp
 )

 set(libfinder_SRCS
@@ -394,47 +395,60 @@
     finder/umlscenefinder.cpp
 )

-########### next target ###############
+set(libuml_SRCS
+    umlmodel/actor.cpp
+    umlmodel/artifact.cpp
+    umlmodel/association.cpp
+    umlmodel/attribute.cpp
+    umlmodel/category.cpp
+    umlmodel/checkconstraint.cpp
+    umlmodel/classifier.cpp
+    umlmodel/classifierlistitem.cpp
+    umlmodel/component.cpp
+    umlmodel/entity.cpp
+    umlmodel/entityattribute.cpp
+    umlmodel/entityconstraint.cpp
+    umlmodel/enum.cpp
+    umlmodel/enumliteral.cpp
+    umlmodel/folder.cpp
+    umlmodel/foreignkeyconstraint.cpp
+    umlmodel/node.cpp
+    umlmodel/operation.cpp
+    umlmodel/package.cpp
+    umlmodel/port.cpp
+    umlmodel/stereotype.cpp
+    umlmodel/template.cpp
+    umlmodel/umlattributelist.cpp
+    umlmodel/umlcanvasobject.cpp
+    umlmodel/umlclassifierlistitemlist.cpp
+    umlmodel/umlentityattributelist.cpp
+    umlmodel/umlentityconstraintlist.cpp
+    umlmodel/umlobject.cpp
+    umlmodel/umlobjectlist.cpp
+    umlmodel/umlrole.cpp
+    umlmodel/usecase.cpp
+    umlmodel/uniqueconstraint.cpp
+)

 set(umbrellobase_SRCS
-    actor.cpp
-    artifact.cpp
-    association.cpp
     assocrules.cpp
-    attribute.cpp
     basictypes.cpp
     birdview.cpp
-    category.cpp
-    checkconstraint.cpp
-    classifier.cpp
-    classifierlistitem.cpp
     cmdlineexportallviewsevent.cpp
-    component.cpp
     docwindow.cpp
     dotgenerator.cpp
-    entity.cpp
-    entityattribute.cpp
-    entityconstraint.cpp
-    enum.cpp
-    enumliteral.cpp
-    folder.cpp
-    foreignkeyconstraint.cpp
     icon_utils.cpp
     import_argo.cpp
     import_rose.cpp
     layoutgenerator.cpp
     listpopupmenu.cpp
     model_utils.cpp
-    node.cpp
     object_factory.cpp
-    operation.cpp
     optionstate.cpp
-    package.cpp
     petalnode.cpp
     petaltree2uml.cpp
-    port.cpp
-    stereotype.cpp
-    template.cpp
+    stereotypeswindow.cpp
+    stereotypesmodel.cpp
     toolbarstatearrow.cpp
     toolbarstateassociation.cpp
     toolbarstate.cpp
@@ -443,26 +457,16 @@
     toolbarstateother.cpp
     toolbarstatepool.cpp
     umlappprivate.cpp
-    umlattributelist.cpp
-    umlcanvasobject.cpp
-    umlclassifierlistitemlist.cpp
     uml.cpp
     umldoc.cpp
-    umlentityattributelist.cpp
-    umlentityconstraintlist.cpp
     umllistview.cpp
     umllistviewitem.cpp
-    umlobject.cpp
-    umlobjectlist.cpp
-    umlrole.cpp
     umlscene.cpp
     umlview.cpp
     umlviewimageexporterall.cpp
     umlviewimageexporter.cpp
     umlviewimageexportermodel.cpp
-    uniqueconstraint.cpp
     uniqueid.cpp
-    usecase.cpp
     worktoolbar.cpp
 )

@@ -482,7 +486,8 @@
     ${libcodegenerator_SRCS}
     ${libdocgenerator_SRCS}
     ${libcmds_SRCS}
-    ${libwidgets_SRCS}
+    ${libuml_SRCS}
+    ${libumlwidgets_SRCS}
     ${umbrellobase_SRCS}
 )

diff -Nuar umbrello-15.08.1.orig/umbrello/component.cpp umbrello-15.08.1/umbrello/component.cpp
--- umbrello-15.08.1.orig/umbrello/component.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/component.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,127 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "component.h"
-// app includes
-#include "association.h"
-#include "debug_utils.h"
-#include "object_factory.h"
-#include "model_utils.h"
-#include "clipboard/idchangelog.h"
-#include "umldoc.h"
-// kde includes
-#include <KLocalizedString>
-
-/**
- * Sets up a Component.
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLComponent::UMLComponent(const QString & name, Uml::ID::Type id)
-  : UMLPackage(name, id),
-    m_executable(false)
-{
-    m_BaseType = UMLObject::ot_Component;
-}
-
-/**
- * Destructor.
- */
-UMLComponent::~UMLComponent()
-{
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLComponent::clone() const
-{
-    UMLComponent *clone = new UMLComponent();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the UML:Component element including its operations,
- * attributes and templates
- */
-void UMLComponent::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement componentElement = UMLObject::save(QLatin1String("UML:Component"), qDoc);
-    componentElement.setAttribute(QLatin1String("executable"), m_executable);
-    // Save contained components if any.
-    if (m_objects.count()) {
-        QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
-        for (UMLObjectListIt objectsIt(m_objects); objectsIt.hasNext();) {
-            UMLObject* obj = objectsIt.next();
-            uIgnoreZeroPointer(obj);
-            obj->saveToXMI (qDoc, ownedElement);
-        }
-        componentElement.appendChild(ownedElement);
-    }
-    qElement.appendChild(componentElement);
-}
-
-/**
- * Loads the UML:Component element including its ports et al.
- */
-bool UMLComponent::load(QDomElement& element)
-{
-    QString executable = element.attribute(QLatin1String("executable"), QLatin1String("0"));
-    m_executable = (bool)executable.toInt();
-    for (QDomNode node = element.firstChild(); !node.isNull();
-            node = node.nextSibling()) {
-        if (node.isComment())
-            continue;
-        QDomElement tempElement = node.toElement();
-        QString type = tempElement.tagName();
-        if (Model_Utils::isCommonXMIAttribute(type))
-            continue;
-        if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
-                UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
-            //CHECK: Umbrello currently assumes that nested elements
-            // are ownedElements anyway.
-            // Therefore these tags are not further interpreted.
-            if (! load(tempElement))
-                return false;
-            continue;
-        }
-        UMLObject *pObject = Object_Factory::makeObjectFromXMI(type);
-        if (!pObject) {
-            uWarning() << "Unknown type of umlobject to create: " << type;
-            continue;
-        }
-        pObject->setUMLPackage(this);
-        if (pObject->loadFromXMI(tempElement)) {
-            addObject(pObject);
-        } else {
-            delete pObject;
-        }
-    }
-    return true;
-}
-
-/**
- * Sets m_executable.
- */
-void UMLComponent::setExecutable(bool executable)
-{
-    m_executable = executable;
-}
-
-/**
- * Returns the value of m_executable.
- */
-bool UMLComponent::getExecutable()
-{
-    return m_executable;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/component.h umbrello-15.08.1/umbrello/component.h
--- umbrello-15.08.1.orig/umbrello/component.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/component.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,48 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef COMPONENT_H
-#define COMPONENT_H
-
-#include "package.h"
-
-/**
- * This class contains the non-graphical information required for a
- * UML Component.
- * This class inherits from @ref UMLPackage which contains most
- * of the information.
- *
- * @short Non-graphical information for a Component.
- * @author Jonathan Riddell
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLComponent : public UMLPackage
-{
-    Q_OBJECT
-public:
-    explicit UMLComponent(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLComponent();
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    void setExecutable(bool executable);
-    bool getExecutable();
-
-protected:
-    bool load(QDomElement & element);
-
-private:
-    bool m_executable;  ///< holds whether this is an executable component or not
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/dialogs/notedialog.cpp umbrello-15.08.1/umbrello/dialogs/notedialog.cpp
--- umbrello-15.08.1.orig/umbrello/dialogs/notedialog.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/dialogs/notedialog.cpp	2015-10-08 11:48:59.497089026 +0300
@@ -36,6 +36,7 @@
     QVBoxLayout *layout = new QVBoxLayout(frame);
     layout->addWidget(m_docWidget, 10);
     setMinimumSize(600, 250);
+    m_docWidget->setFocus();
 }

 /**
diff -Nuar umbrello-15.08.1.orig/umbrello/dialogs/widgets/documentationwidget.cpp umbrello-15.08.1/umbrello/dialogs/widgets/documentationwidget.cpp
--- umbrello-15.08.1.orig/umbrello/dialogs/widgets/documentationwidget.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/dialogs/widgets/documentationwidget.cpp	2015-10-08 11:48:59.499089026 +0300
@@ -67,6 +67,8 @@
     m_editField->setLineWrapMode(QTextEdit::WidgetWidth);
     m_editField->setWordWrapMode(QTextOption::WordWrap);
     m_editField->setText(text);
+    setFocusProxy(m_editField);
+
     QHBoxLayout *layout = new QHBoxLayout(m_box);
     layout->addWidget(m_editField);
     layout->setMargin(fontMetrics().height());
diff -Nuar umbrello-15.08.1.orig/umbrello/docwindow.cpp umbrello-15.08.1/umbrello/docwindow.cpp
--- umbrello-15.08.1.orig/umbrello/docwindow.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/docwindow.cpp	2015-10-08 11:48:59.499089026 +0300
@@ -91,6 +91,7 @@
     statusLayout->addWidget(m_modifiedWidget, 0, 5, 1, 1);
     m_docTE = new KTextEdit(this);
     m_docTE->setText(QString());
+    setFocusProxy(m_docTE);
     //m_docTE->setWordWrapMode(QTextEdit::WidgetWidth);
     QVBoxLayout* docLayout = new QVBoxLayout(this);
     docLayout->addLayout(statusLayout);
@@ -461,5 +462,6 @@
                 tab->setCurrentIndex(i);
         }
     }
+    m_docTE->setFocus();
 }

diff -Nuar umbrello-15.08.1.orig/umbrello/entityattribute.cpp umbrello-15.08.1/umbrello/entityattribute.cpp
--- umbrello-15.08.1.orig/umbrello/entityattribute.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/entityattribute.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,280 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "entityattribute.h"
-
-// app includes
-#include "debug_utils.h"
-//#include "umlcanvasobject.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "umlentityattributedialog.h"
-#include "object_factory.h"
-
-// qt includes
-#include <QRegExp>
-
-/**
- * Sets up an entityattribute.
- * @param parent    The parent of this UMLEntityAttribute.
- * @param name      The name of this UMLEntityAttribute.
- * @param id        The unique id given to this UMLEntityAttribute.
- * @param s         The visibility of the UMLEntityAttribute.
- * @param type      The type of this UMLEntityAttribute.
- * @param iv        The initial value of the entityattribute.
- */
-UMLEntityAttribute::UMLEntityAttribute(UMLObject *parent, const QString& name,
-                                        Uml::ID::Type id, Uml::Visibility::Enum s,
-                                        UMLObject *type, const QString& iv)
-  : UMLAttribute(parent, name, id, s, type, iv)
-{
-    init();
-    if (m_pSecondary) {
-        m_pSecondary->setBaseType(UMLObject::ot_Entity);
-    }
-}
-
-/**
- * Sets up an entityattribute.
- * @param parent    The parent of this UMLEntityAttribute.
- */
-UMLEntityAttribute::UMLEntityAttribute(UMLObject *parent)
- : UMLAttribute(parent)
-{
-    init();
-}
-
-/**
- * Destructor.
- */
-UMLEntityAttribute::~UMLEntityAttribute()
-{
-}
-
-/**
- * Initialize members of this class.
- * Auxiliary method used by constructors.
- */
-void UMLEntityAttribute::init()
-{
-    m_BaseType = UMLObject::ot_EntityAttribute;
-    m_indexType = UMLEntityAttribute::None;
-    m_autoIncrement = false;
-    m_null = false;
-}
-
-/**
- * Returns the value of the UMLEntityAttribute's attributes property.
- * @return  The value of the UMLEntityAttribute's attributes property.
- */
-QString UMLEntityAttribute::getAttributes() const
-{
-    return m_attributes;
-}
-
-/**
- * Sets the UMLEntityAttribute's attributes property.
- * @param attributes  The new value for the attributes property.
- */
-void UMLEntityAttribute::setAttributes(const QString& attributes)
-{
-    m_attributes = attributes;
-}
-
-/**
- * Returns the UMLEntityAttribute's length/values property.
- * @return  The new value of the length/values property.
- */
-QString UMLEntityAttribute::getValues() const
-{
-    return m_values;
-}
-
-/**
- * Sets the UMLEntityAttribute's length/values property.
- * @param values    The new value of the length/values property.
- */
-void UMLEntityAttribute::setValues(const QString& values)
-{
-    m_values = values;
-}
-
-/**
- * Returns the UMLEntityAttribute's auto_increment boolean
- * @return  The UMLEntityAttribute's auto_increment boolean
- */
-bool UMLEntityAttribute::getAutoIncrement() const
-{
-    return m_autoIncrement;
-}
-
-/**
- * Sets the UMLEntityAttribute's auto_increment boolean
- * @param autoIncrement  The UMLEntityAttribute's auto_increment boolean
- */
-void UMLEntityAttribute::setAutoIncrement(const bool autoIncrement)
-{
-    m_autoIncrement = autoIncrement;
-}
-
-/**
- * Returns the UMLEntityAttribute's index type property.
- * @return  The value of the UMLEntityAttribute's index type property.
- */
-UMLEntityAttribute::DBIndex_Type UMLEntityAttribute::indexType() const
-{
-    return m_indexType;
-}
-
-/**
- * Sets the initial value of the UMLEntityAttribute's index type property.
- * @param indexType  The initial value of the UMLEntityAttribute's index type property.
- */
-void UMLEntityAttribute::setIndexType(const UMLEntityAttribute::DBIndex_Type indexType)
-{
-    m_indexType = indexType;
-}
-
-/**
- * Returns the UMLEntityAttribute's allow null value.
- * @return  The UMLEntityAttribute's allow null value.
- */
-bool UMLEntityAttribute::getNull() const
-{
-    return m_null;
-}
-
-/**
- * Sets the initial value of the UMLEntityAttribute's allow null value.
- * @param nullIn   The initial value of the UMLEntityAttribute's allow null value.
- */
-void UMLEntityAttribute::setNull(const bool nullIn)
-{
-    m_null = nullIn;
-}
-
-/**
- * Returns a string representation of the UMLEntityAttribute.
- * @param sig   If true will show the entityattribute type and initial value.
- * @return  Returns a string representation of the UMLEntityAttribute.
- */
-QString UMLEntityAttribute::toString(Uml::SignatureType::Enum sig)
-{
-    QString s;
-    //FIXME
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::NoSig) {
-        s = Uml::Visibility::toString(m_visibility, true) + QLatin1Char(' ');
-    }
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
-        QString string = s + name() + QLatin1String(" : ") + getTypeName();
-        if(m_InitialValue.length() > 0)
-            string += QLatin1String(" = ") + m_InitialValue;
-        return string;
-    } else
-        return s + name();
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLEntityAttribute::operator==(const UMLEntityAttribute &rhs) const
-{
-    if(this == &rhs)
-        return true;
-
-    if(!UMLObject::operator==(rhs))
-        return false;
-
-    // The type name is the only distinguishing criterion.
-    // (Some programming languages might support more, but others don't.)
-    if (m_pSecondary != rhs.m_pSecondary)
-        return false;
-
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the UMLEntityAttribute
- * object.
- */
-void UMLEntityAttribute::copyInto(UMLObject *lhs) const
-{
-    UMLEntityAttribute *target = static_cast<UMLEntityAttribute*>(lhs);
-
-    // call the parent first.
-    UMLClassifierListItem::copyInto(target);
-
-    // Copy all datamembers
-    target->m_pSecondary = m_pSecondary;
-    target->m_SecondaryId = m_SecondaryId;
-    target->m_InitialValue = m_InitialValue;
-    target->m_ParmKind = m_ParmKind;
-}
-
-/**
- * Make a clone of the UMLEntityAttribute.
- */
-UMLObject* UMLEntityAttribute::clone() const
-{
-    UMLEntityAttribute* clone = new UMLEntityAttribute((UMLEntityAttribute*)parent());
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Creates the <UML:EntityAttribute> XMI element.
- */
-void UMLEntityAttribute::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement entityattributeElement = UMLObject::save(QLatin1String("UML:EntityAttribute"), qDoc);
-    if (m_pSecondary == NULL) {
-        uDebug() << name() << ": m_pSecondary is NULL, using local name " << m_SecondaryId;
-        entityattributeElement.setAttribute(QLatin1String("type"), m_SecondaryId);
-    } else {
-        entityattributeElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
-    }
-    entityattributeElement.setAttribute(QLatin1String("initialValue"), m_InitialValue);
-    entityattributeElement.setAttribute(QLatin1String("dbindex_type"), m_indexType);
-    entityattributeElement.setAttribute(QLatin1String("values"), m_values);
-    entityattributeElement.setAttribute(QLatin1String("attributes"), m_attributes);
-    entityattributeElement.setAttribute(QLatin1String("auto_increment"), m_autoIncrement);
-    entityattributeElement.setAttribute(QLatin1String("allow_null"), m_null);
-    qElement.appendChild(entityattributeElement);
-}
-
-/**
- * Loads the <UML:EntityAttribute> XMI element.
- */
-bool UMLEntityAttribute::load(QDomElement & element)
-{
-    if (! UMLAttribute::load(element))
-        return false;
-    int indexType = element.attribute(QLatin1String("dbindex_type"), QLatin1String("1100")).toInt();
-    m_indexType = (UMLEntityAttribute::DBIndex_Type)indexType;
-    m_values = element.attribute(QLatin1String("values"));
-    m_attributes = element.attribute(QLatin1String("attributes"));
-    m_autoIncrement = (bool)element.attribute(QLatin1String("auto_increment")).toInt();
-    m_null = (bool)element.attribute(QLatin1String("allow_null")).toInt();
-    return true;
-}
-
-/**
- * Display the properties configuration dialog for the entityattribute.
- */
-bool UMLEntityAttribute::showPropertiesDialog(QWidget* parent)
-{
-    UMLEntityAttributeDialog dialog(parent, this);
-    return dialog.exec();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/entityattribute.h umbrello-15.08.1/umbrello/entityattribute.h
--- umbrello-15.08.1.orig/umbrello/entityattribute.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/entityattribute.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,85 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ENTITYATTRIBUTE_H
-#define ENTITYATTRIBUTE_H
-
-#include "attribute.h"
-#include "basictypes.h"
-
-/**
- * This class is used to set up information for an entityattribute.  This is a database field
- * It has a type, name, index type and default value.
- *
- * @short Sets up entityattribute information.
- * @author Jonathan Riddell <jr@jriddell.org>
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLEntityAttribute : public UMLAttribute
-{
-    Q_OBJECT
-    Q_ENUMS(DBIndex_Type)
-public:
-    enum DBIndex_Type
-    {
-        None  =  1100,
-        Primary,
-        Index,
-        Unique
-    };
-
-    UMLEntityAttribute(UMLObject* parent, const QString& name,
-                       Uml::ID::Type id = Uml::ID::None,
-                       Uml::Visibility::Enum s = Uml::Visibility::Private,
-                       UMLObject *type = 0, const QString& iv = QString());
-    explicit UMLEntityAttribute(UMLObject* parent);
-    virtual ~UMLEntityAttribute();
-
-    bool operator==(const UMLEntityAttribute& rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    void setAttributes(const QString& attributes);
-    QString getAttributes() const;
-
-    void setIndexType(const DBIndex_Type indexType);
-    DBIndex_Type indexType() const;
-
-    void setValues(const QString& values);
-    QString getValues() const;
-
-    void setAutoIncrement(const bool autoIncrement);
-    bool getAutoIncrement() const;
-
-    void setNull(const bool null);
-    bool getNull() const;
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-protected:
-    void init();
-
-    bool load(QDomElement& element);
-
-private:
-    DBIndex_Type   m_indexType;
-    QString        m_values;
-    QString        m_attributes;
-    bool           m_autoIncrement;
-    bool           m_null;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/entityconstraint.cpp umbrello-15.08.1/umbrello/entityconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/entityconstraint.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/entityconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,76 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-//own header
-#include "entityconstraint.h"
-
-// app includes
-#include "umlobject.h"
-#include "umldoc.h"
-#include "uml.h"
-
-// qt includes
-#include <QRegExp>
-
-/**
- * Sets up a constraint.
- * @param parent    The parent of this UMLEntityConstraint.
- * @param name      The name of this UMLEntityConstraint.
- * @param id        The unique id given to this UMLEntityConstraint.
- */
-UMLEntityConstraint::UMLEntityConstraint(UMLObject *parent,
-    const QString& name, Uml::ID::Type id)
-  : UMLClassifierListItem(parent, name, id)
-{
-    m_BaseType = UMLObject::ot_EntityConstraint;
-}
-
-/**
- * Sets up a constraint.
- * @param parent    The parent of this UMLEntityConstraint.
- */
-UMLEntityConstraint::UMLEntityConstraint(UMLObject *parent)
-  : UMLClassifierListItem(parent)
-{
-    m_BaseType = UMLObject::ot_EntityConstraint;
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLEntityConstraint::operator==(const UMLEntityConstraint &rhs) const
-{
-    if(this == &rhs)
-        return true;
-
-    if(!UMLObject::operator==(rhs))
-        return false;
-
-    return true;
-}
-
-/**
- * destructor.
- */
-UMLEntityConstraint::~UMLEntityConstraint()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the UMLEntityConstraint
- * object.
- */
-void UMLEntityConstraint::copyInto(UMLObject *lhs) const
-{
-    // call the parent first.
-    UMLClassifierListItem::copyInto(lhs);
-}
-
-
diff -Nuar umbrello-15.08.1.orig/umbrello/entityconstraint.h umbrello-15.08.1/umbrello/entityconstraint.h
--- umbrello-15.08.1.orig/umbrello/entityconstraint.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/entityconstraint.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,49 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ENTITYCONSTRAINT_H
-#define ENTITYCONSTRAINT_H
-
-#include "basictypes.h"
-#include "classifierlistitem.h"
-#include "umlclassifierlist.h"
-
-/**
- * This class is used to set up information for a entity constraint.
- *
- * @short Sets up entity constraint information.
- * @author Sharan Rao
- * @see UMLObject UMLClassifierListItem
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLEntityConstraint : public UMLClassifierListItem
-{
-     Q_OBJECT
-
-public:
-    UMLEntityConstraint(UMLObject *parent, const QString& name,
-                        Uml::ID::Type id = Uml::ID::None);
-
-    explicit UMLEntityConstraint(UMLObject *parent);
-
-    bool operator==(const UMLEntityConstraint &rhs) const;
-
-    virtual ~UMLEntityConstraint();
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    /**
-     * Make a clone of the UMLEntityConstraint.
-     */
-    virtual UMLObject* clone() const = 0;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/entity.cpp umbrello-15.08.1/umbrello/entity.cpp
--- umbrello-15.08.1.orig/umbrello/entity.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/entity.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,719 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "entity.h"
-
-// app includes
-#include "debug_utils.h"
-#include "entityattribute.h"
-#include "uniqueconstraint.h"
-#include "foreignkeyconstraint.h"
-#include "checkconstraint.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "uniqueid.h"
-#include "umlentityattributelist.h"
-#include "umlentityconstraintlist.h"
-#include "idchangelog.h"
-#include "umlentityattributedialog.h"
-#include "umluniqueconstraintdialog.h"
-#include "umlforeignkeyconstraintdialog.h"
-#include "umlcheckconstraintdialog.h"
-
-// kde includes
-#include <KLocalizedString>
-#include <KMessageBox>
-
-// qt includes
-#include <QPointer>
-
-/**
- * Constructor.
- */
-UMLEntity::UMLEntity(const QString& name, Uml::ID::Type id)
-  : UMLClassifier(name, id),
-    m_PrimaryKey(0)
-{
-    m_BaseType = UMLObject::ot_Entity;
-    connect(this, SIGNAL(entityAttributeRemoved(UMLClassifierListItem*)),
-            this, SLOT(slotEntityAttributeRemoved(UMLClassifierListItem*)));
-}
-
-/**
- * Standard destructor.
- */
-UMLEntity::~UMLEntity()
-{
-    m_List.clear();
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLEntity::operator==(const UMLEntity& rhs) const
-{
-    return UMLClassifier::operator==(rhs);
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLEntity::copyInto(UMLObject *lhs) const
-{
-    UMLEntity *target = static_cast<UMLEntity*>(lhs);
-
-    // call base class copy function
-    UMLClassifier::copyInto(target);
-
-    // copy local data items
-    target->m_PrimaryKey = m_PrimaryKey;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLEntity::clone() const
-{
-    UMLEntity* clone = new UMLEntity();
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Create an UMLAttribute.
- * @param name   an optional name for the attribute
- * @param type   an optional type object for the attribute
- * @param vis    the visibility of the attribute
- * @param iv     the initial value for the attribute
- * @return   the just created attribute or null
- */
-UMLAttribute* UMLEntity::createAttribute(const QString &name /*= QString()*/, UMLObject *type /*= 0*/,
-                                         Uml::Visibility::Enum vis /* = Uml::Visibility::Private*/,
-                                         const QString& iv /* = QString()*/)
-{
-    Uml::ID::Type id = UniqueID::gen();
-    QString currentName;
-    if (name.isNull())  {
-        currentName = uniqChildName(UMLObject::ot_EntityAttribute);
-    } else {
-        currentName = name;
-    }
-
-    UMLEntityAttribute* newAttribute = new UMLEntityAttribute(this, currentName, id, vis, type, iv);
-
-    int button = QDialog::Accepted;
-    bool goodName = false;
-
-    //check for name.isNull() stops dialog being shown
-    //when creating attribute via list view
-    while (button == QDialog::Accepted && !goodName && name.isNull()) {
-        QPointer<UMLEntityAttributeDialog> dialog = new UMLEntityAttributeDialog(0, newAttribute);
-        button = dialog->exec();
-        QString name = newAttribute->name();
-
-        if (name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        } else if (findChildObject(name) != NULL) {
-            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
-        } else {
-            goodName = true;
-        }
-        delete dialog;
-    }
-
-    if (button != QDialog::Accepted) {
-        delete newAttribute;
-        return 0;
-    }
-
-    addEntityAttribute(newAttribute);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newAttribute);
-    return newAttribute;
-}
-
-/**
- * Creates a Unique Constraint for this Entity.
- * @param name   an optional name
- * @return the UniqueConstraint created
- */
-UMLUniqueConstraint* UMLEntity::createUniqueConstraint(const QString &name)
-{
-    Uml::ID::Type id = UniqueID::gen();
-    QString currentName;
-    if (name.isNull())  {
-
-        /**
-         *  @todo check parameter
-         */
-        currentName = uniqChildName(UMLObject::ot_UniqueConstraint);
-    } else {
-        currentName = name;
-    }
-
-    UMLUniqueConstraint* newUniqueConstraint = new UMLUniqueConstraint(this, currentName, id);
-
-    int button = QDialog::Accepted;
-    bool goodName = false;
-
-    //check for name.isNull() stops dialog being shown
-    //when creating attribute via list view
-    while (button == QDialog::Accepted && !goodName && name.isNull()) {
-        QPointer<UMLUniqueConstraintDialog> dialog = new UMLUniqueConstraintDialog(0, newUniqueConstraint);
-        button = dialog->exec();
-        QString name = newUniqueConstraint->name();
-
-        if (name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        } else if (findChildObject(name) != NULL) {
-            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
-        } else {
-            goodName = true;
-        }
-        delete dialog;
-    }
-
-    if (button != QDialog::Accepted) {
-        delete newUniqueConstraint;
-        return NULL;
-    }
-
-    addConstraint(newUniqueConstraint);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newUniqueConstraint);
-    emitModified();
-    return newUniqueConstraint;
-}
-
-/**
- * Creates a Foreign Key  Constraint for this Entity.
- * @param name   an optional name
- * @return the ForeignKeyConstraint created
- */
-UMLForeignKeyConstraint* UMLEntity::createForeignKeyConstraint(const QString &name)
-{
-    Uml::ID::Type id = UniqueID::gen();
-    QString currentName;
-    if (name.isNull())  {
-        currentName = uniqChildName(UMLObject::ot_ForeignKeyConstraint);
-    } else {
-        currentName = name;
-    }
-
-    UMLForeignKeyConstraint* newForeignKeyConstraint = new UMLForeignKeyConstraint(this, currentName, id);
-
-    int button = QDialog::Accepted;
-    bool goodName = false;
-
-    //check for name.isNull() stops dialog being shown
-    //when creating attribute via list view
-    while (button == QDialog::Accepted && !goodName && name.isNull()) {
-        QPointer<UMLForeignKeyConstraintDialog> dialog = new UMLForeignKeyConstraintDialog(0, newForeignKeyConstraint);
-        button = dialog->exec();
-        QString name = newForeignKeyConstraint->name();
-
-        if (name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        } else if (findChildObject(name) != NULL) {
-            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
-        } else {
-            goodName = true;
-        }
-        delete dialog;
-    }
-
-    if (button != QDialog::Accepted) {
-        return NULL;
-    }
-
-    addConstraint(newForeignKeyConstraint);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newForeignKeyConstraint);
-    emitModified();
-    return newForeignKeyConstraint;
-}
-
-/**
- * Creates a Check  Constraint for this Entity.
- * @param name   an optional name
- * @return the CheckConstraint created
- */
-UMLCheckConstraint* UMLEntity::createCheckConstraint(const QString &name)
-{
-    Uml::ID::Type id = UniqueID::gen();
-    QString currentName;
-    if (name.isNull())  {
-        currentName = uniqChildName(UMLObject::ot_CheckConstraint);
-    } else {
-        currentName = name;
-    }
-
-    UMLCheckConstraint* newCheckConstraint = new UMLCheckConstraint(this, currentName, id);
-
-    int button = QDialog::Accepted;
-    bool goodName = false;
-
-    //check for name.isNull() stops dialog being shown
-    //when creating attribute via list view
-    while (button == QDialog::Accepted && !goodName && name.isNull()) {
-        QPointer<UMLCheckConstraintDialog> dialog = new UMLCheckConstraintDialog(0, newCheckConstraint);
-        button = dialog->exec();
-        QString name = newCheckConstraint->name();
-
-        if (name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        } else if (findChildObject(name) != NULL) {
-            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
-        } else {
-            goodName = true;
-        }
-        delete dialog;
-    }
-
-    if (button != QDialog::Accepted) {
-        return NULL;
-    }
-
-    addConstraint(newCheckConstraint);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newCheckConstraint);
-    emitModified();
-    return newCheckConstraint;
-}
-
-/**
- * Adds an entityAttribute.
- * The entityAttribute object must not belong to any other concept.
- * @param name   name of the UMLEntityAttribute
- * @param id     id of the UMLEntityAttribute
- * @return  True if the entityAttribute was successfully added.
- */
-UMLObject* UMLEntity::addEntityAttribute(const QString& name, Uml::ID::Type id)
-{
-    UMLEntityAttribute* literal = new UMLEntityAttribute(this, name, id);
-    m_List.append(literal);
-    emit entityAttributeAdded(literal);
-    UMLObject::emitModified();
-    connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
-    return literal;
-}
-
-/**
- * Adds an already created entityAttribute.
- * The entityAttribute object must not belong to any other concept.
- * @param att   Pointer to the UMLEntityAttribute.
- * @param log   Pointer to the IDChangeLog.
- * @return  True if the entityAttribute was successfully added.
- */
-bool UMLEntity::addEntityAttribute(UMLEntityAttribute* att, IDChangeLog* log /* = 0*/)
-{
-    QString name = (QString)att->name();
-    if (findChildObject(name) == NULL) {
-        att->setParent(this);
-        m_List.append(att);
-        emit entityAttributeAdded(att);
-        UMLObject::emitModified();
-        connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    } else if (log) {
-        log->removeChangeByNewID(att->id());
-        delete att;
-    }
-    return false;
-}
-
-/**
- * Adds an entityAttribute to the entity, at the given position.
- * If position is negative or too large, the entityAttribute is added
- * to the end of the list.
- * TODO:  give default value -1 to position (append) - now it conflicts with the method above..
- * @param att       Pointer to the UMLEntityAttribute.
- * @param position  Position index for the insertion.
- * @return  True if the entityAttribute was successfully added.
- */
-bool UMLEntity::addEntityAttribute(UMLEntityAttribute* att, int position)
-{
-    Q_ASSERT(att);
-    QString name = (QString)att->name();
-    if (findChildObject(name) == NULL) {
-        att->setParent(this);
-        if (position >= 0 && position <= (int)m_List.count())  {
-            m_List.insert(position, att);
-        } else {
-            m_List.append(att);
-        }
-        emit entityAttributeAdded(att);
-        UMLObject::emitModified();
-        connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    }
-    return false;
-}
-
-/**
- * Removes an entityAttribute from the class.
- * @param att   The entityAttribute to remove.
- * @return  Count of the remaining entityAttributes after removal.
- *          Returns -1 if the given entityAttribute was not found.
- */
-int UMLEntity::removeEntityAttribute(UMLClassifierListItem* att)
-{
-    if (!m_List.removeAll((UMLEntityAttribute*)att)) {
-        uDebug() << "cannot find att given in list";
-        return -1;
-    }
-    emit entityAttributeRemoved(att);
-    UMLObject::emitModified();
-    // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
-    // for us by QObject. -b.t.
-    // disconnect(att, SIGNAL(modified()), this, SIGNAL(modified()));
-    delete att;
-    return m_List.count();
-}
-
-/**
- * Returns the number of entityAttributes for the class.
- * @return  The number of entityAttributes for the class.
- */
-int UMLEntity::entityAttributes()
-{
-    UMLClassifierListItemList entityAttributes = getFilteredList(UMLObject::ot_EntityAttribute);
-    return entityAttributes.count();
-}
-
-/**
- * Emit the entityAttributeRemoved signal.
- */
-void UMLEntity::signalEntityAttributeRemoved(UMLClassifierListItem *eattr)
-{
-    emit entityAttributeRemoved(eattr);
-}
-
-/**
- * Resolve the types referenced by our UMLEntityAttributes.
- * Reimplements the method from UMLClassifier.
- */
-bool UMLEntity::resolveRef()
-{
-    bool success = UMLClassifier::resolveRef();
-    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
-        UMLObject* obj = oit.next();
-        if (obj->resolveRef()) {
-            UMLClassifierListItem *cli = static_cast<UMLClassifierListItem*>(obj);
-            switch (cli->baseType()) {
-                case UMLObject::ot_EntityAttribute:
-                    emit entityAttributeAdded(cli);
-                    break;
-                case UMLObject::ot_UniqueConstraint:
-                case UMLObject::ot_ForeignKeyConstraint:
-                    emit entityConstraintAdded(cli);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-    return success;
-}
-
-/**
- * Creates the <UML:Entity> element including its entityliterals.
- */
-void UMLEntity::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement entityElement = UMLObject::save(QLatin1String("UML:Entity"), qDoc);
-    //save operations
-    UMLClassifierListItemList entityAttributes = getFilteredList(UMLObject::ot_EntityAttribute);
-    UMLClassifierListItem* pEntityAttribute = 0;
-    foreach (pEntityAttribute, entityAttributes) {
-        pEntityAttribute->saveToXMI(qDoc, entityElement);
-    }
-
-    UMLClassifierListItemList entityConstraints = getFilteredList(UMLObject::ot_EntityConstraint);
-    foreach(UMLClassifierListItem* cli, entityConstraints) {
-        cli->saveToXMI(qDoc, entityElement);
-    }
-
-    qElement.appendChild(entityElement);
-}
-
-/**
- * Loads the <UML:Entity> element including its entityAttributes.
- */
-bool UMLEntity::load(QDomElement& element)
-{
-    QDomNode node = element.firstChild();
-    while(!node.isNull()) {
-        if (node.isComment()) {
-            node = node.nextSibling();
-            continue;
-        }
-        QDomElement tempElement = node.toElement();
-        QString tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("EntityAttribute"))) {   // for backward compatibility
-            UMLEntityAttribute* pEntityAttribute = new UMLEntityAttribute(this);
-            if(!pEntityAttribute->loadFromXMI(tempElement)) {
-                return false;
-            }
-            m_List.append(pEntityAttribute);
-        } else if (UMLDoc::tagEq(tag, QLatin1String("UniqueConstraint"))) {
-            UMLUniqueConstraint* pUniqueConstraint = new UMLUniqueConstraint(this);
-            if (!pUniqueConstraint->loadFromXMI(tempElement)) {
-                return false;
-            }
-            addConstraint(pUniqueConstraint);
-        } else if (UMLDoc::tagEq(tag, QLatin1String("ForeignKeyConstraint"))) {
-            UMLForeignKeyConstraint* pForeignKeyConstraint = new UMLForeignKeyConstraint(this);
-            if (!pForeignKeyConstraint->loadFromXMI(tempElement)) {
-                return false;
-            }
-
-            addConstraint(pForeignKeyConstraint);
-        } else if (UMLDoc::tagEq(tag, QLatin1String("CheckConstraint"))) {
-
-            UMLCheckConstraint* pCheckConstraint = new UMLCheckConstraint(this);
-            if (!pCheckConstraint->loadFromXMI(tempElement)) {
-                return false;
-            }
-
-            addConstraint(pCheckConstraint);
-        } else if (tag == QLatin1String("stereotype")) {
-            uDebug() << name() << ": losing old-format stereotype.";
-        } else {
-            uWarning() << "unknown child type in UMLEntity::load";
-        }
-        node = node.nextSibling();
-    }//end while
-    return true;
-}
-
-/**
- * Sets the UniqueConstraint passed as the Primary Key of this Entity
- * If the UniqueConstraint exists, then it is made a primary key
- * Else the UniqueConstraint is added and set as PrimaryKey
- * @param uconstr The Unique Constraint that is  to be set as Primary Key
- * @return true if Primary key could be set successfully
- */
-bool UMLEntity::setAsPrimaryKey(UMLUniqueConstraint* uconstr)
-{
-    if (uconstr == NULL) {
-        uDebug() << "NULL value passed. To unset a Primary Key use "
-                 << "unsetPrimaryKey()";
-        return false;
-    }
-
-    if (static_cast<UMLEntity*>(uconstr->parent()) != this) {
-
-        uDebug() << "Parent of " << uconstr->name()
-                 << " does not match with current entity";
-        return false;
-    }
-
-    // check if this constraint already exists as a unique constraint for this entity
-    UMLUniqueConstraint* uuc = static_cast<UMLUniqueConstraint*>(findChildObjectById(uconstr->id()));
-    if (uuc == NULL) {
-        addConstraint(uconstr);
-        uuc = uconstr;
-    }
-
-    UMLUniqueConstraint* oldPrimaryKey = m_PrimaryKey;
-
-    m_PrimaryKey = uuc;
-
-    if (oldPrimaryKey != NULL)
-        oldPrimaryKey->emitModified();
-
-    uuc->emitModified();
-    emitModified();
-    return true;
-}
-
-/**
- * Unset a Primary Key Constraint if it exists, else does nothing
- * This function will make the primary key into just another UniqueConstraint
- * if it exists
- */
-void UMLEntity::unsetPrimaryKey()
-{
-    m_PrimaryKey = 0;
-}
-
-/**
- * Checks if This UMLEntity has a primary key set.
- * @return true if a Primary Key Exists for this UMLEntity
- */
-bool UMLEntity::hasPrimaryKey() const
-{
-    if (m_PrimaryKey) {
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * Adds a Constraint to this UMLEntity.
- * To set a UMLUniqueConstraint as Primary Key use setAsPrimaryKey.
- * @param constr The UMLEntityConstraint that is to be added
- * @return true if the constraint could be added successfully
- */
-bool UMLEntity::addConstraint(UMLEntityConstraint* constr)
-{
-    if (findChildObjectById(constr->id()) != NULL) {
-        uDebug() << "Constraint with id " << Uml::ID::toString(constr->id())
-                 << " already exists ";
-        return false;
-    }
-
-    m_List.append(constr);
-
-    emit entityConstraintAdded(constr);
-    UMLObject::emitModified();
-    connect(constr, SIGNAL(modified()), this, SIGNAL(modified()));
-
-    return true;
-}
-
-/**
- * Removes an existing constraint from this UMLEntity.
- * If the Contraint is a Primary Key, this Entity will no longer have a PrimaryKey.
- * @param constr   the constraint to be removed
- * @return true if the constraint could be removed successfully
- */
-bool UMLEntity::removeConstraint(UMLEntityConstraint* constr)
-{
-     if (findChildObjectById(constr->id()) == NULL) {
-        uDebug() << "Constraint with id " << Uml::ID::toString(constr->id())
-                 << " does not exist ";
-        return false;
-    }
-
-    if (m_PrimaryKey == constr) {
-        unsetPrimaryKey();
-    }
-
-    m_List.removeAll(constr);
-
-    emit entityConstraintRemoved(constr);
-    UMLObject::emitModified();
-
-    delete constr;
-    return true;
-}
-
-/**
- * Slot for entity attribute removed.
- */
-void UMLEntity::slotEntityAttributeRemoved(UMLClassifierListItem* cli)
-{
-    // this function does some cleanjobs related to this entity when the attribute is
-    // removed, like, removing the attribute from all constraints
-
-    UMLEntityAttribute* entAtt = static_cast<UMLEntityAttribute*>(cli);
-    if (cli) {
-       UMLClassifierListItemList ual = this->getFilteredList(UMLObject::ot_UniqueConstraint);
-
-       foreach(UMLClassifierListItem* ucli,  ual) {
-           UMLUniqueConstraint* uuc = static_cast<UMLUniqueConstraint*>(ucli);
-           if (uuc->hasEntityAttribute(entAtt)) {
-               uuc->removeEntityAttribute(entAtt);
-           }
-       }
-    }
-
-}
-
-/**
- * Reimplementation of getFilteredList to support ot=UMLObject::ot_EntityConstraint.
- */
-UMLClassifierListItemList UMLEntity::getFilteredList(UMLObject::ObjectType ot) const
-{
-    if (ot == UMLObject::ot_EntityConstraint) {
-        UMLClassifierListItemList ucList, fcList, ccList, rcList;
-        ucList = UMLClassifier::getFilteredList(UMLObject::ot_UniqueConstraint);
-        fcList = UMLClassifier::getFilteredList(UMLObject::ot_ForeignKeyConstraint);
-        ccList = UMLClassifier::getFilteredList(UMLObject::ot_CheckConstraint);
-
-        // append the lists to rcList
-        // first the Unique Constraints
-        foreach(UMLClassifierListItem* ucli, ucList) {
-            rcList.append(ucli);
-        }
-
-        // then the Foreign Key Constraints
-        foreach(UMLClassifierListItem* ucli, fcList) {
-            rcList.append(ucli);
-        }
-
-        foreach(UMLClassifierListItem* ucli, ccList) {
-            rcList.append(ucli);
-        }
-
-        return rcList;
-    } else {
-        return UMLClassifier::getFilteredList(ot);
-    }
-}
-
-/**
- * Checks if a given Unique Constraint is primary key of this entity
- * @param uConstr   a Unique Constraint
- * @return bool true if passed parameter is a primary key of this entity
- */
-bool UMLEntity::isPrimaryKey(UMLUniqueConstraint* uConstr) const
-{
-    if (uConstr == m_PrimaryKey) {
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * Returns the Entity Attributes.
- * Same as getFilteredList(UMLObject::ot_EntityAttribute).
- */
-UMLEntityAttributeList UMLEntity::getEntityAttributes() const
-{
-    UMLEntityAttributeList entityAttributeList;
-    for (UMLObjectListIt lit(m_List); lit.hasNext();) {
-        UMLObject *listItem = lit.next();
-        if (listItem->baseType() == UMLObject::ot_EntityAttribute) {
-            entityAttributeList.append(static_cast<UMLEntityAttribute*>(listItem));
-        }
-    }
-    return entityAttributeList;
-}
-
-
-/**
- * Create a new ClassifierListObject (entityattribute)
- * according to the given XMI tag.
- * Returns NULL if the string given does not contain one of the tags
- * <UML:EntityAttribute>
- * Used by the clipboard for paste operation.
- * Reimplemented from UMLClassifier for UMLEntity
- */
-UMLClassifierListItem* UMLEntity::makeChildObject(const QString& xmiTag)
-{
-    UMLClassifierListItem* pObject = NULL;
-    if (UMLDoc::tagEq(xmiTag, QLatin1String("EntityAttribute"))) {
-        pObject = new UMLEntityAttribute(this);
-    }
-    return pObject;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/entity.h umbrello-15.08.1/umbrello/entity.h
--- umbrello-15.08.1.orig/umbrello/entity.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/entity.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,108 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ENTITY_H
-#define ENTITY_H
-
-#include "classifier.h"
-
-// forward declarations
-class UMLEntityAttribute;
-class UMLEntityConstraint;
-class UMLUniqueConstraint;
-class UMLForeignKeyConstraint;
-class UMLCheckConstraint;
-class UMLEntityAttributeList;
-
-/**
- * This class contains the non-graphical information required for a UML
- * Entity.
- * This class inherits from @ref UMLClassifier which contains most of the
- * information.
- *
- * @short Non-graphical Information for an Entity.
- * @author Jonathan Riddell
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLEntity : public UMLClassifier
-{
-    Q_OBJECT
-public:
-    explicit UMLEntity(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLEntity();
-
-    bool operator==(const UMLEntity& rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    virtual UMLAttribute* createAttribute(const QString &name = QString(),
-                                  UMLObject *type = 0, Uml::Visibility::Enum vis = Uml::Visibility::Private,
-                                  const QString &init = QString());
-
-    UMLUniqueConstraint* createUniqueConstraint(const QString &name = QString());
-    UMLForeignKeyConstraint* createForeignKeyConstraint(const QString &name = QString());
-    UMLCheckConstraint* createCheckConstraint(const QString &name = QString());
-
-    UMLObject* addEntityAttribute(const QString &name, Uml::ID::Type id = Uml::ID::None);
-    bool addEntityAttribute(UMLEntityAttribute* att, IDChangeLog* log = 0);
-    bool addEntityAttribute(UMLEntityAttribute* att, int position);
-
-    int removeEntityAttribute(UMLClassifierListItem* att);
-
-    void signalEntityAttributeRemoved(UMLClassifierListItem *eattr);
-
-    int entityAttributes() ;
-
-    bool setAsPrimaryKey(UMLUniqueConstraint* uconstr);
-    void unsetPrimaryKey();
-    bool hasPrimaryKey() const;
-    bool isPrimaryKey(UMLUniqueConstraint* uConstr) const;
-
-    bool addConstraint(UMLEntityConstraint* constr);
-    bool removeConstraint(UMLEntityConstraint* constr);
-
-    virtual bool resolveRef();
-
-    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    UMLClassifierListItemList getFilteredList(UMLObject::ObjectType ot) const;
-
-    UMLEntityAttributeList getEntityAttributes() const;
-
-    virtual UMLClassifierListItem* makeChildObject(const QString& xmiTag);
-
-private slots:
-    void slotEntityAttributeRemoved(UMLClassifierListItem*);
-
-signals:
-    void entityAttributeAdded(UMLClassifierListItem*);
-    void entityAttributeRemoved(UMLClassifierListItem*);
-    void entityConstraintAdded(UMLClassifierListItem*);
-    void entityConstraintRemoved(UMLClassifierListItem*);
-
-protected:
-    bool load(QDomElement& element);
-
-private:
-
-    /**
-     * Primary Key of this Entity
-     * This is a pointer kept for easy access to the primary key, and to distinguish it
-     * from all other UniqueConstraints. It is also there in m_List (inherited from
-     * UMLCanvasObject)
-     */
-    UMLUniqueConstraint* m_PrimaryKey;
-
-};
-
-#endif // ENTITY_H
-
diff -Nuar umbrello-15.08.1.orig/umbrello/enum.cpp umbrello-15.08.1/umbrello/enum.cpp
--- umbrello-15.08.1.orig/umbrello/enum.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/enum.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,302 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "enum.h"
-
-// app includes
-#include "debug_utils.h"
-#include "enumliteral.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "uniqueid.h"
-#include "idchangelog.h"
-
-// kde includes
-#include <KLocalizedString>
-#include <KMessageBox>
-
-/**
- * Sets up an enum.
- * @param name  The name of the Enum.
- * @param id  The unique id of the Enum.
- */
-UMLEnum::UMLEnum(const QString& name, Uml::ID::Type id) : UMLClassifier(name, id)
-{
-    init();
-}
-
-/**
- * Standard destructor.
- */
-UMLEnum::~UMLEnum()
-{
-    m_List.clear();
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLEnum::operator==(const UMLEnum & rhs) const
-{
-    return UMLClassifier::operator==(rhs);
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLEnum::copyInto(UMLObject *lhs) const
-{
-    UMLClassifier::copyInto(lhs);
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLEnum::clone() const
-{
-    UMLEnum *clone = new UMLEnum();
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLEnum::init()
-{
-    m_BaseType = UMLObject::ot_Enum;
-    setStereotypeCmd(QLatin1String("enum"));
-}
-
-/**
- * Creates a literal for the enum.
- * @return  The UMLEnum created
- */
-UMLObject* UMLEnum::createEnumLiteral(const QString& name)
-{
-    Uml::ID::Type id = UniqueID::gen();
-    QString currentName;
-    if (name.isNull())  {
-        currentName = uniqChildName(UMLObject::ot_EnumLiteral);
-    } else {
-        currentName = name;
-    }
-
-    UMLEnumLiteral* newEnumLiteral = new UMLEnumLiteral(this, currentName);
-
-    bool ok = true;
-    bool goodName = false;
-
-    //check for name.isNull() stops dialog being shown
-    //when creating enum literal via list view
-    while (ok && !goodName && name.isNull()) {
-        ok = newEnumLiteral->showPropertiesDialog(UMLApp::app());
-        QString name = newEnumLiteral->name();
-
-        if(name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
-        } else {
-            goodName = true;
-        }
-    }
-
-    if (!ok) {
-        delete newEnumLiteral;
-        return NULL;
-    }
-
-    addEnumLiteral(newEnumLiteral);
-
-    UMLDoc *umldoc = UMLApp::app()->document();
-    umldoc->signalUMLObjectCreated(newEnumLiteral);
-    return newEnumLiteral;
-}
-
-/**
- * Adds an enumliteral to the enum.
- * @param name  The name of the enumliteral.
- * @param id  The id of the enumliteral (optional.)
- *            If omitted a new ID is assigned internally.
- * @return  Pointer to the UMLEnumliteral created.
- */
-UMLObject* UMLEnum::addEnumLiteral(const QString &name, Uml::ID::Type id)
-{
-    UMLObject *el = UMLCanvasObject::findChildObject(name);
-    if (el != NULL) {
-        uDebug() << name << " is already present";
-        return el;
-    }
-    UMLEnumLiteral* literal = new UMLEnumLiteral(this, name, id);
-    m_List.append(literal);
-    UMLObject::emitModified();
-    emit enumLiteralAdded(literal);
-    connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
-    return literal;
-}
-
-/**
- * Adds an already created enumliteral.
- * The enumliteral object must not belong to any other concept.
- * @param literal  Pointer to the UMLEnumLiteral.
- * @param Log      Pointer to the IDChangeLog.
- * @return  True if the enumliteral was successfully added.
- */
-bool UMLEnum::addEnumLiteral(UMLEnumLiteral* literal, IDChangeLog* Log /* = 0*/)
-{
-    QString name = (QString)literal->name();
-    if (findChildObject(name) == NULL) {
-        literal->setParent(this);
-        m_List.append(literal);
-        UMLObject::emitModified();
-        emit enumLiteralAdded(literal);
-        connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    } else if (Log) {
-        Log->removeChangeByNewID(literal->id());
-        delete literal;
-    }
-    return false;
-}
-
-/**
- * Adds an enumliteral to the enum, at the given position.
- * If position is negative or too large, the enumliteral is added
- * to the end of the list.
- * TODO:  give default value -1 to position (append) - now it conflicts with the method above..
- * @param literal   Pointer to the UMLEnumLiteral.
- * @param position  Position index for the insertion.
- * @return  True if the enumliteral was successfully added.
- */
-bool UMLEnum::addEnumLiteral(UMLEnumLiteral* literal, int position)
-{
-    Q_ASSERT(literal);
-    QString name = (QString)literal->name();
-    if (findChildObject(name) == NULL) {
-        literal->setParent(this);
-        if (position >= 0 && position <= (int)m_List.count())  {
-            m_List.insert(position, literal);
-        } else {
-            m_List.append(literal);
-        }
-        UMLObject::emitModified();
-        emit enumLiteralAdded(literal);
-        connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
-        return true;
-    }
-    return false;
-}
-
-/**
- * Removes an enumliteral from the class.
- * @param literal  The enumliteral to remove.
- * @return  Count of the remaining enumliterals after removal.
- *          Returns -1 if the given enumliteral was not found.
- */
-int UMLEnum::removeEnumLiteral(UMLEnumLiteral* literal)
-{
-    if (!m_List.removeAll(literal)) {
-        uDebug() << "cannot find att given in list";
-        return -1;
-    }
-    emit enumLiteralRemoved(literal);
-    UMLObject::emitModified();
-    // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
-    // for us by QObject. -b.t.
-    // disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
-    delete literal;
-    return m_List.count();
-}
-
-/**
- * Returns the number of enumliterals for the class.
- * @return  The number of enumliterals for the class.
- */
-int UMLEnum::enumLiterals()
-{
-    return m_List.count();
-}
-
-/**
- * Emit the enumLiteralRemoved signal.
- */
-void UMLEnum::signalEnumLiteralRemoved(UMLClassifierListItem *elit)
-{
-    emit enumLiteralRemoved(elit);
-}
-
-/**
- * Creates the <UML:Enum> element including its enumliterals.
- */
-void UMLEnum::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement enumElement = UMLObject::save(QLatin1String("UML:Enumeration"), qDoc);
-    // save enum literals
-    UMLClassifierListItemList enumLiterals = getFilteredList(UMLObject::ot_EnumLiteral);
-    foreach (UMLClassifierListItem* pEnumLiteral, enumLiterals) {
-        pEnumLiteral->saveToXMI(qDoc, enumElement);
-    }
-    qElement.appendChild(enumElement);
-}
-
-/**
- * Loads the <UML:Enum> element including its enumliterals.
- */
-bool UMLEnum::load(QDomElement& element)
-{
-    QDomNode node = element.firstChild();
-    while(!node.isNull()) {
-        if (node.isComment()) {
-            node = node.nextSibling();
-            continue;
-        }
-        QDomElement tempElement = node.toElement();
-        QString tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("EnumerationLiteral")) ||
-            UMLDoc::tagEq(tag, QLatin1String("ownedLiteral")) ||
-                UMLDoc::tagEq(tag, QLatin1String("EnumLiteral"))) {   // for backward compatibility
-            UMLEnumLiteral* pEnumLiteral = new UMLEnumLiteral(this);
-            if(!pEnumLiteral->loadFromXMI(tempElement)) {
-                return false;
-            }
-            m_List.append(pEnumLiteral);
-        } else if (UMLDoc::tagEq(tag, QLatin1String("Enumeration.literal"))) {  // Embarcadero's Describe
-            if (! load(tempElement))
-                return false;
-        } else if (tag == QLatin1String("stereotype")) {
-            uDebug() << name() << ": losing old-format stereotype.";
-        } else {
-            uWarning() << "unknown child type: " << tag;
-        }
-        node = node.nextSibling();
-    }//end while
-    return true;
-}
-
-/**
- * Create a new ClassifierListObject (enumLiteral)
- * according to the given XMI tag.
- * Returns NULL if the string given does not contain one of the tags
- * <UML:EnumLiteral>
- * Used by the clipboard for paste operation.
- * Reimplemented from UMLClassifier for UMLEnum
- */
-UMLClassifierListItem* UMLEnum::makeChildObject(const QString& xmiTag)
-{
-    UMLClassifierListItem* pObject = NULL;
-    if (UMLDoc::tagEq(xmiTag, QLatin1String("EnumerationLiteral")) ||
-               UMLDoc::tagEq(xmiTag, QLatin1String("EnumLiteral"))) {
-        pObject = new UMLEnumLiteral(this);
-    }
-    return pObject;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/enum.h umbrello-15.08.1/umbrello/enum.h
--- umbrello-15.08.1.orig/umbrello/enum.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/enum.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,72 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ENUM_H
-#define ENUM_H
-
-#include "classifier.h"
-
-class UMLEnumLiteral;
-
-/**
- * This class contains the non-graphical information required for a UML
- * Enum.
- * This class inherits from @ref UMLClassifier which contains most of the
- * information.
- *
- * @short Non-graphical Information for an Enum.
- * @author Jonathan Riddell
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLEnum : public UMLClassifier
-{
-    Q_OBJECT
-public:
-    explicit UMLEnum(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
-
-    virtual ~UMLEnum();
-
-    bool operator==(const UMLEnum& rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    UMLObject* createEnumLiteral(const QString& name = QString());
-
-    UMLObject* addEnumLiteral(const QString &name, Uml::ID::Type id = Uml::ID::None);
-
-    bool addEnumLiteral(UMLEnumLiteral* literal, IDChangeLog* Log = 0);
-    bool addEnumLiteral(UMLEnumLiteral* literal, int position);
-
-    int removeEnumLiteral(UMLEnumLiteral* literal);
-
-    int enumLiterals();
-
-    void signalEnumLiteralRemoved(UMLClassifierListItem *elit);
-
-    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    virtual UMLClassifierListItem* makeChildObject(const QString& xmiTag);
-
-signals:
-    void enumLiteralAdded(UMLClassifierListItem*);
-    void enumLiteralRemoved(UMLClassifierListItem*);
-
-protected:
-    bool load(QDomElement & element);
-
-private:
-    void init();
-
-};
-
-#endif // ENUM_H
-
diff -Nuar umbrello-15.08.1.orig/umbrello/enumliteral.cpp umbrello-15.08.1/umbrello/enumliteral.cpp
--- umbrello-15.08.1.orig/umbrello/enumliteral.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/enumliteral.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,126 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "enumliteral.h"
-
-// kde includes
-#if QT_VERSION < 0x050000
-#include <kinputdialog.h>
-#endif
-#include <KLocalizedString>
-
-// qt includes
-#if QT_VERSION >= 0x050000
-#include <QInputDialog>
-#endif
-
-/**
- * Sets up an enum literal.
- * @param parent    The parent of this UMLEnumLiteral.
- * @param name      The name of this UMLEnumLiteral.
- * @param id        The unique id given to this UMLEnumLiteral.
- */
-UMLEnumLiteral::UMLEnumLiteral(UMLObject *parent,
-                               const QString& name, Uml::ID::Type id)
-  : UMLClassifierListItem(parent, name, id)
-{
-    m_BaseType = UMLObject::ot_EnumLiteral;
-}
-
-/**
- * Sets up an enum literal.
- * @param parent    The parent of this UMLEnumLiteral.
- */
-UMLEnumLiteral::UMLEnumLiteral(UMLObject *parent)
-  : UMLClassifierListItem(parent)
-{
-    m_BaseType = UMLObject::ot_EnumLiteral;
-}
-
-/**
- * Destructor.
- */
-UMLEnumLiteral::~UMLEnumLiteral()
-{
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLEnumLiteral::operator==(const UMLEnumLiteral& rhs) const
-{
-    if (this == &rhs)  {
-        return true;
-    }
-    if (!UMLObject::operator==(rhs))  {
-        return false;
-    }
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLEnumLiteral::copyInto(UMLObject *lhs) const
-{
-    UMLClassifierListItem::copyInto(lhs);
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLEnumLiteral::clone() const
-{
-    UMLEnumLiteral *clone = new UMLEnumLiteral((UMLObject *) parent());
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Creates the <UML:EnumLiteral> XMI element.
- */
-void UMLEnumLiteral::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement attributeElement = UMLObject::save(QLatin1String("UML:EnumerationLiteral"), qDoc);
-    qElement.appendChild(attributeElement);
-}
-
-/**
- * Loads the <UML:EnumLiteral> XMI element (empty.)
- */
-bool UMLEnumLiteral::load(QDomElement& element)
-{
-    Q_UNUSED(element);
-    return true;
-}
-
-/**
- * Display the properties configuration dialog for the enum literal.
- */
-bool UMLEnumLiteral::showPropertiesDialog(QWidget* parent)
-{
-    bool ok;
-#if QT_VERSION >= 0x050000
-    QString enumName = QInputDialog::getText(parent,
-                                             i18nc("enum name", "Name"), i18n("Enter name:"),
-                                             QLineEdit::Normal,
-                                             name(), &ok);
-#else
-    QString enumName = KInputDialog::getText(i18nc("enum name", "Name"), i18n("Enter name:"), name(), &ok, parent);
-#endif
-    if (ok && !enumName.isEmpty())  {
-        setName(enumName);
-        return true;
-    } else {
-        return false;
-    }
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/enumliteral.h umbrello-15.08.1/umbrello/enumliteral.h
--- umbrello-15.08.1.orig/umbrello/enumliteral.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/enumliteral.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,49 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ENUMLITERAL_H
-#define ENUMLITERAL_H
-
-#include "classifierlistitem.h"
-
-/**
- * This class is used to set up information for an enum literal.  Enum
- * literals are the values that enums can be set to.
- *
- * @short Sets up attribute information.
- * @author Paul Hensgen <phensgen@techie.com>
- * @see UMLObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLEnumLiteral : public UMLClassifierListItem
-{
-public:
-    UMLEnumLiteral(UMLObject* parent,
-                   const QString& name, Uml::ID::Type id = Uml::ID::None);
-    explicit UMLEnumLiteral(UMLObject* parent);
-
-    bool operator==(const UMLEnumLiteral &rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    virtual ~UMLEnumLiteral();
-
-    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-protected:
-    bool load(QDomElement& element);
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/folder.cpp umbrello-15.08.1/umbrello/folder.cpp
--- umbrello-15.08.1.orig/umbrello/folder.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/folder.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,558 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2006-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "folder.h"
-
-// app includes
-#include "debug_utils.h"
-#include "model_utils.h"
-#include "object_factory.h"
-#include "optionstate.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umlscene.h"
-#include "umlview.h"
-
-// kde includes
-#include <KLocalizedString>
-#include <KMessageBox>
-
-// qt includes
-#include <QFile>
-
-/**
- * Sets up a Folder.
- * @param name    The name of the Folder.
- * @param id      The unique id of the Folder. A new ID will be generated
- *                if this argument is left away.
- */
-UMLFolder::UMLFolder(const QString & name, Uml::ID::Type id)
-  : UMLPackage(name, id)
-{
-    m_BaseType = UMLObject::ot_Folder;
-    UMLObject::setStereotypeCmd(QLatin1String("folder"));
-}
-
-/**
- * Empty destructor.
- */
-UMLFolder::~UMLFolder()
-{
-    qDeleteAll(m_diagrams);
-    m_diagrams.clear();
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLFolder::clone() const
-{
-    UMLFolder *clone = new UMLFolder();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Set the localized name of this folder.
- * This is set for the predefined root views (Logical,
- * UseCase, Component, Deployment, EntityRelationship,
- * and the Datatypes folder inside the Logical View.)
- */
-void UMLFolder::setLocalName(const QString& localName)
-{
-    m_localName = localName;
-}
-
-/**
- * Return the localized name of this folder.
- * Only useful for the predefined root folders.
- */
-QString UMLFolder::localName() const
-{
-    return m_localName;
-}
-
-/**
- * Add a view to the diagram list.
- */
-void UMLFolder::addView(UMLView *view)
-{
-    m_diagrams.append(view);
-}
-
-/**
- * Remove a view from the diagram list.
- */
-void UMLFolder::removeView(UMLView *view)
-{
-    m_diagrams.removeAll(view);
-    delete view;
-}
-
-/**
- * Append the views in this folder to the given diagram list.
- * @param viewList       The UMLViewList to which to append the diagrams.
- * @param includeNested  Whether to include diagrams from nested folders
- *                       (default: true.)
- */
-void UMLFolder::appendViews(UMLViewList& viewList, bool includeNested)
-{
-    if (includeNested) {
-        foreach (UMLObject* o, m_objects) {
-            uIgnoreZeroPointer(o);
-            if (o->baseType() == UMLObject::ot_Folder) {
-                UMLFolder *f = static_cast<UMLFolder*>(o);
-                f->appendViews(viewList);
-            }
-        }
-    }
-    foreach (UMLView* v, m_diagrams) {
-        viewList.append(v);
-    }
-}
-
-/**
- * Acivate the views in this folder.
- * "Activation": Some widgets require adjustments after loading from file,
- * those are done here.
- */
-void UMLFolder::activateViews()
-{
-    foreach (UMLObject* o, m_objects) {
-        uIgnoreZeroPointer(o);
-        if (o->baseType() == UMLObject::ot_Folder) {
-            UMLFolder *f = static_cast<UMLFolder*>(o);
-            f->activateViews();
-        }
-    }
-
-    foreach (UMLView* v, m_diagrams) {
-        v->umlScene()->activateAfterLoad();
-    }
-    // Make sure we have a treeview item for each diagram.
-    // It may happen that we are missing them after switching off tabbed widgets.
-    Settings::OptionState optionState = Settings::optionState();
-    if (optionState.generalState.tabdiagrams) {
-        return;
-    }
-    Model_Utils::treeViewAddViews(m_diagrams);
-}
-
-/**
- * Seek a view of the given ID in this folder.
- * @param id   ID of the view to find.
- * @return     Pointer to the view if found, NULL if no view found.
- */
-UMLView *UMLFolder::findView(Uml::ID::Type id)
-{
-    foreach (UMLView* v, m_diagrams) {
-        if (v->umlScene()->ID() == id) {
-            return v;
-        }
-    }
-
-    UMLView* v = 0;
-    UMLPackageList packages;
-    appendPackages(packages);
-    foreach (UMLPackage *o, packages) {
-        if (o->baseType() != UMLObject::ot_Folder) {
-            continue;
-        }
-        UMLFolder *f = static_cast<UMLFolder*>(o);
-        v = f->findView(id);
-        if (v) {
-            break;
-        }
-    }
-    return v;
-}
-
-/**
- * Seek a view by the type and name given.
- * @param type              The type of view to find.
- * @param name              The name of the view to find.
- * @param searchAllScopes   Search in all subfolders (default: true.)
- * @return  Pointer to the view found, or NULL if not found.
- */
-UMLView *UMLFolder::findView(Uml::DiagramType::Enum type, const QString &name, bool searchAllScopes)
-{
-    foreach (UMLView* v, m_diagrams) {
-        if (v->umlScene()->type() == type && v->umlScene()->name() == name) {
-            return v;
-        }
-    }
-
-    UMLView* v = 0;
-    if (searchAllScopes) {
-        foreach (UMLObject* o, m_objects) {
-            uIgnoreZeroPointer(o);
-            if (o->baseType() != UMLObject::ot_Folder) {
-                continue;
-            }
-            UMLFolder *f = static_cast<UMLFolder*>(o);
-            v = f->findView(type, name, searchAllScopes);
-            if (v) {
-                break;
-            }
-        }
-    }
-    return v;
-}
-
-/**
- * Set the options for the views in this folder.
- */
-void UMLFolder::setViewOptions(const Settings::OptionState& optionState)
-{
-    // for each view update settings
-    foreach (UMLView* v, m_diagrams) {
-        v->umlScene()->setOptionState(optionState);
-    }
-}
-
-/**
- * Remove all views in this folder.
- */
-void UMLFolder::removeAllViews()
-{
-    foreach (UMLObject* o, m_objects) {
-        uIgnoreZeroPointer(o);
-        if (o->baseType() != UMLObject::ot_Folder)
-            continue;
-        UMLFolder *f = static_cast<UMLFolder*>(o);
-        f->removeAllViews();
-    }
-
-    foreach (UMLView* v, m_diagrams) {
-        // TODO ------------------ check this code - bad: calling back to UMLDoc::removeView()
-        v->umlScene()->removeAllAssociations(); // note : It may not be apparent, but when we remove all associations
-        // from a view, it also causes any UMLAssociations that lack parent
-        // association widgets (but once had them) to remove themselves from
-        // this document.
-        uDebug() << "removing " << v->umlScene()->name();
-        UMLApp::app()->document()->removeView(v, false);
-    }
-
-    qDeleteAll(m_diagrams);
-    m_diagrams.clear();
-}
-
-/**
- * Set the folder file name for a separate submodel.
- */
-void UMLFolder::setFolderFile(const QString& fileName)
-{
-    m_folderFile = fileName;
-}
-
-/**
- * Get the folder file name for a separate submodel.
- */
-QString UMLFolder::folderFile() const
-{
-    return m_folderFile;
-}
-
-/**
- * Auxiliary to saveToXMI(): Save the contained objects and diagrams.
- * Can be used regardless of whether saving to the main model file
- * or to an external folder file (see m_folderFile.)
- */
-void UMLFolder::saveContents(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
-    UMLObject *obj = 0;
-    // Save contained objects if any.
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        obj = oit.next();
-        uIgnoreZeroPointer(obj);
-        obj->saveToXMI (qDoc, ownedElement);
-    }
-    // Save asscociations if any.
-    for (UMLObjectListIt ait(m_List); ait.hasNext();) {
-        obj = ait.next();
-        obj->saveToXMI (qDoc, ownedElement);
-    }
-    qElement.appendChild(ownedElement);
-    // Save diagrams to `extension'.
-    if (m_diagrams.count()) {
-        QDomElement diagramsElement = qDoc.createElement(QLatin1String("diagrams"));
-
-        foreach (UMLView* pView, m_diagrams) {
-            pView->umlScene()->saveToXMI(qDoc, diagramsElement);
-        }
-        QDomElement extension = qDoc.createElement(QLatin1String("XMI.extension"));
-        extension.setAttribute(QLatin1String("xmi.extender"), QLatin1String("umbrello"));
-        extension.appendChild(diagramsElement);
-        qElement.appendChild(extension);
-    }
-}
-
-/**
- * Auxiliary to saveToXMI(): Creates a <UML:Model> element when saving
- * a predefined modelview, or a <UML:Package> element when saving a
- * user created folder. Invokes saveContents() with the newly created
- * element.
- */
-void UMLFolder::save(QDomDocument& qDoc, QDomElement& qElement)
-{
-    UMLDoc *umldoc = UMLApp::app()->document();
-    QString elementName(QLatin1String("UML:Package"));
-    const Uml::ModelType::Enum mt = umldoc->rootFolderType(this);
-    if (mt != Uml::ModelType::N_MODELTYPES) {
-        elementName = QLatin1String("UML:Model");
-    }
-    QDomElement folderElement = UMLObject::save(elementName, qDoc);
-    saveContents(qDoc, folderElement);
-    qElement.appendChild(folderElement);
-}
-
-/**
- * Creates a UML:Model or UML:Package element:
- * UML:Model is created for the predefined fixed folders,
- * UML:Package with stereotype "folder" is created for all else.
- */
-void UMLFolder::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    if (m_folderFile.isEmpty()) {
-        save(qDoc, qElement);
-        return;
-    }
-    // See if we can create the external file.
-    // If not then internalize the folder.
-    UMLDoc *umldoc = UMLApp::app()->document();
-#if QT_VERSION >= 0x050000
-    QString fileName = umldoc->url().adjusted(QUrl::RemoveFilename).path() + m_folderFile;
-#else
-    QString fileName = umldoc->url().directory() + QLatin1Char('/') + m_folderFile;
-#endif
-    QFile file(fileName);
-    if (!file.open(QIODevice::WriteOnly)) {
-        uError() << m_folderFile << QLatin1String(": ")
-            << "cannot create file, contents will be saved in main model file";
-        m_folderFile.clear();
-        save(qDoc, qElement);
-        return;
-    }
-    // Okay, external file is writable.  Wrap up main file.
-    QDomElement folderElement = UMLObject::save(QLatin1String("UML:Package"), qDoc);
-    QDomElement extension = qDoc.createElement(QLatin1String("XMI.extension"));
-    extension.setAttribute(QLatin1String("xmi.extender"), QLatin1String("umbrello"));
-    QDomElement fileElement = qDoc.createElement(QLatin1String("external_file"));
-    fileElement.setAttribute(QLatin1String("name"), m_folderFile);
-    extension.appendChild(fileElement);
-    folderElement.appendChild(extension);
-    qElement.appendChild(folderElement);
-
-    // Save folder to external file.
-    QDomDocument folderDoc;
-    QDomElement folderRoot;
-    QDomProcessingInstruction xmlHeading =
-        folderDoc.createProcessingInstruction(QLatin1String("xml"),
-                                              QString::fromLatin1("version=\"1.0\" encoding=\"UTF-8\""));
-    folderDoc.appendChild(xmlHeading);
-    folderRoot = folderDoc.createElement(QLatin1String("external_file"));
-    folderRoot.setAttribute(QLatin1String("name"), name());
-    folderRoot.setAttribute(QLatin1String("filename"), m_folderFile);
-    folderRoot.setAttribute(QLatin1String("mainModel"), umldoc->url().fileName());
-    folderRoot.setAttribute(QLatin1String("parentId"), Uml::ID::toString(m_pUMLPackage->id()));
-    folderRoot.setAttribute(QLatin1String("parent"), m_pUMLPackage->fullyQualifiedName(QLatin1String("::"), true));
-    saveContents(folderDoc, folderRoot);
-    folderDoc.appendChild(folderRoot);
-    QTextStream stream(&file);
-    stream.setCodec("UTF-8");
-    stream << folderDoc.toString();
-    file.close();
-}
-
-/**
- * Auxiliary to load():
- * Load the diagrams from the "diagrams" in the <XMI.extension>
- */
-bool UMLFolder::loadDiagramsFromXMI(QDomNode& diagrams)
-{
-    const Settings::OptionState optionState = Settings::optionState();
-    UMLDoc *umldoc = UMLApp::app()->document();
-    bool totalSuccess = true;
-    for (QDomElement diagram = diagrams.toElement(); !diagram.isNull();
-         diagrams = diagrams.nextSibling(), diagram = diagrams.toElement()) {
-        QString tag = diagram.tagName();
-        if (tag != QLatin1String("diagram")) {
-            uDebug() << "ignoring " << tag << " in <diagrams>";
-            continue;
-        }
-        UMLView * pView = new UMLView(this);
-        pView->umlScene()->setOptionState(optionState);
-        if (pView->umlScene()->loadFromXMI(diagram)) {
-            pView->hide();
-            umldoc->addView(pView);
-        } else {
-            delete pView;
-            totalSuccess = false;
-        }
-    }
-    return totalSuccess;
-}
-
-/**
- * Folders in the listview can be marked such that their contents
- * are saved to a separate file.
- * This method loads the separate folder file.
- * CAVEAT: This is not XMI standard compliant.
- * If standard compliance is an issue then avoid folder files.
- * @param path  Fully qualified file name, i.e. absolute directory
- *              plus file name.
- * @return   True for success.
- */
-bool UMLFolder::loadFolderFile(const QString& path)
-{
-    QFile file(path);
-    if (!file.exists()) {
-        KMessageBox::error(0, i18n("The folderfile %1 does not exist.", path), i18n("Load Error"));
-        return false;
-    }
-    if (!file.open(QIODevice::ReadOnly)) {
-        KMessageBox::error(0, i18n("The folderfile %1 cannot be opened.", path), i18n("Load Error"));
-        return false;
-    }
-    QTextStream stream(&file);
-    QString data = stream.readAll();
-    file.close();
-    QDomDocument doc;
-    QString error;
-    int line;
-    if (!doc.setContent(data, false, &error, &line)) {
-        uError() << "Cannot set content:" << error << " line:" << line;
-        return false;
-    }
-    QDomNode rootNode = doc.firstChild();
-    while (rootNode.isComment() || rootNode.isProcessingInstruction()) {
-        rootNode = rootNode.nextSibling();
-    }
-    if (rootNode.isNull()) {
-        uError() << "Root node is Null";
-        return false;
-    }
-    QDomElement element = rootNode.toElement();
-    QString type = element.tagName();
-    if (type != QLatin1String("external_file")) {
-        uError() << "Root node has unknown type " << type;
-        return false;
-    }
-    return load(element);
-}
-
-/**
- * Loads the owned elements of the <UML:Model>.
- */
-bool UMLFolder::load(QDomElement& element)
-{
-    UMLDoc *umldoc = UMLApp::app()->document();
-    bool totalSuccess = true;
-    for (QDomNode node = element.firstChild(); !node.isNull();
-            node = node.nextSibling()) {
-        if (node.isComment())
-            continue;
-        QDomElement tempElement = node.toElement();
-        QString type = tempElement.tagName();
-        if (Model_Utils::isCommonXMIAttribute(type))
-            continue;
-        if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
-                UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
-            //CHECK: Umbrello currently assumes that nested elements
-            // are ownedElements anyway.
-            // Therefore these tags are not further interpreted.
-            if (! load(tempElement)) {
-                uDebug() << "An error happened while loading the " << type
-                    << " of the " << name();
-                totalSuccess = false;
-            }
-            continue;
-        } else if (UMLDoc::tagEq(type, QLatin1String("packagedElement")) ||
-                   UMLDoc::tagEq(type, QLatin1String("ownedElement"))) {
-            type = tempElement.attribute(QLatin1String("xmi:type"));
-        } else if (type == QLatin1String("XMI.extension")) {
-            for (QDomNode xtnode = node.firstChild(); !xtnode.isNull();
-                                              xtnode = xtnode.nextSibling()) {
-                QDomElement el = xtnode.toElement();
-                const QString xtag = el.tagName();
-                if (xtag == QLatin1String("diagrams")) {
-                    QDomNode diagramNode = xtnode.firstChild();
-                    if (!loadDiagramsFromXMI(diagramNode))
-                        totalSuccess = false;
-                } else if (xtag == QLatin1String("external_file")) {
-#if QT_VERSION >= 0x050000
-                    const QString rootDir(umldoc->url().adjusted(QUrl::RemoveFilename).path());
-#else
-                    const QString rootDir(umldoc->url().directory());
-#endif
-                    QString fileName = el.attribute(QLatin1String("name"));
-                    const QString path(rootDir + QLatin1Char('/') + fileName);
-                    if (loadFolderFile(path))
-                        m_folderFile = fileName;
-                } else {
-                    uDebug() << name() << ": ignoring XMI.extension " << xtag;
-                    continue;
-                }
-            }
-            continue;
-        }
-        // Do not re-create the predefined Datatypes folder in the Logical View,
-        // it already exists.
-        UMLFolder *logicalView = umldoc->rootFolder(Uml::ModelType::Logical);
-        if (this == logicalView && UMLDoc::tagEq(type, QLatin1String("Package"))) {
-            QString thisName = tempElement.attribute(QLatin1String("name"));
-            if (thisName == QLatin1String("Datatypes")) {
-                UMLFolder *datatypeFolder = umldoc->datatypeFolder();
-                if (!datatypeFolder->loadFromXMI(tempElement))
-                    totalSuccess = false;
-                continue;
-            }
-        }
-        UMLObject *pObject = 0;
-        // Avoid duplicate creation of forward declared object
-        QString idStr = Model_Utils::getXmiId(tempElement);
-        if (!idStr.isEmpty()) {
-            Uml::ID::Type id = Uml::ID::fromString(idStr);
-            pObject = umldoc->findObjectById(id);
-            if (pObject) {
-                uDebug() << "object " << idStr << "already exists";
-            }
-        }
-        if (pObject == 0) {
-            QString stereoID = tempElement.attribute(QLatin1String("stereotype"));
-            pObject = Object_Factory::makeObjectFromXMI(type, stereoID);
-            if (!pObject) {
-                uWarning() << "Unknown type of umlobject to create: " << type;
-                continue;
-            }
-        }
-        pObject->setUMLPackage(this);
-        if (!pObject->loadFromXMI(tempElement)) {
-            removeObject(pObject);
-            delete pObject;
-            totalSuccess = false;
-        }
-    }
-    return totalSuccess;
-}
-
-/**
- * Overloading operator for debugging output.
- */
-QDebug operator<<(QDebug out, const UMLFolder& item)
-{
-    out.nospace() << "UMLFolder: localName=" << item.m_localName
-        << ", folderFile=" << item.m_folderFile
-        << ", diagrams=" << item.m_diagrams.count();
-    return out.space();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/folder.h umbrello-15.08.1/umbrello/folder.h
--- umbrello-15.08.1.orig/umbrello/folder.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/folder.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,92 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2006-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLFOLDER_H
-#define UMLFOLDER_H
-
-#include "package.h"
-#include "umlviewlist.h"
-#include "optionstate.h"
-
-/**
- * This class manages the UMLObjects and UMLViews of a Folder.
- * This class inherits from UMLPackage which contains most
- * of the information.
- *
- * The UMLDoc class allocates a fixed instance of this class for
- * each of the predefined Logical, UseCase, Component, Deployment, and
- * Entity-Relationship folders.  Further instances are created on demand
- * for user folders.
- *
- * @short Non-graphical management of objects and diagrams of a Folder
- * @author Oliver Kellogg
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- *
- * TODO: This whole class needs a relook regarding view/scene.
- */
-class UMLFolder : public UMLPackage
-{
-    Q_OBJECT
-public:
-    explicit UMLFolder(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLFolder();
-
-    virtual UMLObject* clone() const;
-
-    void setLocalName(const QString& localName);
-    QString localName() const;
-
-    void addView(UMLView *view);
-
-    void removeView(UMLView *view);
-
-    void appendViews(UMLViewList& viewList, bool includeNested = true);
-
-    void activateViews();
-
-    UMLView* findView(Uml::ID::Type id);
-    UMLView* findView(Uml::DiagramType::Enum type, const QString &name, bool searchAllScopes = true);
-
-    void setViewOptions(const Settings::OptionState& optionState);
-
-    void removeAllViews();
-
-    void setFolderFile(const QString& fileName);
-    QString folderFile() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    friend QDebug operator<<(QDebug out, const UMLFolder& item);
-
-protected:
-    void saveContents(QDomDocument& qDoc, QDomElement& qElement);
-
-    void save(QDomDocument& qDoc, QDomElement& qElement);
-
-    bool loadDiagramsFromXMI(QDomNode& diagrams);
-
-    bool loadFolderFile(const QString& path);
-
-    bool load(QDomElement & element);
-
-private:
-    QString m_localName;  ///< i18n name, only used for predefined root folders
-    /**
-     * If m_folderFile is not empty then it contains a file name to which
-     * this folder is saved.
-     * In this case the folder file acts as a physically separate submodel.
-     * What is saved in the main model is not the folder contents but a
-     * reference to the folder file.
-     */
-    QString m_folderFile;
-    UMLViewList m_diagrams;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/foreignkeyconstraint.cpp umbrello-15.08.1/umbrello/foreignkeyconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/foreignkeyconstraint.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/foreignkeyconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,444 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-//own header
-#include "foreignkeyconstraint.h"
-
-// app includes
-#include "debug_utils.h"
-#include "entity.h"
-#include "entityattribute.h"
-#include "umlobject.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "umlforeignkeyconstraintdialog.h"
-#include "object_factory.h"
-
-/**
- * Sets up a constraint.
- * @param parent    The parent of this UMLForeignKeyConstraint.
- * @param name      The name of this UMLForeignKeyConstraint.
- * @param id        The unique id given to this UMLForeignKeyConstraint.
- */
-UMLForeignKeyConstraint::UMLForeignKeyConstraint(UMLObject *parent,
-    const QString& name, Uml::ID::Type id)
-  : UMLEntityConstraint(parent, name, id)
-{
-    init();
-}
-
-/**
- * Sets up a constraint.
- * @param parent    The parent of this UMLForeignKeyConstraint.
- */
-UMLForeignKeyConstraint::UMLForeignKeyConstraint(UMLObject *parent)
-    : UMLEntityConstraint(parent)
-{
-    init();
-}
-
-/**
- * Initialisation of common variables
- */
-void UMLForeignKeyConstraint::init()
-{
-    // initialise attributes
-     m_BaseType = UMLObject::ot_ForeignKeyConstraint;
-
-     // should be NULL actually
-     // self referencing assigned to protect default behaviour
-     m_ReferencedEntity = static_cast<UMLEntity*>(parent());
-
-     m_UpdateAction = uda_NoAction;
-     m_DeleteAction = uda_NoAction;
-
-    // connecte signals and slots
-     connect(this, SIGNAL(sigReferencedEntityChanged()), this, SLOT(slotReferencedEntityChanged()));
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLForeignKeyConstraint::operator==(const UMLForeignKeyConstraint &rhs) const
-{
-    if(this == &rhs)
-        return true;
-
-    if(!UMLObject::operator==(rhs))
-        return false;
-
-    return true;
-}
-
-/**
- * Destructor.
- */
-UMLForeignKeyConstraint::~UMLForeignKeyConstraint()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the UMLForeignKeyConstraint
- * object.
- */
-void UMLForeignKeyConstraint::copyInto(UMLObject *lhs) const
-{
-    UMLForeignKeyConstraint *target = static_cast<UMLForeignKeyConstraint*>(lhs);
-
-    // call the parent first.
-    UMLEntityConstraint::copyInto(target);
-
-    // Copy all datamembers
-    target->m_ReferencedEntity = m_ReferencedEntity;
-    target->m_AttributeMap = m_AttributeMap;
-    target->m_DeleteAction = m_DeleteAction;
-    target->m_UpdateAction = m_UpdateAction;
-}
-
-/**
- * Make a clone of the UMLForeignKeyConstraint.
- */
-UMLObject* UMLForeignKeyConstraint::clone() const
-{
-    //FIXME: The new attribute should be slaved to the NEW parent not the old.
-    UMLForeignKeyConstraint *clone = new UMLForeignKeyConstraint(static_cast<UMLObject*>(parent()));
-    copyInto(clone);
-    return clone;
-}
-
-/**
- * Returns a string representation of the UMLForeignKeyConstraint.
- * @param sig   If true will show the attribute type and initial value.
- * @return  Returns a string representation of the UMLAttribute.
- */
-QString UMLForeignKeyConstraint::toString(Uml::SignatureType::Enum sig)
-{
-    QString s;
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
-        s = name() + QLatin1Char(':');
-        s += QLatin1String(" Foreign Key (");
-        QList<UMLEntityAttribute*> keys = m_AttributeMap.keys();
-        bool first = true;
-        foreach(UMLEntityAttribute* key, keys) {
-            if (first) {
-                first = false;
-            } else
-                s += QLatin1Char(',');
-            s += key->name();
-        }
-        s += QLatin1Char(')');
-    }
-
-    return s;
-}
-
-/**
- * Creates the <UML:ForeignKeyConstraint> XMI element.
- */
-void UMLForeignKeyConstraint::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement foreignKeyConstraintElement = UMLObject::save(QLatin1String("UML:ForeignKeyConstraint"), qDoc);
-
-    foreignKeyConstraintElement.setAttribute(QLatin1String("referencedEntity"), Uml::ID::toString(m_ReferencedEntity->id()));
-
-    int updateAction = (int)m_UpdateAction;
-    int deleteAction = (int)m_DeleteAction;
-
-    foreignKeyConstraintElement.setAttribute(QLatin1String("updateAction"), updateAction);
-    foreignKeyConstraintElement.setAttribute(QLatin1String("deleteAction"), deleteAction);
-
-    QMap<UMLEntityAttribute*, UMLEntityAttribute*>::iterator i;
-    for (i = m_AttributeMap.begin(); i!= m_AttributeMap.end() ; ++i) {
-        QDomElement mapElement = qDoc.createElement(QLatin1String("AttributeMap"));
-        mapElement.setAttribute(QLatin1String("key"), Uml::ID::toString((i.key())->id()));
-        mapElement.setAttribute(QLatin1String("value"), Uml::ID::toString((i.value())->id()));
-        foreignKeyConstraintElement.appendChild(mapElement);
-    }
-
-    qElement.appendChild(foreignKeyConstraintElement);
-}
-
-/**
- * Display the properties configuration dialog for the attribute.
- */
-bool UMLForeignKeyConstraint::showPropertiesDialog(QWidget* parent)
-{
-    UMLForeignKeyConstraintDialog dialog(parent, this);
-    return dialog.exec();
-}
-
-/**
- * Adds the attribute pair to the attributeMap
- * @param pAttr The Attribute of the Parent Entity
- * @param rAttr The Attribute of the Referenced Entity
- * @return true if the attribute pair could be added successfully
- */
-bool UMLForeignKeyConstraint::addEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr)
-{
-    UMLEntity *owningParent = dynamic_cast<UMLEntity*>(parent());
-
-    if (pAttr == NULL || rAttr == NULL) {
-        uError() << "null values passed to function";
-        return false;
-    }
-    // check for sanity of pAttr (parent entity attribute)
-    if (owningParent == NULL) {
-        uError() << name() << ": parent is not a UMLEntity";
-        return false;
-    }
-
-    if (owningParent->findChildObjectById(pAttr->id()) == NULL) {
-        uError() << " parent " << owningParent->name()
-                 << " does not contain attribute " << pAttr->name();
-        return false;
-    }
-
-    //check for sanity of rAttr (referenced entity attribute)
-    if (m_ReferencedEntity != NULL) {
-       if (m_ReferencedEntity->findChildObjectById(rAttr->id()) == NULL) {
-        uError() << " parent " << m_ReferencedEntity->name()
-                 << " does not contain attribute " << rAttr->name();
-        return false;
-       }
-    } else {
-        uError() << "Referenced Table Not set. Not Adding Pair ";
-        return false;
-    }
-
-    // check if key takes part in some mapping
-    if (m_AttributeMap.contains(pAttr) == true)
-        return false;
-
-    // check if value takes part in some mapping (no direct function)
-    foreach(UMLEntityAttribute* attr, m_AttributeMap.values()) {
-        if (rAttr == attr)
-            return false;
-    }
-
-    // passed all checks, insert now
-    m_AttributeMap.insert(pAttr, rAttr);
-
-     QMap<UMLEntityAttribute*, UMLEntityAttribute*>::iterator i;
-     for (i = m_AttributeMap.begin(); i != m_AttributeMap.end(); ++i)
-         uDebug() << i.key()->name() << QLatin1String(" ") << i.key()->baseType()
-                 << QLatin1String(" ") << i.value()->name() << QLatin1String(" ") << i.value()->baseType();
-
-     return true;
-}
-
-/**
- * Removes an Attribute pair
- * @param pAttr The Attribute of the Parent Entity in the map. This attribute is the
-                key of the map.
- * @return true of the attribute pair could be removed successfully
- */
-bool UMLForeignKeyConstraint::removeEntityAttributePair(UMLEntityAttribute* /*key*/ pAttr)
-{
-    bool state = m_AttributeMap.remove(pAttr);
-
-    return state;
-}
-
-/**
- * Check if a attribute pair already exists
- * @param pAttr The Attribute of the Parent Entity
- * @param rAttr The Attribute of the Referenced Entity
- * @return true if the attribute pair could be found.
- */
-bool UMLForeignKeyConstraint::hasEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr) const
-{
-    if (m_AttributeMap.contains(pAttr)) {
-        if (m_AttributeMap.value(pAttr) == rAttr) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-/**
- * Loads the <UML:ForeignKeyConstraint> XMI element.
- */
-bool UMLForeignKeyConstraint::load(QDomElement & element)
-{
-    UMLDoc* doc = UMLApp::app()->document();
-
-    Uml::ID::Type referencedEntityId = Uml::ID::fromString(element.attribute(QLatin1String("referencedEntity")));
-
-    UMLObject* obj = doc->findObjectById(referencedEntityId);
-    m_ReferencedEntity = static_cast<UMLEntity*>(obj);
-
-    if (m_ReferencedEntity == NULL) {
-        // save for resolving later
-        m_pReferencedEntityID = referencedEntityId;
-    }
-
-    m_UpdateAction = (UpdateDeleteAction)element.attribute(QLatin1String("updateAction")).toInt();
-    m_DeleteAction = (UpdateDeleteAction)element.attribute(QLatin1String("deleteAction")).toInt();
-
-    QDomNode node = element.firstChild();
-    while (!node.isNull()) {
-        if (node.isComment()) {
-            node = node.nextSibling();
-            continue;
-        }
-        QDomElement tempElement = node.toElement();
-        QString tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("AttributeMap"))) {
-
-            QString xmiKey = tempElement.attribute(QLatin1String("key"));
-            QString xmiValue = tempElement.attribute(QLatin1String("value"));
-            Uml::ID::Type keyId = Uml::ID::fromString(xmiKey);
-            Uml::ID::Type valueId = Uml::ID::fromString(xmiValue);
-
-            UMLEntity* parentEntity = static_cast<UMLEntity*>(parent());
-            UMLObject* keyObj = parentEntity->findChildObjectById(keyId);
-            UMLEntityAttribute* key = static_cast<UMLEntityAttribute*>(keyObj);
-
-            if (keyObj == NULL) {
-                uWarning() << "unable to resolve foreign key referencing attribute " << xmiKey;
-            } else if (m_ReferencedEntity == NULL) {
-                // if referenced entity is null, then we won't find its attributes even
-                // save for resolving later
-                m_pEntityAttributeIDMap.insert(key, valueId);
-            } else {
-                UMLObject* valueObj = m_ReferencedEntity->findChildObjectById(valueId);
-                if (valueObj == NULL) {
-                    uWarning() << "unable to resolve foreign key referenced attribute" << xmiValue;
-                } else {
-                    m_AttributeMap[key] = static_cast<UMLEntityAttribute*>(valueObj);
-                }
-            }
-
-        } else {
-            uWarning() << "unknown child type in UMLForeignKeyConstraint::load";
-        }
-
-        node = node.nextSibling();
-    }
-
-    return true;
-}
-
-/**
- * Set the Referenced Entity.
- * @param ent The Entity to Reference
- */
-void UMLForeignKeyConstraint::setReferencedEntity(UMLEntity* ent)
-{
-    if (ent == m_ReferencedEntity)
-        return;
-
-    m_ReferencedEntity = ent;
-
-    emit sigReferencedEntityChanged();
-}
-
-/**
- * Get the Referenced Entity.
- * @return the UML entity object
- */
-UMLEntity* UMLForeignKeyConstraint::getReferencedEntity() const
-{
-    return m_ReferencedEntity;
-}
-
-/**
- * Slot for referenced entity changed.
- */
-void UMLForeignKeyConstraint::slotReferencedEntityChanged()
-{
-    // clear all mappings
-    m_AttributeMap.clear();
-}
-
-/**
- * Clears all mappings between local and referenced attributes
- */
-void UMLForeignKeyConstraint::clearMappings()
-{
-    m_AttributeMap.clear();
-}
-
-/**
- * Remimplementation from base classes
- * Used to resolve forward references to referenced entities in xmi
- */
-bool UMLForeignKeyConstraint::resolveRef()
-{
-    // resolve referenced entity first
-    UMLDoc* doc = UMLApp::app()->document();
-
-    bool success = true;
-
-    //resolve the referenced entity
-    if (!Uml::ID::toString(m_pReferencedEntityID).isEmpty()) {
-        UMLObject* obj = doc->findObjectById(m_pReferencedEntityID);
-        m_ReferencedEntity = static_cast<UMLEntity*>(obj);
-        if (m_ReferencedEntity == NULL) {
-            success = false;
-        }
-    }
-
-    QMap<UMLEntityAttribute*, Uml::ID::Type>::iterator i;
-    for (i = m_pEntityAttributeIDMap.begin(); i!= m_pEntityAttributeIDMap.end() ; ++i) {
-       if (!Uml::ID::toString(i.value()).isEmpty()) {
-           UMLObject* obj = doc->findObjectById(i.value());
-           m_AttributeMap[i.key()] = static_cast<UMLEntityAttribute*>(obj);
-           if (m_AttributeMap[i.key()] == NULL) {
-               success = false;
-           }
-       }
-    }
-
-    return success;
-}
-
-/**
- * Retrieve all Pairs of Attributes.
- */
-QMap<UMLEntityAttribute*, UMLEntityAttribute*> UMLForeignKeyConstraint::getEntityAttributePairs()
-{
-    return m_AttributeMap;
-}
-
-/**
- * Get the Delete Action.
- */
-UMLForeignKeyConstraint::UpdateDeleteAction UMLForeignKeyConstraint::getDeleteAction() const
-{
-    return m_DeleteAction;
-}
-
-/**
- * Get the Update Action.
- */
-UMLForeignKeyConstraint::UpdateDeleteAction UMLForeignKeyConstraint::getUpdateAction() const
-{
-    return m_UpdateAction;
-}
-
-/**
- * Set the Delete Action to the specified UpdateDeleteAction.
- */
-void UMLForeignKeyConstraint::setDeleteAction(UpdateDeleteAction uda)
-{
-    m_DeleteAction = uda;
-}
-
-/**
- * Set the Update Action to the specified UpdateDeleteAction
- */
-void UMLForeignKeyConstraint::setUpdateAction(UpdateDeleteAction uda)
-{
-    m_UpdateAction = uda;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/foreignkeyconstraint.h umbrello-15.08.1/umbrello/foreignkeyconstraint.h
--- umbrello-15.08.1.orig/umbrello/foreignkeyconstraint.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/foreignkeyconstraint.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,120 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef FOREIGNKEYCONSTRAINT_H
-#define FOREIGNKEYCONSTRAINT_H
-
-// appl includes
-#include "basictypes.h"
-#include "entityconstraint.h"
-
-// qt includes
-#include <QMap>
-
-//forward declarations
-class UMLEntityAttribute;
-class UMLEntity;
-
-/**
- * This class is used to set up information for a foreign key entity constraint.
- * @short Sets up Foreign Key  entity constraint information.
- * @author Sharan Rao
- * @see UMLObject UMLClassifierListItem UMLEntityConstraint
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLForeignKeyConstraint : public UMLEntityConstraint
-{
-     Q_OBJECT
-
-public:
-
-    /**
-     * Update/Delete Action: Action to be taken on Update or Delete of a referenced attribute
-     * is either, No Action, Restrict, Cascade, Set NULL, Set Default.
-     */
-    enum UpdateDeleteAction { uda_NoAction = 0,
-                              uda_Restrict,
-                              uda_Cascade,
-                              uda_SetNull,
-                              uda_SetDefault };
-
-    UMLForeignKeyConstraint(UMLObject *parent, const QString& name,
-                            Uml::ID::Type id = Uml::ID::None);
-    explicit UMLForeignKeyConstraint(UMLObject *parent);
-
-    bool operator==(const UMLForeignKeyConstraint &rhs) const;
-
-    virtual ~UMLForeignKeyConstraint();
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    void setReferencedEntity(UMLEntity* ent);
-    UMLEntity* getReferencedEntity() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-    bool addEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr);
-
-    bool removeEntityAttributePair(UMLEntityAttribute* /*key*/ pAttr);
-
-    bool hasEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr) const;
-
-    QMap<UMLEntityAttribute*, UMLEntityAttribute*> getEntityAttributePairs();
-
-    void setDeleteAction(UpdateDeleteAction uda);
-    UpdateDeleteAction getDeleteAction() const;
-
-    void setUpdateAction(UpdateDeleteAction uda);
-    UpdateDeleteAction getUpdateAction() const;
-
-    void clearMappings();
-
-    bool resolveRef();
-
-signals:
-    void sigReferencedEntityChanged();
-
-private slots:
-    void slotReferencedEntityChanged();
-
-protected:
-    bool load(QDomElement & element);
-
-private:
-
-    Uml::ID::Type m_pReferencedEntityID;  ///< Used to resolve forward references to UMLEntity.
-
-    /**
-     * Used to resolve forward references to UMLEntityAttributes
-     * Key -> The local attribute
-     * Value -> Id of the attribute it is mapping to
-     */
-    QMap<UMLEntityAttribute*, Uml::ID::Type> m_pEntityAttributeIDMap;
-
-    void init();
-
-    UMLEntity* m_ReferencedEntity;  ///< The UMLEntity that this foreign key references.
-
-    /**
-     * Stores the Mapping of attributes between parent table and referenced table
-     */
-    QMap<UMLEntityAttribute*, UMLEntityAttribute*> m_AttributeMap;
-
-    UpdateDeleteAction m_UpdateAction;  ///< What to do on Update of referenced attributes.
-    UpdateDeleteAction m_DeleteAction;  ///< What to do on Deletion of referenced attributes.
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/listpopupmenu.cpp umbrello-15.08.1/umbrello/listpopupmenu.cpp
--- umbrello-15.08.1.orig/umbrello/listpopupmenu.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/listpopupmenu.cpp	2015-10-08 11:48:59.500089026 +0300
@@ -1195,7 +1195,6 @@
 void ListPopupMenu::makeClassifierShowPopup(ClassifierWidget *c)
 {
     WidgetBase::WidgetType type = c->baseType();
-    ClassifierWidget *cls = NULL;

 #if QT_VERSION >= 0x050000
     QMenu* show = new QMenu(i18n("Show"), this);
@@ -1208,9 +1207,8 @@
     setActionChecked(mt_Show_Documentation, c->visualProperty(ClassifierWidget::ShowDocumentation));
 #endif
     if (type == WidgetBase::wt_Class) {
-        cls = static_cast<ClassifierWidget*>(c);
         insert(mt_Show_Attributes, show, i18n("Attributes"), CHECKABLE);
-        setActionChecked(mt_Show_Attributes, cls->visualProperty(ClassifierWidget::ShowAttributes));
+        setActionChecked(mt_Show_Attributes, c->visualProperty(ClassifierWidget::ShowAttributes));
     }
     insert(mt_Show_Operations, show, i18n("Operations"), CHECKABLE);
     setActionChecked(mt_Show_Operations, c->visualProperty(ClassifierWidget::ShowOperations));
@@ -1224,16 +1222,14 @@
     setActionChecked(mt_Show_Operation_Signature, sig);
     if (type == WidgetBase::wt_Class) {
         insert(mt_Show_Attribute_Signature, show, i18n("Attribute Signature"), CHECKABLE);
-        sig = (cls->attributeSignature() == Uml::SignatureType::SigNoVis ||
-               cls->attributeSignature() == Uml::SignatureType::ShowSig);
+        sig = (c->attributeSignature() == Uml::SignatureType::SigNoVis ||
+               c->attributeSignature() == Uml::SignatureType::ShowSig);
         setActionChecked(mt_Show_Attribute_Signature, sig);
     }
     insert(mt_Show_Packages, show, i18n("Package"), CHECKABLE);
     setActionChecked(mt_Show_Packages, c->visualProperty(ClassifierWidget::ShowPackage));
-    if (type == WidgetBase::wt_Class) {
-        insert(mt_Show_Stereotypes, show, i18n("Stereotype"), CHECKABLE);
-        setActionChecked(mt_Show_Stereotypes, cls->visualProperty(ClassifierWidget::ShowStereotype));
-    }
+    insert(mt_Show_Stereotypes, show, i18n("Stereotype"), CHECKABLE);
+    setActionChecked(mt_Show_Stereotypes, c->visualProperty(ClassifierWidget::ShowStereotype));
     addMenu(show);
 }

diff -Nuar umbrello-15.08.1.orig/umbrello/node.cpp umbrello-15.08.1/umbrello/node.cpp
--- umbrello-15.08.1.orig/umbrello/node.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/node.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,68 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "node.h"
-
-#include <KLocalizedString>
-
-/**
- * Sets up a Node.
- *
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLNode::UMLNode(const QString & name, Uml::ID::Type id)
-  : UMLCanvasObject(name, id)
-{
-    init();
-}
-
-/**
- * Destructor.
- */
-UMLNode::~UMLNode()
-{
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLNode::init()
-{
-    m_BaseType = UMLObject::ot_Node;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLNode::clone() const
-{
-    UMLNode *clone = new UMLNode();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the <UML:Node> XMI element.
- */
-void UMLNode::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement nodeElement = UMLObject::save(QLatin1String("UML:Node"), qDoc);
-    qElement.appendChild(nodeElement);
-}
-
-/**
- * Loads the <UML:Node> XMI element (empty.)
- */
-bool UMLNode::load(QDomElement&)
-{
-    return true;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/node.h umbrello-15.08.1/umbrello/node.h
--- umbrello-15.08.1.orig/umbrello/node.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/node.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,46 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef NODE_H
-#define NODE_H
-
-#include "umlcanvasobject.h"
-
-/**
- * This class contains the non-graphical information required for a UML Node.
- * This class inherits from @ref UMLCanvasObject which contains most of the
- * information.
- *
- * @short Non-graphical information for a Node.
- * @author Jonathan Riddell
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLNode : public UMLCanvasObject
-{
-    Q_OBJECT
-public:
-
-    explicit UMLNode(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLNode();
-
-    virtual void init();
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-
-    bool load(QDomElement & element);
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/operation.cpp umbrello-15.08.1/umbrello/operation.cpp
--- umbrello-15.08.1.orig/umbrello/operation.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/operation.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,611 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "operation.h"
-
-// app includes
-#include "attribute.h"
-#include "classifier.h"
-#include "model_utils.h"
-#include "debug_utils.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "uniqueid.h"
-#include "umloperationdialog.h"
-#include "codegenerator.h"
-#include "codedocument.h"
-#include "codeblock.h"
-
-// kde includes
-#include <KLocalizedString>
-
-// qt includes
-#include <QRegExp>
-
-/**
- * Constructs an UMLOperation.
- * Not intended for general use: The operation is not tied in with
- * umbrello's Qt signalling for object creation.
- * If you want to create an Operation use the method in UMLDoc instead.
- *
- * @param parent    the parent to this operation
- * @param name      the name of the operation
- * @param id        the id of the operation
- * @param s         the visibility of the operation
- * @param rt        the return type of the operation
- */
-UMLOperation::UMLOperation(UMLClassifier *parent, const QString& name,
-                           Uml::ID::Type id, Uml::Visibility::Enum s, UMLObject *rt)
-  : UMLClassifierListItem(parent, name, id)
-{
-    if (rt)
-        m_returnId = UniqueID::gen();
-    else
-        m_returnId = Uml::ID::None;
-    m_pSecondary = rt;
-    m_visibility = s;
-    m_BaseType = UMLObject::ot_Operation;
-    m_bConst = false;
-    m_Code.clear();
-}
-
-/**
- * Constructs an UMLOperation.
- * Not intended for general use: The operation is not tied in with
- * umbrello's Qt signalling for object creation.
- * If you want to create an Operation use the method in UMLDoc instead.
- *
- * @param parent    the parent to this operation
- */
-UMLOperation::UMLOperation(UMLClassifier * parent)
-  : UMLClassifierListItem (parent)
-{
-    m_BaseType = UMLObject::ot_Operation;
-    m_bConst = false;
-    m_Code.clear();
-}
-
-/**
- * Destructor.
- */
-UMLOperation::~UMLOperation()
-{
-}
-
-/**
- * Reimplement method from UMLClassifierListItem.
- *
- * @param type      pointer to the type object
- */
-void UMLOperation::setType(UMLObject* type)
-{
-    UMLClassifierListItem::setType(type);
-    if (m_returnId == Uml::ID::None)
-        m_returnId = UniqueID::gen();
-}
-
-/**
- * Move a parameter one position to the left.
- *
- * @param a   the parameter to move
- */
-void UMLOperation::moveParmLeft(UMLAttribute * a)
-{
-    if (a == NULL) {
-        uDebug() << "called on NULL attribute";
-        return;
-    }
-    uDebug() << "called for " << a->name();
-    disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
-    int idx;
-    if ((idx=m_List.indexOf(a)) == -1) {
-        uDebug() << "Error move parm left " << a->name();
-        return;
-    }
-    if (idx == 0)
-        return;
-    m_List.removeAll(a);
-    m_List.insert(idx-1, a);
-}
-
-/**
- * Move a parameter one position to the right.
- *
- * @param a   the parameter to move
- */
-void UMLOperation::moveParmRight(UMLAttribute * a)
-{
-    if (a == NULL) {
-        uDebug() << "called on NULL attribute";
-        return;
-    }
-    uDebug() << "called for " << a->name();
-    disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
-    int idx;
-    if ((idx=m_List.indexOf(a)) == -1) {
-        uDebug() << "Error move parm right " << a->name();
-        return;
-    }
-    int count = m_List.count();
-    if (idx == count-1)
-        return;
-    m_List.removeAll(a);
-    m_List.insert(idx+1, a);
-}
-
-/**
- * Remove a parameter from the operation.
- *
- * @param a         the parameter to remove
- * @param emitModifiedSignal  whether to emit the "modified" signal
- *                  which creates an entry in the Undo stack for the
- *                  removal, default: true
- */
-void UMLOperation::removeParm(UMLAttribute * a, bool emitModifiedSignal /* =true */)
-{
-    if (a == NULL) {
-        uDebug() << "called on NULL attribute";
-        return;
-    }
-    uDebug() << "called for " << a->name();
-    disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
-    if(!m_List.removeAll(a))
-        uDebug() << "Error removing parm " << a->name();
-
-    if (emitModifiedSignal)
-        emit modified();
-}
-
-/**
- * Returns a list of parameters.
- *
- * @return a list of the parameters in the operation
- */
-UMLAttributeList UMLOperation::getParmList() const
-{
-    return m_List;
-}
-
-/**
- * Finds a parameter of the operation.
- *
- * @param name      the parameter name to search for
- * @return          the found parameter, 0 if not found
- */
-UMLAttribute* UMLOperation::findParm(const QString &name)
-{
-    UMLAttribute * obj=0;
-    foreach (obj, m_List) {
-        if (obj->name() == name)
-            return obj;
-    }
-    return 0;
-}
-
-/**
- * Returns a string representation of the operation.
- *
- * @param sig       what type of operation string to show
- * @return          the string representation of the operation
- */
-QString UMLOperation::toString(Uml::SignatureType::Enum sig)
-{
-    QString s;
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::NoSig)
-          s = Uml::Visibility::toString(m_visibility, true) + QLatin1Char(' ');
-
-    s += name();
-    Uml::ProgrammingLanguage::Enum pl = UMLApp::app()->activeLanguage();
-    bool parameterlessOpNeedsParentheses =
-        (pl != Uml::ProgrammingLanguage::Pascal && pl != Uml::ProgrammingLanguage::Ada);
-
-    if (sig == Uml::SignatureType::NoSig || sig == Uml::SignatureType::NoSigNoVis) {
-        if (parameterlessOpNeedsParentheses)
-            s.append(QLatin1String("()"));
-        return s;
-    }
-    int last = m_List.count();
-    if (last) {
-        s.append(QLatin1String("("));
-        int i = 0;
-        foreach (UMLAttribute *param, m_List) {
-            i++;
-            s.append(param->toString(Uml::SignatureType::SigNoVis));
-            if (i < last)
-                s.append(QLatin1String(", "));
-        }
-        s.append(QLatin1String(")"));
-    } else if (parameterlessOpNeedsParentheses) {
-        s.append(QLatin1String("()"));
-    }
-    UMLClassifier *ownParent = static_cast<UMLClassifier*>(parent());
-    QString returnType;
-    UMLClassifier *retType = UMLClassifierListItem::getType();
-    if (retType) {
-        UMLPackage *retVisibility = retType->umlPackage();
-        if (retVisibility != ownParent && retVisibility != ownParent->umlPackage())
-            returnType = retType->fullyQualifiedName();
-        else
-            returnType = retType->name();
-    }
-    if (returnType.length() > 0 && returnType != QLatin1String("void")) {
-        s.append(QLatin1String(" : "));
-
-        if (returnType.startsWith(QLatin1String(QLatin1String("virtual ")))) {
-            s += returnType.mid(8);
-        } else {
-            s += returnType;
-        }
-    }
-    return s;
-}
-
-/**
- * Add a parameter to the operation.
- *
- * @param parameter the parameter to add
- * @param position  the position in the parameter list.
- *                  If position = -1 the parameter will be
- *                  appended to the list.
- */
-void UMLOperation::addParm(UMLAttribute *parameter, int position)
-{
-    if(position >= 0 && position <= (int)m_List.count())
-        m_List.insert(position, parameter);
-    else
-        m_List.append(parameter);
-    UMLObject::emitModified();
-    connect(parameter, SIGNAL(modified()), this, SIGNAL(modified()));
-}
-
-/**
- * Returns an unused parameter name for a new parameter.
- */
-QString UMLOperation::getUniqueParameterName()
-{
-    QString currentName = i18n("new_parameter");
-    QString name = currentName;
-    for (int number = 1; findParm(name); ++number) {
-        name = currentName + QLatin1Char('_') + QString::number(number);
-    }
-    return name;
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLOperation::operator==(const UMLOperation & rhs) const
-{
-    if (this == &rhs)
-        return true;
-
-    if (!UMLObject::operator==(rhs))
-        return false;
-
-    if (getTypeName() != rhs.getTypeName())
-        return false;
-
-    if (m_List.count() != rhs.m_List.count())
-        return false;
-
-    if (!(m_List == rhs.m_List))
-        return false;
-
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLOperation::copyInto(UMLObject *lhs) const
-{
-    UMLOperation *target = static_cast<UMLOperation*>(lhs);
-
-    UMLClassifierListItem::copyInto(target);
-
-    m_List.copyInto(&(target->m_List));
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLOperation::clone() const
-{
-    //FIXME: The new operation should be slaved to the NEW parent not the old.
-    UMLOperation *clone = new UMLOperation(static_cast<UMLClassifier*>(parent()));
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Calls resolveRef() on all parameters.
- * Needs to be called after all UML objects are loaded from file.
- *
- * @return  true for success
- */
-bool UMLOperation::resolveRef()
-{
-    bool overallSuccess = UMLObject::resolveRef();
-    // See remark on iteration style in UMLClassifier::resolveRef()
-    foreach (UMLAttribute* pAtt, m_List) {
-        if (! pAtt->resolveRef())
-            overallSuccess = false;
-    }
-    return overallSuccess;
-}
-
-/**
- * Returns whether this operation is a constructor.
- *
- * @return  true if this operation is a constructor
- */
-bool UMLOperation::isConstructorOperation()
-{
-    // if an operation has the stereotype constructor
-    // return true
-    if (stereotype() == QLatin1String("constructor"))
-        return true;
-
-    UMLClassifier * c = static_cast<UMLClassifier*>(this->parent());
-    QString cName = c->name();
-    QString opName = name();
-    // It's a constructor operation if the operation name
-    // matches that of the parent classifier.
-    return (cName == opName);
-}
-
-/**
- * Returns whether this operation is a destructor.
- *
- * @return  true if this operation is a destructor
- */
-bool UMLOperation::isDestructorOperation()
-{
-    if (stereotype() == QLatin1String("destructor"))
-        return true;
-    UMLClassifier * c = static_cast<UMLClassifier*>(this->parent());
-
-    QString cName = c->name();
-    QString opName = name();
-    // Special support for C++ syntax:
-    // It's a destructor operation if the operation name begins
-    // with "~" followed by the name of the parent classifier.
-    if (! opName.startsWith(QLatin1Char('~')))
-        return false;
-    opName.remove(QRegExp(QLatin1String("^~\\s*")));
-    return (cName == opName);
-}
-
-/**
- * Shortcut for (isConstructorOperation() || isDestructorOperation()).
- *
- * @return  true if this operation is a constructor or destructor
- */
-bool UMLOperation::isLifeOperation()
-{
-    return (isConstructorOperation() || isDestructorOperation());
-}
-
-/**
- * Sets whether this operation is a query (C++ "const").
- */
-void UMLOperation::setConst(bool b)
-{
-    m_bConst = b;
-}
-
-/**
- * Returns whether this operation is a query (C++ "const").
- */
-bool UMLOperation::getConst() const
-{
-    return m_bConst;
-}
-
-/**
- * Display the properties configuration dialog for the template.
- *
- * @param parent   the parent for the dialog
- */
-bool UMLOperation::showPropertiesDialog(QWidget* parent)
-{
-    UMLOperationDialog dialog(parent, this);
-    return dialog.exec();
-}
-
-/**
- * Sets the source code for this operation.
- *
- * @param code  the body of this operation
- */
-void UMLOperation::setSourceCode(const QString& code)
-{
-    m_Code = code;
-}
-
-/**
- * Returns the source code for this operation.
- */
-QString UMLOperation::getSourceCode() const
-{
-    return m_Code;
-}
-
-/**
- * Saves to the <UML:Operation> XMI element.
- */
-void UMLOperation::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement operationElement = UMLObject::save(QLatin1String("UML:Operation"), qDoc);
-    operationElement.setAttribute(QLatin1String("isQuery"), m_bConst ? QLatin1String("true") : QLatin1String("false"));
-    QDomElement featureElement = qDoc.createElement(QLatin1String("UML:BehavioralFeature.parameter"));
-    if (m_pSecondary) {
-        QDomElement retElement = qDoc.createElement(QLatin1String("UML:Parameter"));
-        if (m_returnId == Uml::ID::None) {
-            uDebug() << name() << ": m_returnId is not set, setting it now.";
-            m_returnId = UniqueID::gen();
-        }
-        retElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(m_returnId));
-        retElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
-        retElement.setAttribute(QLatin1String("kind"), QLatin1String("return"));
-        featureElement.appendChild(retElement);
-    } else {
-        uDebug() << "m_SecondaryId is " << m_SecondaryId;
-    }
-
-    //save each attribute here, type different
-    foreach(UMLAttribute* pAtt, m_List) {
-        QDomElement attElement = pAtt->UMLObject::save(QLatin1String("UML:Parameter"), qDoc);
-        UMLClassifier *attrType = pAtt->getType();
-        if (attrType) {
-            attElement.setAttribute(QLatin1String("type"), Uml::ID::toString(attrType->id()));
-        } else {
-            attElement.setAttribute(QLatin1String("type"), pAtt->getTypeName());
-        }
-        attElement.setAttribute(QLatin1String("value"), pAtt->getInitialValue());
-
-        Uml::ParameterDirection::Enum kind = pAtt->getParmKind();
-        if (kind == Uml::ParameterDirection::Out)
-            attElement.setAttribute(QLatin1String("kind"), QLatin1String("out"));
-        else if (kind == Uml::ParameterDirection::InOut)
-            attElement.setAttribute(QLatin1String("kind"), QLatin1String("inout"));
-        // The default for the parameter kind is "in".
-
-        featureElement.appendChild(attElement);
-    }
-    if (featureElement.hasChildNodes()) {
-        operationElement.appendChild(featureElement);
-    }
-    qElement.appendChild(operationElement);
-}
-
-/**
- * Loads a <UML:Operation> XMI element.
- */
-bool UMLOperation::load(QDomElement & element)
-{
-    m_SecondaryId = element.attribute(QLatin1String("type"));
-    QString isQuery = element.attribute(QLatin1String("isQuery"));
-    if (!isQuery.isEmpty()) {
-        // We need this extra test for isEmpty() because load() might have been
-        // called again by the processing for BehavioralFeature.parameter (see below)
-        m_bConst = (isQuery == QLatin1String("true"));
-    }
-    QDomNode node = element.firstChild();
-    if (node.isComment())
-        node = node.nextSibling();
-    QDomElement attElement = node.toElement();
-    while (!attElement.isNull()) {
-        QString tag = attElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("BehavioralFeature.parameter")) ||
-            UMLDoc::tagEq(tag, QLatin1String("Element.ownedElement"))) {  // Embarcadero's Describe
-            if (! load(attElement))
-                return false;
-        } else if (UMLDoc::tagEq(tag, QLatin1String("Parameter"))) {
-            QString kind = attElement.attribute(QLatin1String("kind"));
-            if (kind.isEmpty()) {
-                kind = attElement.attribute(QLatin1String("direction"));  // Embarcadero's Describe
-                if (kind.isEmpty()) {
-                    // Perhaps the kind is stored in a child node:
-                    for (QDomNode n = attElement.firstChild(); !n.isNull(); n = n.nextSibling()) {
-                        if (n.isComment())
-                            continue;
-                        QDomElement tempElement = n.toElement();
-                        QString tag = tempElement.tagName();
-                        if (!UMLDoc::tagEq(tag, QLatin1String("kind")))
-                            continue;
-                        kind = tempElement.attribute(QLatin1String("xmi.value"));
-                        break;
-                    }
-                }
-                if (kind.isEmpty()) {
-                    kind = QLatin1String("in");
-                }
-            }
-            if (kind == QLatin1String("return") ||
-                kind == QLatin1String("result")) {  // Embarcadero's Describe
-                QString returnId = Model_Utils::getXmiId(attElement);
-                if (!returnId.isEmpty())
-                    m_returnId = Uml::ID::fromString(returnId);
-                m_SecondaryId = attElement.attribute(QLatin1String("type"));
-                if (m_SecondaryId.isEmpty()) {
-                    // Perhaps the type is stored in a child node:
-                    QDomNode node = attElement.firstChild();
-                    while (!node.isNull()) {
-                        if (node.isComment()) {
-                            node = node.nextSibling();
-                            continue;
-                        }
-                        QDomElement tempElement = node.toElement();
-                        QString tag = tempElement.tagName();
-                        if (!UMLDoc::tagEq(tag, QLatin1String("type"))) {
-                            node = node.nextSibling();
-                            continue;
-                        }
-                        m_SecondaryId = Model_Utils::getXmiId(tempElement);
-                        if (m_SecondaryId.isEmpty())
-                            m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
-                        if (m_SecondaryId.isEmpty()) {
-                            QDomNode inner = node.firstChild();
-                            QDomElement tmpElem = inner.toElement();
-                            m_SecondaryId = Model_Utils::getXmiId(tmpElem);
-                            if (m_SecondaryId.isEmpty())
-                                m_SecondaryId = tmpElem.attribute(QLatin1String("xmi.idref"));
-                        }
-                        break;
-                    }
-                    if (m_SecondaryId.isEmpty()) {
-                        uError() << name() << ": cannot find return type.";
-                    }
-                }
-                // Use deferred xmi.id resolution.
-                m_pSecondary = NULL;
-            } else {
-                UMLAttribute * pAtt = new UMLAttribute(this);
-                if(!pAtt->loadFromXMI(attElement)) {
-                    delete pAtt;
-                    return false;
-                }
-                if (kind == QLatin1String("out"))
-                    pAtt->setParmKind(Uml::ParameterDirection::Out);
-                else if (kind == QLatin1String("inout"))
-                    pAtt->setParmKind(Uml::ParameterDirection::InOut);
-                else
-                    pAtt->setParmKind(Uml::ParameterDirection::In);
-                m_List.append(pAtt);
-            }
-        }
-        node = node.nextSibling();
-        if (node.isComment())
-            node = node.nextSibling();
-        attElement = node.toElement();
-
-        // loading the source code which was entered in the 'classpropdlg' dialog is not done
-        // with the following code, because there is no CodeDocument.
-        /*
-        CodeGenerator* codegen = UMLApp::app()->getGenerator();
-        if (codegen) {
-            uDebug() << "CodeDocument searching with id=" << Uml::ID::toString(UMLObject::ID());
-            CodeDocument* codeDoc = codegen->findCodeDocumentByID(Uml::ID::toString(UMLObject::ID()));
-            if (codeDoc) {
-                uDebug() << "CodeDocument found:\n" << codeDoc;
-            }
-        }
-        */
-        // it is done in the code generators by calling CodeGenerator::loadFromXMI(...).
-
-    }//end while
-    return true;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/operation.h umbrello-15.08.1/umbrello/operation.h
--- umbrello-15.08.1.orig/umbrello/operation.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/operation.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,84 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef OPERATION_H
-#define OPERATION_H
-
-#include "umlattributelist.h"
-#include "classifierlistitem.h"
-
-class UMLClassifier;
-
-/**
- * This class represents an operation in the UML model.
- *
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLOperation : public UMLClassifierListItem
-{
-    Q_OBJECT
-public:
-    UMLOperation(UMLClassifier * parent, const QString& name,
-                 Uml::ID::Type id = Uml::ID::None,
-                 Uml::Visibility::Enum s = Uml::Visibility::Public,
-                 UMLObject *rt = 0);
-    explicit UMLOperation(UMLClassifier * parent);
-    virtual ~UMLOperation();
-
-    bool operator==(const UMLOperation & rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    void setType(UMLObject* type);
-
-    void moveParmLeft(UMLAttribute *a);
-    void moveParmRight(UMLAttribute *a);
-
-    void removeParm(UMLAttribute *a, bool emitModifiedSignal = true);
-
-    UMLAttributeList getParmList() const;
-
-    UMLAttribute * findParm(const QString &name);
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    void addParm(UMLAttribute *parameter, int position = -1);
-
-    bool resolveRef();
-
-    QString getUniqueParameterName();
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-    bool isConstructorOperation();
-    bool isDestructorOperation();
-    bool isLifeOperation();
-
-    void setConst(bool b);
-    bool getConst() const;
-
-    void setSourceCode(const QString& code);
-    QString getSourceCode() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-    bool load(QDomElement & element);
-
-private:
-    Uml::ID::Type    m_returnId;  ///< Holds the xmi.id of the <UML:Parameter kind="return">
-    UMLAttributeList m_List;      ///< Parameter list
-    bool             m_bConst;    ///< Holds the isQuery attribute of the <UML:Operation>
-    QString          m_Code;      ///< Holds the entered source code
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/org.kde.umbrello.appdata.xml umbrello-15.08.1/umbrello/org.kde.umbrello.appdata.xml
--- umbrello-15.08.1.orig/umbrello/org.kde.umbrello.appdata.xml	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/org.kde.umbrello.appdata.xml	2015-10-08 11:48:59.501089026 +0300
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<component type="desktop">
+  <id>org.kde.umbrello.desktop</id>
+  <metadata_license>CC0-1.0</metadata_license>
+  <project_license>GPL-2.0+</project_license>
+  <name>Umbrello</name>
+  <name xml:lang="ca">Umbrello</name>
+  <name xml:lang="cs">Umbrello</name>
+  <name xml:lang="de">Umbrello</name>
+  <name xml:lang="en-GB">Umbrello</name>
+  <name xml:lang="es">Umbrello</name>
+  <name xml:lang="et">Umbrello</name>
+  <name xml:lang="fi">Umbrello</name>
+  <name xml:lang="gl">Umbrello</name>
+  <name xml:lang="it">Umbrello</name>
+  <name xml:lang="nl">Umbrello</name>
+  <name xml:lang="pl">Umbrello</name>
+  <name xml:lang="pt">Umbrello</name>
+  <name xml:lang="pt-BR">Umbrello</name>
+  <name xml:lang="sk">Umbrello</name>
+  <name xml:lang="sl">Umbrello</name>
+  <name xml:lang="sv">Umbrello</name>
+  <name xml:lang="uk">Umbrello</name>
+  <name xml:lang="x-test">xxUmbrelloxx</name>
+  <summary>UML Modeller</summary>
+  <summary xml:lang="ca">Modelador UML</summary>
+  <summary xml:lang="cs">UML modelář</summary>
+  <summary xml:lang="de">UML-Modeller</summary>
+  <summary xml:lang="en-GB">UML Modeller</summary>
+  <summary xml:lang="es">Modelador UML</summary>
+  <summary xml:lang="et">UML-i modelleerimise rakendus</summary>
+  <summary xml:lang="fi">UML-mallinnusohjelma</summary>
+  <summary xml:lang="gl">Modelador de UML</summary>
+  <summary xml:lang="it">Modellatore UML</summary>
+  <summary xml:lang="nl">UML-modeller</summary>
+  <summary xml:lang="pl">Program do modelowania UML</summary>
+  <summary xml:lang="pt">Modelador de UML</summary>
+  <summary xml:lang="pt-BR">Modelador de UML</summary>
+  <summary xml:lang="sk">Modelár UML</summary>
+  <summary xml:lang="sl">Modelirnik UML</summary>
+  <summary xml:lang="sv">UML-modellering</summary>
+  <summary xml:lang="uk">Засіб моделювання UML</summary>
+  <summary xml:lang="x-test">xxUML Modellerxx</summary>
+  <description>
+    <p>
+      Umbrello is a Unified Modelling Language (UML) modelling tool and code generator.
+      It can create diagrams of software and other systems in the industry-standard UML format, and can also generate code from UML diagrams
+      in a variety of programming languages.
+    </p>
+    <p xml:lang="ca">L'Umbrello és una eina de modelatge de Llenguatge Unificat de Modelatge (UML) i generador de codi. Pot crear diagrames de programari i altres sistemes en el format UML estàndard de la indústria, i també pot generar codi des de diagrames UML en diversos llenguatges de programació.</p>
+    <p xml:lang="en-GB">Umbrello is a Unified Modelling Language (UML) modelling tool and code generator. It can create diagrams of software and other systems in the industry-standard UML format, and can also generate code from UML diagrams in a variety of programming languages.</p>
+    <p xml:lang="es">Umbrello es una herramienta de modelado y de generación de código para el lenguaje unificado de modelado (UML). Puede crear diagramas de software y de otros sistemas en el formato estándar de la industria UML, además de generar código a partir de diagramas UML en diversos lenguajes de programación.</p>
+    <p xml:lang="et">Umbrello on unifitseeritud modelleerimiskeele UML modelleerimistööriist ja koodi genereerija. See võib luua tarkvara ja muude süsteemide skeeme standardses UML-vormingus, samuti genereerida UML-skeemide põhjal koodi mitmes programmeerimiskeeles.</p>
+    <p xml:lang="fi">Umbrello on UML-mallinnusohjelma. Umbrellolla voi luoda kaavioita ohjelmistoista ja muista järjestelmistä käyttäen standardia UML-muotoa. Sillä voi myös luoda koodin UML-kaavioiden perusteella useille ohjelmointikielille.</p>
+    <p xml:lang="gl">Umbrello é unha ferramenta de modelaxe e xerador de código baseado na linguaxe de modelaxe UML. Pode crear diagramas de software e doutros sistemas usando o formato estándar da industria, UML, e pode tamén xerar código a partir de diagramas UML en varios linguaxes de programación.</p>
+    <p xml:lang="it">Umbrello è uno strumento per diagrammi UML e un generatore di codice. Può creare diagrammi di software e altri sistemi nello standard industriale UML, e può anche generare codice partendo dai diagrammi UML in diversi linguaggi di programmazione.</p>
+    <p xml:lang="nl">Umbrello is een Unified Modelling Language (UML) hulpmiddel voor modellering en generator van code. Het kan diagrammen van software en andere systemen maken  in het industrie-standaard UML-formaat en kan ook code genereren uit UML diagrammen in een verscheidenheid van programmeertalen.</p>
+    <p xml:lang="pl">Umbrello jest Unified Modelling Language (UML) (z ang. Językiem do Jednolitego Modelowania)  i generatorem kodu. Może tworzyć diagramy oprogramowania i innych systemów w formacie standardu przemysłowego UML, a także generować kod z diagramów UML w wielu językach programowania.</p>
+    <p xml:lang="pt">O Umbrello é uma ferramenta de modelação em UML (Unified Modelling Language) e gerador de código. Poderá criar diagramas de aplicações e outros sistemas, usando o formato-padrão da indústria UML, podendo também gerar código a partir de diagramas UML, numa grande variedade de linguagens de programação.</p>
+    <p xml:lang="pt-BR">Umbrello é uma ferramenta de modelação de UML (Unified Modelling Language) e gerador de código. Ele pode criar diagramas de softwares e outros sistemas, usando o formato de UML padrão da indústria, assim como gerar código a partir de diagramas UML, em uma grande variedade de linguagens de programação.</p>
+    <p xml:lang="sk">Umbrello je nástroj na modelovania v UML a generátor kódu. Dokáže vytvárať diagramy softvéru a iných systémov v priemyselnom štandarde UML a tiež generovať kód z UML diagramov v množstve programovacích jazykov.</p>
+    <p xml:lang="sl">Umbrello je orodje za modeliranje v poenotenem jeziku za modeliranje (UML) in ustvarjalnik kode. Ustvari lahko diagrame programov in drugih sistemov v industrijski standardizirani obliki UML, iz diagramov UML pa lahko ustvari tudi kodo v različnih programskih jezikih.</p>
+    <p xml:lang="sv">Umbrello är ett modelleringsverktyg för Unified Modelling Language och kodgenerator. Det kan skapa diagram av programvara och andra system med industristandardformatet UML, och kan också skapa kod från UML-diagram på ett antal olika programspråk.</p>
+    <p xml:lang="uk">Umbrello — засіб моделювання уніфікованою мовою моделювання (UML) та інструмент для створення шаблонів коду. Програма здатна створювати діаграми систем програмного забезпечення та інших систем у стандартному форматі UML та реалізовувати діаграми UML у програмному коді багатьма мовами програмування.</p>
+    <p xml:lang="x-test">xxUmbrello is a Unified Modelling Language (UML) modelling tool and code generator. It can create diagrams of software and other systems in the industry-standard UML format, and can also generate code from UML diagrams in a variety of programming languages.xx</p>
+    <p>Features:</p>
+    <p xml:lang="ca">Característiques:</p>
+    <p xml:lang="cs">Vlastnosti:</p>
+    <p xml:lang="de">Funktionen:</p>
+    <p xml:lang="en-GB">Features:</p>
+    <p xml:lang="es">Funciones:</p>
+    <p xml:lang="et">Omadused:</p>
+    <p xml:lang="fi">Ominaisuuksia:</p>
+    <p xml:lang="gl">Funcionalidades:</p>
+    <p xml:lang="it">Funzionalità:</p>
+    <p xml:lang="nl">Kenmerken:</p>
+    <p xml:lang="pl">Możliwości:</p>
+    <p xml:lang="pt">Funcionalidades:</p>
+    <p xml:lang="pt-BR">Funcionalidades:</p>
+    <p xml:lang="sk">Funkcie:</p>
+    <p xml:lang="sl">Zmožnosti:</p>
+    <p xml:lang="sv">Funktioner:</p>
+    <p xml:lang="uk">Можливості:</p>
+    <p xml:lang="x-test">xxFeatures:xx</p>
+    <ul>
+      <li>Supported formats: XMI</li>
+      <li xml:lang="ca">Formats acceptats: XMI</li>
+      <li xml:lang="cs">Podporované formáty: XMI</li>
+      <li xml:lang="de">Unterstützte Formate: XMI</li>
+      <li xml:lang="en-GB">Supported formats: XMI</li>
+      <li xml:lang="es">Formatos permitidos: XMI</li>
+      <li xml:lang="et">Toetatud vormingud: XMI</li>
+      <li xml:lang="fi">Tukee XMI-tiedostomuotoa</li>
+      <li xml:lang="gl">Formatos compatíbeis: XMI.</li>
+      <li xml:lang="it">Formati supportati: XMI</li>
+      <li xml:lang="nl">Ondersteunde formaten: XMI</li>
+      <li xml:lang="pl">Obsługiwane formaty: XMI</li>
+      <li xml:lang="pt">Formatos suportados: XMI</li>
+      <li xml:lang="pt-BR">Formatos suportados: XMI</li>
+      <li xml:lang="sk">Podporované formáty: XMI</li>
+      <li xml:lang="sl">Podprte oblike: XMI</li>
+      <li xml:lang="sv">Format som stöds: XMI</li>
+      <li xml:lang="uk">Підтримувані формати: XMI</li>
+      <li xml:lang="x-test">xxSupported formats: XMIxx</li>
+      <li>Several type of diagrams supported: use case, class, sequence, collaboration, state, activity, component, deployment, entity relationship</li>
+      <li xml:lang="ca">Es permeten diversos tipus de diagrames: cas d'ús, classe, seqüència, col·laboració, estat, activitat, component, desplegament, entitat relació</li>
+      <li xml:lang="en-GB">Several type of diagrams supported: use case, class, sequence, collaboration, state, activity, component, deployment, entity relationship</li>
+      <li xml:lang="es">Permite usar varios tipos de diagramas: casos de uso, clase, secuencia, colaboración, estado, actividad, componente, despliegue y relación de entidades</li>
+      <li xml:lang="et">Toetatud on mitut tüüpi skeemid: kasutus, klass, järgnevus, koostöö, olek, tegevus, komponent, evitus, olem-seos</li>
+      <li xml:lang="fi">Tukee monenlaisia kaavioita: käyttötapauskaavio, luokkakaavio, sekvenssikaavio, yhteistyökaavio, tilakaavio, aktiviteettikaavio, komponenttikaavio, sijoittelukaavio, käsitekaavio</li>
+      <li xml:lang="gl">Permite traballar con varios tipos de diagramas: caso de uso, clase, secuencia, colaboración, estado, actividade, compoñente, distribución, e entidade-relación.</li>
+      <li xml:lang="it">Diversi tipi di diagrammi supportati: casi d'uso, classe, sequenza, collaborazione, stato, attività, componente, dispiegamento, relazione tra entità</li>
+      <li xml:lang="nl">Verschillende typen diagrammen worden ondersteund: use case, klassen, volgorde, samenwerking, status, activiteit, component, deployment, relaties tussen eenheden</li>
+      <li xml:lang="pl">Kilka obsługiwanych rodzajów diagramów: przypadki użycia, klasy, sekwencje, kolaboracje, stany, aktywności, składniki, zastosowanie, współzależności obiektów</li>
+      <li xml:lang="pt">Diversos tipos de diagramas suportados: casos de uso, classe, sequência, colaboração, estado, actividade, componente, entrada em produção, entidade-associação</li>
+      <li xml:lang="pt-BR">Há suporte para diversos tipos de diagramas: casos de uso, classe, sequência, colaboração, estado, atividade, componente, distribuição, relacionamento de entidade</li>
+      <li xml:lang="sk">Podporovaných je niekoľko typov diagramov: prípady použitia, triedy, sekvencie, stavy, aktivity, nasadenie, vzžahy entít</li>
+      <li xml:lang="sl">Podprte so številne vrste diagramov: primer uporabe, razred, zaporedje, sodelovanje, stanje, dejavnost, sestavni del, namestitev, odvisnost entitete</li>
+      <li xml:lang="sv">Flera diagramtyper stöds: användningsfall, klass, sekvens, samarbete, tillstånd, aktivitet, komponent, utplacering, objektsamband</li>
+      <li xml:lang="uk">Підтримка декількох типів діаграм: випадків використання, класів, послідовності, співпраці, станів, компонент, розміщення та взаємозв’язку компонентів.</li>
+      <li xml:lang="x-test">xxSeveral type of diagrams supported: use case, class, sequence, collaboration, state, activity, component, deployment, entity relationshipxx</li>
+    </ul>
+  </description>
+  <url type="homepage">http://umbrello.kde.org</url>
+  <url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?format=guided&product=umbrello</url>
+  <url type="help">http://docs.kde.org/stable/en/kdesdk/umbrello/index.html</url>
+  <screenshots>
+    <screenshot type="default">
+      <image>http://kde.org/images/screenshots/umbrello.png</image>
+    </screenshot>
+  </screenshots>
+  <project_group>KDE</project_group>
+  <provides>
+    <binary>umbrello</binary>
+  </provides>
+</component>
diff -Nuar umbrello-15.08.1.orig/umbrello/package.cpp umbrello-15.08.1/umbrello/package.cpp
--- umbrello-15.08.1.orig/umbrello/package.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/package.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,461 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header file
-#include "package.h"
-
-// local includes
-#include "debug_utils.h"
-#include "dialog_utils.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "classifier.h"
-#include "association.h"
-#include "entity.h"
-#include "object_factory.h"
-#include "model_utils.h"
-
-// kde includes
-#if QT_VERSION < 0x050000
-#include <kinputdialog.h>
-#endif
-#include <KLocalizedString>
-#include <KMessageBox>
-
-// qt includes
-#if QT_VERSION >= 0x050000
-#include <QInputDialog>
-#endif
-
-using namespace Uml;
-
-/**
- * Sets up a Package.
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLPackage::UMLPackage(const QString & name, Uml::ID::Type id)
-        : UMLCanvasObject(name, id)
-{
-    m_BaseType = ot_Package;
-}
-
-/**
- * Destructor.
- */
-UMLPackage::~UMLPackage()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new object.
- */
-void UMLPackage::copyInto(UMLObject *lhs) const
-{
-    UMLPackage *target = static_cast<UMLPackage*>(lhs);
-
-    UMLCanvasObject::copyInto(target);
-
-    m_objects.copyInto(&(target->m_objects));
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLPackage::clone() const
-{
-    UMLPackage *clone = new UMLPackage();
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Adds an existing association to the matching concept in the list of concepts.
- * The selection of the matching concept depends on the association type:
- * For generalizations, the assoc is added to the concept that matches role A.
- * For aggregations and compositions, the assoc is added to the concept
- * that matches role B.
- * @param assoc   the association to add
- */
-void UMLPackage::addAssocToConcepts(UMLAssociation* assoc)
-{
-    if (! AssociationType::hasUMLRepresentation(assoc->getAssocType()))
-        return;
-    Uml::ID::Type AId = assoc->getObjectId(Uml::RoleType::A);
-    Uml::ID::Type BId = assoc->getObjectId(Uml::RoleType::B);
-    UMLObject *o = NULL;
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        o = oit.next();
-        UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
-        if (c == NULL)
-            continue;
-        if (AId == c->id() || (BId == c->id())) {
-            if (c->hasAssociation(assoc))
-                uDebug() << c->name() << " already has association id=" << Uml::ID::toString(assoc->id());
-            else
-               c->addAssociationEnd(assoc);
-        }
-        UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
-        if (pkg)
-            pkg->addAssocToConcepts(assoc);
-    }
-}
-
-/**
- * Remove the association from the participating concepts.
- * @param assoc   the association to remove
- */
-void UMLPackage::removeAssocFromConcepts(UMLAssociation *assoc)
-{
-    UMLObject *o = 0;
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        o = oit.next();
-        UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
-        if (c) {
-            if (c->hasAssociation(assoc))
-                c->removeAssociationEnd(assoc);
-            UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
-            if (pkg)
-                pkg->removeAssocFromConcepts(assoc);
-        }
-    }
-}
-
-/**
- * Adds an object in this package.
- *
- * @param pObject   Pointer to the UMLObject to add.
- * @return    True if the object was actually added.
- */
-bool UMLPackage::addObject(UMLObject *pObject)
-{
-    if (pObject == NULL) {
-        uError() << "is called with a NULL object";
-        return false;
-    }
-    if (pObject == this) {
-        uError() << "adding myself as child is not allowed";
-        return false;
-    }
-
-    if (m_objects.indexOf(pObject) != -1) {
-        uDebug() << pObject->name() << " is already there";
-        return false;
-    }
-    if (pObject->baseType() == UMLObject::ot_Association) {
-        UMLAssociation *assoc = static_cast<UMLAssociation*>(pObject);
-        // Adding the UMLAssociation at the participating concepts is done
-        // again later (in UMLAssociation::resolveRef()) if they are not yet
-        // known right here.
-        if (assoc->getObject(Uml::RoleType::A) && assoc->getObject(Uml::RoleType::B)) {
-            UMLPackage *pkg = pObject->umlPackage();
-            if (pkg != this) {
-               uError() << "UMLPackage " << name() << " addObject: "
-                        << "assoc's UMLPackage is " << pkg->name();
-            }
-            addAssocToConcepts(assoc);
-        }
-    }
-    else {
-      QString name = pObject->name();
-      QString oldName = name;
-      while (findObject(name) != NULL) {
-         QString prevName = name;
-         name = Model_Utils::uniqObjectName(pObject->baseType(), this);
-         bool ok = Dialog_Utils::askName(i18nc("object name", "Name"),
-                                         i18n("An object with the name %1\nalready exists in the package %2.\nPlease enter a new name:", prevName, this->name()),
-                                         name);
-         if (!ok) {
-            name = oldName;
-            continue;
-         }
-         if (name.length() == 0) {
-            KMessageBox::error(0, i18n("That is an invalid name."),
-                               i18n("Invalid Name"));
-            continue;
-        }
-      }
-      if (oldName != name) {
-        pObject->setName(name);
-      }
-    }
-    m_objects.append(pObject);
-    return true;
-}
-
-/**
- * Removes an object from this package.
- * Does not physically delete the object.
- *
- * @param pObject   Pointer to the UMLObject to be removed.
- */
-void UMLPackage::removeObject(UMLObject *pObject)
-{
-    if (pObject->baseType() == UMLObject::ot_Association) {
-        UMLObject *o = const_cast<UMLObject*>(pObject);
-        UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
-        removeAssocFromConcepts(assoc);
-    }
-    if (m_objects.indexOf(pObject) == -1)
-        uDebug() << name() << " removeObject: object with id="
-                 << Uml::ID::toString(pObject->id()) << "not found.";
-    else
-        m_objects.removeAll(pObject);
-}
-
-/**
- * Removes all objects from this package.
- * Inner containers (e.g. nested packages) are removed recursively.
- */
-void UMLPackage::removeAllObjects()
-{
-    UMLCanvasObject::removeAllChildObjects();
-    UMLObject *o = NULL;
-
-    while (!m_objects.isEmpty() && (o = m_objects.first()) != NULL)  {
-        UMLPackage *pkg = dynamic_cast<UMLPackage*>(o);
-        if (pkg)
-            pkg->removeAllObjects();
-        removeObject(o);
-        delete o;
-    }
-}
-
-/**
- * Returns the list of objects contained in this package.
- */
-UMLObjectList UMLPackage::containedObjects()
-{
-    return m_objects;
-}
-
-/**
- * Find the object of the given name in the list of contained objects.
- *
- * @param name   The name to seek.
- * @return  Pointer to the UMLObject found or NULL if not found.
- */
-UMLObject * UMLPackage::findObject(const QString &name)
-{
-    const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        UMLObject *obj = oit.next();
-        if (!obj)
-            continue;
-        if (caseSensitive) {
-            if (obj->name() == name)
-                return obj;
-        } else if (obj->name().toLower() == name.toLower()) {
-            return obj;
-        }
-    }
-    return NULL;
-}
-
-/**
- * Find the object of the given ID in the list of contained objects.
- *
- * @param id   The ID to seek.
- * @return  Pointer to the UMLObject found or NULL if not found.
- */
-UMLObject * UMLPackage::findObjectById(Uml::ID::Type id)
-{
-    return Model_Utils::findObjectInList(id, m_objects);
-}
-
-/**
- * Append all packages from this package (and those from nested packages)
- * to the given UMLPackageList.
- *
- * @param packages        The list to append to
- * @param includeNested   Whether to include the packages from nested packages
- *                        (default:true)
- */
-void UMLPackage::appendPackages(UMLPackageList& packages, bool includeNested)
-{
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        UMLObject *o = oit.next();
-        uIgnoreZeroPointer(o);
-        ObjectType ot = o->baseType();
-        if (ot == ot_Package || ot == ot_Folder) {
-            packages.append(static_cast<UMLPackage*>(o));
-            if (includeNested) {
-               UMLPackage *inner = static_cast<UMLPackage*>(o);
-               inner->appendPackages(packages);
-            }
-         }
-    }
-}
-
-/**
- * Append all classifiers from this package (and those from
- * nested packages) to the given UMLClassifierList.
- *
- * @param classifiers     The list to append to.
- * @param includeNested   Whether to include the classifiers from
- *                        nested packages (default: true.)
- */
-void UMLPackage::appendClassifiers(UMLClassifierList& classifiers,
-                                   bool includeNested /* = true */)
-{
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        UMLObject *o = oit.next();
-        uIgnoreZeroPointer(o);
-        ObjectType ot = o->baseType();
-        if (ot == ot_Class || ot == ot_Interface ||
-                ot == ot_Datatype || ot == ot_Enum || ot == ot_Entity) {
-            classifiers.append((UMLClassifier *)o);
-        } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
-            UMLPackage *inner = static_cast<UMLPackage *>(o);
-            inner->appendClassifiers(classifiers);
-        }
-    }
-}
-
-/**
- * Append all entities from this package (and those
- * from nested packages) to the given UMLEntityList.
- *
- * @param entities        The list to append to.
- * @param includeNested   Whether to include the entities from
- *                        nested packages (default: true.)
- */
-void UMLPackage::appendEntities(UMLEntityList& entities,
-                                 bool includeNested /* = true */)
-{
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        UMLObject *o = oit.next();
-        uIgnoreZeroPointer(o);
-        ObjectType ot = o->baseType();
-        if (ot == ot_Entity) {
-            UMLEntity *c = static_cast<UMLEntity*>(o);
-            entities.append(c);
-        } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
-            UMLPackage *inner = static_cast<UMLPackage *>(o);
-            inner->appendEntities(entities);
-        }
-    }
-}
-
-/**
- * Append all classes and interfaces from this package (and those
- * from nested packages) to the given UMLClassifierList.
- *
- * @param classifiers     The list to append to.
- * @param includeNested   Whether to include the classifiers from
- *                        nested packages (default: true.)
- */
-void UMLPackage::appendClassesAndInterfaces(UMLClassifierList& classifiers,
-        bool includeNested /* = true */)
-{
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        UMLObject *o = oit.next();
-        uIgnoreZeroPointer(o);
-        ObjectType ot = o->baseType();
-        if (ot == ot_Class || ot == ot_Interface) {
-            UMLClassifier *c = static_cast<UMLClassifier*>(o);
-            classifiers.append(c);
-        } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
-            UMLPackage *inner = static_cast<UMLPackage *>(o);
-            inner->appendClassesAndInterfaces(classifiers);
-        }
-    }
-}
-
-/**
- * Resolve types. Required when dealing with foreign XMI files.
- * Needs to be called after all UML objects are loaded from file.
- * Overrides the method from UMLObject.
- * Calls resolveRef() on each contained object.
- *
- * @return  True for overall success.
- */
-bool UMLPackage::resolveRef()
-{
-    bool overallSuccess = UMLCanvasObject::resolveRef();
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        UMLObject *obj = oit.next();
-        uIgnoreZeroPointer(obj);
-        if (! obj->resolveRef()) {
-            UMLObject::ObjectType ot = obj->baseType();
-            if (ot != UMLObject::ot_Package && ot != UMLObject::ot_Folder)
-                m_objects.removeAll(obj);
-            overallSuccess = false;
-        }
-    }
-    return overallSuccess;
-}
-
-/**
- * Creates the <UML:Package> XMI element.
- */
-void UMLPackage::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement packageElement = UMLObject::save(QLatin1String("UML:Package"), qDoc);
-    QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
-    UMLObject *obj = NULL;
-    // save classifiers etc.
-    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
-        obj = oit.next();
-        uIgnoreZeroPointer(obj);
-        obj->saveToXMI (qDoc, ownedElement);
-    }
-    // save associations
-    for (UMLObjectListIt ait(m_List); ait.hasNext();) {
-        obj = ait.next();
-        obj->saveToXMI (qDoc, ownedElement);
-    }
-
-    packageElement.appendChild(ownedElement);
-    qElement.appendChild(packageElement);
-}
-
-/**
- * Loads the <UML:Package> XMI element.
- * Auxiliary to UMLObject::loadFromXMI.
- */
-bool UMLPackage::load(QDomElement& element)
-{
-    for (QDomNode node = element.firstChild(); !node.isNull();
-            node = node.nextSibling()) {
-        if (node.isComment())
-            continue;
-        QDomElement tempElement = node.toElement();
-        QString type = tempElement.tagName();
-        if (Model_Utils::isCommonXMIAttribute(type))
-            continue;
-        if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
-                UMLDoc::tagEq(type, QLatin1String("Element.ownedElement")) ||  // Embarcadero's Describe
-                UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
-            //CHECK: Umbrello currently assumes that nested elements
-            // are ownedElements anyway.
-            // Therefore these tags are not further interpreted.
-            if (! load(tempElement))
-                return false;
-            continue;
-        } else if (UMLDoc::tagEq(type, QLatin1String("packagedElement")) ||
-                   UMLDoc::tagEq(type, QLatin1String("ownedElement"))) {
-            type = tempElement.attribute(QLatin1String("xmi:type"));
-        }
-        UMLObject *pObject = Object_Factory::makeObjectFromXMI(type);
-        if(!pObject) {
-            uWarning() << "Unknown type of umlobject to create: " << type;
-            continue;
-        }
-        pObject->setUMLPackage(this);
-        if (!pObject->loadFromXMI(tempElement)) {
-            removeObject(pObject);
-            delete pObject;
-        }
-    }
-    return true;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/package.h umbrello-15.08.1/umbrello/package.h
--- umbrello-15.08.1.orig/umbrello/package.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/package.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,79 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef PACKAGE_H
-#define PACKAGE_H
-
-#include "umlcanvasobject.h"
-#include "umlclassifierlist.h"
-#include "umlentitylist.h"
-
-// forward declarations
-class UMLAssociation;
-
-/**
- * This class contains the non-graphical information required for a UML
- * Package.
- * This class inherits from @ref UMLCanvasObject which contains most of the
- * information.
- *
- * @short Non-graphical information for a Package.
- * @author Jonathan Riddell
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLPackage : public UMLCanvasObject
-{
-    Q_OBJECT
-public:
-    explicit UMLPackage(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLPackage();
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    bool addObject(UMLObject *pObject);
-    void removeObject(UMLObject *pObject);
-
-    virtual void removeAllObjects();
-
-    UMLObjectList containedObjects();
-
-    void addAssocToConcepts(UMLAssociation* assoc);
-    void removeAssocFromConcepts(UMLAssociation *assoc);
-
-    UMLObject * findObject(const QString &name);
-    UMLObject * findObjectById(Uml::ID::Type id);
-
-    void appendPackages(UMLPackageList& packages, bool includeNested = true);
-    void appendClassifiers(UMLClassifierList& classifiers,
-                            bool includeNested = true);
-    void appendClassesAndInterfaces(UMLClassifierList& classifiers,
-                                    bool includeNested = true);
-    void appendEntities(UMLEntityList& entities,
-                        bool includeNested = true);
-
-    virtual bool resolveRef();
-
-    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-protected:
-    virtual bool load(QDomElement& element);
-
-    /**
-     * References to the objects contained in this package.
-     * The UMLPackage is the owner of the objects.
-     */
-    UMLObjectList m_objects;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/port.cpp umbrello-15.08.1/umbrello/port.cpp
--- umbrello-15.08.1.orig/umbrello/port.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/port.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,68 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2014                                                    *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "port.h"
-
-#include <KLocalizedString>
-
-/**
- * Sets up a Port.
- *
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLPort::UMLPort(const QString & name, Uml::ID::Type id)
-  : UMLCanvasObject(name, id)
-{
-    init();
-}
-
-/**
- * Destructor.
- */
-UMLPort::~UMLPort()
-{
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLPort::init()
-{
-    m_BaseType = UMLObject::ot_Port;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLPort::clone() const
-{
-    UMLPort *clone = new UMLPort();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the <UML:Port> XMI element.
- */
-void UMLPort::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement portElement = UMLObject::save(QLatin1String("UML:Port"), qDoc);
-    qElement.appendChild(portElement);
-}
-
-/**
- * Loads the <UML:Port> XMI element (empty.)
- */
-bool UMLPort::load(QDomElement&)
-{
-    return true;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/port.h umbrello-15.08.1/umbrello/port.h
--- umbrello-15.08.1.orig/umbrello/port.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/port.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,46 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2014                                                    *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef PORT_H
-#define PORT_H
-
-#include "umlcanvasobject.h"
-
-/**
- * This class contains the non-graphical information required for a UML Port.
- * This class inherits from @ref UMLCanvasObject which contains most of the
- * information.
- *
- * @short Non-graphical information for a Port.
- * @author Oliver Kellogg
- * @see UMLCanvasObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLPort : public UMLCanvasObject
-{
-    Q_OBJECT
-public:
-
-    explicit UMLPort(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLPort();
-
-    virtual void init();
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-
-    bool load(QDomElement & element);
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/stereotype.cpp umbrello-15.08.1/umbrello/stereotype.cpp
--- umbrello-15.08.1.orig/umbrello/stereotype.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/stereotype.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,164 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "stereotype.h"
-
-// local includes
-#include "debug_utils.h"
-#include "umldoc.h"
-#include "uml.h"
-
-// kde includes
-#if QT_VERSION < 0x050000
-#include <kinputdialog.h>
-#endif
-#include <KLocalizedString>
-
-// qt includes
-#if QT_VERSION >= 0x050000
-#include <QInputDialog>
-#endif
-
-/**
- * Sets up a stereotype.
- *
- * @param name   The name of this UMLStereotype.
- * @param id     The unique id given to this UMLStereotype.
- */
-UMLStereotype::UMLStereotype(const QString &name, Uml::ID::Type id /* = Uml::id_None */)
-  : UMLObject(name, id)
-{
-    m_BaseType = UMLObject::ot_Stereotype;
-    UMLStereotype * existing = UMLApp::app()->document()->findStereotype(name);
-    if (existing) {
-        uError() << "UMLStereotype constructor: " << name << " already exists";
-    }
-    m_refCount = 0;
-}
-
-/**
- * Sets up a stereotype.
- */
-UMLStereotype::UMLStereotype()
-  : UMLObject()
-{
-    m_BaseType = UMLObject::ot_Stereotype;
-    m_refCount = 0;
-}
-
-/**
- * Destructor.
- */
-UMLStereotype::~UMLStereotype()
-{
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLStereotype::operator==(const UMLStereotype &rhs) const
-{
-    if (this == &rhs) {
-        return true;
-    }
-
-    if (!UMLObject::operator==(rhs)) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLStereotype::copyInto(UMLObject *lhs) const
-{
-    UMLObject::copyInto(lhs);
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLStereotype::clone() const
-{
-    UMLStereotype *clone = new UMLStereotype();
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Saves to the <UML:StereoType> XMI element.
- */
-void UMLStereotype::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    //FIXME: uml13.dtd compliance
-    QDomElement stereotypeElement = UMLObject::save(QLatin1String("UML:Stereotype"), qDoc);
-    qElement.appendChild(stereotypeElement);
-}
-
-/**
- * Display the properties configuration dialog for the stereotype
- * (just a line edit).
- */
-bool UMLStereotype::showPropertiesDialog(QWidget* parent)
-{
-    bool ok;
-#if QT_VERSION >= 0x050000
-    QString stereoTypeName = QInputDialog::getText(parent,
-                                                   i18n("Stereotype"), i18n("Enter name:"),
-                                                   QLineEdit::Normal,
-                                                   name(), &ok);
-#else
-    QString stereoTypeName = KInputDialog::getText(i18n("Stereotype"), i18n("Enter name:"), name(), &ok, parent);
-#endif
-    if (ok) {
-        setName(stereoTypeName);
-    }
-    return ok;
-}
-
-/**
- * Increments the reference count for this stereotype.
- */
-void UMLStereotype::incrRefCount()
-{
-    m_refCount++;
-}
-
-/**
- * Decrements the reference count for this stereotype.
- */
-void UMLStereotype::decrRefCount()
-{
-    m_refCount--;
-}
-
-/**
- * Returns the reference count for this stereotype.
- */
-int UMLStereotype::refCount() const
-{
-    return m_refCount;
-}
-
-/**
- * Returns the name as string
- */
-QString UMLStereotype::name(bool includeAdornments) const
-{
-    if (includeAdornments)
-        return QString::fromUtf8("«") + UMLObject::name() + QString::fromUtf8("»");
-    else
-        return UMLObject::name();
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/stereotype.h umbrello-15.08.1/umbrello/stereotype.h
--- umbrello-15.08.1.orig/umbrello/stereotype.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/stereotype.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,71 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef STEREOTYPE_H
-#define STEREOTYPE_H
-
-#include "umlobject.h"
-
-/**
- * This class is used to set up information for a stereotype.
- * Stereotypes are used essentially as properties of
- * attributes and operations etc.
- *
- * Each stereotype object is reference counted, i.e. client code
- * manages it such that it comes into existence as soon as there is
- * at least one user, and ceases existing when the number of users
- * drops to 0.
- * m_refCount reflects the number of users. It is externally managed,
- * i.e. client code must take care to call incrRefCount() and
- * decrRefCount() as appropriate.
- *
- * The one and only owner of all stereotypes is the UMLDoc, and the
- * ownership is specially managed (umlPackage() returns NULL for a
- * UMLStereotype.) The reason for this special treatment is that
- * class UMLDoc does not inherit from class UMLPackage, and therefore
- * setUMLPackage() cannot be used for stereotypes.
- *
- * @short Sets up stereotype information.
- * @author Jonathan Riddell
- * @author Oliver Kellogg
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLStereotype : public UMLObject
-{
-    Q_OBJECT
-public:
-    explicit UMLStereotype(const QString &name, Uml::ID::Type id = Uml::ID::None);
-    UMLStereotype();
-
-    virtual ~UMLStereotype();
-
-    bool operator==(const UMLStereotype &rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    void incrRefCount();
-    void decrRefCount();
-
-    int refCount() const;
-
-    QString name(bool includeAdornments=false) const;
-
-    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent);
-
-protected:
-    int m_refCount;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/stereotypesmodel.cpp umbrello-15.08.1/umbrello/stereotypesmodel.cpp
--- umbrello-15.08.1.orig/umbrello/stereotypesmodel.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/stereotypesmodel.cpp	2015-10-08 11:48:59.505089026 +0300
@@ -0,0 +1,121 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2015                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "stereotypesmodel.h"
+
+// app includes
+#include "stereotype.h"
+#include "uml.h"
+#include "umldoc.h"
+
+// kde includes
+#include <KLocalizedString>
+
+// qt includes
+#include <QtDebug>
+
+StereotypesModel::StereotypesModel(UMLStereotypeList *stereotypes)
+  : m_count(0),
+    m_stereotypes(stereotypes)
+{
+}
+
+int StereotypesModel::rowCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+
+    int count = m_stereotypes->count();
+    return count;
+}
+
+int StereotypesModel::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+
+    return 2;
+}
+
+QVariant StereotypesModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if (section < 0)
+        return QVariant();
+
+    if (role != Qt::DisplayRole)
+        return QVariant();
+
+    if (orientation == Qt::Vertical)
+        return section + 1;
+    if (section == 0)
+        return QVariant(i18n("Name"));
+    else if (section == 1)
+        return QVariant(i18n("Usage"));
+    else return QVariant();
+}
+
+QVariant StereotypesModel::data(const QModelIndex & index, int role) const
+{
+    if (role == Qt::UserRole && index.column() == 0) {
+        QVariant v;
+        v.setValue(m_stereotypes->at(index.row()));
+        return v;
+    }
+
+    if (role != Qt::DisplayRole)
+        return QVariant();
+
+    int cCount = columnCount(index);
+    if (index.column() >= cCount)
+        return QVariant();
+
+    UMLStereotype *s = m_stereotypes->at(index.row());
+    if (cCount == 1) {
+        QString a = s->name() + QString(QLatin1String(" (%1)")).arg(s->refCount());
+        return a;
+      }
+
+    // table view
+    if (index.column() == 0)
+        return s->name();
+    else
+        return s->refCount();
+}
+
+bool StereotypesModel::addStereotype(UMLStereotype *stereotype)
+{
+    if (m_stereotypes->contains(stereotype))
+        return false;
+    int index = m_stereotypes->count();
+    beginInsertRows(QModelIndex(), index, index);
+    m_stereotypes->append(stereotype);
+    endInsertRows();
+    return true;
+}
+
+bool StereotypesModel::removeStereotype(UMLStereotype *stereotype)
+{
+    if (!m_stereotypes->contains(stereotype))
+        return false;
+    int index = m_stereotypes->indexOf(stereotype);
+    beginRemoveRows(QModelIndex(), index, index);
+    m_stereotypes->removeAll(stereotype);
+    endRemoveRows();
+    return true;
+}
+
+void StereotypesModel::emitDataChanged(const QModelIndex &index)
+{
+    emit dataChanged(index, index);
+}
+
+void StereotypesModel::emitDataChanged(int index)
+{
+    QModelIndex mi = createIndex(index,0);
+    emit dataChanged(mi, mi);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/stereotypesmodel.h umbrello-15.08.1/umbrello/stereotypesmodel.h
--- umbrello-15.08.1.orig/umbrello/stereotypesmodel.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/stereotypesmodel.h	2015-10-08 11:48:59.505089026 +0300
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2015                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef STEREOTYPESMODEL_H
+#define STEREOTYPESMODEL_H
+
+// app includes
+#include "umlstereotypelist.h"
+
+// qt includes
+#include <QAbstractTableModel>
+
+class UMLStereotype;
+
+Q_DECLARE_METATYPE(UMLStereotype*);
+
+class StereotypesModel : public QAbstractTableModel
+{
+    Q_OBJECT
+public:
+    StereotypesModel(UMLStereotypeList *stereotypes);
+
+    int rowCount(const QModelIndex &parent) const;
+    int columnCount(const QModelIndex &parent) const;
+
+    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
+
+    bool addStereotype(UMLStereotype *stereotype);
+    bool removeStereotype(UMLStereotype *stereotype);
+
+    void emitDataChanged(const QModelIndex &index);
+    void emitDataChanged(int index);
+
+protected:
+    int m_count;
+    UMLStereotypeList *m_stereotypes;
+};
+
+#endif // STEREOTYPESMODEL_H
diff -Nuar umbrello-15.08.1.orig/umbrello/stereotypeswindow.cpp umbrello-15.08.1/umbrello/stereotypeswindow.cpp
--- umbrello-15.08.1.orig/umbrello/stereotypeswindow.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/stereotypeswindow.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2015                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "stereotypeswindow.h"
+
+// app includes
+#include "stereotype.h"
+#include "stereotypesmodel.h"
+#include "uml.h"
+#include "umldoc.h"
+
+// kde includes
+#include <KLocalizedString>
+
+// qt includes
+#include <QHeaderView>
+#include <QTableView>
+#include <QSortFilterProxyModel>
+#include <QtDebug>
+
+StereotypesWindow::StereotypesWindow(QWidget *parent)
+    : QDockWidget(i18n("&Stereotypes"), parent)
+{
+    setObjectName(QLatin1String("StereotypesWindow"));
+
+    QSortFilterProxyModel *proxy = new QSortFilterProxyModel;
+    proxy->setSourceModel(UMLApp::app()->document()->stereotypesModel());
+    proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
+    m_stereotypesTree = new QTableView;
+    m_stereotypesTree->setModel(proxy);
+    m_stereotypesTree->setSortingEnabled(true);
+    m_stereotypesTree->verticalHeader()->setDefaultSectionSize(20);
+    m_stereotypesTree->verticalHeader()->setVisible(false);
+#if QT_VERSION >= 0x050000
+    m_stereotypesTree->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+#else
+    m_stereotypesTree->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
+#endif
+    setWidget(m_stereotypesTree);
+
+    connect(m_stereotypesTree, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotStereotypesDoubleClicked(QModelIndex)));
+}
+
+StereotypesWindow::~StereotypesWindow()
+{
+    delete m_stereotypesTree;
+}
+
+void StereotypesWindow::modified()
+{
+    UMLStereotype *o = static_cast<UMLStereotype*>(QObject::sender());
+    if (!o)
+        return;
+    int index = UMLApp::app()->document()->stereotypes().indexOf(o);
+    UMLApp::app()->document()->stereotypesModel()->emitDataChanged(index);
+}
+
+void StereotypesWindow::slotStereotypesDoubleClicked(QModelIndex index)
+{
+    QVariant v = UMLApp::app()->document()->stereotypesModel()->data(index, Qt::UserRole);
+    if (v.canConvert<UMLStereotype*>()) {
+        UMLStereotype *s = v.value<UMLStereotype*>();
+        s->showPropertiesDialog(this);
+    }
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/stereotypeswindow.h umbrello-15.08.1/umbrello/stereotypeswindow.h
--- umbrello-15.08.1.orig/umbrello/stereotypeswindow.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/stereotypeswindow.h	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,38 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2015                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef STEREOTYPESWINDOW_H
+#define STEREOTYPESWINDOW_H
+
+#include <QDockWidget>
+#include <QModelIndex>
+
+class QTableView;
+
+class StereotypesWindow : public QDockWidget
+{
+    Q_OBJECT
+public:
+    explicit StereotypesWindow(QWidget *parent = 0);
+    ~StereotypesWindow();
+
+signals:
+
+public slots:
+    void modified();
+
+protected slots:
+    void slotStereotypesDoubleClicked(QModelIndex index);
+
+protected:
+    QTableView *m_stereotypesTree;
+};
+
+#endif // STEREOTYPESWINDOW_H
diff -Nuar umbrello-15.08.1.orig/umbrello/template.cpp umbrello-15.08.1/umbrello/template.cpp
--- umbrello-15.08.1.orig/umbrello/template.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/template.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,146 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "template.h"
-
-// app includes
-#include "debug_utils.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umltemplatedialog.h"
-
-/**
- * Sets up a template.
- *
- * @param parent   The parent of this UMLTemplate (i.e. its concept).
- * @param name     The name of this UMLTemplate.
- * @param id       The unique id given to this UMLTemplate.
- * @param type     The type of this UMLTemplate.
- */
-UMLTemplate::UMLTemplate(UMLObject *parent, const QString& name,
-                         Uml::ID::Type id, const QString& type)
-        : UMLClassifierListItem(parent, name, id)
-{
-    setTypeName(type);
-    m_BaseType = UMLObject::ot_Template;
-}
-
-/**
- * Sets up a template.
- *
- * @param parent    The parent of this UMLTemplate (i.e. its concept).
- */
-UMLTemplate::UMLTemplate(UMLObject *parent)
-        : UMLClassifierListItem(parent)
-{
-    m_BaseType = UMLObject::ot_Template;
-}
-
-/**
- * Destructor.
- */
-UMLTemplate::~UMLTemplate()
-{
-}
-
-QString UMLTemplate::toString(Uml::SignatureType::Enum sig)
-{
-    Q_UNUSED(sig);
-    if (m_pSecondary == NULL || m_pSecondary->name() == QLatin1String("class")) {
-        return name();
-    } else {
-        return name() + QLatin1String(" : ") + m_pSecondary->name();
-    }
-}
-
-/**
- * Overrides method from UMLClassifierListItem.
- * Returns the type name of the UMLTemplate.
- * If the template parameter is a class, there is no separate
- * type object. In this case, getTypeName() returns "class".
- *
- * @return  The type name of the UMLClassifierListItem.
- */
-QString UMLTemplate::getTypeName() const
-{
-    if (m_pSecondary == NULL)
-        return QLatin1String("class");
-    return m_pSecondary->name();
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLTemplate::operator==(const UMLTemplate &rhs) const
-{
-    if (this == &rhs) {
-        return true;
-    }
-    if (!UMLObject::operator==(rhs)) {
-        return false;
-    }
-    if (m_pSecondary != rhs.m_pSecondary) {
-        return false;
-    }
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLTemplate::copyInto(UMLObject *lhs) const
-{
-    UMLClassifierListItem::copyInto(lhs);
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLTemplate::clone() const
-{
-    UMLTemplate *clone = new UMLTemplate((UMLTemplate*) parent());
-    copyInto(clone);
-
-    return clone;
-}
-
-/**
- * Writes the <UML:TemplateParameter> XMI element.
- */
-void UMLTemplate::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    //FIXME: uml13.dtd compliance
-    QDomElement attributeElement = UMLObject::save(QLatin1String("UML:TemplateParameter"), qDoc);
-    if (m_pSecondary)
-        attributeElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
-    qElement.appendChild(attributeElement);
-}
-
-/**
- * Loads the <UML:TemplateParameter> XMI element.
- */
-bool UMLTemplate::load(QDomElement& element)
-{
-    m_SecondaryId = element.attribute(QLatin1String("type"));
-    return true;
-}
-
-/**
- * Display the properties configuration dialog for the template.
- *
- * @return  Success status.
- */
-bool UMLTemplate::showPropertiesDialog(QWidget* parent)
-{
-    UMLTemplateDialog dialog(parent, this);
-    return dialog.exec();
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/template.h umbrello-15.08.1/umbrello/template.h
--- umbrello-15.08.1.orig/umbrello/template.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/template.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,57 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef TEMPLATE_H
-#define TEMPLATE_H
-
-#include "classifierlistitem.h"
-
-/**
- * This class holds information used by template classes, called
- * paramaterised class in UML and a generic in Java.  It has a
- * type (usually just "class") and name.
- *
- * @short Sets up template information.
- * @author Jonathan Riddell
- * @see UMLObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLTemplate : public UMLClassifierListItem
-{
-public:
-
-    UMLTemplate(UMLObject *parent, const QString& name,
-                Uml::ID::Type id = Uml::ID::None, const QString& type = QLatin1String("class"));
-
-    explicit UMLTemplate(UMLObject *parent);
-
-    bool operator==(const UMLTemplate &rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    virtual ~UMLTemplate();
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    virtual QString getTypeName() const;
-
-    virtual bool showPropertiesDialog(QWidget* parent);
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-
-    bool load(QDomElement & element);
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umbrelloui.rc umbrello-15.08.1/umbrello/umbrelloui.rc
--- umbrello-15.08.1.orig/umbrello/umbrelloui.rc	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umbrelloui.rc	2015-10-08 11:48:59.506089026 +0300
@@ -85,6 +85,7 @@
     <Action name="view_show_doc"/>
     <Action name="view_show_undo"/>
     <Action name="view_show_bird"/>
+    <Action name="view_show_stereotypes"/>
   </Menu>
 </MenuBar>
 <ToolBar name="mainToolBar" fullWidth="true" newline="true">
diff -Nuar umbrello-15.08.1.orig/umbrello/umlappprivate.h umbrello-15.08.1/umbrello/umlappprivate.h
--- umbrello-15.08.1.orig/umbrello/umlappprivate.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlappprivate.h	2015-10-08 11:48:59.506089026 +0300
@@ -15,8 +15,11 @@
 #include "finddialog.h"
 #include "findresults.h"
 #include "uml.h"
+#include "stereotypeswindow.h"

 // kde includes
+#include <KActionCollection>
+#include <KToggleAction>
 #include <ktexteditor/configinterface.h>
 #include <ktexteditor/document.h>
 #include <ktexteditor/editor.h>
@@ -43,16 +46,18 @@
 {
     Q_OBJECT
 public:
-    QWidget *parent;
+    UMLApp *parent;
     FindDialog findDialog;
     FindResults findResults;
     QListWidget *logWindow;         ///< Logging window.
+    KToggleAction *viewStereotypesWindow;
+    StereotypesWindow *stereotypesWindow;

     KTextEditor::Editor *editor;
     KTextEditor::View *view;
     KTextEditor::Document *document;

-    explicit UMLAppPrivate(QWidget *_parent)
+    explicit UMLAppPrivate(UMLApp *_parent)
       : parent(_parent),
         findDialog(_parent),
         view(0),
@@ -101,6 +106,18 @@
         delete dialog;
         delete document;
     }
+
+    void createStereotypesWindow()
+    {
+        // create the tree viewer
+        stereotypesWindow = new StereotypesWindow(parent);
+        parent->addDockWidget(Qt::LeftDockWidgetArea, stereotypesWindow);
+
+        viewStereotypesWindow = parent->actionCollection()->add<KToggleAction>(QLatin1String("view_stereotypes_window"));
+        viewStereotypesWindow->setText(i18n("Stereotypes"));
+        connect(viewStereotypesWindow, SIGNAL(triggered(bool)), stereotypesWindow, SLOT(setVisible(bool)));
+    }
+
 };

 #endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlassociationlist.h umbrello-15.08.1/umbrello/umlassociationlist.h
--- umbrello-15.08.1.orig/umbrello/umlassociationlist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlassociationlist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,23 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2007                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLASSOCIATIONLIST_H
-#define UMLASSOCIATIONLIST_H
-
-#include <qlist.h>
-
-// forward declaration
-class UMLAssociation;
-
-typedef QList<UMLAssociation*> UMLAssociationList;
-typedef QListIterator<UMLAssociation*> UMLAssociationListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlattributelist.cpp umbrello-15.08.1/umbrello/umlattributelist.cpp
--- umbrello-15.08.1.orig/umbrello/umlattributelist.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlattributelist.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,61 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "umlattributelist.h"
-
-#include "attribute.h"
-
-#include <KLocalizedString>
-
-UMLAttributeList::UMLAttributeList()
-{
-}
-
-UMLAttributeList::UMLAttributeList(const UMLAttributeList& other)
-    : QList<UMLAttribute*>(other)
-{
-}
-
-UMLAttributeList::~UMLAttributeList()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLAttributeList::copyInto(UMLAttributeList *rhs) const
-{
-    // Don't copy yourself.
-    if (rhs == this) return;
-
-    rhs->clear();
-
-    // Suffering from const; we shall not modify our object.
-    UMLAttributeList *tmp = new UMLAttributeList(*this);
-
-    UMLAttribute *item;
-    for (UMLAttributeListIt ait(*tmp); ait.hasNext() ;)
-    {
-        item = ait.next();
-        rhs->append((UMLAttribute*)item->clone());
-    }
-    delete tmp;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLAttributeList* UMLAttributeList::clone() const
-{
-    UMLAttributeList *clone = new UMLAttributeList();
-    copyInto(clone);
-    return clone;
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlattributelist.h umbrello-15.08.1/umbrello/umlattributelist.h
--- umbrello-15.08.1.orig/umbrello/umlattributelist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlattributelist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,42 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLATTRIBUTELIST_H
-#define UMLATTRIBUTELIST_H
-
-#include <QList>
-
-#include "attribute.h"
-
-//typedef QPtrList<UMLAttribute> UMLAttributeList;
-typedef QListIterator<UMLAttribute*> UMLAttributeListIt;
-
-/**
- * This sub-class adds copyInto and clone to the QPtrList<UMLAttribute>
- * base class.
- */
-class UMLAttributeList : public QList<UMLAttribute*>
-{
-public:
-
-    UMLAttributeList();
-
-    UMLAttributeList(const UMLAttributeList&);
-
-    virtual ~UMLAttributeList();
-
-    virtual void copyInto(UMLAttributeList *rhs) const;
-
-    virtual UMLAttributeList* clone() const;
-};
-
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlcanvasobject.cpp umbrello-15.08.1/umbrello/umlcanvasobject.cpp
--- umbrello-15.08.1.orig/umbrello/umlcanvasobject.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlcanvasobject.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,464 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "umlcanvasobject.h"
-
-// local includes
-#include "debug_utils.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "classifier.h"
-#include "association.h"
-#include "attribute.h"
-#include "operation.h"
-#include "template.h"
-#include "stereotype.h"
-#include "idchangelog.h"
-
-// kde includes
-#include <KLocalizedString>
-
-DEBUG_REGISTER_DISABLED(UMLCanvasObject)
-
-/**
- * Sets up a UMLCanvasObject.
- *
- * @param name   The name of the Concept.
- * @param id     The unique id of the Concept.
- */
-UMLCanvasObject::UMLCanvasObject(const QString & name, Uml::ID::Type id)
-  : UMLObject(name, id)
-{
-}
-
-/**
- * Standard deconstructor.
- */
-UMLCanvasObject::~UMLCanvasObject()
-{
-    //removeAllAssociations();
-    // No! This is way too late to do that.
-    //  It should have been called explicitly before destructing the
-    //  UMLCanvasObject.
-    if (associations())
-        DEBUG(DBG_SRC) << "UMLCanvasObject destructor: FIXME: there are still associations()";
-}
-
-/**
- * Return the subset of m_List that matches the given type.
- *
- * @param assocType   The AssociationType::Enum to match.
- * @return   The list of associations that match assocType.
- */
-UMLAssociationList UMLCanvasObject::getSpecificAssocs(Uml::AssociationType::Enum assocType)
-{
-    UMLAssociationList list;
-    UMLObject *o = NULL;
-    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
-        o = oit.next();
-        uIgnoreZeroPointer(o);
-        if (o->baseType() != UMLObject::ot_Association)
-            continue;
-        UMLAssociation *a = static_cast<UMLAssociation*>(o);
-        if (a->getAssocType() == assocType)
-            list.append(a);
-    }
-    return list;
-}
-
-/**
- * Adds an association end to m_List.
- *
- * @param assoc  The association to add.
- *               @todo change param type to UMLRole
- */
-bool UMLCanvasObject::addAssociationEnd(UMLAssociation* assoc)
-{
-    Q_ASSERT(assoc);
-    // add association only if not already present in list
-    if (!hasAssociation(assoc))
-    {
-        m_List.append(assoc);
-
-        // Don't emit signals during load from XMI
-        UMLObject::emitModified();
-        emit sigAssociationEndAdded(assoc);
-        return true;
-    }
-    return false;
-}
-
-/**
- * Determine if this canvasobject has the given association.
- *
- * @param assoc   The association to check.
- */
-bool UMLCanvasObject::hasAssociation(UMLAssociation* assoc)
-{
-    uint cnt = m_List.count(assoc);
-    DEBUG(DBG_SRC) << "count is " << cnt;
-    return (cnt > 0);
-}
-
-/**
- * Remove an association end from the CanvasObject.
- *
- * @param assoc   The association to remove.
- *                @todo change param type to UMLRole
- */
-int UMLCanvasObject::removeAssociationEnd(UMLAssociation * assoc)
-{
-    if (!hasAssociation(assoc) || !m_List.removeAll(assoc)) {
-        DEBUG(DBG_SRC) << "cannot find given assoc " << assoc << " in list";
-        return -1;
-    }
-    UMLApp::app()->document()->removeAssociation(assoc, false);
-    UMLObject::emitModified();
-    emit sigAssociationEndRemoved(assoc);
-    return m_List.count();
-}
-
-/**
- * Remove all association ends from the CanvasObject.
- */
-void UMLCanvasObject::removeAllAssociationEnds()
-{
-    for (int i = 0; i < m_List.count(); i++) {
-        UMLObject *o = m_List.at(i);
-        uIgnoreZeroPointer(o);
-        if (o->baseType() != UMLObject::ot_Association) {
-            continue;
-        }
-        UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
-        //umldoc->slotRemoveUMLObject(assoc);
-        UMLObject* objA = assoc->getObject(Uml::RoleType::A);
-        UMLObject* objB = assoc->getObject(Uml::RoleType::B);
-        UMLCanvasObject *roleAObj = dynamic_cast<UMLCanvasObject*>(objA);
-        if (roleAObj) {
-            roleAObj->removeAssociationEnd(assoc);
-        } else if (objA) {
-            DEBUG(DBG_SRC) << name() << ": objA " << objA->name() << " is not a UMLCanvasObject";
-        } else
-            DEBUG(DBG_SRC) << name() << "): objA is NULL";
-        UMLCanvasObject *roleBObj = dynamic_cast<UMLCanvasObject*>(objB);
-        if (roleBObj) {
-            roleBObj->removeAssociationEnd(assoc);
-        } else if (objB) {
-            DEBUG(DBG_SRC) << name() << "): objB " << objB->name() << " is not a UMLCanvasObject";
-        } else
-            DEBUG(DBG_SRC) << name() << "): objB is NULL";
-    }
-}
-
-/**
- * Remove all child objects.
- * Just clear list, objects must be deleted where they were created
- * (or we have bad crashes).
- */
-void UMLCanvasObject::removeAllChildObjects()
-{
-    if (!m_List.isEmpty()) {
-        removeAllAssociationEnds();
-        m_List.clear();
-    }
-}
-
-/**
- * Returns a name for the new association, operation, template
- * or attribute appended with a number if the default name is
- * taken e.g. new_association, new_association_1 etc.
- *
- * @param type      The object type for which to make a name.
- * @param prefix    Optional prefix to use for the name.
- *                  If not given then uniqChildName() will choose the prefix
- *                  internally based on the object type.
- * @return  Unique name string for the ObjectType given.
- */
-QString UMLCanvasObject::uniqChildName(const UMLObject::ObjectType type,
-                                        const QString &prefix /* = QString() */)
-{
-    QString currentName;
-    currentName = prefix;
-    if (currentName.isEmpty()) {
-        switch (type) {
-            case UMLObject::ot_Association:
-                currentName = i18n("new_association");
-                break;
-            case UMLObject::ot_Attribute:
-                currentName = i18n("new_attribute");
-                break;
-            case UMLObject::ot_Template:
-                currentName = i18n("new_template");
-                break;
-            case UMLObject::ot_Operation:
-                currentName = i18n("new_operation");
-                break;
-            case UMLObject::ot_EnumLiteral:
-                currentName = i18n("new_literal");
-                break;
-            case UMLObject::ot_EntityAttribute:
-                currentName = i18n("new_field");
-                break;
-            case UMLObject::ot_UniqueConstraint:
-                currentName = i18n("new_unique_constraint");
-                break;
-            case UMLObject::ot_ForeignKeyConstraint:
-                currentName = i18n("new_fkey_constraint");
-                break;
-            case UMLObject::ot_CheckConstraint:
-                currentName = i18n("new_check_constraint");
-                break;
-            default:
-                uWarning() << "uniqChildName() called for unknown child type " << UMLObject::toString(type);
-                return QLatin1String("ERROR_in_UMLCanvasObject_uniqChildName");
-        }
-    }
-
-    QString name = currentName;
-    for (int number = 1; findChildObject(name); ++number) {
-        name = currentName + QLatin1Char('_') + QString::number(number);
-    }
-    return name;
-}
-
-/**
- * Find a child object with the given name.
- *
- * @param n  The name of the object to find.
- * @param t  The type to find (optional.) If not given then
- *           any object type will match.
- * @return  Pointer to the object found; NULL if none found.
- */
-UMLObject * UMLCanvasObject::findChildObject(const QString &n, UMLObject::ObjectType t)
-{
-    const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
-    UMLObject *obj = NULL;
-    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
-        obj = oit.next();
-        uIgnoreZeroPointer(obj);
-        if (t != UMLObject::ot_UMLObject && obj->baseType() != t)
-            continue;
-        if (caseSensitive) {
-            if (obj->name() == n)
-                return obj;
-        } else if (obj->name().toLower() == n.toLower()) {
-            return obj;
-        }
-    }
-    return NULL;
-}
-
-/**
- * Find an association.
- *
- * @param id        The id of the object to find.
- * @param considerAncestors boolean switch to consider ancestors while searching
- * @return  Pointer to the object found (NULL if not found.)
- */
-UMLObject* UMLCanvasObject::findChildObjectById(Uml::ID::Type id, bool considerAncestors)
-{
-    Q_UNUSED(considerAncestors);
-    UMLObject *o = NULL;
-    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
-        o = oit.next();
-        uIgnoreZeroPointer(o);
-        if (o->id() == id)
-            return o;
-    }
-    return 0;
-}
-
-/**
- *  Overloaded '==' operator
- */
-bool UMLCanvasObject::operator==(const UMLCanvasObject& rhs) const
-{
-    if (this == &rhs) {
-        return true;
-    }
-    if (!UMLObject::operator==(rhs)) {
-        return false;
-    }
-    if (m_List.count() != rhs.m_List.count()) {
-        return false;
-    }
-    if (&m_List != &(rhs.m_List)) {
-        return false;
-    }
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLCanvasObject::copyInto(UMLObject *lhs) const
-{
-    UMLObject::copyInto(lhs);
-
-    // TODO Associations are not copied at the moment. This because
-    // the duplicate function (on umlwidgets) do not copy the associations.
-    //
-    //target->m_List = m_List;
-}
-
-/**
- * Returns the number of associations for the CanvasObject.
- * This is the sum of the aggregations and compositions.
- *
- * @return  The number of associations for the Concept.
- */
-int UMLCanvasObject::associations()
-{
-    int count = 0;
-    UMLObject *obj = NULL;
-    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
-        obj = oit.next();
-        uIgnoreZeroPointer(obj);
-        if (obj->baseType() == UMLObject::ot_Association)
-            count++;
-    }
-    return count;
-}
-
-/**
- * Return the list of associations for the CanvasObject.
- *
- * @return   The list of associations for the CanvasObject.
- */
-UMLAssociationList UMLCanvasObject::getAssociations()
-{
-    UMLAssociationList assocs;
-    UMLObject *o = NULL;
-    for (UMLObjectListIt oit(m_List); oit.hasNext() ;) {
-        o = oit.next();
-        uIgnoreZeroPointer(o);
-        if (o->baseType() != UMLObject::ot_Association)
-            continue;
-        UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
-        assocs.append(assoc);
-    }
-    return assocs;
-}
-
-/**
- * Return a list of the superclasses of this concept.
- * TODO: This overlaps with UMLClassifier::findSuperClassConcepts(),
- *       see if we can merge the two.
- *
- * @param withRealizations include realizations in the returned list (default=yes)
- * @return  The list of superclasses for the concept.
- */
-UMLClassifierList UMLCanvasObject::getSuperClasses(bool withRealizations)
-{
-    UMLClassifierList list;
-    UMLAssociationList assocs = getAssociations();
-    foreach (UMLAssociation* a, assocs) {
-        uIgnoreZeroPointer(a);
-        if ((a->getAssocType() != Uml::AssociationType::Generalization &&
-             a->getAssocType() != Uml::AssociationType::Realization) ||
-             (!withRealizations && a->getAssocType() == Uml::AssociationType::Realization) ||
-                a->getObjectId(Uml::RoleType::A) != id())
-            continue;
-        UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::RoleType::B));
-        if (c)
-            list.append(c);
-        else
-            DEBUG(DBG_SRC) << name() << ": generalization's other end is not a "
-                << "UMLClassifier (id= " << Uml::ID::toString(a->getObjectId(Uml::RoleType::B)) << ")";
-    }
-    return list;
-}
-
-/**
- * Return a list of the classes that inherit from this concept.
- * TODO: This overlaps with UMLClassifier::findSubClassConcepts(),
- *       see if we can merge the two.
- *
- * @return  The list of classes inheriting from the concept.
- */
-UMLClassifierList UMLCanvasObject::getSubClasses()
-{
-    UMLClassifierList list;
-    UMLAssociationList assocs = getAssociations();
-    foreach (UMLAssociation* a, assocs) {
-        uIgnoreZeroPointer(a);
-        if ((a->getAssocType() != Uml::AssociationType::Generalization &&
-             a->getAssocType() != Uml::AssociationType::Realization) ||
-                a->getObjectId(Uml::RoleType::B) != id())
-            continue;
-        UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::RoleType::A));
-        if (c)
-            list.append(c);
-        else
-            DEBUG(DBG_SRC) << "specialization's other end is not a UMLClassifier"
-                << " (id=" << Uml::ID::toString(a->getObjectId(Uml::RoleType::A)) << ")";
-    }
-    return list;
-}
-
-/**
- * Shorthand for getSpecificAssocs(Uml::at_Realization)
- *
- * @return  The list of realizations for the Concept.
- */
-UMLAssociationList UMLCanvasObject::getRealizations()
-{
-    return getSpecificAssocs(Uml::AssociationType::Realization);
-}
-
-/**
- * Shorthand for getSpecificAssocs(Uml::at_Aggregation)
- *
- * @return  The list of aggregations for the Concept.
- */
-UMLAssociationList UMLCanvasObject::getAggregations()
-{
-    return getSpecificAssocs(Uml::AssociationType::Aggregation);
-}
-
-/**
- * Shorthand for getSpecificAssocs(Uml::at_Composition)
- *
- * @return  The list of compositions for the Concept.
- */
-UMLAssociationList UMLCanvasObject::getCompositions()
-{
-    return getSpecificAssocs(Uml::AssociationType::Composition);
-}
-
-/**
- * Shorthand for getSpecificAssocs(Uml::at_Relationship)
- *
- * @return  The list of relationships for the entity.
- */
-UMLAssociationList UMLCanvasObject::getRelationships()
-{
-    return getSpecificAssocs(Uml::AssociationType::Relationship);
-}
-
-/**
- * Reimplementation of UMLObject method.
- */
-bool UMLCanvasObject::resolveRef()
-{
-    bool overallSuccess = UMLObject::resolveRef();
-    for (UMLObjectListIt ait(m_List); ait.hasNext();) {
-        UMLObject *obj = ait.next();
-        uIgnoreZeroPointer(obj);
-        if (! obj->resolveRef()) {
-            m_List.removeAll(obj);
-            overallSuccess = false;
-        }
-    }
-    return overallSuccess;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/umlcanvasobject.h umbrello-15.08.1/umbrello/umlcanvasobject.h
--- umbrello-15.08.1.orig/umbrello/umlcanvasobject.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlcanvasobject.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,108 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef CANVASOBJECT_H
-#define CANVASOBJECT_H
-
-#include "umlobject.h"
-#include "umlobjectlist.h"
-#include "umlclassifierlist.h"
-#include "umlassociationlist.h"
-
-/**
- * This class contains the non-graphical information required for UMLObjects
- * which appear as moveable widgets on the scene.
- *
- * This class inherits from @ref UMLObject which contains most of the
- * information.
- * It is not instantiated itself, it's just used as a super class for
- * actual model objects.
- *
- * @short Non-graphical information for a UMLCanvasObject.
- * @author Jonathan Riddell
- * @see UMLObject
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLCanvasObject : public UMLObject
-{
-    Q_OBJECT
-
-public:
-    explicit UMLCanvasObject(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLCanvasObject();
-
-    bool operator==(const UMLCanvasObject& rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    // The abstract method UMLObject::clone() is implemented
-    // in the classes inheriting from UMLCanvasObject.
-
-    bool addAssociationEnd(UMLAssociation* assoc);
-
-    bool hasAssociation(UMLAssociation* assoc);
-
-    int removeAssociationEnd(UMLAssociation *assoc);
-
-    void removeAllAssociationEnds();
-
-    int associations();
-
-    UMLAssociationList getAssociations();
-
-    UMLAssociationList getSpecificAssocs(Uml::AssociationType::Enum assocType);
-
-    UMLClassifierList getSuperClasses(bool withRealizations = true);
-    UMLClassifierList getSubClasses();
-
-    virtual UMLAssociationList getRealizations();
-
-    UMLAssociationList getAggregations();
-    UMLAssociationList getCompositions();
-    UMLAssociationList getRelationships();
-
-    virtual UMLObject *findChildObject(const QString &n,
-                                       UMLObject::ObjectType t = UMLObject::ot_UMLObject);
-    virtual UMLObject *findChildObjectById(Uml::ID::Type id, bool considerAncestors = false);
-
-    virtual QString uniqChildName(const UMLObject::ObjectType type,
-                                  const QString &prefix = QString());
-
-    virtual void removeAllChildObjects();
-
-    UMLObjectList subordinates() const {
-        return m_List;
-    }
-
-    virtual bool resolveRef();
-
-    // The abstract method UMLObject::saveToXMI() is implemented
-    // in the classes inheriting from UMLCanvasObject.
-
-protected:
-
-    /**
-     * List of all the associations in this object.
-     * Inheriting classes add more types of objects that are possible in this list;
-     * for example, UMLClassifier adds operations, attributes, and templates.
-     *
-     * @todo Only a pointer to the appropriate assocation end object
-     *       (UMLRole) should be saved here, not the entire UMLAssociation.
-     */
-    UMLObjectList m_List;
-
-signals:
-
-    void sigAssociationEndAdded(UMLAssociation * assoc);
-    void sigAssociationEndRemoved(UMLAssociation * assoc);
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlclassifierlist.h umbrello-15.08.1/umbrello/umlclassifierlist.h
--- umbrello-15.08.1.orig/umbrello/umlclassifierlist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlclassifierlist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,22 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2010                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLCLASSIFIERLIST_H
-#define UMLCLASSIFIERLIST_H
-
-#include <QList>
-
-// forward declaration
-class UMLClassifier;
-
-typedef QList<UMLClassifier*> UMLClassifierList;
-typedef QListIterator<UMLClassifier*> UMLClassifierListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlclassifierlistitemlist.cpp umbrello-15.08.1/umbrello/umlclassifierlistitemlist.cpp
--- umbrello-15.08.1.orig/umbrello/umlclassifierlistitemlist.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlclassifierlistitemlist.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,60 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "umlclassifierlistitemlist.h"
-
-#include "classifierlistitem.h"
-
-#include <KLocalizedString>
-
-UMLClassifierListItemList::UMLClassifierListItemList()
-{
-}
-
-UMLClassifierListItemList::UMLClassifierListItemList(const UMLClassifierListItemList& other)
-  : QList<UMLClassifierListItem*>(other)
-{
-}
-
-UMLClassifierListItemList::~UMLClassifierListItemList()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLClassifierListItemList::copyInto(UMLClassifierListItemList *rhs) const
-{
-    // Prevent copying to yourself. (Can cause serious injuries)
-    if (rhs == this) return;
-
-    rhs->clear();
-
-    // Suffering from const; we shall not modify our object.
-    UMLClassifierListItemList *tmp = new UMLClassifierListItemList(*this);
-
-    UMLClassifierListItem *item;
-    for (UMLClassifierListItemListIt clit(*tmp); clit.hasNext() ;) {
-        item = clit.next();
-        rhs->append((UMLClassifierListItem*)item->clone());
-    }
-    delete tmp;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLClassifierListItemList* UMLClassifierListItemList::clone() const
-{
-    UMLClassifierListItemList *clone = new UMLClassifierListItemList();
-    copyInto(clone);
-    return clone;
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlclassifierlistitemlist.h umbrello-15.08.1/umbrello/umlclassifierlistitemlist.h
--- umbrello-15.08.1.orig/umbrello/umlclassifierlistitemlist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlclassifierlistitemlist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,41 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLCLASSIFIERLISTITEMLIST_H
-#define UMLCLASSIFIERLISTITEMLIST_H
-
-#include <QList>
-
-// forward declaration
-class UMLClassifierListItem;
-
-//typedef QPtrList<UMLClassifierListItem> UMLClassifierListItemList;
-typedef QListIterator<UMLClassifierListItem*> UMLClassifierListItemListIt;
-
-/**
- * This sub-class adds copyInto and clone to the QPtrList<UMLClassifierListItem>
- * base class.
- */
-class UMLClassifierListItemList : public QList<UMLClassifierListItem*>
-{
-public:
-
-    UMLClassifierListItemList();
-    UMLClassifierListItemList(const UMLClassifierListItemList& other);
-
-    virtual ~UMLClassifierListItemList();
-
-    virtual void copyInto (UMLClassifierListItemList *rhs) const;
-
-    virtual UMLClassifierListItemList* clone() const;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/uml.cpp umbrello-15.08.1/umbrello/uml.cpp
--- umbrello-15.08.1.orig/umbrello/uml.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/uml.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -240,15 +240,15 @@
     delete m_clipTimer;
     delete m_copyTimer;
     delete m_commoncodegenpolicy;
-    delete m_d;
-    delete m_doc;
     delete m_imageExporterAll;
-    delete m_listView;
     delete m_printer;
     delete m_policyext;
     delete m_pUndoStack;
     delete m_refactoringAssist;
     delete m_xhtmlGenerator;
+    delete m_listView;
+    delete m_doc;
+    delete m_d;
 }

 /**
@@ -918,6 +918,8 @@
     widget->setLayout(m_layout);
     setCentralWidget(widget);

+    m_d->createStereotypesWindow();
+
     // create the tree viewer
     m_listDock = new QDockWidget(i18n("&Tree View"), this);
     m_listDock->setObjectName(QLatin1String("TreeViewDock"));
diff -Nuar umbrello-15.08.1.orig/umbrello/umldoc.cpp umbrello-15.08.1/umbrello/umldoc.cpp
--- umbrello-15.08.1.orig/umbrello/umldoc.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umldoc.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -44,6 +44,7 @@
 #include "umlscene.h"
 #include "version.h"
 #include "worktoolbar.h"
+#include "stereotypesmodel.h"

 // kde includes
 #include <kio/job.h>
@@ -113,7 +114,8 @@
     m_nViewID(Uml::ID::None),
     m_bTypesAreResolved(true),
     m_pCurrentRoot(0),
-    m_bClosing(false)
+    m_bClosing(false),
+    m_stereotypesModel(new StereotypesModel(&m_stereoList))
 {
     for (int i = 0; i < Uml::ModelType::N_MODELTYPES; ++i)
         m_root[i] = 0;
@@ -190,6 +192,7 @@
     }
     delete m_pChangeLog;
     qDeleteAll(m_stereoList);
+    delete m_stereotypesModel;
 }

 /**
@@ -402,18 +405,19 @@
         // @fixme With advanced code generation enabled, this crashes.
         removeAllObjects();

+        // Remove any stereotypes.
+        if (stereotypes().count() > 0) {
+            foreach(UMLStereotype *s, stereotypes()) {
+                m_stereotypesModel->removeStereotype(s);
+                delete s;
+            }
+            m_stereoList.clear();
+        }
+
         // Restore the datatype folder, it has been deleted above.
         createDatatypeFolder();
         // this creates to much items only Logical View should be created
         listView->init();
-        /* Remove any stereotypes.
-        if (m_stereoList.count() > 0) {
-            UMLStereotype *s;
-            for (UMLStereotypeListIt sit(m_stereoList); (s = sit.current()) != 0; ++sit)
-                delete s;
-            m_stereoList.clear();
-        }
-        */
     }
     m_bClosing = false;
 }
@@ -1268,9 +1272,8 @@
  */
 void UMLDoc::addStereotype(UMLStereotype *s)
 {
-    if (! m_stereoList.contains(s)) {
-        m_stereoList.append(s);
-    }
+    if (m_stereotypesModel->addStereotype(s))
+        emit sigObjectCreated(s);
 }

 /**
@@ -1279,9 +1282,8 @@
  */
 void UMLDoc::removeStereotype(UMLStereotype *s)
 {
-    if (m_stereoList.contains(s)) {
-        m_stereoList.removeAll(s);
-    }
+    if (m_stereotypesModel->removeStereotype(s))
+        emit sigObjectRemoved(s);
 }

 /**
@@ -2444,6 +2446,11 @@
     qApp->processEvents();  // give UI events a chance
 }

+StereotypesModel *UMLDoc::stereotypesModel()
+{
+    return m_stereotypesModel;
+}
+
 /**
  * Ensures the XMI file is a valid UML file.
  * Currently only checks for metamodel=UML.
diff -Nuar umbrello-15.08.1.orig/umbrello/umldoc.h umbrello-15.08.1/umbrello/umldoc.h
--- umbrello-15.08.1.orig/umbrello/umldoc.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umldoc.h	2015-10-08 11:48:59.506089026 +0300
@@ -48,6 +48,7 @@
 class QPrinter;

 class IDChangeLog;
+class StereotypesModel;
 class UMLPackage;
 class UMLFolder;
 class DiagramPrintPage;
@@ -233,6 +234,8 @@

     void resolveTypes();

+    StereotypesModel *stereotypesModel();
+
 private:
     void initSaveTimer();
     void createDatatypeFolder();
@@ -308,6 +311,8 @@
      */
     bool m_bClosing;

+    StereotypesModel *m_stereotypesModel;
+
 public slots:
     void slotRemoveUMLObject(UMLObject*o);
     void slotAutoSave();
diff -Nuar umbrello-15.08.1.orig/umbrello/umlentityattributelist.cpp umbrello-15.08.1/umbrello/umlentityattributelist.cpp
--- umbrello-15.08.1.orig/umbrello/umlentityattributelist.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlentityattributelist.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,60 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "umlentityattributelist.h"
-
-#include "entityattribute.h"
-
-#include <KLocalizedString>
-
-UMLEntityAttributeList::UMLEntityAttributeList()
-{
-}
-
-UMLEntityAttributeList::UMLEntityAttributeList(const UMLEntityAttributeList& other)
-  : QList<UMLEntityAttribute*>(other)
-{
-}
-
-UMLEntityAttributeList::~UMLEntityAttributeList()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLEntityAttributeList::copyInto(UMLEntityAttributeList* rhs) const
-{
-    // Don't copy yourself.
-    if (rhs == this) return;
-
-    rhs->clear();
-
-    // Suffering from const; we shall not modify our object.
-    UMLEntityAttributeList* tmp = new UMLEntityAttributeList(*this);
-
-    UMLEntityAttribute* item;
-    for (UMLEntityAttributeListIt eait(*tmp); eait.hasNext() ;) {
-        item = eait.next();
-        rhs->append((UMLEntityAttribute*)item->clone());
-    }
-    delete tmp;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLEntityAttributeList* UMLEntityAttributeList::clone() const
-{
-    UMLEntityAttributeList *clone = new UMLEntityAttributeList();
-    copyInto(clone);
-    return clone;
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlentityattributelist.h umbrello-15.08.1/umbrello/umlentityattributelist.h
--- umbrello-15.08.1.orig/umbrello/umlentityattributelist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlentityattributelist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,41 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLENTITYATTRIBUTELIST_H
-#define UMLENTITYATTRIBUTELIST_H
-
-#include <qlist.h>
-#include "entityattribute.h"
-
-//typedef QPtrList<UMLEntityAttribute> UMLEntityAttributeList;
-typedef QListIterator<UMLEntityAttribute*> UMLEntityAttributeListIt;
-
-/**
- * This sub-class adds copyInto and clone to the QPtrList<UMLEntityAttribute>
- * base class.
- */
-class UMLEntityAttributeList : public QList<UMLEntityAttribute*>
-{
-public:
-
-    UMLEntityAttributeList();
-
-    UMLEntityAttributeList(const UMLEntityAttributeList&);
-
-    virtual ~UMLEntityAttributeList();
-
-    virtual void copyInto (UMLEntityAttributeList* rhs) const;
-
-    virtual UMLEntityAttributeList* clone() const;
-};
-
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlentityconstraintlist.cpp umbrello-15.08.1/umbrello/umlentityconstraintlist.cpp
--- umbrello-15.08.1.orig/umbrello/umlentityconstraintlist.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlentityconstraintlist.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,60 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "umlentityconstraintlist.h"
-
-#include "entityconstraint.h"
-
-#include <KLocalizedString>
-
-UMLEntityConstraintList::UMLEntityConstraintList()
-{
-}
-
-UMLEntityConstraintList::UMLEntityConstraintList(const UMLEntityConstraintList& other)
-    : QList<UMLEntityConstraint*>(other)
-{
-}
-
-UMLEntityConstraintList::~UMLEntityConstraintList()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLEntityConstraintList::copyInto(UMLEntityConstraintList* rhs) const
-{
-    // Don't copy yourself.
-    if (rhs == this) return;
-
-    rhs->clear();
-
-    // Suffering from const; we shall not modify our object.
-    UMLEntityConstraintList* tmp = new UMLEntityConstraintList(*this);
-
-    UMLEntityConstraint* item;
-    for (UMLEntityConstraintListIt ecit(*tmp); ecit.hasNext() ;) {
-        item = ecit.next();
-        rhs->append((UMLEntityConstraint*)item->clone());
-    }
-    delete tmp;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLEntityConstraintList* UMLEntityConstraintList::clone() const
-{
-    UMLEntityConstraintList *clone = new UMLEntityConstraintList();
-    copyInto(clone);
-    return clone;
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlentityconstraintlist.h umbrello-15.08.1/umbrello/umlentityconstraintlist.h
--- umbrello-15.08.1.orig/umbrello/umlentityconstraintlist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlentityconstraintlist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,43 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLENTITYCONSTRAINTLIST_H
-#define UMLENTITYCONSTRAINTLIST_H
-
-#include <qlist.h>
-
-// forward declaration
-class UMLEntityConstraint;
-
-
-typedef QListIterator<UMLEntityConstraint*> UMLEntityConstraintListIt;
-
-/**
- * This sub-class adds copyInto and clone to the QPtrList<UMLEntityConstraint>
- * base class.
- */
-class UMLEntityConstraintList : public QList<UMLEntityConstraint*>
-{
-public:
-
-    UMLEntityConstraintList();
-
-    UMLEntityConstraintList(const UMLEntityConstraintList&);
-
-    virtual ~UMLEntityConstraintList();
-
-    virtual void copyInto (UMLEntityConstraintList* rhs) const;
-
-    virtual UMLEntityConstraintList* clone() const;
-};
-
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlentitylist.h umbrello-15.08.1/umbrello/umlentitylist.h
--- umbrello-15.08.1.orig/umbrello/umlentitylist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlentitylist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,22 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2010                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLENTITYLIST_H
-#define UMLENTITYLIST_H
-
-#include <QList>
-
-// forward declaration
-class UMLEntity;
-
-typedef QList<UMLEntity*> UMLEntityList;
-typedef QListIterator<UMLEntity*> UMLEntityListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlenumliterallist.h umbrello-15.08.1/umbrello/umlenumliterallist.h
--- umbrello-15.08.1.orig/umbrello/umlenumliterallist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlenumliterallist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,23 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2007                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLENUMLITERALLIST_H
-#define UMLENUMLITERALLIST_H
-
-#include <QList>
-
-// forward declaration
-class UMLEnumLiteral;
-
-typedef QList<UMLEnumLiteral*> UMLEnumLiteralList;
-typedef QListIterator<UMLEnumLiteral*> UMLEnumLiteralListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umllistview.cpp umbrello-15.08.1/umbrello/umllistview.cpp
--- umbrello-15.08.1.orig/umbrello/umllistview.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umllistview.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -2161,6 +2161,11 @@
         QString name = classifier->uniqChildName(objectType);
         UMLObject* object = Object_Factory::createChildObject(classifier, objectType, name);

+        if (object == 0) {
+            // creation was cancelled by the user
+            return;
+        }
+
         // Handle primary key constraints (mark the unique constraint as PK on
         // the parent entity)
         if (type == UMLListViewItem::lvt_PrimaryKeyConstraint) {
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/actor.cpp umbrello-15.08.1/umbrello/umlmodel/actor.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/actor.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/actor.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,67 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "actor.h"
+
+/**
+ * Constructs an Actor.
+ *
+ * @param name   The name of the Actor.
+ * @param id     The unique id to assign to this Actor.
+ */
+UMLActor::UMLActor(const QString & name, Uml::ID::Type id)
+  : UMLCanvasObject(name, id)
+{
+    init();
+}
+
+/**
+ * Standard destructor.
+ */
+UMLActor::~UMLActor()
+{
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLActor::init()
+{
+    m_BaseType = UMLObject::ot_Actor;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLActor::clone() const
+{
+    UMLActor *clone = new UMLActor();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the <UML:Actor> XMI element.
+ */
+void UMLActor::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement actorElement = UMLObject::save(QLatin1String("UML:Actor"), qDoc);
+    qElement.appendChild(actorElement);
+}
+
+/**
+ * Loads the <UML:Actor> XMI element (empty).
+ */
+bool UMLActor::load(QDomElement& element)
+{
+    Q_UNUSED(element);
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/actor.h umbrello-15.08.1/umbrello/umlmodel/actor.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/actor.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/actor.h	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,44 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ACTOR_H
+#define ACTOR_H
+
+#include "umlcanvasobject.h"
+
+/**
+ * This class contains the non-graphical information required for a UML Actor.
+ * This class inherits from @ref UMLCanvasObject which contains most of the
+ * information.
+ * The @ref UMLDoc class creates instances of this type.
+ *
+ * @short Information for a non-graphical UML Actor.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLActor : public UMLCanvasObject
+{
+    Q_OBJECT
+public:
+    explicit UMLActor(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLActor();
+
+    virtual void init();
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+    bool load(QDomElement & element);
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/artifact.cpp umbrello-15.08.1/umbrello/umlmodel/artifact.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/artifact.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/artifact.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,90 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "artifact.h"
+#include "association.h"
+#include "clipboard/idchangelog.h"
+
+#include <KLocalizedString>
+
+/**
+ * Sets up an Artifact.
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLArtifact::UMLArtifact(const QString & name, Uml::ID::Type id)
+  : UMLPackage(name, id),
+    m_drawAsType(defaultDraw)
+{
+    m_BaseType = UMLObject::ot_Artifact;
+}
+
+/**
+ * Standard deconstructor.
+ */
+UMLArtifact::~UMLArtifact()
+{
+}
+
+/**
+ * Make a clone of this object.
+ * @return the cloned object
+ */
+UMLObject* UMLArtifact::clone() const
+{
+    UMLArtifact *clone = new UMLArtifact();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the UML:Artifact element including its operations,
+ * attributes and templates
+ * @param qDoc       the xml document
+ * @param qElement   the xml element
+ */
+void UMLArtifact::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement artifactElement = UMLObject::save(QLatin1String("UML:Artifact"), qDoc);
+    artifactElement.setAttribute(QLatin1String("drawas"), m_drawAsType);
+    qElement.appendChild(artifactElement);
+}
+
+/**
+ * Loads the UML:Artifact element including its operations,
+ * attributes and templates.
+ * @param element   the xml element to load
+ * @return the success status of the operation
+ */
+bool UMLArtifact::load(QDomElement& element)
+{
+    QString drawAs = element.attribute(QLatin1String("drawas"), QLatin1String("0"));
+    m_drawAsType = (Draw_Type)drawAs.toInt();
+    return true;
+}
+
+/**
+ * Sets m_drawAsType for which method to draw the artifact as.
+ * @param type   the draw type
+ */
+void UMLArtifact::setDrawAsType(Draw_Type type)
+{
+    m_drawAsType = type;
+}
+
+/**
+ * Returns the value of m_drawAsType.
+ * @return the value of the draw type attribute
+ */
+UMLArtifact::Draw_Type UMLArtifact::getDrawAsType()
+{
+    return m_drawAsType;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/artifact.h umbrello-15.08.1/umbrello/umlmodel/artifact.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/artifact.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/artifact.h	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ARTIFACT_H
+#define ARTIFACT_H
+
+#include "package.h"
+
+/**
+ * This class contains the non-graphical information required for a UML
+ * Artifact.
+ * This class inherits from @ref UMLCanvasObject which contains most of the
+ * information.
+ *
+ * @short Non-graphical information for a Artifact.
+ * @author Jonathan Riddell
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLArtifact : public UMLPackage
+{
+    Q_OBJECT
+public:
+
+    /**
+     * Artifacts can be drawn using one of several icons.
+     */
+    enum Draw_Type {
+        defaultDraw,
+        file,
+        library,
+        table
+    };
+
+    explicit UMLArtifact(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLArtifact();
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    void setDrawAsType(Draw_Type type);
+
+    Draw_Type getDrawAsType();
+
+protected:
+
+    bool load(QDomElement & element);
+
+private:
+
+    /**
+     * Artifacts can be drawn as one of several different icons,
+     * this value choosing how to draw them.
+     */
+    Draw_Type m_drawAsType;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/association.cpp umbrello-15.08.1/umbrello/umlmodel/association.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/association.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/association.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,742 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "association.h"
+
+// app includes
+#include "debug_utils.h"
+#include "classifier.h"
+#include "classpropertiesdialog.h"
+#include "folder.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlrole.h"
+#include "uniqueid.h"
+#include "model_utils.h"
+#include "cmds.h"
+
+// kde includes
+#include <KLocalizedString>
+
+// qt includes
+#include <QPointer>
+#include <QRegExp>
+
+using namespace Uml;
+
+DEBUG_REGISTER(UMLAssociation)
+
+/**
+ * Sets up an association.
+ * A new unique ID is assigned internally.
+ * @param type    The AssociationType::Enum to construct.
+ * @param roleA   Pointer to the UMLObject in role A.
+ * @param roleB   Pointer to the UMLObject in role B.
+ */
+UMLAssociation::UMLAssociation(Uml::AssociationType::Enum type,
+                                UMLObject * roleA, UMLObject * roleB)
+  : UMLObject(QString())
+{
+    init(type, roleA, roleB);
+
+    m_pRole[RoleType::A]->setID(UniqueID::gen());
+    m_pRole[RoleType::B]->setID(UniqueID::gen());
+}
+
+/**
+ * Constructs an association - for loading only.
+ * This constructor should not normally be used as it constructs
+ * an incomplete association (i.e. the role objects are missing.)
+ * @param type   The AssociationType::Enum to construct.
+ *               Default: Unknown.
+ */
+UMLAssociation::UMLAssociation(Uml::AssociationType::Enum type)
+  : UMLObject(QString(), Uml::ID::Reserved)
+{
+    init(type, NULL, NULL);
+}
+
+/**
+ * Standard destructor.
+ */
+UMLAssociation::~UMLAssociation()
+{
+    if (m_pRole[RoleType::A] == NULL) {
+        uError() << "UMLAssociation destructor: m_pRole[A] is NULL already";
+    } else {
+        delete m_pRole[RoleType::A];
+        m_pRole[RoleType::A] = NULL;
+    }
+    if (m_pRole[RoleType::B] == NULL) {
+        uError() << "UMLAssociation destructor: m_pRole[B] is NULL already";
+    } else {
+        delete m_pRole[RoleType::B];
+        m_pRole[RoleType::B] = NULL;
+    }
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLAssociation::operator==(const UMLAssociation &rhs) const
+{
+    if (this == &rhs) {
+        return true;
+    }
+    return (UMLObject::operator== (rhs) &&
+             m_AssocType == rhs.m_AssocType &&
+             m_Name == rhs.m_Name &&
+             m_pRole[RoleType::A] == rhs.m_pRole[RoleType::A] &&
+             m_pRole[RoleType::B] == rhs.m_pRole[RoleType::B]);
+}
+
+/**
+ * Returns the AssociationType::Enum of the UMLAssociation.
+ * @return  The AssociationType::Enum of the UMLAssociation.
+ */
+Uml::AssociationType::Enum UMLAssociation::getAssocType() const
+{
+    return m_AssocType;
+}
+
+/**
+ * Returns a String representation of this UMLAssociation.
+ */
+QString UMLAssociation::toString() const
+{
+    QString string;
+    if(m_pRole[RoleType::A])
+    {
+        string += m_pRole[RoleType::A]->object()->name();
+        string += QLatin1Char(':');
+        string += m_pRole[RoleType::A]->name();
+    }
+    string += QLatin1Char(':') + Uml::AssociationType::toStringI18n(m_AssocType) + QLatin1Char(':');
+    if(m_pRole[RoleType::B])
+    {
+        string += m_pRole[RoleType::B]->object()->name();
+        string += QLatin1Char(':');
+        string += m_pRole[RoleType::B]->name();
+    }
+    return string;
+}
+
+/**
+ * Resolve types. Required when dealing with foreign XMI files.
+ * Needs to be called after all UML objects are loaded from file.
+ * Overrides the method from UMLObject.
+ * Calls resolveRef() for each role.
+ * @return  True for success.
+ */
+bool UMLAssociation::resolveRef()
+{
+    bool successA = getUMLRole(RoleType::A)->resolveRef();
+    bool successB = getUMLRole(RoleType::B)->resolveRef();
+    if (successA && successB) {
+        UMLObject *objA = getUMLRole(RoleType::A)->object();
+        UMLObject *objB = getUMLRole(RoleType::B)->object();
+        // Check if need to change the assoc type to Realization
+        if (isRealization(objA, objB)) {
+            m_AssocType = Uml::AssociationType::Realization;
+        }
+        m_pUMLPackage->addAssocToConcepts(this);
+        return true;
+    }
+    return false;
+}
+
+/**
+ * Creates the <UML:Generalization> or <UML:Association> XMI element
+ * including its role objects.
+ */
+void UMLAssociation::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    if (m_AssocType == Uml::AssociationType::Generalization) {
+        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Generalization"), qDoc);
+        assocElement.setAttribute(QLatin1String("discriminator"), QString());
+        assocElement.setAttribute(QLatin1String("child"), Uml::ID::toString(getObjectId(RoleType::A)));
+        assocElement.setAttribute(QLatin1String("parent"), Uml::ID::toString(getObjectId(RoleType::B)));
+        qElement.appendChild(assocElement);
+        return;
+    }
+    if (m_AssocType == Uml::AssociationType::Realization) {
+        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Abstraction"), qDoc);
+        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
+        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
+        qElement.appendChild(assocElement);
+        return;
+    }
+    if (m_AssocType == Uml::AssociationType::Dependency) {
+        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Dependency"), qDoc);
+        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
+        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
+        qElement.appendChild(assocElement);
+        return;
+    }
+    if (m_AssocType == Uml::AssociationType::Child2Category) {
+        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Child2Category"), qDoc);
+        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
+        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
+        qElement.appendChild(assocElement);
+        return;
+    }
+    if (m_AssocType == Uml::AssociationType::Category2Parent) {
+        QDomElement assocElement = UMLObject::save(QLatin1String("UML:Category2Parent"), qDoc);
+        assocElement.setAttribute(QLatin1String("client"), Uml::ID::toString(getObjectId(RoleType::A)));
+        assocElement.setAttribute(QLatin1String("supplier"), Uml::ID::toString(getObjectId(RoleType::B)));
+        qElement.appendChild(assocElement);
+        return;
+    }
+
+    QDomElement associationElement = UMLObject::save(QLatin1String("UML:Association"), qDoc);
+    QDomElement connElement = qDoc.createElement(QLatin1String("UML:Association.connection"));
+    getUMLRole(RoleType::A)->saveToXMI (qDoc, connElement);
+    getUMLRole(RoleType::B)->saveToXMI (qDoc, connElement);
+    associationElement.appendChild (connElement);
+    qElement.appendChild(associationElement);
+}
+
+bool UMLAssociation::showPropertiesDialog(QWidget *parent)
+{
+    QPointer<ClassPropertiesDialog> dlg = new ClassPropertiesDialog(parent, this, true);
+    bool modified = false;
+    if (dlg->exec()) {
+        modified = true;
+    }
+    dlg->close();
+    delete dlg;
+    return modified;
+}
+
+/**
+ * Creates the <UML:Generalization> or <UML:Association> XMI element
+ * including its role objects.
+ */
+bool UMLAssociation::load(QDomElement & element)
+{
+    if (id() == Uml::ID::None)
+        return false; // old style XMI file. No real info in this association.
+
+    UMLDoc * doc = UMLApp::app()->document();
+    UMLObject * obj[2] = { NULL, NULL };
+    if (m_AssocType == Uml::AssociationType::Generalization ||
+        m_AssocType == Uml::AssociationType::Realization    ||
+        m_AssocType == Uml::AssociationType::Dependency     ||
+        m_AssocType == Uml::AssociationType::Child2Category ||
+        m_AssocType == Uml::AssociationType::Category2Parent) {
+        QString general = element.attribute(QLatin1String("general"));
+        if (!general.isEmpty()) {
+            UMLClassifier *owningClassifier = dynamic_cast<UMLClassifier*>(m_pUMLPackage);
+            if (owningClassifier == NULL){
+                uWarning() << "Cannot load UML2 generalization: m_pUMLPackage is expected "
+                           << "to be the owning classifier (=client)";
+                return false;
+            }
+            m_pRole[RoleType::A]->setObject(owningClassifier);
+            m_pRole[RoleType::B]->setSecondaryId(general);     // defer resolution to resolveRef()
+            owningClassifier->addAssociationEnd(this);
+            m_pUMLPackage = m_pUMLPackage->umlPackage();       // reparent
+            m_pUMLPackage->addObject(this);
+            return true;
+        }
+        for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
+            const QString fetch = (m_AssocType == Uml::AssociationType::Generalization ?
+                                   r == RoleType::A ? QLatin1String("child") : QLatin1String("parent")
+                       : r == RoleType::A ? QLatin1String("client") : QLatin1String("supplier"));
+            QString roleIdStr = element.attribute(fetch);
+            if (roleIdStr.isEmpty()) {
+                // Might be given as a child node instead - see below.
+                continue;
+            }
+
+            // set umlobject of role if possible (else defer resolution)
+            obj[r] = doc->findObjectById(Uml::ID::fromString(roleIdStr));
+            Uml::RoleType::Enum role = Uml::RoleType::fromInt(r);
+            if (obj[r] == NULL) {
+                m_pRole[role]->setSecondaryId(roleIdStr);  // defer to resolveRef()
+            } else {
+                m_pRole[role]->setObject(obj[r]);
+                if (m_pUMLPackage == NULL) {
+                    Uml::ModelType::Enum mt = Model_Utils::convert_OT_MT(obj[r]->baseType());
+                    m_pUMLPackage = doc->rootFolder(mt);
+                    DEBUG(DBG_SRC) << "assoctype " << m_AssocType
+                        << ": setting model type " << Uml::ModelType::toString(mt);
+                }
+            }
+        }
+        if (obj[RoleType::A] == NULL || obj[RoleType::B] == NULL) {
+            for (QDomNode node = element.firstChild(); !node.isNull();
+                    node = node.nextSibling()) {
+                if (node.isComment())
+                    continue;
+                QDomElement tempElement = node.toElement();
+                QString tag = tempElement.tagName();
+                if (Model_Utils::isCommonXMIAttribute(tag))
+                    continue;
+                // Permitted tag names:
+                //  roleA: "child" "subtype" "client"
+                //  roleB: "parent" "supertype" "supplier"
+                QString idStr = tempElement.attribute(QLatin1String("xmi.id"));
+                if (idStr.isEmpty())
+                    idStr = tempElement.attribute(QLatin1String("xmi.idref"));
+                if (idStr.isEmpty()) {
+                    QDomNode inner = node.firstChild();
+                    QDomElement tmpElem = inner.toElement();
+                    idStr = tmpElem.attribute(QLatin1String("xmi.id"));
+                    if (idStr.isEmpty())
+                        idStr = tmpElem.attribute(QLatin1String("xmi.idref"));
+                }
+                if (idStr.isEmpty()) {
+                    uError() << "type " << m_AssocType
+                        << ", id " << Uml::ID::toString(id()) << ": "
+                        << "xmi id not given for " << tag;
+                    continue;
+                }
+                // Since we know for sure that we're dealing with a non
+                // umbrello file, use deferred resolution unconditionally.
+                if (UMLDoc::tagEq(tag, QLatin1String("child")) ||
+                        UMLDoc::tagEq(tag, QLatin1String("subtype")) ||
+                        UMLDoc::tagEq(tag, QLatin1String("client"))) {
+                    getUMLRole(RoleType::A)->setSecondaryId(idStr);
+                } else {
+                    getUMLRole(RoleType::B)->setSecondaryId(idStr);
+                }
+            }
+        }
+
+        // it is a realization if either endpoint is an interface
+        if (isRealization(obj[RoleType::A], obj[RoleType::B])) {
+            m_AssocType = Uml::AssociationType::Realization;
+        }
+        return true;
+    }
+
+    for (QDomNode node = element.firstChild(); !node.isNull();
+            node = node.nextSibling()) {
+        // uml13.dtd compliant format (new style)
+        if (node.isComment())
+            continue;
+        QDomElement tempElement = node.toElement();
+        QString tag = tempElement.tagName();
+        if (Model_Utils::isCommonXMIAttribute(tag))
+            continue;
+        if (!UMLDoc::tagEq(tag, QLatin1String("Association.connection")) &&
+                !UMLDoc::tagEq(tag, QLatin1String("Association.end")) &&  // Embarcadero's Describe
+                !UMLDoc::tagEq(tag, QLatin1String("Namespace.ownedElement")) &&
+                !UMLDoc::tagEq(tag, QLatin1String("Namespace.contents"))) {
+            uWarning() << "unknown child node " << tag;
+            continue;
+        }
+        // Load role A.
+        QDomNode nodeA = tempElement.firstChild();
+        while (nodeA.isComment())
+            nodeA = nodeA.nextSibling();
+        tempElement = nodeA.toElement();
+        if (tempElement.isNull()) {
+            uWarning() << "UML:Association : element (A) is Null";
+            return false;
+        }
+        tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("NavigableEnd"))) {  // Embarcadero's Describe
+            m_AssocType = Uml::AssociationType::UniAssociation;
+        } else if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
+                   !UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
+            uWarning() << "unknown child (A) tag " << tag;
+            return false;
+        }
+        if (! getUMLRole(RoleType::A)->loadFromXMI(tempElement))
+            return false;
+        // Load role B.
+        QDomNode nodeB = nodeA.nextSibling();
+        while (nodeB.isComment())
+            nodeB = nodeB.nextSibling();
+        tempElement = nodeB.toElement();
+        if (tempElement.isNull()) {
+            uWarning() << "UML:Association : element (B) is Null";
+            return false;
+        }
+        tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("NavigableEnd"))) {  // Embarcadero's Describe
+            m_AssocType = Uml::AssociationType::UniAssociation;
+        } else if (!UMLDoc::tagEq(tag, QLatin1String("AssociationEndRole")) &&
+                   !UMLDoc::tagEq(tag, QLatin1String("AssociationEnd"))) {
+            uWarning() << "unknown child (B) tag " << tag;
+            return false;
+        }
+        if (! getUMLRole(RoleType::B)->loadFromXMI(tempElement))
+            return false;
+
+        if (m_pUMLPackage == NULL) {
+            Uml::ModelType::Enum mt = Model_Utils::convert_OT_MT(getObject(RoleType::B)->baseType());
+            m_pUMLPackage = doc->rootFolder(mt);
+            DEBUG(DBG_SRC) << "setting model type " << Uml::ModelType::toString(mt);
+        }
+
+        // setting the association type:
+        //
+        // In the old days, we could just record this on the association,
+        // and be done with it. But thats not how the UML13.dtd does things.
+        // As a result, we are checking roleA for information about the
+        // parent association (!) which by this point in the parse, should
+        // be set. However, the information that the roles are allowed to have
+        // is not complete, so we need to finish the analysis here.
+
+        // find self-associations
+        if (m_AssocType == Uml::AssociationType::Association && getObjectId(RoleType::A) == getObjectId(RoleType::B))
+            m_AssocType = Uml::AssociationType::Association_Self;
+
+        // fall-back default type
+        if (m_AssocType == Uml::AssociationType::Unknown) {
+            m_AssocType = Uml::AssociationType::Association;
+        }
+
+        return true;
+    }
+
+    // From here on it's old-style stuff.
+    QString assocTypeStr = element.attribute(QLatin1String("assoctype"), QLatin1String("-1"));
+    Uml::AssociationType::Enum assocType = Uml::AssociationType::Unknown;
+    if (assocTypeStr[0] >= QLatin1Char('a') && assocTypeStr[0] <= QLatin1Char('z')) {
+        // In an earlier version, the natural assoctype names were saved.
+        const char *assocTypeString[] = {
+                    "generalization",   // Uml::AssociationType::Generalization
+                    "aggregation",      // Uml::AssociationType::Aggregation
+                    "dependency",       // Uml::AssociationType::Dependency
+                    "association",      // Uml::AssociationType::Association
+                    "associationself",  // Uml::AssociationType::Association_Self
+                    "collmessage",      // Uml::AssociationType::Coll_Message
+                    "seqmessage",       // Uml::AssociationType::Seq_Message
+                    "collmessageself",  // Uml::AssociationType::Coll_Message_Self
+                    "seqmessageself",   // Uml::AssociationType::Seq_Message_Self
+                    "implementation",   // Uml::AssociationType::Implementation
+                    "composition",      // Uml::AssociationType::Composition
+                    "realization",      // Uml::AssociationType::Realization
+                    "uniassociation",   // Uml::AssociationType::UniAssociation
+                    "anchor",           // Uml::AssociationType::Anchor
+                    "state",            // Uml::AssociationType::State
+                    "activity",         // Uml::AssociationType::Activity
+                    "exception",        // Uml::AssociationType::Exception
+                    "category2parent"   // Uml::AssociationType::Category2Parent
+                    "child2category"    // Uml::AssociationType::Child2Category
+                    "relationship"      // Uml::AssociationType::Relationship
+        };
+        const int arraySize = sizeof(assocTypeString) / sizeof(char*);
+        DEBUG(DBG_SRC) << "AssociationType string array size = " << arraySize;
+
+        int index;
+        for (index = 0; index < arraySize; ++index)
+            if (assocTypeStr == QString::fromLatin1(assocTypeString[index]))
+                break;
+        if (index < arraySize)
+            assocType = Uml::AssociationType::fromInt(index);
+    } else {
+        int assocTypeNum = assocTypeStr.toInt();
+        if (assocTypeNum < (int)Uml::AssociationType::Generalization ||   // first enum
+            assocTypeNum >= (int)Uml::AssociationType::Reserved) {     // last enum
+            uWarning() << "bad assoctype of UML:AssociationType::Enum " << Uml::ID::toString(id());
+            return false;
+        }
+        assocType = Uml::AssociationType::fromInt(assocTypeNum);
+    }
+    setAssociationType(assocType);
+
+    Uml::ID::Type roleAObjID = Uml::ID::fromString(element.attribute(QLatin1String("rolea"), QLatin1String("-1")));
+    Uml::ID::Type roleBObjID = Uml::ID::fromString(element.attribute(QLatin1String("roleb"), QLatin1String("-1")));
+    if (assocType == Uml::AssociationType::Aggregation ||
+        assocType == Uml::AssociationType::Composition) {
+        // Flip roles to compensate for changed diamond logic in AssociationLine.
+        // For further explanations see AssociationWidget::loadFromXMI.
+        Uml::ID::Type tmp = roleAObjID;
+        roleAObjID = roleBObjID;
+        roleBObjID = tmp;
+    }
+
+    UMLObject * objA = doc->findObjectById(roleAObjID);
+    UMLObject * objB = doc->findObjectById(roleBObjID);
+
+    if(objA)
+        getUMLRole(RoleType::A)->setObject(objA);
+    else
+        return false;
+
+    if(objB)
+        getUMLRole(RoleType::B)->setObject(objB);
+    else
+        return false;
+
+    setMultiplicity(element.attribute(QLatin1String("multia")), RoleType::A);
+    setMultiplicity(element.attribute(QLatin1String("multib")), RoleType::B);
+
+    setRoleName(element.attribute(QLatin1String("namea")), RoleType::A);
+    setRoleName(element.attribute(QLatin1String("nameb")), RoleType::B);
+
+    setRoleDoc(element.attribute(QLatin1String("doca")), RoleType::A);
+    setRoleDoc(element.attribute(QLatin1String("docb")), RoleType::B);
+
+    // Visibility defaults to Public if it cant set it here..
+    QString visibilityA = element.attribute(QLatin1String("visibilitya"), QLatin1String("0"));
+    QString visibilityB = element.attribute(QLatin1String("visibilityb"), QLatin1String("0"));
+    int vis = visibilityA.toInt();
+    if (vis >= 200)  // bkwd compat.
+        vis -= 200;
+    setVisibility((Uml::Visibility::Enum)vis, RoleType::A);
+    vis = visibilityB.toInt();
+    if (vis >= 200)  // bkwd compat.
+        vis -= 200;
+    setVisibility((Uml::Visibility::Enum)vis, RoleType::B);
+
+    // Changeability defaults to Changeable if it cant set it here..
+    QString changeabilityA = element.attribute(QLatin1String("changeabilitya"), QLatin1String("0"));
+    QString changeabilityB = element.attribute(QLatin1String("changeabilityb"), QLatin1String("0"));
+    if (changeabilityA.toInt() > 0)
+        setChangeability(Uml::Changeability::fromInt(changeabilityA.toInt()), RoleType::A);
+    if (changeabilityB.toInt() > 0)
+        setChangeability(Uml::Changeability::fromInt(changeabilityB.toInt()), RoleType::B);
+
+    return true;
+}
+
+/**
+ * Returns the UMLObject assigned to the given role.
+ * @return  Pointer to the UMLObject in the given role.
+ */
+UMLObject* UMLAssociation::getObject(Uml::RoleType::Enum role) const
+{
+    if (m_pRole[role] == NULL)
+        return NULL;
+    return m_pRole[role]->object();
+}
+
+/**
+ * Returns the ID of the UMLObject assigned to the given role.
+ * Shorthand for getObject(role)->ID().
+ * @return  ID of the UMLObject in the given role.
+ */
+Uml::ID::Type UMLAssociation::getObjectId(Uml::RoleType::Enum role) const
+{
+    UMLRole *roleObj = m_pRole[role];
+    if (roleObj == NULL)
+        return Uml::ID::None;
+    UMLObject *o = roleObj->object();
+    if (o == NULL) {
+        QString auxID = roleObj->secondaryId();
+        if (auxID.isEmpty()) {
+            uError() << "role " << role << ": getObject returns NULL";
+            return Uml::ID::None;
+        } else {
+            DEBUG(DBG_SRC) << "role " << role << ": using secondary ID " << auxID;
+            return Uml::ID::fromString(auxID);
+        }
+    }
+    return o->id();
+}
+
+/**
+ * Returns the ID of the UMLObject assigned to the given role.
+ * CURRENTLY UNUSED.
+ * @return  ID of the UMLObject of the given role.
+ */
+Uml::ID::Type UMLAssociation::getRoleId(RoleType::Enum role) const
+{
+    return m_pRole[role]->id();
+}
+
+/**
+ * Returns the changeability.
+ */
+Uml::Changeability::Enum UMLAssociation::changeability(Uml::RoleType::Enum role) const
+{
+    return m_pRole[role]->changeability();
+}
+
+/**
+ * Returns the Visibility of the given role.
+ * @return  Visibility of the given role.
+ */
+Uml::Visibility::Enum UMLAssociation::visibility(Uml::RoleType::Enum role) const
+{
+    return m_pRole[role]->visibility();
+}
+
+/**
+ * Returns the multiplicity assigned to the given role.
+ * @return  The multiplicity assigned to the given role.
+ */
+QString UMLAssociation::getMultiplicity(Uml::RoleType::Enum role) const
+{
+    return m_pRole[role]->multiplicity();
+}
+
+/**
+ * Returns the name assigned to the role A.
+ * @return  The name assigned to the given role.
+ */
+QString UMLAssociation::getRoleName(Uml::RoleType::Enum role) const
+{
+    return m_pRole[role]->name();
+}
+
+/**
+ * Returns the documentation assigned to the given role.
+ * @return  Documentation text of given role.
+ */
+QString UMLAssociation::getRoleDoc(Uml::RoleType::Enum role) const
+{
+    return m_pRole[role]->doc();
+}
+
+/**
+ * Get the underlying UMLRole object for the given role.
+ * @return  Pointer to the UMLRole object for the given role.
+ */
+UMLRole * UMLAssociation::getUMLRole(Uml::RoleType::Enum role) const
+{
+    return m_pRole[role];
+}
+
+/**
+ * Set the attribute m_bOldLoadMode.
+ * @param value   the new value to set
+ */
+void UMLAssociation::setOldLoadMode(bool value /* = true */)
+{
+    m_bOldLoadMode = value;
+}
+
+/**
+ * Return the backward compatibility flag for loading files.
+ */
+bool UMLAssociation::getOldLoadMode() const
+{
+    return m_bOldLoadMode;
+}
+
+/**
+ * Sets the assocType of the UMLAssociation.
+ * @param assocType The AssociationType::Enum of the UMLAssociation.
+ */
+void UMLAssociation::setAssociationType(Uml::AssociationType::Enum assocType)
+{
+    m_AssocType = assocType;
+    if (m_AssocType == Uml::AssociationType::UniAssociation)
+    {
+        // In this case we need to auto-set the multiplicity/rolenames
+        // of the roles
+#ifdef VERBOSE_DEBUGGING
+        DEBUG(DBG_SRC) << " A new uni-association has been created.";
+#endif
+    }
+    UMLObject::emitModified();
+}
+
+/**
+ * Sets the UMLObject playing the given role in the association.
+ * @param obj  Pointer to the UMLObject of the given role.
+ * @param role The Uml::RoleType::Enum played by the association
+ */
+void UMLAssociation::setObject(UMLObject *obj, Uml::RoleType::Enum role)
+{
+    m_pRole[role]->setObject(obj);
+}
+
+/**
+ * Sets the visibility of the given role of the UMLAssociation.
+ * @param value  Visibility of role.
+ * @param role   The Uml::RoleType::Enum to which the visibility is being applied
+ */
+void UMLAssociation::setVisibility(Visibility::Enum value, Uml::RoleType::Enum role)
+{
+    m_pRole[role]->setVisibility(value);
+}
+
+/**
+ * Sets the changeability of the given role of the UMLAssociation.
+ * @param value     Changeability_Type of the given role.
+ * @param role      The Uml::RoleType::Enum to which the changeability is being set
+ */
+void UMLAssociation::setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role)
+{
+    m_pRole[role]->setChangeability(value);
+}
+
+/**
+ * Sets the multiplicity of the given role of the UMLAssociation.
+ * @param multi    The multiplicity of the given role.
+ * @param role     The Uml::RoleType::Enum to which the multiplicity is being applied
+ */
+void UMLAssociation::setMultiplicity(const QString &multi, Uml::RoleType::Enum role)
+{
+    if (m_pRole[role]->multiplicity() != multi) {
+        UMLApp::app()->executeCommand(new CmdChangeMultiplicity(m_pRole[role], multi));
+    }
+}
+
+/**
+ * Sets the name of the given role of the UMLAssociation.
+ * @param roleName  The name to set for the given role.
+ * @param role      The Uml::RoleType::Enum for which to set the name.
+ */
+void UMLAssociation::setRoleName(const QString &roleName, Uml::RoleType::Enum role)
+{
+    m_pRole[role]->setName(roleName);
+}
+
+/**
+ * Sets the documentation on the given role in the association.
+ * @param doc      The string with the documentation.
+ * @param role     The Uml::RoleType::Enum to which the documentation is being applied
+ */
+void UMLAssociation::setRoleDoc(const QString &doc, Uml::RoleType::Enum role)
+{
+    m_pRole[role]->setDoc(doc);
+}
+
+/**
+ * When the association type is "Generalization" and at least one of the
+ * given objects an interface, then it is a "Realization".
+ * @param objA   UML object as role A
+ * @param objB   UML object as role B
+ * @return flag whether association is a realization
+ */
+bool UMLAssociation::isRealization(UMLObject* objA, UMLObject* objB) const
+{
+    bool aIsInterface = false;
+    if (objA && (objA->baseType() == UMLObject::ot_Interface)) {
+        aIsInterface = true;
+    }
+    bool bIsInterface = false;
+    if (objB && (objB->baseType() == UMLObject::ot_Interface)) {
+        bIsInterface = true;
+    }
+    return (m_AssocType == Uml::AssociationType::Generalization) &&
+           (aIsInterface || bIsInterface);
+}
+
+/**
+ * Common initializations at construction time.
+ * @param type      The AssociationType::Enum to represent.
+ * @param roleAObj  Pointer to the role A UMLObject.
+ * @param roleBObj  Pointer to the role B UMLObject.
+ */
+void UMLAssociation::init(Uml::AssociationType::Enum type, UMLObject *roleAObj, UMLObject *roleBObj)
+{
+    m_AssocType = type;
+    m_BaseType = ot_Association;
+    m_Name = QString();
+    m_bOldLoadMode = false;
+    nrof_parent_widgets = -1;
+    if (!UMLApp::app()->document()->loading()) {
+        m_pUMLPackage = UMLApp::app()->document()->currentRoot();
+    }
+    m_pRole[RoleType::A] = new UMLRole (this, roleAObj, RoleType::A);
+    m_pRole[RoleType::B] = new UMLRole (this, roleBObj, RoleType::B);
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/association.h umbrello-15.08.1/umbrello/umlmodel/association.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/association.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/association.h	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,102 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ASSOCIATION_H
+#define ASSOCIATION_H
+
+#include "basictypes.h"
+#include "umlobject.h"
+
+#include <QDomDocument>
+#include <QDomElement>
+
+class UMLRole;
+
+/**
+ * This class contains the non-graphic representation of an association.
+ * An association can be a generalization, realization, simple association,
+ * directed association, aggregation, or composition.
+ *
+ * @short Sets up association information.
+ * @author Oliver Kellogg <okellogg@users.sourceforge.net>
+ * @see UMLObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLAssociation : public UMLObject
+{
+    Q_OBJECT
+    friend class AssociationWidget;
+
+public:
+    UMLAssociation(Uml::AssociationType::Enum type, UMLObject *roleA, UMLObject *roleB);
+    explicit UMLAssociation(Uml::AssociationType::Enum type = Uml::AssociationType::Unknown);
+
+    virtual ~UMLAssociation();
+
+    bool operator==(const UMLAssociation &rhs) const;
+
+    QString toString() const;
+
+    UMLRole * getUMLRole(Uml::RoleType::Enum role) const;
+    Uml::ID::Type getObjectId(Uml::RoleType::Enum role) const;
+    Uml::ID::Type getRoleId(Uml::RoleType::Enum role) const;
+
+    void setAssociationType(Uml::AssociationType::Enum assocType);
+    Uml::AssociationType::Enum getAssocType() const;
+
+    void setObject(UMLObject *obj, Uml::RoleType::Enum role);
+    UMLObject* getObject(Uml::RoleType::Enum role) const;
+
+    void setVisibility(Uml::Visibility::Enum value, Uml::RoleType::Enum role);
+    Uml::Visibility::Enum visibility(Uml::RoleType::Enum role) const;
+
+    void setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role);
+    Uml::Changeability::Enum changeability(Uml::RoleType::Enum role) const;
+
+    void setMultiplicity(const QString &multi, Uml::RoleType::Enum role);
+    QString getMultiplicity(Uml::RoleType::Enum role) const;
+
+    void setRoleName(const QString &roleName, Uml::RoleType::Enum role);
+    QString getRoleName(Uml::RoleType::Enum role) const;
+
+    void setRoleDoc(const QString &doc, Uml::RoleType::Enum role);
+    QString getRoleDoc(Uml::RoleType::Enum role) const;
+
+    void setOldLoadMode(bool value = true);
+    bool getOldLoadMode() const;
+
+    virtual UMLObject* clone() const { return NULL; }
+
+    virtual bool resolveRef();
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual bool showPropertiesDialog(QWidget *parent = 0);
+
+protected:
+
+    bool load(QDomElement& element);
+
+    // keep track of number of parent widgets
+    int nrof_parent_widgets;
+
+    void init(Uml::AssociationType::Enum type, UMLObject *roleAObj, UMLObject *roleBObj);
+
+    UMLRole *                    m_pRole[2];
+    Uml::AssociationType::Enum   m_AssocType;
+    QString                      m_Name;
+    bool                         m_bOldLoadMode;
+
+private:
+
+    bool isRealization(UMLObject* objA, UMLObject* objB) const;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/attribute.cpp umbrello-15.08.1/umbrello/umlmodel/attribute.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/attribute.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/attribute.cpp	2015-10-08 11:48:59.506089026 +0300
@@ -0,0 +1,424 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "attribute.h"
+
+// app includes
+#include "debug_utils.h"
+#include "classifier.h"
+#include "operation.h"
+#include "umlobject.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "folder.h"
+#include "umlattributedialog.h"
+#include "object_factory.h"
+
+/**
+ * Sets up an attribute.
+ *
+ * @param parent    The parent of this UMLAttribute.
+ * @param name      The name of this UMLAttribute.
+ * @param id        The unique id given to this UMLAttribute.
+ * @param s         The visibility of the UMLAttribute.
+ * @param type      The type of this UMLAttribute.
+ * @param iv        The initial value of the attribute.
+ */
+UMLAttribute::UMLAttribute(UMLObject *parent,
+                           const QString& name, Uml::ID::Type id,
+                           Uml::Visibility::Enum s,
+                           UMLObject *type, const QString& iv)
+  : UMLClassifierListItem(parent, name, id)
+{
+    m_InitialValue = iv;
+    m_BaseType = UMLObject::ot_Attribute;
+    m_visibility = s;
+    m_ParmKind = Uml::ParameterDirection::In;
+    /* CHECK: Do we need this:
+    if (type == NULL) {
+        type = Object_Factory::createUMLObject(Uml::ot_Datatype, "undef");
+    }
+     */
+    m_pSecondary = type;
+}
+
+/**
+ * Sets up an attribute.
+ *
+ * @param parent    The parent of this UMLAttribute.
+ */
+UMLAttribute::UMLAttribute(UMLObject *parent) : UMLClassifierListItem(parent)
+{
+    m_BaseType = UMLObject::ot_Attribute;
+    m_visibility = Uml::Visibility::Private;
+    m_ParmKind = Uml::ParameterDirection::In;
+}
+
+/**
+ * Destructor.
+ */
+UMLAttribute::~UMLAttribute()
+{
+}
+
+/**
+ * Reimplementation of method from UMLObject is required as
+ * an extra signal, attributeChanged(), is emitted.
+ */
+void UMLAttribute::setName(const QString &name)
+{
+    m_name = name;
+    emit attributeChanged();
+    UMLObject::emitModified();
+}
+
+/**
+ * Reimplementation of method from UMLObject is required as
+ * an extra signal, attributeChanged(), is emitted.
+ */
+void UMLAttribute::setVisibility(Uml::Visibility::Enum s)
+{
+    m_visibility = s;
+    emit attributeChanged();
+    UMLObject::emitModified();
+}
+
+/**
+ * Returns The initial value of the UMLAttribute.
+ *
+ * @return  The initial value of the Atrtibute.
+ */
+QString UMLAttribute::getInitialValue() const
+{
+    return m_InitialValue;
+}
+
+/**
+ * Sets the initial value of the UMLAttribute.
+ *
+ * @param iv   The initial value of the UMLAttribute.
+ */
+void UMLAttribute::setInitialValue(const QString &iv)
+{
+    if(m_InitialValue != iv) {
+        m_InitialValue = iv;
+        UMLObject::emitModified();
+    }
+}
+
+void UMLAttribute::setParmKind (Uml::ParameterDirection::Enum pk)
+{
+    m_ParmKind = pk;
+}
+
+Uml::ParameterDirection::Enum UMLAttribute::getParmKind() const
+{
+    return m_ParmKind;
+}
+
+/**
+ * Returns a string representation of the UMLAttribute.
+ *
+ * @param sig   If true will show the attribute type and initial value.
+ * @return  Returns a string representation of the UMLAttribute.
+ */
+QString UMLAttribute::toString(Uml::SignatureType::Enum sig)
+{
+    QString s;
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::NoSig) {
+        s = Uml::Visibility::toString(m_visibility, true) + QLatin1Char(' ');
+    }
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
+        // Determine whether the type name needs to be scoped.
+        UMLObject *owningObject = static_cast<UMLObject*>(parent());
+        if (owningObject->baseType() == UMLObject::ot_Operation) {
+            // The immediate parent() is the UMLOperation but we want
+            // the UMLClassifier:
+            owningObject = static_cast<UMLObject*>(owningObject->parent());
+        }
+        UMLClassifier *ownParent = dynamic_cast<UMLClassifier*>(owningObject);
+        if (ownParent == NULL) {
+            uError() << "parent " << owningObject->name()
+                << " is not a UMLClassifier";
+            return QString();
+        }
+        QString typeName;
+        UMLClassifier *type = UMLClassifierListItem::getType();
+        if (type) {
+            UMLPackage *typeScope = type->umlPackage();
+            if (typeScope != ownParent && typeScope != ownParent->umlPackage())
+                typeName = type->fullyQualifiedName();
+            else
+                typeName = type->name();
+        }
+        // The default direction, "in", is not mentioned.
+        // Perhaps we should include a pd_Unspecified in
+        // Uml::ParameterDirection::Enum to have better control over this.
+        if (m_ParmKind == Uml::ParameterDirection::InOut)
+            s += QLatin1String("inout ");
+        else if (m_ParmKind == Uml::ParameterDirection::Out)
+            s += QLatin1String("out ");
+        // Construct the attribute text.
+        QString string = s + name() + QLatin1String(" : ") + typeName;
+        if (m_InitialValue.length() > 0)
+            string += QLatin1String(" = ") + m_InitialValue;
+        return string;
+    }
+    return s + name();
+}
+
+/**
+ * Reimplement method from UMLObject.
+ */
+QString UMLAttribute::getFullyQualifiedName(const QString& separator,
+                                            bool includeRoot /* = false */) const
+{
+    UMLOperation *op = NULL;
+    UMLObject *owningObject = static_cast<UMLObject*>(parent());
+    if (owningObject->baseType() == UMLObject::ot_Operation) {
+        op = static_cast<UMLOperation*>(owningObject);
+        owningObject = static_cast<UMLObject*>(owningObject->parent());
+    }
+    UMLClassifier *ownParent = dynamic_cast<UMLClassifier*>(owningObject);
+    if (ownParent == NULL) {
+        uError() << name() << ": parent " << owningObject->name()
+            << " is not a UMLClassifier";
+        return QString();
+    }
+    QString tempSeparator = separator;
+    if (tempSeparator.isEmpty())
+        tempSeparator = UMLApp::app()->activeLanguageScopeSeparator();
+    QString fqn = ownParent->fullyQualifiedName(tempSeparator, includeRoot);
+    if (op)
+        fqn.append(tempSeparator + op->name());
+    fqn.append(tempSeparator + name());
+    return fqn;
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLAttribute::operator==(const UMLAttribute &rhs) const
+{
+    if(this == &rhs)
+        return true;
+
+    if(!UMLObject::operator==(rhs))
+        return false;
+
+    // The type name is the only distinguishing criterion.
+    // (Some programming languages might support more, but others don't.)
+    if (m_pSecondary != rhs.m_pSecondary)
+        return false;
+
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the UMLAttribute
+ * object.
+ */
+void UMLAttribute::copyInto(UMLObject *lhs) const
+{
+    UMLAttribute *target = static_cast<UMLAttribute*>(lhs);
+    // call the parent first.
+    UMLClassifierListItem::copyInto(target);
+
+    // Copy all datamembers
+    target->m_pSecondary = m_pSecondary;
+    target->m_SecondaryId = m_SecondaryId;
+    target->m_InitialValue = m_InitialValue;
+    target->m_ParmKind = m_ParmKind;
+}
+
+/**
+ * Make a clone of the UMLAttribute.
+ */
+UMLObject* UMLAttribute::clone() const
+{
+    //FIXME: The new attribute should be slaved to the NEW parent not the old.
+    UMLAttribute *clone = new UMLAttribute(static_cast<UMLObject*>(parent()));
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Creates the <UML:Attribute> XMI element.
+ */
+void UMLAttribute::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement attributeElement = UMLObject::save(QLatin1String("UML:Attribute"), qDoc);
+    if (m_pSecondary == NULL) {
+        uDebug() << name() << ": m_pSecondary is NULL, m_SecondaryId is '"
+            << m_SecondaryId << "'";
+    } else {
+        attributeElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
+    }
+    if (! m_InitialValue.isEmpty())
+        attributeElement.setAttribute(QLatin1String("initialValue"), m_InitialValue);
+    qElement.appendChild(attributeElement);
+}
+
+/**
+ * Loads the <UML:Attribute> XMI element.
+ */
+bool UMLAttribute::load(QDomElement & element)
+{
+    m_SecondaryId = element.attribute(QLatin1String("type"));
+    // We use the m_SecondaryId as a temporary store for the xmi.id
+    // of the attribute type model object.
+    // It is resolved later on, when all classes have been loaded.
+    // This deferred resolution is required because the xmi.id may
+    // be a forward reference, i.e. it may identify a model object
+    // that has not yet been loaded.
+    if (m_SecondaryId.isEmpty()) {
+        // Perhaps the type is stored in a child node:
+        QDomNode node = element.firstChild();
+        while (!node.isNull()) {
+            if (node.isComment()) {
+                node = node.nextSibling();
+                continue;
+            }
+            QDomElement tempElement = node.toElement();
+            QString tag = tempElement.tagName();
+            if (!UMLDoc::tagEq(tag, QLatin1String("type"))) {
+                node = node.nextSibling();
+                continue;
+            }
+            m_SecondaryId = Model_Utils::getXmiId(tempElement);
+            if (m_SecondaryId.isEmpty())
+                m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
+            if (m_SecondaryId.isEmpty()) {
+                QString href = tempElement.attribute(QLatin1String("href"));
+                if (href.isEmpty()) {
+                    QDomNode inner = node.firstChild();
+                    QDomElement tmpElem = inner.toElement();
+                    m_SecondaryId = Model_Utils::getXmiId(tmpElem);
+                    if (m_SecondaryId.isEmpty())
+                        m_SecondaryId = tmpElem.attribute(QLatin1String("xmi.idref"));
+                } else {
+                    int hashpos = href.lastIndexOf(QChar(QLatin1Char('#')));
+                    if (hashpos < 0) {
+                        uDebug() << name() << ": cannot find type " << href;
+                    } else {
+                        QString typeName = href.mid(hashpos + 1);
+                        UMLFolder *dtFolder = UMLApp::app()->document()->datatypeFolder();
+                        m_pSecondary = Model_Utils::findUMLObject(dtFolder->containedObjects(),
+                                                                  typeName, UMLObject::ot_Datatype);
+                        if (!m_pSecondary) {
+                            m_pSecondary = Object_Factory::createUMLObject(UMLObject::ot_Datatype,
+                                                                           typeName, dtFolder);
+                        }
+                    }
+                }
+            }
+            break;
+        }
+        if (m_SecondaryId.isEmpty()) {
+            uDebug() << name() << ": cannot find type.";
+        }
+    }
+    m_InitialValue = element.attribute(QLatin1String("initialValue"));
+    if (m_InitialValue.isEmpty()) {
+        // for backward compatibility
+        m_InitialValue = element.attribute(QLatin1String("value"));
+    }
+    return true;
+}
+
+/**
+ * Display the properties configuration dialog for the attribute.
+ */
+bool UMLAttribute::showPropertiesDialog(QWidget* parent)
+{
+    UMLAttributeDialog dialog(parent, this);
+    return dialog.exec();
+}
+
+/**
+ * Puts in the param templateParamList all the template params that are in templateParam
+ */
+void UMLAttribute::setTemplateParams(const QString& templateParam, UMLClassifierList &templateParamList)
+{
+    if (templateParam.isEmpty())
+        return;
+    QString type = templateParam.simplified();
+
+    int start = type.indexOf(QLatin1Char('<'));
+    if (start >= 0) {
+        int end = start;
+        int count = 1;
+        int len = type.length();
+        while (count != 0 && ++end < len) {
+            QChar c = type.at(end);
+            if (c == QLatin1Char('<')) {
+                count++;
+            }
+            if (c == QLatin1Char('>')) {
+                count--;
+            }
+        }
+        if (count != 0) {
+            //The template is ill-formated, let's quit
+            return;
+        }
+        setTemplateParams(type.mid(start + 1, end - start - 1), templateParamList);
+        setTemplateParams(type.left(start) + type.right(len - end - 1), templateParamList);
+    } else {
+        QStringList paramsList = type.split(QLatin1Char(','));
+        for (QStringList::Iterator it = paramsList.begin(); it != paramsList.end(); ++it) {
+            QString param = *it;
+            if (!param.isEmpty()) {
+                UMLDoc *pDoc = UMLApp::app()->document();
+                UMLObject* obj = pDoc->findUMLObject(param);
+                if (obj == NULL) {
+                    obj = pDoc->findUMLObject(param.remove(QLatin1Char(' ')));
+                }
+                if (obj != NULL) {
+                    //We want to list only the params that already exist in this document
+                    //If the param doesnt't already exist, we couldn't draw an association anyway
+                    UMLClassifier* tmpClassifier = static_cast<UMLClassifier*>(obj);
+                    if (templateParamList.indexOf(tmpClassifier) == -1) {
+                        templateParamList.append(tmpClassifier);
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Returns all the template params (if any) that are in the type of this attribute
+ */
+UMLClassifierList UMLAttribute::getTemplateParams()
+{
+    UMLClassifierList templateParamList;
+    QString type = getType()->name();
+    QString templateParam;
+    // Handle C++/D/Java template/generic parameters
+    const Uml::ProgrammingLanguage::Enum pl = UMLApp::app()->activeLanguage();
+    if (pl == Uml::ProgrammingLanguage::Cpp  ||
+        pl == Uml::ProgrammingLanguage::Java || pl == Uml::ProgrammingLanguage::D) {
+        int start = type.indexOf(QLatin1Char('<'));
+        if (start >= 0) {
+            int end = type.lastIndexOf(QLatin1Char('>'));
+            if (end > start) {
+                templateParam = type.mid(start + 1, end - start - 1);
+                setTemplateParams(templateParam, templateParamList);
+            }
+        }
+    }
+    return templateParamList;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/attribute.h umbrello-15.08.1/umbrello/umlmodel/attribute.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/attribute.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/attribute.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+
+#include "basictypes.h"
+#include "classifierlistitem.h"
+#include "umlclassifierlist.h"
+
+/**
+ * This class is used to set up information for an attribute.  This is like
+ * a programming attribute.  It has a type, name, visibility and initial value.
+ *
+ * @short Sets up attribute information.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLAttribute : public UMLClassifierListItem
+{
+    Q_OBJECT
+public:
+
+    UMLAttribute(UMLObject *parent, const QString& name,
+                 Uml::ID::Type id = Uml::ID::None,
+                 Uml::Visibility::Enum s = Uml::Visibility::Private,
+                 UMLObject *type = 0, const QString& iv = QString());
+    explicit UMLAttribute(UMLObject *parent);
+
+    bool operator==(const UMLAttribute &rhs) const;
+
+    virtual ~UMLAttribute();
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    void setName(const QString &name);
+
+    void setVisibility(Uml::Visibility::Enum s);
+
+    virtual UMLObject* clone() const;
+
+    QString getInitialValue() const;
+    void setInitialValue(const QString &iv);
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    QString getFullyQualifiedName(const QString& separator = QString(),
+                                  bool includeRoot = false) const;
+
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+    void setParmKind(Uml::ParameterDirection::Enum pk);
+    Uml::ParameterDirection::Enum getParmKind() const;
+
+    virtual UMLClassifierList getTemplateParams();
+
+signals:
+
+    void attributeChanged();
+
+protected:
+
+    bool load(QDomElement & element);
+
+    QString m_InitialValue; ///< text for the attribute's initial value.
+    Uml::ParameterDirection::Enum m_ParmKind;
+
+private:
+
+    void setTemplateParams(const QString& templateParam, UMLClassifierList &templateParamList);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/category.cpp umbrello-15.08.1/umbrello/umlmodel/category.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/category.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/category.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,101 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "category.h"
+
+/**
+ * Constructs a Category.
+ *
+ * @param name   The name of the Category.
+ * @param id     The unique id to assign to this Category.
+ */
+UMLCategory::UMLCategory(const QString & name, Uml::ID::Type id)
+  : UMLCanvasObject(name, id)
+{
+    init();
+}
+
+/**
+ * Standard destructor.
+ */
+UMLCategory::~UMLCategory()
+{
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLCategory::init()
+{
+    m_BaseType = UMLObject::ot_Category;
+    m_CategoryType = ct_Disjoint_Specialisation;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLCategory::copyInto(UMLObject *lhs) const
+{
+    UMLCategory *target = static_cast<UMLCategory*>(lhs);
+
+    // call the parent first
+    UMLCanvasObject::copyInto(target);
+
+    target->m_CategoryType = m_CategoryType;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLCategory::clone() const
+{
+    UMLCategory *clone = new UMLCategory();
+    copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the <UML:Category> XMI element.
+ */
+void UMLCategory::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+     QDomElement categoryElement = UMLObject::save(QLatin1String("UML:Category"), qDoc);
+     categoryElement.setAttribute(QLatin1String("categoryType"), (int)m_CategoryType);
+     qElement.appendChild(categoryElement);
+}
+
+/**
+ * Loads the <UML:Category> XMI element (empty.)
+ */
+bool UMLCategory::load(QDomElement& element)
+{
+    m_CategoryType = (Category_Type)element.attribute(QLatin1String("categoryType"),
+                                                      QLatin1String("0")).toInt();
+    return true;
+}
+
+/**
+ * Get the category type
+ */
+UMLCategory::Category_Type UMLCategory::getType()
+{
+    return m_CategoryType;
+}
+
+/**
+ * Set the category type
+ */
+void UMLCategory::setType(Category_Type type)
+{
+    m_CategoryType = type;
+    emitModified();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/category.h umbrello-15.08.1/umbrello/umlmodel/category.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/category.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/category.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,62 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef CATEGORY_H
+#define CATEGORY_H
+
+#include "umlcanvasobject.h"
+
+/**
+ * This class contains the non-graphical information required for a UML Category.
+ * This class inherits from @ref UMLCanvasObject which contains most of the
+ * information.
+ * The @ref UMLDoc class creates instances of this type.
+ *
+ * @short Information for a non-graphical UML Category.
+ * @author Sharan Rao
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLCategory : public UMLCanvasObject {
+    Q_OBJECT
+public:
+
+    enum Category_Type {
+        ct_Disjoint_Specialisation,
+        ct_Overlapping_Specialisation,
+        ct_Union
+    };
+
+    explicit UMLCategory(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    ~UMLCategory();
+
+    virtual void init();
+
+    void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    UMLCategory::Category_Type getType();
+
+    void setType(Category_Type type);
+
+protected:
+
+    bool load(QDomElement & element);
+
+private:
+
+    Category_Type m_CategoryType;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/checkconstraint.cpp umbrello-15.08.1/umbrello/umlmodel/checkconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/checkconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/checkconstraint.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,160 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+//own header
+#include "checkconstraint.h"
+
+// app includes
+#include "debug_utils.h"
+#include "umlcheckconstraintdialog.h"
+
+/**
+ * Sets up a constraint.
+ *
+ * @param parent    The parent of this UMLCheckConstraint.
+ * @param name      The name of this UMLCheckConstraint.
+ * @param id        The unique id given to this UMLCheckConstraint.
+ */
+UMLCheckConstraint::UMLCheckConstraint(UMLObject *parent,
+                          const QString& name, Uml::ID::Type id)
+    : UMLEntityConstraint(parent, name, id)
+{
+    init();
+}
+
+/**
+ * Sets up a constraint.
+ *
+ * @param parent    The parent of this UMLCheckConstraint.
+ */
+UMLCheckConstraint::UMLCheckConstraint(UMLObject *parent)
+    : UMLEntityConstraint(parent)
+{
+    init();
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLCheckConstraint::operator==(const UMLCheckConstraint &rhs) const
+{
+    if (this == &rhs)
+        return true;
+
+    if (!UMLObject::operator==(rhs))
+        return false;
+
+    return true;
+}
+
+/**
+ * Destructor.
+ */
+UMLCheckConstraint::~UMLCheckConstraint()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the UMLCheckConstraint
+ * object.
+ */
+void UMLCheckConstraint::copyInto(UMLObject *lhs) const
+{
+    UMLCheckConstraint *target = static_cast<UMLCheckConstraint*>(lhs);
+
+    // call the parent first.
+    UMLEntityConstraint::copyInto(target);
+
+    // Copy all datamembers
+    target->m_CheckCondition = m_CheckCondition;
+}
+
+/**
+ * Make a clone of the UMLCheckConstraint.
+ */
+UMLObject* UMLCheckConstraint::clone() const
+{
+    //FIXME: The new attribute should be slaved to the NEW parent not the old.
+    UMLCheckConstraint *clone = new UMLCheckConstraint(static_cast<UMLObject*>(parent()));
+    copyInto(clone);
+    return clone;
+}
+
+/**
+ * Returns a string representation of the UMLCheckConstraint.
+ *
+ * @param sig   If true will show the attribute type and initial value.
+ * @return  Returns a string representation of the UMLAttribute.
+ */
+QString UMLCheckConstraint::toString(Uml::SignatureType::Enum sig)
+{
+    QString s;
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
+        s = name() ;
+    }
+
+    return s;
+}
+
+QString UMLCheckConstraint::getFullyQualifiedName(const QString& separator,
+                                                  bool includeRoot) const
+{
+    Q_UNUSED(separator); Q_UNUSED(includeRoot);
+    return this->name();
+}
+
+/**
+ * Creates the <UML:UniqueConstraint> XMI element.
+ */
+void UMLCheckConstraint::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement checkConstraintElement = UMLObject::save(QLatin1String("UML:CheckConstraint"), qDoc);
+
+    QDomNode checkCondition = qDoc.createTextNode(m_CheckCondition);
+    checkConstraintElement.appendChild(checkCondition);
+
+    qElement.appendChild(checkConstraintElement);
+}
+
+/**
+ * Display the properties configuration dialog for the attribute.
+ */
+bool UMLCheckConstraint::showPropertiesDialog(QWidget* parent)
+{
+    UMLCheckConstraintDialog dialog(parent, this);
+    return dialog.exec();
+}
+
+/**
+ * Loads the <UML:CheckConstraint> XMI element.
+ */
+bool UMLCheckConstraint::load(QDomElement & element)
+{
+    QDomNode node = element.firstChild();
+
+    QDomText checkConstraintText = node.toText();
+    if (checkConstraintText.isNull())
+        m_CheckCondition = QString();
+    else
+        m_CheckCondition = checkConstraintText.data();
+
+    return true;
+}
+
+/**
+ * Initialises Check Constraint
+ */
+void UMLCheckConstraint::init()
+{
+    m_BaseType = UMLObject::ot_CheckConstraint;
+    m_CheckCondition.clear();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/checkconstraint.h umbrello-15.08.1/umbrello/umlmodel/checkconstraint.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/checkconstraint.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/checkconstraint.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,71 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef CHECKCONSTRAINT_H
+#define CHECKCONSTRAINT_H
+
+#include "basictypes.h"
+#include "entityconstraint.h"
+
+/**
+ * This class is used to set up information for a unique entity constraint.
+ *
+ * @short Sets up Check Constraint information for UMLEntities.
+ * @author Sharan Rao
+ * @see UMLObject UMLClassifierListItem UMLEntityConstraint
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLCheckConstraint : public UMLEntityConstraint
+{
+     Q_OBJECT
+public:
+
+    UMLCheckConstraint(UMLObject *parent, const QString& name,
+                       Uml::ID::Type id = Uml::ID::None);
+    explicit UMLCheckConstraint(UMLObject *parent);
+
+    bool operator==(const UMLCheckConstraint &rhs) const;
+
+    virtual ~UMLCheckConstraint();
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    QString getFullyQualifiedName(const QString& separator = QString(),
+                                  bool includeRoot = false) const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+    QString getCheckCondition() const {
+        return m_CheckCondition;
+    }
+
+    void setCheckCondition(const QString& condition) {
+        m_CheckCondition = condition.trimmed();
+    }
+
+protected:
+
+    bool load(QDomElement & element);
+
+private:
+
+    void init();
+
+    QString m_CheckCondition;   ///< the check condition
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/classifier.cpp umbrello-15.08.1/umbrello/umlmodel/classifier.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/classifier.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/classifier.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,1631 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+#include "classifier.h"
+
+// app includes
+#include "association.h"
+#include "debug_utils.h"
+#include "umlassociationlist.h"
+#include "operation.h"
+#include "attribute.h"
+#include "template.h"
+#include "enumliteral.h"
+#include "entityattribute.h"
+#include "enum.h"
+#include "entity.h"
+#include "stereotype.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "uniqueid.h"
+#include "object_factory.h"
+#include "model_utils.h"
+#include "idchangelog.h"
+#include "umloperationdialog.h"
+#include "umlattributedialog.h"
+#include "umltemplatedialog.h"
+#include "optionstate.h"
+#include "icon_utils.h"
+
+// kde includes
+#include <KLocalizedString>
+#include <KMessageBox>
+
+// qt includes
+#include <QPointer>
+
+using namespace Uml;
+
+/**
+ * @brief holds set of classifiers for recursive loop detection
+ */
+class UMLClassifierSet: public QSet<UMLClassifier *> {
+public:
+    UMLClassifierSet() : level(0)
+    {
+    }
+    int level;
+};
+
+/**
+ * Sets up a Classifier.
+ *
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLClassifier::UMLClassifier(const QString & name, Uml::ID::Type id)
+  : UMLPackage(name, id)
+{
+    m_BaseType = UMLObject::ot_Class;  // default value
+    m_pClassAssoc = NULL;
+    m_isRef = false;
+}
+
+/**
+ * Standard deconstructor.
+ */
+UMLClassifier::~UMLClassifier()
+{
+}
+
+/**
+ * Reimplementation of method from class UMLObject for controlling the
+ * exact type of this classifier: class, interface, or datatype.
+ * @param ot   the base type to set
+ */
+void UMLClassifier::setBaseType(UMLObject::ObjectType ot)
+{
+    m_BaseType = ot;
+    Icon_Utils::IconType newIcon;
+    switch (ot) {
+        case ot_Interface:
+            UMLObject::setStereotypeCmd(QLatin1String("interface"));
+            UMLObject::m_bAbstract = true;
+            newIcon = Icon_Utils::it_Interface;
+            break;
+        case ot_Class:
+            UMLObject::setStereotypeCmd(QString());
+            UMLObject::m_bAbstract = false;
+            newIcon = Icon_Utils::it_Class;
+            break;
+        case ot_Datatype:
+            UMLObject::setStereotypeCmd(QLatin1String("datatype"));
+            UMLObject::m_bAbstract = false;
+            newIcon = Icon_Utils::it_Datatype;
+            break;
+        case ot_Package:
+            UMLObject::setStereotypeCmd(QString());
+            UMLObject::m_bAbstract = false;
+            newIcon = Icon_Utils::it_Package;
+            break;
+        default:
+            uError() << "cannot set to type " << ot;
+            return;
+    }
+    Model_Utils::treeViewChangeIcon(this, newIcon);
+}
+
+/**
+ * Returns true if this classifier represents an interface.
+ */
+bool UMLClassifier::isInterface() const
+{
+    return (m_BaseType == ot_Interface);
+}
+
+/**
+ * Returns true if this classifier represents a datatype.
+ */
+bool UMLClassifier::isDatatype() const
+{
+    return (m_BaseType == ot_Datatype);
+}
+
+/**
+ * Checks whether an operation is valid based on its signature -
+ * An operation is "valid" if the operation's name and parameter list
+ * are unique in the classifier.
+ *
+ * @param name      Name of the operation to check.
+ * @param opParams  The operation's argument list.
+ * @param exemptOp  Pointer to the exempt method (optional.)
+ * @return  NULL if the signature is valid (ok), else return a pointer
+ *          to the existing UMLOperation that causes the conflict.
+ */
+UMLOperation * UMLClassifier::checkOperationSignature(
+        const QString& name,
+        UMLAttributeList opParams,
+        UMLOperation *exemptOp)
+{
+    UMLOperationList list = findOperations(name);
+    if (list.count() == 0) {
+        return NULL;
+    }
+    const int inputParmCount = opParams.count();
+
+    // there is at least one operation with the same name... compare the parameter list
+    foreach (UMLOperation* test, list) {
+        if (test == exemptOp) {
+            continue;
+        }
+        UMLAttributeList testParams = test->getParmList();
+        const int pCount = testParams.count();
+        if (pCount != inputParmCount) {
+            continue;
+        }
+        int i = 0;
+        while (i < pCount) {
+            // The only criterion for equivalence is the parameter types.
+            // (Default values are not considered.)
+            if(testParams.at(i)->getTypeName() != opParams.at(i)->getTypeName())
+                break;
+            i++;
+        }
+        if (i == pCount) { // all parameters matched->the signature is not unique
+            return test;
+        }
+    }
+    // we did not find an exact match, so the signature is unique (acceptable)
+    return NULL;
+}
+
+/**
+ * Find an operation of the given name and parameter signature.
+ *
+ * @param name     The name of the operation to find.
+ * @param params   The parameter descriptors of the operation to find.
+ *
+ * @return  The operation found.  Will return 0 if none found.
+ */
+UMLOperation* UMLClassifier::findOperation(const QString& name,
+                                           Model_Utils::NameAndType_List params)
+{
+    UMLOperationList list = findOperations(name);
+    if (list.count() == 0) {
+        return NULL;
+    }
+    // if there are operation(s) with the same name then compare the parameter list
+    const int inputParmCount = params.count();
+
+    foreach (UMLOperation* test, list) {
+        UMLAttributeList testParams = test->getParmList();
+        const int pCount = testParams.count();
+        if (inputParmCount == 0 && pCount == 0)
+            return test;
+        if (inputParmCount != pCount)
+            continue;
+        int i = 0;
+        for (; i < pCount; ++i) {
+            Model_Utils::NameAndType_ListIt nt(params.begin() + i);
+            UMLClassifier *type = dynamic_cast<UMLClassifier*>((*nt).m_type);
+            UMLClassifier *testType = testParams.at(i)->getType();
+            if (type == NULL && testType == NULL) { //no parameter type
+                continue;
+            } else if (type == NULL) {  //template parameter
+                if (testType->name() != QLatin1String("class"))
+                    break;
+            } else if (type != testType)
+                break;
+        }
+        if (i == pCount)
+            return test;  // all parameters matched
+    }
+    return 0;
+}
+
+/**
+ * Creates an operation in the current document.
+ * The new operation is initialized with name, id, etc.
+ * If a method with the given profile already exists in the classifier,
+ * no new method is created and the existing operation is returned.
+ * If no name is provided, or if the params are NULL, an Operation
+ * Dialog is shown to ask the user for a name and parameters.
+ * The operation's signature is checked for validity within the parent
+ * classifier.
+ *
+ * @param name           The operation name (will be chosen internally if
+ *                       none given.)
+ * @param isExistingOp   Optional pointer to bool. If supplied, the bool is
+ *                       set to true if an existing operation is returned.
+ * @param params         Optional list of parameter names and types.
+ *                       If supplied, new operation parameters are
+ *                       constructed using this list.
+ * @return The new operation, or NULL if the operation could not be
+ *         created because for example, the user canceled the dialog
+ *         or no appropriate name can be found.
+ */
+UMLOperation* UMLClassifier::createOperation(
+        const QString &name /*=QString()*/,
+        bool *isExistingOp  /*=NULL*/,
+        Model_Utils::NameAndType_List *params  /*=NULL*/)
+{
+    bool nameNotSet = (name.isNull() || name.isEmpty());
+    if (! nameNotSet) {
+        Model_Utils::NameAndType_List parList;
+        if (params)
+            parList = *params;
+        UMLOperation* existingOp = findOperation(name, parList);
+        if (existingOp != NULL) {
+            if (isExistingOp != NULL)
+                *isExistingOp = true;
+            return existingOp;
+        }
+    }
+    // we did not find an exact match, so the signature is unique
+    UMLOperation *op = new UMLOperation(this, name);
+    if (params) {
+        for (Model_Utils::NameAndType_ListIt it = params->begin(); it != params->end(); ++it) {
+            const Model_Utils::NameAndType &nt = *it;
+            UMLAttribute *par = new UMLAttribute(op, nt.m_name, Uml::ID::None, Uml::Visibility::Private,
+                                                 nt.m_type, nt.m_initialValue);
+            par->setParmKind(nt.m_direction);
+            op->addParm(par);
+        }
+    }
+
+    // Only show the operation dialog if no name was provided (allows quick-create
+    // from listview)
+    if (nameNotSet) {
+        op->setName(uniqChildName(UMLObject::ot_Operation));
+
+        while (true) {
+            QPointer<UMLOperationDialog> operationDialog = new UMLOperationDialog(0, op);
+            if(operationDialog->exec() != QDialog::Accepted) {
+                delete op;
+                delete operationDialog;
+                return NULL;
+            } else if (checkOperationSignature(op->name(), op->getParmList())) {
+                KMessageBox::information(0,
+                                         i18n("An operation with the same name and signature already exists. You cannot add it again."));
+            } else {
+                break;
+            }
+            delete operationDialog;
+        }
+    }
+
+    // operation name is ok, formally add it to the classifier
+    if (! addOperation(op)) {
+        delete op;
+        return NULL;
+    }
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(op);
+    return op;
+}
+
+/**
+ * Appends an operation to the classifier.
+ * This function is mainly intended for the clipboard.
+ *
+ * @param op         Pointer to the UMLOperation to add.
+ * @param position   Inserted at the given position.
+ * @return           True if the operation was added successfully.
+ */
+bool UMLClassifier::addOperation(UMLOperation* op, int position)
+{
+    Q_ASSERT(op);
+    if (m_List.indexOf(op) != -1) {
+        uDebug() << "findRef(" << op->name() << ") finds op (bad)";
+        return false;
+    }
+    if (checkOperationSignature(op->name(), op->getParmList())) {
+        uDebug() << "checkOperationSignature(" << op->name() << ") op is non-unique";
+        return false;
+    }
+
+    if (position >= 0 && position <= m_List.count()) {
+        uDebug() << op->name() << ": inserting at position " << position;
+        m_List.insert(position, op);
+        UMLClassifierListItemList itemList = getFilteredList(UMLObject::ot_Operation);
+        QString buf;
+        foreach (UMLClassifierListItem* currentAtt, itemList) {
+            buf.append(QLatin1Char(' ') + currentAtt->name());
+        }
+        uDebug() << "  list after change: " << buf;
+    }
+    else {
+        m_List.append(op);
+    }
+    emit operationAdded(op);
+    UMLObject::emitModified();
+    connect(op, SIGNAL(modified()), this, SIGNAL(modified()));
+    return true;
+}
+
+/**
+ * Appends an operation to the classifier.
+ * @see bool addOperation(UMLOperation* Op, int position = -1)
+ * This function is mainly intended for the clipboard.
+ *
+ * @param op    Pointer to the UMLOperation to add.
+ * @param log   Pointer to the IDChangeLog.
+ * @return      True if the operation was added successfully.
+ */
+bool UMLClassifier::addOperation(UMLOperation* op, IDChangeLog* log)
+{
+    if (addOperation(op, -1)) {
+        return true;
+    }
+    else if (log) {
+        log->removeChangeByNewID(op->id());
+    }
+    return false;
+}
+
+/**
+ * Remove an operation from the Classifier.
+ * The operation is not deleted so the caller is responsible for what
+ * happens to it after this.
+ *
+ * @param op   The operation to remove.
+ * @return     Count of the remaining operations after removal, or
+ *             -1 if the given operation was not found.
+ */
+int UMLClassifier::removeOperation(UMLOperation *op)
+{
+    if (op == NULL) {
+        uDebug() << "called on NULL op";
+        return -1;
+    }
+    if (!m_List.removeAll(op)) {
+        uDebug() << "cannot find op " << op->name() << " in list";
+        return -1;
+    }
+    // disconnection needed.
+    // note that we don't delete the operation, just remove it from the Classifier
+    disconnect(op, SIGNAL(modified()), this, SIGNAL(modified()));
+    emit operationRemoved(op);
+    UMLObject::emitModified();
+    return m_List.count();
+}
+
+/**
+ * Create and add a just created template.
+ * @param currentName   the name of the template
+ * @return              the template or NULL
+ */
+UMLObject* UMLClassifier::createTemplate(const QString& currentName /*= QString()*/)
+{
+    QString name = currentName;
+    bool goodName = !name.isEmpty();
+    if (!goodName) {
+        name = uniqChildName(UMLObject::ot_Template);
+    }
+    UMLTemplate* newTemplate = new UMLTemplate(this, name);
+
+    int button = QDialog::Accepted;
+
+    while (button == QDialog::Accepted && !goodName) {
+        QPointer<UMLTemplateDialog> templateDialog = new UMLTemplateDialog(0, newTemplate);
+        button = templateDialog->exec();
+        name = newTemplate->name();
+
+        if (name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        }
+        else if (findChildObject(name) != NULL) {
+            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
+        }
+        else {
+            goodName = true;
+        }
+        delete templateDialog;
+    }
+
+    if (button != QDialog::Accepted) {
+        return NULL;
+    }
+
+    addTemplate(newTemplate);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newTemplate);
+    return newTemplate;
+}
+
+/**
+ * Returns the number of attributes for the class.
+ *
+ * @return  The number of attributes for the class.
+ */
+int UMLClassifier::attributes()
+{
+    UMLClassifierListItemList atts = getFilteredList(UMLObject::ot_Attribute);
+    return atts.count();
+}
+
+/**
+ * Returns the attributes for the specified scope.
+ * @return   List of true attributes for the class.
+ */
+UMLAttributeList UMLClassifier::getAttributeList() const
+{
+    UMLAttributeList attributeList;
+    foreach (UMLObject* listItem, m_List) {
+        uIgnoreZeroPointer(listItem);
+        if (listItem->baseType() == UMLObject::ot_Attribute) {
+            attributeList.append(static_cast<UMLAttribute*>(listItem));
+        }
+    }
+    return attributeList;
+}
+
+/**
+ * Returns the attributes for the specified scope.
+ * @param scope   The scope of the attribute.
+ * @return        List of true attributes for the class.
+ */
+UMLAttributeList UMLClassifier::getAttributeList(Visibility::Enum scope) const
+{
+    UMLAttributeList list;
+    if (!isInterface())
+    {
+        UMLAttributeList atl = getAttributeList();
+        foreach(UMLAttribute* at, atl)
+        {
+            uIgnoreZeroPointer(at);
+            if (! at->isStatic())
+            {
+                if (scope == Uml::Visibility::Private)
+                {
+                    if ((at->visibility() == Uml::Visibility::Private) ||
+                       (at->visibility() == Uml::Visibility::Implementation))
+                    {
+                        list.append(at);
+                    }
+                }
+                else if (scope == at->visibility())
+                {
+                   list.append(at);
+                }
+            }
+        }
+    }
+    return list;
+}
+
+/**
+ * Returns the static attributes for the specified scope.
+ *
+ * @param scope   The scope of the attribute.
+ * @return        List of true attributes for the class.
+ */
+UMLAttributeList UMLClassifier::getAttributeListStatic(Visibility::Enum scope) const
+{
+    UMLAttributeList list;
+    if (!isInterface())
+    {
+        UMLAttributeList atl = getAttributeList();
+        foreach(UMLAttribute* at, atl)
+        {
+            uIgnoreZeroPointer(at);
+            if (at->isStatic())
+            {
+                if (scope == Uml::Visibility::Private)
+                {
+                    if ((at->visibility() == Uml::Visibility::Private) ||
+                       (at->visibility() == Uml::Visibility::Implementation))
+                    {
+                        list.append(at);
+                    }
+                }
+                else if (scope == at->visibility())
+                {
+                    list.append(at);
+                }
+            }
+        }
+    }
+    return list;
+}
+
+/**
+ * Find a list of operations with the given name.
+ *
+ * @param n   The name of the operation to find.
+ * @return    The list of objects found; will be empty if none found.
+ */
+UMLOperationList UMLClassifier::findOperations(const QString &n)
+{
+    const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
+    UMLOperationList list;
+    foreach (UMLObject*  obj, m_List) {
+        uIgnoreZeroPointer(obj);
+        if (obj->baseType() != UMLObject::ot_Operation)
+            continue;
+        UMLOperation *op = static_cast<UMLOperation*>(obj);
+        if (caseSensitive) {
+            if (obj->name() == n)
+                list.append(op);
+        } else if (obj->name().toLower() == n.toLower()) {
+            list.append(op);
+        }
+    }
+    return list;
+}
+
+/**
+ * Find the child object by the given id.
+ * @param id                  the id of the child object
+ * @param considerAncestors   flag whether the ancestors should be considered during search
+ * @return                    the found child object or NULL
+ */
+UMLObject* UMLClassifier::findChildObjectById(Uml::ID::Type id, bool considerAncestors /* =false */)
+{
+    UMLObject *o = UMLCanvasObject::findChildObjectById(id);
+    if (o) {
+        return o;
+    }
+    if (considerAncestors) {
+        UMLClassifierList ancestors = findSuperClassConcepts();
+        foreach (UMLClassifier *anc, ancestors) {
+            UMLObject *o = anc->findChildObjectById(id);
+            if (o) {
+                return o;
+            }
+        }
+    }
+    return NULL;
+}
+
+/**
+ * Returns a list of concepts which inherit from this concept.
+ *
+ * @param type   The ClassifierType to seek.
+ * @return       List of UMLClassifiers that inherit from us.
+ */
+UMLClassifierList UMLClassifier::findSubClassConcepts (ClassifierType type)
+{
+    UMLClassifierList list = getSubClasses();
+    UMLAssociationList rlist = getRealizations();
+
+    UMLClassifierList inheritingConcepts;
+    Uml::ID::Type myID = id();
+    foreach(UMLClassifier *c, list) {
+        uIgnoreZeroPointer(c);
+        if (type == ALL || (!c->isInterface() && type == CLASS)
+                || (c->isInterface() && type == INTERFACE)) {
+            inheritingConcepts.append(c);
+        }
+    }
+
+    foreach (UMLAssociation *a, rlist) {
+        uIgnoreZeroPointer(a);
+        if (a->getObjectId(RoleType::A) != myID)
+        {
+            UMLObject* obj = a->getObject(RoleType::A);
+            UMLClassifier *concept = dynamic_cast<UMLClassifier*>(obj);
+            if (concept && (type == ALL || (!concept->isInterface() && type == CLASS)
+                            || (concept->isInterface() && type == INTERFACE))
+                        && (inheritingConcepts.indexOf(concept) == -1))
+            {
+                inheritingConcepts.append(concept);
+            }
+        }
+    }
+
+    return inheritingConcepts;
+}
+
+/**
+ * Returns a list of concepts which this concept inherits from.
+ *
+ * @param type   The ClassifierType to seek.
+ * @return       List of UMLClassifiers we inherit from.
+ */
+UMLClassifierList UMLClassifier::findSuperClassConcepts (ClassifierType type)
+{
+    UMLClassifierList list = getSuperClasses();
+    UMLAssociationList rlist = getRealizations();
+
+    UMLClassifierList parentConcepts;
+    Uml::ID::Type myID = id();
+    foreach (UMLClassifier *concept, list) {
+        uIgnoreZeroPointer(concept);
+        if (type == ALL || (!concept->isInterface() && type == CLASS)
+                || (concept->isInterface() && type == INTERFACE))
+            parentConcepts.append(concept);
+    }
+
+    foreach (UMLAssociation *a, rlist) {
+        if (a->getObjectId(RoleType::A) == myID)
+        {
+            UMLObject* obj = a->getObject(RoleType::B);
+            UMLClassifier *concept = dynamic_cast<UMLClassifier*>(obj);
+            if (concept && (type == ALL || (!concept->isInterface() && type == CLASS)
+                            || (concept->isInterface() && type == INTERFACE))
+                        && (parentConcepts.indexOf(concept) == -1))
+                parentConcepts.append(concept);
+        }
+    }
+
+    return parentConcepts;
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLClassifier::operator==(const UMLClassifier & rhs) const
+{
+    return UMLCanvasObject::operator==(rhs);
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLClassifier::copyInto(UMLObject *lhs) const
+{
+    UMLClassifier *target = static_cast<UMLClassifier*>(lhs);
+    UMLCanvasObject::copyInto(target);
+    target->setBaseType(m_BaseType);
+    // CHECK: association property m_pClassAssoc is not copied
+    m_List.copyInto(&(target->m_List));
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLClassifier::clone() const
+{
+    UMLClassifier *clone = new UMLClassifier();
+    copyInto(clone);
+    return clone;
+}
+
+/**
+ * Needs to be called after all UML objects are loaded from file.
+ * Calls the parent resolveRef(), and calls resolveRef() on all
+ * UMLClassifierListItems.
+ * Overrides the method from UMLObject.
+ *
+ * @return  true for success.
+ */
+bool UMLClassifier::resolveRef()
+{
+    bool success = UMLPackage::resolveRef();
+    // Using reentrant iteration is a bare necessity here:
+    foreach (UMLObject* obj, m_List) {
+        uIgnoreZeroPointer(obj);
+        /**** For reference, here is the non-reentrant iteration scheme -
+              DO NOT USE THIS !
+        for (UMLObject *obj = m_List.first(); obj; obj = m_List.next())
+         {  ....  }
+         ****/
+        if (obj->resolveRef()) {
+            UMLClassifierListItem *cli = static_cast<UMLClassifierListItem*>(obj);
+            switch (cli->baseType()) {
+                case UMLObject::ot_Attribute:
+                    emit attributeAdded(cli);
+                    break;
+                case UMLObject::ot_Operation:
+                    emit operationAdded(cli);
+                    break;
+                case UMLObject::ot_Template:
+                    emit templateAdded(cli);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+    return success;
+}
+
+/**
+ * Reimplemented from UMLObject.
+ */
+bool UMLClassifier::acceptAssociationType(AssociationType::Enum type)
+{
+    switch(type)
+    {
+        case AssociationType::Generalization:
+        case AssociationType::Aggregation:
+        case AssociationType::Relationship:
+        case AssociationType::Dependency:
+        case AssociationType::Association:
+        case AssociationType::Association_Self:
+        case AssociationType::Containment:
+        case AssociationType::Composition:
+        case AssociationType::Realization:
+        case AssociationType::UniAssociation:
+            return true;
+        default:
+            return false;
+    }
+    return false; //shutup compiler warning
+}
+
+/**
+ * Creates an attribute for the class.
+ *
+ * @param name  An optional name, used by when creating through UMLListView
+ * @param type  An optional type, used by when creating through UMLListView
+ * @param vis   An optional visibility, used by when creating through UMLListView
+ * @param init  An optional initial value, used by when creating through UMLListView
+ * @return      The UMLAttribute created
+ */
+UMLAttribute* UMLClassifier::createAttribute(const QString &name,
+                                             UMLObject *type,
+                                             Visibility::Enum vis,
+                                             const QString &init)
+{
+    Uml::ID::Type id = UniqueID::gen();
+    QString currentName;
+    if (name.isNull())  {
+        currentName = uniqChildName(UMLObject::ot_Attribute);
+    } else {
+        currentName = name;
+    }
+    UMLAttribute* newAttribute = new UMLAttribute(this, currentName, id, vis, type, init);
+
+    int button = QDialog::Accepted;
+    bool goodName = false;
+
+    //check for name.isNull() stops dialog being shown
+    //when creating attribute via list view
+    while (button == QDialog::Accepted && !goodName && name.isNull()) {
+        QPointer<UMLAttributeDialog> attributeDialog = new UMLAttributeDialog(0, newAttribute);
+        button = attributeDialog->exec();
+        QString name = newAttribute->name();
+
+        if(name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        } else if (findChildObject(name) != NULL) {
+            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
+        } else {
+            goodName = true;
+        }
+        delete attributeDialog;
+    }
+
+    if (button != QDialog::Accepted) {
+        delete newAttribute;
+        return NULL;
+    }
+
+    addAttribute(newAttribute);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newAttribute);
+    return newAttribute;
+}
+
+/**
+ * Creates and adds an attribute for the class.
+ *
+ * @param name  an optional name, used by when creating through UMLListView
+ * @param id    an optional id
+ * @return      the UMLAttribute created and added
+ */
+
+UMLAttribute* UMLClassifier::addAttribute(const QString &name, Uml::ID::Type id /* = Uml::id_None */)
+{
+    foreach (UMLObject* obj, m_List) {
+        uIgnoreZeroPointer(obj);
+        if (obj->baseType() == UMLObject::ot_Attribute && obj->name() == name)
+            return static_cast<UMLAttribute*>(obj);
+    }
+    Uml::Visibility::Enum scope = Settings::optionState().classState.defaultAttributeScope;
+    UMLAttribute *a = new UMLAttribute(this, name, id, scope);
+    m_List.append(a);
+    emit attributeAdded(a);
+    UMLObject::emitModified();
+    connect(a, SIGNAL(modified()), this, SIGNAL(modified()));
+    return a;
+}
+
+/**
+ * Adds an already created attribute.
+ * The attribute object must not belong to any other concept.
+ *
+ * @param name    the name of the attribute
+ * @param type    the type of the attribute
+ * @param scope   the visibility of the attribute
+ * @return        the just created and added attribute
+ */
+UMLAttribute* UMLClassifier::addAttribute(const QString &name, UMLObject *type, Visibility::Enum scope)
+{
+    UMLAttribute *a = new UMLAttribute(this);
+    a->setName(name);
+    a->setVisibility(scope);
+    a->setID(UniqueID::gen());
+    if (type) {
+        a->setType(type);
+    }
+    m_List.append(a);
+    emit attributeAdded(a);
+    UMLObject::emitModified();
+    connect(a, SIGNAL(modified()), this, SIGNAL(modified()));
+    return a;
+}
+
+/**
+ * Adds an already created attribute.
+ * The attribute object must not belong to any other concept.
+ *
+ * @param att        Pointer to the UMLAttribute.
+ * @param log        Pointer to the IDChangeLog (optional.)
+ * @param position   Position index for the insertion (optional.)
+ *                   If the position is omitted, or if it is
+ *                   negative or too large, the attribute is added
+ *                   to the end of the list.
+ * @return           True if the attribute was successfully added.
+ */
+bool UMLClassifier::addAttribute(UMLAttribute* att, IDChangeLog* log /* = 0 */,
+                                 int position /* = -1 */)
+{
+    Q_ASSERT(att);
+    if (findChildObject(att->name()) == NULL) {
+        att->setParent(this);
+        if (position >= 0 && position < (int)m_List.count()) {
+            m_List.insert(position, att);
+        }
+        else {
+            m_List.append(att);
+        }
+        emit attributeAdded(att);
+        UMLObject::emitModified();
+        connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    } else if (log) {
+        log->removeChangeByNewID(att->id());
+        delete att;
+    }
+    return false;
+}
+
+/**
+ * Removes an attribute from the class.
+ *
+ * @param att   The attribute to remove.
+ * @return      Count of the remaining attributes after removal.
+ *              Returns -1 if the given attribute was not found.
+ */
+int UMLClassifier::removeAttribute(UMLAttribute* att)
+{
+    if (!m_List.removeAll(att)) {
+        uDebug() << "cannot find att given in list";
+        return -1;
+    }
+    emit attributeRemoved(att);
+    UMLObject::emitModified();
+    // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
+    // for us by QObject. -b.t.
+    // disconnect(att, SIGNAL(modified()), this, SIGNAL(modified()));
+    delete att;
+    return m_List.count();
+}
+
+/**
+ * Sets the UMLAssociation for which this class shall act as an
+ * association class.
+ */
+void UMLClassifier::setClassAssoc(UMLAssociation *assoc)
+{
+    m_pClassAssoc = assoc;
+}
+
+/**
+ * Returns the UMLAssociation for which this class acts as an
+ * association class. Returns NULL if this class does not act
+ * as an association class.
+ */
+UMLAssociation *UMLClassifier::getClassAssoc() const
+{
+    return m_pClassAssoc;
+}
+
+/**
+ * Return true if this classifier has abstract operations.
+ */
+bool UMLClassifier::hasAbstractOps ()
+{
+    UMLOperationList opl(getOpList());
+    foreach(UMLOperation *op, opl) {
+        uIgnoreZeroPointer(op);
+        if (op->isAbstract()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Counts the number of operations in the Classifier.
+ *
+ * @return   The number of operations for the Classifier.
+ */
+int UMLClassifier::operations()
+{
+    return getOpList().count();
+}
+
+
+/**
+ * Return a list of operations for the Classifier.
+ *
+ * @param includeInherited   Includes operations from superclasses.
+ * @param alreadyTraversed   internal used object to avoid recursive loops
+ * @return   The list of operations for the Classifier.
+ */
+UMLOperationList UMLClassifier::getOpList(bool includeInherited, UMLClassifierSet *alreadyTraversed)
+{
+    UMLOperationList ops;
+    foreach (UMLObject* li, m_List) {
+        uIgnoreZeroPointer(li);
+        if (li->baseType() == ot_Operation) {
+            ops.append(static_cast<UMLOperation*>(li));
+        }
+    }
+    if (includeInherited) {
+        if (!alreadyTraversed) {
+            alreadyTraversed = new UMLClassifierSet;
+        }
+        else
+            alreadyTraversed->level++;
+
+        if (!alreadyTraversed->contains(this))
+            *alreadyTraversed << this;
+
+        // get a list of parents of this class
+        UMLClassifierList parents = findSuperClassConcepts();
+        foreach(UMLClassifier *c, parents) {
+            if (alreadyTraversed->contains(c)) {
+                uError() << "class " << c->name() << " is starting a dependency loop!";
+                continue;
+            }
+            // get operations for each parent by recursive call
+            UMLOperationList pops = c->getOpList(true, alreadyTraversed);
+            // add these operations to operation list, but only if unique.
+            foreach (UMLOperation *po, pops) {
+                QString po_as_string(po->toString(Uml::SignatureType::SigNoVis));
+                bool breakFlag = false;
+                foreach (UMLOperation* o,  ops) {
+                    if (o->toString(Uml::SignatureType::SigNoVis) == po_as_string) {
+                        breakFlag = true;
+                        break;
+                    }
+                }
+                if (breakFlag == false)
+                    ops.append(po);
+            }
+            // remember this node
+            *alreadyTraversed << c;
+        }
+        if (alreadyTraversed->level-- == 0) {
+            delete alreadyTraversed;
+            alreadyTraversed = 0;
+        }
+    }
+    return ops;
+}
+
+/**
+ * Returns the entries in m_List that are of the requested type.
+ * If the requested type is UMLObject::ot_UMLObject then all entries
+ * are returned.
+ * @param ot   the requested object type
+ * @return     The list of true operations for the Concept.
+ */
+UMLClassifierListItemList UMLClassifier::getFilteredList(UMLObject::ObjectType ot) const
+{
+    UMLClassifierListItemList resultList;
+    foreach (UMLObject* o, m_List) {
+        uIgnoreZeroPointer(o);
+        if (!o || o->baseType() == UMLObject::ot_Association) {
+            continue;
+        }
+        UMLClassifierListItem *listItem = static_cast<UMLClassifierListItem*>(o);
+        if (ot == UMLObject::ot_UMLObject || listItem->baseType() == ot) {
+            resultList.append(listItem);
+        }
+    }
+    return resultList;
+}
+
+/**
+ * Adds an already created template.
+ * The template object must not belong to any other concept.
+ *
+ * @param name   the name of the template
+ * @param id     the id of the template
+ * @return       the added template
+ */
+UMLTemplate* UMLClassifier::addTemplate(const QString &name, Uml::ID::Type id)
+{
+    UMLTemplate *templt = findTemplate(name);
+    if (templt) {
+        return templt;
+    }
+    templt = new UMLTemplate(this, name, id);
+    m_List.append(templt);
+    emit templateAdded(templt);
+    UMLObject::emitModified();
+    connect(templt, SIGNAL(modified()), this, SIGNAL(modified()));
+    return templt;
+}
+
+/**
+ * Adds an already created template.
+ * The template object must not belong to any other concept.
+ *
+ * @param newTemplate   Pointer to the UMLTemplate object to add.
+ * @param log           Pointer to the IDChangeLog.
+ * @return              True if the template was successfully added.
+ */
+bool UMLClassifier::addTemplate(UMLTemplate* newTemplate, IDChangeLog* log /* = 0*/)
+{
+    QString name = newTemplate->name();
+    if (findChildObject(name) == NULL) {
+        newTemplate->setParent(this);
+        m_List.append(newTemplate);
+        emit templateAdded(newTemplate);
+        UMLObject::emitModified();
+        connect(newTemplate, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    }
+    else if (log) {
+        log->removeChangeByNewID(newTemplate->id());
+        delete newTemplate;
+    }
+    return false;
+}
+
+/**
+ * Adds an template to the class.
+ * The template object must not belong to any other class.
+ * TODO: If the param IDChangeLog from the method above is not being used,
+ * give position a default value of -1 and the method can replace the above one.
+ * @param templt     Pointer to the UMLTemplate to add.
+ * @param position   The position of the template in the list.
+ *                   A value of -1 will add the template at the end.
+ * @return  True if the template was successfully added.
+ */
+bool UMLClassifier::addTemplate(UMLTemplate* templt, int position)
+{
+    Q_ASSERT(templt);
+    QString name = templt->name();
+    if (findChildObject(name) == NULL) {
+        templt->setParent(this);
+        if (position >= 0 && position <= (int)m_List.count()) {
+            m_List.insert(position, templt);
+        }
+        else {
+            m_List.append(templt);
+        }
+        emit templateAdded(templt);
+        UMLObject::emitModified();
+        connect(templt, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    }
+    //else
+    return false;
+}
+
+/**
+ * Removes a template from the class.
+ *
+ * @param umltemplate   The template to remove.
+ * @return  Count of the remaining templates after removal.
+ *          Returns -1 if the given template was not found.
+ */
+int UMLClassifier::removeTemplate(UMLTemplate* umltemplate)
+{
+    if (!m_List.removeAll(umltemplate)) {
+        uWarning() << "cannot find att given in list";
+        return -1;
+    }
+    emit templateRemoved(umltemplate);
+    UMLObject::emitModified();
+    disconnect(umltemplate, SIGNAL(modified()), this, SIGNAL(modified()));
+    return m_List.count();
+}
+
+/**
+ * Seeks the template parameter of the given name.
+ * @param name   the template name
+ * @return       the found template or 0
+ */
+UMLTemplate *UMLClassifier::findTemplate(const QString& name)
+{
+    UMLTemplateList templParams = getTemplateList();
+    foreach (UMLTemplate *templt, templParams) {
+        if (templt->name() == name) {
+            return templt;
+        }
+    }
+    return 0;
+}
+
+/**
+ * Returns the number of templates for the class.
+ *
+ * @return  The number of templates for the class.
+ */
+int UMLClassifier::templates()
+{
+    UMLClassifierListItemList tempList = getFilteredList(UMLObject::ot_Template);
+    return tempList.count();
+}
+
+/**
+ * Returns the templates.
+ * Same as UMLClassifier::getFilteredList(ot_Template) but
+ * return type is a true UMLTemplateList.
+ *
+ * @return  Pointer to the list of true templates for the class.
+ */
+UMLTemplateList UMLClassifier::getTemplateList() const
+{
+    UMLTemplateList templateList;
+    foreach (UMLObject* listItem, m_List) {
+        uIgnoreZeroPointer(listItem);
+        if (listItem->baseType() == UMLObject::ot_Template) {
+            templateList.append(static_cast<UMLTemplate*>(listItem));
+        }
+    }
+    return templateList;
+}
+
+/**
+ * Take and return a subordinate item from this classifier.
+ * Ownership of the item is passed to the caller.
+ *
+ * @param item   Subordinate item to take.
+ * @return       Index in m_List of the item taken.
+ *               Return -1 if the item is not found in m_List.
+ */
+int UMLClassifier::takeItem(UMLClassifierListItem *item)
+{
+    QString buf;
+    foreach (UMLObject* currentAtt, m_List) {
+        uIgnoreZeroPointer(currentAtt);
+        QString txt = currentAtt->name();
+        if (txt.isEmpty()) {
+           txt = QLatin1String("Type-") + QString::number((int) currentAtt->baseType());
+        }
+        buf.append(QLatin1Char(' ') + currentAtt->name());
+    }
+    uDebug() << "  UMLClassifier::takeItem (before): m_List is " << buf;
+
+    int index = m_List.indexOf(item);
+    if (index == -1) {
+        return -1;
+    }
+    switch (item->baseType()) {
+        case UMLObject::ot_Operation: {
+            if (removeOperation(dynamic_cast<UMLOperation*>(item)) < 0) {
+                index = -1;
+            }
+            break;
+        }
+        case UMLObject::ot_Attribute: {
+            UMLAttribute *retval = dynamic_cast<UMLAttribute*>(m_List.takeAt(index).data());
+            if (retval) {
+                emit attributeRemoved(retval);
+                UMLObject::emitModified();
+            } else {
+                index = -1;
+            }
+            break;
+        }
+        case UMLObject::ot_Template: {
+            UMLTemplate *templt = dynamic_cast<UMLTemplate*>(m_List.takeAt(index).data());
+            if (templt) {
+                emit templateRemoved(templt);
+                UMLObject::emitModified();
+            } else {
+                index = -1;
+            }
+            break;
+        }
+        case UMLObject::ot_EnumLiteral: {
+            UMLEnumLiteral *el = dynamic_cast<UMLEnumLiteral*>(m_List.takeAt(index).data());
+            if (el) {
+                UMLEnum *e = static_cast<UMLEnum*>(this);
+                e->signalEnumLiteralRemoved(el);
+                UMLObject::emitModified();
+            } else {
+                index = -1;
+            }
+            break;
+        }
+        case UMLObject::ot_EntityAttribute: {
+            UMLEntityAttribute* el = dynamic_cast<UMLEntityAttribute*>(m_List.takeAt(index).data());
+            if (el) {
+                UMLEntity *e = static_cast<UMLEntity*>(this);
+                e->signalEntityAttributeRemoved(el);
+                UMLObject::emitModified();
+            } else {
+                index = -1;
+            }
+            break;
+        }
+        default:
+            index = -1;
+            break;
+    }
+    return index;
+}
+
+/**
+ * Set the origin type (in case of e.g. typedef)
+ * @param origType   the origin type to set
+ */
+void UMLClassifier::setOriginType(UMLClassifier *origType)
+{
+    m_pSecondary = origType;
+}
+
+/**
+ * Get the origin type (in case of e.g. typedef)
+ * @return   the origin type
+ */
+UMLClassifier * UMLClassifier::originType() const
+{
+    return dynamic_cast<UMLClassifier*>(m_pSecondary.data());
+}
+
+/**
+ * Set the m_isRef flag (true when dealing with a pointer type)
+ * @param isRef   the flag to set
+ */
+void UMLClassifier::setIsReference(bool isRef)
+{
+    m_isRef = isRef;
+}
+
+/**
+ * Get the m_isRef flag.
+ * @return   true if is reference, otherwise false
+ */
+bool UMLClassifier::isReference() const
+{
+    return m_isRef;
+}
+
+/**
+ * Return true if this classifier has associations.
+ * @return   true if classifier has associations
+ */
+bool UMLClassifier::hasAssociations()
+{
+    return getSpecificAssocs(AssociationType::Association).count() > 0
+            || getAggregations().count() > 0
+            || getCompositions().count() > 0
+            || getUniAssociationToBeImplemented().count() > 0;
+}
+
+/**
+ * Return true if this classifier has attributes.
+ */
+bool UMLClassifier::hasAttributes()
+{
+    return getAttributeList(Uml::Visibility::Public).count() > 0
+            || getAttributeList(Uml::Visibility::Protected).count() > 0
+            || getAttributeList(Uml::Visibility::Private).count() > 0
+            || getAttributeListStatic(Uml::Visibility::Public).count() > 0
+            || getAttributeListStatic(Uml::Visibility::Protected).count() > 0
+            || getAttributeListStatic(Uml::Visibility::Private).count() > 0;
+}
+
+/**
+ * Return true if this classifier has static attributes.
+ */
+bool UMLClassifier::hasStaticAttributes()
+{
+    return getAttributeListStatic(Uml::Visibility::Public).count() > 0
+            || getAttributeListStatic(Uml::Visibility::Protected).count() > 0
+            || getAttributeListStatic(Uml::Visibility::Private).count() > 0;
+}
+
+/**
+ * Return true if this classifier has accessor methods.
+ */
+bool UMLClassifier::hasAccessorMethods()
+{
+    return hasAttributes() || hasAssociations();
+}
+
+/**
+ * Return true if this classifier has operation methods.
+ */
+bool UMLClassifier::hasOperationMethods()
+{
+    return getOpList().last() ? true : false;
+}
+
+/**
+ * Return true if this classifier has methods.
+ */
+bool UMLClassifier::hasMethods()
+{
+    return hasOperationMethods() || hasAccessorMethods();
+}
+
+// this is a bit too simplistic..some associations are for
+// SINGLE objects, and WONT be declared as Vectors, so this
+// is a bit overly inclusive (I guess that's better than the other way around)
+
+/**
+ * Return true if this classifier has vector fields.
+ */
+bool UMLClassifier::hasVectorFields()
+{
+    return hasAssociations();
+}
+
+/**
+ * Return the list of unidirectional association that should show up in the code
+ */
+UMLAssociationList  UMLClassifier::getUniAssociationToBeImplemented()
+{
+    UMLAssociationList associations = getSpecificAssocs(AssociationType::UniAssociation);
+    UMLAssociationList uniAssocListToBeImplemented;
+
+    foreach (UMLAssociation *a, associations) {
+        uIgnoreZeroPointer(a);
+        if (a->getObjectId(RoleType::B) == id()) {
+            continue;  // we need to be at the A side
+        }
+        QString roleNameB = a->getRoleName(RoleType::B);
+        if (!roleNameB.isEmpty()) {
+            UMLAttributeList atl = getAttributeList();
+            bool found = false;
+            //make sure that an attribute with the same name doesn't already exist
+            foreach (UMLAttribute *at, atl) {
+                uIgnoreZeroPointer(a);
+                if (at->name() == roleNameB) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                uniAssocListToBeImplemented.append(a);
+            }
+        }
+    }
+    return uniAssocListToBeImplemented;
+}
+
+/**
+ * Creates XML tag <UML:Class>, <UML:Interface>, or <UML:DataType>
+ * depending on m_BaseType.
+ * Saves possible template parameters, generalizations, attributes,
+ * operations, and contained objects to the given QDomElement.
+ */
+void UMLClassifier::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QString tag;
+    switch (m_BaseType) {
+        case UMLObject::ot_Class:
+            tag = QLatin1String("UML:Class");
+            break;
+        case UMLObject::ot_Interface:
+            tag = QLatin1String("UML:Interface");
+            break;
+        case UMLObject::ot_Datatype:
+            tag = QLatin1String("UML:DataType");
+            break;
+        case UMLObject::ot_Package:
+            UMLPackage::saveToXMI(qDoc, qElement);
+            return;
+            break;
+        default:
+            uError() << "internal error: basetype is " << m_BaseType;
+            return;
+    }
+    QDomElement classifierElement = UMLObject::save(tag, qDoc);
+    if (m_BaseType == UMLObject::ot_Datatype && m_pSecondary != NULL)
+        classifierElement.setAttribute(QLatin1String("elementReference"),
+                                        Uml::ID::toString(m_pSecondary->id()));
+
+    //save templates
+    UMLClassifierListItemList list = getFilteredList(UMLObject::ot_Template);
+    if (list.count()) {
+        QDomElement tmplElement = qDoc.createElement(QLatin1String("UML:ModelElement.templateParameter"));
+        foreach (UMLClassifierListItem *tmpl, list) {
+            tmpl->saveToXMI(qDoc, tmplElement);
+        }
+        classifierElement.appendChild(tmplElement);
+    }
+
+    //save generalizations (we are the subclass, the other end is the superclass)
+    UMLAssociationList generalizations = getSpecificAssocs(AssociationType::Generalization);
+    if (generalizations.count()) {
+        QDomElement genElement = qDoc.createElement(QLatin1String("UML:GeneralizableElement.generalization"));
+        foreach (UMLAssociation *a, generalizations) {
+            // We are the subclass if we are at the role A end.
+            if (m_nId != a->getObjectId(RoleType::A)) {
+                continue;
+            }
+            QDomElement gElem = qDoc.createElement(QLatin1String("UML:Generalization"));
+            gElem.setAttribute(QLatin1String("xmi.idref"), Uml::ID::toString(a->id()));
+            genElement.appendChild(gElem);
+        }
+        if (genElement.hasChildNodes()) {
+            classifierElement.appendChild(genElement);
+        }
+    }
+
+    // save attributes
+    QDomElement featureElement = qDoc.createElement(QLatin1String("UML:Classifier.feature"));
+    UMLClassifierListItemList attList = getFilteredList(UMLObject::ot_Attribute);
+    foreach (UMLClassifierListItem *pAtt, attList) {
+        pAtt->saveToXMI(qDoc, featureElement);
+    }
+
+    // save operations
+    UMLOperationList opList = getOpList();
+    foreach (UMLOperation *pOp, opList) {
+        pOp->saveToXMI(qDoc, featureElement);
+    }
+    if (featureElement.hasChildNodes()) {
+        classifierElement.appendChild(featureElement);
+    }
+
+    // save contained objects
+    if (m_objects.count()) {
+        QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
+        foreach (UMLObject* obj, m_objects) {
+            uIgnoreZeroPointer(obj);
+            obj->saveToXMI (qDoc, ownedElement);
+        }
+        classifierElement.appendChild(ownedElement);
+    }
+    qElement.appendChild(classifierElement);
+}
+
+/**
+ * Create a new ClassifierListObject (attribute, operation, template)
+ * according to the given XMI tag.
+ * Returns NULL if the string given does not contain one of the tags
+ * <UML:Attribute>, <UML:Operation>, or <UML:TemplateParameter>.
+ * Used by the clipboard for paste operation.
+ */
+UMLClassifierListItem* UMLClassifier::makeChildObject(const QString& xmiTag)
+{
+    UMLClassifierListItem* pObject = NULL;
+    if (UMLDoc::tagEq(xmiTag, QLatin1String("Operation")) ||
+        UMLDoc::tagEq(xmiTag, QLatin1String("ownedOperation"))) {
+        pObject = new UMLOperation(this);
+    } else if (UMLDoc::tagEq(xmiTag, QLatin1String("Attribute")) ||
+               UMLDoc::tagEq(xmiTag, QLatin1String("ownedAttribute"))) {
+        if (baseType() != UMLObject::ot_Class)
+            return NULL;
+        pObject = new UMLAttribute(this);
+    } else if (UMLDoc::tagEq(xmiTag, QLatin1String("TemplateParameter"))) {
+        pObject = new UMLTemplate(this);
+    }
+    return pObject;
+}
+
+/**
+ * Auxiliary to loadFromXMI:
+ * The loading of operations is implemented here.
+ * Calls loadSpecialized() for any other tag.
+ * Child classes can override the loadSpecialized method
+ * to load its additional tags.
+ */
+bool UMLClassifier::load(QDomElement& element)
+{
+    UMLClassifierListItem *child = NULL;
+    m_SecondaryId = element.attribute(QLatin1String("elementReference"));
+    if (!m_SecondaryId.isEmpty()) {
+        // @todo We do not currently support composition.
+        m_isRef = true;
+    }
+    bool totalSuccess = true;
+    for (QDomNode node = element.firstChild(); !node.isNull();
+            node = node.nextSibling()) {
+        if (node.isComment())
+            continue;
+        element = node.toElement();
+        QString tag = element.tagName();
+        QString stereotype = element.attribute(QLatin1String("stereotype"));
+        if (UMLDoc::tagEq(tag, QLatin1String("ModelElement.templateParameter")) ||
+                UMLDoc::tagEq(tag, QLatin1String("Classifier.feature")) ||
+                UMLDoc::tagEq(tag, QLatin1String("Namespace.ownedElement")) ||
+                UMLDoc::tagEq(tag, QLatin1String("Element.ownedElement")) ||  // Embarcadero's Describe
+                UMLDoc::tagEq(tag, QLatin1String("Namespace.contents"))) {
+            load(element);
+            // Not evaluating the return value from load()
+            // because we want a best effort.
+
+        } else if ((child = makeChildObject(tag)) != NULL) {
+            if (child->loadFromXMI(element)) {
+                switch (child->baseType()) {
+                    case UMLObject::ot_Template:
+                        addTemplate(static_cast<UMLTemplate*>(child));
+                        break;
+                    case UMLObject::ot_Operation:
+                        if (! addOperation(static_cast<UMLOperation*>(child))) {
+                            uError() << "error from addOperation(op)";
+                            delete child;
+                            totalSuccess = false;
+                        }
+                        break;
+                    case UMLObject::ot_Attribute:
+                        addAttribute(static_cast<UMLAttribute*>(child));
+                        break;
+                    default:
+                        break;
+                }
+            } else {
+                uWarning() << "failed to load " << tag;
+                delete child;
+                totalSuccess = false;
+            }
+        } else if (!Model_Utils::isCommonXMIAttribute(tag)) {
+            UMLObject *pObject = Object_Factory::makeObjectFromXMI(tag, stereotype);
+            if (pObject == NULL) {
+                // Not setting totalSuccess to false
+                // because we want a best effort.
+                continue;
+            }
+            pObject->setUMLPackage(this);
+            if (! pObject->loadFromXMI(element)) {
+                removeObject(pObject);
+                delete pObject;
+                totalSuccess = false;
+            }
+        }
+    }
+    return totalSuccess;
+}
+
+/*
+UMLClassifierList UMLClassifier::getPlainAssocChildClassifierList()
+{
+    UMLAssociationList plainAssociations = getSpecificAssocs(Uml::AssociationType::Association);
+    return findAssocClassifierObjsInRoles(&plainAssociations);
+}
+
+UMLClassifierList UMLClassifier::getAggregateChildClassifierList()
+{
+    UMLAssociationList aggregations = getAggregations();
+    return findAssocClassifierObjsInRoles(&aggregations);
+}
+
+UMLClassifierList UMLClassifier::getCompositionChildClassifierList()
+{
+    UMLAssociationList compositions = getCompositions();
+    return findAssocClassifierObjsInRoles(&compositions);
+}
+
+UMLClassifierList UMLClassifier::findAssocClassifierObjsInRoles (UMLAssociationList * list)
+{
+    UMLClassifierList classifiers;
+
+    for (UMLAssociationListIt alit(*list); alit.hasNext(); ) {
+        UMLAssociation* a = alit.next();
+        // DON'T accept a classifier IF the association role is empty, by
+        // convention, that means to ignore the classifier on that end of
+        // the association.
+        // We also ignore classifiers which are the same as the current one
+        // (e.g. id matches), we only want the "other" classifiers
+        if (a->getObjectId(RoleType::A) == id() && !a->getRoleName(RoleType::B).isEmpty()) {
+            UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(RoleType::B));
+            if(c)
+                classifiers.append(c);
+        } else if (a->getObjectId(RoleType::B) == id() && !a->getRoleName(RoleType::A).isEmpty()) {
+            UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(RoleType::A));
+            if(c)
+                classifiers.append(c);
+        }
+    }
+
+    return classifiers;
+}
+*/
+
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/classifier.h umbrello-15.08.1/umbrello/umlmodel/classifier.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/classifier.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/classifier.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,199 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+#ifndef CLASSIFIER_H
+#define CLASSIFIER_H
+
+#include "package.h"
+#include "umlattributelist.h"
+#include "umloperationlist.h"
+#include "umlclassifierlistitemlist.h"
+#include "classifierlistitem.h"
+#include "umltemplatelist.h"
+#include "model_utils.h"
+
+// forward declarations
+class UMLAssociation;
+class IDChangeLog;
+class UMLClassifierSet;
+
+/**
+ * This class defines the non-graphical information required for a
+ * UML Classifier (ie a class or interface).
+ * This class inherits from @ref UMLPackage which allows classifiers
+ * to also act as namespaces, i.e. it allows classifiers to nest.
+ *
+ * NOTE: There is a unit test available for this class.
+ *       Please, use and adapt it when necessary.
+ *
+ * @short Information for a non-graphical Concept/Class.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLClassifier : public UMLPackage
+{
+    Q_OBJECT
+public:
+
+    /**
+     * Enumeration identifying the type of classifier.
+     */
+    enum ClassifierType { ALL = 0, CLASS, INTERFACE, DATATYPE };
+
+    explicit UMLClassifier(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLClassifier();
+
+    bool operator==(const UMLClassifier & rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    UMLObject* clone() const;
+
+    virtual UMLAttribute* createAttribute(const QString &name = QString(),
+                                          UMLObject *type = 0,
+                                          Uml::Visibility::Enum vis = Uml::Visibility::Private,
+                                          const QString &init = QString());
+
+    UMLAttribute* addAttribute(const QString &name, Uml::ID::Type id = Uml::ID::None);
+    UMLAttribute* addAttribute(const QString &name, UMLObject *type, Uml::Visibility::Enum scope);
+
+    bool addAttribute(UMLAttribute* att, IDChangeLog* log = 0,
+                      int position = -1);
+
+    int removeAttribute(UMLAttribute *att);
+
+    int attributes() ;
+
+    UMLAttributeList getAttributeList() const;
+    UMLAttributeList getAttributeList(Uml::Visibility::Enum scope) const;
+    UMLAttributeList getAttributeListStatic(Uml::Visibility::Enum scope) const;
+
+    UMLOperation* createOperation(const QString &name = QString(),
+                                  bool *isExistingOp = NULL,
+                                  Model_Utils::NameAndType_List *params = NULL);
+
+    bool addOperation(UMLOperation* op, int position = -1);
+    bool addOperation(UMLOperation* op, IDChangeLog* log);
+
+    UMLOperation * checkOperationSignature(const QString& name,
+                                           UMLAttributeList opParams,
+                                           UMLOperation *exemptOp = NULL);
+
+    int removeOperation(UMLOperation *op);
+
+    int operations();
+
+    UMLOperationList getOpList(bool includeInherited = false, UMLClassifierSet *alreadyTraversed = 0);
+
+    UMLObject* createTemplate(const QString& name = QString());
+
+    UMLTemplate* addTemplate(const QString &name, Uml::ID::Type id = Uml::ID::None);
+
+    bool addTemplate(UMLTemplate* newTemplate, IDChangeLog* log = 0);
+    bool addTemplate(UMLTemplate* templt, int position);
+
+    int removeTemplate(UMLTemplate* umltemplate);
+
+    UMLTemplate *findTemplate(const QString& name);
+
+    int templates();
+
+    UMLTemplateList getTemplateList() const;
+
+    int takeItem(UMLClassifierListItem* item);
+
+    virtual UMLClassifierListItemList getFilteredList(UMLObject::ObjectType ot) const;
+
+    virtual bool resolveRef();
+
+    UMLOperationList findOperations(const QString &n);
+
+    virtual UMLObject* findChildObjectById(Uml::ID::Type id, bool considerAncestors = false);
+
+    UMLOperation* findOperation(const QString& name,
+                                Model_Utils::NameAndType_List params);
+
+    UMLClassifierList findSuperClassConcepts(ClassifierType type = ALL);
+
+    UMLClassifierList findSubClassConcepts(ClassifierType type = ALL);
+
+    virtual bool acceptAssociationType(Uml::AssociationType::Enum type);
+
+    void setClassAssoc(UMLAssociation *assoc);
+    UMLAssociation *getClassAssoc() const;
+
+    void setBaseType(UMLObject::ObjectType ot);
+
+    bool isInterface() const;
+
+    bool isDatatype() const;
+
+    void setOriginType(UMLClassifier *origType);
+    UMLClassifier * originType() const;
+
+    void setIsReference(bool isRef = true);
+    bool isReference() const;
+
+    bool hasAbstractOps();
+    bool hasAssociations();
+    bool hasAttributes();
+    bool hasStaticAttributes();
+    bool hasMethods();
+    bool hasAccessorMethods();
+    bool hasOperationMethods();
+    bool hasVectorFields();
+
+    /**
+     * utility functions to allow easy determination of what classifiers
+     * are "owned" by the current one via named association type (e.g.
+     * plain, aggregate or compositions).
+     */
+//    UMLClassifierList getPlainAssocChildClassifierList();
+//    UMLClassifierList getAggregateChildClassifierList();
+//    UMLClassifierList getCompositionChildClassifierList();
+
+    virtual UMLClassifierListItem* makeChildObject(const QString& xmiTag);
+
+    virtual UMLAssociationList  getUniAssociationToBeImplemented();
+
+signals:
+
+    void operationAdded(UMLClassifierListItem *);
+    void operationRemoved(UMLClassifierListItem *);
+
+    void templateAdded(UMLClassifierListItem*);
+    void templateRemoved(UMLClassifierListItem*);
+
+    // only applies when (m_Type == ot_Class)
+    void attributeAdded(UMLClassifierListItem*);
+    void attributeRemoved(UMLClassifierListItem*);
+
+private:
+
+    UMLAssociation *m_pClassAssoc;
+
+    bool m_isRef;
+
+    /**
+     * Utility method called by "get*ChildClassfierList()" methods. It basically
+     * finds all the classifiers named in each association in the given association list
+     * which aren't the current one. Useful for finding which classifiers are "owned" by the
+     * current one via declared associations such as in aggregations/compositions.
+     */
+//    UMLClassifierList findAssocClassifierObjsInRoles (UMLAssociationList * list);
+
+protected:
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual bool load(QDomElement& element);
+
+};
+
+#endif // CLASSIFIER_H
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/classifierlistitem.cpp umbrello-15.08.1/umbrello/umlmodel/classifierlistitem.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/classifierlistitem.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/classifierlistitem.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,159 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "classifierlistitem.h"
+
+// local includes
+#include "debug_utils.h"
+#include "classifier.h"
+#include "model_utils.h"
+#include "object_factory.h"
+#include "uml.h"
+#include "umldoc.h"
+
+// kde includes
+#include <KLocalizedString>
+
+/**
+ * Constructor.
+ *
+ * @param parent   The parent to this operation.
+ *          At first sight it would appear that the type of the
+ *          parent should be UMLClassifier. However, the class
+ *          UMLAttribute is also used for the parameters of
+ *          operations, and in this case the UMLOperation is the
+ *          parent.
+ * @param name    The name of the operation.
+ * @param id      The id of the operation.
+ */
+UMLClassifierListItem::UMLClassifierListItem(UMLObject *parent,
+                                             const QString& name, Uml::ID::Type id)
+  : UMLObject(parent, name, id)
+{
+    UMLObject *parentObj = const_cast<UMLObject*>(parent);
+    UMLClassifier *pc = dynamic_cast<UMLClassifier*>(parentObj);
+    if (pc)
+        UMLObject::setUMLPackage(pc);
+}
+
+/**
+ * Constructor.
+ *
+ * @param parent    The parent to this operation.
+ *          At first sight it would appear that the type of the
+ *          parent should be UMLClassifier. However, the class
+ *          UMLAttribute is also used for the parameters of
+ *          operations, and in this case the UMLOperation is the
+ *          parent.
+ */
+UMLClassifierListItem::UMLClassifierListItem(UMLObject *parent)
+  : UMLObject(parent)
+{
+    UMLObject *parentObj = const_cast<UMLObject*>(parent);
+    UMLClassifier *pc = dynamic_cast<UMLClassifier*>(parentObj);
+    if (pc)
+        UMLObject::setUMLPackage(pc);
+}
+
+/**
+ * Destructor.  Empty.
+ */
+UMLClassifierListItem::~UMLClassifierListItem()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLClassifierListItem::copyInto(UMLObject *lhs) const
+{
+    // Call the parent.
+    UMLObject::copyInto(lhs);
+}
+
+/**
+ * Returns a string representation of the list item.
+ *
+ * @param sig   What type of operation string to show.
+ * @return  The string representation of the operation.
+ */
+QString UMLClassifierListItem::toString(Uml::SignatureType::Enum sig)
+{
+    Q_UNUSED(sig);
+    return name();
+}
+
+/**
+ * Returns the type of the UMLClassifierListItem.
+ *
+ * @return  The type of the UMLClassifierListItem.
+ */
+UMLClassifier * UMLClassifierListItem::getType() const
+{
+    return dynamic_cast<UMLClassifier*>(m_pSecondary.data());
+}
+
+/**
+ * Returns the type name of the UMLClassifierListItem.
+ *
+ * @return  The type name of the UMLClassifierListItem.
+ */
+QString UMLClassifierListItem::getTypeName() const
+{
+    if (m_pSecondary == NULL)
+        return m_SecondaryId;
+    const UMLPackage *typePkg = m_pSecondary->umlPackage();
+    if (typePkg != NULL && typePkg != m_pUMLPackage)
+        return m_pSecondary->fullyQualifiedName();
+    return m_pSecondary->name();
+}
+
+/**
+ * Sets the type of the UMLAttribute.
+ *
+ * @param type      Pointer to the UMLObject of the type.
+ */
+void UMLClassifierListItem::setType(UMLObject *type)
+{
+    if (m_pSecondary != type) {
+        m_pSecondary = type;
+        UMLObject::emitModified();
+    }
+}
+
+/**
+ * Sets the type name of the UMLClassifierListItem.
+ * DEPRECATED - use setType() instead.
+ *
+ * @param type      The type name of the UMLClassifierListItem.
+ */
+void UMLClassifierListItem::setTypeName(const QString &type)
+{
+    if (type.isEmpty() || type == QLatin1String("void")) {
+        m_pSecondary = NULL;
+        m_SecondaryId.clear();
+        return;
+    }
+    UMLDoc *pDoc = UMLApp::app()->document();
+    m_pSecondary = pDoc->findUMLObject(type);
+    if (m_pSecondary == NULL) {
+        // Make data type for easily identified cases
+        if (Model_Utils::isCommonDataType(type) || type.contains(QLatin1Char('*'))) {
+            m_pSecondary = Object_Factory::createUMLObject(UMLObject::ot_Datatype, type);
+            uDebug() << "created datatype for " << type;
+        } else {
+            m_SecondaryId = type;
+        }
+    }
+    UMLObject::emitModified();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/classifierlistitem.h umbrello-15.08.1/umbrello/umlmodel/classifierlistitem.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/classifierlistitem.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/classifierlistitem.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef CLASSIFIERLISTITEM_H
+#define CLASSIFIERLISTITEM_H
+
+#include "umlobject.h"
+
+// forward declaration
+class UMLClassifier;
+
+/**
+ * Classifiers (classes, interfaces) have lists of operations,
+ * attributes, templates and others.  This is a base class for
+ * the items in this list.  This abstraction should remove
+ * duplication of dialogs and allow for stereotypes in lists.
+ *
+ * @short A base class for classifier list items (e.g. attributes)
+ * @author Jonathan Riddell
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLClassifierListItem : public UMLObject
+{
+    Q_OBJECT
+public:
+
+    UMLClassifierListItem(UMLObject *parent,
+                          const QString& name,
+                          Uml::ID::Type id = Uml::ID::None);
+    explicit UMLClassifierListItem(UMLObject *parent);
+    virtual ~UMLClassifierListItem();
+
+    virtual void setType(UMLObject *type);
+    UMLClassifier * getType() const;
+
+    void setTypeName(const QString &type);
+    virtual QString getTypeName() const;
+
+    virtual QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    /**
+     * The abstract method UMLObject::clone() must be implemented
+     * by the classes inheriting from UMLClassifierListItem.
+     */
+    virtual UMLObject* clone() const = 0;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/component.cpp umbrello-15.08.1/umbrello/umlmodel/component.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/component.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/component.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,127 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "component.h"
+// app includes
+#include "association.h"
+#include "debug_utils.h"
+#include "object_factory.h"
+#include "model_utils.h"
+#include "clipboard/idchangelog.h"
+#include "umldoc.h"
+// kde includes
+#include <KLocalizedString>
+
+/**
+ * Sets up a Component.
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLComponent::UMLComponent(const QString & name, Uml::ID::Type id)
+  : UMLPackage(name, id),
+    m_executable(false)
+{
+    m_BaseType = UMLObject::ot_Component;
+}
+
+/**
+ * Destructor.
+ */
+UMLComponent::~UMLComponent()
+{
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLComponent::clone() const
+{
+    UMLComponent *clone = new UMLComponent();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the UML:Component element including its operations,
+ * attributes and templates
+ */
+void UMLComponent::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement componentElement = UMLObject::save(QLatin1String("UML:Component"), qDoc);
+    componentElement.setAttribute(QLatin1String("executable"), m_executable);
+    // Save contained components if any.
+    if (m_objects.count()) {
+        QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
+        for (UMLObjectListIt objectsIt(m_objects); objectsIt.hasNext();) {
+            UMLObject* obj = objectsIt.next();
+            uIgnoreZeroPointer(obj);
+            obj->saveToXMI (qDoc, ownedElement);
+        }
+        componentElement.appendChild(ownedElement);
+    }
+    qElement.appendChild(componentElement);
+}
+
+/**
+ * Loads the UML:Component element including its ports et al.
+ */
+bool UMLComponent::load(QDomElement& element)
+{
+    QString executable = element.attribute(QLatin1String("executable"), QLatin1String("0"));
+    m_executable = (bool)executable.toInt();
+    for (QDomNode node = element.firstChild(); !node.isNull();
+            node = node.nextSibling()) {
+        if (node.isComment())
+            continue;
+        QDomElement tempElement = node.toElement();
+        QString type = tempElement.tagName();
+        if (Model_Utils::isCommonXMIAttribute(type))
+            continue;
+        if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
+                UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
+            //CHECK: Umbrello currently assumes that nested elements
+            // are ownedElements anyway.
+            // Therefore these tags are not further interpreted.
+            if (! load(tempElement))
+                return false;
+            continue;
+        }
+        UMLObject *pObject = Object_Factory::makeObjectFromXMI(type);
+        if (!pObject) {
+            uWarning() << "Unknown type of umlobject to create: " << type;
+            continue;
+        }
+        pObject->setUMLPackage(this);
+        if (pObject->loadFromXMI(tempElement)) {
+            addObject(pObject);
+        } else {
+            delete pObject;
+        }
+    }
+    return true;
+}
+
+/**
+ * Sets m_executable.
+ */
+void UMLComponent::setExecutable(bool executable)
+{
+    m_executable = executable;
+}
+
+/**
+ * Returns the value of m_executable.
+ */
+bool UMLComponent::getExecutable()
+{
+    return m_executable;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/component.h umbrello-15.08.1/umbrello/umlmodel/component.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/component.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/component.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef COMPONENT_H
+#define COMPONENT_H
+
+#include "package.h"
+
+/**
+ * This class contains the non-graphical information required for a
+ * UML Component.
+ * This class inherits from @ref UMLPackage which contains most
+ * of the information.
+ *
+ * @short Non-graphical information for a Component.
+ * @author Jonathan Riddell
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLComponent : public UMLPackage
+{
+    Q_OBJECT
+public:
+    explicit UMLComponent(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLComponent();
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    void setExecutable(bool executable);
+    bool getExecutable();
+
+protected:
+    bool load(QDomElement & element);
+
+private:
+    bool m_executable;  ///< holds whether this is an executable component or not
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/entityattribute.cpp umbrello-15.08.1/umbrello/umlmodel/entityattribute.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/entityattribute.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/entityattribute.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,280 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "entityattribute.h"
+
+// app includes
+#include "debug_utils.h"
+//#include "umlcanvasobject.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "umlentityattributedialog.h"
+#include "object_factory.h"
+
+// qt includes
+#include <QRegExp>
+
+/**
+ * Sets up an entityattribute.
+ * @param parent    The parent of this UMLEntityAttribute.
+ * @param name      The name of this UMLEntityAttribute.
+ * @param id        The unique id given to this UMLEntityAttribute.
+ * @param s         The visibility of the UMLEntityAttribute.
+ * @param type      The type of this UMLEntityAttribute.
+ * @param iv        The initial value of the entityattribute.
+ */
+UMLEntityAttribute::UMLEntityAttribute(UMLObject *parent, const QString& name,
+                                        Uml::ID::Type id, Uml::Visibility::Enum s,
+                                        UMLObject *type, const QString& iv)
+  : UMLAttribute(parent, name, id, s, type, iv)
+{
+    init();
+    if (m_pSecondary) {
+        m_pSecondary->setBaseType(UMLObject::ot_Entity);
+    }
+}
+
+/**
+ * Sets up an entityattribute.
+ * @param parent    The parent of this UMLEntityAttribute.
+ */
+UMLEntityAttribute::UMLEntityAttribute(UMLObject *parent)
+ : UMLAttribute(parent)
+{
+    init();
+}
+
+/**
+ * Destructor.
+ */
+UMLEntityAttribute::~UMLEntityAttribute()
+{
+}
+
+/**
+ * Initialize members of this class.
+ * Auxiliary method used by constructors.
+ */
+void UMLEntityAttribute::init()
+{
+    m_BaseType = UMLObject::ot_EntityAttribute;
+    m_indexType = UMLEntityAttribute::None;
+    m_autoIncrement = false;
+    m_null = false;
+}
+
+/**
+ * Returns the value of the UMLEntityAttribute's attributes property.
+ * @return  The value of the UMLEntityAttribute's attributes property.
+ */
+QString UMLEntityAttribute::getAttributes() const
+{
+    return m_attributes;
+}
+
+/**
+ * Sets the UMLEntityAttribute's attributes property.
+ * @param attributes  The new value for the attributes property.
+ */
+void UMLEntityAttribute::setAttributes(const QString& attributes)
+{
+    m_attributes = attributes;
+}
+
+/**
+ * Returns the UMLEntityAttribute's length/values property.
+ * @return  The new value of the length/values property.
+ */
+QString UMLEntityAttribute::getValues() const
+{
+    return m_values;
+}
+
+/**
+ * Sets the UMLEntityAttribute's length/values property.
+ * @param values    The new value of the length/values property.
+ */
+void UMLEntityAttribute::setValues(const QString& values)
+{
+    m_values = values;
+}
+
+/**
+ * Returns the UMLEntityAttribute's auto_increment boolean
+ * @return  The UMLEntityAttribute's auto_increment boolean
+ */
+bool UMLEntityAttribute::getAutoIncrement() const
+{
+    return m_autoIncrement;
+}
+
+/**
+ * Sets the UMLEntityAttribute's auto_increment boolean
+ * @param autoIncrement  The UMLEntityAttribute's auto_increment boolean
+ */
+void UMLEntityAttribute::setAutoIncrement(const bool autoIncrement)
+{
+    m_autoIncrement = autoIncrement;
+}
+
+/**
+ * Returns the UMLEntityAttribute's index type property.
+ * @return  The value of the UMLEntityAttribute's index type property.
+ */
+UMLEntityAttribute::DBIndex_Type UMLEntityAttribute::indexType() const
+{
+    return m_indexType;
+}
+
+/**
+ * Sets the initial value of the UMLEntityAttribute's index type property.
+ * @param indexType  The initial value of the UMLEntityAttribute's index type property.
+ */
+void UMLEntityAttribute::setIndexType(const UMLEntityAttribute::DBIndex_Type indexType)
+{
+    m_indexType = indexType;
+}
+
+/**
+ * Returns the UMLEntityAttribute's allow null value.
+ * @return  The UMLEntityAttribute's allow null value.
+ */
+bool UMLEntityAttribute::getNull() const
+{
+    return m_null;
+}
+
+/**
+ * Sets the initial value of the UMLEntityAttribute's allow null value.
+ * @param nullIn   The initial value of the UMLEntityAttribute's allow null value.
+ */
+void UMLEntityAttribute::setNull(const bool nullIn)
+{
+    m_null = nullIn;
+}
+
+/**
+ * Returns a string representation of the UMLEntityAttribute.
+ * @param sig   If true will show the entityattribute type and initial value.
+ * @return  Returns a string representation of the UMLEntityAttribute.
+ */
+QString UMLEntityAttribute::toString(Uml::SignatureType::Enum sig)
+{
+    QString s;
+    //FIXME
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::NoSig) {
+        s = Uml::Visibility::toString(m_visibility, true) + QLatin1Char(' ');
+    }
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
+        QString string = s + name() + QLatin1String(" : ") + getTypeName();
+        if(m_InitialValue.length() > 0)
+            string += QLatin1String(" = ") + m_InitialValue;
+        return string;
+    } else
+        return s + name();
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLEntityAttribute::operator==(const UMLEntityAttribute &rhs) const
+{
+    if(this == &rhs)
+        return true;
+
+    if(!UMLObject::operator==(rhs))
+        return false;
+
+    // The type name is the only distinguishing criterion.
+    // (Some programming languages might support more, but others don't.)
+    if (m_pSecondary != rhs.m_pSecondary)
+        return false;
+
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the UMLEntityAttribute
+ * object.
+ */
+void UMLEntityAttribute::copyInto(UMLObject *lhs) const
+{
+    UMLEntityAttribute *target = static_cast<UMLEntityAttribute*>(lhs);
+
+    // call the parent first.
+    UMLClassifierListItem::copyInto(target);
+
+    // Copy all datamembers
+    target->m_pSecondary = m_pSecondary;
+    target->m_SecondaryId = m_SecondaryId;
+    target->m_InitialValue = m_InitialValue;
+    target->m_ParmKind = m_ParmKind;
+}
+
+/**
+ * Make a clone of the UMLEntityAttribute.
+ */
+UMLObject* UMLEntityAttribute::clone() const
+{
+    UMLEntityAttribute* clone = new UMLEntityAttribute((UMLEntityAttribute*)parent());
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Creates the <UML:EntityAttribute> XMI element.
+ */
+void UMLEntityAttribute::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement entityattributeElement = UMLObject::save(QLatin1String("UML:EntityAttribute"), qDoc);
+    if (m_pSecondary == NULL) {
+        uDebug() << name() << ": m_pSecondary is NULL, using local name " << m_SecondaryId;
+        entityattributeElement.setAttribute(QLatin1String("type"), m_SecondaryId);
+    } else {
+        entityattributeElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
+    }
+    entityattributeElement.setAttribute(QLatin1String("initialValue"), m_InitialValue);
+    entityattributeElement.setAttribute(QLatin1String("dbindex_type"), m_indexType);
+    entityattributeElement.setAttribute(QLatin1String("values"), m_values);
+    entityattributeElement.setAttribute(QLatin1String("attributes"), m_attributes);
+    entityattributeElement.setAttribute(QLatin1String("auto_increment"), m_autoIncrement);
+    entityattributeElement.setAttribute(QLatin1String("allow_null"), m_null);
+    qElement.appendChild(entityattributeElement);
+}
+
+/**
+ * Loads the <UML:EntityAttribute> XMI element.
+ */
+bool UMLEntityAttribute::load(QDomElement & element)
+{
+    if (! UMLAttribute::load(element))
+        return false;
+    int indexType = element.attribute(QLatin1String("dbindex_type"), QLatin1String("1100")).toInt();
+    m_indexType = (UMLEntityAttribute::DBIndex_Type)indexType;
+    m_values = element.attribute(QLatin1String("values"));
+    m_attributes = element.attribute(QLatin1String("attributes"));
+    m_autoIncrement = (bool)element.attribute(QLatin1String("auto_increment")).toInt();
+    m_null = (bool)element.attribute(QLatin1String("allow_null")).toInt();
+    return true;
+}
+
+/**
+ * Display the properties configuration dialog for the entityattribute.
+ */
+bool UMLEntityAttribute::showPropertiesDialog(QWidget* parent)
+{
+    UMLEntityAttributeDialog dialog(parent, this);
+    return dialog.exec();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/entityattribute.h umbrello-15.08.1/umbrello/umlmodel/entityattribute.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/entityattribute.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/entityattribute.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENTITYATTRIBUTE_H
+#define ENTITYATTRIBUTE_H
+
+#include "attribute.h"
+#include "basictypes.h"
+
+/**
+ * This class is used to set up information for an entityattribute.  This is a database field
+ * It has a type, name, index type and default value.
+ *
+ * @short Sets up entityattribute information.
+ * @author Jonathan Riddell <jr@jriddell.org>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLEntityAttribute : public UMLAttribute
+{
+    Q_OBJECT
+    Q_ENUMS(DBIndex_Type)
+public:
+    enum DBIndex_Type
+    {
+        None  =  1100,
+        Primary,
+        Index,
+        Unique
+    };
+
+    UMLEntityAttribute(UMLObject* parent, const QString& name,
+                       Uml::ID::Type id = Uml::ID::None,
+                       Uml::Visibility::Enum s = Uml::Visibility::Private,
+                       UMLObject *type = 0, const QString& iv = QString());
+    explicit UMLEntityAttribute(UMLObject* parent);
+    virtual ~UMLEntityAttribute();
+
+    bool operator==(const UMLEntityAttribute& rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    void setAttributes(const QString& attributes);
+    QString getAttributes() const;
+
+    void setIndexType(const DBIndex_Type indexType);
+    DBIndex_Type indexType() const;
+
+    void setValues(const QString& values);
+    QString getValues() const;
+
+    void setAutoIncrement(const bool autoIncrement);
+    bool getAutoIncrement() const;
+
+    void setNull(const bool null);
+    bool getNull() const;
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+protected:
+    void init();
+
+    bool load(QDomElement& element);
+
+private:
+    DBIndex_Type   m_indexType;
+    QString        m_values;
+    QString        m_attributes;
+    bool           m_autoIncrement;
+    bool           m_null;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/entityconstraint.cpp umbrello-15.08.1/umbrello/umlmodel/entityconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/entityconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/entityconstraint.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,76 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+//own header
+#include "entityconstraint.h"
+
+// app includes
+#include "umlobject.h"
+#include "umldoc.h"
+#include "uml.h"
+
+// qt includes
+#include <QRegExp>
+
+/**
+ * Sets up a constraint.
+ * @param parent    The parent of this UMLEntityConstraint.
+ * @param name      The name of this UMLEntityConstraint.
+ * @param id        The unique id given to this UMLEntityConstraint.
+ */
+UMLEntityConstraint::UMLEntityConstraint(UMLObject *parent,
+    const QString& name, Uml::ID::Type id)
+  : UMLClassifierListItem(parent, name, id)
+{
+    m_BaseType = UMLObject::ot_EntityConstraint;
+}
+
+/**
+ * Sets up a constraint.
+ * @param parent    The parent of this UMLEntityConstraint.
+ */
+UMLEntityConstraint::UMLEntityConstraint(UMLObject *parent)
+  : UMLClassifierListItem(parent)
+{
+    m_BaseType = UMLObject::ot_EntityConstraint;
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLEntityConstraint::operator==(const UMLEntityConstraint &rhs) const
+{
+    if(this == &rhs)
+        return true;
+
+    if(!UMLObject::operator==(rhs))
+        return false;
+
+    return true;
+}
+
+/**
+ * destructor.
+ */
+UMLEntityConstraint::~UMLEntityConstraint()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the UMLEntityConstraint
+ * object.
+ */
+void UMLEntityConstraint::copyInto(UMLObject *lhs) const
+{
+    // call the parent first.
+    UMLClassifierListItem::copyInto(lhs);
+}
+
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/entityconstraint.h umbrello-15.08.1/umbrello/umlmodel/entityconstraint.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/entityconstraint.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/entityconstraint.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,49 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENTITYCONSTRAINT_H
+#define ENTITYCONSTRAINT_H
+
+#include "basictypes.h"
+#include "classifierlistitem.h"
+#include "umlclassifierlist.h"
+
+/**
+ * This class is used to set up information for a entity constraint.
+ *
+ * @short Sets up entity constraint information.
+ * @author Sharan Rao
+ * @see UMLObject UMLClassifierListItem
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLEntityConstraint : public UMLClassifierListItem
+{
+     Q_OBJECT
+
+public:
+    UMLEntityConstraint(UMLObject *parent, const QString& name,
+                        Uml::ID::Type id = Uml::ID::None);
+
+    explicit UMLEntityConstraint(UMLObject *parent);
+
+    bool operator==(const UMLEntityConstraint &rhs) const;
+
+    virtual ~UMLEntityConstraint();
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    /**
+     * Make a clone of the UMLEntityConstraint.
+     */
+    virtual UMLObject* clone() const = 0;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/entity.cpp umbrello-15.08.1/umbrello/umlmodel/entity.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/entity.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/entity.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,719 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "entity.h"
+
+// app includes
+#include "debug_utils.h"
+#include "entityattribute.h"
+#include "uniqueconstraint.h"
+#include "foreignkeyconstraint.h"
+#include "checkconstraint.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "uniqueid.h"
+#include "umlentityattributelist.h"
+#include "umlentityconstraintlist.h"
+#include "idchangelog.h"
+#include "umlentityattributedialog.h"
+#include "umluniqueconstraintdialog.h"
+#include "umlforeignkeyconstraintdialog.h"
+#include "umlcheckconstraintdialog.h"
+
+// kde includes
+#include <KLocalizedString>
+#include <KMessageBox>
+
+// qt includes
+#include <QPointer>
+
+/**
+ * Constructor.
+ */
+UMLEntity::UMLEntity(const QString& name, Uml::ID::Type id)
+  : UMLClassifier(name, id),
+    m_PrimaryKey(0)
+{
+    m_BaseType = UMLObject::ot_Entity;
+    connect(this, SIGNAL(entityAttributeRemoved(UMLClassifierListItem*)),
+            this, SLOT(slotEntityAttributeRemoved(UMLClassifierListItem*)));
+}
+
+/**
+ * Standard destructor.
+ */
+UMLEntity::~UMLEntity()
+{
+    m_List.clear();
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLEntity::operator==(const UMLEntity& rhs) const
+{
+    return UMLClassifier::operator==(rhs);
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLEntity::copyInto(UMLObject *lhs) const
+{
+    UMLEntity *target = static_cast<UMLEntity*>(lhs);
+
+    // call base class copy function
+    UMLClassifier::copyInto(target);
+
+    // copy local data items
+    target->m_PrimaryKey = m_PrimaryKey;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLEntity::clone() const
+{
+    UMLEntity* clone = new UMLEntity();
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Create an UMLAttribute.
+ * @param name   an optional name for the attribute
+ * @param type   an optional type object for the attribute
+ * @param vis    the visibility of the attribute
+ * @param iv     the initial value for the attribute
+ * @return   the just created attribute or null
+ */
+UMLAttribute* UMLEntity::createAttribute(const QString &name /*= QString()*/, UMLObject *type /*= 0*/,
+                                         Uml::Visibility::Enum vis /* = Uml::Visibility::Private*/,
+                                         const QString& iv /* = QString()*/)
+{
+    Uml::ID::Type id = UniqueID::gen();
+    QString currentName;
+    if (name.isNull())  {
+        currentName = uniqChildName(UMLObject::ot_EntityAttribute);
+    } else {
+        currentName = name;
+    }
+
+    UMLEntityAttribute* newAttribute = new UMLEntityAttribute(this, currentName, id, vis, type, iv);
+
+    int button = QDialog::Accepted;
+    bool goodName = false;
+
+    //check for name.isNull() stops dialog being shown
+    //when creating attribute via list view
+    while (button == QDialog::Accepted && !goodName && name.isNull()) {
+        QPointer<UMLEntityAttributeDialog> dialog = new UMLEntityAttributeDialog(0, newAttribute);
+        button = dialog->exec();
+        QString name = newAttribute->name();
+
+        if (name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        } else if (findChildObject(name) != NULL) {
+            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
+        } else {
+            goodName = true;
+        }
+        delete dialog;
+    }
+
+    if (button != QDialog::Accepted) {
+        delete newAttribute;
+        return 0;
+    }
+
+    addEntityAttribute(newAttribute);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newAttribute);
+    return newAttribute;
+}
+
+/**
+ * Creates a Unique Constraint for this Entity.
+ * @param name   an optional name
+ * @return the UniqueConstraint created
+ */
+UMLUniqueConstraint* UMLEntity::createUniqueConstraint(const QString &name)
+{
+    Uml::ID::Type id = UniqueID::gen();
+    QString currentName;
+    if (name.isNull())  {
+
+        /**
+         *  @todo check parameter
+         */
+        currentName = uniqChildName(UMLObject::ot_UniqueConstraint);
+    } else {
+        currentName = name;
+    }
+
+    UMLUniqueConstraint* newUniqueConstraint = new UMLUniqueConstraint(this, currentName, id);
+
+    int button = QDialog::Accepted;
+    bool goodName = false;
+
+    //check for name.isNull() stops dialog being shown
+    //when creating attribute via list view
+    while (button == QDialog::Accepted && !goodName && name.isNull()) {
+        QPointer<UMLUniqueConstraintDialog> dialog = new UMLUniqueConstraintDialog(0, newUniqueConstraint);
+        button = dialog->exec();
+        QString name = newUniqueConstraint->name();
+
+        if (name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        } else if (findChildObject(name) != NULL) {
+            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
+        } else {
+            goodName = true;
+        }
+        delete dialog;
+    }
+
+    if (button != QDialog::Accepted) {
+        delete newUniqueConstraint;
+        return NULL;
+    }
+
+    addConstraint(newUniqueConstraint);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newUniqueConstraint);
+    emitModified();
+    return newUniqueConstraint;
+}
+
+/**
+ * Creates a Foreign Key  Constraint for this Entity.
+ * @param name   an optional name
+ * @return the ForeignKeyConstraint created
+ */
+UMLForeignKeyConstraint* UMLEntity::createForeignKeyConstraint(const QString &name)
+{
+    Uml::ID::Type id = UniqueID::gen();
+    QString currentName;
+    if (name.isNull())  {
+        currentName = uniqChildName(UMLObject::ot_ForeignKeyConstraint);
+    } else {
+        currentName = name;
+    }
+
+    UMLForeignKeyConstraint* newForeignKeyConstraint = new UMLForeignKeyConstraint(this, currentName, id);
+
+    int button = QDialog::Accepted;
+    bool goodName = false;
+
+    //check for name.isNull() stops dialog being shown
+    //when creating attribute via list view
+    while (button == QDialog::Accepted && !goodName && name.isNull()) {
+        QPointer<UMLForeignKeyConstraintDialog> dialog = new UMLForeignKeyConstraintDialog(0, newForeignKeyConstraint);
+        button = dialog->exec();
+        QString name = newForeignKeyConstraint->name();
+
+        if (name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        } else if (findChildObject(name) != NULL) {
+            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
+        } else {
+            goodName = true;
+        }
+        delete dialog;
+    }
+
+    if (button != QDialog::Accepted) {
+        return NULL;
+    }
+
+    addConstraint(newForeignKeyConstraint);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newForeignKeyConstraint);
+    emitModified();
+    return newForeignKeyConstraint;
+}
+
+/**
+ * Creates a Check  Constraint for this Entity.
+ * @param name   an optional name
+ * @return the CheckConstraint created
+ */
+UMLCheckConstraint* UMLEntity::createCheckConstraint(const QString &name)
+{
+    Uml::ID::Type id = UniqueID::gen();
+    QString currentName;
+    if (name.isNull())  {
+        currentName = uniqChildName(UMLObject::ot_CheckConstraint);
+    } else {
+        currentName = name;
+    }
+
+    UMLCheckConstraint* newCheckConstraint = new UMLCheckConstraint(this, currentName, id);
+
+    int button = QDialog::Accepted;
+    bool goodName = false;
+
+    //check for name.isNull() stops dialog being shown
+    //when creating attribute via list view
+    while (button == QDialog::Accepted && !goodName && name.isNull()) {
+        QPointer<UMLCheckConstraintDialog> dialog = new UMLCheckConstraintDialog(0, newCheckConstraint);
+        button = dialog->exec();
+        QString name = newCheckConstraint->name();
+
+        if (name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        } else if (findChildObject(name) != NULL) {
+            KMessageBox::error(0, i18n("That name is already being used."), i18n("Not a Unique Name"));
+        } else {
+            goodName = true;
+        }
+        delete dialog;
+    }
+
+    if (button != QDialog::Accepted) {
+        return NULL;
+    }
+
+    addConstraint(newCheckConstraint);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newCheckConstraint);
+    emitModified();
+    return newCheckConstraint;
+}
+
+/**
+ * Adds an entityAttribute.
+ * The entityAttribute object must not belong to any other concept.
+ * @param name   name of the UMLEntityAttribute
+ * @param id     id of the UMLEntityAttribute
+ * @return  True if the entityAttribute was successfully added.
+ */
+UMLObject* UMLEntity::addEntityAttribute(const QString& name, Uml::ID::Type id)
+{
+    UMLEntityAttribute* literal = new UMLEntityAttribute(this, name, id);
+    m_List.append(literal);
+    emit entityAttributeAdded(literal);
+    UMLObject::emitModified();
+    connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
+    return literal;
+}
+
+/**
+ * Adds an already created entityAttribute.
+ * The entityAttribute object must not belong to any other concept.
+ * @param att   Pointer to the UMLEntityAttribute.
+ * @param log   Pointer to the IDChangeLog.
+ * @return  True if the entityAttribute was successfully added.
+ */
+bool UMLEntity::addEntityAttribute(UMLEntityAttribute* att, IDChangeLog* log /* = 0*/)
+{
+    QString name = (QString)att->name();
+    if (findChildObject(name) == NULL) {
+        att->setParent(this);
+        m_List.append(att);
+        emit entityAttributeAdded(att);
+        UMLObject::emitModified();
+        connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    } else if (log) {
+        log->removeChangeByNewID(att->id());
+        delete att;
+    }
+    return false;
+}
+
+/**
+ * Adds an entityAttribute to the entity, at the given position.
+ * If position is negative or too large, the entityAttribute is added
+ * to the end of the list.
+ * TODO:  give default value -1 to position (append) - now it conflicts with the method above..
+ * @param att       Pointer to the UMLEntityAttribute.
+ * @param position  Position index for the insertion.
+ * @return  True if the entityAttribute was successfully added.
+ */
+bool UMLEntity::addEntityAttribute(UMLEntityAttribute* att, int position)
+{
+    Q_ASSERT(att);
+    QString name = (QString)att->name();
+    if (findChildObject(name) == NULL) {
+        att->setParent(this);
+        if (position >= 0 && position <= (int)m_List.count())  {
+            m_List.insert(position, att);
+        } else {
+            m_List.append(att);
+        }
+        emit entityAttributeAdded(att);
+        UMLObject::emitModified();
+        connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    }
+    return false;
+}
+
+/**
+ * Removes an entityAttribute from the class.
+ * @param att   The entityAttribute to remove.
+ * @return  Count of the remaining entityAttributes after removal.
+ *          Returns -1 if the given entityAttribute was not found.
+ */
+int UMLEntity::removeEntityAttribute(UMLClassifierListItem* att)
+{
+    if (!m_List.removeAll((UMLEntityAttribute*)att)) {
+        uDebug() << "cannot find att given in list";
+        return -1;
+    }
+    emit entityAttributeRemoved(att);
+    UMLObject::emitModified();
+    // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
+    // for us by QObject. -b.t.
+    // disconnect(att, SIGNAL(modified()), this, SIGNAL(modified()));
+    delete att;
+    return m_List.count();
+}
+
+/**
+ * Returns the number of entityAttributes for the class.
+ * @return  The number of entityAttributes for the class.
+ */
+int UMLEntity::entityAttributes()
+{
+    UMLClassifierListItemList entityAttributes = getFilteredList(UMLObject::ot_EntityAttribute);
+    return entityAttributes.count();
+}
+
+/**
+ * Emit the entityAttributeRemoved signal.
+ */
+void UMLEntity::signalEntityAttributeRemoved(UMLClassifierListItem *eattr)
+{
+    emit entityAttributeRemoved(eattr);
+}
+
+/**
+ * Resolve the types referenced by our UMLEntityAttributes.
+ * Reimplements the method from UMLClassifier.
+ */
+bool UMLEntity::resolveRef()
+{
+    bool success = UMLClassifier::resolveRef();
+    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
+        UMLObject* obj = oit.next();
+        if (obj->resolveRef()) {
+            UMLClassifierListItem *cli = static_cast<UMLClassifierListItem*>(obj);
+            switch (cli->baseType()) {
+                case UMLObject::ot_EntityAttribute:
+                    emit entityAttributeAdded(cli);
+                    break;
+                case UMLObject::ot_UniqueConstraint:
+                case UMLObject::ot_ForeignKeyConstraint:
+                    emit entityConstraintAdded(cli);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+    return success;
+}
+
+/**
+ * Creates the <UML:Entity> element including its entityliterals.
+ */
+void UMLEntity::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement entityElement = UMLObject::save(QLatin1String("UML:Entity"), qDoc);
+    //save operations
+    UMLClassifierListItemList entityAttributes = getFilteredList(UMLObject::ot_EntityAttribute);
+    UMLClassifierListItem* pEntityAttribute = 0;
+    foreach (pEntityAttribute, entityAttributes) {
+        pEntityAttribute->saveToXMI(qDoc, entityElement);
+    }
+
+    UMLClassifierListItemList entityConstraints = getFilteredList(UMLObject::ot_EntityConstraint);
+    foreach(UMLClassifierListItem* cli, entityConstraints) {
+        cli->saveToXMI(qDoc, entityElement);
+    }
+
+    qElement.appendChild(entityElement);
+}
+
+/**
+ * Loads the <UML:Entity> element including its entityAttributes.
+ */
+bool UMLEntity::load(QDomElement& element)
+{
+    QDomNode node = element.firstChild();
+    while(!node.isNull()) {
+        if (node.isComment()) {
+            node = node.nextSibling();
+            continue;
+        }
+        QDomElement tempElement = node.toElement();
+        QString tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("EntityAttribute"))) {   // for backward compatibility
+            UMLEntityAttribute* pEntityAttribute = new UMLEntityAttribute(this);
+            if(!pEntityAttribute->loadFromXMI(tempElement)) {
+                return false;
+            }
+            m_List.append(pEntityAttribute);
+        } else if (UMLDoc::tagEq(tag, QLatin1String("UniqueConstraint"))) {
+            UMLUniqueConstraint* pUniqueConstraint = new UMLUniqueConstraint(this);
+            if (!pUniqueConstraint->loadFromXMI(tempElement)) {
+                return false;
+            }
+            addConstraint(pUniqueConstraint);
+        } else if (UMLDoc::tagEq(tag, QLatin1String("ForeignKeyConstraint"))) {
+            UMLForeignKeyConstraint* pForeignKeyConstraint = new UMLForeignKeyConstraint(this);
+            if (!pForeignKeyConstraint->loadFromXMI(tempElement)) {
+                return false;
+            }
+
+            addConstraint(pForeignKeyConstraint);
+        } else if (UMLDoc::tagEq(tag, QLatin1String("CheckConstraint"))) {
+
+            UMLCheckConstraint* pCheckConstraint = new UMLCheckConstraint(this);
+            if (!pCheckConstraint->loadFromXMI(tempElement)) {
+                return false;
+            }
+
+            addConstraint(pCheckConstraint);
+        } else if (tag == QLatin1String("stereotype")) {
+            uDebug() << name() << ": losing old-format stereotype.";
+        } else {
+            uWarning() << "unknown child type in UMLEntity::load";
+        }
+        node = node.nextSibling();
+    }//end while
+    return true;
+}
+
+/**
+ * Sets the UniqueConstraint passed as the Primary Key of this Entity
+ * If the UniqueConstraint exists, then it is made a primary key
+ * Else the UniqueConstraint is added and set as PrimaryKey
+ * @param uconstr The Unique Constraint that is  to be set as Primary Key
+ * @return true if Primary key could be set successfully
+ */
+bool UMLEntity::setAsPrimaryKey(UMLUniqueConstraint* uconstr)
+{
+    if (uconstr == NULL) {
+        uDebug() << "NULL value passed. To unset a Primary Key use "
+                 << "unsetPrimaryKey()";
+        return false;
+    }
+
+    if (static_cast<UMLEntity*>(uconstr->parent()) != this) {
+
+        uDebug() << "Parent of " << uconstr->name()
+                 << " does not match with current entity";
+        return false;
+    }
+
+    // check if this constraint already exists as a unique constraint for this entity
+    UMLUniqueConstraint* uuc = static_cast<UMLUniqueConstraint*>(findChildObjectById(uconstr->id()));
+    if (uuc == NULL) {
+        addConstraint(uconstr);
+        uuc = uconstr;
+    }
+
+    UMLUniqueConstraint* oldPrimaryKey = m_PrimaryKey;
+
+    m_PrimaryKey = uuc;
+
+    if (oldPrimaryKey != NULL)
+        oldPrimaryKey->emitModified();
+
+    uuc->emitModified();
+    emitModified();
+    return true;
+}
+
+/**
+ * Unset a Primary Key Constraint if it exists, else does nothing
+ * This function will make the primary key into just another UniqueConstraint
+ * if it exists
+ */
+void UMLEntity::unsetPrimaryKey()
+{
+    m_PrimaryKey = 0;
+}
+
+/**
+ * Checks if This UMLEntity has a primary key set.
+ * @return true if a Primary Key Exists for this UMLEntity
+ */
+bool UMLEntity::hasPrimaryKey() const
+{
+    if (m_PrimaryKey) {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * Adds a Constraint to this UMLEntity.
+ * To set a UMLUniqueConstraint as Primary Key use setAsPrimaryKey.
+ * @param constr The UMLEntityConstraint that is to be added
+ * @return true if the constraint could be added successfully
+ */
+bool UMLEntity::addConstraint(UMLEntityConstraint* constr)
+{
+    if (findChildObjectById(constr->id()) != NULL) {
+        uDebug() << "Constraint with id " << Uml::ID::toString(constr->id())
+                 << " already exists ";
+        return false;
+    }
+
+    m_List.append(constr);
+
+    emit entityConstraintAdded(constr);
+    UMLObject::emitModified();
+    connect(constr, SIGNAL(modified()), this, SIGNAL(modified()));
+
+    return true;
+}
+
+/**
+ * Removes an existing constraint from this UMLEntity.
+ * If the Contraint is a Primary Key, this Entity will no longer have a PrimaryKey.
+ * @param constr   the constraint to be removed
+ * @return true if the constraint could be removed successfully
+ */
+bool UMLEntity::removeConstraint(UMLEntityConstraint* constr)
+{
+     if (findChildObjectById(constr->id()) == NULL) {
+        uDebug() << "Constraint with id " << Uml::ID::toString(constr->id())
+                 << " does not exist ";
+        return false;
+    }
+
+    if (m_PrimaryKey == constr) {
+        unsetPrimaryKey();
+    }
+
+    m_List.removeAll(constr);
+
+    emit entityConstraintRemoved(constr);
+    UMLObject::emitModified();
+
+    delete constr;
+    return true;
+}
+
+/**
+ * Slot for entity attribute removed.
+ */
+void UMLEntity::slotEntityAttributeRemoved(UMLClassifierListItem* cli)
+{
+    // this function does some cleanjobs related to this entity when the attribute is
+    // removed, like, removing the attribute from all constraints
+
+    UMLEntityAttribute* entAtt = static_cast<UMLEntityAttribute*>(cli);
+    if (cli) {
+       UMLClassifierListItemList ual = this->getFilteredList(UMLObject::ot_UniqueConstraint);
+
+       foreach(UMLClassifierListItem* ucli,  ual) {
+           UMLUniqueConstraint* uuc = static_cast<UMLUniqueConstraint*>(ucli);
+           if (uuc->hasEntityAttribute(entAtt)) {
+               uuc->removeEntityAttribute(entAtt);
+           }
+       }
+    }
+
+}
+
+/**
+ * Reimplementation of getFilteredList to support ot=UMLObject::ot_EntityConstraint.
+ */
+UMLClassifierListItemList UMLEntity::getFilteredList(UMLObject::ObjectType ot) const
+{
+    if (ot == UMLObject::ot_EntityConstraint) {
+        UMLClassifierListItemList ucList, fcList, ccList, rcList;
+        ucList = UMLClassifier::getFilteredList(UMLObject::ot_UniqueConstraint);
+        fcList = UMLClassifier::getFilteredList(UMLObject::ot_ForeignKeyConstraint);
+        ccList = UMLClassifier::getFilteredList(UMLObject::ot_CheckConstraint);
+
+        // append the lists to rcList
+        // first the Unique Constraints
+        foreach(UMLClassifierListItem* ucli, ucList) {
+            rcList.append(ucli);
+        }
+
+        // then the Foreign Key Constraints
+        foreach(UMLClassifierListItem* ucli, fcList) {
+            rcList.append(ucli);
+        }
+
+        foreach(UMLClassifierListItem* ucli, ccList) {
+            rcList.append(ucli);
+        }
+
+        return rcList;
+    } else {
+        return UMLClassifier::getFilteredList(ot);
+    }
+}
+
+/**
+ * Checks if a given Unique Constraint is primary key of this entity
+ * @param uConstr   a Unique Constraint
+ * @return bool true if passed parameter is a primary key of this entity
+ */
+bool UMLEntity::isPrimaryKey(UMLUniqueConstraint* uConstr) const
+{
+    if (uConstr == m_PrimaryKey) {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * Returns the Entity Attributes.
+ * Same as getFilteredList(UMLObject::ot_EntityAttribute).
+ */
+UMLEntityAttributeList UMLEntity::getEntityAttributes() const
+{
+    UMLEntityAttributeList entityAttributeList;
+    for (UMLObjectListIt lit(m_List); lit.hasNext();) {
+        UMLObject *listItem = lit.next();
+        if (listItem->baseType() == UMLObject::ot_EntityAttribute) {
+            entityAttributeList.append(static_cast<UMLEntityAttribute*>(listItem));
+        }
+    }
+    return entityAttributeList;
+}
+
+
+/**
+ * Create a new ClassifierListObject (entityattribute)
+ * according to the given XMI tag.
+ * Returns NULL if the string given does not contain one of the tags
+ * <UML:EntityAttribute>
+ * Used by the clipboard for paste operation.
+ * Reimplemented from UMLClassifier for UMLEntity
+ */
+UMLClassifierListItem* UMLEntity::makeChildObject(const QString& xmiTag)
+{
+    UMLClassifierListItem* pObject = NULL;
+    if (UMLDoc::tagEq(xmiTag, QLatin1String("EntityAttribute"))) {
+        pObject = new UMLEntityAttribute(this);
+    }
+    return pObject;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/entity.h umbrello-15.08.1/umbrello/umlmodel/entity.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/entity.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/entity.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,108 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENTITY_H
+#define ENTITY_H
+
+#include "classifier.h"
+
+// forward declarations
+class UMLEntityAttribute;
+class UMLEntityConstraint;
+class UMLUniqueConstraint;
+class UMLForeignKeyConstraint;
+class UMLCheckConstraint;
+class UMLEntityAttributeList;
+
+/**
+ * This class contains the non-graphical information required for a UML
+ * Entity.
+ * This class inherits from @ref UMLClassifier which contains most of the
+ * information.
+ *
+ * @short Non-graphical Information for an Entity.
+ * @author Jonathan Riddell
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLEntity : public UMLClassifier
+{
+    Q_OBJECT
+public:
+    explicit UMLEntity(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLEntity();
+
+    bool operator==(const UMLEntity& rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    virtual UMLAttribute* createAttribute(const QString &name = QString(),
+                                  UMLObject *type = 0, Uml::Visibility::Enum vis = Uml::Visibility::Private,
+                                  const QString &init = QString());
+
+    UMLUniqueConstraint* createUniqueConstraint(const QString &name = QString());
+    UMLForeignKeyConstraint* createForeignKeyConstraint(const QString &name = QString());
+    UMLCheckConstraint* createCheckConstraint(const QString &name = QString());
+
+    UMLObject* addEntityAttribute(const QString &name, Uml::ID::Type id = Uml::ID::None);
+    bool addEntityAttribute(UMLEntityAttribute* att, IDChangeLog* log = 0);
+    bool addEntityAttribute(UMLEntityAttribute* att, int position);
+
+    int removeEntityAttribute(UMLClassifierListItem* att);
+
+    void signalEntityAttributeRemoved(UMLClassifierListItem *eattr);
+
+    int entityAttributes() ;
+
+    bool setAsPrimaryKey(UMLUniqueConstraint* uconstr);
+    void unsetPrimaryKey();
+    bool hasPrimaryKey() const;
+    bool isPrimaryKey(UMLUniqueConstraint* uConstr) const;
+
+    bool addConstraint(UMLEntityConstraint* constr);
+    bool removeConstraint(UMLEntityConstraint* constr);
+
+    virtual bool resolveRef();
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    UMLClassifierListItemList getFilteredList(UMLObject::ObjectType ot) const;
+
+    UMLEntityAttributeList getEntityAttributes() const;
+
+    virtual UMLClassifierListItem* makeChildObject(const QString& xmiTag);
+
+private slots:
+    void slotEntityAttributeRemoved(UMLClassifierListItem*);
+
+signals:
+    void entityAttributeAdded(UMLClassifierListItem*);
+    void entityAttributeRemoved(UMLClassifierListItem*);
+    void entityConstraintAdded(UMLClassifierListItem*);
+    void entityConstraintRemoved(UMLClassifierListItem*);
+
+protected:
+    bool load(QDomElement& element);
+
+private:
+
+    /**
+     * Primary Key of this Entity
+     * This is a pointer kept for easy access to the primary key, and to distinguish it
+     * from all other UniqueConstraints. It is also there in m_List (inherited from
+     * UMLCanvasObject)
+     */
+    UMLUniqueConstraint* m_PrimaryKey;
+
+};
+
+#endif // ENTITY_H
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/enum.cpp umbrello-15.08.1/umbrello/umlmodel/enum.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/enum.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/enum.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,302 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "enum.h"
+
+// app includes
+#include "debug_utils.h"
+#include "enumliteral.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "uniqueid.h"
+#include "idchangelog.h"
+
+// kde includes
+#include <KLocalizedString>
+#include <KMessageBox>
+
+/**
+ * Sets up an enum.
+ * @param name  The name of the Enum.
+ * @param id  The unique id of the Enum.
+ */
+UMLEnum::UMLEnum(const QString& name, Uml::ID::Type id) : UMLClassifier(name, id)
+{
+    init();
+}
+
+/**
+ * Standard destructor.
+ */
+UMLEnum::~UMLEnum()
+{
+    m_List.clear();
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLEnum::operator==(const UMLEnum & rhs) const
+{
+    return UMLClassifier::operator==(rhs);
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLEnum::copyInto(UMLObject *lhs) const
+{
+    UMLClassifier::copyInto(lhs);
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLEnum::clone() const
+{
+    UMLEnum *clone = new UMLEnum();
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLEnum::init()
+{
+    m_BaseType = UMLObject::ot_Enum;
+    setStereotypeCmd(QLatin1String("enum"));
+}
+
+/**
+ * Creates a literal for the enum.
+ * @return  The UMLEnum created
+ */
+UMLObject* UMLEnum::createEnumLiteral(const QString& name)
+{
+    Uml::ID::Type id = UniqueID::gen();
+    QString currentName;
+    if (name.isNull())  {
+        currentName = uniqChildName(UMLObject::ot_EnumLiteral);
+    } else {
+        currentName = name;
+    }
+
+    UMLEnumLiteral* newEnumLiteral = new UMLEnumLiteral(this, currentName);
+
+    bool ok = true;
+    bool goodName = false;
+
+    //check for name.isNull() stops dialog being shown
+    //when creating enum literal via list view
+    while (ok && !goodName && name.isNull()) {
+        ok = newEnumLiteral->showPropertiesDialog(UMLApp::app());
+        QString name = newEnumLiteral->name();
+
+        if(name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."), i18n("Invalid Name"));
+        } else {
+            goodName = true;
+        }
+    }
+
+    if (!ok) {
+        delete newEnumLiteral;
+        return NULL;
+    }
+
+    addEnumLiteral(newEnumLiteral);
+
+    UMLDoc *umldoc = UMLApp::app()->document();
+    umldoc->signalUMLObjectCreated(newEnumLiteral);
+    return newEnumLiteral;
+}
+
+/**
+ * Adds an enumliteral to the enum.
+ * @param name  The name of the enumliteral.
+ * @param id  The id of the enumliteral (optional.)
+ *            If omitted a new ID is assigned internally.
+ * @return  Pointer to the UMLEnumliteral created.
+ */
+UMLObject* UMLEnum::addEnumLiteral(const QString &name, Uml::ID::Type id)
+{
+    UMLObject *el = UMLCanvasObject::findChildObject(name);
+    if (el != NULL) {
+        uDebug() << name << " is already present";
+        return el;
+    }
+    UMLEnumLiteral* literal = new UMLEnumLiteral(this, name, id);
+    m_List.append(literal);
+    UMLObject::emitModified();
+    emit enumLiteralAdded(literal);
+    connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
+    return literal;
+}
+
+/**
+ * Adds an already created enumliteral.
+ * The enumliteral object must not belong to any other concept.
+ * @param literal  Pointer to the UMLEnumLiteral.
+ * @param Log      Pointer to the IDChangeLog.
+ * @return  True if the enumliteral was successfully added.
+ */
+bool UMLEnum::addEnumLiteral(UMLEnumLiteral* literal, IDChangeLog* Log /* = 0*/)
+{
+    QString name = (QString)literal->name();
+    if (findChildObject(name) == NULL) {
+        literal->setParent(this);
+        m_List.append(literal);
+        UMLObject::emitModified();
+        emit enumLiteralAdded(literal);
+        connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    } else if (Log) {
+        Log->removeChangeByNewID(literal->id());
+        delete literal;
+    }
+    return false;
+}
+
+/**
+ * Adds an enumliteral to the enum, at the given position.
+ * If position is negative or too large, the enumliteral is added
+ * to the end of the list.
+ * TODO:  give default value -1 to position (append) - now it conflicts with the method above..
+ * @param literal   Pointer to the UMLEnumLiteral.
+ * @param position  Position index for the insertion.
+ * @return  True if the enumliteral was successfully added.
+ */
+bool UMLEnum::addEnumLiteral(UMLEnumLiteral* literal, int position)
+{
+    Q_ASSERT(literal);
+    QString name = (QString)literal->name();
+    if (findChildObject(name) == NULL) {
+        literal->setParent(this);
+        if (position >= 0 && position <= (int)m_List.count())  {
+            m_List.insert(position, literal);
+        } else {
+            m_List.append(literal);
+        }
+        UMLObject::emitModified();
+        emit enumLiteralAdded(literal);
+        connect(literal, SIGNAL(modified()), this, SIGNAL(modified()));
+        return true;
+    }
+    return false;
+}
+
+/**
+ * Removes an enumliteral from the class.
+ * @param literal  The enumliteral to remove.
+ * @return  Count of the remaining enumliterals after removal.
+ *          Returns -1 if the given enumliteral was not found.
+ */
+int UMLEnum::removeEnumLiteral(UMLEnumLiteral* literal)
+{
+    if (!m_List.removeAll(literal)) {
+        uDebug() << "cannot find att given in list";
+        return -1;
+    }
+    emit enumLiteralRemoved(literal);
+    UMLObject::emitModified();
+    // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
+    // for us by QObject. -b.t.
+    // disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
+    delete literal;
+    return m_List.count();
+}
+
+/**
+ * Returns the number of enumliterals for the class.
+ * @return  The number of enumliterals for the class.
+ */
+int UMLEnum::enumLiterals()
+{
+    return m_List.count();
+}
+
+/**
+ * Emit the enumLiteralRemoved signal.
+ */
+void UMLEnum::signalEnumLiteralRemoved(UMLClassifierListItem *elit)
+{
+    emit enumLiteralRemoved(elit);
+}
+
+/**
+ * Creates the <UML:Enum> element including its enumliterals.
+ */
+void UMLEnum::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement enumElement = UMLObject::save(QLatin1String("UML:Enumeration"), qDoc);
+    // save enum literals
+    UMLClassifierListItemList enumLiterals = getFilteredList(UMLObject::ot_EnumLiteral);
+    foreach (UMLClassifierListItem* pEnumLiteral, enumLiterals) {
+        pEnumLiteral->saveToXMI(qDoc, enumElement);
+    }
+    qElement.appendChild(enumElement);
+}
+
+/**
+ * Loads the <UML:Enum> element including its enumliterals.
+ */
+bool UMLEnum::load(QDomElement& element)
+{
+    QDomNode node = element.firstChild();
+    while(!node.isNull()) {
+        if (node.isComment()) {
+            node = node.nextSibling();
+            continue;
+        }
+        QDomElement tempElement = node.toElement();
+        QString tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("EnumerationLiteral")) ||
+            UMLDoc::tagEq(tag, QLatin1String("ownedLiteral")) ||
+                UMLDoc::tagEq(tag, QLatin1String("EnumLiteral"))) {   // for backward compatibility
+            UMLEnumLiteral* pEnumLiteral = new UMLEnumLiteral(this);
+            if(!pEnumLiteral->loadFromXMI(tempElement)) {
+                return false;
+            }
+            m_List.append(pEnumLiteral);
+        } else if (UMLDoc::tagEq(tag, QLatin1String("Enumeration.literal"))) {  // Embarcadero's Describe
+            if (! load(tempElement))
+                return false;
+        } else if (tag == QLatin1String("stereotype")) {
+            uDebug() << name() << ": losing old-format stereotype.";
+        } else {
+            uWarning() << "unknown child type: " << tag;
+        }
+        node = node.nextSibling();
+    }//end while
+    return true;
+}
+
+/**
+ * Create a new ClassifierListObject (enumLiteral)
+ * according to the given XMI tag.
+ * Returns NULL if the string given does not contain one of the tags
+ * <UML:EnumLiteral>
+ * Used by the clipboard for paste operation.
+ * Reimplemented from UMLClassifier for UMLEnum
+ */
+UMLClassifierListItem* UMLEnum::makeChildObject(const QString& xmiTag)
+{
+    UMLClassifierListItem* pObject = NULL;
+    if (UMLDoc::tagEq(xmiTag, QLatin1String("EnumerationLiteral")) ||
+               UMLDoc::tagEq(xmiTag, QLatin1String("EnumLiteral"))) {
+        pObject = new UMLEnumLiteral(this);
+    }
+    return pObject;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/enum.h umbrello-15.08.1/umbrello/umlmodel/enum.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/enum.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/enum.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENUM_H
+#define ENUM_H
+
+#include "classifier.h"
+
+class UMLEnumLiteral;
+
+/**
+ * This class contains the non-graphical information required for a UML
+ * Enum.
+ * This class inherits from @ref UMLClassifier which contains most of the
+ * information.
+ *
+ * @short Non-graphical Information for an Enum.
+ * @author Jonathan Riddell
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLEnum : public UMLClassifier
+{
+    Q_OBJECT
+public:
+    explicit UMLEnum(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
+
+    virtual ~UMLEnum();
+
+    bool operator==(const UMLEnum& rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    UMLObject* createEnumLiteral(const QString& name = QString());
+
+    UMLObject* addEnumLiteral(const QString &name, Uml::ID::Type id = Uml::ID::None);
+
+    bool addEnumLiteral(UMLEnumLiteral* literal, IDChangeLog* Log = 0);
+    bool addEnumLiteral(UMLEnumLiteral* literal, int position);
+
+    int removeEnumLiteral(UMLEnumLiteral* literal);
+
+    int enumLiterals();
+
+    void signalEnumLiteralRemoved(UMLClassifierListItem *elit);
+
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    virtual UMLClassifierListItem* makeChildObject(const QString& xmiTag);
+
+signals:
+    void enumLiteralAdded(UMLClassifierListItem*);
+    void enumLiteralRemoved(UMLClassifierListItem*);
+
+protected:
+    bool load(QDomElement & element);
+
+private:
+    void init();
+
+};
+
+#endif // ENUM_H
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/enumliteral.cpp umbrello-15.08.1/umbrello/umlmodel/enumliteral.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/enumliteral.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/enumliteral.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,126 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "enumliteral.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+
+/**
+ * Sets up an enum literal.
+ * @param parent    The parent of this UMLEnumLiteral.
+ * @param name      The name of this UMLEnumLiteral.
+ * @param id        The unique id given to this UMLEnumLiteral.
+ */
+UMLEnumLiteral::UMLEnumLiteral(UMLObject *parent,
+                               const QString& name, Uml::ID::Type id)
+  : UMLClassifierListItem(parent, name, id)
+{
+    m_BaseType = UMLObject::ot_EnumLiteral;
+}
+
+/**
+ * Sets up an enum literal.
+ * @param parent    The parent of this UMLEnumLiteral.
+ */
+UMLEnumLiteral::UMLEnumLiteral(UMLObject *parent)
+  : UMLClassifierListItem(parent)
+{
+    m_BaseType = UMLObject::ot_EnumLiteral;
+}
+
+/**
+ * Destructor.
+ */
+UMLEnumLiteral::~UMLEnumLiteral()
+{
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLEnumLiteral::operator==(const UMLEnumLiteral& rhs) const
+{
+    if (this == &rhs)  {
+        return true;
+    }
+    if (!UMLObject::operator==(rhs))  {
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLEnumLiteral::copyInto(UMLObject *lhs) const
+{
+    UMLClassifierListItem::copyInto(lhs);
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLEnumLiteral::clone() const
+{
+    UMLEnumLiteral *clone = new UMLEnumLiteral((UMLObject *) parent());
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Creates the <UML:EnumLiteral> XMI element.
+ */
+void UMLEnumLiteral::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement attributeElement = UMLObject::save(QLatin1String("UML:EnumerationLiteral"), qDoc);
+    qElement.appendChild(attributeElement);
+}
+
+/**
+ * Loads the <UML:EnumLiteral> XMI element (empty.)
+ */
+bool UMLEnumLiteral::load(QDomElement& element)
+{
+    Q_UNUSED(element);
+    return true;
+}
+
+/**
+ * Display the properties configuration dialog for the enum literal.
+ */
+bool UMLEnumLiteral::showPropertiesDialog(QWidget* parent)
+{
+    bool ok;
+#if QT_VERSION >= 0x050000
+    QString enumName = QInputDialog::getText(parent,
+                                             i18nc("enum name", "Name"), i18n("Enter name:"),
+                                             QLineEdit::Normal,
+                                             name(), &ok);
+#else
+    QString enumName = KInputDialog::getText(i18nc("enum name", "Name"), i18n("Enter name:"), name(), &ok, parent);
+#endif
+    if (ok && !enumName.isEmpty())  {
+        setName(enumName);
+        return true;
+    } else {
+        return false;
+    }
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/enumliteral.h umbrello-15.08.1/umbrello/umlmodel/enumliteral.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/enumliteral.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/enumliteral.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,49 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENUMLITERAL_H
+#define ENUMLITERAL_H
+
+#include "classifierlistitem.h"
+
+/**
+ * This class is used to set up information for an enum literal.  Enum
+ * literals are the values that enums can be set to.
+ *
+ * @short Sets up attribute information.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLEnumLiteral : public UMLClassifierListItem
+{
+public:
+    UMLEnumLiteral(UMLObject* parent,
+                   const QString& name, Uml::ID::Type id = Uml::ID::None);
+    explicit UMLEnumLiteral(UMLObject* parent);
+
+    bool operator==(const UMLEnumLiteral &rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    virtual ~UMLEnumLiteral();
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+protected:
+    bool load(QDomElement& element);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/folder.cpp umbrello-15.08.1/umbrello/umlmodel/folder.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/folder.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/folder.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,558 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2006-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "folder.h"
+
+// app includes
+#include "debug_utils.h"
+#include "model_utils.h"
+#include "object_factory.h"
+#include "optionstate.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// kde includes
+#include <KLocalizedString>
+#include <KMessageBox>
+
+// qt includes
+#include <QFile>
+
+/**
+ * Sets up a Folder.
+ * @param name    The name of the Folder.
+ * @param id      The unique id of the Folder. A new ID will be generated
+ *                if this argument is left away.
+ */
+UMLFolder::UMLFolder(const QString & name, Uml::ID::Type id)
+  : UMLPackage(name, id)
+{
+    m_BaseType = UMLObject::ot_Folder;
+    UMLObject::setStereotypeCmd(QLatin1String("folder"));
+}
+
+/**
+ * Empty destructor.
+ */
+UMLFolder::~UMLFolder()
+{
+    qDeleteAll(m_diagrams);
+    m_diagrams.clear();
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLFolder::clone() const
+{
+    UMLFolder *clone = new UMLFolder();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Set the localized name of this folder.
+ * This is set for the predefined root views (Logical,
+ * UseCase, Component, Deployment, EntityRelationship,
+ * and the Datatypes folder inside the Logical View.)
+ */
+void UMLFolder::setLocalName(const QString& localName)
+{
+    m_localName = localName;
+}
+
+/**
+ * Return the localized name of this folder.
+ * Only useful for the predefined root folders.
+ */
+QString UMLFolder::localName() const
+{
+    return m_localName;
+}
+
+/**
+ * Add a view to the diagram list.
+ */
+void UMLFolder::addView(UMLView *view)
+{
+    m_diagrams.append(view);
+}
+
+/**
+ * Remove a view from the diagram list.
+ */
+void UMLFolder::removeView(UMLView *view)
+{
+    m_diagrams.removeAll(view);
+    delete view;
+}
+
+/**
+ * Append the views in this folder to the given diagram list.
+ * @param viewList       The UMLViewList to which to append the diagrams.
+ * @param includeNested  Whether to include diagrams from nested folders
+ *                       (default: true.)
+ */
+void UMLFolder::appendViews(UMLViewList& viewList, bool includeNested)
+{
+    if (includeNested) {
+        foreach (UMLObject* o, m_objects) {
+            uIgnoreZeroPointer(o);
+            if (o->baseType() == UMLObject::ot_Folder) {
+                UMLFolder *f = static_cast<UMLFolder*>(o);
+                f->appendViews(viewList);
+            }
+        }
+    }
+    foreach (UMLView* v, m_diagrams) {
+        viewList.append(v);
+    }
+}
+
+/**
+ * Acivate the views in this folder.
+ * "Activation": Some widgets require adjustments after loading from file,
+ * those are done here.
+ */
+void UMLFolder::activateViews()
+{
+    foreach (UMLObject* o, m_objects) {
+        uIgnoreZeroPointer(o);
+        if (o->baseType() == UMLObject::ot_Folder) {
+            UMLFolder *f = static_cast<UMLFolder*>(o);
+            f->activateViews();
+        }
+    }
+
+    foreach (UMLView* v, m_diagrams) {
+        v->umlScene()->activateAfterLoad();
+    }
+    // Make sure we have a treeview item for each diagram.
+    // It may happen that we are missing them after switching off tabbed widgets.
+    Settings::OptionState optionState = Settings::optionState();
+    if (optionState.generalState.tabdiagrams) {
+        return;
+    }
+    Model_Utils::treeViewAddViews(m_diagrams);
+}
+
+/**
+ * Seek a view of the given ID in this folder.
+ * @param id   ID of the view to find.
+ * @return     Pointer to the view if found, NULL if no view found.
+ */
+UMLView *UMLFolder::findView(Uml::ID::Type id)
+{
+    foreach (UMLView* v, m_diagrams) {
+        if (v->umlScene()->ID() == id) {
+            return v;
+        }
+    }
+
+    UMLView* v = 0;
+    UMLPackageList packages;
+    appendPackages(packages);
+    foreach (UMLPackage *o, packages) {
+        if (o->baseType() != UMLObject::ot_Folder) {
+            continue;
+        }
+        UMLFolder *f = static_cast<UMLFolder*>(o);
+        v = f->findView(id);
+        if (v) {
+            break;
+        }
+    }
+    return v;
+}
+
+/**
+ * Seek a view by the type and name given.
+ * @param type              The type of view to find.
+ * @param name              The name of the view to find.
+ * @param searchAllScopes   Search in all subfolders (default: true.)
+ * @return  Pointer to the view found, or NULL if not found.
+ */
+UMLView *UMLFolder::findView(Uml::DiagramType::Enum type, const QString &name, bool searchAllScopes)
+{
+    foreach (UMLView* v, m_diagrams) {
+        if (v->umlScene()->type() == type && v->umlScene()->name() == name) {
+            return v;
+        }
+    }
+
+    UMLView* v = 0;
+    if (searchAllScopes) {
+        foreach (UMLObject* o, m_objects) {
+            uIgnoreZeroPointer(o);
+            if (o->baseType() != UMLObject::ot_Folder) {
+                continue;
+            }
+            UMLFolder *f = static_cast<UMLFolder*>(o);
+            v = f->findView(type, name, searchAllScopes);
+            if (v) {
+                break;
+            }
+        }
+    }
+    return v;
+}
+
+/**
+ * Set the options for the views in this folder.
+ */
+void UMLFolder::setViewOptions(const Settings::OptionState& optionState)
+{
+    // for each view update settings
+    foreach (UMLView* v, m_diagrams) {
+        v->umlScene()->setOptionState(optionState);
+    }
+}
+
+/**
+ * Remove all views in this folder.
+ */
+void UMLFolder::removeAllViews()
+{
+    foreach (UMLObject* o, m_objects) {
+        uIgnoreZeroPointer(o);
+        if (o->baseType() != UMLObject::ot_Folder)
+            continue;
+        UMLFolder *f = static_cast<UMLFolder*>(o);
+        f->removeAllViews();
+    }
+
+    foreach (UMLView* v, m_diagrams) {
+        // TODO ------------------ check this code - bad: calling back to UMLDoc::removeView()
+        v->umlScene()->removeAllAssociations(); // note : It may not be apparent, but when we remove all associations
+        // from a view, it also causes any UMLAssociations that lack parent
+        // association widgets (but once had them) to remove themselves from
+        // this document.
+        uDebug() << "removing " << v->umlScene()->name();
+        UMLApp::app()->document()->removeView(v, false);
+    }
+
+    qDeleteAll(m_diagrams);
+    m_diagrams.clear();
+}
+
+/**
+ * Set the folder file name for a separate submodel.
+ */
+void UMLFolder::setFolderFile(const QString& fileName)
+{
+    m_folderFile = fileName;
+}
+
+/**
+ * Get the folder file name for a separate submodel.
+ */
+QString UMLFolder::folderFile() const
+{
+    return m_folderFile;
+}
+
+/**
+ * Auxiliary to saveToXMI(): Save the contained objects and diagrams.
+ * Can be used regardless of whether saving to the main model file
+ * or to an external folder file (see m_folderFile.)
+ */
+void UMLFolder::saveContents(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
+    UMLObject *obj = 0;
+    // Save contained objects if any.
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        obj = oit.next();
+        uIgnoreZeroPointer(obj);
+        obj->saveToXMI (qDoc, ownedElement);
+    }
+    // Save asscociations if any.
+    for (UMLObjectListIt ait(m_List); ait.hasNext();) {
+        obj = ait.next();
+        obj->saveToXMI (qDoc, ownedElement);
+    }
+    qElement.appendChild(ownedElement);
+    // Save diagrams to `extension'.
+    if (m_diagrams.count()) {
+        QDomElement diagramsElement = qDoc.createElement(QLatin1String("diagrams"));
+
+        foreach (UMLView* pView, m_diagrams) {
+            pView->umlScene()->saveToXMI(qDoc, diagramsElement);
+        }
+        QDomElement extension = qDoc.createElement(QLatin1String("XMI.extension"));
+        extension.setAttribute(QLatin1String("xmi.extender"), QLatin1String("umbrello"));
+        extension.appendChild(diagramsElement);
+        qElement.appendChild(extension);
+    }
+}
+
+/**
+ * Auxiliary to saveToXMI(): Creates a <UML:Model> element when saving
+ * a predefined modelview, or a <UML:Package> element when saving a
+ * user created folder. Invokes saveContents() with the newly created
+ * element.
+ */
+void UMLFolder::save(QDomDocument& qDoc, QDomElement& qElement)
+{
+    UMLDoc *umldoc = UMLApp::app()->document();
+    QString elementName(QLatin1String("UML:Package"));
+    const Uml::ModelType::Enum mt = umldoc->rootFolderType(this);
+    if (mt != Uml::ModelType::N_MODELTYPES) {
+        elementName = QLatin1String("UML:Model");
+    }
+    QDomElement folderElement = UMLObject::save(elementName, qDoc);
+    saveContents(qDoc, folderElement);
+    qElement.appendChild(folderElement);
+}
+
+/**
+ * Creates a UML:Model or UML:Package element:
+ * UML:Model is created for the predefined fixed folders,
+ * UML:Package with stereotype "folder" is created for all else.
+ */
+void UMLFolder::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    if (m_folderFile.isEmpty()) {
+        save(qDoc, qElement);
+        return;
+    }
+    // See if we can create the external file.
+    // If not then internalize the folder.
+    UMLDoc *umldoc = UMLApp::app()->document();
+#if QT_VERSION >= 0x050000
+    QString fileName = umldoc->url().adjusted(QUrl::RemoveFilename).path() + m_folderFile;
+#else
+    QString fileName = umldoc->url().directory() + QLatin1Char('/') + m_folderFile;
+#endif
+    QFile file(fileName);
+    if (!file.open(QIODevice::WriteOnly)) {
+        uError() << m_folderFile << QLatin1String(": ")
+            << "cannot create file, contents will be saved in main model file";
+        m_folderFile.clear();
+        save(qDoc, qElement);
+        return;
+    }
+    // Okay, external file is writable.  Wrap up main file.
+    QDomElement folderElement = UMLObject::save(QLatin1String("UML:Package"), qDoc);
+    QDomElement extension = qDoc.createElement(QLatin1String("XMI.extension"));
+    extension.setAttribute(QLatin1String("xmi.extender"), QLatin1String("umbrello"));
+    QDomElement fileElement = qDoc.createElement(QLatin1String("external_file"));
+    fileElement.setAttribute(QLatin1String("name"), m_folderFile);
+    extension.appendChild(fileElement);
+    folderElement.appendChild(extension);
+    qElement.appendChild(folderElement);
+
+    // Save folder to external file.
+    QDomDocument folderDoc;
+    QDomElement folderRoot;
+    QDomProcessingInstruction xmlHeading =
+        folderDoc.createProcessingInstruction(QLatin1String("xml"),
+                                              QString::fromLatin1("version=\"1.0\" encoding=\"UTF-8\""));
+    folderDoc.appendChild(xmlHeading);
+    folderRoot = folderDoc.createElement(QLatin1String("external_file"));
+    folderRoot.setAttribute(QLatin1String("name"), name());
+    folderRoot.setAttribute(QLatin1String("filename"), m_folderFile);
+    folderRoot.setAttribute(QLatin1String("mainModel"), umldoc->url().fileName());
+    folderRoot.setAttribute(QLatin1String("parentId"), Uml::ID::toString(m_pUMLPackage->id()));
+    folderRoot.setAttribute(QLatin1String("parent"), m_pUMLPackage->fullyQualifiedName(QLatin1String("::"), true));
+    saveContents(folderDoc, folderRoot);
+    folderDoc.appendChild(folderRoot);
+    QTextStream stream(&file);
+    stream.setCodec("UTF-8");
+    stream << folderDoc.toString();
+    file.close();
+}
+
+/**
+ * Auxiliary to load():
+ * Load the diagrams from the "diagrams" in the <XMI.extension>
+ */
+bool UMLFolder::loadDiagramsFromXMI(QDomNode& diagrams)
+{
+    const Settings::OptionState optionState = Settings::optionState();
+    UMLDoc *umldoc = UMLApp::app()->document();
+    bool totalSuccess = true;
+    for (QDomElement diagram = diagrams.toElement(); !diagram.isNull();
+         diagrams = diagrams.nextSibling(), diagram = diagrams.toElement()) {
+        QString tag = diagram.tagName();
+        if (tag != QLatin1String("diagram")) {
+            uDebug() << "ignoring " << tag << " in <diagrams>";
+            continue;
+        }
+        UMLView * pView = new UMLView(this);
+        pView->umlScene()->setOptionState(optionState);
+        if (pView->umlScene()->loadFromXMI(diagram)) {
+            pView->hide();
+            umldoc->addView(pView);
+        } else {
+            delete pView;
+            totalSuccess = false;
+        }
+    }
+    return totalSuccess;
+}
+
+/**
+ * Folders in the listview can be marked such that their contents
+ * are saved to a separate file.
+ * This method loads the separate folder file.
+ * CAVEAT: This is not XMI standard compliant.
+ * If standard compliance is an issue then avoid folder files.
+ * @param path  Fully qualified file name, i.e. absolute directory
+ *              plus file name.
+ * @return   True for success.
+ */
+bool UMLFolder::loadFolderFile(const QString& path)
+{
+    QFile file(path);
+    if (!file.exists()) {
+        KMessageBox::error(0, i18n("The folderfile %1 does not exist.", path), i18n("Load Error"));
+        return false;
+    }
+    if (!file.open(QIODevice::ReadOnly)) {
+        KMessageBox::error(0, i18n("The folderfile %1 cannot be opened.", path), i18n("Load Error"));
+        return false;
+    }
+    QTextStream stream(&file);
+    QString data = stream.readAll();
+    file.close();
+    QDomDocument doc;
+    QString error;
+    int line;
+    if (!doc.setContent(data, false, &error, &line)) {
+        uError() << "Cannot set content:" << error << " line:" << line;
+        return false;
+    }
+    QDomNode rootNode = doc.firstChild();
+    while (rootNode.isComment() || rootNode.isProcessingInstruction()) {
+        rootNode = rootNode.nextSibling();
+    }
+    if (rootNode.isNull()) {
+        uError() << "Root node is Null";
+        return false;
+    }
+    QDomElement element = rootNode.toElement();
+    QString type = element.tagName();
+    if (type != QLatin1String("external_file")) {
+        uError() << "Root node has unknown type " << type;
+        return false;
+    }
+    return load(element);
+}
+
+/**
+ * Loads the owned elements of the <UML:Model>.
+ */
+bool UMLFolder::load(QDomElement& element)
+{
+    UMLDoc *umldoc = UMLApp::app()->document();
+    bool totalSuccess = true;
+    for (QDomNode node = element.firstChild(); !node.isNull();
+            node = node.nextSibling()) {
+        if (node.isComment())
+            continue;
+        QDomElement tempElement = node.toElement();
+        QString type = tempElement.tagName();
+        if (Model_Utils::isCommonXMIAttribute(type))
+            continue;
+        if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
+                UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
+            //CHECK: Umbrello currently assumes that nested elements
+            // are ownedElements anyway.
+            // Therefore these tags are not further interpreted.
+            if (! load(tempElement)) {
+                uDebug() << "An error happened while loading the " << type
+                    << " of the " << name();
+                totalSuccess = false;
+            }
+            continue;
+        } else if (UMLDoc::tagEq(type, QLatin1String("packagedElement")) ||
+                   UMLDoc::tagEq(type, QLatin1String("ownedElement"))) {
+            type = tempElement.attribute(QLatin1String("xmi:type"));
+        } else if (type == QLatin1String("XMI.extension")) {
+            for (QDomNode xtnode = node.firstChild(); !xtnode.isNull();
+                                              xtnode = xtnode.nextSibling()) {
+                QDomElement el = xtnode.toElement();
+                const QString xtag = el.tagName();
+                if (xtag == QLatin1String("diagrams")) {
+                    QDomNode diagramNode = xtnode.firstChild();
+                    if (!loadDiagramsFromXMI(diagramNode))
+                        totalSuccess = false;
+                } else if (xtag == QLatin1String("external_file")) {
+#if QT_VERSION >= 0x050000
+                    const QString rootDir(umldoc->url().adjusted(QUrl::RemoveFilename).path());
+#else
+                    const QString rootDir(umldoc->url().directory());
+#endif
+                    QString fileName = el.attribute(QLatin1String("name"));
+                    const QString path(rootDir + QLatin1Char('/') + fileName);
+                    if (loadFolderFile(path))
+                        m_folderFile = fileName;
+                } else {
+                    uDebug() << name() << ": ignoring XMI.extension " << xtag;
+                    continue;
+                }
+            }
+            continue;
+        }
+        // Do not re-create the predefined Datatypes folder in the Logical View,
+        // it already exists.
+        UMLFolder *logicalView = umldoc->rootFolder(Uml::ModelType::Logical);
+        if (this == logicalView && UMLDoc::tagEq(type, QLatin1String("Package"))) {
+            QString thisName = tempElement.attribute(QLatin1String("name"));
+            if (thisName == QLatin1String("Datatypes")) {
+                UMLFolder *datatypeFolder = umldoc->datatypeFolder();
+                if (!datatypeFolder->loadFromXMI(tempElement))
+                    totalSuccess = false;
+                continue;
+            }
+        }
+        UMLObject *pObject = 0;
+        // Avoid duplicate creation of forward declared object
+        QString idStr = Model_Utils::getXmiId(tempElement);
+        if (!idStr.isEmpty()) {
+            Uml::ID::Type id = Uml::ID::fromString(idStr);
+            pObject = umldoc->findObjectById(id);
+            if (pObject) {
+                uDebug() << "object " << idStr << "already exists";
+            }
+        }
+        if (pObject == 0) {
+            QString stereoID = tempElement.attribute(QLatin1String("stereotype"));
+            pObject = Object_Factory::makeObjectFromXMI(type, stereoID);
+            if (!pObject) {
+                uWarning() << "Unknown type of umlobject to create: " << type;
+                continue;
+            }
+        }
+        pObject->setUMLPackage(this);
+        if (!pObject->loadFromXMI(tempElement)) {
+            removeObject(pObject);
+            delete pObject;
+            totalSuccess = false;
+        }
+    }
+    return totalSuccess;
+}
+
+/**
+ * Overloading operator for debugging output.
+ */
+QDebug operator<<(QDebug out, const UMLFolder& item)
+{
+    out.nospace() << "UMLFolder: localName=" << item.m_localName
+        << ", folderFile=" << item.m_folderFile
+        << ", diagrams=" << item.m_diagrams.count();
+    return out.space();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/folder.h umbrello-15.08.1/umbrello/umlmodel/folder.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/folder.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/folder.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,92 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2006-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLFOLDER_H
+#define UMLFOLDER_H
+
+#include "package.h"
+#include "umlviewlist.h"
+#include "optionstate.h"
+
+/**
+ * This class manages the UMLObjects and UMLViews of a Folder.
+ * This class inherits from UMLPackage which contains most
+ * of the information.
+ *
+ * The UMLDoc class allocates a fixed instance of this class for
+ * each of the predefined Logical, UseCase, Component, Deployment, and
+ * Entity-Relationship folders.  Further instances are created on demand
+ * for user folders.
+ *
+ * @short Non-graphical management of objects and diagrams of a Folder
+ * @author Oliver Kellogg
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ *
+ * TODO: This whole class needs a relook regarding view/scene.
+ */
+class UMLFolder : public UMLPackage
+{
+    Q_OBJECT
+public:
+    explicit UMLFolder(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLFolder();
+
+    virtual UMLObject* clone() const;
+
+    void setLocalName(const QString& localName);
+    QString localName() const;
+
+    void addView(UMLView *view);
+
+    void removeView(UMLView *view);
+
+    void appendViews(UMLViewList& viewList, bool includeNested = true);
+
+    void activateViews();
+
+    UMLView* findView(Uml::ID::Type id);
+    UMLView* findView(Uml::DiagramType::Enum type, const QString &name, bool searchAllScopes = true);
+
+    void setViewOptions(const Settings::OptionState& optionState);
+
+    void removeAllViews();
+
+    void setFolderFile(const QString& fileName);
+    QString folderFile() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    friend QDebug operator<<(QDebug out, const UMLFolder& item);
+
+protected:
+    void saveContents(QDomDocument& qDoc, QDomElement& qElement);
+
+    void save(QDomDocument& qDoc, QDomElement& qElement);
+
+    bool loadDiagramsFromXMI(QDomNode& diagrams);
+
+    bool loadFolderFile(const QString& path);
+
+    bool load(QDomElement & element);
+
+private:
+    QString m_localName;  ///< i18n name, only used for predefined root folders
+    /**
+     * If m_folderFile is not empty then it contains a file name to which
+     * this folder is saved.
+     * In this case the folder file acts as a physically separate submodel.
+     * What is saved in the main model is not the folder contents but a
+     * reference to the folder file.
+     */
+    QString m_folderFile;
+    UMLViewList m_diagrams;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/foreignkeyconstraint.cpp umbrello-15.08.1/umbrello/umlmodel/foreignkeyconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/foreignkeyconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/foreignkeyconstraint.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,444 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+//own header
+#include "foreignkeyconstraint.h"
+
+// app includes
+#include "debug_utils.h"
+#include "entity.h"
+#include "entityattribute.h"
+#include "umlobject.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "umlforeignkeyconstraintdialog.h"
+#include "object_factory.h"
+
+/**
+ * Sets up a constraint.
+ * @param parent    The parent of this UMLForeignKeyConstraint.
+ * @param name      The name of this UMLForeignKeyConstraint.
+ * @param id        The unique id given to this UMLForeignKeyConstraint.
+ */
+UMLForeignKeyConstraint::UMLForeignKeyConstraint(UMLObject *parent,
+    const QString& name, Uml::ID::Type id)
+  : UMLEntityConstraint(parent, name, id)
+{
+    init();
+}
+
+/**
+ * Sets up a constraint.
+ * @param parent    The parent of this UMLForeignKeyConstraint.
+ */
+UMLForeignKeyConstraint::UMLForeignKeyConstraint(UMLObject *parent)
+    : UMLEntityConstraint(parent)
+{
+    init();
+}
+
+/**
+ * Initialisation of common variables
+ */
+void UMLForeignKeyConstraint::init()
+{
+    // initialise attributes
+     m_BaseType = UMLObject::ot_ForeignKeyConstraint;
+
+     // should be NULL actually
+     // self referencing assigned to protect default behaviour
+     m_ReferencedEntity = static_cast<UMLEntity*>(parent());
+
+     m_UpdateAction = uda_NoAction;
+     m_DeleteAction = uda_NoAction;
+
+    // connecte signals and slots
+     connect(this, SIGNAL(sigReferencedEntityChanged()), this, SLOT(slotReferencedEntityChanged()));
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLForeignKeyConstraint::operator==(const UMLForeignKeyConstraint &rhs) const
+{
+    if(this == &rhs)
+        return true;
+
+    if(!UMLObject::operator==(rhs))
+        return false;
+
+    return true;
+}
+
+/**
+ * Destructor.
+ */
+UMLForeignKeyConstraint::~UMLForeignKeyConstraint()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the UMLForeignKeyConstraint
+ * object.
+ */
+void UMLForeignKeyConstraint::copyInto(UMLObject *lhs) const
+{
+    UMLForeignKeyConstraint *target = static_cast<UMLForeignKeyConstraint*>(lhs);
+
+    // call the parent first.
+    UMLEntityConstraint::copyInto(target);
+
+    // Copy all datamembers
+    target->m_ReferencedEntity = m_ReferencedEntity;
+    target->m_AttributeMap = m_AttributeMap;
+    target->m_DeleteAction = m_DeleteAction;
+    target->m_UpdateAction = m_UpdateAction;
+}
+
+/**
+ * Make a clone of the UMLForeignKeyConstraint.
+ */
+UMLObject* UMLForeignKeyConstraint::clone() const
+{
+    //FIXME: The new attribute should be slaved to the NEW parent not the old.
+    UMLForeignKeyConstraint *clone = new UMLForeignKeyConstraint(static_cast<UMLObject*>(parent()));
+    copyInto(clone);
+    return clone;
+}
+
+/**
+ * Returns a string representation of the UMLForeignKeyConstraint.
+ * @param sig   If true will show the attribute type and initial value.
+ * @return  Returns a string representation of the UMLAttribute.
+ */
+QString UMLForeignKeyConstraint::toString(Uml::SignatureType::Enum sig)
+{
+    QString s;
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
+        s = name() + QLatin1Char(':');
+        s += QLatin1String(" Foreign Key (");
+        QList<UMLEntityAttribute*> keys = m_AttributeMap.keys();
+        bool first = true;
+        foreach(UMLEntityAttribute* key, keys) {
+            if (first) {
+                first = false;
+            } else
+                s += QLatin1Char(',');
+            s += key->name();
+        }
+        s += QLatin1Char(')');
+    }
+
+    return s;
+}
+
+/**
+ * Creates the <UML:ForeignKeyConstraint> XMI element.
+ */
+void UMLForeignKeyConstraint::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement foreignKeyConstraintElement = UMLObject::save(QLatin1String("UML:ForeignKeyConstraint"), qDoc);
+
+    foreignKeyConstraintElement.setAttribute(QLatin1String("referencedEntity"), Uml::ID::toString(m_ReferencedEntity->id()));
+
+    int updateAction = (int)m_UpdateAction;
+    int deleteAction = (int)m_DeleteAction;
+
+    foreignKeyConstraintElement.setAttribute(QLatin1String("updateAction"), updateAction);
+    foreignKeyConstraintElement.setAttribute(QLatin1String("deleteAction"), deleteAction);
+
+    QMap<UMLEntityAttribute*, UMLEntityAttribute*>::iterator i;
+    for (i = m_AttributeMap.begin(); i!= m_AttributeMap.end() ; ++i) {
+        QDomElement mapElement = qDoc.createElement(QLatin1String("AttributeMap"));
+        mapElement.setAttribute(QLatin1String("key"), Uml::ID::toString((i.key())->id()));
+        mapElement.setAttribute(QLatin1String("value"), Uml::ID::toString((i.value())->id()));
+        foreignKeyConstraintElement.appendChild(mapElement);
+    }
+
+    qElement.appendChild(foreignKeyConstraintElement);
+}
+
+/**
+ * Display the properties configuration dialog for the attribute.
+ */
+bool UMLForeignKeyConstraint::showPropertiesDialog(QWidget* parent)
+{
+    UMLForeignKeyConstraintDialog dialog(parent, this);
+    return dialog.exec();
+}
+
+/**
+ * Adds the attribute pair to the attributeMap
+ * @param pAttr The Attribute of the Parent Entity
+ * @param rAttr The Attribute of the Referenced Entity
+ * @return true if the attribute pair could be added successfully
+ */
+bool UMLForeignKeyConstraint::addEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr)
+{
+    UMLEntity *owningParent = dynamic_cast<UMLEntity*>(parent());
+
+    if (pAttr == NULL || rAttr == NULL) {
+        uError() << "null values passed to function";
+        return false;
+    }
+    // check for sanity of pAttr (parent entity attribute)
+    if (owningParent == NULL) {
+        uError() << name() << ": parent is not a UMLEntity";
+        return false;
+    }
+
+    if (owningParent->findChildObjectById(pAttr->id()) == NULL) {
+        uError() << " parent " << owningParent->name()
+                 << " does not contain attribute " << pAttr->name();
+        return false;
+    }
+
+    //check for sanity of rAttr (referenced entity attribute)
+    if (m_ReferencedEntity != NULL) {
+       if (m_ReferencedEntity->findChildObjectById(rAttr->id()) == NULL) {
+        uError() << " parent " << m_ReferencedEntity->name()
+                 << " does not contain attribute " << rAttr->name();
+        return false;
+       }
+    } else {
+        uError() << "Referenced Table Not set. Not Adding Pair ";
+        return false;
+    }
+
+    // check if key takes part in some mapping
+    if (m_AttributeMap.contains(pAttr) == true)
+        return false;
+
+    // check if value takes part in some mapping (no direct function)
+    foreach(UMLEntityAttribute* attr, m_AttributeMap.values()) {
+        if (rAttr == attr)
+            return false;
+    }
+
+    // passed all checks, insert now
+    m_AttributeMap.insert(pAttr, rAttr);
+
+     QMap<UMLEntityAttribute*, UMLEntityAttribute*>::iterator i;
+     for (i = m_AttributeMap.begin(); i != m_AttributeMap.end(); ++i)
+         uDebug() << i.key()->name() << QLatin1String(" ") << i.key()->baseType()
+                 << QLatin1String(" ") << i.value()->name() << QLatin1String(" ") << i.value()->baseType();
+
+     return true;
+}
+
+/**
+ * Removes an Attribute pair
+ * @param pAttr The Attribute of the Parent Entity in the map. This attribute is the
+                key of the map.
+ * @return true of the attribute pair could be removed successfully
+ */
+bool UMLForeignKeyConstraint::removeEntityAttributePair(UMLEntityAttribute* /*key*/ pAttr)
+{
+    bool state = m_AttributeMap.remove(pAttr);
+
+    return state;
+}
+
+/**
+ * Check if a attribute pair already exists
+ * @param pAttr The Attribute of the Parent Entity
+ * @param rAttr The Attribute of the Referenced Entity
+ * @return true if the attribute pair could be found.
+ */
+bool UMLForeignKeyConstraint::hasEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr) const
+{
+    if (m_AttributeMap.contains(pAttr)) {
+        if (m_AttributeMap.value(pAttr) == rAttr) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * Loads the <UML:ForeignKeyConstraint> XMI element.
+ */
+bool UMLForeignKeyConstraint::load(QDomElement & element)
+{
+    UMLDoc* doc = UMLApp::app()->document();
+
+    Uml::ID::Type referencedEntityId = Uml::ID::fromString(element.attribute(QLatin1String("referencedEntity")));
+
+    UMLObject* obj = doc->findObjectById(referencedEntityId);
+    m_ReferencedEntity = static_cast<UMLEntity*>(obj);
+
+    if (m_ReferencedEntity == NULL) {
+        // save for resolving later
+        m_pReferencedEntityID = referencedEntityId;
+    }
+
+    m_UpdateAction = (UpdateDeleteAction)element.attribute(QLatin1String("updateAction")).toInt();
+    m_DeleteAction = (UpdateDeleteAction)element.attribute(QLatin1String("deleteAction")).toInt();
+
+    QDomNode node = element.firstChild();
+    while (!node.isNull()) {
+        if (node.isComment()) {
+            node = node.nextSibling();
+            continue;
+        }
+        QDomElement tempElement = node.toElement();
+        QString tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("AttributeMap"))) {
+
+            QString xmiKey = tempElement.attribute(QLatin1String("key"));
+            QString xmiValue = tempElement.attribute(QLatin1String("value"));
+            Uml::ID::Type keyId = Uml::ID::fromString(xmiKey);
+            Uml::ID::Type valueId = Uml::ID::fromString(xmiValue);
+
+            UMLEntity* parentEntity = static_cast<UMLEntity*>(parent());
+            UMLObject* keyObj = parentEntity->findChildObjectById(keyId);
+            UMLEntityAttribute* key = static_cast<UMLEntityAttribute*>(keyObj);
+
+            if (keyObj == NULL) {
+                uWarning() << "unable to resolve foreign key referencing attribute " << xmiKey;
+            } else if (m_ReferencedEntity == NULL) {
+                // if referenced entity is null, then we won't find its attributes even
+                // save for resolving later
+                m_pEntityAttributeIDMap.insert(key, valueId);
+            } else {
+                UMLObject* valueObj = m_ReferencedEntity->findChildObjectById(valueId);
+                if (valueObj == NULL) {
+                    uWarning() << "unable to resolve foreign key referenced attribute" << xmiValue;
+                } else {
+                    m_AttributeMap[key] = static_cast<UMLEntityAttribute*>(valueObj);
+                }
+            }
+
+        } else {
+            uWarning() << "unknown child type in UMLForeignKeyConstraint::load";
+        }
+
+        node = node.nextSibling();
+    }
+
+    return true;
+}
+
+/**
+ * Set the Referenced Entity.
+ * @param ent The Entity to Reference
+ */
+void UMLForeignKeyConstraint::setReferencedEntity(UMLEntity* ent)
+{
+    if (ent == m_ReferencedEntity)
+        return;
+
+    m_ReferencedEntity = ent;
+
+    emit sigReferencedEntityChanged();
+}
+
+/**
+ * Get the Referenced Entity.
+ * @return the UML entity object
+ */
+UMLEntity* UMLForeignKeyConstraint::getReferencedEntity() const
+{
+    return m_ReferencedEntity;
+}
+
+/**
+ * Slot for referenced entity changed.
+ */
+void UMLForeignKeyConstraint::slotReferencedEntityChanged()
+{
+    // clear all mappings
+    m_AttributeMap.clear();
+}
+
+/**
+ * Clears all mappings between local and referenced attributes
+ */
+void UMLForeignKeyConstraint::clearMappings()
+{
+    m_AttributeMap.clear();
+}
+
+/**
+ * Remimplementation from base classes
+ * Used to resolve forward references to referenced entities in xmi
+ */
+bool UMLForeignKeyConstraint::resolveRef()
+{
+    // resolve referenced entity first
+    UMLDoc* doc = UMLApp::app()->document();
+
+    bool success = true;
+
+    //resolve the referenced entity
+    if (!Uml::ID::toString(m_pReferencedEntityID).isEmpty()) {
+        UMLObject* obj = doc->findObjectById(m_pReferencedEntityID);
+        m_ReferencedEntity = static_cast<UMLEntity*>(obj);
+        if (m_ReferencedEntity == NULL) {
+            success = false;
+        }
+    }
+
+    QMap<UMLEntityAttribute*, Uml::ID::Type>::iterator i;
+    for (i = m_pEntityAttributeIDMap.begin(); i!= m_pEntityAttributeIDMap.end() ; ++i) {
+       if (!Uml::ID::toString(i.value()).isEmpty()) {
+           UMLObject* obj = doc->findObjectById(i.value());
+           m_AttributeMap[i.key()] = static_cast<UMLEntityAttribute*>(obj);
+           if (m_AttributeMap[i.key()] == NULL) {
+               success = false;
+           }
+       }
+    }
+
+    return success;
+}
+
+/**
+ * Retrieve all Pairs of Attributes.
+ */
+QMap<UMLEntityAttribute*, UMLEntityAttribute*> UMLForeignKeyConstraint::getEntityAttributePairs()
+{
+    return m_AttributeMap;
+}
+
+/**
+ * Get the Delete Action.
+ */
+UMLForeignKeyConstraint::UpdateDeleteAction UMLForeignKeyConstraint::getDeleteAction() const
+{
+    return m_DeleteAction;
+}
+
+/**
+ * Get the Update Action.
+ */
+UMLForeignKeyConstraint::UpdateDeleteAction UMLForeignKeyConstraint::getUpdateAction() const
+{
+    return m_UpdateAction;
+}
+
+/**
+ * Set the Delete Action to the specified UpdateDeleteAction.
+ */
+void UMLForeignKeyConstraint::setDeleteAction(UpdateDeleteAction uda)
+{
+    m_DeleteAction = uda;
+}
+
+/**
+ * Set the Update Action to the specified UpdateDeleteAction
+ */
+void UMLForeignKeyConstraint::setUpdateAction(UpdateDeleteAction uda)
+{
+    m_UpdateAction = uda;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/foreignkeyconstraint.h umbrello-15.08.1/umbrello/umlmodel/foreignkeyconstraint.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/foreignkeyconstraint.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/foreignkeyconstraint.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,120 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef FOREIGNKEYCONSTRAINT_H
+#define FOREIGNKEYCONSTRAINT_H
+
+// appl includes
+#include "basictypes.h"
+#include "entityconstraint.h"
+
+// qt includes
+#include <QMap>
+
+//forward declarations
+class UMLEntityAttribute;
+class UMLEntity;
+
+/**
+ * This class is used to set up information for a foreign key entity constraint.
+ * @short Sets up Foreign Key  entity constraint information.
+ * @author Sharan Rao
+ * @see UMLObject UMLClassifierListItem UMLEntityConstraint
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLForeignKeyConstraint : public UMLEntityConstraint
+{
+     Q_OBJECT
+
+public:
+
+    /**
+     * Update/Delete Action: Action to be taken on Update or Delete of a referenced attribute
+     * is either, No Action, Restrict, Cascade, Set NULL, Set Default.
+     */
+    enum UpdateDeleteAction { uda_NoAction = 0,
+                              uda_Restrict,
+                              uda_Cascade,
+                              uda_SetNull,
+                              uda_SetDefault };
+
+    UMLForeignKeyConstraint(UMLObject *parent, const QString& name,
+                            Uml::ID::Type id = Uml::ID::None);
+    explicit UMLForeignKeyConstraint(UMLObject *parent);
+
+    bool operator==(const UMLForeignKeyConstraint &rhs) const;
+
+    virtual ~UMLForeignKeyConstraint();
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    void setReferencedEntity(UMLEntity* ent);
+    UMLEntity* getReferencedEntity() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+    bool addEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr);
+
+    bool removeEntityAttributePair(UMLEntityAttribute* /*key*/ pAttr);
+
+    bool hasEntityAttributePair(UMLEntityAttribute* pAttr, UMLEntityAttribute* rAttr) const;
+
+    QMap<UMLEntityAttribute*, UMLEntityAttribute*> getEntityAttributePairs();
+
+    void setDeleteAction(UpdateDeleteAction uda);
+    UpdateDeleteAction getDeleteAction() const;
+
+    void setUpdateAction(UpdateDeleteAction uda);
+    UpdateDeleteAction getUpdateAction() const;
+
+    void clearMappings();
+
+    bool resolveRef();
+
+signals:
+    void sigReferencedEntityChanged();
+
+private slots:
+    void slotReferencedEntityChanged();
+
+protected:
+    bool load(QDomElement & element);
+
+private:
+
+    Uml::ID::Type m_pReferencedEntityID;  ///< Used to resolve forward references to UMLEntity.
+
+    /**
+     * Used to resolve forward references to UMLEntityAttributes
+     * Key -> The local attribute
+     * Value -> Id of the attribute it is mapping to
+     */
+    QMap<UMLEntityAttribute*, Uml::ID::Type> m_pEntityAttributeIDMap;
+
+    void init();
+
+    UMLEntity* m_ReferencedEntity;  ///< The UMLEntity that this foreign key references.
+
+    /**
+     * Stores the Mapping of attributes between parent table and referenced table
+     */
+    QMap<UMLEntityAttribute*, UMLEntityAttribute*> m_AttributeMap;
+
+    UpdateDeleteAction m_UpdateAction;  ///< What to do on Update of referenced attributes.
+    UpdateDeleteAction m_DeleteAction;  ///< What to do on Deletion of referenced attributes.
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/node.cpp umbrello-15.08.1/umbrello/umlmodel/node.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/node.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/node.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,68 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "node.h"
+
+#include <KLocalizedString>
+
+/**
+ * Sets up a Node.
+ *
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLNode::UMLNode(const QString & name, Uml::ID::Type id)
+  : UMLCanvasObject(name, id)
+{
+    init();
+}
+
+/**
+ * Destructor.
+ */
+UMLNode::~UMLNode()
+{
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLNode::init()
+{
+    m_BaseType = UMLObject::ot_Node;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLNode::clone() const
+{
+    UMLNode *clone = new UMLNode();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the <UML:Node> XMI element.
+ */
+void UMLNode::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement nodeElement = UMLObject::save(QLatin1String("UML:Node"), qDoc);
+    qElement.appendChild(nodeElement);
+}
+
+/**
+ * Loads the <UML:Node> XMI element (empty.)
+ */
+bool UMLNode::load(QDomElement&)
+{
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/node.h umbrello-15.08.1/umbrello/umlmodel/node.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/node.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/node.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,46 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef NODE_H
+#define NODE_H
+
+#include "umlcanvasobject.h"
+
+/**
+ * This class contains the non-graphical information required for a UML Node.
+ * This class inherits from @ref UMLCanvasObject which contains most of the
+ * information.
+ *
+ * @short Non-graphical information for a Node.
+ * @author Jonathan Riddell
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLNode : public UMLCanvasObject
+{
+    Q_OBJECT
+public:
+
+    explicit UMLNode(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLNode();
+
+    virtual void init();
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+
+    bool load(QDomElement & element);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/operation.cpp umbrello-15.08.1/umbrello/umlmodel/operation.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/operation.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/operation.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,611 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "operation.h"
+
+// app includes
+#include "attribute.h"
+#include "classifier.h"
+#include "model_utils.h"
+#include "debug_utils.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "uniqueid.h"
+#include "umloperationdialog.h"
+#include "codegenerator.h"
+#include "codedocument.h"
+#include "codeblock.h"
+
+// kde includes
+#include <KLocalizedString>
+
+// qt includes
+#include <QRegExp>
+
+/**
+ * Constructs an UMLOperation.
+ * Not intended for general use: The operation is not tied in with
+ * umbrello's Qt signalling for object creation.
+ * If you want to create an Operation use the method in UMLDoc instead.
+ *
+ * @param parent    the parent to this operation
+ * @param name      the name of the operation
+ * @param id        the id of the operation
+ * @param s         the visibility of the operation
+ * @param rt        the return type of the operation
+ */
+UMLOperation::UMLOperation(UMLClassifier *parent, const QString& name,
+                           Uml::ID::Type id, Uml::Visibility::Enum s, UMLObject *rt)
+  : UMLClassifierListItem(parent, name, id)
+{
+    if (rt)
+        m_returnId = UniqueID::gen();
+    else
+        m_returnId = Uml::ID::None;
+    m_pSecondary = rt;
+    m_visibility = s;
+    m_BaseType = UMLObject::ot_Operation;
+    m_bConst = false;
+    m_Code.clear();
+}
+
+/**
+ * Constructs an UMLOperation.
+ * Not intended for general use: The operation is not tied in with
+ * umbrello's Qt signalling for object creation.
+ * If you want to create an Operation use the method in UMLDoc instead.
+ *
+ * @param parent    the parent to this operation
+ */
+UMLOperation::UMLOperation(UMLClassifier * parent)
+  : UMLClassifierListItem (parent)
+{
+    m_BaseType = UMLObject::ot_Operation;
+    m_bConst = false;
+    m_Code.clear();
+}
+
+/**
+ * Destructor.
+ */
+UMLOperation::~UMLOperation()
+{
+}
+
+/**
+ * Reimplement method from UMLClassifierListItem.
+ *
+ * @param type      pointer to the type object
+ */
+void UMLOperation::setType(UMLObject* type)
+{
+    UMLClassifierListItem::setType(type);
+    if (m_returnId == Uml::ID::None)
+        m_returnId = UniqueID::gen();
+}
+
+/**
+ * Move a parameter one position to the left.
+ *
+ * @param a   the parameter to move
+ */
+void UMLOperation::moveParmLeft(UMLAttribute * a)
+{
+    if (a == NULL) {
+        uDebug() << "called on NULL attribute";
+        return;
+    }
+    uDebug() << "called for " << a->name();
+    disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
+    int idx;
+    if ((idx=m_List.indexOf(a)) == -1) {
+        uDebug() << "Error move parm left " << a->name();
+        return;
+    }
+    if (idx == 0)
+        return;
+    m_List.removeAll(a);
+    m_List.insert(idx-1, a);
+}
+
+/**
+ * Move a parameter one position to the right.
+ *
+ * @param a   the parameter to move
+ */
+void UMLOperation::moveParmRight(UMLAttribute * a)
+{
+    if (a == NULL) {
+        uDebug() << "called on NULL attribute";
+        return;
+    }
+    uDebug() << "called for " << a->name();
+    disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
+    int idx;
+    if ((idx=m_List.indexOf(a)) == -1) {
+        uDebug() << "Error move parm right " << a->name();
+        return;
+    }
+    int count = m_List.count();
+    if (idx == count-1)
+        return;
+    m_List.removeAll(a);
+    m_List.insert(idx+1, a);
+}
+
+/**
+ * Remove a parameter from the operation.
+ *
+ * @param a         the parameter to remove
+ * @param emitModifiedSignal  whether to emit the "modified" signal
+ *                  which creates an entry in the Undo stack for the
+ *                  removal, default: true
+ */
+void UMLOperation::removeParm(UMLAttribute * a, bool emitModifiedSignal /* =true */)
+{
+    if (a == NULL) {
+        uDebug() << "called on NULL attribute";
+        return;
+    }
+    uDebug() << "called for " << a->name();
+    disconnect(a, SIGNAL(modified()), this, SIGNAL(modified()));
+    if(!m_List.removeAll(a))
+        uDebug() << "Error removing parm " << a->name();
+
+    if (emitModifiedSignal)
+        emit modified();
+}
+
+/**
+ * Returns a list of parameters.
+ *
+ * @return a list of the parameters in the operation
+ */
+UMLAttributeList UMLOperation::getParmList() const
+{
+    return m_List;
+}
+
+/**
+ * Finds a parameter of the operation.
+ *
+ * @param name      the parameter name to search for
+ * @return          the found parameter, 0 if not found
+ */
+UMLAttribute* UMLOperation::findParm(const QString &name)
+{
+    UMLAttribute * obj=0;
+    foreach (obj, m_List) {
+        if (obj->name() == name)
+            return obj;
+    }
+    return 0;
+}
+
+/**
+ * Returns a string representation of the operation.
+ *
+ * @param sig       what type of operation string to show
+ * @return          the string representation of the operation
+ */
+QString UMLOperation::toString(Uml::SignatureType::Enum sig)
+{
+    QString s;
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::NoSig)
+          s = Uml::Visibility::toString(m_visibility, true) + QLatin1Char(' ');
+
+    s += name();
+    Uml::ProgrammingLanguage::Enum pl = UMLApp::app()->activeLanguage();
+    bool parameterlessOpNeedsParentheses =
+        (pl != Uml::ProgrammingLanguage::Pascal && pl != Uml::ProgrammingLanguage::Ada);
+
+    if (sig == Uml::SignatureType::NoSig || sig == Uml::SignatureType::NoSigNoVis) {
+        if (parameterlessOpNeedsParentheses)
+            s.append(QLatin1String("()"));
+        return s;
+    }
+    int last = m_List.count();
+    if (last) {
+        s.append(QLatin1String("("));
+        int i = 0;
+        foreach (UMLAttribute *param, m_List) {
+            i++;
+            s.append(param->toString(Uml::SignatureType::SigNoVis));
+            if (i < last)
+                s.append(QLatin1String(", "));
+        }
+        s.append(QLatin1String(")"));
+    } else if (parameterlessOpNeedsParentheses) {
+        s.append(QLatin1String("()"));
+    }
+    UMLClassifier *ownParent = static_cast<UMLClassifier*>(parent());
+    QString returnType;
+    UMLClassifier *retType = UMLClassifierListItem::getType();
+    if (retType) {
+        UMLPackage *retVisibility = retType->umlPackage();
+        if (retVisibility != ownParent && retVisibility != ownParent->umlPackage())
+            returnType = retType->fullyQualifiedName();
+        else
+            returnType = retType->name();
+    }
+    if (returnType.length() > 0 && returnType != QLatin1String("void")) {
+        s.append(QLatin1String(" : "));
+
+        if (returnType.startsWith(QLatin1String(QLatin1String("virtual ")))) {
+            s += returnType.mid(8);
+        } else {
+            s += returnType;
+        }
+    }
+    return s;
+}
+
+/**
+ * Add a parameter to the operation.
+ *
+ * @param parameter the parameter to add
+ * @param position  the position in the parameter list.
+ *                  If position = -1 the parameter will be
+ *                  appended to the list.
+ */
+void UMLOperation::addParm(UMLAttribute *parameter, int position)
+{
+    if(position >= 0 && position <= (int)m_List.count())
+        m_List.insert(position, parameter);
+    else
+        m_List.append(parameter);
+    UMLObject::emitModified();
+    connect(parameter, SIGNAL(modified()), this, SIGNAL(modified()));
+}
+
+/**
+ * Returns an unused parameter name for a new parameter.
+ */
+QString UMLOperation::getUniqueParameterName()
+{
+    QString currentName = i18n("new_parameter");
+    QString name = currentName;
+    for (int number = 1; findParm(name); ++number) {
+        name = currentName + QLatin1Char('_') + QString::number(number);
+    }
+    return name;
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLOperation::operator==(const UMLOperation & rhs) const
+{
+    if (this == &rhs)
+        return true;
+
+    if (!UMLObject::operator==(rhs))
+        return false;
+
+    if (getTypeName() != rhs.getTypeName())
+        return false;
+
+    if (m_List.count() != rhs.m_List.count())
+        return false;
+
+    if (!(m_List == rhs.m_List))
+        return false;
+
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLOperation::copyInto(UMLObject *lhs) const
+{
+    UMLOperation *target = static_cast<UMLOperation*>(lhs);
+
+    UMLClassifierListItem::copyInto(target);
+
+    m_List.copyInto(&(target->m_List));
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLOperation::clone() const
+{
+    //FIXME: The new operation should be slaved to the NEW parent not the old.
+    UMLOperation *clone = new UMLOperation(static_cast<UMLClassifier*>(parent()));
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Calls resolveRef() on all parameters.
+ * Needs to be called after all UML objects are loaded from file.
+ *
+ * @return  true for success
+ */
+bool UMLOperation::resolveRef()
+{
+    bool overallSuccess = UMLObject::resolveRef();
+    // See remark on iteration style in UMLClassifier::resolveRef()
+    foreach (UMLAttribute* pAtt, m_List) {
+        if (! pAtt->resolveRef())
+            overallSuccess = false;
+    }
+    return overallSuccess;
+}
+
+/**
+ * Returns whether this operation is a constructor.
+ *
+ * @return  true if this operation is a constructor
+ */
+bool UMLOperation::isConstructorOperation()
+{
+    // if an operation has the stereotype constructor
+    // return true
+    if (stereotype() == QLatin1String("constructor"))
+        return true;
+
+    UMLClassifier * c = static_cast<UMLClassifier*>(this->parent());
+    QString cName = c->name();
+    QString opName = name();
+    // It's a constructor operation if the operation name
+    // matches that of the parent classifier.
+    return (cName == opName);
+}
+
+/**
+ * Returns whether this operation is a destructor.
+ *
+ * @return  true if this operation is a destructor
+ */
+bool UMLOperation::isDestructorOperation()
+{
+    if (stereotype() == QLatin1String("destructor"))
+        return true;
+    UMLClassifier * c = static_cast<UMLClassifier*>(this->parent());
+
+    QString cName = c->name();
+    QString opName = name();
+    // Special support for C++ syntax:
+    // It's a destructor operation if the operation name begins
+    // with "~" followed by the name of the parent classifier.
+    if (! opName.startsWith(QLatin1Char('~')))
+        return false;
+    opName.remove(QRegExp(QLatin1String("^~\\s*")));
+    return (cName == opName);
+}
+
+/**
+ * Shortcut for (isConstructorOperation() || isDestructorOperation()).
+ *
+ * @return  true if this operation is a constructor or destructor
+ */
+bool UMLOperation::isLifeOperation()
+{
+    return (isConstructorOperation() || isDestructorOperation());
+}
+
+/**
+ * Sets whether this operation is a query (C++ "const").
+ */
+void UMLOperation::setConst(bool b)
+{
+    m_bConst = b;
+}
+
+/**
+ * Returns whether this operation is a query (C++ "const").
+ */
+bool UMLOperation::getConst() const
+{
+    return m_bConst;
+}
+
+/**
+ * Display the properties configuration dialog for the template.
+ *
+ * @param parent   the parent for the dialog
+ */
+bool UMLOperation::showPropertiesDialog(QWidget* parent)
+{
+    UMLOperationDialog dialog(parent, this);
+    return dialog.exec();
+}
+
+/**
+ * Sets the source code for this operation.
+ *
+ * @param code  the body of this operation
+ */
+void UMLOperation::setSourceCode(const QString& code)
+{
+    m_Code = code;
+}
+
+/**
+ * Returns the source code for this operation.
+ */
+QString UMLOperation::getSourceCode() const
+{
+    return m_Code;
+}
+
+/**
+ * Saves to the <UML:Operation> XMI element.
+ */
+void UMLOperation::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement operationElement = UMLObject::save(QLatin1String("UML:Operation"), qDoc);
+    operationElement.setAttribute(QLatin1String("isQuery"), m_bConst ? QLatin1String("true") : QLatin1String("false"));
+    QDomElement featureElement = qDoc.createElement(QLatin1String("UML:BehavioralFeature.parameter"));
+    if (m_pSecondary) {
+        QDomElement retElement = qDoc.createElement(QLatin1String("UML:Parameter"));
+        if (m_returnId == Uml::ID::None) {
+            uDebug() << name() << ": m_returnId is not set, setting it now.";
+            m_returnId = UniqueID::gen();
+        }
+        retElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(m_returnId));
+        retElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
+        retElement.setAttribute(QLatin1String("kind"), QLatin1String("return"));
+        featureElement.appendChild(retElement);
+    } else {
+        uDebug() << "m_SecondaryId is " << m_SecondaryId;
+    }
+
+    //save each attribute here, type different
+    foreach(UMLAttribute* pAtt, m_List) {
+        QDomElement attElement = pAtt->UMLObject::save(QLatin1String("UML:Parameter"), qDoc);
+        UMLClassifier *attrType = pAtt->getType();
+        if (attrType) {
+            attElement.setAttribute(QLatin1String("type"), Uml::ID::toString(attrType->id()));
+        } else {
+            attElement.setAttribute(QLatin1String("type"), pAtt->getTypeName());
+        }
+        attElement.setAttribute(QLatin1String("value"), pAtt->getInitialValue());
+
+        Uml::ParameterDirection::Enum kind = pAtt->getParmKind();
+        if (kind == Uml::ParameterDirection::Out)
+            attElement.setAttribute(QLatin1String("kind"), QLatin1String("out"));
+        else if (kind == Uml::ParameterDirection::InOut)
+            attElement.setAttribute(QLatin1String("kind"), QLatin1String("inout"));
+        // The default for the parameter kind is "in".
+
+        featureElement.appendChild(attElement);
+    }
+    if (featureElement.hasChildNodes()) {
+        operationElement.appendChild(featureElement);
+    }
+    qElement.appendChild(operationElement);
+}
+
+/**
+ * Loads a <UML:Operation> XMI element.
+ */
+bool UMLOperation::load(QDomElement & element)
+{
+    m_SecondaryId = element.attribute(QLatin1String("type"));
+    QString isQuery = element.attribute(QLatin1String("isQuery"));
+    if (!isQuery.isEmpty()) {
+        // We need this extra test for isEmpty() because load() might have been
+        // called again by the processing for BehavioralFeature.parameter (see below)
+        m_bConst = (isQuery == QLatin1String("true"));
+    }
+    QDomNode node = element.firstChild();
+    if (node.isComment())
+        node = node.nextSibling();
+    QDomElement attElement = node.toElement();
+    while (!attElement.isNull()) {
+        QString tag = attElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("BehavioralFeature.parameter")) ||
+            UMLDoc::tagEq(tag, QLatin1String("Element.ownedElement"))) {  // Embarcadero's Describe
+            if (! load(attElement))
+                return false;
+        } else if (UMLDoc::tagEq(tag, QLatin1String("Parameter"))) {
+            QString kind = attElement.attribute(QLatin1String("kind"));
+            if (kind.isEmpty()) {
+                kind = attElement.attribute(QLatin1String("direction"));  // Embarcadero's Describe
+                if (kind.isEmpty()) {
+                    // Perhaps the kind is stored in a child node:
+                    for (QDomNode n = attElement.firstChild(); !n.isNull(); n = n.nextSibling()) {
+                        if (n.isComment())
+                            continue;
+                        QDomElement tempElement = n.toElement();
+                        QString tag = tempElement.tagName();
+                        if (!UMLDoc::tagEq(tag, QLatin1String("kind")))
+                            continue;
+                        kind = tempElement.attribute(QLatin1String("xmi.value"));
+                        break;
+                    }
+                }
+                if (kind.isEmpty()) {
+                    kind = QLatin1String("in");
+                }
+            }
+            if (kind == QLatin1String("return") ||
+                kind == QLatin1String("result")) {  // Embarcadero's Describe
+                QString returnId = Model_Utils::getXmiId(attElement);
+                if (!returnId.isEmpty())
+                    m_returnId = Uml::ID::fromString(returnId);
+                m_SecondaryId = attElement.attribute(QLatin1String("type"));
+                if (m_SecondaryId.isEmpty()) {
+                    // Perhaps the type is stored in a child node:
+                    QDomNode node = attElement.firstChild();
+                    while (!node.isNull()) {
+                        if (node.isComment()) {
+                            node = node.nextSibling();
+                            continue;
+                        }
+                        QDomElement tempElement = node.toElement();
+                        QString tag = tempElement.tagName();
+                        if (!UMLDoc::tagEq(tag, QLatin1String("type"))) {
+                            node = node.nextSibling();
+                            continue;
+                        }
+                        m_SecondaryId = Model_Utils::getXmiId(tempElement);
+                        if (m_SecondaryId.isEmpty())
+                            m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
+                        if (m_SecondaryId.isEmpty()) {
+                            QDomNode inner = node.firstChild();
+                            QDomElement tmpElem = inner.toElement();
+                            m_SecondaryId = Model_Utils::getXmiId(tmpElem);
+                            if (m_SecondaryId.isEmpty())
+                                m_SecondaryId = tmpElem.attribute(QLatin1String("xmi.idref"));
+                        }
+                        break;
+                    }
+                    if (m_SecondaryId.isEmpty()) {
+                        uError() << name() << ": cannot find return type.";
+                    }
+                }
+                // Use deferred xmi.id resolution.
+                m_pSecondary = NULL;
+            } else {
+                UMLAttribute * pAtt = new UMLAttribute(this);
+                if(!pAtt->loadFromXMI(attElement)) {
+                    delete pAtt;
+                    return false;
+                }
+                if (kind == QLatin1String("out"))
+                    pAtt->setParmKind(Uml::ParameterDirection::Out);
+                else if (kind == QLatin1String("inout"))
+                    pAtt->setParmKind(Uml::ParameterDirection::InOut);
+                else
+                    pAtt->setParmKind(Uml::ParameterDirection::In);
+                m_List.append(pAtt);
+            }
+        }
+        node = node.nextSibling();
+        if (node.isComment())
+            node = node.nextSibling();
+        attElement = node.toElement();
+
+        // loading the source code which was entered in the 'classpropdlg' dialog is not done
+        // with the following code, because there is no CodeDocument.
+        /*
+        CodeGenerator* codegen = UMLApp::app()->getGenerator();
+        if (codegen) {
+            uDebug() << "CodeDocument searching with id=" << Uml::ID::toString(UMLObject::ID());
+            CodeDocument* codeDoc = codegen->findCodeDocumentByID(Uml::ID::toString(UMLObject::ID()));
+            if (codeDoc) {
+                uDebug() << "CodeDocument found:\n" << codeDoc;
+            }
+        }
+        */
+        // it is done in the code generators by calling CodeGenerator::loadFromXMI(...).
+
+    }//end while
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/operation.h umbrello-15.08.1/umbrello/umlmodel/operation.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/operation.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/operation.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef OPERATION_H
+#define OPERATION_H
+
+#include "umlattributelist.h"
+#include "classifierlistitem.h"
+
+class UMLClassifier;
+
+/**
+ * This class represents an operation in the UML model.
+ *
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLOperation : public UMLClassifierListItem
+{
+    Q_OBJECT
+public:
+    UMLOperation(UMLClassifier * parent, const QString& name,
+                 Uml::ID::Type id = Uml::ID::None,
+                 Uml::Visibility::Enum s = Uml::Visibility::Public,
+                 UMLObject *rt = 0);
+    explicit UMLOperation(UMLClassifier * parent);
+    virtual ~UMLOperation();
+
+    bool operator==(const UMLOperation & rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    void setType(UMLObject* type);
+
+    void moveParmLeft(UMLAttribute *a);
+    void moveParmRight(UMLAttribute *a);
+
+    void removeParm(UMLAttribute *a, bool emitModifiedSignal = true);
+
+    UMLAttributeList getParmList() const;
+
+    UMLAttribute * findParm(const QString &name);
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    void addParm(UMLAttribute *parameter, int position = -1);
+
+    bool resolveRef();
+
+    QString getUniqueParameterName();
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+    bool isConstructorOperation();
+    bool isDestructorOperation();
+    bool isLifeOperation();
+
+    void setConst(bool b);
+    bool getConst() const;
+
+    void setSourceCode(const QString& code);
+    QString getSourceCode() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+    bool load(QDomElement & element);
+
+private:
+    Uml::ID::Type    m_returnId;  ///< Holds the xmi.id of the <UML:Parameter kind="return">
+    UMLAttributeList m_List;      ///< Parameter list
+    bool             m_bConst;    ///< Holds the isQuery attribute of the <UML:Operation>
+    QString          m_Code;      ///< Holds the entered source code
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/package.cpp umbrello-15.08.1/umbrello/umlmodel/package.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/package.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/package.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,461 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header file
+#include "package.h"
+
+// local includes
+#include "debug_utils.h"
+#include "dialog_utils.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "classifier.h"
+#include "association.h"
+#include "entity.h"
+#include "object_factory.h"
+#include "model_utils.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+#include <KMessageBox>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+
+using namespace Uml;
+
+/**
+ * Sets up a Package.
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLPackage::UMLPackage(const QString & name, Uml::ID::Type id)
+        : UMLCanvasObject(name, id)
+{
+    m_BaseType = ot_Package;
+}
+
+/**
+ * Destructor.
+ */
+UMLPackage::~UMLPackage()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new object.
+ */
+void UMLPackage::copyInto(UMLObject *lhs) const
+{
+    UMLPackage *target = static_cast<UMLPackage*>(lhs);
+
+    UMLCanvasObject::copyInto(target);
+
+    m_objects.copyInto(&(target->m_objects));
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLPackage::clone() const
+{
+    UMLPackage *clone = new UMLPackage();
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Adds an existing association to the matching concept in the list of concepts.
+ * The selection of the matching concept depends on the association type:
+ * For generalizations, the assoc is added to the concept that matches role A.
+ * For aggregations and compositions, the assoc is added to the concept
+ * that matches role B.
+ * @param assoc   the association to add
+ */
+void UMLPackage::addAssocToConcepts(UMLAssociation* assoc)
+{
+    if (! AssociationType::hasUMLRepresentation(assoc->getAssocType()))
+        return;
+    Uml::ID::Type AId = assoc->getObjectId(Uml::RoleType::A);
+    Uml::ID::Type BId = assoc->getObjectId(Uml::RoleType::B);
+    UMLObject *o = NULL;
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        o = oit.next();
+        UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
+        if (c == NULL)
+            continue;
+        if (AId == c->id() || (BId == c->id())) {
+            if (c->hasAssociation(assoc))
+                uDebug() << c->name() << " already has association id=" << Uml::ID::toString(assoc->id());
+            else
+               c->addAssociationEnd(assoc);
+        }
+        UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
+        if (pkg)
+            pkg->addAssocToConcepts(assoc);
+    }
+}
+
+/**
+ * Remove the association from the participating concepts.
+ * @param assoc   the association to remove
+ */
+void UMLPackage::removeAssocFromConcepts(UMLAssociation *assoc)
+{
+    UMLObject *o = 0;
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        o = oit.next();
+        UMLCanvasObject *c = dynamic_cast<UMLCanvasObject*>(o);
+        if (c) {
+            if (c->hasAssociation(assoc))
+                c->removeAssociationEnd(assoc);
+            UMLPackage *pkg = dynamic_cast<UMLPackage*>(c);
+            if (pkg)
+                pkg->removeAssocFromConcepts(assoc);
+        }
+    }
+}
+
+/**
+ * Adds an object in this package.
+ *
+ * @param pObject   Pointer to the UMLObject to add.
+ * @return    True if the object was actually added.
+ */
+bool UMLPackage::addObject(UMLObject *pObject)
+{
+    if (pObject == NULL) {
+        uError() << "is called with a NULL object";
+        return false;
+    }
+    if (pObject == this) {
+        uError() << "adding myself as child is not allowed";
+        return false;
+    }
+
+    if (m_objects.indexOf(pObject) != -1) {
+        uDebug() << pObject->name() << " is already there";
+        return false;
+    }
+    if (pObject->baseType() == UMLObject::ot_Association) {
+        UMLAssociation *assoc = static_cast<UMLAssociation*>(pObject);
+        // Adding the UMLAssociation at the participating concepts is done
+        // again later (in UMLAssociation::resolveRef()) if they are not yet
+        // known right here.
+        if (assoc->getObject(Uml::RoleType::A) && assoc->getObject(Uml::RoleType::B)) {
+            UMLPackage *pkg = pObject->umlPackage();
+            if (pkg != this) {
+               uError() << "UMLPackage " << name() << " addObject: "
+                        << "assoc's UMLPackage is " << pkg->name();
+            }
+            addAssocToConcepts(assoc);
+        }
+    }
+    else {
+      QString name = pObject->name();
+      QString oldName = name;
+      while (findObject(name) != NULL) {
+         QString prevName = name;
+         name = Model_Utils::uniqObjectName(pObject->baseType(), this);
+         bool ok = Dialog_Utils::askName(i18nc("object name", "Name"),
+                                         i18n("An object with the name %1\nalready exists in the package %2.\nPlease enter a new name:", prevName, this->name()),
+                                         name);
+         if (!ok) {
+            name = oldName;
+            continue;
+         }
+         if (name.length() == 0) {
+            KMessageBox::error(0, i18n("That is an invalid name."),
+                               i18n("Invalid Name"));
+            continue;
+        }
+      }
+      if (oldName != name) {
+        pObject->setName(name);
+      }
+    }
+    m_objects.append(pObject);
+    return true;
+}
+
+/**
+ * Removes an object from this package.
+ * Does not physically delete the object.
+ *
+ * @param pObject   Pointer to the UMLObject to be removed.
+ */
+void UMLPackage::removeObject(UMLObject *pObject)
+{
+    if (pObject->baseType() == UMLObject::ot_Association) {
+        UMLObject *o = const_cast<UMLObject*>(pObject);
+        UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
+        removeAssocFromConcepts(assoc);
+    }
+    if (m_objects.indexOf(pObject) == -1)
+        uDebug() << name() << " removeObject: object with id="
+                 << Uml::ID::toString(pObject->id()) << "not found.";
+    else
+        m_objects.removeAll(pObject);
+}
+
+/**
+ * Removes all objects from this package.
+ * Inner containers (e.g. nested packages) are removed recursively.
+ */
+void UMLPackage::removeAllObjects()
+{
+    UMLCanvasObject::removeAllChildObjects();
+    UMLObject *o = NULL;
+
+    while (!m_objects.isEmpty() && (o = m_objects.first()) != NULL)  {
+        UMLPackage *pkg = dynamic_cast<UMLPackage*>(o);
+        if (pkg)
+            pkg->removeAllObjects();
+        removeObject(o);
+        delete o;
+    }
+}
+
+/**
+ * Returns the list of objects contained in this package.
+ */
+UMLObjectList UMLPackage::containedObjects()
+{
+    return m_objects;
+}
+
+/**
+ * Find the object of the given name in the list of contained objects.
+ *
+ * @param name   The name to seek.
+ * @return  Pointer to the UMLObject found or NULL if not found.
+ */
+UMLObject * UMLPackage::findObject(const QString &name)
+{
+    const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        UMLObject *obj = oit.next();
+        if (!obj)
+            continue;
+        if (caseSensitive) {
+            if (obj->name() == name)
+                return obj;
+        } else if (obj->name().toLower() == name.toLower()) {
+            return obj;
+        }
+    }
+    return NULL;
+}
+
+/**
+ * Find the object of the given ID in the list of contained objects.
+ *
+ * @param id   The ID to seek.
+ * @return  Pointer to the UMLObject found or NULL if not found.
+ */
+UMLObject * UMLPackage::findObjectById(Uml::ID::Type id)
+{
+    return Model_Utils::findObjectInList(id, m_objects);
+}
+
+/**
+ * Append all packages from this package (and those from nested packages)
+ * to the given UMLPackageList.
+ *
+ * @param packages        The list to append to
+ * @param includeNested   Whether to include the packages from nested packages
+ *                        (default:true)
+ */
+void UMLPackage::appendPackages(UMLPackageList& packages, bool includeNested)
+{
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        UMLObject *o = oit.next();
+        uIgnoreZeroPointer(o);
+        ObjectType ot = o->baseType();
+        if (ot == ot_Package || ot == ot_Folder) {
+            packages.append(static_cast<UMLPackage*>(o));
+            if (includeNested) {
+               UMLPackage *inner = static_cast<UMLPackage*>(o);
+               inner->appendPackages(packages);
+            }
+         }
+    }
+}
+
+/**
+ * Append all classifiers from this package (and those from
+ * nested packages) to the given UMLClassifierList.
+ *
+ * @param classifiers     The list to append to.
+ * @param includeNested   Whether to include the classifiers from
+ *                        nested packages (default: true.)
+ */
+void UMLPackage::appendClassifiers(UMLClassifierList& classifiers,
+                                   bool includeNested /* = true */)
+{
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        UMLObject *o = oit.next();
+        uIgnoreZeroPointer(o);
+        ObjectType ot = o->baseType();
+        if (ot == ot_Class || ot == ot_Interface ||
+                ot == ot_Datatype || ot == ot_Enum || ot == ot_Entity) {
+            classifiers.append((UMLClassifier *)o);
+        } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+            UMLPackage *inner = static_cast<UMLPackage *>(o);
+            inner->appendClassifiers(classifiers);
+        }
+    }
+}
+
+/**
+ * Append all entities from this package (and those
+ * from nested packages) to the given UMLEntityList.
+ *
+ * @param entities        The list to append to.
+ * @param includeNested   Whether to include the entities from
+ *                        nested packages (default: true.)
+ */
+void UMLPackage::appendEntities(UMLEntityList& entities,
+                                 bool includeNested /* = true */)
+{
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        UMLObject *o = oit.next();
+        uIgnoreZeroPointer(o);
+        ObjectType ot = o->baseType();
+        if (ot == ot_Entity) {
+            UMLEntity *c = static_cast<UMLEntity*>(o);
+            entities.append(c);
+        } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+            UMLPackage *inner = static_cast<UMLPackage *>(o);
+            inner->appendEntities(entities);
+        }
+    }
+}
+
+/**
+ * Append all classes and interfaces from this package (and those
+ * from nested packages) to the given UMLClassifierList.
+ *
+ * @param classifiers     The list to append to.
+ * @param includeNested   Whether to include the classifiers from
+ *                        nested packages (default: true.)
+ */
+void UMLPackage::appendClassesAndInterfaces(UMLClassifierList& classifiers,
+        bool includeNested /* = true */)
+{
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        UMLObject *o = oit.next();
+        uIgnoreZeroPointer(o);
+        ObjectType ot = o->baseType();
+        if (ot == ot_Class || ot == ot_Interface) {
+            UMLClassifier *c = static_cast<UMLClassifier*>(o);
+            classifiers.append(c);
+        } else if (includeNested && (ot == ot_Package || ot == ot_Folder)) {
+            UMLPackage *inner = static_cast<UMLPackage *>(o);
+            inner->appendClassesAndInterfaces(classifiers);
+        }
+    }
+}
+
+/**
+ * Resolve types. Required when dealing with foreign XMI files.
+ * Needs to be called after all UML objects are loaded from file.
+ * Overrides the method from UMLObject.
+ * Calls resolveRef() on each contained object.
+ *
+ * @return  True for overall success.
+ */
+bool UMLPackage::resolveRef()
+{
+    bool overallSuccess = UMLCanvasObject::resolveRef();
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        UMLObject *obj = oit.next();
+        uIgnoreZeroPointer(obj);
+        if (! obj->resolveRef()) {
+            UMLObject::ObjectType ot = obj->baseType();
+            if (ot != UMLObject::ot_Package && ot != UMLObject::ot_Folder)
+                m_objects.removeAll(obj);
+            overallSuccess = false;
+        }
+    }
+    return overallSuccess;
+}
+
+/**
+ * Creates the <UML:Package> XMI element.
+ */
+void UMLPackage::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement packageElement = UMLObject::save(QLatin1String("UML:Package"), qDoc);
+    QDomElement ownedElement = qDoc.createElement(QLatin1String("UML:Namespace.ownedElement"));
+    UMLObject *obj = NULL;
+    // save classifiers etc.
+    for (UMLObjectListIt oit(m_objects); oit.hasNext();) {
+        obj = oit.next();
+        uIgnoreZeroPointer(obj);
+        obj->saveToXMI (qDoc, ownedElement);
+    }
+    // save associations
+    for (UMLObjectListIt ait(m_List); ait.hasNext();) {
+        obj = ait.next();
+        obj->saveToXMI (qDoc, ownedElement);
+    }
+
+    packageElement.appendChild(ownedElement);
+    qElement.appendChild(packageElement);
+}
+
+/**
+ * Loads the <UML:Package> XMI element.
+ * Auxiliary to UMLObject::loadFromXMI.
+ */
+bool UMLPackage::load(QDomElement& element)
+{
+    for (QDomNode node = element.firstChild(); !node.isNull();
+            node = node.nextSibling()) {
+        if (node.isComment())
+            continue;
+        QDomElement tempElement = node.toElement();
+        QString type = tempElement.tagName();
+        if (Model_Utils::isCommonXMIAttribute(type))
+            continue;
+        if (UMLDoc::tagEq(type, QLatin1String("Namespace.ownedElement")) ||
+                UMLDoc::tagEq(type, QLatin1String("Element.ownedElement")) ||  // Embarcadero's Describe
+                UMLDoc::tagEq(type, QLatin1String("Namespace.contents"))) {
+            //CHECK: Umbrello currently assumes that nested elements
+            // are ownedElements anyway.
+            // Therefore these tags are not further interpreted.
+            if (! load(tempElement))
+                return false;
+            continue;
+        } else if (UMLDoc::tagEq(type, QLatin1String("packagedElement")) ||
+                   UMLDoc::tagEq(type, QLatin1String("ownedElement"))) {
+            type = tempElement.attribute(QLatin1String("xmi:type"));
+        }
+        UMLObject *pObject = Object_Factory::makeObjectFromXMI(type);
+        if(!pObject) {
+            uWarning() << "Unknown type of umlobject to create: " << type;
+            continue;
+        }
+        pObject->setUMLPackage(this);
+        if (!pObject->loadFromXMI(tempElement)) {
+            removeObject(pObject);
+            delete pObject;
+        }
+    }
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/package.h umbrello-15.08.1/umbrello/umlmodel/package.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/package.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/package.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,79 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PACKAGE_H
+#define PACKAGE_H
+
+#include "umlcanvasobject.h"
+#include "umlclassifierlist.h"
+#include "umlentitylist.h"
+
+// forward declarations
+class UMLAssociation;
+
+/**
+ * This class contains the non-graphical information required for a UML
+ * Package.
+ * This class inherits from @ref UMLCanvasObject which contains most of the
+ * information.
+ *
+ * @short Non-graphical information for a Package.
+ * @author Jonathan Riddell
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLPackage : public UMLCanvasObject
+{
+    Q_OBJECT
+public:
+    explicit UMLPackage(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLPackage();
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    bool addObject(UMLObject *pObject);
+    void removeObject(UMLObject *pObject);
+
+    virtual void removeAllObjects();
+
+    UMLObjectList containedObjects();
+
+    void addAssocToConcepts(UMLAssociation* assoc);
+    void removeAssocFromConcepts(UMLAssociation *assoc);
+
+    UMLObject * findObject(const QString &name);
+    UMLObject * findObjectById(Uml::ID::Type id);
+
+    void appendPackages(UMLPackageList& packages, bool includeNested = true);
+    void appendClassifiers(UMLClassifierList& classifiers,
+                            bool includeNested = true);
+    void appendClassesAndInterfaces(UMLClassifierList& classifiers,
+                                    bool includeNested = true);
+    void appendEntities(UMLEntityList& entities,
+                        bool includeNested = true);
+
+    virtual bool resolveRef();
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+protected:
+    virtual bool load(QDomElement& element);
+
+    /**
+     * References to the objects contained in this package.
+     * The UMLPackage is the owner of the objects.
+     */
+    UMLObjectList m_objects;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/port.cpp umbrello-15.08.1/umbrello/umlmodel/port.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/port.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/port.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,68 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2014                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "port.h"
+
+#include <KLocalizedString>
+
+/**
+ * Sets up a Port.
+ *
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLPort::UMLPort(const QString & name, Uml::ID::Type id)
+  : UMLCanvasObject(name, id)
+{
+    init();
+}
+
+/**
+ * Destructor.
+ */
+UMLPort::~UMLPort()
+{
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLPort::init()
+{
+    m_BaseType = UMLObject::ot_Port;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLPort::clone() const
+{
+    UMLPort *clone = new UMLPort();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the <UML:Port> XMI element.
+ */
+void UMLPort::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement portElement = UMLObject::save(QLatin1String("UML:Port"), qDoc);
+    qElement.appendChild(portElement);
+}
+
+/**
+ * Loads the <UML:Port> XMI element (empty.)
+ */
+bool UMLPort::load(QDomElement&)
+{
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/port.h umbrello-15.08.1/umbrello/umlmodel/port.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/port.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/port.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,46 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2014                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PORT_H
+#define PORT_H
+
+#include "umlcanvasobject.h"
+
+/**
+ * This class contains the non-graphical information required for a UML Port.
+ * This class inherits from @ref UMLCanvasObject which contains most of the
+ * information.
+ *
+ * @short Non-graphical information for a Port.
+ * @author Oliver Kellogg
+ * @see UMLCanvasObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLPort : public UMLCanvasObject
+{
+    Q_OBJECT
+public:
+
+    explicit UMLPort(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLPort();
+
+    virtual void init();
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+
+    bool load(QDomElement & element);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/stereotype.cpp umbrello-15.08.1/umbrello/umlmodel/stereotype.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/stereotype.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/stereotype.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,165 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "stereotype.h"
+
+// local includes
+#include "debug_utils.h"
+#include "umldoc.h"
+#include "uml.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+
+/**
+ * Sets up a stereotype.
+ *
+ * @param name   The name of this UMLStereotype.
+ * @param id     The unique id given to this UMLStereotype.
+ */
+UMLStereotype::UMLStereotype(const QString &name, Uml::ID::Type id /* = Uml::id_None */)
+  : UMLObject(name, id)
+{
+    m_BaseType = UMLObject::ot_Stereotype;
+    UMLStereotype * existing = UMLApp::app()->document()->findStereotype(name);
+    if (existing) {
+        uError() << "UMLStereotype constructor: " << name << " already exists";
+    }
+    m_refCount = 0;
+}
+
+/**
+ * Sets up a stereotype.
+ */
+UMLStereotype::UMLStereotype()
+  : UMLObject()
+{
+    m_BaseType = UMLObject::ot_Stereotype;
+    m_refCount = 0;
+}
+
+/**
+ * Destructor.
+ */
+UMLStereotype::~UMLStereotype()
+{
+    //Q_ASSERT(m_refCount == 0);
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLStereotype::operator==(const UMLStereotype &rhs) const
+{
+    if (this == &rhs) {
+        return true;
+    }
+
+    if (!UMLObject::operator==(rhs)) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLStereotype::copyInto(UMLObject *lhs) const
+{
+    UMLObject::copyInto(lhs);
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLStereotype::clone() const
+{
+    UMLStereotype *clone = new UMLStereotype();
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Saves to the <UML:StereoType> XMI element.
+ */
+void UMLStereotype::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    //FIXME: uml13.dtd compliance
+    QDomElement stereotypeElement = UMLObject::save(QLatin1String("UML:Stereotype"), qDoc);
+    qElement.appendChild(stereotypeElement);
+}
+
+/**
+ * Display the properties configuration dialog for the stereotype
+ * (just a line edit).
+ */
+bool UMLStereotype::showPropertiesDialog(QWidget* parent)
+{
+    bool ok;
+#if QT_VERSION >= 0x050000
+    QString stereoTypeName = QInputDialog::getText(parent,
+                                                   i18n("Stereotype"), i18n("Enter name:"),
+                                                   QLineEdit::Normal,
+                                                   name(), &ok);
+#else
+    QString stereoTypeName = KInputDialog::getText(i18n("Stereotype"), i18n("Enter name:"), name(), &ok, parent);
+#endif
+    if (ok) {
+        setName(stereoTypeName);
+    }
+    return ok;
+}
+
+/**
+ * Increments the reference count for this stereotype.
+ */
+void UMLStereotype::incrRefCount()
+{
+    m_refCount++;
+}
+
+/**
+ * Decrements the reference count for this stereotype.
+ */
+void UMLStereotype::decrRefCount()
+{
+    m_refCount--;
+}
+
+/**
+ * Returns the reference count for this stereotype.
+ */
+int UMLStereotype::refCount() const
+{
+    return m_refCount;
+}
+
+/**
+ * Returns the name as string
+ */
+QString UMLStereotype::name(bool includeAdornments) const
+{
+    if (includeAdornments)
+        return QString::fromUtf8("«") + UMLObject::name() + QString::fromUtf8("»");
+    else
+        return UMLObject::name();
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/stereotype.h umbrello-15.08.1/umbrello/umlmodel/stereotype.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/stereotype.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/stereotype.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,71 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef STEREOTYPE_H
+#define STEREOTYPE_H
+
+#include "umlobject.h"
+
+/**
+ * This class is used to set up information for a stereotype.
+ * Stereotypes are used essentially as properties of
+ * attributes and operations etc.
+ *
+ * Each stereotype object is reference counted, i.e. client code
+ * manages it such that it comes into existence as soon as there is
+ * at least one user, and ceases existing when the number of users
+ * drops to 0.
+ * m_refCount reflects the number of users. It is externally managed,
+ * i.e. client code must take care to call incrRefCount() and
+ * decrRefCount() as appropriate.
+ *
+ * The one and only owner of all stereotypes is the UMLDoc, and the
+ * ownership is specially managed (umlPackage() returns NULL for a
+ * UMLStereotype.) The reason for this special treatment is that
+ * class UMLDoc does not inherit from class UMLPackage, and therefore
+ * setUMLPackage() cannot be used for stereotypes.
+ *
+ * @short Sets up stereotype information.
+ * @author Jonathan Riddell
+ * @author Oliver Kellogg
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLStereotype : public UMLObject
+{
+    Q_OBJECT
+public:
+    explicit UMLStereotype(const QString &name, Uml::ID::Type id = Uml::ID::None);
+    UMLStereotype();
+
+    virtual ~UMLStereotype();
+
+    bool operator==(const UMLStereotype &rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    void incrRefCount();
+    void decrRefCount();
+
+    int refCount() const;
+
+    QString name(bool includeAdornments=false) const;
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent);
+
+protected:
+    int m_refCount;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/template.cpp umbrello-15.08.1/umbrello/umlmodel/template.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/template.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/template.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,146 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "template.h"
+
+// app includes
+#include "debug_utils.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umltemplatedialog.h"
+
+/**
+ * Sets up a template.
+ *
+ * @param parent   The parent of this UMLTemplate (i.e. its concept).
+ * @param name     The name of this UMLTemplate.
+ * @param id       The unique id given to this UMLTemplate.
+ * @param type     The type of this UMLTemplate.
+ */
+UMLTemplate::UMLTemplate(UMLObject *parent, const QString& name,
+                         Uml::ID::Type id, const QString& type)
+        : UMLClassifierListItem(parent, name, id)
+{
+    setTypeName(type);
+    m_BaseType = UMLObject::ot_Template;
+}
+
+/**
+ * Sets up a template.
+ *
+ * @param parent    The parent of this UMLTemplate (i.e. its concept).
+ */
+UMLTemplate::UMLTemplate(UMLObject *parent)
+        : UMLClassifierListItem(parent)
+{
+    m_BaseType = UMLObject::ot_Template;
+}
+
+/**
+ * Destructor.
+ */
+UMLTemplate::~UMLTemplate()
+{
+}
+
+QString UMLTemplate::toString(Uml::SignatureType::Enum sig)
+{
+    Q_UNUSED(sig);
+    if (m_pSecondary == NULL || m_pSecondary->name() == QLatin1String("class")) {
+        return name();
+    } else {
+        return name() + QLatin1String(" : ") + m_pSecondary->name();
+    }
+}
+
+/**
+ * Overrides method from UMLClassifierListItem.
+ * Returns the type name of the UMLTemplate.
+ * If the template parameter is a class, there is no separate
+ * type object. In this case, getTypeName() returns "class".
+ *
+ * @return  The type name of the UMLClassifierListItem.
+ */
+QString UMLTemplate::getTypeName() const
+{
+    if (m_pSecondary == NULL)
+        return QLatin1String("class");
+    return m_pSecondary->name();
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLTemplate::operator==(const UMLTemplate &rhs) const
+{
+    if (this == &rhs) {
+        return true;
+    }
+    if (!UMLObject::operator==(rhs)) {
+        return false;
+    }
+    if (m_pSecondary != rhs.m_pSecondary) {
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLTemplate::copyInto(UMLObject *lhs) const
+{
+    UMLClassifierListItem::copyInto(lhs);
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLTemplate::clone() const
+{
+    UMLTemplate *clone = new UMLTemplate((UMLTemplate*) parent());
+    copyInto(clone);
+
+    return clone;
+}
+
+/**
+ * Writes the <UML:TemplateParameter> XMI element.
+ */
+void UMLTemplate::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    //FIXME: uml13.dtd compliance
+    QDomElement attributeElement = UMLObject::save(QLatin1String("UML:TemplateParameter"), qDoc);
+    if (m_pSecondary)
+        attributeElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
+    qElement.appendChild(attributeElement);
+}
+
+/**
+ * Loads the <UML:TemplateParameter> XMI element.
+ */
+bool UMLTemplate::load(QDomElement& element)
+{
+    m_SecondaryId = element.attribute(QLatin1String("type"));
+    return true;
+}
+
+/**
+ * Display the properties configuration dialog for the template.
+ *
+ * @return  Success status.
+ */
+bool UMLTemplate::showPropertiesDialog(QWidget* parent)
+{
+    UMLTemplateDialog dialog(parent, this);
+    return dialog.exec();
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/template.h umbrello-15.08.1/umbrello/umlmodel/template.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/template.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/template.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,57 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef TEMPLATE_H
+#define TEMPLATE_H
+
+#include "classifierlistitem.h"
+
+/**
+ * This class holds information used by template classes, called
+ * paramaterised class in UML and a generic in Java.  It has a
+ * type (usually just "class") and name.
+ *
+ * @short Sets up template information.
+ * @author Jonathan Riddell
+ * @see UMLObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLTemplate : public UMLClassifierListItem
+{
+public:
+
+    UMLTemplate(UMLObject *parent, const QString& name,
+                Uml::ID::Type id = Uml::ID::None, const QString& type = QLatin1String("class"));
+
+    explicit UMLTemplate(UMLObject *parent);
+
+    bool operator==(const UMLTemplate &rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    virtual ~UMLTemplate();
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    virtual QString getTypeName() const;
+
+    virtual bool showPropertiesDialog(QWidget* parent);
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+
+    bool load(QDomElement & element);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlassociationlist.h umbrello-15.08.1/umbrello/umlmodel/umlassociationlist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlassociationlist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlassociationlist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2007                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLASSOCIATIONLIST_H
+#define UMLASSOCIATIONLIST_H
+
+#include <qlist.h>
+
+// forward declaration
+class UMLAssociation;
+
+typedef QList<UMLAssociation*> UMLAssociationList;
+typedef QListIterator<UMLAssociation*> UMLAssociationListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlattributelist.cpp umbrello-15.08.1/umbrello/umlmodel/umlattributelist.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlattributelist.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlattributelist.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "umlattributelist.h"
+
+#include "attribute.h"
+
+#include <KLocalizedString>
+
+UMLAttributeList::UMLAttributeList()
+{
+}
+
+UMLAttributeList::UMLAttributeList(const UMLAttributeList& other)
+    : QList<UMLAttribute*>(other)
+{
+}
+
+UMLAttributeList::~UMLAttributeList()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLAttributeList::copyInto(UMLAttributeList *rhs) const
+{
+    // Don't copy yourself.
+    if (rhs == this) return;
+
+    rhs->clear();
+
+    // Suffering from const; we shall not modify our object.
+    UMLAttributeList *tmp = new UMLAttributeList(*this);
+
+    UMLAttribute *item;
+    for (UMLAttributeListIt ait(*tmp); ait.hasNext() ;)
+    {
+        item = ait.next();
+        rhs->append((UMLAttribute*)item->clone());
+    }
+    delete tmp;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLAttributeList* UMLAttributeList::clone() const
+{
+    UMLAttributeList *clone = new UMLAttributeList();
+    copyInto(clone);
+    return clone;
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlattributelist.h umbrello-15.08.1/umbrello/umlmodel/umlattributelist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlattributelist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlattributelist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLATTRIBUTELIST_H
+#define UMLATTRIBUTELIST_H
+
+#include <QList>
+
+#include "attribute.h"
+
+//typedef QPtrList<UMLAttribute> UMLAttributeList;
+typedef QListIterator<UMLAttribute*> UMLAttributeListIt;
+
+/**
+ * This sub-class adds copyInto and clone to the QPtrList<UMLAttribute>
+ * base class.
+ */
+class UMLAttributeList : public QList<UMLAttribute*>
+{
+public:
+
+    UMLAttributeList();
+
+    UMLAttributeList(const UMLAttributeList&);
+
+    virtual ~UMLAttributeList();
+
+    virtual void copyInto(UMLAttributeList *rhs) const;
+
+    virtual UMLAttributeList* clone() const;
+};
+
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlcanvasobject.cpp umbrello-15.08.1/umbrello/umlmodel/umlcanvasobject.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlcanvasobject.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlcanvasobject.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,464 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "umlcanvasobject.h"
+
+// local includes
+#include "debug_utils.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "classifier.h"
+#include "association.h"
+#include "attribute.h"
+#include "operation.h"
+#include "template.h"
+#include "stereotype.h"
+#include "idchangelog.h"
+
+// kde includes
+#include <KLocalizedString>
+
+DEBUG_REGISTER_DISABLED(UMLCanvasObject)
+
+/**
+ * Sets up a UMLCanvasObject.
+ *
+ * @param name   The name of the Concept.
+ * @param id     The unique id of the Concept.
+ */
+UMLCanvasObject::UMLCanvasObject(const QString & name, Uml::ID::Type id)
+  : UMLObject(name, id)
+{
+}
+
+/**
+ * Standard deconstructor.
+ */
+UMLCanvasObject::~UMLCanvasObject()
+{
+    //removeAllAssociations();
+    // No! This is way too late to do that.
+    //  It should have been called explicitly before destructing the
+    //  UMLCanvasObject.
+    if (associations())
+        DEBUG(DBG_SRC) << "UMLCanvasObject destructor: FIXME: there are still associations()";
+}
+
+/**
+ * Return the subset of m_List that matches the given type.
+ *
+ * @param assocType   The AssociationType::Enum to match.
+ * @return   The list of associations that match assocType.
+ */
+UMLAssociationList UMLCanvasObject::getSpecificAssocs(Uml::AssociationType::Enum assocType)
+{
+    UMLAssociationList list;
+    UMLObject *o = NULL;
+    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
+        o = oit.next();
+        uIgnoreZeroPointer(o);
+        if (o->baseType() != UMLObject::ot_Association)
+            continue;
+        UMLAssociation *a = static_cast<UMLAssociation*>(o);
+        if (a->getAssocType() == assocType)
+            list.append(a);
+    }
+    return list;
+}
+
+/**
+ * Adds an association end to m_List.
+ *
+ * @param assoc  The association to add.
+ *               @todo change param type to UMLRole
+ */
+bool UMLCanvasObject::addAssociationEnd(UMLAssociation* assoc)
+{
+    Q_ASSERT(assoc);
+    // add association only if not already present in list
+    if (!hasAssociation(assoc))
+    {
+        m_List.append(assoc);
+
+        // Don't emit signals during load from XMI
+        UMLObject::emitModified();
+        emit sigAssociationEndAdded(assoc);
+        return true;
+    }
+    return false;
+}
+
+/**
+ * Determine if this canvasobject has the given association.
+ *
+ * @param assoc   The association to check.
+ */
+bool UMLCanvasObject::hasAssociation(UMLAssociation* assoc)
+{
+    uint cnt = m_List.count(assoc);
+    DEBUG(DBG_SRC) << "count is " << cnt;
+    return (cnt > 0);
+}
+
+/**
+ * Remove an association end from the CanvasObject.
+ *
+ * @param assoc   The association to remove.
+ *                @todo change param type to UMLRole
+ */
+int UMLCanvasObject::removeAssociationEnd(UMLAssociation * assoc)
+{
+    if (!hasAssociation(assoc) || !m_List.removeAll(assoc)) {
+        DEBUG(DBG_SRC) << "cannot find given assoc " << assoc << " in list";
+        return -1;
+    }
+    UMLApp::app()->document()->removeAssociation(assoc, false);
+    UMLObject::emitModified();
+    emit sigAssociationEndRemoved(assoc);
+    return m_List.count();
+}
+
+/**
+ * Remove all association ends from the CanvasObject.
+ */
+void UMLCanvasObject::removeAllAssociationEnds()
+{
+    for (int i = 0; i < m_List.count(); i++) {
+        UMLObject *o = m_List.at(i);
+        uIgnoreZeroPointer(o);
+        if (o->baseType() != UMLObject::ot_Association) {
+            continue;
+        }
+        UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
+        //umldoc->slotRemoveUMLObject(assoc);
+        UMLObject* objA = assoc->getObject(Uml::RoleType::A);
+        UMLObject* objB = assoc->getObject(Uml::RoleType::B);
+        UMLCanvasObject *roleAObj = dynamic_cast<UMLCanvasObject*>(objA);
+        if (roleAObj) {
+            roleAObj->removeAssociationEnd(assoc);
+        } else if (objA) {
+            DEBUG(DBG_SRC) << name() << ": objA " << objA->name() << " is not a UMLCanvasObject";
+        } else
+            DEBUG(DBG_SRC) << name() << "): objA is NULL";
+        UMLCanvasObject *roleBObj = dynamic_cast<UMLCanvasObject*>(objB);
+        if (roleBObj) {
+            roleBObj->removeAssociationEnd(assoc);
+        } else if (objB) {
+            DEBUG(DBG_SRC) << name() << "): objB " << objB->name() << " is not a UMLCanvasObject";
+        } else
+            DEBUG(DBG_SRC) << name() << "): objB is NULL";
+    }
+}
+
+/**
+ * Remove all child objects.
+ * Just clear list, objects must be deleted where they were created
+ * (or we have bad crashes).
+ */
+void UMLCanvasObject::removeAllChildObjects()
+{
+    if (!m_List.isEmpty()) {
+        removeAllAssociationEnds();
+        m_List.clear();
+    }
+}
+
+/**
+ * Returns a name for the new association, operation, template
+ * or attribute appended with a number if the default name is
+ * taken e.g. new_association, new_association_1 etc.
+ *
+ * @param type      The object type for which to make a name.
+ * @param prefix    Optional prefix to use for the name.
+ *                  If not given then uniqChildName() will choose the prefix
+ *                  internally based on the object type.
+ * @return  Unique name string for the ObjectType given.
+ */
+QString UMLCanvasObject::uniqChildName(const UMLObject::ObjectType type,
+                                        const QString &prefix /* = QString() */)
+{
+    QString currentName;
+    currentName = prefix;
+    if (currentName.isEmpty()) {
+        switch (type) {
+            case UMLObject::ot_Association:
+                currentName = i18n("new_association");
+                break;
+            case UMLObject::ot_Attribute:
+                currentName = i18n("new_attribute");
+                break;
+            case UMLObject::ot_Template:
+                currentName = i18n("new_template");
+                break;
+            case UMLObject::ot_Operation:
+                currentName = i18n("new_operation");
+                break;
+            case UMLObject::ot_EnumLiteral:
+                currentName = i18n("new_literal");
+                break;
+            case UMLObject::ot_EntityAttribute:
+                currentName = i18n("new_field");
+                break;
+            case UMLObject::ot_UniqueConstraint:
+                currentName = i18n("new_unique_constraint");
+                break;
+            case UMLObject::ot_ForeignKeyConstraint:
+                currentName = i18n("new_fkey_constraint");
+                break;
+            case UMLObject::ot_CheckConstraint:
+                currentName = i18n("new_check_constraint");
+                break;
+            default:
+                uWarning() << "uniqChildName() called for unknown child type " << UMLObject::toString(type);
+                return QLatin1String("ERROR_in_UMLCanvasObject_uniqChildName");
+        }
+    }
+
+    QString name = currentName;
+    for (int number = 1; findChildObject(name); ++number) {
+        name = currentName + QLatin1Char('_') + QString::number(number);
+    }
+    return name;
+}
+
+/**
+ * Find a child object with the given name.
+ *
+ * @param n  The name of the object to find.
+ * @param t  The type to find (optional.) If not given then
+ *           any object type will match.
+ * @return  Pointer to the object found; NULL if none found.
+ */
+UMLObject * UMLCanvasObject::findChildObject(const QString &n, UMLObject::ObjectType t)
+{
+    const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
+    UMLObject *obj = NULL;
+    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
+        obj = oit.next();
+        uIgnoreZeroPointer(obj);
+        if (t != UMLObject::ot_UMLObject && obj->baseType() != t)
+            continue;
+        if (caseSensitive) {
+            if (obj->name() == n)
+                return obj;
+        } else if (obj->name().toLower() == n.toLower()) {
+            return obj;
+        }
+    }
+    return NULL;
+}
+
+/**
+ * Find an association.
+ *
+ * @param id        The id of the object to find.
+ * @param considerAncestors boolean switch to consider ancestors while searching
+ * @return  Pointer to the object found (NULL if not found.)
+ */
+UMLObject* UMLCanvasObject::findChildObjectById(Uml::ID::Type id, bool considerAncestors)
+{
+    Q_UNUSED(considerAncestors);
+    UMLObject *o = NULL;
+    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
+        o = oit.next();
+        uIgnoreZeroPointer(o);
+        if (o->id() == id)
+            return o;
+    }
+    return 0;
+}
+
+/**
+ *  Overloaded '==' operator
+ */
+bool UMLCanvasObject::operator==(const UMLCanvasObject& rhs) const
+{
+    if (this == &rhs) {
+        return true;
+    }
+    if (!UMLObject::operator==(rhs)) {
+        return false;
+    }
+    if (m_List.count() != rhs.m_List.count()) {
+        return false;
+    }
+    if (&m_List != &(rhs.m_List)) {
+        return false;
+    }
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLCanvasObject::copyInto(UMLObject *lhs) const
+{
+    UMLObject::copyInto(lhs);
+
+    // TODO Associations are not copied at the moment. This because
+    // the duplicate function (on umlwidgets) do not copy the associations.
+    //
+    //target->m_List = m_List;
+}
+
+/**
+ * Returns the number of associations for the CanvasObject.
+ * This is the sum of the aggregations and compositions.
+ *
+ * @return  The number of associations for the Concept.
+ */
+int UMLCanvasObject::associations()
+{
+    int count = 0;
+    UMLObject *obj = NULL;
+    for (UMLObjectListIt oit(m_List); oit.hasNext();) {
+        obj = oit.next();
+        uIgnoreZeroPointer(obj);
+        if (obj->baseType() == UMLObject::ot_Association)
+            count++;
+    }
+    return count;
+}
+
+/**
+ * Return the list of associations for the CanvasObject.
+ *
+ * @return   The list of associations for the CanvasObject.
+ */
+UMLAssociationList UMLCanvasObject::getAssociations()
+{
+    UMLAssociationList assocs;
+    UMLObject *o = NULL;
+    for (UMLObjectListIt oit(m_List); oit.hasNext() ;) {
+        o = oit.next();
+        uIgnoreZeroPointer(o);
+        if (o->baseType() != UMLObject::ot_Association)
+            continue;
+        UMLAssociation *assoc = static_cast<UMLAssociation*>(o);
+        assocs.append(assoc);
+    }
+    return assocs;
+}
+
+/**
+ * Return a list of the superclasses of this concept.
+ * TODO: This overlaps with UMLClassifier::findSuperClassConcepts(),
+ *       see if we can merge the two.
+ *
+ * @param withRealizations include realizations in the returned list (default=yes)
+ * @return  The list of superclasses for the concept.
+ */
+UMLClassifierList UMLCanvasObject::getSuperClasses(bool withRealizations)
+{
+    UMLClassifierList list;
+    UMLAssociationList assocs = getAssociations();
+    foreach (UMLAssociation* a, assocs) {
+        uIgnoreZeroPointer(a);
+        if ((a->getAssocType() != Uml::AssociationType::Generalization &&
+             a->getAssocType() != Uml::AssociationType::Realization) ||
+             (!withRealizations && a->getAssocType() == Uml::AssociationType::Realization) ||
+                a->getObjectId(Uml::RoleType::A) != id())
+            continue;
+        UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::RoleType::B));
+        if (c)
+            list.append(c);
+        else
+            DEBUG(DBG_SRC) << name() << ": generalization's other end is not a "
+                << "UMLClassifier (id= " << Uml::ID::toString(a->getObjectId(Uml::RoleType::B)) << ")";
+    }
+    return list;
+}
+
+/**
+ * Return a list of the classes that inherit from this concept.
+ * TODO: This overlaps with UMLClassifier::findSubClassConcepts(),
+ *       see if we can merge the two.
+ *
+ * @return  The list of classes inheriting from the concept.
+ */
+UMLClassifierList UMLCanvasObject::getSubClasses()
+{
+    UMLClassifierList list;
+    UMLAssociationList assocs = getAssociations();
+    foreach (UMLAssociation* a, assocs) {
+        uIgnoreZeroPointer(a);
+        if ((a->getAssocType() != Uml::AssociationType::Generalization &&
+             a->getAssocType() != Uml::AssociationType::Realization) ||
+                a->getObjectId(Uml::RoleType::B) != id())
+            continue;
+        UMLClassifier *c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::RoleType::A));
+        if (c)
+            list.append(c);
+        else
+            DEBUG(DBG_SRC) << "specialization's other end is not a UMLClassifier"
+                << " (id=" << Uml::ID::toString(a->getObjectId(Uml::RoleType::A)) << ")";
+    }
+    return list;
+}
+
+/**
+ * Shorthand for getSpecificAssocs(Uml::at_Realization)
+ *
+ * @return  The list of realizations for the Concept.
+ */
+UMLAssociationList UMLCanvasObject::getRealizations()
+{
+    return getSpecificAssocs(Uml::AssociationType::Realization);
+}
+
+/**
+ * Shorthand for getSpecificAssocs(Uml::at_Aggregation)
+ *
+ * @return  The list of aggregations for the Concept.
+ */
+UMLAssociationList UMLCanvasObject::getAggregations()
+{
+    return getSpecificAssocs(Uml::AssociationType::Aggregation);
+}
+
+/**
+ * Shorthand for getSpecificAssocs(Uml::at_Composition)
+ *
+ * @return  The list of compositions for the Concept.
+ */
+UMLAssociationList UMLCanvasObject::getCompositions()
+{
+    return getSpecificAssocs(Uml::AssociationType::Composition);
+}
+
+/**
+ * Shorthand for getSpecificAssocs(Uml::at_Relationship)
+ *
+ * @return  The list of relationships for the entity.
+ */
+UMLAssociationList UMLCanvasObject::getRelationships()
+{
+    return getSpecificAssocs(Uml::AssociationType::Relationship);
+}
+
+/**
+ * Reimplementation of UMLObject method.
+ */
+bool UMLCanvasObject::resolveRef()
+{
+    bool overallSuccess = UMLObject::resolveRef();
+    for (UMLObjectListIt ait(m_List); ait.hasNext();) {
+        UMLObject *obj = ait.next();
+        uIgnoreZeroPointer(obj);
+        if (! obj->resolveRef()) {
+            m_List.removeAll(obj);
+            overallSuccess = false;
+        }
+    }
+    return overallSuccess;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlcanvasobject.h umbrello-15.08.1/umbrello/umlmodel/umlcanvasobject.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlcanvasobject.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlcanvasobject.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,108 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef CANVASOBJECT_H
+#define CANVASOBJECT_H
+
+#include "umlobject.h"
+#include "umlobjectlist.h"
+#include "umlclassifierlist.h"
+#include "umlassociationlist.h"
+
+/**
+ * This class contains the non-graphical information required for UMLObjects
+ * which appear as moveable widgets on the scene.
+ *
+ * This class inherits from @ref UMLObject which contains most of the
+ * information.
+ * It is not instantiated itself, it's just used as a super class for
+ * actual model objects.
+ *
+ * @short Non-graphical information for a UMLCanvasObject.
+ * @author Jonathan Riddell
+ * @see UMLObject
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLCanvasObject : public UMLObject
+{
+    Q_OBJECT
+
+public:
+    explicit UMLCanvasObject(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLCanvasObject();
+
+    bool operator==(const UMLCanvasObject& rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    // The abstract method UMLObject::clone() is implemented
+    // in the classes inheriting from UMLCanvasObject.
+
+    bool addAssociationEnd(UMLAssociation* assoc);
+
+    bool hasAssociation(UMLAssociation* assoc);
+
+    int removeAssociationEnd(UMLAssociation *assoc);
+
+    void removeAllAssociationEnds();
+
+    int associations();
+
+    UMLAssociationList getAssociations();
+
+    UMLAssociationList getSpecificAssocs(Uml::AssociationType::Enum assocType);
+
+    UMLClassifierList getSuperClasses(bool withRealizations = true);
+    UMLClassifierList getSubClasses();
+
+    virtual UMLAssociationList getRealizations();
+
+    UMLAssociationList getAggregations();
+    UMLAssociationList getCompositions();
+    UMLAssociationList getRelationships();
+
+    virtual UMLObject *findChildObject(const QString &n,
+                                       UMLObject::ObjectType t = UMLObject::ot_UMLObject);
+    virtual UMLObject *findChildObjectById(Uml::ID::Type id, bool considerAncestors = false);
+
+    virtual QString uniqChildName(const UMLObject::ObjectType type,
+                                  const QString &prefix = QString());
+
+    virtual void removeAllChildObjects();
+
+    UMLObjectList subordinates() const {
+        return m_List;
+    }
+
+    virtual bool resolveRef();
+
+    // The abstract method UMLObject::saveToXMI() is implemented
+    // in the classes inheriting from UMLCanvasObject.
+
+protected:
+
+    /**
+     * List of all the associations in this object.
+     * Inheriting classes add more types of objects that are possible in this list;
+     * for example, UMLClassifier adds operations, attributes, and templates.
+     *
+     * @todo Only a pointer to the appropriate assocation end object
+     *       (UMLRole) should be saved here, not the entire UMLAssociation.
+     */
+    UMLObjectList m_List;
+
+signals:
+
+    void sigAssociationEndAdded(UMLAssociation * assoc);
+    void sigAssociationEndRemoved(UMLAssociation * assoc);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlclassifierlist.h umbrello-15.08.1/umbrello/umlmodel/umlclassifierlist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlclassifierlist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlclassifierlist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,22 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2010                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLCLASSIFIERLIST_H
+#define UMLCLASSIFIERLIST_H
+
+#include <QList>
+
+// forward declaration
+class UMLClassifier;
+
+typedef QList<UMLClassifier*> UMLClassifierList;
+typedef QListIterator<UMLClassifier*> UMLClassifierListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlclassifierlistitemlist.cpp umbrello-15.08.1/umbrello/umlmodel/umlclassifierlistitemlist.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlclassifierlistitemlist.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlclassifierlistitemlist.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,60 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "umlclassifierlistitemlist.h"
+
+#include "classifierlistitem.h"
+
+#include <KLocalizedString>
+
+UMLClassifierListItemList::UMLClassifierListItemList()
+{
+}
+
+UMLClassifierListItemList::UMLClassifierListItemList(const UMLClassifierListItemList& other)
+  : QList<UMLClassifierListItem*>(other)
+{
+}
+
+UMLClassifierListItemList::~UMLClassifierListItemList()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLClassifierListItemList::copyInto(UMLClassifierListItemList *rhs) const
+{
+    // Prevent copying to yourself. (Can cause serious injuries)
+    if (rhs == this) return;
+
+    rhs->clear();
+
+    // Suffering from const; we shall not modify our object.
+    UMLClassifierListItemList *tmp = new UMLClassifierListItemList(*this);
+
+    UMLClassifierListItem *item;
+    for (UMLClassifierListItemListIt clit(*tmp); clit.hasNext() ;) {
+        item = clit.next();
+        rhs->append((UMLClassifierListItem*)item->clone());
+    }
+    delete tmp;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLClassifierListItemList* UMLClassifierListItemList::clone() const
+{
+    UMLClassifierListItemList *clone = new UMLClassifierListItemList();
+    copyInto(clone);
+    return clone;
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlclassifierlistitemlist.h umbrello-15.08.1/umbrello/umlmodel/umlclassifierlistitemlist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlclassifierlistitemlist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlclassifierlistitemlist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,41 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLCLASSIFIERLISTITEMLIST_H
+#define UMLCLASSIFIERLISTITEMLIST_H
+
+#include <QList>
+
+// forward declaration
+class UMLClassifierListItem;
+
+//typedef QPtrList<UMLClassifierListItem> UMLClassifierListItemList;
+typedef QListIterator<UMLClassifierListItem*> UMLClassifierListItemListIt;
+
+/**
+ * This sub-class adds copyInto and clone to the QPtrList<UMLClassifierListItem>
+ * base class.
+ */
+class UMLClassifierListItemList : public QList<UMLClassifierListItem*>
+{
+public:
+
+    UMLClassifierListItemList();
+    UMLClassifierListItemList(const UMLClassifierListItemList& other);
+
+    virtual ~UMLClassifierListItemList();
+
+    virtual void copyInto (UMLClassifierListItemList *rhs) const;
+
+    virtual UMLClassifierListItemList* clone() const;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlentityattributelist.cpp umbrello-15.08.1/umbrello/umlmodel/umlentityattributelist.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlentityattributelist.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlentityattributelist.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,60 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "umlentityattributelist.h"
+
+#include "entityattribute.h"
+
+#include <KLocalizedString>
+
+UMLEntityAttributeList::UMLEntityAttributeList()
+{
+}
+
+UMLEntityAttributeList::UMLEntityAttributeList(const UMLEntityAttributeList& other)
+  : QList<UMLEntityAttribute*>(other)
+{
+}
+
+UMLEntityAttributeList::~UMLEntityAttributeList()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLEntityAttributeList::copyInto(UMLEntityAttributeList* rhs) const
+{
+    // Don't copy yourself.
+    if (rhs == this) return;
+
+    rhs->clear();
+
+    // Suffering from const; we shall not modify our object.
+    UMLEntityAttributeList* tmp = new UMLEntityAttributeList(*this);
+
+    UMLEntityAttribute* item;
+    for (UMLEntityAttributeListIt eait(*tmp); eait.hasNext() ;) {
+        item = eait.next();
+        rhs->append((UMLEntityAttribute*)item->clone());
+    }
+    delete tmp;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLEntityAttributeList* UMLEntityAttributeList::clone() const
+{
+    UMLEntityAttributeList *clone = new UMLEntityAttributeList();
+    copyInto(clone);
+    return clone;
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlentityattributelist.h umbrello-15.08.1/umbrello/umlmodel/umlentityattributelist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlentityattributelist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlentityattributelist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,41 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLENTITYATTRIBUTELIST_H
+#define UMLENTITYATTRIBUTELIST_H
+
+#include <qlist.h>
+#include "entityattribute.h"
+
+//typedef QPtrList<UMLEntityAttribute> UMLEntityAttributeList;
+typedef QListIterator<UMLEntityAttribute*> UMLEntityAttributeListIt;
+
+/**
+ * This sub-class adds copyInto and clone to the QPtrList<UMLEntityAttribute>
+ * base class.
+ */
+class UMLEntityAttributeList : public QList<UMLEntityAttribute*>
+{
+public:
+
+    UMLEntityAttributeList();
+
+    UMLEntityAttributeList(const UMLEntityAttributeList&);
+
+    virtual ~UMLEntityAttributeList();
+
+    virtual void copyInto (UMLEntityAttributeList* rhs) const;
+
+    virtual UMLEntityAttributeList* clone() const;
+};
+
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlentityconstraintlist.cpp umbrello-15.08.1/umbrello/umlmodel/umlentityconstraintlist.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlentityconstraintlist.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlentityconstraintlist.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,60 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "umlentityconstraintlist.h"
+
+#include "entityconstraint.h"
+
+#include <KLocalizedString>
+
+UMLEntityConstraintList::UMLEntityConstraintList()
+{
+}
+
+UMLEntityConstraintList::UMLEntityConstraintList(const UMLEntityConstraintList& other)
+    : QList<UMLEntityConstraint*>(other)
+{
+}
+
+UMLEntityConstraintList::~UMLEntityConstraintList()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLEntityConstraintList::copyInto(UMLEntityConstraintList* rhs) const
+{
+    // Don't copy yourself.
+    if (rhs == this) return;
+
+    rhs->clear();
+
+    // Suffering from const; we shall not modify our object.
+    UMLEntityConstraintList* tmp = new UMLEntityConstraintList(*this);
+
+    UMLEntityConstraint* item;
+    for (UMLEntityConstraintListIt ecit(*tmp); ecit.hasNext() ;) {
+        item = ecit.next();
+        rhs->append((UMLEntityConstraint*)item->clone());
+    }
+    delete tmp;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLEntityConstraintList* UMLEntityConstraintList::clone() const
+{
+    UMLEntityConstraintList *clone = new UMLEntityConstraintList();
+    copyInto(clone);
+    return clone;
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlentityconstraintlist.h umbrello-15.08.1/umbrello/umlmodel/umlentityconstraintlist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlentityconstraintlist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlentityconstraintlist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,43 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLENTITYCONSTRAINTLIST_H
+#define UMLENTITYCONSTRAINTLIST_H
+
+#include <qlist.h>
+
+// forward declaration
+class UMLEntityConstraint;
+
+
+typedef QListIterator<UMLEntityConstraint*> UMLEntityConstraintListIt;
+
+/**
+ * This sub-class adds copyInto and clone to the QPtrList<UMLEntityConstraint>
+ * base class.
+ */
+class UMLEntityConstraintList : public QList<UMLEntityConstraint*>
+{
+public:
+
+    UMLEntityConstraintList();
+
+    UMLEntityConstraintList(const UMLEntityConstraintList&);
+
+    virtual ~UMLEntityConstraintList();
+
+    virtual void copyInto (UMLEntityConstraintList* rhs) const;
+
+    virtual UMLEntityConstraintList* clone() const;
+};
+
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlentitylist.h umbrello-15.08.1/umbrello/umlmodel/umlentitylist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlentitylist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlentitylist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,22 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2010                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLENTITYLIST_H
+#define UMLENTITYLIST_H
+
+#include <QList>
+
+// forward declaration
+class UMLEntity;
+
+typedef QList<UMLEntity*> UMLEntityList;
+typedef QListIterator<UMLEntity*> UMLEntityListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlenumliterallist.h umbrello-15.08.1/umbrello/umlmodel/umlenumliterallist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlenumliterallist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlenumliterallist.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2007                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLENUMLITERALLIST_H
+#define UMLENUMLITERALLIST_H
+
+#include <QList>
+
+// forward declaration
+class UMLEnumLiteral;
+
+typedef QList<UMLEnumLiteral*> UMLEnumLiteralList;
+typedef QListIterator<UMLEnumLiteral*> UMLEnumLiteralListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlobject.cpp umbrello-15.08.1/umbrello/umlmodel/umlobject.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlobject.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlobject.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,1157 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "umlobject.h"
+
+// app includes
+#include "classpropertiesdialog.h"
+#include "debug_utils.h"
+#include "enumliteral.h"
+#include "uniqueid.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umllistview.h"
+#include "package.h"
+#include "folder.h"
+#include "stereotype.h"
+#include "object_factory.h"
+#include "model_utils.h"
+#include "import_utils.h"
+#include "docwindow.h"
+#include "cmds.h"
+
+// kde includes
+#include <KLocalizedString>
+
+// qt includes
+#include <QApplication>
+#include <QPointer>
+
+using namespace Uml;
+
+DEBUG_REGISTER_DISABLED(UMLObject)
+
+/**
+ * Creates a UMLObject.
+ * @param other object to created from
+ */
+UMLObject::UMLObject(const UMLObject &other)
+  : QObject(other.parent())
+{
+    other.copyInto(this);
+}
+
+/**
+ * Creates a UMLObject.
+ * @param parent   The parent of the object.
+ * @param name     The name of the object.
+ * @param id       The ID of the object (optional.) If omitted
+ *                 then a new ID will be assigned internally.
+ */
+UMLObject::UMLObject(UMLObject* parent, const QString& name, ID::Type id)
+  : QObject(parent),
+    m_nId(id),
+    m_name(name)
+{
+    init();
+    if (id == Uml::ID::None)
+        m_nId = UniqueID::gen();
+}
+
+/**
+ * Creates a UMLObject.
+ * @param name     The name of the object.
+ * @param id       The ID of the object (optional.) If omitted
+ *                 then a new ID will be assigned internally.
+ */
+UMLObject::UMLObject(const QString& name, ID::Type id)
+  : QObject(UMLApp::app()->document()),
+    m_nId(id),
+    m_name(name)
+{
+    init();
+    if (id == Uml::ID::None)
+        m_nId = UniqueID::gen();
+}
+
+/**
+ * Creates a UMLObject.
+ * @param   parent   The parent of the object.
+ */
+UMLObject::UMLObject(UMLObject * parent)
+  : QObject(parent),
+    m_nId(Uml::ID::None),
+    m_name(QString())
+{
+    init();
+}
+
+/**
+ * Standard destructor.
+ */
+UMLObject::~UMLObject()
+{
+    // unref stereotype
+    setUMLStereotype(0);
+    if (m_pSecondary && m_pSecondary->baseType() == ot_Stereotype) {
+        UMLStereotype* stereotype = dynamic_cast<UMLStereotype*>(m_pSecondary.data());
+        if (stereotype)
+            stereotype->decrRefCount();
+    }
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLObject::init()
+{
+    setObjectName(QLatin1String("UMLObject"));
+    m_BaseType = ot_UMLObject;
+    m_pUMLPackage = 0;
+    m_visibility = Uml::Visibility::Public;
+    m_pStereotype = 0;
+    m_Doc.clear();
+    m_bAbstract = false;
+    m_bStatic = false;
+    m_bCreationWasSignalled = false;
+    m_pSecondary = 0;
+}
+
+/**
+ * Display the properties configuration dialog for the object.
+ *
+ * @param parent    The parent widget.
+ * @return  True for success of this operation.
+ */
+bool UMLObject::showPropertiesDialog(QWidget *parent)
+{
+    DocWindow *docwindow = UMLApp::app()->docWindow();
+    docwindow->updateDocumentation(false);
+    QPointer<ClassPropertiesDialog> dlg = new ClassPropertiesDialog(parent, this, false);
+    bool modified = false;
+    if (dlg->exec()) {
+        docwindow->showDocumentation(this, true);
+        UMLApp::app()->document()->setModified(true);
+        modified = true;
+    }
+    dlg->close();
+    delete dlg;
+    return modified;
+}
+
+/**
+ * This should be reimplemented by subclasses if they wish to
+ * accept certain types of associations. Note that this only
+ * tells if this UMLObject can accept the association
+ * type. When creating an association another check is made to
+ * see if the association is valid. For example a UMLClass
+ * (UMLClassifier) can accept generalizations and should
+ * return true. If while creating a generalization the
+ * superclass is already subclassed from this, the association
+ * is not valid and will not be created.  The default accepts
+ * nothing (returns false)
+ */
+bool UMLObject::acceptAssociationType(Uml::AssociationType::Enum type)
+{
+    Q_UNUSED(type);
+    // A UMLObject accepts nothing. This should be reimplemented by the subclasses
+    return false;
+}
+
+/**
+ * Assigns a new Id to the object
+ */
+void UMLObject::setID(ID::Type NewID)
+{
+    m_nId = NewID;
+    emitModified();
+}
+
+/**
+ * Set the UMLObject's name
+ */
+void UMLObject::setName(const QString &strName)
+{
+    if (name() != strName) {
+        UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(this, strName));
+    }
+}
+
+/**
+ * Method used by setName: it is called by  cmdSetName, Don't use it!
+ */
+void UMLObject::setNameCmd(const QString &strName)
+{
+    m_name = strName;
+    emitModified();
+}
+
+/**
+ * Returns a copy of m_name
+ */
+QString UMLObject::name() const
+{
+    return m_name;
+}
+
+/**
+ * Returns the fully qualified name, i.e. all package prefixes and then m_name.
+ *
+ * @param separator  The separator string to use (optional.)
+ *                   If not given then the separator is chosen according
+ *                   to the currently selected active programming language
+ *                   of import and code generation.
+ * @param includeRoot  Whether to prefix the root folder name to the FQN.
+ *                     See UMLDoc::getRootFolder(). Default: false.
+ * @return  The fully qualified name of this UMLObject.
+ */
+QString UMLObject::fullyQualifiedName(const QString& separator,
+        bool includeRoot /* = false */) const
+{
+    QString fqn;
+    if (m_pUMLPackage && m_pUMLPackage != this) {
+        bool skipPackage = false;
+        if (!includeRoot) {
+            UMLDoc *umldoc = UMLApp::app()->document();
+            if (umldoc->rootFolderType(m_pUMLPackage) != Uml::ModelType::N_MODELTYPES ||
+                    m_pUMLPackage == umldoc->datatypeFolder())
+                skipPackage = true;
+        }
+        if (!skipPackage) {
+            QString tempSeparator = separator;
+            if (tempSeparator.isEmpty())
+                tempSeparator = UMLApp::app()->activeLanguageScopeSeparator();
+            fqn = m_pUMLPackage->fullyQualifiedName(tempSeparator, includeRoot);
+            fqn.append(tempSeparator);
+        }
+    }
+    fqn.append(m_name);
+    return fqn;
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLObject::operator==(const UMLObject & rhs) const
+{
+    if (this == &rhs)
+        return true;
+
+    //don't compare IDs, these are program specific and
+    //don't mean the objects are the same
+    //***** CHECK: Who put in this comment? What was the reason?
+    //***** Currently some operator== in umbrello compare the IDs
+    //***** while others don't.
+
+    if (m_name != rhs.m_name)
+        return false;
+
+    // Packages create different namespaces, therefore they should be
+    // part of the equality test.
+    if (m_pUMLPackage != rhs.m_pUMLPackage)
+        return false;
+
+    // Making the type part of an object's identity has its problems:
+    // Not all programming languages support declarations of the same
+    // name but different type.
+    // In such cases, the code generator is responsible for generating
+    // the appropriate error message.
+    if (m_BaseType != rhs.m_BaseType)
+        return false;
+
+    // The documentation should not be part of the equality test.
+    // If two objects are the same but differ only in their documentation,
+    // what does that mean?
+    //if(m_Doc != rhs.m_Doc)
+    //  return false;
+
+    // The visibility should not be part of the equality test.
+    // What does it mean if two objects are the same but differ in their
+    // visibility? - I'm not aware of any programming language that would
+    // support that.
+    //if(m_visibility != rhs.m_visibility)
+    //  return false;
+
+    // See comments above
+    //if(m_pStereotype != rhs.m_pStereotype)
+    //  return false;
+
+    // See comments above
+    //if(m_bAbstract != rhs.m_bAbstract)
+    //  return false;
+
+    // See comments above
+    //if(m_bStatic != rhs.m_bStatic)
+    //  return false;
+
+    return true;
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLObject::copyInto(UMLObject *lhs) const
+{
+    // Data members with copy constructor
+    lhs->m_Doc = m_Doc;
+    lhs->m_pStereotype = m_pStereotype;
+    if (lhs->m_pStereotype)
+        lhs->m_pStereotype->incrRefCount();
+    lhs->m_bAbstract = m_bAbstract;
+    lhs->m_bStatic = m_bStatic;
+    lhs->m_BaseType = m_BaseType;
+    lhs->m_visibility = m_visibility;
+    lhs->m_pUMLPackage = m_pUMLPackage;
+
+    // We don't want the same name existing twice.
+    lhs->m_name = Model_Utils::uniqObjectName(m_BaseType, m_pUMLPackage, m_name);
+
+    // Create a new ID.
+    lhs->m_nId = UniqueID::gen();
+
+    // Hope that the parent from QObject is okay.
+    if (lhs->parent() != parent())
+        uDebug() << "copyInto has a wrong parent";
+}
+
+UMLObject *UMLObject::clone() const
+{
+    UMLObject *clone = new UMLObject;
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Returns the abstract state of the object.
+ */
+bool UMLObject::isAbstract() const
+{
+    return m_bAbstract;
+}
+
+/**
+ * Sets the paste state of the object.
+ */
+void UMLObject::setAbstract(bool bAbstract)
+{
+    m_bAbstract = bAbstract;
+    emitModified();
+}
+
+/**
+ * Returns true if this UMLObject has classifier scope,
+ * otherwise false (the default).
+ */
+bool UMLObject::isStatic() const
+{
+    return m_bStatic;
+}
+
+/**
+ * Sets the value for m_bStatic.
+ */
+void UMLObject::setStatic(bool bStatic)
+{
+    m_bStatic = bStatic;
+    emitModified();
+}
+
+/**
+ * Forces the emission of the modified signal.  Useful when
+ * updating several attributes at a time: you can block the
+ * signals, update all atts, and then force the signal.
+ */
+void UMLObject::emitModified()
+{
+    UMLDoc *umldoc = UMLApp::app()->document();
+    if (!umldoc->loading() && !umldoc->closing())
+        emit modified();
+}
+
+/**
+ * Returns the type of the object.
+ *
+ * @return  Returns the type of the object.
+ */
+UMLObject::ObjectType UMLObject::baseType() const
+{
+    return m_BaseType;
+}
+
+/**
+ * @return The type used for rtti as string.
+ */
+QLatin1String UMLObject::baseTypeStr() const
+{
+    return QLatin1String(ENUM_NAME(UMLObject, ObjectType, m_BaseType));
+}
+
+/**
+ * Set the type of the object.
+ *
+ * @param ot The ObjectType to set.
+ */
+void UMLObject::setBaseType(ObjectType ot)
+{
+    m_BaseType = ot;
+}
+
+/**
+ * Returns the ID of the object.
+ *
+ * @return  Returns the ID of the object.
+ */
+ID::Type UMLObject::id() const
+{
+    return m_nId;
+}
+
+/**
+ * Returns the documentation for the object.
+ *
+ * @return  Returns the documentation for the object.
+ */
+QString UMLObject::doc() const
+{
+    return m_Doc;
+}
+
+/**
+ * Returns state of documentation for the object.
+ *
+ * @return false if documentation is empty
+ */
+bool UMLObject::hasDoc() const
+{
+    return !m_Doc.isEmpty();
+}
+
+/**
+ * Sets the documentation for the object.
+ *
+ * @param d The documentation for the object.
+ */
+void UMLObject::setDoc(const QString &d)
+{
+    m_Doc = d;
+    //emit modified();  No, this is done centrally at DocWindow::updateDocumentation()
+}
+
+/**
+ * Returns the visibility of the object.
+ *
+ * @return  Returns the visibility of the object.
+ */
+Visibility::Enum UMLObject::visibility() const
+{
+    return m_visibility;
+}
+
+/**
+ * Sets the visibility of the object.
+ *
+ * @param visibility  The visibility of the object.
+ */
+void UMLObject::setVisibility(Visibility::Enum visibility)
+{
+    if (m_visibility != visibility) {
+        UMLApp::app()->executeCommand(new CmdSetVisibility(this, visibility));
+    }
+}
+
+/**
+ * Method used by setVisibility: it is called by  cmdSetVisibility, Don't use it!
+ */
+void UMLObject::setVisibilityCmd(Visibility::Enum visibility)
+{
+    m_visibility = visibility;
+    emitModified();
+}
+
+/**
+ * Sets the class' UMLStereotype. Adjusts the reference counts
+ * at the previously set stereotype and at the new stereotype.
+ * If the previously set UMLStereotype's reference count drops
+ * to zero then the UMLStereotype is removed at the UMLDoc and
+ * it is then physically deleted.
+ *
+ * @param stereo Sets the classes UMLStereotype.
+ */
+void UMLObject::setUMLStereotype(UMLStereotype *stereo)
+{
+    if (stereo == m_pStereotype)
+        return;
+    if (stereo) {
+        stereo->incrRefCount();
+    }
+    if (m_pStereotype) {
+        m_pStereotype->decrRefCount();
+        if (m_pStereotype->refCount() == 0) {
+            UMLDoc *pDoc = UMLApp::app()->document();
+            pDoc->removeStereotype(m_pStereotype);
+            delete m_pStereotype;
+        }
+    }
+    m_pStereotype = stereo;
+    // TODO: don't emit modified() if predefined folder
+    emitModified();
+}
+
+/**
+ * Sets the classes stereotype name.
+ * Internally uses setUMLStereotype().
+ *
+ * @param name     Sets the classes stereotype name.
+ */
+void UMLObject::setStereotype(const QString &name)
+{
+    if (name != stereotype()) {
+        UMLApp::app()->executeCommand(new CmdSetStereotype(this, name));
+    }
+}
+
+void UMLObject::setStereotypeCmd(const QString& name)
+{
+    if (name.isEmpty()) {
+        setUMLStereotype(NULL);
+        return;
+    }
+    UMLDoc *pDoc = UMLApp::app()->document();
+    UMLStereotype *s = pDoc->findOrCreateStereotype(name);
+    setUMLStereotype(s);
+}
+
+/**
+ * Sets the UMLPackage in which this class is located.
+ *
+ * @param pPkg   Pointer to the class' UMLPackage.
+ */
+bool UMLObject::setUMLPackage(UMLPackage* pPkg)
+{
+    if (pPkg == this) {
+        uDebug() << "setting parent to myself is not allowed";
+        return false;
+    }
+
+    if (pPkg == NULL) {
+        // Allow setting to NULL for stereotypes
+        m_pUMLPackage = pPkg;
+        return true;
+    }
+
+    if (pPkg->umlPackage() == this) {
+        uDebug() << "setting parent to an object of which I'm already the parent is not allowed";
+        return false;
+    }
+
+    m_pUMLPackage = pPkg;
+    emitModified();
+    return true;
+}
+
+/**
+ * Returns the classes UMLStereotype object.
+ *
+ * @return   Returns the classes UMLStereotype object.
+ */
+UMLStereotype * UMLObject::umlStereotype()
+{
+    return m_pStereotype;
+}
+
+/**
+ * Returns the stereotype.
+ */
+QString UMLObject::stereotype(bool includeAdornments /* = false */) const
+{
+    if (m_pStereotype == NULL)
+        return QString();
+    return m_pStereotype->name(includeAdornments);
+}
+
+/**
+ * Return the package(s) in which this UMLObject is contained
+ * as a text.
+ *
+ * @param separator Separator string for joining together the
+ *                  individual package prefixes (optional.)
+ *                  If no separator is given then the separator
+ *                  of the currently selected language is used.
+ * @param includeRoot  Whether to prefix the root folder name.
+ *                     Default: false.
+ * @return  The UMLObject's enclosing package(s) as a text.
+ */
+QString UMLObject::package(const QString& separator, bool includeRoot)
+{
+    QString tempSeparator = separator;
+    if (tempSeparator.isEmpty())
+        tempSeparator = UMLApp::app()->activeLanguageScopeSeparator();
+    QString fqn = fullyQualifiedName(tempSeparator, includeRoot);
+    if (!fqn.contains(tempSeparator))
+        return QString();
+    QString scope = fqn.left(fqn.length() - tempSeparator.length() - m_name.length());
+    return scope;
+}
+
+/**
+ * Return a list of the packages in which this class is embedded.
+ * The outermost package is first in the list.
+ *
+ * @param includeRoot  Whether to prefix the root folder name.
+ *                     Default: false.
+ * @return  UMLPackageList of the containing packages.
+ */
+UMLPackageList UMLObject::packages(bool includeRoot) const
+{
+    UMLPackageList pkgList;
+    UMLPackage* pkg = m_pUMLPackage;
+    while (pkg != NULL) {
+        pkgList.prepend(pkg);
+        pkg = pkg->umlPackage();
+    }
+    if (!includeRoot)
+        pkgList.removeFirst();
+    return pkgList;
+}
+
+/**
+ * Returns the UMLPackage that this class is located in.
+ *
+ * @return  Pointer to the UMLPackage of this class.
+ */
+UMLPackage* UMLObject::umlPackage()
+{
+    return m_pUMLPackage;
+}
+
+/**
+ * Return secondary ID. Required by resolveRef().
+ */
+QString UMLObject::secondaryId() const
+{
+    return m_SecondaryId;
+}
+
+/**
+ * Set the secondary ID.
+ * Currently only required by petalTree2Uml(); all other setting of the
+ * m_SecondaryID is internal to the UMLObject class hierarchy.
+ */
+void UMLObject::setSecondaryId(const QString& id)
+{
+    m_SecondaryId = id;
+}
+
+/**
+ * Return secondary ID fallback.
+ * Required by resolveRef() for imported model files.
+ */
+QString UMLObject::secondaryFallback() const
+{
+    return m_SecondaryFallback;
+}
+
+/**
+ * Set the secondary ID fallback.
+ * Currently only used by petalTree2Uml().
+ */
+void UMLObject::setSecondaryFallback(const QString& id)
+{
+    m_SecondaryFallback = id;
+}
+
+/**
+ * Calls UMLDoc::signalUMLObjectCreated() if m_BaseType affords
+ * doing so.
+ */
+void UMLObject::maybeSignalObjectCreated()
+{
+    if (!m_bCreationWasSignalled &&
+            m_BaseType != ot_Stereotype &&
+            m_BaseType != ot_Association &&
+            m_BaseType != ot_Role) {
+        m_bCreationWasSignalled = true;
+        UMLDoc* umldoc = UMLApp::app()->document();
+        umldoc->signalUMLObjectCreated(this);
+    }
+}
+
+/**
+ * Resolve referenced objects (if any.)
+ * Needs to be called after all UML objects are loaded from file.
+ * This needs to be done after all model objects are loaded because
+ * some of the xmi.id's might be forward references, i.e. they may
+ * identify model objects which were not yet loaded at the point of
+ * reference.
+ * The default implementation attempts resolution of the m_SecondaryId.
+ *
+ * @return   True for success.
+ */
+bool UMLObject::resolveRef()
+{
+    if (m_pSecondary || (m_SecondaryId.isEmpty() && m_SecondaryFallback.isEmpty())) {
+        maybeSignalObjectCreated();
+        return true;
+    }
+#ifdef VERBOSE_DEBUGGING
+    uDebug() << m_name << ": m_SecondaryId is " << m_SecondaryId;
+#endif
+    UMLDoc *pDoc = UMLApp::app()->document();
+    // In the new, XMI standard compliant save format,
+    // the type is the xmi.id of a UMLClassifier.
+    if (! m_SecondaryId.isEmpty()) {
+        m_pSecondary = pDoc->findObjectById(Uml::ID::fromString(m_SecondaryId));
+        if (m_pSecondary != NULL) {
+            if (m_pSecondary->baseType() == ot_Stereotype) {
+                if (m_pStereotype)
+                    m_pStereotype->decrRefCount();
+                m_pStereotype = dynamic_cast<UMLStereotype*>(m_pSecondary.data());
+                m_pStereotype->incrRefCount();
+                m_pSecondary = NULL;
+            }
+            m_SecondaryId = QString();
+            maybeSignalObjectCreated();
+            return true;
+        }
+        if (m_SecondaryFallback.isEmpty()) {
+            uDebug() << "object with xmi.id=" << m_SecondaryId << " not found, setting to undef";
+            UMLFolder *datatypes = pDoc->datatypeFolder();
+            m_pSecondary = Object_Factory::createUMLObject(ot_Datatype, QLatin1String("undef"), datatypes, false);
+            return true;
+        }
+    }
+    if (m_SecondaryFallback.isEmpty()) {
+        uError() << m_name << ": cannot find type with id " << m_SecondaryId;
+        return false;
+    }
+#ifdef VERBOSE_DEBUGGING
+    uDebug() << m_name << ": could not resolve secondary ID " << m_SecondaryId
+             << ", using secondary fallback " << m_SecondaryFallback;
+#endif
+    m_SecondaryId = m_SecondaryFallback;
+    // Assume we're dealing with the older Umbrello format where
+    // the type name was saved in the "type" attribute rather
+    // than the xmi.id of the model object of the attribute type.
+    m_pSecondary = pDoc->findUMLObject(m_SecondaryId, ot_UMLObject, this);
+    if (m_pSecondary) {
+        m_SecondaryId = QString();
+        maybeSignalObjectCreated();
+        return true;
+    }
+    // Work around Object_Factory::createUMLObject()'s incapability
+    // of on-the-fly scope creation:
+    if (m_SecondaryId.contains(QLatin1String("::"))) {
+        // TODO: Merge Import_Utils::createUMLObject() into Object_Factory::createUMLObject()
+        m_pSecondary = Import_Utils::createUMLObject(ot_UMLObject, m_SecondaryId, m_pUMLPackage);
+        if (m_pSecondary) {
+            if (Import_Utils::newUMLObjectWasCreated()) {
+                maybeSignalObjectCreated();
+                qApp->processEvents();
+                uDebug() << "Import_Utils::createUMLObject() created a new type for "
+                         << m_SecondaryId;
+            } else {
+                uDebug() << "Import_Utils::createUMLObject() returned an existing type for "
+                         << m_SecondaryId;
+            }
+            m_SecondaryId = QString();
+            return true;
+        }
+        uError() << "Import_Utils::createUMLObject() failed to create a new type for "
+                 << m_SecondaryId;
+        return false;
+    }
+    uDebug() << "Creating new type for " << m_SecondaryId;
+    // This is very C++ specific - we rely on  some '*' or
+    // '&' to decide it's a ref type. Plus, we don't recognize
+    // typedefs of ref types.
+    bool isReferenceType = (m_SecondaryId.contains(QLatin1Char('*')) ||
+                            m_SecondaryId.contains(QLatin1Char('&')));
+    ObjectType ot = ot_Class;
+    if (isReferenceType) {
+        ot = ot_Datatype;
+    } else {
+        if (Model_Utils::isCommonDataType(m_SecondaryId))
+            ot = ot_Datatype;
+    }
+    m_pSecondary = Object_Factory::createUMLObject(ot, m_SecondaryId, NULL);
+    if (m_pSecondary == NULL)
+        return false;
+    m_SecondaryId = QString();
+    maybeSignalObjectCreated();
+    //qApp->processEvents();
+    return true;
+}
+
+void UMLObject::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
+{
+    Q_UNUSED(qDoc); Q_UNUSED(qElement);
+}
+
+/**
+ * Auxiliary to saveToXMI.
+ * Create a QDomElement with the given tag, and save the XMI attributes
+ * that are common to all child classes to the newly created element.
+ * This method does not need to be overridden by child classes.
+ */
+QDomElement UMLObject::save(const QString &tag, QDomDocument & qDoc)
+{
+    /*
+      Call as the first action of saveToXMI() in child class:
+      This creates the QDomElement with which to work.
+    */
+    QDomElement qElement = qDoc.createElement(tag);
+    qElement.setAttribute(QLatin1String("isSpecification"), QLatin1String("false"));
+    if (m_BaseType != ot_Association &&
+        m_BaseType != ot_Role &&
+        m_BaseType != ot_Attribute) {
+        qElement.setAttribute(QLatin1String("isLeaf"), QLatin1String("false"));
+        qElement.setAttribute(QLatin1String("isRoot"), QLatin1String("false"));
+        if (m_bAbstract)
+            qElement.setAttribute(QLatin1String("isAbstract"), QLatin1String("true"));
+        else
+            qElement.setAttribute(QLatin1String("isAbstract"), QLatin1String("false"));
+    }
+    qElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(m_nId));
+    qElement.setAttribute(QLatin1String("name"), m_name);
+    if (m_BaseType != ot_Operation &&
+        m_BaseType != ot_Role &&
+        m_BaseType != ot_Attribute) {
+        Uml::ID::Type nmSpc;
+        if (m_pUMLPackage)
+            nmSpc = m_pUMLPackage->id();
+        else
+            nmSpc = UMLApp::app()->document()->modelID();
+        qElement.setAttribute(QLatin1String("namespace"), Uml::ID::toString(nmSpc));
+    }
+    if (! m_Doc.isEmpty())
+        qElement.setAttribute(QLatin1String("comment"), m_Doc);    //CHECK: uml13.dtd compliance
+#ifdef XMI_FLAT_PACKAGES
+    if (m_pUMLPackage)             //FIXME: uml13.dtd compliance
+        qElement.setAttribute(QLatin1String("package"), m_pUMLPackage->ID());
+#endif
+    QString visibility = Uml::Visibility::toString(m_visibility, false);
+    qElement.setAttribute(QLatin1String("visibility"), visibility);
+    if (m_pStereotype != NULL)
+        qElement.setAttribute(QLatin1String("stereotype"), Uml::ID::toString(m_pStereotype->id()));
+    if (m_bStatic)
+        qElement.setAttribute(QLatin1String("ownerScope"), QLatin1String("classifier"));
+    /* else
+        qElement.setAttribute("ownerScope", "instance");
+     *** ownerScope defaults to instance if not set **********/
+    return qElement;
+}
+
+/**
+ * Auxiliary to loadFromXMI.
+ * This method is usually overridden by child classes.
+ * It is responsible for loading the specific XMI structure
+ * of the child class.
+ */
+bool UMLObject::load(QDomElement&)
+{
+    // This body is not usually executed because child classes
+    // overwrite the load method.
+    return true;
+}
+
+/**
+ * Analyzes the given QDomElement for a reference to a stereotype.
+ *
+ * @param element   QDomElement to analyze.
+ * @return          True if a stereotype reference was found, else false.
+ */
+bool UMLObject::loadStereotype(QDomElement & element)
+{
+    QString tag = element.tagName();
+    if (!UMLDoc::tagEq(tag, QLatin1String("stereotype")))
+        return false;
+    QString stereo = element.attribute(QLatin1String("xmi.value"));
+    if (stereo.isEmpty() && element.hasChildNodes()) {
+        /* like so:
+         <UML:ModelElement.stereotype>
+           <UML:Stereotype xmi.idref = '07CD'/>
+         </UML:ModelElement.stereotype>
+         */
+        QDomNode stereoNode = element.firstChild();
+        QDomElement stereoElem = stereoNode.toElement();
+        tag = stereoElem.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("Stereotype"))) {
+            stereo = stereoElem.attribute(QLatin1String("xmi.idref"));
+        }
+    }
+    if (stereo.isEmpty())
+        return false;
+    Uml::ID::Type stereoID = Uml::ID::fromString(stereo);
+    UMLDoc *pDoc = UMLApp::app()->document();
+    if (m_pStereotype)
+        m_pStereotype->decrRefCount();
+    m_pStereotype = pDoc->findStereotypeById(stereoID);
+    if (m_pStereotype)
+        m_pStereotype->incrRefCount();
+    else
+        m_SecondaryId = stereo;  // leave it to resolveRef()
+    return true;
+}
+
+/**
+ * This method loads the generic parts of the XMI common to most model
+ * classes.  It is not usually reimplemented by child classes.
+ * Instead, it invokes the load() method which implements the loading
+ * of the specifics of each child class.
+ *
+ * @param element   The QDomElement from which to load.
+ */
+bool UMLObject::loadFromXMI(QDomElement & element)
+{
+    UMLDoc* umldoc = UMLApp::app()->document();
+    if (umldoc == 0) {
+        uError() << "umldoc is NULL";
+        return false;
+    }
+    // Read the name first so that if we encounter a problem, the error
+    // message can say the name.
+    m_name = element.attribute(QLatin1String("name"));
+    QString id = Model_Utils::getXmiId(element);
+    if (id.isEmpty() || id == QLatin1String("-1")) {
+        // Before version 1.4, Umbrello did not save the xmi.id of UMLRole objects.
+        // Some tools (such as Embarcadero's) do not have an xmi.id on all attributes.
+        m_nId = UniqueID::gen();
+        uWarning() << m_name << ": xmi.id not present, generating a new one";
+    } else {
+        Uml::ID::Type nId = Uml::ID::fromString(id);
+        if (m_BaseType == ot_Role) {
+            // Some older Umbrello versions had a problem with xmi.id's
+            // of other objects being reused for the UMLRole, see e.g.
+            // attachment 21179 at http://bugs.kde.org/147988 .
+            // If the xmi.id is already being used then we generate a new one.
+            UMLObject *o = umldoc->findObjectById(nId);
+            if (o) {
+                uError() << "loadFromXMI(UMLRole): id " << id
+                         << " is already in use!!! Please fix your XMI file.";
+            }
+        }
+        m_nId = nId;
+    }
+
+    if (element.hasAttribute(QLatin1String("documentation")))  // for bkwd compat.
+        m_Doc = element.attribute(QLatin1String("documentation"));
+    else
+        m_Doc = element.attribute(QLatin1String("comment"));    //CHECK: need a UML:Comment?
+
+    m_visibility = Uml::Visibility::Public;
+    if (element.hasAttribute(QLatin1String("scope"))) {        // for bkwd compat.
+        QString scope = element.attribute(QLatin1String("scope"));
+        if (scope == QLatin1String("instance_level"))         // nsuml compat.
+            m_bStatic = false;
+        else if (scope == QLatin1String("classifier_level"))  // nsuml compat.
+            m_bStatic = true;
+        else {
+            int nScope = scope.toInt();
+            switch (nScope) {
+            case 200:
+                m_visibility = Uml::Visibility::Public;
+                break;
+            case 201:
+                m_visibility = Uml::Visibility::Private;
+                break;
+            case 202:
+                m_visibility = Uml::Visibility::Protected;
+                break;
+            default:
+                uError() << m_name << ": illegal scope " << nScope;
+            }
+        }
+    } else {
+        QString visibility = element.attribute(QLatin1String("visibility"), QLatin1String("public"));
+        if (visibility == QLatin1String("private")
+                || visibility == QLatin1String("private_vis"))    // for compatibility with other programs
+            m_visibility = Uml::Visibility::Private;
+        else if (visibility == QLatin1String("protected")
+                 || visibility == QLatin1String("protected_vis"))  // for compatibility with other programs
+            m_visibility = Uml::Visibility::Protected;
+        else if (visibility == QLatin1String("implementation"))
+            m_visibility = Uml::Visibility::Implementation;
+    }
+
+    QString stereo = element.attribute(QLatin1String("stereotype"));
+    if (!stereo.isEmpty()) {
+        Uml::ID::Type stereoID = Uml::ID::fromString(stereo);
+        if (m_pStereotype)
+            m_pStereotype->decrRefCount();
+        m_pStereotype = umldoc->findStereotypeById(stereoID);
+        if (m_pStereotype) {
+            m_pStereotype->incrRefCount();
+        } else {
+            uDebug() << m_name << ": UMLStereotype " << Uml::ID::toString(stereoID)
+                     << " not found, creating now.";
+            setStereotypeCmd(stereo);
+        }
+    }
+
+    if (element.hasAttribute(QLatin1String("abstract"))) {      // for bkwd compat.
+        QString abstract = element.attribute(QLatin1String("abstract"), QLatin1String("0"));
+        m_bAbstract = (bool)abstract.toInt();
+    } else {
+        QString isAbstract = element.attribute(QLatin1String("isAbstract"), QLatin1String("false"));
+        m_bAbstract = (isAbstract == QLatin1String("true"));
+    }
+
+    if (element.hasAttribute(QLatin1String("static"))) {        // for bkwd compat.
+        QString staticScope = element.attribute(QLatin1String("static"), QLatin1String("0"));
+        m_bStatic = (bool)staticScope.toInt();
+    } else {
+        QString ownerScope = element.attribute(QLatin1String("ownerScope"), QLatin1String("instance"));
+        m_bStatic = (ownerScope == QLatin1String("classifier"));
+    }
+
+    // If the node has child nodes, check whether attributes can be
+    // extracted from them.
+    if (element.hasChildNodes()) {
+        QDomNode node = element.firstChild();
+        if (node.isComment())
+            node = node.nextSibling();
+        QDomElement elem = node.toElement();
+        while (!elem.isNull()) {
+            QString tag = elem.tagName();
+            if (UMLDoc::tagEq(tag, QLatin1String("name"))) {
+                m_name = elem.attribute(QLatin1String("xmi.value"));
+                if (m_name.isEmpty())
+                    m_name = elem.text();
+            } else if (UMLDoc::tagEq(tag, QLatin1String("visibility"))) {
+                QString vis = elem.attribute(QLatin1String("xmi.value"));
+                if (vis.isEmpty())
+                    vis = elem.text();
+                if (vis == QLatin1String("private") || vis == QLatin1String("private_vis"))
+                    m_visibility = Uml::Visibility::Private;
+                else if (vis == QLatin1String("protected") || vis == QLatin1String("protected_vis"))
+                    m_visibility = Uml::Visibility::Protected;
+                else if (vis == QLatin1String("implementation"))
+                    m_visibility = Uml::Visibility::Implementation;
+            } else if (UMLDoc::tagEq(tag, QLatin1String("isAbstract"))) {
+                QString isAbstract = elem.attribute(QLatin1String("xmi.value"));
+                if (isAbstract.isEmpty())
+                    isAbstract = elem.text();
+                m_bAbstract = (isAbstract == QLatin1String("true"));
+            } else if (UMLDoc::tagEq(tag, QLatin1String("ownerScope"))) {
+                QString ownerScope = elem.attribute(QLatin1String("xmi.value"));
+                if (ownerScope.isEmpty())
+                    ownerScope = elem.text();
+                m_bStatic = (ownerScope == QLatin1String("classifier"));
+            } else {
+                loadStereotype(elem);
+            }
+            node = node.nextSibling();
+            if (node.isComment())
+                node = node.nextSibling();
+            elem = node.toElement();
+        }
+    }
+
+    // Operations, attributes, enum literals, templates, stereotypes,
+    // and association role objects get added and signaled elsewhere.
+    if (m_BaseType != ot_Operation && m_BaseType != ot_Attribute &&
+        m_BaseType != ot_EnumLiteral && m_BaseType != ot_EntityAttribute &&
+        m_BaseType != ot_Template && m_BaseType != ot_Stereotype &&
+        m_BaseType != ot_Role && m_BaseType != ot_UniqueConstraint &&
+        m_BaseType != ot_ForeignKeyConstraint && m_BaseType != ot_CheckConstraint) {
+        if (m_pUMLPackage) {
+            m_pUMLPackage->addObject(this);
+        } else if (umldoc->rootFolderType(this) == Uml::ModelType::N_MODELTYPES) {
+            // m_pUMLPackage is not set on the root folders.
+            uDebug() << m_name << ": m_pUMLPackage is not set";
+        }
+    }
+    return load(element);
+}
+
+/**
+ * Helper function for debug output.
+ * Returns the given enum value as string.
+ * @param ot   ObjectType of which a string representation is wanted
+ * @return   the ObjectType as string
+ */
+QString UMLObject::toString(ObjectType ot)
+{
+    return QLatin1String(ENUM_NAME(UMLObject, ObjectType, ot));
+}
+
+/**
+ * Returns the given object type value as localized string.
+ * @param ot   ObjectType of which a string representation is wanted
+ * @return   the ObjectType as localized string
+ */
+QString UMLObject::toI18nString(ObjectType t)
+{
+    QString name;
+
+    switch (t) {
+    case UMLObject::ot_Actor:
+        name = i18n("Actor &name:");
+        break;
+    case  UMLObject::ot_Artifact:
+        name = i18n("Artifact &name:");
+        break;
+    case UMLObject::ot_Class:
+        name = i18n("Class &name:");
+        break;
+    case  UMLObject::ot_Component:
+        name = i18n("Component &name:");
+        break;
+    case  UMLObject::ot_Datatype:
+        name = i18n("Datatype &name:");
+        break;
+    case  UMLObject::ot_Entity:
+        name = i18n("Entity &name:");
+        break;
+    case  UMLObject::ot_Enum:
+        name = i18n("Enum &name:");
+        break;
+    case  UMLObject::ot_Folder:
+        name = i18n("Folder &name:");
+        break;
+    case  UMLObject::ot_Interface:
+        name = i18n("Interface &name:");
+        break;
+    case  UMLObject::ot_Node:
+        name = i18n("Node &name:");
+        break;
+    case  UMLObject::ot_Package:
+        name = i18n("Package &name:");
+        break;
+    case  UMLObject::ot_Port:
+        name = i18n("Port &name:");
+        break;
+    case  UMLObject::ot_Stereotype:
+        name = i18n("Stereotype &name:");
+        break;
+    case  UMLObject::ot_UseCase:
+        name = i18n("Use case &name:");
+        break;
+    default:
+        name = QLatin1String("<unknown> &name:");
+        uWarning() << "unknown object type";
+        break;
+    }
+    return name;
+}
+
+/**
+ * Print UML Object to debug output stream, so it can be used like
+ *   uDebug() << "This object shouldn't be here: " << illegalObject;
+ */
+QDebug operator<<(QDebug out, const UMLObject& obj)
+{
+    out.nospace() << "UMLObject: name= " << obj.name()
+        << ", type= " << UMLObject::toString(obj.m_BaseType);
+    return out.space();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlobject.h umbrello-15.08.1/umbrello/umlmodel/umlobject.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlobject.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlobject.h	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,198 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLOBJECT_H
+#define UMLOBJECT_H
+
+#include "basictypes.h"
+#include "umlpackagelist.h"
+
+//qt includes
+#include <QDomDocument>
+#include <QDomElement>
+#include <QObject>
+#include <QPointer>
+#include <QString>
+
+class UMLStereotype;
+
+/**
+ * This class is the non-graphical version of @ref UMLWidget.  These are
+ * created and maintained in the class @ref UMLDoc.  This class holds all
+ * the generic information needed for all UML objects.
+ *
+ * @ref clone needs to be implemented by each child class.
+ *
+ * @ref saveToXMI saves the XMI attributes of each specific model class.
+ * It needs to be implemented by each child class.
+ * For creating the QDomElement and saving the common XMI parts,
+ * it can use the save() method.
+ *
+ * @short The base class for UML objects.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLObject : public QObject
+{
+    Q_OBJECT
+    Q_ENUMS(ObjectType)
+
+public:
+    enum ObjectType
+    {
+        ot_Unknown = -1,
+        ot_UMLObject  = 100,
+        ot_Actor,
+        ot_UseCase,
+        ot_Package,
+        ot_Interface,
+        ot_Datatype,
+        ot_Enum,
+        ot_Class,
+        ot_Association,
+        ot_Attribute,
+        ot_Operation,
+        ot_EnumLiteral,
+        ot_Template,
+        ot_Component,
+        ot_Artifact,
+        ot_Node,
+        ot_Stereotype,
+        ot_Role,
+        ot_Entity,
+        ot_EntityAttribute,
+        ot_Folder,
+        ot_EntityConstraint,
+        ot_UniqueConstraint,
+        ot_ForeignKeyConstraint,
+        ot_CheckConstraint,
+        ot_Category,
+        ot_Port
+    };
+
+    static QString toString(ObjectType ot);
+    static QString toI18nString(ObjectType t);
+
+    explicit UMLObject(const UMLObject& other);
+    explicit UMLObject(UMLObject* parent, const QString& name, Uml::ID::Type id = Uml::ID::None);
+    explicit UMLObject(UMLObject* parent);
+    explicit UMLObject(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLObject();
+
+    bool operator==(const UMLObject & rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    virtual void setBaseType(ObjectType ot);
+    ObjectType baseType() const;
+    QLatin1String baseTypeStr() const;
+
+    virtual void setID(Uml::ID::Type NewID);
+    virtual Uml::ID::Type id() const;
+
+    QString doc() const;
+    bool hasDoc() const;
+    void setDoc(const QString &d);
+
+    void setVisibility(Uml::Visibility::Enum visibility);
+    void setVisibilityCmd(Uml::Visibility::Enum visibility);
+    Uml::Visibility::Enum visibility() const;
+
+    void setStereotype(const QString &_name);
+    void setStereotypeCmd(const QString &_name);
+    QString stereotype(bool includeAdornments = false) const;
+
+    void setUMLStereotype(UMLStereotype *stereo);
+    UMLStereotype *umlStereotype();
+
+    QString package(const QString& separator = QString(),
+                    bool includeRoot = false);
+
+    bool setUMLPackage(UMLPackage* pPkg);
+    UMLPackage* umlPackage();
+
+    UMLPackageList packages(bool includeRoot = false) const;
+
+    virtual void setName(const QString &strName);
+    void setNameCmd(const QString &strName) ;
+    QString name() const;
+
+    virtual QString fullyQualifiedName(const QString& separator = QString(),
+                                       bool includeRoot = false) const;
+
+    void setAbstract(bool bAbstract);
+    bool isAbstract() const;
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+    virtual bool resolveRef();
+
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+    virtual bool loadFromXMI(QDomElement & element);
+
+    bool loadStereotype(QDomElement & element);
+
+    void setStatic(bool bStatic);
+    bool isStatic() const;
+
+    virtual bool acceptAssociationType(Uml::AssociationType::Enum);  //:TODO: check if this is really needed here
+
+    void setSecondaryId(const QString& id);
+    QString secondaryId() const;
+
+    void setSecondaryFallback(const QString& id);
+    QString secondaryFallback() const;
+
+    QDomElement save(const QString &tag, QDomDocument & qDoc);
+
+    friend QDebug operator<< (QDebug out, const UMLObject& obj);
+
+public slots:
+    void emitModified();
+
+signals:
+    void modified();
+
+protected:
+    void init();
+
+    void maybeSignalObjectCreated();
+
+    virtual bool load(QDomElement& element);
+
+    Uml::ID::Type          m_nId;          ///< object's id
+    QString                m_Doc;          ///< object's documentation
+    UMLPackage*            m_pUMLPackage;  ///< package the object belongs to if applicable
+    QPointer<UMLStereotype> m_pStereotype;  ///< stereotype of the object if applicable
+    QString                m_name;         ///< objects name
+    ObjectType             m_BaseType;     ///< objects type
+    Uml::Visibility::Enum  m_visibility;   ///< objects visibility
+    bool                   m_bAbstract;    ///< state of whether the object is abstract or not
+    bool                   m_bStatic;      ///< flag for instance scope
+    bool                   m_bInPaste;     ///< caller sets this true when in paste operation
+    bool        m_bCreationWasSignalled;   ///< auxiliary to maybeSignalObjectCreated()
+    QPointer<UMLObject>    m_pSecondary;   ///< pointer to an associated object
+                                           ///< Only a few of the classes inheriting from UMLObject use this.
+                                           ///< However, it needs to be here because of inheritance graph
+                                           ///< disjunctness.
+    QString                m_SecondaryId;  ///< xmi.id of the secondary object for intermediate use during
+                                           ///< loading. The secondary ID is resolved to the m_pSecondary
+                                           ///< in the course of resolveRef() at the end of loading.
+    QString           m_SecondaryFallback; ///< Last-chance backup for when m_SecondaryId is not found.
+                                           ///< Used by Rose import: MDL files specify both a "quidu"
+                                           ///< (which corresponds to m_SecondaryId) and the human readable
+                                           ///< fully qualified target name of a reference.
+                                           ///< In case the quidu is not found, the human readable name is
+                                           ///< used which we store in m_SecondaryFallback.
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlobjectlist.cpp umbrello-15.08.1/umbrello/umlmodel/umlobjectlist.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlobjectlist.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlobjectlist.cpp	2015-10-08 11:48:59.507089026 +0300
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "umlobjectlist.h"
+#include "umlobject.h"
+
+UMLObjectList::UMLObjectList()
+{
+}
+
+UMLObjectList::~UMLObjectList()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the new
+ * object.
+ */
+void UMLObjectList::copyInto(UMLObjectList *rhs) const
+{
+    // Don't copy yourself.
+    if (rhs == this) return;
+
+    rhs->clear();
+
+    // Suffering from const; we shall not modify our object.
+    UMLObjectList *tmp = new UMLObjectList(*this);
+
+    UMLObject *item = NULL;
+    for (UMLObjectListIt oit(*tmp); oit.hasNext() ;)
+    {
+        item = oit.next();
+        rhs->append(item->clone());
+    }
+    delete tmp;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObjectList* UMLObjectList::clone() const
+{
+    UMLObjectList *clone = new UMLObjectList();
+    copyInto(clone);
+    return clone;
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlobjectlist.h umbrello-15.08.1/umbrello/umlmodel/umlobjectlist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlobjectlist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlobjectlist.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,40 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2001      Gustavo Madrigal gmadrigal@nextphere.com      *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLOBJECTLIST_H
+#define UMLOBJECTLIST_H
+
+#include <QList>
+#include <QPointer>
+
+// forward declarations
+class UMLObject;
+
+typedef QListIterator<QPointer<UMLObject> >
+UMLObjectListIt;
+
+/**
+ * This sub-class adds copyInto and clone to the QList<UMLObject*>
+ * base class.
+ */
+class UMLObjectList : public QList<QPointer<UMLObject> >
+{
+public:
+
+    UMLObjectList();
+    virtual ~UMLObjectList();
+
+    virtual void copyInto(UMLObjectList *rhs) const;
+
+    virtual UMLObjectList* clone() const;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umloperationlist.h umbrello-15.08.1/umbrello/umlmodel/umloperationlist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umloperationlist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umloperationlist.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2007                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLOPERATIONLIST_H
+#define UMLOPERATIONLIST_H
+
+#include <qlist.h>
+
+// forward declaration
+class UMLOperation;
+
+typedef QList<UMLOperation*> UMLOperationList;
+typedef QListIterator<UMLOperation*> UMLOperationListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlpackagelist.h umbrello-15.08.1/umbrello/umlmodel/umlpackagelist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlpackagelist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlpackagelist.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,22 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2007                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLPACKAGELIST_H
+#define UMLPACKAGELIST_H
+
+#include <qlist.h>
+
+class UMLPackage;
+
+typedef QList<UMLPackage*> UMLPackageList;
+typedef QListIterator<UMLPackage*> UMLPackageListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlrole.cpp umbrello-15.08.1/umbrello/umlmodel/umlrole.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlrole.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlrole.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,415 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "umlrole.h"
+
+// local includes
+#include "association.h"
+#include "debug_utils.h"
+#include "umldoc.h"
+#include "umlroledialog.h"
+#include "uml.h"
+
+// qt includes
+#include <QPointer>
+#include <QRegExp>
+
+/**
+ * Sets up an association.
+ *
+ * @param parent     The parent (association) of this UMLRole.
+ * @param parentObj  The Parent UML Object of this UMLRole
+ * @param role       The Uml::RoleType::Enum of this UMLRole
+ */
+UMLRole::UMLRole(UMLAssociation * parent, UMLObject * parentObj, Uml::RoleType::Enum role)
+  : UMLObject(const_cast<UMLAssociation*>(parent)),
+    m_pAssoc(parent),
+    m_role(role),
+    m_Multi(QString()),
+    m_Changeability(Uml::Changeability::Changeable)
+{
+    m_BaseType = UMLObject::ot_Role;
+    m_name.clear();
+    m_pSecondary = parentObj;
+
+    // connect this up to parent
+    connect(this, SIGNAL(modified()), parent, SIGNAL(modified()));
+}
+
+/**
+ * Standard destructor.
+ */
+UMLRole::~UMLRole()
+{
+}
+
+/**
+ * Overloaded '==' operator.
+ */
+bool UMLRole::operator==(const UMLRole &rhs) const
+{
+    if (this == &rhs) {
+        return true;
+    }
+    return (UMLObject::operator==(rhs) &&
+             m_Changeability == rhs.m_Changeability &&
+             m_Multi == rhs.m_Multi &&
+             m_name == rhs.m_name
+          );
+}
+
+UMLAssociation * UMLRole::parentAssociation() const
+{
+    return m_pAssoc;
+}
+
+/**
+ * Returns the UMLObject assigned to the role.
+ * @return  Pointer to the UMLObject in role.
+ */
+UMLObject* UMLRole::object() const
+{
+    return m_pSecondary;
+}
+
+/**
+ * Returns the Changeablity of the role.
+ *
+ * @return  Changeability of role.
+ */
+Uml::Changeability::Enum UMLRole::changeability() const
+{
+    return m_Changeability;
+}
+
+/**
+ * Returns the multiplicity assigned to the role.
+ *
+ * @return  The multiplicity assigned to the role.
+ */
+QString UMLRole::multiplicity() const
+{
+    return m_Multi;
+}
+
+/**
+ * Sets the UMLObject playing the role in the association.
+ *
+ * @param obj   Pointer to the UMLObject of role.
+ */
+void UMLRole::setObject(UMLObject *obj)
+{
+    // because we will get the id of this role from the parent
+    // object, we CANT allow UMLRoles to take other UMLRoles as
+    // parent objects. In fact, there is probably good reason
+    // to only take UMLClassifiers here, but I'll leave it more open
+    // for the time being. -b.t.
+    if (obj && dynamic_cast<UMLRole*>(obj)) {
+        uError() << "UMLRole(" << Uml::ID::toString(m_nId) << ") cannot setObject() to another UMLRole("
+            << Uml::ID::toString(obj->id()) << ")";
+        return;
+    }
+
+    m_pSecondary = obj;
+    UMLObject::emitModified();
+}
+
+/**
+ * Sets the changeability of the role.
+ *
+ * @param value   Changeability::Enum of role.
+ */
+void UMLRole::setChangeability(Uml::Changeability::Enum value)
+{
+    m_Changeability = value;
+    UMLObject::emitModified();
+}
+
+/**
+ * Sets the multiplicity of the role.
+ *
+ * @param multi   The multiplicity of role.
+ */
+void UMLRole::setMultiplicity(const QString &multi)
+{
+    m_Multi = multi;
+    UMLObject::emitModified();
+}
+
+/**
+ * Get the 'id' of the role (NOT the parent object). This could be
+ * either Uml::RoleType::A or Uml::RoleType::B. Yes, it would be better if we
+ * could get along without this, but we need it to distinguish saved
+ * umlrole objects in the XMI for 'self' associations where both roles
+ * will point to the same underlying UMLObject.
+ */
+Uml::RoleType::Enum UMLRole::role() const
+{
+    return m_role;
+}
+
+/**
+ * Creates the <UML:AssociationEnd> XMI element.
+ */
+void UMLRole::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement roleElement = UMLObject::save(QLatin1String("UML:AssociationEnd"), qDoc);
+    if (m_pSecondary)
+        roleElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
+    else
+        uError() << "id " << Uml::ID::toString(m_nId) << ": m_pSecondary is NULL";
+    if (!m_Multi.isEmpty())
+        roleElement.setAttribute(QLatin1String("multiplicity"), m_Multi);
+    if (m_role == Uml::RoleType::A) {  // role aggregation based on parent type
+        // role A
+        switch (m_pAssoc->getAssocType()) {
+        case Uml::AssociationType::Composition:
+            roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("composite"));
+            break;
+        case Uml::AssociationType::Aggregation:
+            roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("aggregate"));
+            break;
+        default:
+            roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("none"));
+            break;
+        }
+        if (m_pAssoc->getAssocType() == Uml::AssociationType::UniAssociation) {
+            // Normally the isNavigable attribute is "true".
+            // We set it to false on role A to indicate that
+            // role B gets an explicit arrowhead.
+            roleElement.setAttribute(QLatin1String("isNavigable"), QLatin1String("false"));
+        } else {
+            roleElement.setAttribute(QLatin1String("isNavigable"), QLatin1String("true"));
+        }
+    } else {
+        roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("none"));
+        roleElement.setAttribute(QLatin1String("isNavigable"), QLatin1String("true"));
+        //FIXME obviously this isn't standard XMI
+        if (m_pAssoc->getAssocType() == Uml::AssociationType::Relationship) {
+            roleElement.setAttribute(QLatin1String("relationship"), QLatin1String("true"));
+        }
+    }
+
+    roleElement.setAttribute(QLatin1String("visibility"), Uml::Visibility::toString(visibility(), false));
+
+    switch (m_Changeability) {
+        case Uml::Changeability::Frozen:
+            roleElement.setAttribute(QLatin1String("changeability"), QLatin1String("frozen"));
+            break;
+        case Uml::Changeability::AddOnly:
+            roleElement.setAttribute(QLatin1String("changeability"), QLatin1String("addOnly"));
+            break;
+        case Uml::Changeability::Changeable:
+            roleElement.setAttribute(QLatin1String("changeability"), QLatin1String("changeable"));
+            break;
+    }
+    qElement.appendChild(roleElement);
+}
+
+/**
+ * Display the properties configuration dialog for the object.
+ *
+ * @param parent    The parent widget.
+ * @return  True for success of this operation.
+ */
+bool UMLRole::showPropertiesDialog(QWidget *parent)
+{
+    QPointer<UMLRoleDialog> dlg = new UMLRoleDialog(parent, this);
+    bool modified = false;
+    if (dlg->exec() == QDialog::Accepted) {
+        modified = true;
+    }
+    delete dlg;
+    return modified;
+}
+
+/**
+ * Loads the <UML:AssociationEnd> XMI element.
+ * Auxiliary to UMLObject::loadFromXMI.
+ */
+bool UMLRole::load(QDomElement & element)
+{
+    UMLDoc * doc = UMLApp::app()->document();
+    QString type = element.attribute(QLatin1String("type"));
+    if (!type.isEmpty()) {
+        if (!m_SecondaryId.isEmpty())
+            uWarning() << "overwriting old m_SecondaryId \"" << m_SecondaryId
+                << " with new value \"" << type << "\"";
+        m_SecondaryId = type;
+    }
+    // Inspect child nodes - for multiplicity (and type if not set above.)
+    for (QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling()) {
+        if (node.isComment())
+            continue;
+        QDomElement tempElement = node.toElement();
+        QString tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("name"))) {
+            m_name = tempElement.text();
+        } else if (UMLDoc::tagEq(tag, QLatin1String("AssociationEnd.multiplicity"))) {
+            /*
+             * There are different ways in which the multiplicity might be given:
+             *  - direct value in the <AssociationEnd.multiplicity> tag,
+             *  - attributes "lower" and "upper" of a subordinate <MultiplicityRange>,
+             *  - direct value in subordinate <MultiplicityRange.lower> and
+             *    <MultiplicityRange.upper> tags
+             */
+            QDomNode n = tempElement.firstChild();
+            if (node.isNull() || tempElement.isNull() || n.isNull() ||
+                    n.toElement().isNull()) {
+                m_Multi = tempElement.text().trimmed();
+                continue;
+            }
+            tempElement = n.toElement();
+            tag = tempElement.tagName();
+            if (!UMLDoc::tagEq(tag, QLatin1String("Multiplicity"))) {
+                m_Multi = tempElement.text().trimmed();
+                continue;
+            }
+            n = tempElement.firstChild();
+            tempElement = n.toElement();
+            tag = tempElement.tagName();
+            if (!UMLDoc::tagEq(tag, QLatin1String("Multiplicity.range"))) {
+                m_Multi = tempElement.text().trimmed();
+                continue;
+            }
+            n = tempElement.firstChild();
+            tempElement = n.toElement();
+            tag = tempElement.tagName();
+            if (!UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange"))) {
+                m_Multi = tempElement.text().trimmed();
+                continue;
+            }
+            QString multiUpper;
+            if (tempElement.hasAttribute(QLatin1String("lower"))) {
+                m_Multi = tempElement.attribute(QLatin1String("lower"));
+                multiUpper = tempElement.attribute(QLatin1String("upper"));
+                if (!multiUpper.isEmpty()) {
+                    if (!m_Multi.isEmpty())
+                        m_Multi.append(QLatin1String(".."));
+                    m_Multi.append(multiUpper);
+                }
+                continue;
+            }
+            n = tempElement.firstChild();
+            while (!n.isNull()) {
+                tempElement = n.toElement();
+                tag = tempElement.tagName();
+                if (UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange.lower"))) {
+                    m_Multi = tempElement.text();
+                } else if (UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange.upper"))) {
+                    multiUpper = tempElement.text();
+                }
+                n = n.nextSibling();
+            }
+            if (!multiUpper.isEmpty()) {
+                if (!m_Multi.isEmpty())
+                    m_Multi.append(QLatin1String(".."));
+                m_Multi.append(multiUpper);
+            }
+        } else if (m_SecondaryId.isEmpty() &&
+                   (UMLDoc::tagEq(tag, QLatin1String("type")) ||
+                    UMLDoc::tagEq(tag, QLatin1String("participant")))) {
+            m_SecondaryId = tempElement.attribute(QLatin1String("xmi.id"));
+            if (m_SecondaryId.isEmpty())
+                m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
+            if (m_SecondaryId.isEmpty()) {
+                QDomNode inner = tempElement.firstChild();
+                QDomElement innerElem = inner.toElement();
+                m_SecondaryId = innerElem.attribute(QLatin1String("xmi.id"));
+                if (m_SecondaryId.isEmpty())
+                    m_SecondaryId = innerElem.attribute(QLatin1String("xmi.idref"));
+            }
+        }
+    }
+    if (!m_Multi.isEmpty())
+        uDebug() << name() << ": m_Multi is " << m_Multi;
+    if (m_SecondaryId.isEmpty()) {
+        uError() << name() << ": type not given or illegal";
+        return false;
+    }
+    UMLObject * obj;
+    obj = doc->findObjectById(Uml::ID::fromString(m_SecondaryId));
+    if (obj) {
+        m_pSecondary = obj;
+        m_SecondaryId = QString();
+    }
+
+    // block signals to prevent needless updating
+    blockSignals(true);
+    // Here comes the handling of the association type.
+    // This is open for discussion - I'm pretty sure there are better ways..
+
+    // Yeah, for one, setting the *parent* object parameters from here is sucky
+    // as hell. Why are we using roleA to store what is essentially a parent (association)
+    // parameter, eh? The UML13.dtd is pretty silly, but since that is what
+    // is driving us to that point, we have to go with it. Some analysis of
+    // the component roles/linked items needs to be done in order to get things
+    // right. *sigh* -b.t.
+
+    // Setting association type from the role (A)
+    // Determination of the "aggregation" attribute used to be done only
+    // when (m_role == Uml::RoleType::A) but some XMI writers (e.g. StarUML) place
+    // the aggregation attribute at role B.
+    // The role end with the aggregation unequal to "none" wins.
+    QString aggregation = element.attribute(QLatin1String("aggregation"), QLatin1String("none"));
+    if (aggregation == QLatin1String("composite"))
+        m_pAssoc->setAssociationType(Uml::AssociationType::Composition);
+    else if (aggregation == QLatin1String("shared")       // UML1.3
+          || aggregation == QLatin1String("aggregate"))   // UML1.4
+        m_pAssoc->setAssociationType(Uml::AssociationType::Aggregation);
+
+    if (!element.hasAttribute(QLatin1String("isNavigable"))) {
+        // Backward compatibility mode: In Umbrello version 1.3.x the
+        // logic for saving the isNavigable flag was wrong.
+        // May happen on loading role A.
+        m_pAssoc->setOldLoadMode(true);
+    } else if (m_pAssoc->getOldLoadMode() == true) {
+        // Here is the original logic:
+        // "Role B:
+        //  If isNavigable is not given, we make no change to the
+        //  association type.
+        //  If isNavigable is given, and is "true", then we assume that
+        //  the association's other end (role A) is not navigable, and
+        //  therefore we change the association type to UniAssociation.
+        //  The case that isNavigable is given as "false" is ignored.
+        //  Combined with the association type logic for role A, this
+        //  allows us to support at_Association and at_UniAssociation."
+        if (element.attribute(QLatin1String("isNavigable")) == QLatin1String("true"))
+            m_pAssoc->setAssociationType(Uml::AssociationType::UniAssociation);
+    } else if (element.attribute(QLatin1String("isNavigable")) == QLatin1String("false")) {
+        m_pAssoc->setAssociationType(Uml::AssociationType::UniAssociation);
+    }
+
+    //FIXME not standard XMI
+    if (element.hasAttribute(QLatin1String("relationship"))) {
+        if (element.attribute(QLatin1String("relationship")) == QLatin1String("true")) {
+            m_pAssoc->setAssociationType(Uml::AssociationType::Relationship);
+        }
+    }
+
+    if (m_Multi.isEmpty())
+        m_Multi = element.attribute(QLatin1String("multiplicity"));
+
+    // Changeability defaults to Changeable if it cant set it here..
+    m_Changeability = Uml::Changeability::Changeable;
+    QString changeability = element.attribute(QLatin1String("changeability"));
+    if (changeability.isEmpty())
+        element.attribute(QLatin1String("changeable"));  // for backward compatibility
+    if (changeability == QLatin1String("frozen"))
+        m_Changeability = Uml::Changeability::Frozen;
+    else if (changeability == QLatin1String("addOnly"))
+        m_Changeability = Uml::Changeability::AddOnly;
+
+    // finished config, now unblock
+    blockSignals(false);
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlrole.h umbrello-15.08.1/umbrello/umlmodel/umlrole.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlrole.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlrole.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,65 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLROLE_H
+#define UMLROLE_H
+
+#include "umlobject.h"
+
+class UMLAssociation;
+
+/**
+ * This class contains the non-graphic representation of an association role.
+ *
+ * @author Brian Thomas <brian.thomas@gsfc.nasa.gov>
+ * @see UMLObject
+ */
+class UMLRole : public UMLObject
+{
+    Q_OBJECT
+public:
+
+    UMLRole(UMLAssociation * parent, UMLObject * parentUMLObject, Uml::RoleType::Enum role);
+    virtual ~UMLRole();
+
+    bool operator==(const UMLRole & rhs) const;
+
+    void setObject(UMLObject *obj);
+    UMLObject* object() const;
+
+    void setChangeability(Uml::Changeability::Enum value);
+    Uml::Changeability::Enum changeability() const;
+
+    void setMultiplicity(const QString &multi);
+    QString multiplicity() const;
+
+    UMLAssociation * parentAssociation() const;
+
+    Uml::RoleType::Enum role() const;
+
+    UMLObject* clone() const { return NULL; }
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual bool showPropertiesDialog(QWidget *parent = 0);
+
+protected:
+
+    bool load(QDomElement& element);
+
+private:
+
+    UMLAssociation *           m_pAssoc;
+    Uml::RoleType::Enum        m_role;
+    QString                    m_Multi;
+    Uml::Changeability::Enum   m_Changeability;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umlstereotypelist.h umbrello-15.08.1/umbrello/umlmodel/umlstereotypelist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umlstereotypelist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umlstereotypelist.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,22 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2012                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLSTEREOTYPELIST_H
+#define UMLSTEREOTYPELIST_H
+
+#include <QList>
+
+// forward declaration
+class UMLStereotype;
+
+typedef QList<UMLStereotype*> UMLStereotypeList;
+typedef QListIterator<UMLStereotype*> UMLStereotypeListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/umltemplatelist.h umbrello-15.08.1/umbrello/umlmodel/umltemplatelist.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/umltemplatelist.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/umltemplatelist.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2007                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLTEMPLATELIST_H
+#define UMLTEMPLATELIST_H
+
+#include <qlist.h>
+
+// forward declaration
+class UMLTemplate;
+
+typedef QList<UMLTemplate*> UMLTemplateList;
+typedef QListIterator<UMLTemplate*> UMLTemplateListIt;
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/uniqueconstraint.cpp umbrello-15.08.1/umbrello/umlmodel/uniqueconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/uniqueconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/uniqueconstraint.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,325 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+//own header
+#include "uniqueconstraint.h"
+
+// app includes
+#include "debug_utils.h"
+#include "entity.h"
+#include "entityattribute.h"
+#include "umldoc.h"
+#include "uml.h"
+#include "umlattributedialog.h"
+#include "umluniqueconstraintdialog.h"
+#include "object_factory.h"
+
+/**
+ * Sets up a constraint.
+ *
+ * @param parent    The parent of this UMLUniqueConstraint.
+ * @param name      The name of this UMLUniqueConstraint.
+ * @param id        The unique id given to this UMLUniqueConstraint.
+ */
+UMLUniqueConstraint::UMLUniqueConstraint(UMLObject *parent, const QString& name, Uml::ID::Type id)
+  : UMLEntityConstraint(parent, name, id)
+{
+    init();
+}
+
+/**
+ * Sets up a constraint.
+ *
+ * @param parent    The parent of this UMLUniqueConstraint.
+ */
+UMLUniqueConstraint::UMLUniqueConstraint(UMLObject *parent)
+  : UMLEntityConstraint(parent)
+{
+    init();
+}
+
+/**
+ * Overloaded '==' operator
+ */
+bool UMLUniqueConstraint::operator==(const  UMLUniqueConstraint &rhs) const
+{
+    if(this == &rhs)
+        return true;
+
+    if(!UMLObject::operator==(rhs))
+        return false;
+
+    return true;
+}
+
+/**
+ * Destructor.
+ */
+UMLUniqueConstraint::~UMLUniqueConstraint()
+{
+}
+
+/**
+ * Copy the internal presentation of this object into the UMLUniqueConstraint
+ * object.
+ */
+void UMLUniqueConstraint::copyInto(UMLObject *lhs) const
+{
+    UMLUniqueConstraint *target = static_cast<UMLUniqueConstraint*>(lhs);
+
+    // call the parent first.
+    UMLEntityConstraint::copyInto(target);
+
+    // Copy all datamembers
+    target->m_EntityAttributeList.clear();
+    bool valid = true;
+    foreach(UMLEntityAttribute* attr, m_EntityAttributeList) {
+       if (!valid)
+           break;
+       valid = target->addEntityAttribute(attr);
+    }
+
+    if (!valid) {
+        target->m_EntityAttributeList.clear();
+        uDebug() <<"Copying Attributes Failed : Target list cleared instead";
+    }
+}
+
+/**
+ * Make a clone of the UMLUniqueConstraint.
+ */
+UMLObject* UMLUniqueConstraint::clone() const
+{
+    //FIXME: The new attribute should be slaved to the NEW parent not the old.
+    UMLUniqueConstraint *clone = new UMLUniqueConstraint(static_cast<UMLObject*>(parent()));
+    copyInto(clone);
+    return clone;
+}
+
+/**
+ * Returns a string representation of the UMLUniqueConstraint.
+ *
+ * @param sig  If true will show the attribute type and initial value.
+ * @return  Returns a string representation of the UMLAttribute.
+ */
+QString UMLUniqueConstraint::toString(Uml::SignatureType::Enum sig)
+{
+     QString s;
+
+    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
+        s = name() + QLatin1Char(':');
+
+        if (static_cast<UMLEntity*>(parent())->isPrimaryKey(this)) {
+           s += QLatin1String("Primary Key (");
+        } else {
+           s += QLatin1String("Unique (");
+        }
+
+        bool first = true;
+        foreach(UMLEntityAttribute* att, m_EntityAttributeList) {
+            if (first) {
+               first = false;
+            } else
+                s += QLatin1Char(',');
+            s += att->name();
+        }
+        s +=  QLatin1Char(')') ;
+    }
+
+    return s;
+}
+
+QString UMLUniqueConstraint::getFullyQualifiedName(const QString& separator,
+                                                   bool includeRoot) const
+{
+    Q_UNUSED(separator); Q_UNUSED(includeRoot);
+    return this->name();
+}
+
+/**
+ * Creates the <UML:UniqueConstraint> XMI element.
+ */
+void UMLUniqueConstraint::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement uniqueConstraintElement = UMLObject::save(QLatin1String("UML:UniqueConstraint"), qDoc);
+
+    UMLEntity* parentEnt = static_cast<UMLEntity*>(parent());
+    if (parentEnt->isPrimaryKey(this)) {
+        uniqueConstraintElement.setAttribute(QLatin1String("isPrimary"), QLatin1String("1"));
+    } else {
+        uniqueConstraintElement.setAttribute(QLatin1String("isPrimary"), QLatin1String("0"));
+    }
+
+    foreach(UMLEntityAttribute* att, m_EntityAttributeList) {
+        att->saveToXMI(qDoc, uniqueConstraintElement);
+    }
+
+    qElement.appendChild(uniqueConstraintElement);
+}
+
+/**
+ * Display the properties configuration dialog for the attribute.
+ */
+bool UMLUniqueConstraint::showPropertiesDialog(QWidget* parent)
+{
+    UMLUniqueConstraintDialog dialog(parent, this);
+    return dialog.exec();
+}
+
+/**
+ * Loads the <UML:UniqueConstraint> XMI element.
+ */
+bool UMLUniqueConstraint::load(QDomElement & element)
+{
+    int isPrimary = element.attribute(QLatin1String("isPrimary"), QLatin1String("0")).toInt();
+    UMLEntity* parentEnt = static_cast<UMLEntity*>(parent());
+
+    if (isPrimary == 1) {
+        parentEnt->setAsPrimaryKey(this);
+    }
+
+    QDomNode node = element.firstChild();
+    while (!node.isNull()) {
+        if (node.isComment()) {
+            node = node.nextSibling();
+            continue;
+        }
+        QDomElement tempElement = node.toElement();
+        QString tag = tempElement.tagName();
+        if (UMLDoc::tagEq(tag, QLatin1String("EntityAttribute"))) {
+
+            QString attName = tempElement.attribute(QLatin1String("name"));
+            UMLObject* obj = parentEnt->findChildObject(attName);
+
+            UMLEntityAttribute* entAtt = static_cast<UMLEntityAttribute*>(obj);
+            if (entAtt == NULL)
+                continue;
+
+            m_EntityAttributeList.append(entAtt);
+
+        } else {
+            uWarning() << "unknown child type in UMLUniqueConstraint::load";
+        }
+
+        node = node.nextSibling();
+    }
+
+    return true;
+}
+
+
+/**
+ * Check if a entity attribute is present in m_entityAttributeList
+ *
+ * @param attr The Entity Attribute to check for existence in list
+ * @return true if it exists in the list, else false
+ */
+bool UMLUniqueConstraint::hasEntityAttribute(UMLEntityAttribute* attr)
+{
+    if (m_EntityAttributeList.indexOf(attr) == -1) {
+        //not present
+        return false;
+    }
+
+    // else present
+    return true;
+}
+
+/**
+ * Adds a UMLEntityAttribute to the list.
+ * The UMLEntityAttribute should already exist and should
+ * belong to the parent UMLEntity.
+ *
+ * @param attr The UMLEntityAttribute to add
+ * @return false if it failed to add, else true
+ */
+bool UMLUniqueConstraint::addEntityAttribute(UMLEntityAttribute* attr)
+{
+    UMLEntity *owningParent = dynamic_cast<UMLEntity*>(parent());
+
+    if (hasEntityAttribute(attr)) {
+        uDebug() << "Unique Constraint already contains" << attr->name();
+        return false;
+
+    }
+    if (owningParent == NULL) {
+        uError() << name() << ": parent is not a UMLEntity";
+        return false;
+    }
+
+    if (owningParent->findChildObjectById(attr->id()) == NULL) {
+        uError()
+            << " parent " << owningParent->name()
+            << " does not contain attribute " << attr->name();
+        return false;
+    }
+
+    //else add the attribute to the Entity Attribute List
+    m_EntityAttributeList.append(attr);
+
+    return true;
+}
+
+/**
+ * Removes a UMLEntityAttribute from the list
+ *
+ * @param attr The UMLEntityAttribute to remove from list
+ * @return false if it failed to remove the attribute from the list
+ */
+bool UMLUniqueConstraint::removeEntityAttribute(UMLEntityAttribute* attr)
+{
+    UMLEntity *owningParent = dynamic_cast<UMLEntity*>(parent());
+
+    if (owningParent == NULL) {
+        uError() << name() << ": parent is not a UMLEntity";
+        return false;
+    }
+
+    /*
+     * The attribute may already be removed from the Entity when this function
+     * is called. So checking this is not right
+     *
+     * if (owningParent->findChildObjectById(attr->ID()) == NULL) {
+     *    uError()
+     *        << " parent " << owningParent->getName()
+     *        << " does not contain attribute " << attr->getName();
+     *    return false;
+     * }
+     */
+
+    //else remove the attribute from the Entity Attribute List
+    if (m_EntityAttributeList.removeAll(attr)) {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * Get the Entity Attributes List.
+ */
+UMLEntityAttributeList UMLUniqueConstraint::getEntityAttributeList() const
+{
+    return m_EntityAttributeList;
+}
+
+void UMLUniqueConstraint::init()
+{
+    m_BaseType = UMLObject::ot_UniqueConstraint;
+}
+
+/**
+ * Clear the list of attributes contained in this UniqueConstraint
+ */
+void UMLUniqueConstraint::clearAttributeList()
+{
+    m_EntityAttributeList.clear();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/uniqueconstraint.h umbrello-15.08.1/umbrello/umlmodel/uniqueconstraint.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/uniqueconstraint.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/uniqueconstraint.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,77 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UNIQUECONSTRAINT_H
+#define UNIQUECONSTRAINT_H
+
+#include "basictypes.h"
+#include "classifierlistitem.h"
+#include "entityconstraint.h"
+#include "umlclassifierlist.h"
+#include "umlentityattributelist.h"
+
+/**
+ * This class is used to set up information for a unique entity constraint.
+ *
+ * @short Sets up Unique entity constraint information.
+ * @author Sharan Rao
+ * @see UMLObject UMLClassifierListItem UMLEntityConstraint
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLUniqueConstraint : public UMLEntityConstraint
+{
+public:
+
+    UMLUniqueConstraint(UMLObject *parent, const QString& name,
+                        Uml::ID::Type id = Uml::ID::None);
+    explicit UMLUniqueConstraint(UMLObject *parent);
+    virtual ~UMLUniqueConstraint();
+
+    bool operator==(const UMLUniqueConstraint &rhs) const;
+
+    virtual void copyInto(UMLObject *lhs) const;
+
+    virtual UMLObject* clone() const;
+
+    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
+
+    QString getFullyQualifiedName(const QString& separator = QString(),
+                                  bool includeRoot = false) const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    virtual bool showPropertiesDialog(QWidget* parent = 0);
+
+    bool hasEntityAttribute(UMLEntityAttribute* attr);
+
+    bool addEntityAttribute(UMLEntityAttribute* attr);
+
+    bool removeEntityAttribute(UMLEntityAttribute* attr);
+
+    UMLEntityAttributeList getEntityAttributeList() const;
+
+    void clearAttributeList();
+
+protected:
+
+    bool load(QDomElement & element);
+
+private:
+
+    void init();
+
+    /**
+     * The list of entity attributes that together make up the unique constraint.
+     */
+    UMLEntityAttributeList m_EntityAttributeList;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/usecase.cpp umbrello-15.08.1/umbrello/umlmodel/usecase.cpp
--- umbrello-15.08.1.orig/umbrello/umlmodel/usecase.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/usecase.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,67 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "usecase.h"
+
+/**
+ * Creates a UseCase object
+ *
+ * @param name   The name of the object.
+ * @param id     The id of the object.
+ */
+UMLUseCase::UMLUseCase(const QString & name, Uml::ID::Type id)
+  : UMLCanvasObject(name, id)
+{
+    init();
+}
+
+/**
+ * Standard decstructor.
+ */
+UMLUseCase::~UMLUseCase()
+{
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void UMLUseCase::init()
+{
+    m_BaseType = UMLObject::ot_UseCase;
+}
+
+/**
+ * Make a clone of this object.
+ */
+UMLObject* UMLUseCase::clone() const
+{
+    UMLUseCase *clone = new UMLUseCase();
+    UMLObject::copyInto(clone);
+    return clone;
+}
+
+/**
+ * Creates the <UML:UseCase> element.
+ */
+void UMLUseCase::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement usecaseElement = UMLObject::save(QLatin1String("UML:UseCase"), qDoc);
+    qElement.appendChild(usecaseElement);
+}
+
+/**
+ * Loads the <UML:UseCase> element (TODO).
+ */
+bool UMLUseCase::load(QDomElement&)
+{
+    return true;
+}
+
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlmodel/usecase.h umbrello-15.08.1/umbrello/umlmodel/usecase.h
--- umbrello-15.08.1.orig/umbrello/umlmodel/usecase.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlmodel/usecase.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,40 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef USECASE_H
+#define USECASE_H
+
+#include "umlcanvasobject.h"
+
+/**
+ * This class contains the non-graphical information required for a UML UseCase.
+ * This class inherits from @ref UMLCanvasObject which contains most of the information.
+ *
+ * @short Information for a non-graphical UML UseCase.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLUseCase : public UMLCanvasObject
+{
+public:
+    explicit UMLUseCase(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
+    ~UMLUseCase();
+
+    virtual void init();
+
+    virtual UMLObject* clone() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+    bool load(QDomElement & element);
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlobject.cpp umbrello-15.08.1/umbrello/umlobject.cpp
--- umbrello-15.08.1.orig/umbrello/umlobject.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlobject.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,1142 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "umlobject.h"
-
-// app includes
-#include "classpropertiesdialog.h"
-#include "debug_utils.h"
-#include "enumliteral.h"
-#include "uniqueid.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umllistview.h"
-#include "package.h"
-#include "folder.h"
-#include "stereotype.h"
-#include "object_factory.h"
-#include "model_utils.h"
-#include "import_utils.h"
-#include "docwindow.h"
-#include "cmds.h"
-
-// kde includes
-#include <KLocalizedString>
-
-// qt includes
-#include <QApplication>
-#include <QPointer>
-
-using namespace Uml;
-
-DEBUG_REGISTER_DISABLED(UMLObject)
-
-/**
- * Creates a UMLObject.
- * @param other object to created from
- */
-UMLObject::UMLObject(const UMLObject &other)
-  : QObject(other.parent())
-{
-    other.copyInto(this);
-}
-
-/**
- * Creates a UMLObject.
- * @param parent   The parent of the object.
- * @param name     The name of the object.
- * @param id       The ID of the object (optional.) If omitted
- *                 then a new ID will be assigned internally.
- */
-UMLObject::UMLObject(UMLObject* parent, const QString& name, ID::Type id)
-  : QObject(parent),
-    m_nId(id),
-    m_name(name)
-{
-    init();
-    if (id == Uml::ID::None)
-        m_nId = UniqueID::gen();
-}
-
-/**
- * Creates a UMLObject.
- * @param name     The name of the object.
- * @param id       The ID of the object (optional.) If omitted
- *                 then a new ID will be assigned internally.
- */
-UMLObject::UMLObject(const QString& name, ID::Type id)
-  : QObject(UMLApp::app()->document()),
-    m_nId(id),
-    m_name(name)
-{
-    init();
-    if (id == Uml::ID::None)
-        m_nId = UniqueID::gen();
-}
-
-/**
- * Creates a UMLObject.
- * @param   parent   The parent of the object.
- */
-UMLObject::UMLObject(UMLObject * parent)
-  : QObject(parent),
-    m_nId(Uml::ID::None),
-    m_name(QString())
-{
-    init();
-}
-
-/**
- * Standard destructor.
- */
-UMLObject::~UMLObject()
-{
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLObject::init()
-{
-    setObjectName(QLatin1String("UMLObject"));
-    m_BaseType = ot_UMLObject;
-    m_pUMLPackage = 0;
-    m_visibility = Uml::Visibility::Public;
-    m_pStereotype = 0;
-    m_Doc.clear();
-    m_bAbstract = false;
-    m_bStatic = false;
-    m_bCreationWasSignalled = false;
-    m_pSecondary = 0;
-}
-
-/**
- * Display the properties configuration dialog for the object.
- *
- * @param parent    The parent widget.
- * @return  True for success of this operation.
- */
-bool UMLObject::showPropertiesDialog(QWidget *parent)
-{
-    DocWindow *docwindow = UMLApp::app()->docWindow();
-    docwindow->updateDocumentation(false);
-    QPointer<ClassPropertiesDialog> dlg = new ClassPropertiesDialog(parent, this, false);
-    bool modified = false;
-    if (dlg->exec()) {
-        docwindow->showDocumentation(this, true);
-        UMLApp::app()->document()->setModified(true);
-        modified = true;
-    }
-    dlg->close();
-    delete dlg;
-    return modified;
-}
-
-/**
- * This should be reimplemented by subclasses if they wish to
- * accept certain types of associations. Note that this only
- * tells if this UMLObject can accept the association
- * type. When creating an association another check is made to
- * see if the association is valid. For example a UMLClass
- * (UMLClassifier) can accept generalizations and should
- * return true. If while creating a generalization the
- * superclass is already subclassed from this, the association
- * is not valid and will not be created.  The default accepts
- * nothing (returns false)
- */
-bool UMLObject::acceptAssociationType(Uml::AssociationType::Enum type)
-{
-    Q_UNUSED(type);
-    // A UMLObject accepts nothing. This should be reimplemented by the subclasses
-    return false;
-}
-
-/**
- * Assigns a new Id to the object
- */
-void UMLObject::setID(ID::Type NewID)
-{
-    m_nId = NewID;
-    emitModified();
-}
-
-/**
- * Set the UMLObject's name
- */
-void UMLObject::setName(const QString &strName)
-{
-    if (name() != strName) {
-        UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(this, strName));
-    }
-}
-
-/**
- * Method used by setName: it is called by  cmdSetName, Don't use it!
- */
-void UMLObject::setNameCmd(const QString &strName)
-{
-    m_name = strName;
-    emitModified();
-}
-
-/**
- * Returns a copy of m_name
- */
-QString UMLObject::name() const
-{
-    return m_name;
-}
-
-/**
- * Returns the fully qualified name, i.e. all package prefixes and then m_name.
- *
- * @param separator  The separator string to use (optional.)
- *                   If not given then the separator is chosen according
- *                   to the currently selected active programming language
- *                   of import and code generation.
- * @param includeRoot  Whether to prefix the root folder name to the FQN.
- *                     See UMLDoc::getRootFolder(). Default: false.
- * @return  The fully qualified name of this UMLObject.
- */
-QString UMLObject::fullyQualifiedName(const QString& separator,
-        bool includeRoot /* = false */) const
-{
-    QString fqn;
-    if (m_pUMLPackage && m_pUMLPackage != this) {
-        bool skipPackage = false;
-        if (!includeRoot) {
-            UMLDoc *umldoc = UMLApp::app()->document();
-            if (umldoc->rootFolderType(m_pUMLPackage) != Uml::ModelType::N_MODELTYPES ||
-                    m_pUMLPackage == umldoc->datatypeFolder())
-                skipPackage = true;
-        }
-        if (!skipPackage) {
-            QString tempSeparator = separator;
-            if (tempSeparator.isEmpty())
-                tempSeparator = UMLApp::app()->activeLanguageScopeSeparator();
-            fqn = m_pUMLPackage->fullyQualifiedName(tempSeparator, includeRoot);
-            fqn.append(tempSeparator);
-        }
-    }
-    fqn.append(m_name);
-    return fqn;
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLObject::operator==(const UMLObject & rhs) const
-{
-    if (this == &rhs)
-        return true;
-
-    //don't compare IDs, these are program specific and
-    //don't mean the objects are the same
-    //***** CHECK: Who put in this comment? What was the reason?
-    //***** Currently some operator== in umbrello compare the IDs
-    //***** while others don't.
-
-    if (m_name != rhs.m_name)
-        return false;
-
-    // Packages create different namespaces, therefore they should be
-    // part of the equality test.
-    if (m_pUMLPackage != rhs.m_pUMLPackage)
-        return false;
-
-    // Making the type part of an object's identity has its problems:
-    // Not all programming languages support declarations of the same
-    // name but different type.
-    // In such cases, the code generator is responsible for generating
-    // the appropriate error message.
-    if (m_BaseType != rhs.m_BaseType)
-        return false;
-
-    // The documentation should not be part of the equality test.
-    // If two objects are the same but differ only in their documentation,
-    // what does that mean?
-    //if(m_Doc != rhs.m_Doc)
-    //  return false;
-
-    // The visibility should not be part of the equality test.
-    // What does it mean if two objects are the same but differ in their
-    // visibility? - I'm not aware of any programming language that would
-    // support that.
-    //if(m_visibility != rhs.m_visibility)
-    //  return false;
-
-    // See comments above
-    //if(m_pStereotype != rhs.m_pStereotype)
-    //  return false;
-
-    // See comments above
-    //if(m_bAbstract != rhs.m_bAbstract)
-    //  return false;
-
-    // See comments above
-    //if(m_bStatic != rhs.m_bStatic)
-    //  return false;
-
-    return true;
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLObject::copyInto(UMLObject *lhs) const
-{
-    // Data members with copy constructor
-    lhs->m_Doc = m_Doc;
-    lhs->m_pStereotype = m_pStereotype;
-    lhs->m_bAbstract = m_bAbstract;
-    lhs->m_bStatic = m_bStatic;
-    lhs->m_BaseType = m_BaseType;
-    lhs->m_visibility = m_visibility;
-    lhs->m_pUMLPackage = m_pUMLPackage;
-
-    // We don't want the same name existing twice.
-    lhs->m_name = Model_Utils::uniqObjectName(m_BaseType, m_pUMLPackage, m_name);
-
-    // Create a new ID.
-    lhs->m_nId = UniqueID::gen();
-
-    // Hope that the parent from QObject is okay.
-    if (lhs->parent() != parent())
-        uDebug() << "copyInto has a wrong parent";
-}
-
-UMLObject *UMLObject::clone() const
-{
-    UMLObject *clone = new UMLObject;
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Returns the abstract state of the object.
- */
-bool UMLObject::isAbstract() const
-{
-    return m_bAbstract;
-}
-
-/**
- * Sets the paste state of the object.
- */
-void UMLObject::setAbstract(bool bAbstract)
-{
-    m_bAbstract = bAbstract;
-    emitModified();
-}
-
-/**
- * Returns true if this UMLObject has classifier scope,
- * otherwise false (the default).
- */
-bool UMLObject::isStatic() const
-{
-    return m_bStatic;
-}
-
-/**
- * Sets the value for m_bStatic.
- */
-void UMLObject::setStatic(bool bStatic)
-{
-    m_bStatic = bStatic;
-    emitModified();
-}
-
-/**
- * Forces the emission of the modified signal.  Useful when
- * updating several attributes at a time: you can block the
- * signals, update all atts, and then force the signal.
- */
-void UMLObject::emitModified()
-{
-    UMLDoc *umldoc = UMLApp::app()->document();
-    if (!umldoc->loading() && !umldoc->closing())
-        emit modified();
-}
-
-/**
- * Returns the type of the object.
- *
- * @return  Returns the type of the object.
- */
-UMLObject::ObjectType UMLObject::baseType() const
-{
-    return m_BaseType;
-}
-
-/**
- * @return The type used for rtti as string.
- */
-QLatin1String UMLObject::baseTypeStr() const
-{
-    return QLatin1String(ENUM_NAME(UMLObject, ObjectType, m_BaseType));
-}
-
-/**
- * Set the type of the object.
- *
- * @param ot The ObjectType to set.
- */
-void UMLObject::setBaseType(ObjectType ot)
-{
-    m_BaseType = ot;
-}
-
-/**
- * Returns the ID of the object.
- *
- * @return  Returns the ID of the object.
- */
-ID::Type UMLObject::id() const
-{
-    return m_nId;
-}
-
-/**
- * Returns the documentation for the object.
- *
- * @return  Returns the documentation for the object.
- */
-QString UMLObject::doc() const
-{
-    return m_Doc;
-}
-
-/**
- * Returns state of documentation for the object.
- *
- * @return false if documentation is empty
- */
-bool UMLObject::hasDoc() const
-{
-    return !m_Doc.isEmpty();
-}
-
-/**
- * Sets the documentation for the object.
- *
- * @param d The documentation for the object.
- */
-void UMLObject::setDoc(const QString &d)
-{
-    m_Doc = d;
-    //emit modified();  No, this is done centrally at DocWindow::updateDocumentation()
-}
-
-/**
- * Returns the visibility of the object.
- *
- * @return  Returns the visibility of the object.
- */
-Visibility::Enum UMLObject::visibility() const
-{
-    return m_visibility;
-}
-
-/**
- * Sets the visibility of the object.
- *
- * @param visibility  The visibility of the object.
- */
-void UMLObject::setVisibility(Visibility::Enum visibility)
-{
-    if (m_visibility != visibility) {
-        UMLApp::app()->executeCommand(new CmdSetVisibility(this, visibility));
-    }
-}
-
-/**
- * Method used by setVisibility: it is called by  cmdSetVisibility, Don't use it!
- */
-void UMLObject::setVisibilityCmd(Visibility::Enum visibility)
-{
-    m_visibility = visibility;
-    emitModified();
-}
-
-/**
- * Sets the class' UMLStereotype. Adjusts the reference counts
- * at the previously set stereotype and at the new stereotype.
- * If the previously set UMLStereotype's reference count drops
- * to zero then the UMLStereotype is removed at the UMLDoc and
- * it is then physically deleted.
- *
- * @param stereo Sets the classes UMLStereotype.
- */
-void UMLObject::setUMLStereotype(UMLStereotype *stereo)
-{
-    if (stereo == m_pStereotype)
-        return;
-    if (stereo) {
-        stereo->incrRefCount();
-    }
-    if (m_pStereotype) {
-        m_pStereotype->decrRefCount();
-        if (m_pStereotype->refCount() == 0) {
-            UMLDoc *pDoc = UMLApp::app()->document();
-            pDoc->removeStereotype(m_pStereotype);
-            delete m_pStereotype;
-        }
-    }
-    m_pStereotype = stereo;
-    // TODO: don't emit modified() if predefined folder
-    emitModified();
-}
-
-/**
- * Sets the classes stereotype name.
- * Internally uses setUMLStereotype().
- *
- * @param name     Sets the classes stereotype name.
- */
-void UMLObject::setStereotype(const QString &name)
-{
-    if (name != stereotype()) {
-        UMLApp::app()->executeCommand(new CmdSetStereotype(this, name));
-    }
-}
-
-void UMLObject::setStereotypeCmd(const QString& name)
-{
-    if (name.isEmpty()) {
-        setUMLStereotype(NULL);
-        return;
-    }
-    UMLDoc *pDoc = UMLApp::app()->document();
-    UMLStereotype *s = pDoc->findOrCreateStereotype(name);
-    setUMLStereotype(s);
-}
-
-/**
- * Sets the UMLPackage in which this class is located.
- *
- * @param pPkg   Pointer to the class' UMLPackage.
- */
-bool UMLObject::setUMLPackage(UMLPackage* pPkg)
-{
-    if (pPkg == this) {
-        uDebug() << "setting parent to myself is not allowed";
-        return false;
-    }
-
-    if (pPkg == NULL) {
-        // Allow setting to NULL for stereotypes
-        m_pUMLPackage = pPkg;
-        return true;
-    }
-
-    if (pPkg->umlPackage() == this) {
-        uDebug() << "setting parent to an object of which I'm already the parent is not allowed";
-        return false;
-    }
-
-    m_pUMLPackage = pPkg;
-    emitModified();
-    return true;
-}
-
-/**
- * Returns the classes UMLStereotype object.
- *
- * @return   Returns the classes UMLStereotype object.
- */
-UMLStereotype * UMLObject::umlStereotype()
-{
-    return m_pStereotype;
-}
-
-/**
- * Returns the stereotype.
- */
-QString UMLObject::stereotype(bool includeAdornments /* = false */) const
-{
-    if (m_pStereotype == NULL)
-        return QString();
-    return m_pStereotype->name(includeAdornments);
-}
-
-/**
- * Return the package(s) in which this UMLObject is contained
- * as a text.
- *
- * @param separator Separator string for joining together the
- *                  individual package prefixes (optional.)
- *                  If no separator is given then the separator
- *                  of the currently selected language is used.
- * @param includeRoot  Whether to prefix the root folder name.
- *                     Default: false.
- * @return  The UMLObject's enclosing package(s) as a text.
- */
-QString UMLObject::package(const QString& separator, bool includeRoot)
-{
-    QString tempSeparator = separator;
-    if (tempSeparator.isEmpty())
-        tempSeparator = UMLApp::app()->activeLanguageScopeSeparator();
-    QString fqn = fullyQualifiedName(tempSeparator, includeRoot);
-    if (!fqn.contains(tempSeparator))
-        return QString();
-    QString scope = fqn.left(fqn.length() - tempSeparator.length() - m_name.length());
-    return scope;
-}
-
-/**
- * Return a list of the packages in which this class is embedded.
- * The outermost package is first in the list.
- *
- * @param includeRoot  Whether to prefix the root folder name.
- *                     Default: false.
- * @return  UMLPackageList of the containing packages.
- */
-UMLPackageList UMLObject::packages(bool includeRoot) const
-{
-    UMLPackageList pkgList;
-    UMLPackage* pkg = m_pUMLPackage;
-    while (pkg != NULL) {
-        pkgList.prepend(pkg);
-        pkg = pkg->umlPackage();
-    }
-    if (!includeRoot)
-        pkgList.removeFirst();
-    return pkgList;
-}
-
-/**
- * Returns the UMLPackage that this class is located in.
- *
- * @return  Pointer to the UMLPackage of this class.
- */
-UMLPackage* UMLObject::umlPackage()
-{
-    return m_pUMLPackage;
-}
-
-/**
- * Return secondary ID. Required by resolveRef().
- */
-QString UMLObject::secondaryId() const
-{
-    return m_SecondaryId;
-}
-
-/**
- * Set the secondary ID.
- * Currently only required by petalTree2Uml(); all other setting of the
- * m_SecondaryID is internal to the UMLObject class hierarchy.
- */
-void UMLObject::setSecondaryId(const QString& id)
-{
-    m_SecondaryId = id;
-}
-
-/**
- * Return secondary ID fallback.
- * Required by resolveRef() for imported model files.
- */
-QString UMLObject::secondaryFallback() const
-{
-    return m_SecondaryFallback;
-}
-
-/**
- * Set the secondary ID fallback.
- * Currently only used by petalTree2Uml().
- */
-void UMLObject::setSecondaryFallback(const QString& id)
-{
-    m_SecondaryFallback = id;
-}
-
-/**
- * Calls UMLDoc::signalUMLObjectCreated() if m_BaseType affords
- * doing so.
- */
-void UMLObject::maybeSignalObjectCreated()
-{
-    if (!m_bCreationWasSignalled &&
-            m_BaseType != ot_Stereotype &&
-            m_BaseType != ot_Association &&
-            m_BaseType != ot_Role) {
-        m_bCreationWasSignalled = true;
-        UMLDoc* umldoc = UMLApp::app()->document();
-        umldoc->signalUMLObjectCreated(this);
-    }
-}
-
-/**
- * Resolve referenced objects (if any.)
- * Needs to be called after all UML objects are loaded from file.
- * This needs to be done after all model objects are loaded because
- * some of the xmi.id's might be forward references, i.e. they may
- * identify model objects which were not yet loaded at the point of
- * reference.
- * The default implementation attempts resolution of the m_SecondaryId.
- *
- * @return   True for success.
- */
-bool UMLObject::resolveRef()
-{
-    if (m_pSecondary || (m_SecondaryId.isEmpty() && m_SecondaryFallback.isEmpty())) {
-        maybeSignalObjectCreated();
-        return true;
-    }
-#ifdef VERBOSE_DEBUGGING
-    uDebug() << m_name << ": m_SecondaryId is " << m_SecondaryId;
-#endif
-    UMLDoc *pDoc = UMLApp::app()->document();
-    // In the new, XMI standard compliant save format,
-    // the type is the xmi.id of a UMLClassifier.
-    if (! m_SecondaryId.isEmpty()) {
-        m_pSecondary = pDoc->findObjectById(Uml::ID::fromString(m_SecondaryId));
-        if (m_pSecondary != NULL) {
-            if (m_pSecondary->baseType() == ot_Stereotype) {
-                m_pStereotype = dynamic_cast<UMLStereotype*>(m_pSecondary.data());
-                m_pStereotype->incrRefCount();
-                m_pSecondary = NULL;
-            }
-            m_SecondaryId = QString();
-            maybeSignalObjectCreated();
-            return true;
-        }
-        if (m_SecondaryFallback.isEmpty()) {
-            uDebug() << "object with xmi.id=" << m_SecondaryId << " not found, setting to undef";
-            UMLFolder *datatypes = pDoc->datatypeFolder();
-            m_pSecondary = Object_Factory::createUMLObject(ot_Datatype, QLatin1String("undef"), datatypes, false);
-            return true;
-        }
-    }
-    if (m_SecondaryFallback.isEmpty()) {
-        uError() << m_name << ": cannot find type with id " << m_SecondaryId;
-        return false;
-    }
-#ifdef VERBOSE_DEBUGGING
-    uDebug() << m_name << ": could not resolve secondary ID " << m_SecondaryId
-             << ", using secondary fallback " << m_SecondaryFallback;
-#endif
-    m_SecondaryId = m_SecondaryFallback;
-    // Assume we're dealing with the older Umbrello format where
-    // the type name was saved in the "type" attribute rather
-    // than the xmi.id of the model object of the attribute type.
-    m_pSecondary = pDoc->findUMLObject(m_SecondaryId, ot_UMLObject, this);
-    if (m_pSecondary) {
-        m_SecondaryId = QString();
-        maybeSignalObjectCreated();
-        return true;
-    }
-    // Work around Object_Factory::createUMLObject()'s incapability
-    // of on-the-fly scope creation:
-    if (m_SecondaryId.contains(QLatin1String("::"))) {
-        // TODO: Merge Import_Utils::createUMLObject() into Object_Factory::createUMLObject()
-        m_pSecondary = Import_Utils::createUMLObject(ot_UMLObject, m_SecondaryId, m_pUMLPackage);
-        if (m_pSecondary) {
-            if (Import_Utils::newUMLObjectWasCreated()) {
-                maybeSignalObjectCreated();
-                qApp->processEvents();
-                uDebug() << "Import_Utils::createUMLObject() created a new type for "
-                         << m_SecondaryId;
-            } else {
-                uDebug() << "Import_Utils::createUMLObject() returned an existing type for "
-                         << m_SecondaryId;
-            }
-            m_SecondaryId = QString();
-            return true;
-        }
-        uError() << "Import_Utils::createUMLObject() failed to create a new type for "
-                 << m_SecondaryId;
-        return false;
-    }
-    uDebug() << "Creating new type for " << m_SecondaryId;
-    // This is very C++ specific - we rely on  some '*' or
-    // '&' to decide it's a ref type. Plus, we don't recognize
-    // typedefs of ref types.
-    bool isReferenceType = (m_SecondaryId.contains(QLatin1Char('*')) ||
-                            m_SecondaryId.contains(QLatin1Char('&')));
-    ObjectType ot = ot_Class;
-    if (isReferenceType) {
-        ot = ot_Datatype;
-    } else {
-        if (Model_Utils::isCommonDataType(m_SecondaryId))
-            ot = ot_Datatype;
-    }
-    m_pSecondary = Object_Factory::createUMLObject(ot, m_SecondaryId, NULL);
-    if (m_pSecondary == NULL)
-        return false;
-    m_SecondaryId = QString();
-    maybeSignalObjectCreated();
-    //qApp->processEvents();
-    return true;
-}
-
-void UMLObject::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
-{
-    Q_UNUSED(qDoc); Q_UNUSED(qElement);
-}
-
-/**
- * Auxiliary to saveToXMI.
- * Create a QDomElement with the given tag, and save the XMI attributes
- * that are common to all child classes to the newly created element.
- * This method does not need to be overridden by child classes.
- */
-QDomElement UMLObject::save(const QString &tag, QDomDocument & qDoc)
-{
-    /*
-      Call as the first action of saveToXMI() in child class:
-      This creates the QDomElement with which to work.
-    */
-    QDomElement qElement = qDoc.createElement(tag);
-    qElement.setAttribute(QLatin1String("isSpecification"), QLatin1String("false"));
-    if (m_BaseType != ot_Association &&
-        m_BaseType != ot_Role &&
-        m_BaseType != ot_Attribute) {
-        qElement.setAttribute(QLatin1String("isLeaf"), QLatin1String("false"));
-        qElement.setAttribute(QLatin1String("isRoot"), QLatin1String("false"));
-        if (m_bAbstract)
-            qElement.setAttribute(QLatin1String("isAbstract"), QLatin1String("true"));
-        else
-            qElement.setAttribute(QLatin1String("isAbstract"), QLatin1String("false"));
-    }
-    qElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(m_nId));
-    qElement.setAttribute(QLatin1String("name"), m_name);
-    if (m_BaseType != ot_Operation &&
-        m_BaseType != ot_Role &&
-        m_BaseType != ot_Attribute) {
-        Uml::ID::Type nmSpc;
-        if (m_pUMLPackage)
-            nmSpc = m_pUMLPackage->id();
-        else
-            nmSpc = UMLApp::app()->document()->modelID();
-        qElement.setAttribute(QLatin1String("namespace"), Uml::ID::toString(nmSpc));
-    }
-    if (! m_Doc.isEmpty())
-        qElement.setAttribute(QLatin1String("comment"), m_Doc);    //CHECK: uml13.dtd compliance
-#ifdef XMI_FLAT_PACKAGES
-    if (m_pUMLPackage)             //FIXME: uml13.dtd compliance
-        qElement.setAttribute(QLatin1String("package"), m_pUMLPackage->ID());
-#endif
-    QString visibility = Uml::Visibility::toString(m_visibility, false);
-    qElement.setAttribute(QLatin1String("visibility"), visibility);
-    if (m_pStereotype != NULL)
-        qElement.setAttribute(QLatin1String("stereotype"), Uml::ID::toString(m_pStereotype->id()));
-    if (m_bStatic)
-        qElement.setAttribute(QLatin1String("ownerScope"), QLatin1String("classifier"));
-    /* else
-        qElement.setAttribute("ownerScope", "instance");
-     *** ownerScope defaults to instance if not set **********/
-    return qElement;
-}
-
-/**
- * Auxiliary to loadFromXMI.
- * This method is usually overridden by child classes.
- * It is responsible for loading the specific XMI structure
- * of the child class.
- */
-bool UMLObject::load(QDomElement&)
-{
-    // This body is not usually executed because child classes
-    // overwrite the load method.
-    return true;
-}
-
-/**
- * Analyzes the given QDomElement for a reference to a stereotype.
- *
- * @param element   QDomElement to analyze.
- * @return          True if a stereotype reference was found, else false.
- */
-bool UMLObject::loadStereotype(QDomElement & element)
-{
-    QString tag = element.tagName();
-    if (!UMLDoc::tagEq(tag, QLatin1String("stereotype")))
-        return false;
-    QString stereo = element.attribute(QLatin1String("xmi.value"));
-    if (stereo.isEmpty() && element.hasChildNodes()) {
-        /* like so:
-         <UML:ModelElement.stereotype>
-           <UML:Stereotype xmi.idref = '07CD'/>
-         </UML:ModelElement.stereotype>
-         */
-        QDomNode stereoNode = element.firstChild();
-        QDomElement stereoElem = stereoNode.toElement();
-        tag = stereoElem.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("Stereotype"))) {
-            stereo = stereoElem.attribute(QLatin1String("xmi.idref"));
-        }
-    }
-    if (stereo.isEmpty())
-        return false;
-    Uml::ID::Type stereoID = Uml::ID::fromString(stereo);
-    UMLDoc *pDoc = UMLApp::app()->document();
-    m_pStereotype = pDoc->findStereotypeById(stereoID);
-    if (m_pStereotype)
-        m_pStereotype->incrRefCount();
-    else
-        m_SecondaryId = stereo;  // leave it to resolveRef()
-    return true;
-}
-
-/**
- * This method loads the generic parts of the XMI common to most model
- * classes.  It is not usually reimplemented by child classes.
- * Instead, it invokes the load() method which implements the loading
- * of the specifics of each child class.
- *
- * @param element   The QDomElement from which to load.
- */
-bool UMLObject::loadFromXMI(QDomElement & element)
-{
-    UMLDoc* umldoc = UMLApp::app()->document();
-    if (umldoc == 0) {
-        uError() << "umldoc is NULL";
-        return false;
-    }
-    // Read the name first so that if we encounter a problem, the error
-    // message can say the name.
-    m_name = element.attribute(QLatin1String("name"));
-    QString id = Model_Utils::getXmiId(element);
-    if (id.isEmpty() || id == QLatin1String("-1")) {
-        // Before version 1.4, Umbrello did not save the xmi.id of UMLRole objects.
-        // Some tools (such as Embarcadero's) do not have an xmi.id on all attributes.
-        m_nId = UniqueID::gen();
-        uWarning() << m_name << ": xmi.id not present, generating a new one";
-    } else {
-        Uml::ID::Type nId = Uml::ID::fromString(id);
-        if (m_BaseType == ot_Role) {
-            // Some older Umbrello versions had a problem with xmi.id's
-            // of other objects being reused for the UMLRole, see e.g.
-            // attachment 21179 at http://bugs.kde.org/147988 .
-            // If the xmi.id is already being used then we generate a new one.
-            UMLObject *o = umldoc->findObjectById(nId);
-            if (o) {
-                uError() << "loadFromXMI(UMLRole): id " << id
-                         << " is already in use!!! Please fix your XMI file.";
-            }
-        }
-        m_nId = nId;
-    }
-
-    if (element.hasAttribute(QLatin1String("documentation")))  // for bkwd compat.
-        m_Doc = element.attribute(QLatin1String("documentation"));
-    else
-        m_Doc = element.attribute(QLatin1String("comment"));    //CHECK: need a UML:Comment?
-
-    m_visibility = Uml::Visibility::Public;
-    if (element.hasAttribute(QLatin1String("scope"))) {        // for bkwd compat.
-        QString scope = element.attribute(QLatin1String("scope"));
-        if (scope == QLatin1String("instance_level"))         // nsuml compat.
-            m_bStatic = false;
-        else if (scope == QLatin1String("classifier_level"))  // nsuml compat.
-            m_bStatic = true;
-        else {
-            int nScope = scope.toInt();
-            switch (nScope) {
-            case 200:
-                m_visibility = Uml::Visibility::Public;
-                break;
-            case 201:
-                m_visibility = Uml::Visibility::Private;
-                break;
-            case 202:
-                m_visibility = Uml::Visibility::Protected;
-                break;
-            default:
-                uError() << m_name << ": illegal scope " << nScope;
-            }
-        }
-    } else {
-        QString visibility = element.attribute(QLatin1String("visibility"), QLatin1String("public"));
-        if (visibility == QLatin1String("private")
-                || visibility == QLatin1String("private_vis"))    // for compatibility with other programs
-            m_visibility = Uml::Visibility::Private;
-        else if (visibility == QLatin1String("protected")
-                 || visibility == QLatin1String("protected_vis"))  // for compatibility with other programs
-            m_visibility = Uml::Visibility::Protected;
-        else if (visibility == QLatin1String("implementation"))
-            m_visibility = Uml::Visibility::Implementation;
-    }
-
-    QString stereo = element.attribute(QLatin1String("stereotype"));
-    if (!stereo.isEmpty()) {
-        Uml::ID::Type stereoID = Uml::ID::fromString(stereo);
-        m_pStereotype = umldoc->findStereotypeById(stereoID);
-        if (m_pStereotype) {
-            m_pStereotype->incrRefCount();
-        } else {
-            uDebug() << m_name << ": UMLStereotype " << Uml::ID::toString(stereoID)
-                     << " not found, creating now.";
-            setStereotypeCmd(stereo);
-        }
-    }
-
-    if (element.hasAttribute(QLatin1String("abstract"))) {      // for bkwd compat.
-        QString abstract = element.attribute(QLatin1String("abstract"), QLatin1String("0"));
-        m_bAbstract = (bool)abstract.toInt();
-    } else {
-        QString isAbstract = element.attribute(QLatin1String("isAbstract"), QLatin1String("false"));
-        m_bAbstract = (isAbstract == QLatin1String("true"));
-    }
-
-    if (element.hasAttribute(QLatin1String("static"))) {        // for bkwd compat.
-        QString staticScope = element.attribute(QLatin1String("static"), QLatin1String("0"));
-        m_bStatic = (bool)staticScope.toInt();
-    } else {
-        QString ownerScope = element.attribute(QLatin1String("ownerScope"), QLatin1String("instance"));
-        m_bStatic = (ownerScope == QLatin1String("classifier"));
-    }
-
-    // If the node has child nodes, check whether attributes can be
-    // extracted from them.
-    if (element.hasChildNodes()) {
-        QDomNode node = element.firstChild();
-        if (node.isComment())
-            node = node.nextSibling();
-        QDomElement elem = node.toElement();
-        while (!elem.isNull()) {
-            QString tag = elem.tagName();
-            if (UMLDoc::tagEq(tag, QLatin1String("name"))) {
-                m_name = elem.attribute(QLatin1String("xmi.value"));
-                if (m_name.isEmpty())
-                    m_name = elem.text();
-            } else if (UMLDoc::tagEq(tag, QLatin1String("visibility"))) {
-                QString vis = elem.attribute(QLatin1String("xmi.value"));
-                if (vis.isEmpty())
-                    vis = elem.text();
-                if (vis == QLatin1String("private") || vis == QLatin1String("private_vis"))
-                    m_visibility = Uml::Visibility::Private;
-                else if (vis == QLatin1String("protected") || vis == QLatin1String("protected_vis"))
-                    m_visibility = Uml::Visibility::Protected;
-                else if (vis == QLatin1String("implementation"))
-                    m_visibility = Uml::Visibility::Implementation;
-            } else if (UMLDoc::tagEq(tag, QLatin1String("isAbstract"))) {
-                QString isAbstract = elem.attribute(QLatin1String("xmi.value"));
-                if (isAbstract.isEmpty())
-                    isAbstract = elem.text();
-                m_bAbstract = (isAbstract == QLatin1String("true"));
-            } else if (UMLDoc::tagEq(tag, QLatin1String("ownerScope"))) {
-                QString ownerScope = elem.attribute(QLatin1String("xmi.value"));
-                if (ownerScope.isEmpty())
-                    ownerScope = elem.text();
-                m_bStatic = (ownerScope == QLatin1String("classifier"));
-            } else {
-                loadStereotype(elem);
-            }
-            node = node.nextSibling();
-            if (node.isComment())
-                node = node.nextSibling();
-            elem = node.toElement();
-        }
-    }
-
-    // Operations, attributes, enum literals, templates, stereotypes,
-    // and association role objects get added and signaled elsewhere.
-    if (m_BaseType != ot_Operation && m_BaseType != ot_Attribute &&
-        m_BaseType != ot_EnumLiteral && m_BaseType != ot_EntityAttribute &&
-        m_BaseType != ot_Template && m_BaseType != ot_Stereotype &&
-        m_BaseType != ot_Role && m_BaseType != ot_UniqueConstraint &&
-        m_BaseType != ot_ForeignKeyConstraint && m_BaseType != ot_CheckConstraint) {
-        if (m_pUMLPackage) {
-            m_pUMLPackage->addObject(this);
-        } else if (umldoc->rootFolderType(this) == Uml::ModelType::N_MODELTYPES) {
-            // m_pUMLPackage is not set on the root folders.
-            uDebug() << m_name << ": m_pUMLPackage is not set";
-        }
-    }
-    return load(element);
-}
-
-/**
- * Helper function for debug output.
- * Returns the given enum value as string.
- * @param ot   ObjectType of which a string representation is wanted
- * @return   the ObjectType as string
- */
-QString UMLObject::toString(ObjectType ot)
-{
-    return QLatin1String(ENUM_NAME(UMLObject, ObjectType, ot));
-}
-
-/**
- * Returns the given object type value as localized string.
- * @param ot   ObjectType of which a string representation is wanted
- * @return   the ObjectType as localized string
- */
-QString UMLObject::toI18nString(ObjectType t)
-{
-    QString name;
-
-    switch (t) {
-    case UMLObject::ot_Actor:
-        name = i18n("Actor &name:");
-        break;
-    case  UMLObject::ot_Artifact:
-        name = i18n("Artifact &name:");
-        break;
-    case UMLObject::ot_Class:
-        name = i18n("Class &name:");
-        break;
-    case  UMLObject::ot_Component:
-        name = i18n("Component &name:");
-        break;
-    case  UMLObject::ot_Datatype:
-        name = i18n("Datatype &name:");
-        break;
-    case  UMLObject::ot_Entity:
-        name = i18n("Entity &name:");
-        break;
-    case  UMLObject::ot_Enum:
-        name = i18n("Enum &name:");
-        break;
-    case  UMLObject::ot_Folder:
-        name = i18n("Folder &name:");
-        break;
-    case  UMLObject::ot_Interface:
-        name = i18n("Interface &name:");
-        break;
-    case  UMLObject::ot_Node:
-        name = i18n("Node &name:");
-        break;
-    case  UMLObject::ot_Package:
-        name = i18n("Package &name:");
-        break;
-    case  UMLObject::ot_Port:
-        name = i18n("Port &name:");
-        break;
-    case  UMLObject::ot_Stereotype:
-        name = i18n("Stereotype &name:");
-        break;
-    case  UMLObject::ot_UseCase:
-        name = i18n("Use case &name:");
-        break;
-    default:
-        name = QLatin1String("<unknown> &name:");
-        uWarning() << "unknown object type";
-        break;
-    }
-    return name;
-}
-
-/**
- * Print UML Object to debug output stream, so it can be used like
- *   uDebug() << "This object shouldn't be here: " << illegalObject;
- */
-QDebug operator<<(QDebug out, const UMLObject& obj)
-{
-    out.nospace() << "UMLObject: name= " << obj.name()
-        << ", type= " << UMLObject::toString(obj.m_BaseType);
-    return out.space();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/umlobject.h umbrello-15.08.1/umbrello/umlobject.h
--- umbrello-15.08.1.orig/umbrello/umlobject.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlobject.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,198 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLOBJECT_H
-#define UMLOBJECT_H
-
-#include "basictypes.h"
-#include "umlpackagelist.h"
-
-//qt includes
-#include <QDomDocument>
-#include <QDomElement>
-#include <QObject>
-#include <QPointer>
-#include <QString>
-
-class UMLStereotype;
-
-/**
- * This class is the non-graphical version of @ref UMLWidget.  These are
- * created and maintained in the class @ref UMLDoc.  This class holds all
- * the generic information needed for all UML objects.
- *
- * @ref clone needs to be implemented by each child class.
- *
- * @ref saveToXMI saves the XMI attributes of each specific model class.
- * It needs to be implemented by each child class.
- * For creating the QDomElement and saving the common XMI parts,
- * it can use the save() method.
- *
- * @short The base class for UML objects.
- * @author Paul Hensgen <phensgen@techie.com>
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLObject : public QObject
-{
-    Q_OBJECT
-    Q_ENUMS(ObjectType)
-
-public:
-    enum ObjectType
-    {
-        ot_Unknown = -1,
-        ot_UMLObject  = 100,
-        ot_Actor,
-        ot_UseCase,
-        ot_Package,
-        ot_Interface,
-        ot_Datatype,
-        ot_Enum,
-        ot_Class,
-        ot_Association,
-        ot_Attribute,
-        ot_Operation,
-        ot_EnumLiteral,
-        ot_Template,
-        ot_Component,
-        ot_Artifact,
-        ot_Node,
-        ot_Stereotype,
-        ot_Role,
-        ot_Entity,
-        ot_EntityAttribute,
-        ot_Folder,
-        ot_EntityConstraint,
-        ot_UniqueConstraint,
-        ot_ForeignKeyConstraint,
-        ot_CheckConstraint,
-        ot_Category,
-        ot_Port
-    };
-
-    static QString toString(ObjectType ot);
-    static QString toI18nString(ObjectType t);
-
-    explicit UMLObject(const UMLObject& other);
-    explicit UMLObject(UMLObject* parent, const QString& name, Uml::ID::Type id = Uml::ID::None);
-    explicit UMLObject(UMLObject* parent);
-    explicit UMLObject(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
-    virtual ~UMLObject();
-
-    bool operator==(const UMLObject & rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    virtual void setBaseType(ObjectType ot);
-    ObjectType baseType() const;
-    QLatin1String baseTypeStr() const;
-
-    virtual void setID(Uml::ID::Type NewID);
-    virtual Uml::ID::Type id() const;
-
-    QString doc() const;
-    bool hasDoc() const;
-    void setDoc(const QString &d);
-
-    void setVisibility(Uml::Visibility::Enum visibility);
-    void setVisibilityCmd(Uml::Visibility::Enum visibility);
-    Uml::Visibility::Enum visibility() const;
-
-    void setStereotype(const QString &_name);
-    void setStereotypeCmd(const QString &_name);
-    QString stereotype(bool includeAdornments = false) const;
-
-    void setUMLStereotype(UMLStereotype *stereo);
-    UMLStereotype *umlStereotype();
-
-    QString package(const QString& separator = QString(),
-                    bool includeRoot = false);
-
-    bool setUMLPackage(UMLPackage* pPkg);
-    UMLPackage* umlPackage();
-
-    UMLPackageList packages(bool includeRoot = false) const;
-
-    virtual void setName(const QString &strName);
-    void setNameCmd(const QString &strName) ;
-    QString name() const;
-
-    virtual QString fullyQualifiedName(const QString& separator = QString(),
-                                       bool includeRoot = false) const;
-
-    void setAbstract(bool bAbstract);
-    bool isAbstract() const;
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-    virtual bool resolveRef();
-
-    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-    virtual bool loadFromXMI(QDomElement & element);
-
-    bool loadStereotype(QDomElement & element);
-
-    void setStatic(bool bStatic);
-    bool isStatic() const;
-
-    virtual bool acceptAssociationType(Uml::AssociationType::Enum);  //:TODO: check if this is really needed here
-
-    void setSecondaryId(const QString& id);
-    QString secondaryId() const;
-
-    void setSecondaryFallback(const QString& id);
-    QString secondaryFallback() const;
-
-    QDomElement save(const QString &tag, QDomDocument & qDoc);
-
-    friend QDebug operator<< (QDebug out, const UMLObject& obj);
-
-public slots:
-    void emitModified();
-
-signals:
-    void modified();
-
-protected:
-    void init();
-
-    void maybeSignalObjectCreated();
-
-    virtual bool load(QDomElement& element);
-
-    Uml::ID::Type          m_nId;          ///< object's id
-    QString                m_Doc;          ///< object's documentation
-    UMLPackage*            m_pUMLPackage;  ///< package the object belongs to if applicable
-    UMLStereotype*         m_pStereotype;  ///< stereotype of the object if applicable
-    QString                m_name;         ///< objects name
-    ObjectType             m_BaseType;     ///< objects type
-    Uml::Visibility::Enum  m_visibility;   ///< objects visibility
-    bool                   m_bAbstract;    ///< state of whether the object is abstract or not
-    bool                   m_bStatic;      ///< flag for instance scope
-    bool                   m_bInPaste;     ///< caller sets this true when in paste operation
-    bool        m_bCreationWasSignalled;   ///< auxiliary to maybeSignalObjectCreated()
-    QPointer<UMLObject>    m_pSecondary;   ///< pointer to an associated object
-                                           ///< Only a few of the classes inheriting from UMLObject use this.
-                                           ///< However, it needs to be here because of inheritance graph
-                                           ///< disjunctness.
-    QString                m_SecondaryId;  ///< xmi.id of the secondary object for intermediate use during
-                                           ///< loading. The secondary ID is resolved to the m_pSecondary
-                                           ///< in the course of resolveRef() at the end of loading.
-    QString           m_SecondaryFallback; ///< Last-chance backup for when m_SecondaryId is not found.
-                                           ///< Used by Rose import: MDL files specify both a "quidu"
-                                           ///< (which corresponds to m_SecondaryId) and the human readable
-                                           ///< fully qualified target name of a reference.
-                                           ///< In case the quidu is not found, the human readable name is
-                                           ///< used which we store in m_SecondaryFallback.
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlobjectlist.cpp umbrello-15.08.1/umbrello/umlobjectlist.cpp
--- umbrello-15.08.1.orig/umbrello/umlobjectlist.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlobjectlist.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,53 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "umlobjectlist.h"
-#include "umlobject.h"
-
-UMLObjectList::UMLObjectList()
-{
-}
-
-UMLObjectList::~UMLObjectList()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the new
- * object.
- */
-void UMLObjectList::copyInto(UMLObjectList *rhs) const
-{
-    // Don't copy yourself.
-    if (rhs == this) return;
-
-    rhs->clear();
-
-    // Suffering from const; we shall not modify our object.
-    UMLObjectList *tmp = new UMLObjectList(*this);
-
-    UMLObject *item = NULL;
-    for (UMLObjectListIt oit(*tmp); oit.hasNext() ;)
-    {
-        item = oit.next();
-        rhs->append(item->clone());
-    }
-    delete tmp;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObjectList* UMLObjectList::clone() const
-{
-    UMLObjectList *clone = new UMLObjectList();
-    copyInto(clone);
-    return clone;
-}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlobjectlist.h umbrello-15.08.1/umbrello/umlobjectlist.h
--- umbrello-15.08.1.orig/umbrello/umlobjectlist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlobjectlist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,40 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2001      Gustavo Madrigal gmadrigal@nextphere.com      *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLOBJECTLIST_H
-#define UMLOBJECTLIST_H
-
-#include <QList>
-#include <QPointer>
-
-// forward declarations
-class UMLObject;
-
-typedef QListIterator<QPointer<UMLObject> >
-UMLObjectListIt;
-
-/**
- * This sub-class adds copyInto and clone to the QList<UMLObject*>
- * base class.
- */
-class UMLObjectList : public QList<QPointer<UMLObject> >
-{
-public:
-
-    UMLObjectList();
-    virtual ~UMLObjectList();
-
-    virtual void copyInto(UMLObjectList *rhs) const;
-
-    virtual UMLObjectList* clone() const;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umloperationlist.h umbrello-15.08.1/umbrello/umloperationlist.h
--- umbrello-15.08.1.orig/umbrello/umloperationlist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umloperationlist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,23 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2007                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLOPERATIONLIST_H
-#define UMLOPERATIONLIST_H
-
-#include <qlist.h>
-
-// forward declaration
-class UMLOperation;
-
-typedef QList<UMLOperation*> UMLOperationList;
-typedef QListIterator<UMLOperation*> UMLOperationListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlpackagelist.h umbrello-15.08.1/umbrello/umlpackagelist.h
--- umbrello-15.08.1.orig/umbrello/umlpackagelist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlpackagelist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,22 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2007                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLPACKAGELIST_H
-#define UMLPACKAGELIST_H
-
-#include <qlist.h>
-
-class UMLPackage;
-
-typedef QList<UMLPackage*> UMLPackageList;
-typedef QListIterator<UMLPackage*> UMLPackageListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlrole.cpp umbrello-15.08.1/umbrello/umlrole.cpp
--- umbrello-15.08.1.orig/umbrello/umlrole.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlrole.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,415 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "umlrole.h"
-
-// local includes
-#include "association.h"
-#include "debug_utils.h"
-#include "umldoc.h"
-#include "umlroledialog.h"
-#include "uml.h"
-
-// qt includes
-#include <QPointer>
-#include <QRegExp>
-
-/**
- * Sets up an association.
- *
- * @param parent     The parent (association) of this UMLRole.
- * @param parentObj  The Parent UML Object of this UMLRole
- * @param role       The Uml::RoleType::Enum of this UMLRole
- */
-UMLRole::UMLRole(UMLAssociation * parent, UMLObject * parentObj, Uml::RoleType::Enum role)
-  : UMLObject(const_cast<UMLAssociation*>(parent)),
-    m_pAssoc(parent),
-    m_role(role),
-    m_Multi(QString()),
-    m_Changeability(Uml::Changeability::Changeable)
-{
-    m_BaseType = UMLObject::ot_Role;
-    m_name.clear();
-    m_pSecondary = parentObj;
-
-    // connect this up to parent
-    connect(this, SIGNAL(modified()), parent, SIGNAL(modified()));
-}
-
-/**
- * Standard destructor.
- */
-UMLRole::~UMLRole()
-{
-}
-
-/**
- * Overloaded '==' operator.
- */
-bool UMLRole::operator==(const UMLRole &rhs) const
-{
-    if (this == &rhs) {
-        return true;
-    }
-    return (UMLObject::operator==(rhs) &&
-             m_Changeability == rhs.m_Changeability &&
-             m_Multi == rhs.m_Multi &&
-             m_name == rhs.m_name
-          );
-}
-
-UMLAssociation * UMLRole::parentAssociation() const
-{
-    return m_pAssoc;
-}
-
-/**
- * Returns the UMLObject assigned to the role.
- * @return  Pointer to the UMLObject in role.
- */
-UMLObject* UMLRole::object() const
-{
-    return m_pSecondary;
-}
-
-/**
- * Returns the Changeablity of the role.
- *
- * @return  Changeability of role.
- */
-Uml::Changeability::Enum UMLRole::changeability() const
-{
-    return m_Changeability;
-}
-
-/**
- * Returns the multiplicity assigned to the role.
- *
- * @return  The multiplicity assigned to the role.
- */
-QString UMLRole::multiplicity() const
-{
-    return m_Multi;
-}
-
-/**
- * Sets the UMLObject playing the role in the association.
- *
- * @param obj   Pointer to the UMLObject of role.
- */
-void UMLRole::setObject(UMLObject *obj)
-{
-    // because we will get the id of this role from the parent
-    // object, we CANT allow UMLRoles to take other UMLRoles as
-    // parent objects. In fact, there is probably good reason
-    // to only take UMLClassifiers here, but I'll leave it more open
-    // for the time being. -b.t.
-    if (obj && dynamic_cast<UMLRole*>(obj)) {
-        uError() << "UMLRole(" << Uml::ID::toString(m_nId) << ") cannot setObject() to another UMLRole("
-            << Uml::ID::toString(obj->id()) << ")";
-        return;
-    }
-
-    m_pSecondary = obj;
-    UMLObject::emitModified();
-}
-
-/**
- * Sets the changeability of the role.
- *
- * @param value   Changeability::Enum of role.
- */
-void UMLRole::setChangeability(Uml::Changeability::Enum value)
-{
-    m_Changeability = value;
-    UMLObject::emitModified();
-}
-
-/**
- * Sets the multiplicity of the role.
- *
- * @param multi   The multiplicity of role.
- */
-void UMLRole::setMultiplicity(const QString &multi)
-{
-    m_Multi = multi;
-    UMLObject::emitModified();
-}
-
-/**
- * Get the 'id' of the role (NOT the parent object). This could be
- * either Uml::RoleType::A or Uml::RoleType::B. Yes, it would be better if we
- * could get along without this, but we need it to distinguish saved
- * umlrole objects in the XMI for 'self' associations where both roles
- * will point to the same underlying UMLObject.
- */
-Uml::RoleType::Enum UMLRole::role() const
-{
-    return m_role;
-}
-
-/**
- * Creates the <UML:AssociationEnd> XMI element.
- */
-void UMLRole::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement roleElement = UMLObject::save(QLatin1String("UML:AssociationEnd"), qDoc);
-    if (m_pSecondary)
-        roleElement.setAttribute(QLatin1String("type"), Uml::ID::toString(m_pSecondary->id()));
-    else
-        uError() << "id " << Uml::ID::toString(m_nId) << ": m_pSecondary is NULL";
-    if (!m_Multi.isEmpty())
-        roleElement.setAttribute(QLatin1String("multiplicity"), m_Multi);
-    if (m_role == Uml::RoleType::A) {  // role aggregation based on parent type
-        // role A
-        switch (m_pAssoc->getAssocType()) {
-        case Uml::AssociationType::Composition:
-            roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("composite"));
-            break;
-        case Uml::AssociationType::Aggregation:
-            roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("aggregate"));
-            break;
-        default:
-            roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("none"));
-            break;
-        }
-        if (m_pAssoc->getAssocType() == Uml::AssociationType::UniAssociation) {
-            // Normally the isNavigable attribute is "true".
-            // We set it to false on role A to indicate that
-            // role B gets an explicit arrowhead.
-            roleElement.setAttribute(QLatin1String("isNavigable"), QLatin1String("false"));
-        } else {
-            roleElement.setAttribute(QLatin1String("isNavigable"), QLatin1String("true"));
-        }
-    } else {
-        roleElement.setAttribute(QLatin1String("aggregation"), QLatin1String("none"));
-        roleElement.setAttribute(QLatin1String("isNavigable"), QLatin1String("true"));
-        //FIXME obviously this isn't standard XMI
-        if (m_pAssoc->getAssocType() == Uml::AssociationType::Relationship) {
-            roleElement.setAttribute(QLatin1String("relationship"), QLatin1String("true"));
-        }
-    }
-
-    roleElement.setAttribute(QLatin1String("visibility"), Uml::Visibility::toString(visibility(), false));
-
-    switch (m_Changeability) {
-        case Uml::Changeability::Frozen:
-            roleElement.setAttribute(QLatin1String("changeability"), QLatin1String("frozen"));
-            break;
-        case Uml::Changeability::AddOnly:
-            roleElement.setAttribute(QLatin1String("changeability"), QLatin1String("addOnly"));
-            break;
-        case Uml::Changeability::Changeable:
-            roleElement.setAttribute(QLatin1String("changeability"), QLatin1String("changeable"));
-            break;
-    }
-    qElement.appendChild(roleElement);
-}
-
-/**
- * Display the properties configuration dialog for the object.
- *
- * @param parent    The parent widget.
- * @return  True for success of this operation.
- */
-bool UMLRole::showPropertiesDialog(QWidget *parent)
-{
-    QPointer<UMLRoleDialog> dlg = new UMLRoleDialog(parent, this);
-    bool modified = false;
-    if (dlg->exec() == QDialog::Accepted) {
-        modified = true;
-    }
-    delete dlg;
-    return modified;
-}
-
-/**
- * Loads the <UML:AssociationEnd> XMI element.
- * Auxiliary to UMLObject::loadFromXMI.
- */
-bool UMLRole::load(QDomElement & element)
-{
-    UMLDoc * doc = UMLApp::app()->document();
-    QString type = element.attribute(QLatin1String("type"));
-    if (!type.isEmpty()) {
-        if (!m_SecondaryId.isEmpty())
-            uWarning() << "overwriting old m_SecondaryId \"" << m_SecondaryId
-                << " with new value \"" << type << "\"";
-        m_SecondaryId = type;
-    }
-    // Inspect child nodes - for multiplicity (and type if not set above.)
-    for (QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling()) {
-        if (node.isComment())
-            continue;
-        QDomElement tempElement = node.toElement();
-        QString tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("name"))) {
-            m_name = tempElement.text();
-        } else if (UMLDoc::tagEq(tag, QLatin1String("AssociationEnd.multiplicity"))) {
-            /*
-             * There are different ways in which the multiplicity might be given:
-             *  - direct value in the <AssociationEnd.multiplicity> tag,
-             *  - attributes "lower" and "upper" of a subordinate <MultiplicityRange>,
-             *  - direct value in subordinate <MultiplicityRange.lower> and
-             *    <MultiplicityRange.upper> tags
-             */
-            QDomNode n = tempElement.firstChild();
-            if (node.isNull() || tempElement.isNull() || n.isNull() ||
-                    n.toElement().isNull()) {
-                m_Multi = tempElement.text().trimmed();
-                continue;
-            }
-            tempElement = n.toElement();
-            tag = tempElement.tagName();
-            if (!UMLDoc::tagEq(tag, QLatin1String("Multiplicity"))) {
-                m_Multi = tempElement.text().trimmed();
-                continue;
-            }
-            n = tempElement.firstChild();
-            tempElement = n.toElement();
-            tag = tempElement.tagName();
-            if (!UMLDoc::tagEq(tag, QLatin1String("Multiplicity.range"))) {
-                m_Multi = tempElement.text().trimmed();
-                continue;
-            }
-            n = tempElement.firstChild();
-            tempElement = n.toElement();
-            tag = tempElement.tagName();
-            if (!UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange"))) {
-                m_Multi = tempElement.text().trimmed();
-                continue;
-            }
-            QString multiUpper;
-            if (tempElement.hasAttribute(QLatin1String("lower"))) {
-                m_Multi = tempElement.attribute(QLatin1String("lower"));
-                multiUpper = tempElement.attribute(QLatin1String("upper"));
-                if (!multiUpper.isEmpty()) {
-                    if (!m_Multi.isEmpty())
-                        m_Multi.append(QLatin1String(".."));
-                    m_Multi.append(multiUpper);
-                }
-                continue;
-            }
-            n = tempElement.firstChild();
-            while (!n.isNull()) {
-                tempElement = n.toElement();
-                tag = tempElement.tagName();
-                if (UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange.lower"))) {
-                    m_Multi = tempElement.text();
-                } else if (UMLDoc::tagEq(tag, QLatin1String("MultiplicityRange.upper"))) {
-                    multiUpper = tempElement.text();
-                }
-                n = n.nextSibling();
-            }
-            if (!multiUpper.isEmpty()) {
-                if (!m_Multi.isEmpty())
-                    m_Multi.append(QLatin1String(".."));
-                m_Multi.append(multiUpper);
-            }
-        } else if (m_SecondaryId.isEmpty() &&
-                   (UMLDoc::tagEq(tag, QLatin1String("type")) ||
-                    UMLDoc::tagEq(tag, QLatin1String("participant")))) {
-            m_SecondaryId = tempElement.attribute(QLatin1String("xmi.id"));
-            if (m_SecondaryId.isEmpty())
-                m_SecondaryId = tempElement.attribute(QLatin1String("xmi.idref"));
-            if (m_SecondaryId.isEmpty()) {
-                QDomNode inner = tempElement.firstChild();
-                QDomElement innerElem = inner.toElement();
-                m_SecondaryId = innerElem.attribute(QLatin1String("xmi.id"));
-                if (m_SecondaryId.isEmpty())
-                    m_SecondaryId = innerElem.attribute(QLatin1String("xmi.idref"));
-            }
-        }
-    }
-    if (!m_Multi.isEmpty())
-        uDebug() << name() << ": m_Multi is " << m_Multi;
-    if (m_SecondaryId.isEmpty()) {
-        uError() << name() << ": type not given or illegal";
-        return false;
-    }
-    UMLObject * obj;
-    obj = doc->findObjectById(Uml::ID::fromString(m_SecondaryId));
-    if (obj) {
-        m_pSecondary = obj;
-        m_SecondaryId = QString();
-    }
-
-    // block signals to prevent needless updating
-    blockSignals(true);
-    // Here comes the handling of the association type.
-    // This is open for discussion - I'm pretty sure there are better ways..
-
-    // Yeah, for one, setting the *parent* object parameters from here is sucky
-    // as hell. Why are we using roleA to store what is essentially a parent (association)
-    // parameter, eh? The UML13.dtd is pretty silly, but since that is what
-    // is driving us to that point, we have to go with it. Some analysis of
-    // the component roles/linked items needs to be done in order to get things
-    // right. *sigh* -b.t.
-
-    // Setting association type from the role (A)
-    // Determination of the "aggregation" attribute used to be done only
-    // when (m_role == Uml::RoleType::A) but some XMI writers (e.g. StarUML) place
-    // the aggregation attribute at role B.
-    // The role end with the aggregation unequal to "none" wins.
-    QString aggregation = element.attribute(QLatin1String("aggregation"), QLatin1String("none"));
-    if (aggregation == QLatin1String("composite"))
-        m_pAssoc->setAssociationType(Uml::AssociationType::Composition);
-    else if (aggregation == QLatin1String("shared")       // UML1.3
-          || aggregation == QLatin1String("aggregate"))   // UML1.4
-        m_pAssoc->setAssociationType(Uml::AssociationType::Aggregation);
-
-    if (!element.hasAttribute(QLatin1String("isNavigable"))) {
-        // Backward compatibility mode: In Umbrello version 1.3.x the
-        // logic for saving the isNavigable flag was wrong.
-        // May happen on loading role A.
-        m_pAssoc->setOldLoadMode(true);
-    } else if (m_pAssoc->getOldLoadMode() == true) {
-        // Here is the original logic:
-        // "Role B:
-        //  If isNavigable is not given, we make no change to the
-        //  association type.
-        //  If isNavigable is given, and is "true", then we assume that
-        //  the association's other end (role A) is not navigable, and
-        //  therefore we change the association type to UniAssociation.
-        //  The case that isNavigable is given as "false" is ignored.
-        //  Combined with the association type logic for role A, this
-        //  allows us to support at_Association and at_UniAssociation."
-        if (element.attribute(QLatin1String("isNavigable")) == QLatin1String("true"))
-            m_pAssoc->setAssociationType(Uml::AssociationType::UniAssociation);
-    } else if (element.attribute(QLatin1String("isNavigable")) == QLatin1String("false")) {
-        m_pAssoc->setAssociationType(Uml::AssociationType::UniAssociation);
-    }
-
-    //FIXME not standard XMI
-    if (element.hasAttribute(QLatin1String("relationship"))) {
-        if (element.attribute(QLatin1String("relationship")) == QLatin1String("true")) {
-            m_pAssoc->setAssociationType(Uml::AssociationType::Relationship);
-        }
-    }
-
-    if (m_Multi.isEmpty())
-        m_Multi = element.attribute(QLatin1String("multiplicity"));
-
-    // Changeability defaults to Changeable if it cant set it here..
-    m_Changeability = Uml::Changeability::Changeable;
-    QString changeability = element.attribute(QLatin1String("changeability"));
-    if (changeability.isEmpty())
-        element.attribute(QLatin1String("changeable"));  // for backward compatibility
-    if (changeability == QLatin1String("frozen"))
-        m_Changeability = Uml::Changeability::Frozen;
-    else if (changeability == QLatin1String("addOnly"))
-        m_Changeability = Uml::Changeability::AddOnly;
-
-    // finished config, now unblock
-    blockSignals(false);
-    return true;
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/umlrole.h umbrello-15.08.1/umbrello/umlrole.h
--- umbrello-15.08.1.orig/umbrello/umlrole.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlrole.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,65 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLROLE_H
-#define UMLROLE_H
-
-#include "umlobject.h"
-
-class UMLAssociation;
-
-/**
- * This class contains the non-graphic representation of an association role.
- *
- * @author Brian Thomas <brian.thomas@gsfc.nasa.gov>
- * @see UMLObject
- */
-class UMLRole : public UMLObject
-{
-    Q_OBJECT
-public:
-
-    UMLRole(UMLAssociation * parent, UMLObject * parentUMLObject, Uml::RoleType::Enum role);
-    virtual ~UMLRole();
-
-    bool operator==(const UMLRole & rhs) const;
-
-    void setObject(UMLObject *obj);
-    UMLObject* object() const;
-
-    void setChangeability(Uml::Changeability::Enum value);
-    Uml::Changeability::Enum changeability() const;
-
-    void setMultiplicity(const QString &multi);
-    QString multiplicity() const;
-
-    UMLAssociation * parentAssociation() const;
-
-    Uml::RoleType::Enum role() const;
-
-    UMLObject* clone() const { return NULL; }
-
-    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-    virtual bool showPropertiesDialog(QWidget *parent = 0);
-
-protected:
-
-    bool load(QDomElement& element);
-
-private:
-
-    UMLAssociation *           m_pAssoc;
-    Uml::RoleType::Enum        m_role;
-    QString                    m_Multi;
-    Uml::Changeability::Enum   m_Changeability;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlstereotypelist.h umbrello-15.08.1/umbrello/umlstereotypelist.h
--- umbrello-15.08.1.orig/umbrello/umlstereotypelist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umlstereotypelist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,22 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2012                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLSTEREOTYPELIST_H
-#define UMLSTEREOTYPELIST_H
-
-#include <QList>
-
-// forward declaration
-class UMLStereotype;
-
-typedef QList<UMLStereotype*> UMLStereotypeList;
-typedef QListIterator<UMLStereotype*> UMLStereotypeListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umltemplatelist.h umbrello-15.08.1/umbrello/umltemplatelist.h
--- umbrello-15.08.1.orig/umbrello/umltemplatelist.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/umltemplatelist.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,23 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2004-2007                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UMLTEMPLATELIST_H
-#define UMLTEMPLATELIST_H
-
-#include <qlist.h>
-
-// forward declaration
-class UMLTemplate;
-
-typedef QList<UMLTemplate*> UMLTemplateList;
-typedef QListIterator<UMLTemplate*> UMLTemplateListIt;
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/activitywidget.cpp umbrello-15.08.1/umbrello/umlwidgets/activitywidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/activitywidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/activitywidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,457 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "activitywidget.h"
+
+// app includes
+#include "activitydialog.h"
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "listpopupmenu.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPointer>
+/**
+ * Creates a Activity widget.
+ *
+ * @param scene          The parent of the widget.
+ * @param activityType   The type of activity.
+ * @param id             The ID to assign (-1 will prompt a new ID.)
+ */
+ActivityWidget::ActivityWidget(UMLScene * scene, ActivityType activityType, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Activity, id),
+    m_activityType(activityType)
+{
+    // set non zero size to avoid crash on painting
+    setSize(1, 1);
+}
+
+/**
+ *  Destructor.
+ */
+ActivityWidget::~ActivityWidget()
+{
+}
+
+/**
+ * Returns the type of activity.
+ */
+ActivityWidget::ActivityType ActivityWidget::activityType() const
+{
+    return m_activityType;
+}
+
+/**
+ * Returns the type string of activity.
+ */
+QString ActivityWidget::activityTypeStr() const
+{
+    return QLatin1String(ENUM_NAME(ActivityWidget, ActivityType, m_activityType));
+}
+
+/**
+ * Sets the type of activity.
+ */
+void ActivityWidget::setActivityType(ActivityType activityType)
+{
+    m_activityType = activityType;
+    updateGeometry();
+    UMLWidget::m_resizable = true;
+}
+
+/**
+ * Determines whether a toolbar button represents an Activity.
+ * CHECK: currently unused - can this be removed?
+ *
+ * @param tbb               The toolbar button enum input value.
+ * @param resultType        The ActivityType corresponding to tbb.
+ *                  This is only set if tbb is an Activity.
+ * @return  True if tbb represents an Activity.
+ */
+bool ActivityWidget::isActivity(WorkToolBar::ToolBar_Buttons tbb,
+                                ActivityType& resultType)
+{
+    bool status = true;
+    switch (tbb) {
+    case WorkToolBar::tbb_Initial_Activity:
+        resultType = Initial;
+        break;
+    case WorkToolBar::tbb_Activity:
+        resultType = Normal;
+        break;
+    case WorkToolBar::tbb_End_Activity:
+        resultType = End;
+        break;
+    case WorkToolBar::tbb_Final_Activity:
+        resultType = Final;
+        break;
+    case WorkToolBar::tbb_Branch:
+        resultType = Branch;
+        break;
+    default:
+        status = false;
+        break;
+    }
+    return status;
+}
+
+/**
+ * This method get the name of the preText attribute.
+ */
+QString ActivityWidget::preconditionText() const
+{
+    return m_preconditionText;
+}
+
+/**
+ * This method set the name of the preText attribute
+ */
+void ActivityWidget::setPreconditionText(const QString& aPreText)
+{
+    m_preconditionText = aPreText;
+    updateGeometry();
+    adjustAssocs(x(), y());
+}
+
+/**
+ * This method get the name of the postText attribute.
+ */
+QString ActivityWidget::postconditionText() const
+{
+    return m_postconditionText;
+}
+
+/**
+ * This method set the name of the postText attribute
+ */
+void ActivityWidget::setPostconditionText(const QString& aPostText)
+{
+    m_postconditionText = aPostText;
+    updateGeometry();
+    adjustAssocs(x(), y());
+}
+
+/**
+ * Reimplemented from UMLWidget::showPropertiesDialog to show a
+ * properties dialog for an ActivityWidget.
+ */
+void ActivityWidget::showPropertiesDialog()
+{
+    UMLApp::app()->docWindow()->updateDocumentation(false);
+
+    QPointer<ActivityDialog> dialog = new ActivityDialog(umlScene()->activeView(), this);
+    if (dialog->exec() && dialog->getChangesMade()) {
+        UMLApp::app()->docWindow()->showDocumentation(this, true);
+        UMLApp::app()->document()->setModified(true);
+    }
+    delete dialog;
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void ActivityWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+    int w = width();
+    int h = height();
+
+    // Only for the final activity
+    float x;
+    float y;
+    QPen pen = painter->pen();
+
+    switch (m_activityType)
+    {
+    case Normal:
+        UMLWidget::setPenFromSettings(painter);
+        if (UMLWidget::useFillColor()) {
+            painter->setBrush(UMLWidget::fillColor());
+        }
+        {
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing();
+            int textStartY = (h / 2) - (fontHeight / 2);
+            painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
+            painter->setPen(textColor());
+            painter->setFont(UMLWidget::font());
+            painter->drawText(ACTIVITY_MARGIN, textStartY,
+                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
+        }
+        break;
+
+    case Initial:
+        painter->setPen(QPen(WidgetBase::lineColor(), 1));
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(0, 0, w, h);
+        break;
+
+    case Final:
+        UMLWidget::setPenFromSettings(painter);
+        painter->setBrush(Qt::white);
+        pen.setWidth(2);
+        pen.setColor (Qt::red);
+        painter->setPen(pen);
+        painter->drawEllipse(0, 0, w, h);
+        x = w/2 ;
+        y = h/2 ;
+        {
+            const float w2 = 0.7071 * (float)w / 2.0;
+            painter->drawLine((int)(x - w2 + 1), (int)(y - w2 + 1), (int)(x + w2), (int)(y + w2));
+            painter->drawLine((int)(x + w2 - 1), (int)(y - w2 + 1), (int)(x - w2), (int)(y + w2));
+        }
+        break;
+
+    case End:
+        painter->setPen(QPen(WidgetBase::lineColor(), 1));
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(0, 0, w, h);
+        painter->setBrush(Qt::white);
+        painter->drawEllipse(1, 1, w - 2, h - 2);
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(3, 3, w - 6, h - 6);
+        break;
+
+    case Branch:
+        UMLWidget::setPenFromSettings(painter);
+        if (UMLWidget::useFillColor()) {
+            painter->setBrush(UMLWidget::fillColor());
+        }
+        {
+            QPolygon array(4);
+            array[ 0 ] = QPoint(w / 2, 0);
+            array[ 1 ] = QPoint(w, h / 2);
+            array[ 2 ] = QPoint(w / 2, h);
+            array[ 3 ] = QPoint(0, h / 2);
+            painter->drawPolygon(array);
+            painter->drawPolyline(array);
+        }
+        break;
+
+    case Invok:
+        UMLWidget::setPenFromSettings(painter);
+        if (UMLWidget::useFillColor()) {
+            painter->setBrush(UMLWidget::fillColor());
+        }
+        {
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing();
+            int textStartY = (h / 2) - (fontHeight / 2);
+            painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
+            painter->setPen(textColor());
+            painter->setFont(UMLWidget::font());
+            painter->drawText(ACTIVITY_MARGIN, textStartY,
+                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
+
+        }
+        x = w - (w/5);
+        y = h - (h/3);
+
+        painter->drawLine((int)x, (int) y, (int)x, (int)(y + 20));
+        painter->drawLine((int)(x - 10), (int)(y + 10), (int)(x + 10), (int)(y + 10));
+        painter->drawLine((int)(x - 10), (int)(y + 10), (int)(x - 10), (int)(y + 20));
+        painter->drawLine((int)(x + 10), (int)(y + 10), (int)(x + 10), (int)(y + 20));
+        break;
+
+    case Param:
+        UMLWidget::setPenFromSettings(painter);
+        if (UMLWidget::useFillColor()) {
+            painter->setBrush(UMLWidget::fillColor());
+        }
+        {
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing();
+            QString preCond= QLatin1String("<<precondition>> ") + preconditionText();
+            QString postCond= QLatin1String("<<postcondition>> ") + postconditionText();
+            //int textStartY = (h / 2) - (fontHeight / 2);
+            painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
+            painter->setPen(textColor());
+            painter->setFont(UMLWidget::font());
+            painter->drawText(ACTIVITY_MARGIN, fontHeight + 10,
+                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, preCond);
+            painter->drawText(ACTIVITY_MARGIN, fontHeight * 2 + 10,
+                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, postCond);
+            painter->drawText(ACTIVITY_MARGIN, (fontHeight / 2),
+                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
+        }
+
+        break;
+    }
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overridden from UMLWidget due to emission of signal sigActMoved()
+ */
+void ActivityWidget::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    UMLWidget::moveWidgetBy(diffX, diffY);
+    emit sigActMoved(diffX, diffY);
+}
+
+/**
+ * Loads the widget from the "activitywidget" XMI element.
+ */
+bool ActivityWidget::loadFromXMI(QDomElement& qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement))
+        return false;
+    setName(qElement.attribute(QLatin1String("activityname")));
+    setDocumentation(qElement.attribute(QLatin1String("documentation")));
+    setPreconditionText(qElement.attribute(QLatin1String("precondition")));
+    setPostconditionText(qElement.attribute(QLatin1String("postcondition")));
+
+    QString type = qElement.attribute(QLatin1String("activitytype"), QLatin1String("1"));
+    setActivityType((ActivityType)type.toInt());
+
+    return true;
+}
+
+/**
+ * Saves the widget to the "activitywidget" XMI element.
+ */
+void ActivityWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement activityElement = qDoc.createElement(QLatin1String("activitywidget"));
+    UMLWidget::saveToXMI(qDoc, activityElement);
+    activityElement.setAttribute(QLatin1String("activityname"), name());
+    activityElement.setAttribute(QLatin1String("documentation"), documentation());
+    activityElement.setAttribute(QLatin1String("precondition"), preconditionText());
+    activityElement.setAttribute(QLatin1String("postcondition"), postconditionText());
+    activityElement.setAttribute(QLatin1String("activitytype"), m_activityType);
+    qElement.appendChild(activityElement);
+}
+
+/**
+ * Overrides Method from UMLWidget.
+ */
+void ActivityWidget::constrain(qreal& width, qreal& height)
+{
+    if (m_activityType == Normal || m_activityType == Invok || m_activityType == Param) {
+        UMLWidget::constrain(width, height);
+        return;
+    }
+
+    if (width > height)
+        width = height;
+    else if (height > width)
+        height = width;
+
+    UMLWidget::constrain(width, height);
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void ActivityWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString n = name();
+#if QT_VERSION >= 0x050000
+            n = QInputDialog::getText(Q_NULLPTR,
+                                      i18n("Enter Activity Name"),
+                                      i18n("Enter the name of the new activity:"),
+                                      QLineEdit::Normal,
+                                      n, &ok);
+#else
+            n = KInputDialog::getText(i18n("Enter Activity Name"),
+                                      i18n("Enter the name of the new activity:"),
+                                      n, &ok);
+#endif
+            if (ok && !n.isEmpty()) {
+                setName(n);
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Properties:
+        showPropertiesDialog();
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF ActivityWidget::minimumSize() const
+{
+    if (m_activityType == Normal || m_activityType == Invok || m_activityType == Param) {
+        const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+        const int fontHeight  = fm.lineSpacing();
+
+        int textWidth = fm.width(name());
+        int height = fontHeight;
+        height = height > ACTIVITY_HEIGHT ? height : ACTIVITY_HEIGHT;
+        height += ACTIVITY_MARGIN * 2;
+
+        textWidth = textWidth > ACTIVITY_WIDTH ? textWidth : ACTIVITY_WIDTH;
+
+        if (m_activityType == Invok) {
+             height += 40;
+        } else if (m_activityType == Param) {
+            QString maxSize;
+
+            maxSize = name().length() > postconditionText().length() ? name() : postconditionText();
+            maxSize = maxSize.length() > preconditionText().length() ? maxSize : preconditionText();
+
+            textWidth = fm.width(maxSize);
+            textWidth = textWidth + 50;
+            height += 100;
+        }
+
+        int width = textWidth > ACTIVITY_WIDTH ? textWidth : ACTIVITY_WIDTH;
+
+        width += ACTIVITY_MARGIN * 4;
+        return QSizeF(width, height);
+    }
+    else if (m_activityType == Branch) {
+        return QSizeF(20, 20);
+    }
+    return QSizeF(15, 15);
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF ActivityWidget::maximumSize()
+{
+    if (m_activityType == Normal || m_activityType == Invok || m_activityType == Param) {
+        return UMLWidget::maximumSize();
+    }
+    if (m_activityType == Branch) {
+        return QSizeF(50, 50);
+    }
+    return QSizeF(30, 30);
+}
+
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/activitywidget.h umbrello-15.08.1/umbrello/umlwidgets/activitywidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/activitywidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/activitywidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,98 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ACTIVITYWIDGET_H
+#define ACTIVITYWIDGET_H
+
+#include "umlwidget.h"
+#include "worktoolbar.h"
+
+#define ACTIVITY_MARGIN 5
+#define ACTIVITY_WIDTH 30
+#define ACTIVITY_HEIGHT 10
+
+/**
+ * This class is the graphical version of a UML Activity.  A ActivityWidget is created
+ * by a @ref UMLView.  An ActivityWidget belongs to only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
+ *
+ * The ActivityWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @short  A graphical version of a UML Activity.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ActivityWidget : public UMLWidget
+{
+    Q_OBJECT
+    Q_ENUMS(ActivityType)
+public:
+    enum ActivityType
+    {
+        Initial = 0,
+        Normal,
+        End,
+        Final,
+        Branch,
+        Invok,
+        Param
+    };
+
+    explicit ActivityWidget(UMLScene * scene, ActivityType activityType = Normal, Uml::ID::Type id = Uml::ID::None);
+    virtual ~ActivityWidget();
+
+    ActivityType activityType() const;
+    QString activityTypeStr() const;
+    void setActivityType(ActivityType activityType);
+
+    static bool isActivity(WorkToolBar::ToolBar_Buttons tbb,
+                            ActivityType& resultType);
+
+    QString preconditionText() const;
+    void setPreconditionText(const QString&);
+
+    QString postconditionText() const;
+    void setPostconditionText(const QString&);
+
+    virtual void showPropertiesDialog();
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    virtual void moveWidgetBy(qreal diffX, qreal diffY);
+
+    virtual bool loadFromXMI(QDomElement & qElement);
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    void constrain(qreal& width, qreal& height);
+
+signals:
+    /**
+     * Emitted when the activity widget is moved.
+     * Provides the delta X and delta Y amount by which the widget was moved
+     * relative to the previous position.
+     * Slots into PinWidget::slotActMoved()
+     * @param diffX The difference between previous and new X value.
+     * @param diffY The difference between previous and new Y value.
+     */
+    void sigActMoved(qreal diffX, qreal diffY);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+protected:
+    virtual QSizeF minimumSize() const;
+    virtual QSizeF maximumSize();
+
+    ActivityType m_activityType; ///< Type of activity.
+
+    QString m_preconditionText;
+    QString m_postconditionText;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/actorwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/actorwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/actorwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/actorwidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,104 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header file
+#include "actorwidget.h"
+
+// local includes
+#include "actor.h"
+#include "umlview.h"
+
+/**
+ * Constructs an ActorWidget.
+ *
+ * @param scene   The parent of this ActorWidget.
+ * @param a      The Actor class this ActorWidget will display.
+ */
+ActorWidget::ActorWidget(UMLScene * scene, UMLActor *a)
+  : UMLWidget(scene, WidgetBase::wt_Actor, a)
+{
+    setFixedAspectRatio(true);
+}
+
+/**
+ * Destructor.
+ */
+ActorWidget::~ActorWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void ActorWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+    UMLWidget::setPenFromSettings(painter);
+    if(UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    const int w = width();
+    const int h = height();
+    painter->setFont(UMLWidget::font());
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight = fm.lineSpacing();
+    bool drawStereotype = umlObject() && !umlObject()->stereotype().isEmpty();
+    const int a_height = h - (drawStereotype ? 2 * fontHeight : fontHeight) - A_MARGIN;
+    const int h2 = a_height / 2;
+    const int a_width = (h2);
+    const int middleX = w / 2;
+    const int thirdY = a_height / 3;
+
+    //draw actor
+    painter->drawEllipse(middleX - a_width / 2, 0, a_width, thirdY); //head
+    painter->drawLine(middleX, thirdY,
+               middleX, thirdY * 2); //body
+    painter->drawLine(middleX, 2 * thirdY,
+               middleX - a_width / 2, a_height); //left leg
+    painter->drawLine(middleX,  2 * thirdY,
+               middleX + a_width / 2, a_height); //right leg
+    painter->drawLine(middleX - a_width / 2, thirdY + thirdY / 2,
+               middleX + a_width / 2, thirdY + thirdY / 2); //arms
+    //draw text
+    painter->setPen(textColor());
+    if (drawStereotype)
+        painter->drawText(A_MARGIN, h - 2 * fontHeight, w - A_MARGIN * 2, fontHeight, Qt::AlignCenter, umlObject()->stereotype(true));
+    painter->drawText(A_MARGIN, h - fontHeight,
+               w - A_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Saves the widget to the "actorwidget" XMI element.
+ * Note: For loading from XMI, the inherited parent method is used.
+ */
+void ActorWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement actorElement = qDoc.createElement(QLatin1String("actorwidget"));
+    UMLWidget::saveToXMI(qDoc, actorElement);
+    qElement.appendChild(actorElement);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF ActorWidget::minimumSize() const
+{
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    const int textWidth = fm.width(name());
+    bool drawStereotype = umlObject() && !umlObject()->stereotype().isEmpty();
+    int width = textWidth > A_WIDTH ? textWidth : A_WIDTH;
+    int height = A_HEIGHT + (drawStereotype ? 2 * fontHeight : fontHeight) + A_MARGIN;
+    width += A_MARGIN * 2;
+    return QSizeF(width, height);
+}
+
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/actorwidget.h umbrello-15.08.1/umbrello/umlwidgets/actorwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/actorwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/actorwidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,55 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ACTORWIDGET_H
+#define ACTORWIDGET_H
+
+#include "umlwidget.h"
+
+#define A_WIDTH 20
+#define A_HEIGHT 40
+#define A_MARGIN 5
+
+class UMLActor;
+
+/**
+ * This class is the graphical version of a UML Actor.
+ * An ActorWidget is created by a @ref UMLView.  An ActorWidget belongs to only
+ * one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to is destroyed, the
+ * ActorWidget will be automatically deleted.
+ *
+ * If the UMLActor class that this ActorWidget is displaying is deleted, the
+ * @ref UMLView will make sure that this instance is also deleted.
+ *
+ * The ActorWidget class inherits from the @ref UMLWidget class
+ * which adds most of the functionality to this class.
+ *
+ * @short A graphical version of a UML Actor.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLWidget
+ * @see UMLView
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ActorWidget : public UMLWidget
+{
+public:
+    ActorWidget(UMLScene * scene, UMLActor *o);
+    virtual ~ActorWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+    QSizeF minimumSize() const;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/artifactwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/artifactwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/artifactwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/artifactwidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,293 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "artifactwidget.h"
+
+// app includes
+#include "artifact.h"
+#include "debug_utils.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+/**
+ * Constructs a ArtifactWidget.
+ *
+ * @param scene     The parent of this ArtifactWidget.
+ * @param a         The Artifact this widget will be representing.
+ */
+ArtifactWidget::ArtifactWidget(UMLScene *scene, UMLArtifact *a)
+  : UMLWidget(scene, WidgetBase::wt_Artifact, a)
+{
+    setSize(100, 30);
+}
+
+/**
+ * Destructor.
+ */
+ArtifactWidget::~ArtifactWidget()
+{
+}
+
+/**
+ * Reimplemented to paint the articraft widget. Some part of specific
+ * drawing is delegeted to private method like drawAsFile..
+ */
+void ArtifactWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    UMLWidget::setPenFromSettings(painter);
+    if (UMLWidget::useFillColor()) {
+        painter->setBrush(UMLWidget::fillColor());
+    } else {
+        painter->setBrush(m_scene->backgroundColor());
+    }
+
+    if (umlObject()) {
+        UMLArtifact *umlart = static_cast<UMLArtifact*>(m_umlObject);
+        UMLArtifact::Draw_Type drawType = umlart->getDrawAsType();
+        switch (drawType) {
+        case UMLArtifact::defaultDraw:
+            paintAsNormal(painter, option);
+            break;
+        case UMLArtifact::file:
+            paintAsFile(painter, option);
+            break;
+        case UMLArtifact::library:
+            paintAsLibrary(painter, option);
+            break;
+        case UMLArtifact::table:
+            paintAsTable(painter, option);
+            break;
+        default:
+            uWarning() << "Artifact drawn as unknown type";
+            break;
+        }
+    }
+    else {
+        uWarning() << "Cannot draw as there is no UMLArtifact for this widget.";
+    }
+}
+
+/**
+ * Reimplemented from WidgetBase::saveToXMI to save the widget to
+ * the "artifactwidget" XMI element.
+ */
+void ArtifactWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("artifactwidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF ArtifactWidget::minimumSize() const
+{
+    if (!m_umlObject) {
+        return UMLWidget::minimumSize();
+    }
+    UMLArtifact *umlart = static_cast<UMLArtifact*>(m_umlObject);
+    if (umlart->getDrawAsType() == UMLArtifact::defaultDraw) {
+        return calculateNormalSize();
+    } else {
+        return calculateIconSize();
+    }
+}
+
+/**
+ * calculates the size when drawing as an icon (it's the same size for all icons)
+ */
+QSize ArtifactWidget::calculateIconSize() const
+{
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
+    const int fontHeight  = fm.lineSpacing();
+
+    int width = fm.width(m_umlObject->name());
+
+    width = width<50 ? 50 : width;
+
+    int height = 50 + fontHeight;
+
+    return QSize(width, height);
+}
+
+/**
+ * calculates the size for drawing as a box
+ */
+QSize ArtifactWidget::calculateNormalSize() const
+{
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
+    const int fontHeight  = fm.lineSpacing();
+
+    int width = fm.width(m_umlObject->name());
+
+    int tempWidth = 0;
+    if(!m_umlObject->stereotype().isEmpty()) {
+        tempWidth = fm.width(m_umlObject->stereotype(true));
+    }
+    width = tempWidth>width ? tempWidth : width;
+    width += ARTIFACT_MARGIN * 2;
+
+    int height = (2*fontHeight) + (ARTIFACT_MARGIN * 2);
+
+    return QSize(width, height);
+}
+
+/**
+ * draw as a file icon
+ */
+void ArtifactWidget::paintAsFile(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    const int w = width();
+    const int h = height();
+    QFont font = UMLWidget::font();
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+
+    int startX = (w/2) - 25;
+    int iconHeight = h - fontHeight;
+    QPolygon pointArray(5);
+    pointArray.setPoint(0, startX, 0);
+    pointArray.setPoint(1, startX + 40, 0);
+    pointArray.setPoint(2, startX + 50, 10);
+    pointArray.setPoint(3, startX + 50, iconHeight);
+    pointArray.setPoint(4, startX, iconHeight);
+    painter->drawPolygon(pointArray);
+
+    painter->drawLine(startX + 40, 0, startX + 40, 10);
+    painter->drawLine(startX + 40, 10, startX + 50, 10);
+    painter->drawLine(startX + 40, 0, startX + 50, 10);
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    painter->drawText(0, h - fontHeight,
+               w, fontHeight, Qt::AlignCenter, name());
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * draw as a library file icon
+ */
+void ArtifactWidget::paintAsLibrary(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    //FIXME this should have gears on it
+    const int w = width();
+    const int h = height();
+    const QFont font = UMLWidget::font();
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+
+    const int startX = (w/2) - 25;
+    const int iconHeight = h - fontHeight;
+    QPolygon pointArray(5);
+    pointArray.setPoint(0, startX, 0);
+    pointArray.setPoint(1, startX + 40, 0);
+    pointArray.setPoint(2, startX + 50, 10);
+    pointArray.setPoint(3, startX + 50, iconHeight);
+    pointArray.setPoint(4, startX, iconHeight);
+    painter->drawPolygon(pointArray);
+
+    painter->drawLine(startX + 40, 0, startX + 40, 10);
+    painter->drawLine(startX + 40, 10, startX + 50, 10);
+    painter->drawLine(startX + 40, 0, startX + 50, 10);
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    painter->drawText(0, h - fontHeight,
+               w, fontHeight, Qt::AlignCenter, name());
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * draw as a database table icon
+ */
+void ArtifactWidget::paintAsTable(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    const int w = width();
+    const int h = height();
+    const QFont font = UMLWidget::font();
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+
+    const int startX = (w/2) - 25;
+    const int iconHeight = h - fontHeight;
+
+    painter->drawRect(startX, 0, 50, h - fontHeight + 1);
+    painter->drawLine(startX + 20, 0, startX + 20, iconHeight);
+    painter->drawLine(startX + 30, 0, startX + 30, iconHeight);
+    painter->drawLine(startX + 40, 0, startX + 40, iconHeight);
+    painter->drawLine(startX, (iconHeight/2), startX + 49, (iconHeight/2));
+    painter->drawLine(startX, (iconHeight/2) + (iconHeight/4),
+               startX + 49, (iconHeight/2) + (iconHeight/4));
+
+    QPen thickerPen = painter->pen();
+    thickerPen.setWidth(2);
+    painter->setPen(thickerPen);
+    painter->drawLine(startX + 10, 0, startX + 10, iconHeight);
+    painter->drawLine(startX, (iconHeight/4), startX + 50, (iconHeight/4));
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    painter->drawText(0, h - fontHeight,
+               w, fontHeight, Qt::AlignCenter, name());
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * draw as a box
+ */
+void ArtifactWidget::paintAsNormal(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    int w = width();
+    int h = height();
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+    const int fontHeight  = fm.lineSpacing();
+    QString stereotype = m_umlObject->stereotype();
+
+    painter->drawRect(0, 0, w, h);
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    if (!stereotype.isEmpty()) {
+        painter->drawText(ARTIFACT_MARGIN, (h/2) - fontHeight,
+                   w, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true));
+    }
+
+    int lines;
+    if (!stereotype.isEmpty()) {
+        lines = 2;
+    } else {
+        lines = 1;
+    }
+
+    if (lines == 1) {
+        painter->drawText(0, (h/2) - (fontHeight/2),
+                   w, fontHeight, Qt::AlignCenter, name());
+    } else {
+        painter->drawText(0, (h/2),
+                   w, fontHeight, Qt::AlignCenter, name());
+    }
+
+    UMLWidget::paint(painter, option);
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/artifactwidget.h umbrello-15.08.1/umbrello/umlwidgets/artifactwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/artifactwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/artifactwidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,55 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ARTIFACTWIDGET_H
+#define ARTIFACTWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLScene;
+class UMLArtifact;
+
+#define ARTIFACT_MARGIN 5
+
+/**
+ * Defines a graphical version of the @ref UMLArtifact.
+ * Most of the functionality will come from the @ref UMLWidget class.
+ *
+ * @short A graphical version of a Artifact.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ArtifactWidget : public UMLWidget
+{
+public:
+    ArtifactWidget(UMLScene *scene, UMLArtifact *a);
+    virtual ~ArtifactWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    // Note: For loading from XMI, the inherited parent method is used.
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+protected:
+    QSizeF minimumSize() const;
+
+private:
+    void paintAsFile(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintAsLibrary(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintAsTable(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintAsNormal(QPainter *painter, const QStyleOptionGraphicsItem *option);
+
+    QSize calculateIconSize() const;
+    QSize calculateNormalSize() const;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/associationline.cpp umbrello-15.08.1/umbrello/umlwidgets/associationline.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/associationline.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/associationline.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,1404 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "associationline.h"
+
+// application includes
+#include "associationwidget.h"
+#include "debug_utils.h"
+#include "umlwidget.h"
+
+// qt includes
+#include <QDomDocument>
+#include <QPainter>
+
+// system includes
+#include <cstdlib>
+#include <cmath>
+
+DEBUG_REGISTER_DISABLED(AssociationLine)
+
+// Initialize static variables.
+const qreal AssociationLine::Delta = 5;
+const qreal AssociationLine::SelectedPointDiameter = 4;
+const qreal AssociationLine::SelfAssociationMinimumHeight = 30;
+
+/**
+ * Constructor.
+ * Constructs an AssociationLine item with its parent being \a parent.
+ */
+AssociationLine::AssociationLine(AssociationWidget *association)
+  : QGraphicsObject(association),
+    m_associationWidget(association),
+    m_activePointIndex(-1),
+    m_activeSegmentIndex(-1),
+    m_startSymbol(0),
+    m_endSymbol(0),
+    m_subsetSymbol(0),
+    m_collaborationLineItem(0),
+    m_collaborationLineHead(0),
+    m_layout(Polyline)
+{
+    Q_ASSERT(association);
+    setFlag(QGraphicsLineItem::ItemIsSelectable);
+    setAcceptHoverEvents(true);
+    setZValue(3);
+}
+
+/**
+ * Destructor.
+ */
+AssociationLine::~AssociationLine()
+{
+}
+
+/**
+ * Returns the point at the point index.
+ * @return point at given index
+ */
+QPointF AssociationLine::point(int index) const
+{
+    if ((index < 0) | (index >= m_points.size())) {
+        uWarning() << "Index " << index << " out of range [0.." << m_points.size() - 1 << "].";
+        return QPointF(-1.0, -1.0);
+    }
+    return m_points.at(index);
+}
+
+/**
+ * Sets the point value at given index to \a point.
+ */
+bool AssociationLine::setPoint(int index, const QPointF &point)
+{
+    if ((index < 0) | (index >= m_points.size())) {
+        uWarning() << "Index " << index << " out of range [0.." << m_points.size() - 1 << "].";
+        return false;
+    }
+    if (m_points.at(index) == point) {
+        return false;  // nothing to change
+    }
+    prepareGeometryChange();
+    m_points[index] = point;
+    alignSymbols();
+    return true;
+}
+
+/**
+ * Shortcut for point(0).
+ */
+QPointF AssociationLine::startPoint() const
+{
+    return m_points.at(0);
+}
+
+/**
+ * Shortcut for end point.
+ */
+QPointF AssociationLine::endPoint() const
+{
+    return m_points.at(m_points.size()-1);
+}
+
+/**
+ * Inserts the passed in \a point at the \a index passed in and
+ * recalculates the bounding rect.
+ */
+void AssociationLine::insertPoint(int index, const QPointF &point)
+{
+    prepareGeometryChange();
+    m_points.insert(index, point);
+    alignSymbols();
+}
+
+/**
+ * Removes the point at \a index passed in.
+ * @see removeNonEndPoint
+ */
+void AssociationLine::removePoint(int index)
+{
+    prepareGeometryChange();
+    m_points.remove(index);
+    alignSymbols();
+}
+
+/**
+ * Returns the amount of POINTS on the line.
+ * Includes start and end points.
+ * @return   number of points in the AssociationLine
+ */
+int AssociationLine::count() const
+{
+    return m_points.size();
+}
+
+/**
+ * Removes all the points and signals a geometry update.
+ */
+void AssociationLine::cleanup()
+{
+    if (!m_points.isEmpty()) {
+        prepareGeometryChange();
+        m_points.clear();
+        alignSymbols();
+    }
+}
+
+/**
+ * This method optimizes the number of points in the
+ * AssociationLine. This can be used to reduce the clutter caused
+ * due to too many points.
+ * TODO: Use delta comparison 'closestPointIndex' instead of exact comparison.
+ * TODO: Not used anywhere.
+ */
+void AssociationLine::optimizeLinePoints()
+{
+    int i = 1;
+    prepareGeometryChange();
+    while (i < m_points.size()) {
+        if (m_points.at(i) == m_points.at(i-1)) {
+            m_points.remove(i);
+        }
+        else {
+            ++i;
+        }
+    }
+    alignSymbols();
+}
+
+/**
+ * Return index of point closer a given delta.
+ *
+ * @param point The point which is to be tested for closeness.
+ * @param delta The distance the point should be closer to.
+ *
+ * @retval "Index" of the first line point closer to the \a point passed.
+ * @retval -1 If no line point is closer to passed in \a point.
+ */
+int AssociationLine::closestPointIndex(const QPointF &point, qreal delta) const
+{
+    for(int i = 0; i < m_points.size(); ++i) {
+        const QPointF& linePoint = m_points.at(i);
+        // Apply distance formula to see point closeness.
+        qreal deltaXSquare = (point.x() - linePoint.x()) * (point.x() - linePoint.x());
+        qreal deltaYSquare = (point.y() - linePoint.y()) * (point.y() - linePoint.y());
+
+        qreal lhs = deltaXSquare + deltaYSquare;
+        qreal rhs = delta * delta;
+
+        if (lhs <= rhs) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+/**
+ * Return index of closest segment.
+ *
+ * @param point The point which is to be tested for closeness.
+ *
+ * @return Index of the line segment closest to the \a point passed;
+ *         -1 if no line segment is closer to passed in \a point.
+ */
+int AssociationLine::closestSegmentIndex(const QPointF &point, qreal delta) const
+{
+    QPainterPathStroker stroker;
+    stroker.setWidth(delta);
+
+    for(int i = 1; i < m_points.size(); ++i) {
+        QLineF segment(m_points[i-1], m_points[i]);
+
+        QPainterPath path;
+        path.moveTo(segment.p1());
+        path.lineTo(segment.p2());
+
+        path = stroker.createStroke(path);
+
+        if (path.contains(point)) {
+            return i-1;
+        }
+    }
+    return -1;
+}
+
+/**
+ * Retval True If point at \a index is start or end.
+ */
+bool AssociationLine::isEndPointIndex(int index) const
+{
+    const int size = m_points.size();
+    Q_ASSERT(index >= 0 && index < size);
+
+    return (index == 0 || index == (size - 1));
+}
+
+/**
+ * Retval True If segment at \a index is start or end.
+ */
+bool AssociationLine::isEndSegmentIndex(int index) const
+{
+    // num of seg = num of points - 1
+    const int size = m_points.size() - 1;
+    Q_ASSERT(index >= 0 && index < size);
+
+    return (index == 0 || index == (size - 1));
+}
+
+/**
+ * Sets the start and end points.
+ */
+bool AssociationLine::setEndPoints(const QPointF &start, const QPointF &end)
+{
+    const int size = m_points.size();
+
+    prepareGeometryChange();
+
+    if (size == 0) {
+        m_points.insert(0, start);
+        m_points.insert(1, end);
+    }
+    else if (size == 1) {
+        m_points[0] = start;
+        m_points.insert(1, end);
+    }
+    else {
+        m_points[0] = start;
+        m_points[size-1] = end;
+    }
+
+    alignSymbols();
+    return true;
+}
+
+/**
+ * Debug helper method to write out the points.
+ */
+void AssociationLine::dumpPoints()
+{
+    for (int i = 1; i < m_points.size(); ++i) {
+        QPointF p = m_points.at(i);
+        DEBUG(DBG_SRC) << i << ". point x:" << p.x() << " / y:" << p.y();
+    }
+}
+
+/**
+ * Loads AssociationLine information saved in \a qElement XMI element.
+ */
+bool AssociationLine::loadFromXMI(QDomElement &qElement)
+{
+    QString layout = qElement.attribute(QLatin1String("layout"), QLatin1String("polyline"));
+    m_layout = fromString(layout);
+
+    QDomNode node = qElement.firstChild();
+
+    m_points.clear();
+
+    QDomElement startElement = node.toElement();
+    if(startElement.isNull() || startElement.tagName() != QLatin1String("startpoint")) {
+        return false;
+    }
+    QString x = startElement.attribute(QLatin1String("startx"), QLatin1String("0"));
+    qreal nX = x.toFloat();
+    QString y = startElement.attribute(QLatin1String("starty"), QLatin1String("0"));
+    qreal nY = y.toFloat();
+    QPointF startPoint(nX, nY);
+
+    node = startElement.nextSibling();
+    QDomElement endElement = node.toElement();
+    if(endElement.isNull() || endElement.tagName() != QLatin1String("endpoint")) {
+        return false;
+    }
+    x = endElement.attribute(QLatin1String("endx"), QLatin1String("0"));
+    nX = x.toFloat();
+    y = endElement.attribute(QLatin1String("endy"), QLatin1String("0"));
+    nY = y.toFloat();
+    QPointF endPoint(nX, nY);
+    setEndPoints(startPoint, endPoint);
+    QPointF point;
+    node = endElement.nextSibling();
+    QDomElement element = node.toElement();
+    int i = 1;
+    while(!element.isNull()) {
+        if(element.tagName() == QLatin1String("point")) {
+            x = element.attribute(QLatin1String("x"), QLatin1String("0"));
+            y = element.attribute(QLatin1String("y"), QLatin1String("0"));
+            point.setX(x.toFloat());
+            point.setY(y.toFloat());
+            insertPoint(i++, point);
+        }
+        node = element.nextSibling();
+        element = node.toElement();
+    }
+
+    return true;
+}
+
+/**
+ * Saves association line information into XMI element named "linepath".
+ * @note Stored as linepath for backwared compatibility
+ */
+void AssociationLine::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
+{
+    QPointF point = m_associationWidget->mapToScene(startPoint());
+    QDomElement lineElement = qDoc.createElement(QLatin1String("linepath"));
+    lineElement.setAttribute(QLatin1String("layout"), toString(m_layout));
+    QDomElement startElement = qDoc.createElement(QLatin1String("startpoint"));
+    startElement.setAttribute(QLatin1String("startx"), point.x());
+    startElement.setAttribute(QLatin1String("starty"), point.y());
+    lineElement.appendChild(startElement);
+    QDomElement endElement = qDoc.createElement(QLatin1String("endpoint"));
+    point = m_associationWidget->mapToScene(endPoint());
+    endElement.setAttribute(QLatin1String("endx"), point.x());
+    endElement.setAttribute(QLatin1String("endy"), point.y());
+    lineElement.appendChild(endElement);
+    for(int i = 1; i < count()-1; ++i) {
+        QDomElement pointElement = qDoc.createElement(QLatin1String("point"));
+        point = m_associationWidget->mapToScene(this->point(i));
+        pointElement.setAttribute(QLatin1String("x"), point.x());
+        pointElement.setAttribute(QLatin1String("y"), point.y());
+        lineElement.appendChild(pointElement);
+    }
+    qElement.appendChild(lineElement);
+}
+
+/**
+ * Returns the type of brush to use depending on the type of Association.
+ */
+QBrush AssociationLine::brush() const
+{
+    QBrush brush(Qt::SolidPattern);
+    Uml::AssociationType::Enum type = m_associationWidget->associationType();
+    if (type == Uml::AssociationType::Aggregation    ||
+        type == Uml::AssociationType::Generalization ||
+        type == Uml::AssociationType::Realization) {
+        brush.setColor(Qt::white);
+    }
+    if (type == Uml::AssociationType::Composition) {
+        brush.setColor(m_associationWidget->lineColor());
+    }
+    return brush;
+}
+
+/**
+ * Returns the type of pen to use depending on the type of Association.
+ */
+QPen AssociationLine::pen() const
+{
+    QPen pen(m_associationWidget->lineColor(),
+             m_associationWidget->lineWidth(),
+             Qt::SolidLine,
+             Qt::RoundCap,
+             Qt::RoundJoin);
+    Uml::AssociationType::Enum type = m_associationWidget->associationType();
+    if (type == Uml::AssociationType::Dependency  ||
+        type == Uml::AssociationType::Realization ||
+        type == Uml::AssociationType::Anchor) {
+        pen.setStyle(Qt::DashLine);
+    }
+    return pen;
+}
+
+/**
+ * This method simply ensures presence of two points and
+ * adds the needed points for self associations.
+ */
+void AssociationLine::calculateInitialEndPoints()
+{
+    if (m_associationWidget->isSelf() && count() < 4) {
+        for (int i = count(); i < 4; ++i) {
+            insertPoint(i, QPointF());
+        }
+        UMLWidget *wid = m_associationWidget->widgetForRole(Uml::RoleType::B);
+        if (!wid) {
+            uError() << "AssociationWidget is partially constructed."
+                "UMLWidget for role B is null.";
+            return;
+        }
+        const QRectF rect = m_associationWidget->mapFromScene(
+                mapToScene(wid->rect()).boundingRect()).boundingRect();
+
+        qreal l = rect.left() + .25 * rect.width();
+        qreal r = rect.left() + .75 * rect.width();
+        bool drawAbove = rect.top() >= SelfAssociationMinimumHeight;
+        qreal y = drawAbove ? rect.top() : rect.bottom();
+        qreal yOffset = SelfAssociationMinimumHeight;
+        if (drawAbove) {
+            yOffset *= -1.0;
+        }
+
+        setPoint(0, QPointF(l, y));
+        setPoint(1, QPointF(l, y + yOffset));
+        setPoint(2, QPointF(r, y + yOffset));
+        setPoint(3, QPointF(r, y));
+    } else if (!m_associationWidget->isSelf() && count() < 2) {
+        setEndPoints(QPointF(), QPointF());
+    }
+}
+
+/**
+ * This method creates, deletes symbols and collaboration lines based on
+ * m_associationWidget->associationType().
+ *
+ * Call this method when associationType of m_associationWidget changes.
+ */
+void AssociationLine::reconstructSymbols()
+{
+    switch( m_associationWidget->associationType() ) {
+        case Uml::AssociationType::State:
+        case Uml::AssociationType::Activity:
+        case Uml::AssociationType::Exception:
+        case Uml::AssociationType::UniAssociation:
+        case Uml::AssociationType::Dependency:
+            setStartSymbol(Symbol::None);
+            setEndSymbol(Symbol::OpenArrow);
+            removeSubsetSymbol();
+            removeCollaborationLine();
+            break;
+
+        case Uml::AssociationType::Relationship:
+            setStartSymbol(Symbol::None);
+            setEndSymbol(Symbol::CrowFeet);
+            removeSubsetSymbol();
+            removeCollaborationLine();
+            break;
+
+        case Uml::AssociationType::Generalization:
+        case Uml::AssociationType::Realization:
+            setStartSymbol(Symbol::None);
+            setEndSymbol(Symbol::ClosedArrow);
+            removeSubsetSymbol();
+            removeCollaborationLine();
+            break;
+
+        case Uml::AssociationType::Composition:
+        case Uml::AssociationType::Aggregation:
+            setStartSymbol(Symbol::Diamond);
+            setEndSymbol(Symbol::None);
+            removeSubsetSymbol();
+            removeCollaborationLine();
+            break;
+
+        case Uml::AssociationType::Containment:
+            setStartSymbol(Symbol::Circle);
+            setEndSymbol(Symbol::None);
+            removeSubsetSymbol();
+            removeCollaborationLine();
+            break;
+
+        case Uml::AssociationType::Child2Category:
+            setStartSymbol(Symbol::None);
+            setEndSymbol(Symbol::None);
+            createSubsetSymbol();
+            removeCollaborationLine();
+            break;
+
+        case Uml::AssociationType::Coll_Message_Synchronous:
+        case Uml::AssociationType::Coll_Message_Asynchronous:
+        case Uml::AssociationType::Coll_Message_Self:
+            setStartSymbol(Symbol::None);
+            setEndSymbol(Symbol::None);
+            removeSubsetSymbol();
+            createCollaborationLine();
+            break;
+
+        default:
+            break;
+    }
+    alignSymbols();
+}
+
+/**
+ * Sets the Symbol to appear at the first line segment to \a symbol.
+ *
+ * If symbol == Symbol::None , then it deletes the symbol item.
+ */
+void AssociationLine::setStartSymbol(Symbol::SymbolType symbolType)
+{
+    Q_ASSERT(symbolType != Symbol::Count);
+    if (symbolType == Symbol::None) {
+        delete m_startSymbol;
+        m_startSymbol = 0;
+        return;
+    }
+
+    if (m_startSymbol) {
+        m_startSymbol->setSymbolType(symbolType);
+    }
+    else {
+        m_startSymbol = new Symbol(symbolType, m_associationWidget);
+    }
+    m_startSymbol->setPen(pen());
+    m_startSymbol->setBrush(brush());
+}
+
+/**
+ * Sets the Symbol to appear at the last line segment to \a symbol.
+ *
+ * If symbol == Symbol::None , then it deletes the symbol item.
+ */
+void AssociationLine::setEndSymbol(Symbol::SymbolType symbolType)
+{
+    Q_ASSERT(symbolType != Symbol::Count);
+    if (symbolType == Symbol::None) {
+        delete m_endSymbol;
+        m_endSymbol = 0;
+        return;
+    }
+
+    if (m_endSymbol) {
+        m_endSymbol->setSymbolType(symbolType);
+    }
+    else {
+        m_endSymbol = new Symbol(symbolType, m_associationWidget);
+    }
+    m_endSymbol->setPen(pen());
+    m_endSymbol->setBrush(brush());
+}
+
+/**
+ * Constructs a new subset symbol.
+ */
+void AssociationLine::createSubsetSymbol()
+{
+    delete m_subsetSymbol; // recreate
+    m_subsetSymbol = new Symbol(Symbol::Subset, m_associationWidget);
+    m_subsetSymbol->setPen(pen());
+    m_subsetSymbol->setBrush(brush());
+}
+
+/**
+ * Removes the subset symbol if it existed by deleting appropriate items.
+ */
+void AssociationLine::removeSubsetSymbol()
+{
+    delete m_subsetSymbol;
+    m_subsetSymbol = 0;
+}
+
+/**
+ * Constructs the open arrow symbol and arrow line, that would represent Collaboration line.
+ */
+void AssociationLine::createCollaborationLine()
+{
+    const QPen p = pen();
+
+    // recreate
+    delete m_collaborationLineItem;
+    delete m_collaborationLineHead;
+
+    m_collaborationLineItem = new QGraphicsLineItem(m_associationWidget);
+    m_collaborationLineItem->setPen(p);
+
+    if (m_associationWidget->associationType() == Uml::AssociationType::Coll_Message_Synchronous) {
+        m_collaborationLineHead = new Symbol(Symbol::ClosedArrow, m_associationWidget);
+        m_collaborationLineHead->setBrush(p.color());
+    }
+    else
+        m_collaborationLineHead = new Symbol(Symbol::OpenArrow, m_associationWidget);
+    m_collaborationLineHead->setPen(p);
+}
+
+/**
+ * Removes collaboration line by deleting the head and line item.
+ */
+void AssociationLine::removeCollaborationLine()
+{
+    delete m_collaborationLineItem;
+    m_collaborationLineItem = 0;
+
+    delete m_collaborationLineHead;
+    m_collaborationLineHead = 0;
+}
+
+/**
+ * This method aligns both the \b "start" and \b "end" symbols to
+ * the current angles of the \b "first" and the \b "last" line
+ * segment respectively.
+ */
+void AssociationLine::alignSymbols()
+{
+    const int sz = m_points.size();
+    if (sz < 2) {
+        // cannot align if there is no line (one line = 2 points)
+        return;
+    }
+
+    QList<QPolygonF> polygons = path().toSubpathPolygons();
+
+    if (m_startSymbol) {
+        QPolygonF firstLine = polygons.first();
+        QLineF segment(firstLine.at(1), firstLine.at(0));
+        m_startSymbol->alignTo(segment);
+    }
+
+    if (m_endSymbol) {
+        QPolygonF lastLine = polygons.last();
+        int maxIndex = lastLine.size();
+        QLineF segment(lastLine.at(maxIndex-2), lastLine.at(maxIndex-1));
+        m_endSymbol->alignTo(segment);
+    }
+
+    if (m_subsetSymbol) {
+        QPointF p1 = path().pointAtPercent(0.4);
+        QPointF p2 = path().pointAtPercent(0.5);
+        QLineF segment(p1, p2);
+        m_subsetSymbol->alignTo(segment);
+    }
+
+    if (m_collaborationLineItem) {
+        const qreal distance = 10;
+        const int midSegmentIndex = (sz - 1) / 2;
+
+        const QPointF a = m_points.at(midSegmentIndex);
+        const QPointF b = m_points.at(midSegmentIndex + 1);
+
+        if (a == b)
+            return;
+
+        const QPointF p1 = (a + b) / 2.0;
+        const QPointF p2 = (p1 + b) / 2.0;
+
+        // Reversed line as we want normal in opposite direction.
+        QLineF segment(p2, p1);
+        QLineF normal = segment.normalVector().unitVector();
+        normal.setLength(distance);
+
+        QLineF actualLine;
+        actualLine.setP2(normal.p2());
+
+        normal.translate(p1 - p2);
+        actualLine.setP1(normal.p2());
+
+        m_collaborationLineItem->setLine(actualLine);
+        m_collaborationLineHead->alignTo(actualLine);
+    }
+}
+
+/**
+ * @return The path of the AssociationLine.
+ */
+QPainterPath AssociationLine::path() const
+{
+    if (m_points.count() > 0) {
+        QPainterPath path;
+        switch (m_layout) {
+        case Direct:
+            path.moveTo(m_points.first());
+            path.lineTo(m_points.last());
+            break;
+
+        case Spline:
+            path = createBezierCurve(m_points);
+            break;
+
+        case Orthogonal:
+            path = createOrthogonalPath(m_points);
+            break;
+
+        case Polyline:
+        default:
+            QPolygonF polygon(m_points);
+            path.addPolygon(polygon);
+            break;
+        }
+        return path;
+    }
+    else {
+        return QPainterPath();
+    }
+}
+
+/**
+ * The points are used for the bounding rect. The reason is,
+ * that for splines the control points are further away from the path.
+ * @return The bounding rectangle for the AssociationLine.
+ */
+QRectF AssociationLine::boundingRect() const
+{
+    QPolygonF polygon(m_points);
+    QRectF rect = polygon.boundingRect();
+    const qreal margin(5.0);
+    rect.adjust(-margin, -margin, margin, margin);
+    return rect;
+}
+
+/**
+ * @return The shape of the AssociationLine.
+ */
+QPainterPath AssociationLine::shape() const
+{
+    QPainterPathStroker stroker;
+    stroker.setWidth(qMax<qreal>(2*SelectedPointDiameter, pen().widthF()) + 2.0);  // allow delta region
+    stroker.setCapStyle(Qt::FlatCap);
+    return stroker.createStroke(path());
+}
+
+/**
+ * Convert enum LayoutType to string.
+ */
+QString AssociationLine::toString(LayoutType layout)
+{
+    return QLatin1String(ENUM_NAME(AssociationLine, LayoutType, layout));
+}
+
+/**
+ * Convert string to enum LayoutType.
+ */
+AssociationLine::LayoutType AssociationLine::fromString(const QString &layout)
+{
+    if (layout == QLatin1String("Direct"))
+        return Direct;
+    if (layout == QLatin1String("Spline"))
+        return Spline;
+    if (layout == QLatin1String("Orthogonal"))
+        return Orthogonal;
+    return Polyline;
+}
+
+/**
+ * Return the layout type of the association line.
+ * @return   the currently used layout
+ */
+AssociationLine::LayoutType AssociationLine::layout() const
+{
+    return m_layout;
+}
+
+/**
+ * Set the layout type of the association line.
+ * @param layout   the desired layout to set
+ */
+void AssociationLine::setLayout(LayoutType layout)
+{
+    prepareGeometryChange();
+    m_layout = layout;
+    DEBUG(DBG_SRC) << "new layout = " << toString(m_layout);
+    if (m_layout == Spline) {
+        createSplinePoints();
+    }
+    alignSymbols();
+}
+
+/**
+ * For a cubic Bezier curve at least four points are needed.
+ * If there are less, the missing points will be created.
+ * Note: Implementation is only for two points.
+ */
+void AssociationLine::createSplinePoints()
+{
+    if (m_points.size() == 2) {  // create two points
+        QPointF p1 = m_points.first();  // start point
+        QPointF p2 = m_points.last();   // end point
+        qreal dx = p2.x() - p1.x();
+        qreal dy = p2.y() - p1.y();
+        qreal oneThirdX = 0.33 * dx;
+        qreal oneThirdY = 0.33 * dy;
+        QPointF c1(p1.x() + oneThirdX,  // control point 1
+                   p1.y() - oneThirdY);
+        QPointF c2(p2.x() - oneThirdX,  // control point 2
+                   p2.y() + oneThirdY);
+        insertPoint(1, c1);
+        insertPoint(2, c2);
+    }
+    if (m_points.size() == 3) {  // create one point
+        // insertPoint(1 or 2, );
+        // Note: For now we use a quadratic Bezier curve in createBezierCurve(...).
+    }
+}
+
+/**
+ * Returns a Bézier path from given points.
+ * @param points   points which define the Bézier curve
+ * @return   cubic Bézier spline
+ */
+QPainterPath AssociationLine::createBezierCurve(QVector<QPointF> points)
+{
+    QPainterPath path;
+    if (points.size() > 3) {  // cubic Bezier curve(s)
+        path.moveTo(points.at(0));
+        int i = 1;
+        while (i + 2 < points.size()) {
+            path.cubicTo(points.at(i), points.at(i+1), points.at(i+2));
+            i += 3;
+        }
+        while (i < points.size()) {  // draw a line if points are not modulo 3
+            path.lineTo(points.at(i));
+            ++i;
+        }
+    }
+    else {
+        if (points.size() == 3) {  // quadratic Bezier curve
+            path.moveTo(points.at(0));
+            path.quadTo(points.at(1), points.at(2));
+        }
+        else {  // should not be reached
+            QPolygonF polygon(points);
+            path.addPolygon(polygon);
+        }
+    }
+    return path;
+}
+
+/**
+ * Returns an orthogonal path constructed of vertical and horizontal segments
+ * through the given points.
+ * @param points   base points for the path
+ * @return   orthogonal path
+ */
+QPainterPath AssociationLine::createOrthogonalPath(QVector<QPointF> points)
+{
+    QPainterPath path;
+    if (points.size() > 1) {
+        QPointF start  = points.first();
+        QPointF end    = points.last();
+        qreal deltaX = fabs(start.x() - end.x());
+        qreal deltaY = fabs(start.y() - end.y());
+        // DEBUG("AssociationLine") << "start=" << start << " / end=" << end
+        //               << " / deltaX=" << deltaX << " / deltaY=" << deltaY;
+        QVector<QPointF> vector;
+        for (int i = 0; i < points.size() - 1; ++i) {
+            QPointF curr = points.at(i);
+            QPointF next = points.at(i+1);
+            QPointF center = (next + curr)/2.0;
+
+            vector.append(curr);
+            if (deltaX < deltaY) {
+                // go vertical first
+                vector.append(QPointF(curr.x(), center.y()));
+                vector.append(QPointF(next.x(), center.y()));
+            }
+            else {
+                // go horizontal first
+                vector.append(QPointF(center.x(), curr.y()));
+                vector.append(QPointF(center.x(), next.y()));
+            }
+            vector.append(next);
+        }
+
+        QPolygonF rectLine(vector);
+        path.addPolygon(rectLine);
+    }
+    else {
+        QPolygonF polygon(points);
+        path.addPolygon(polygon);
+    }
+    return path;
+}
+
+/**
+ * Reimplemented from QGraphicsItem::paint.
+ * Draws the AssociationLine and also takes care of highlighting active point or line.
+ */
+void AssociationLine::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+    Q_UNUSED(widget)
+    QPen _pen = pen();
+    const QColor orig = _pen.color().lighter();
+    QColor invertedColor(orig.green(), orig.blue(), orig.red());
+    if (invertedColor == _pen.color()) {
+        // Ensure different color.
+        invertedColor.setRed((invertedColor.red() + 50) % 256);
+    }
+    invertedColor.setAlpha(150);
+
+    int sz = m_points.size();
+    if (sz < 1) {
+        // not enough points - do nothing
+        return;
+    }
+
+    QPointF savedStart = m_points.first();
+    QPointF savedEnd = m_points.last();
+
+    // modify the m_points array not to include the Symbol, the value depends on Symbol
+    if (m_startSymbol) {
+        QPointF newStart = m_startSymbol->mapToParent(m_startSymbol->symbolEndPoints().first);
+        m_points[0] = newStart;
+    }
+
+    if (m_endSymbol) {
+        QPointF newEnd = m_endSymbol->mapToParent(m_endSymbol->symbolEndPoints().first);
+        m_points[sz - 1] = newEnd;
+    }
+
+    painter->setPen(_pen);
+    painter->setBrush(Qt::NoBrush);
+    painter->drawPath(path());
+
+    if (option->state & QStyle::State_Selected) {
+        // make the association broader in the selected state
+        QPainterPathStroker stroker;
+        stroker.setWidth(3.0);
+        QPainterPath outline = stroker.createStroke(path());
+        QColor shadowColor(Qt::lightGray);
+        shadowColor.setAlpha(80);
+        QBrush shadowBrush(shadowColor);
+        painter->setBrush(shadowBrush);
+        painter->setPen(Qt::NoPen);
+        painter->drawPath(outline);
+
+        // set color for selected painting
+        _pen.setColor(Qt::blue);
+        QRectF circle(0, 0, SelectedPointDiameter, SelectedPointDiameter);
+        painter->setBrush(_pen.color());
+        painter->setPen(Qt::NoPen);
+
+        // draw points
+        circle.moveCenter(savedStart);
+        painter->drawRect(circle);
+        for (int i = 1; i < sz-1; ++i) {
+            if (i != m_activePointIndex) {
+                circle.moveCenter(m_points.at(i));
+                painter->drawRect(circle);
+            }
+        }
+        circle.moveCenter(savedEnd);
+        painter->drawRect(circle);
+
+        if (m_activePointIndex != -1) {
+            painter->setBrush(invertedColor);
+            painter->setPen(Qt::NoPen);
+            circle.setWidth(1.5*SelectedPointDiameter);
+            circle.setHeight(1.5*SelectedPointDiameter);
+            circle.moveCenter(m_points.at(m_activePointIndex));
+            painter->drawEllipse(circle);
+        }
+        else if (m_activeSegmentIndex != -1) {
+            if (m_layout == Polyline) {
+                painter->setPen(QPen(invertedColor, _pen.widthF() + 1));
+                painter->setBrush(Qt::NoBrush);
+
+                QLineF segmentLine(m_points[m_activeSegmentIndex], m_points[m_activeSegmentIndex + 1]);
+                painter->drawLine(segmentLine);
+            }
+        }
+        // debug info
+        if (Tracer::instance()->isEnabled(QString::fromLatin1(metaObject()->className()))) {
+            painter->setPen(Qt::green);
+            painter->setBrush(Qt::NoBrush);
+            painter->drawPath(shape());
+            painter->setPen(Qt::red);
+            painter->drawRect(boundingRect());
+            // origin
+            painter->drawLine(-10, 0, 10, 0);
+            painter->drawLine(0, -10, 0, 10);
+        }
+
+    }
+
+    // now restore the points array
+    m_points[0] = savedStart;
+    m_points[sz - 1] = savedEnd;
+}
+
+/**
+ * Determines the active point or segment, the latter being given more priority.
+ */
+void AssociationLine::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    DEBUG(DBG_SRC) << "at " << event->scenePos();
+    if (event->buttons() & Qt::LeftButton) {
+        m_activePointIndex = closestPointIndex(event->scenePos());
+        if (m_activePointIndex != -1 && isEndPointIndex(m_activePointIndex)) {
+            // end points are not drawn and hence not active
+            m_activePointIndex = -1;
+        }
+        // calculate only if active point index is -1
+        m_activeSegmentIndex = (m_activePointIndex != -1) ? -1 : closestSegmentIndex(event->scenePos());
+    }
+    else if (event->buttons() & Qt::RightButton) {
+        DEBUG(DBG_SRC) << "call context menu of association widget at " << event->scenePos();
+    }
+    else {
+        m_activePointIndex   = -1;
+        m_activeSegmentIndex = -1;
+    }
+}
+
+/**
+ * Moves the point or line if active.
+ */
+void AssociationLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+    UMLScene* scene = m_associationWidget->umlScene();
+
+    QPointF oldPos = event->scenePos();
+    QPointF newPos(
+        scene->snappedX(oldPos.x()),
+        scene->snappedY(oldPos.y())
+    );
+
+    // Prevent the moving vertex from disappearing underneath a widget
+    // (else there's no way to get it back.)
+    UMLWidget *onW = scene->widgetAt(newPos);
+    if (onW && onW->baseType() != WidgetBase::wt_Box) {  // boxes are transparent
+        const qreal pX = newPos.x();
+        const qreal pY = newPos.y();
+        const qreal wX = onW->x();
+        const qreal wY = onW->y();
+        const qreal wWidth = onW->width();
+        const qreal wHeight = onW->height();
+        if (pX > wX && pX < wX + wWidth) {
+            const qreal midX = wX + wWidth / 2.0;
+            if (pX <= midX)
+                newPos.setX(wX);
+            else
+                newPos.setX(wX + wWidth);
+        }
+        if (pY > wY && pY < wY + wHeight) {
+            const qreal midY = wY + wHeight / 2.0;
+            if (pY <= midY)
+                newPos.setY(wY);
+            else
+                newPos.setY(wY + wHeight);
+        }
+    }
+
+    if (m_activePointIndex != -1) {
+        // Move a single point (snap behaviour)
+        setPoint(m_activePointIndex, newPos);
+    }
+    else if (m_activeSegmentIndex != -1 && !isEndSegmentIndex(m_activeSegmentIndex)) {
+        // Move a segment (between two points, snap behaviour not implemented)
+        QPointF delta = event->scenePos() - event->lastScenePos();
+        setPoint(m_activeSegmentIndex, m_points[m_activeSegmentIndex] + delta);
+        setPoint(m_activeSegmentIndex + 1, m_points[m_activeSegmentIndex + 1] + delta);
+    }
+}
+
+/**
+ * Reset active indices and also push undo command.
+ */
+void AssociationLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (event->buttons() & Qt::LeftButton) {
+        m_activeSegmentIndex = -1;
+        m_activePointIndex   = -1;
+    }
+}
+
+/**
+ * Calculates the "to be highlighted" point and segment indicies
+ * and updates if necessary.
+ */
+void AssociationLine::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+    DEBUG(DBG_SRC) << "at " << event->scenePos();
+    int oldPointIndex = m_activePointIndex;
+    int oldSegmentIndex = m_activeSegmentIndex;
+
+    m_activePointIndex = closestPointIndex(event->scenePos());
+    // End points are not drawn and hence not active.
+    if (m_activePointIndex != -1 && isEndPointIndex(m_activePointIndex)) {
+        m_activePointIndex = -1;
+    }
+    // Activate segment index only if point index is -1
+    m_activeSegmentIndex = (m_activePointIndex != -1) ? -1 : closestSegmentIndex(event->scenePos());
+
+    bool isChanged = (oldSegmentIndex != m_activeSegmentIndex || oldPointIndex != m_activePointIndex);
+    if (isChanged) {
+        m_associationWidget->update();
+    }
+}
+
+/**
+ * Calculates the "to be highlighted" point and segment indicies
+ * and updates if necessary.
+ */
+void AssociationLine::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+    int oldPointIndex = m_activePointIndex;
+    int oldSegmentIndex = m_activeSegmentIndex;
+
+    m_activePointIndex = closestPointIndex(event->scenePos());
+    // End points are not drawn and hence not active.
+    if (m_activePointIndex != -1 && isEndPointIndex(m_activePointIndex)) {
+        m_activePointIndex = -1;
+    }
+    // Activate segment index only if point index is -1
+    m_activeSegmentIndex = (m_activePointIndex != -1) ? -1 : closestSegmentIndex(event->scenePos());
+
+    bool isChanged = (oldSegmentIndex != m_activeSegmentIndex || oldPointIndex != m_activePointIndex);
+    if (isChanged) {
+        m_associationWidget->update();
+    }
+}
+
+/**
+ * Reset active indicies and updates.
+ */
+void AssociationLine::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+    DEBUG(DBG_SRC) << "at " << event->scenePos();
+    //Q_UNUSED(event)
+    m_activePointIndex   = -1;
+    m_activeSegmentIndex = -1;
+    m_associationWidget->update();
+}
+
+//-----------------------------------------------------------------------------
+
+/**
+ * SymbolEndPoints:
+ * The first point is where the AssociationLine's visible line is
+ * supposed to end.
+ * The second points is where the actual symbol part is to appear.
+ */
+Symbol::SymbolProperty Symbol::symbolTable[Count] =
+{
+    {
+        QRectF(-6, 0, 12, 10), QPainterPath(), QLineF(0, 0, 0, 10),
+        SymbolEndPoints(QPointF(0, 10), QPointF(0, 10))
+    },
+    {
+        QRectF(-6, 0, 12, 10), QPainterPath(), QLineF(0, 0, 0, 10),
+        SymbolEndPoints(QPointF(0, 0), QPointF(0, 10))
+    },
+    {
+        QRectF(-6, 0, 12, 10), QPainterPath(), QLineF(0, 0, 0, 10),
+        SymbolEndPoints(QPointF(0, 10), QPointF(0, 10))
+    },
+    {
+        QRectF(-5, -10, 10, 20), QPainterPath(), QLineF(0, -10, 0, 10),
+        SymbolEndPoints(QPointF(0, -10), QPointF(0, 10))
+    },
+    {
+        QRectF(-15, -10, 30, 20), QPainterPath(), QLineF(-10, 0, 0, 0),
+        SymbolEndPoints(QPointF(0, 0), QPointF(0, 0))
+    },
+    {
+        QRectF(-8, -8, 16, 16), QPainterPath(), QLineF(0, -8, 0, 8),
+        SymbolEndPoints(QPointF(0, -8), QPointF(0, 8))
+    }
+
+};
+
+/**
+ * @internal A convenience method to setup shapes of all symbols.
+ */
+void Symbol::setupSymbolTable()
+{
+    SymbolProperty &openArrow = symbolTable[OpenArrow];
+    if (openArrow.shape.isEmpty()) {
+        QRectF rect = openArrow.boundRect;
+        // Defines a 'V' shape arrow fitting in the bound rect.
+        openArrow.shape.moveTo(rect.topLeft());
+        openArrow.shape.lineTo(rect.center().x(), rect.bottom());
+        openArrow.shape.lineTo(rect.topRight());
+    }
+
+    SymbolProperty &closedArrow = symbolTable[ClosedArrow];
+    if (closedArrow.shape.isEmpty()) {
+        QRectF rect = closedArrow.boundRect;
+        // Defines a 'V' shape arrow fitting in the bound rect.
+        closedArrow.shape.moveTo(rect.topLeft());
+        closedArrow.shape.lineTo(rect.center().x(), rect.bottom());
+        closedArrow.shape.lineTo(rect.topRight());
+        closedArrow.shape.lineTo(rect.topLeft());
+    }
+
+    SymbolProperty &crowFeet = symbolTable[CrowFeet];
+    if (crowFeet.shape.isEmpty()) {
+        QRectF rect = crowFeet.boundRect;
+        // Defines a crowFeet fitting in the bound rect.
+        QPointF topMid(rect.center().x(), rect.top());
+
+        // left leg
+        crowFeet.shape.moveTo(rect.bottomLeft());
+        crowFeet.shape.lineTo(topMid);
+
+        // middle leg
+        crowFeet.shape.moveTo(rect.center().x(), rect.bottom());
+        crowFeet.shape.lineTo(topMid);
+
+        // right leg
+        crowFeet.shape.moveTo(rect.bottomRight());
+        crowFeet.shape.lineTo(topMid);
+    }
+
+    SymbolProperty &diamond = symbolTable[Diamond];
+    if (diamond.shape.isEmpty()) {
+        QRectF rect = diamond.boundRect;
+        // Defines a 'diamond' shape fitting in the bound rect.
+        diamond.shape.moveTo(rect.center().x(), rect.top());
+        diamond.shape.lineTo(rect.left(), rect.center().y());
+        diamond.shape.lineTo(rect.center().x(), rect.bottom());
+        diamond.shape.lineTo(rect.right(), rect.center().y());
+        diamond.shape.lineTo(rect.center().x(), rect.top());
+    }
+
+    SymbolProperty &subset = symbolTable[Subset];
+    if (subset.shape.isEmpty()) {
+        QRectF rect = subset.boundRect;
+        // Defines an arc fitting in bound rect.
+        qreal start = 90, span = 180;
+        subset.shape.arcMoveTo(rect, start);
+        subset.shape.arcTo(rect, start, span);
+    }
+
+    SymbolProperty &circle = symbolTable[Circle];
+    if (circle.shape.isEmpty()) {
+        QRectF rect = circle.boundRect;
+        // Defines a circle with a horizontal-vertical cross lines.
+        circle.shape.addEllipse(rect);
+
+        circle.shape.moveTo(rect.center().x(), rect.top());
+        circle.shape.lineTo(rect.center().x(), rect.bottom());
+
+        circle.shape.moveTo(rect.left(), rect.center().y());
+        circle.shape.lineTo(rect.right(), rect.center().y());
+    }
+
+}
+
+/**
+ * Constructs a Symbol with current symbol being \a symbol and
+ * parented to \a parent.
+ */
+Symbol::Symbol(SymbolType symbolType, QGraphicsItem *parent)
+  : QGraphicsItem(parent),
+    m_symbolType(symbolType)
+{
+    // ensure SymbolTable is validly initialized
+    setupSymbolTable();
+}
+
+/**
+ * Destructor.
+ */
+Symbol::~Symbol()
+{
+}
+
+/**
+ * @return The current symbol being represented.
+ */
+Symbol::SymbolType Symbol::symbolType() const
+{
+    return m_symbolType;
+}
+
+/**
+ * Sets the current symbol type to \a symbol and updates the geometry.
+ */
+void Symbol::setSymbolType(SymbolType symbolType)
+{
+    prepareGeometryChange();  // calls update implicitly
+    m_symbolType = symbolType;
+}
+
+/**
+ * Draws the current symbol using the QPainterPath stored for the current
+ * symbol.
+ */
+void Symbol::paint(QPainter *painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
+{
+    Q_UNUSED(option) Q_UNUSED(widget)
+    painter->setPen(m_pen);
+    switch (m_symbolType) {
+    case ClosedArrow:
+    case CrowFeet:
+    case Diamond:
+        painter->setBrush(m_brush);
+        break;
+    default:
+        break;
+    }
+    painter->drawPath(Symbol::symbolTable[m_symbolType].shape);
+}
+
+/**
+ * @return The bound rectangle for this based on current symbol.
+ */
+QRectF Symbol::boundingRect() const
+{
+    const qreal adj = .5 * m_pen.widthF();
+    return Symbol::symbolTable[m_symbolType].boundRect.
+        adjusted(-adj, -adj, adj, adj);
+}
+
+/**
+ * @return The path for this based on current symbol.
+ */
+QPainterPath Symbol::shape() const
+{
+    QPainterPath path;
+    path.addRect(boundingRect());
+    return path;
+}
+
+/**
+ * This method aligns *this* Symbol to the line being
+ * passed. That is, it ensures that the axis of this symbol aligns
+ * exactly with the \a "to" line passed.
+ *
+ * Also this item is moved such that the second end point of the
+ * SymbolEndPoints for the current symbol *collides* with the second end
+ * point of \a "to" line.
+ */
+void Symbol::alignTo(const QLineF& to)
+{
+    QLineF toMapped(mapFromParent(to.p1()), mapFromParent(to.p2()));
+
+    QLineF origAxis = Symbol::symbolTable[m_symbolType].axisLine;
+    QLineF translatedAxis = origAxis.translated(toMapped.p2() - origAxis.p2());
+
+    qreal angle = translatedAxis.angleTo(toMapped);
+    setRotation(rotation() - angle);
+
+    QPointF delta = to.p2() - mapToParent(symbolEndPoints().second);
+    moveBy(delta.x(), delta.y());
+}
+
+/**
+ * @return The end points for the symbol.
+ */
+Symbol::SymbolEndPoints Symbol::symbolEndPoints() const
+{
+    return Symbol::symbolTable[m_symbolType].endPoints;
+}
+
+/**
+ * @return The pen used to draw symbol.
+ */
+QPen Symbol::pen() const
+{
+    return m_pen;
+}
+
+/**
+ * Sets the pen used to draw the symbol.
+ */
+void Symbol::setPen(const QPen& pen)
+{
+    prepareGeometryChange();
+    m_pen = pen;
+    if (m_symbolType == ClosedArrow)
+        m_pen.setStyle(Qt::SolidLine);
+}
+
+/**
+ * @return The brush used to fill symbol.
+ */
+QBrush Symbol::brush() const
+{
+    return m_brush;
+}
+
+/**
+ * Sets the brush used to fill symbol.
+ */
+void Symbol::setBrush(const QBrush &brush)
+{
+    m_brush = brush;
+    update();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/associationline.h umbrello-15.08.1/umbrello/umlwidgets/associationline.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/associationline.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/associationline.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,207 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ASSOCIATIONLINE_H
+#define ASSOCIATIONLINE_H
+
+#include "basictypes.h"
+
+#include <QGraphicsObject>
+#include <QList>
+#include <QPen>
+#include <QPoint>
+
+// forward declarations
+class AssociationWidget;
+class QDomDocument;
+class QDomElement;
+class QPainter;
+
+/**
+ * This class provides with various symbols that can be embedded in
+ * AssociationLine.  It also provides with convenience methods to align
+ * the symbol to AssociationLine.
+ */
+class Symbol : public QGraphicsItem
+{
+    public:
+        typedef QPair<QPointF, QPointF> SymbolEndPoints;
+
+        /**
+         * This enumeration lists all the symbols that can be used as
+         * embedded on AssociationLine.
+         */
+        enum SymbolType {
+            None = -1,
+            OpenArrow,
+            ClosedArrow,
+            CrowFeet,
+            Diamond,
+            Subset,
+            Circle,
+            Count
+        };
+
+        explicit Symbol(SymbolType symbolType, QGraphicsItem *parent = 0);
+        virtual ~Symbol();
+
+        SymbolType symbolType() const;
+        void setSymbolType(SymbolType symbolType);
+
+        virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+        virtual QRectF boundingRect() const;
+        virtual QPainterPath shape() const;
+
+        void alignTo(const QLineF& line);
+        SymbolEndPoints symbolEndPoints() const;
+
+        QPen pen() const;
+        void setPen(const QPen &pen);
+
+        QBrush brush() const;
+        void setBrush(const QBrush& brush);
+
+    private:
+        QPen       m_pen;         ///< pen used to draw Symbol
+        QBrush     m_brush;       ///< brush used to fill Symbol
+        SymbolType m_symbolType;  ///< current symbol being represented by this item
+
+        /// A structure to hold a table of values for all symbols.
+        struct SymbolProperty {
+            QRectF boundRect;
+            QPainterPath shape;
+            QLineF axisLine;
+            SymbolEndPoints endPoints;
+        };
+
+        static SymbolProperty symbolTable[Symbol::Count];  ///< a table which stores all symbol properties
+        static void setupSymbolTable();
+};
+
+/**
+ * A convenience class that encapsulates geometry management, handles
+ * mouse and hover events, embeds and aligns symbols and finally draws the
+ * lines and points.
+ * Context menu events are handled in AssociationWidget.
+ *
+ * This class is infact a draw and event handling proxy for
+ * AssociationWidget.
+ *
+ * @note m_activePointIndex and m_activeSegmentIndex can't be
+ *       active at same time!
+ *
+ * @author Gopala Krishna
+ * @author Andi Fischer
+ * Bugs and comments to uml-devel@lists.sf.net or http://bugs.kde.org
+ */
+class AssociationLine : public QGraphicsObject
+{
+    Q_OBJECT
+    Q_ENUMS(LayoutType)
+public:
+    enum LayoutType {
+        Direct = 1,
+        Orthogonal,
+        Polyline,
+        Spline
+    };
+
+    static QString toString(LayoutType layout);
+    static LayoutType fromString(const QString& layout);
+
+    explicit AssociationLine(AssociationWidget *association);
+    virtual ~AssociationLine();
+
+    QPointF point(int index) const;
+    bool setPoint(int index, const QPointF& point);
+    QPointF startPoint() const;
+    QPointF endPoint() const;
+
+    void insertPoint(int index, const QPointF& point);
+    void removePoint(int index);
+
+    int count() const;
+    void cleanup();
+
+    void optimizeLinePoints();
+
+    int closestPointIndex(const QPointF& point, qreal delta = Delta) const;
+    int closestSegmentIndex(const QPointF& point, qreal delta = Delta) const;
+
+    bool isEndPointIndex(int index) const;
+    bool isEndSegmentIndex(int index) const;
+
+    bool setEndPoints(const QPointF &start, const QPointF &end);
+
+    void dumpPoints();
+
+    bool loadFromXMI(QDomElement &qElement);
+    void saveToXMI(QDomDocument &qDoc, QDomElement &qElement);
+
+    QBrush brush() const;
+    QPen pen() const;
+
+    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
+
+    QPainterPath path() const;
+
+    QRectF boundingRect() const;
+    QPainterPath shape() const;
+
+    LayoutType layout() const;
+    void setLayout(LayoutType layout);
+
+    void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+    void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+
+    void calculateInitialEndPoints();
+
+    void reconstructSymbols();
+
+private:
+    void setStartSymbol(Symbol::SymbolType symbolType);
+    void setEndSymbol(Symbol::SymbolType symbolType);
+
+    void createSubsetSymbol();
+    void removeSubsetSymbol();
+
+    void createCollaborationLine();
+    void removeCollaborationLine();
+
+    void alignSymbols();
+
+    void createSplinePoints();
+
+    AssociationWidget *m_associationWidget;      ///< association widget for which this line represents
+    QVector<QPointF>   m_points;                 ///< points representing the association line
+    int                m_activePointIndex;       ///< index of active point which can be dragged to modify association line
+    int                m_activeSegmentIndex;     ///< index of active segment
+    Symbol            *m_startSymbol;            ///< symbol drawn at the end of "first" line segment
+    Symbol            *m_endSymbol;              ///< symbol drawn at the end of "last" line segment
+    Symbol            *m_subsetSymbol;           ///< subset symbol
+    QGraphicsLineItem *m_collaborationLineItem;  ///< parallel arrow line drawn in case of collaboration message
+    Symbol            *m_collaborationLineHead;  ///< arrow head drawn at end of m_collaborationLineItem
+    LayoutType         m_layout;
+
+    static QPainterPath createBezierCurve(QVector<QPointF> points);
+    static QPainterPath createOrthogonalPath(QVector<QPointF> points);
+
+    static const qreal Delta;  ///< default delta for fuzzy recognition of points closer to point
+    static const qreal SelectedPointDiameter;         ///< radius of circles drawn to show "selection"
+    static const qreal SelfAssociationMinimumHeight;  ///< minimum height for self association's loop
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/associationwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/associationwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/associationwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/associationwidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,4407 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "associationwidget.h"
+
+// app includes
+#include "association.h"
+#include "associationline.h"
+#include "associationpropertiesdialog.h"
+#include "assocrules.h"
+#include "attribute.h"
+#include "classifier.h"
+#include "classifierwidget.h"
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "entity.h"
+#include "floatingtextwidget.h"
+#include "listpopupmenu.h"
+#include "messagewidget.h"
+#include "objectwidget.h"
+#include "operation.h"
+#include "optionstate.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "umlwidget.h"
+#include "widget_utils.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kcolordialog.h>
+#include <kfontdialog.h>
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QColorDialog>
+#include <QFontDialog>
+#include <QInputDialog>
+#endif
+#include <QPainterPath>
+#include <QPointer>
+#include <QRegExpValidator>
+#include <QApplication>
+
+// system includes
+#include <cmath>
+
+#define DBG_AW() DEBUG(QLatin1String("AssociationWidget"))
+DEBUG_REGISTER_DISABLED(AssociationWidget)
+
+using namespace Uml;
+
+/**
+  * Constructor is private because the static create() methods shall
+  * be used for constructing AssociationWidgets.
+  *
+  * @param scene   The parent view of this widget.
+  */
+AssociationWidget::AssociationWidget(UMLScene *scene)
+  : WidgetBase(scene, WidgetBase::wt_Association),
+    m_positions_len(0),
+    m_activated(false),
+    m_unNameLineSegment(-1),
+    m_nLinePathSegmentIndex(-1),
+    m_pAssocClassLine(0),
+    m_pAssocClassLineSel0(0),
+    m_pAssocClassLineSel1(0),
+    m_associationLine(new AssociationLine(this)),
+    m_associationClass(0),
+    m_associationType(Uml::AssociationType::Association),
+    m_nameWidget(0)
+{
+    // floating text widgets objects owned by this association
+    m_role[RoleType::A].changeabilityWidget = 0;
+    m_role[RoleType::B].changeabilityWidget = 0;
+    m_role[RoleType::A].multiplicityWidget = 0;
+    m_role[RoleType::B].multiplicityWidget = 0;
+    m_role[RoleType::A].roleWidget = 0;
+    m_role[RoleType::B].roleWidget = 0;
+    m_role[RoleType::A].umlWidget = 0;
+    m_role[RoleType::B].umlWidget = 0;
+
+    // associationwidget attributes
+    m_role[RoleType::A].m_WidgetRegion = Uml::Region::Error;
+    m_role[RoleType::B].m_WidgetRegion = Uml::Region::Error;
+    m_role[RoleType::A].m_nIndex = 0;
+    m_role[RoleType::B].m_nIndex = 0;
+    m_role[RoleType::A].m_nTotalCount = 0;
+    m_role[RoleType::B].m_nTotalCount = 0;
+    m_role[RoleType::A].visibility = Uml::Visibility::Public;
+    m_role[RoleType::B].visibility = Uml::Visibility::Public;
+    m_role[RoleType::A].changeability = Uml::Changeability::Changeable;
+    m_role[RoleType::B].changeability = Uml::Changeability::Changeable;
+
+    setFlag(QGraphicsLineItem::ItemIsSelectable);
+    setAcceptHoverEvents(true);
+}
+
+/**
+ * This constructor is really only for loading from XMI, otherwise it
+ * should not be allowed as it creates an incomplete associationwidget.
+  *
+  * @param scene   The parent view of this widget.
+ */
+AssociationWidget* AssociationWidget::create(UMLScene *scene)
+{
+    AssociationWidget* instance = new AssociationWidget(scene);
+    return instance;
+}
+
+/**
+  * Preferred constructor (static factory method.)
+  *
+  * @param scene      The parent view of this widget.
+  * @param pWidgetA   Pointer to the role A widget for the association.
+  * @param assocType  The AssociationType::Enum for this association.
+  * @param pWidgetB   Pointer to the role B widget for the association.
+  * @param umlobject  Pointer to the underlying UMLObject (if applicable.)
+  */
+AssociationWidget* AssociationWidget::create
+                                    (UMLScene *scene, UMLWidget* pWidgetA,
+                                     Uml::AssociationType::Enum assocType, UMLWidget* pWidgetB,
+                                     UMLObject *umlobject /* = NULL */)
+{
+    AssociationWidget* instance = new AssociationWidget(scene);
+    if (umlobject) {
+        instance->setUMLObject(umlobject);
+    } else {
+        // set up UMLAssociation obj if assoc is represented and both roles are UML objects
+        if (Uml::AssociationType::hasUMLRepresentation(assocType)) {
+            UMLObject* umlRoleA = pWidgetA->umlObject();
+            UMLObject* umlRoleB = pWidgetB->umlObject();
+            if (umlRoleA != NULL && umlRoleB != NULL) {
+                bool swap;
+
+                // This is not correct. We could very easily have more than one
+                // of the same type of association between the same two objects.
+                // Just create the association. This search should have been
+                // done BEFORE creation of the widget, if it mattered to the code.
+                // But lets leave check in here for the time being so that debugging
+                // output is shown, in case there is a collision with code elsewhere.
+                UMLDoc *doc = UMLApp::app()->document();
+                UMLAssociation *myAssoc = doc->findAssociation(assocType, umlRoleA, umlRoleB, &swap);
+                if (myAssoc != NULL) {
+                    switch (assocType) {
+                        case Uml::AssociationType::Generalization:
+                        case Uml::AssociationType::Dependency:
+                        case Uml::AssociationType::Association_Self:
+                        case Uml::AssociationType::Coll_Message_Self:
+                        case Uml::AssociationType::Seq_Message_Self:
+                        case Uml::AssociationType::Containment:
+                        case Uml::AssociationType::Realization:
+                            DBG_AW() << "Ignoring second construction of same assoctype "
+                                     << assocType << " between " << umlRoleA->name()
+                                     << " and " << umlRoleB->name();
+                            break;
+                        default:
+                            DBG_AW() << "constructing a similar or exact same assoctype "
+                                     << assocType << " between " << umlRoleA->name() << " and "
+                                     << umlRoleB->name() << "as an already existing assoc (swap="
+                                     << swap << ")";
+                            // now, just create a new association anyways
+                            myAssoc = NULL;
+                            break;
+                    }
+                }
+                if (myAssoc == NULL) {
+                    myAssoc = new UMLAssociation(assocType, umlRoleA, umlRoleB);
+                    // CHECK: myAssoc is not yet inserted at any parent UMLPackage -
+                    // need to check carefully that all callers do this, lest it be
+                    // orphaned.
+                    // ToolBarStateAssociation::addAssociationInViewAndDoc() is
+                    // okay in this regard.
+                }
+                instance->setUMLAssociation(myAssoc);
+            }
+        }
+    }
+
+    instance->setWidgetForRole(pWidgetA, RoleType::A);
+    instance->setWidgetForRole(pWidgetB, RoleType::B);
+
+    instance->setAssociationType(assocType);
+
+    instance->calculateEndingPoints();
+
+    instance->associationLine()->calculateInitialEndPoints();
+    instance->associationLine()->reconstructSymbols();
+
+    //The AssociationWidget is set to Activated because it already has its side widgets
+    instance->setActivated(true);
+
+    // sync UML meta-data to settings here
+    instance->mergeAssociationDataIntoUMLRepresentation();
+
+    // Collaboration messages need a name label because it's that
+    // which lets operator== distinguish them, which in turn
+    // permits us to have more than one message between two objects.
+    if (instance->isCollaboration()) {
+        // Create a temporary name to bring on setName()
+        int collabID = instance->m_scene->generateCollaborationId();
+        instance->setName(QLatin1Char('m') + QString::number(collabID));
+    }
+
+    return instance;
+}
+
+/**
+ * Destructor.
+ */
+AssociationWidget::~AssociationWidget()
+{
+    delete m_associationLine;
+}
+
+/**
+ * Overriding the method from WidgetBase because we need to do
+ * something extra in case this AssociationWidget represents
+ * an attribute of a classifier.
+ */
+void AssociationWidget::setUMLObject(UMLObject *obj)
+{
+    WidgetBase::setUMLObject(obj);
+    if (obj == NULL)
+        return;
+    UMLClassifier *klass = NULL;
+    UMLAttribute *attr = NULL;
+    UMLEntity *ent = NULL;
+    const UMLObject::ObjectType ot = obj->baseType();
+    switch (ot) {
+        case UMLObject::ot_Association:
+            setUMLAssociation(dynamic_cast<UMLAssociation*>(obj));
+            break;
+        case UMLObject::ot_Operation:
+            setOperation(dynamic_cast<UMLOperation*>(obj));
+            break;
+        case UMLObject::ot_Attribute:
+            klass = static_cast<UMLClassifier*>(obj->parent());
+            connect(klass, SIGNAL(attributeRemoved(UMLClassifierListItem*)),
+                    this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
+            attr = static_cast<UMLAttribute*>(obj);
+            connect(attr, SIGNAL(attributeChanged()), this, SLOT(slotAttributeChanged()));
+            break;
+        case UMLObject::ot_EntityAttribute:
+            ent = static_cast<UMLEntity*>(obj->parent());
+            connect(ent, SIGNAL(entityAttributeRemoved(UMLClassifierListItem*)),
+                    this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
+            break;
+        case UMLObject::ot_ForeignKeyConstraint:
+            ent = static_cast<UMLEntity*>(obj->parent());
+            connect(ent, SIGNAL(entityConstraintRemoved(UMLClassifierListItem*)),
+                    this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
+            break;
+        default:
+            uError() << "cannot associate UMLObject of type " << UMLObject::toString(ot);
+            break;
+    }
+}
+
+/**
+ * Set all 'owned' child widgets to this font.
+ */
+void AssociationWidget::lwSetFont (QFont font)
+{
+    if (m_nameWidget) {
+        m_nameWidget->setFont(font);
+    }
+    if (m_role[RoleType::A].roleWidget) {
+        m_role[RoleType::A].roleWidget->setFont(font);
+    }
+    if (m_role[RoleType::B].roleWidget) {
+        m_role[RoleType::B].roleWidget->setFont(font);
+    }
+    if (m_role[RoleType::A].multiplicityWidget) {
+        m_role[RoleType::A].multiplicityWidget->setFont(font);
+    }
+    if (m_role[RoleType::B].multiplicityWidget) {
+        m_role[RoleType::B].multiplicityWidget->setFont(font);
+    }
+    if (m_role[RoleType::A].changeabilityWidget)
+        m_role[RoleType::A].changeabilityWidget->setFont(font);
+    if (m_role[RoleType::B].changeabilityWidget)
+        m_role[RoleType::B].changeabilityWidget->setFont(font);
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ * @todo Move to LinkWidget.
+ */
+UMLClassifier *AssociationWidget::operationOwner()
+{
+    Uml::RoleType::Enum role = (isCollaboration() ? Uml::RoleType::B : Uml::RoleType::A);
+    UMLObject *o = widgetForRole(role)->umlObject();
+    if (!o) {
+        return 0;
+    }
+    UMLClassifier *c = dynamic_cast<UMLClassifier*>(o);
+    if (!c) {
+        uError() << "widgetForRole(" << role << ") is not a classifier";
+    }
+    return c;
+}
+
+/**
+ * Implements operation from LinkWidget.
+ * Motivated by FloatingTextWidget.
+ */
+UMLOperation *AssociationWidget::operation()
+{
+    return dynamic_cast<UMLOperation*>(m_umlObject);
+}
+
+/**
+ * Implements operation from LinkWidget.
+ * Motivated by FloatingTextWidget.
+ */
+void AssociationWidget::setOperation(UMLOperation *op)
+{
+    if (m_umlObject)
+        disconnect(m_umlObject, SIGNAL(modified()), m_nameWidget, SLOT(setMessageText()));
+    m_umlObject = op;
+    if (m_umlObject)
+        connect(m_umlObject, SIGNAL(modified()), m_nameWidget, SLOT(setMessageText()));
+    if (m_nameWidget)
+        m_nameWidget->setMessageText();
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+QString AssociationWidget::customOpText()
+{
+    return name();
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+void AssociationWidget::setCustomOpText(const QString &opText)
+{
+    setName(opText);
+}
+
+/**
+ * Calls setTextPosition on all the labels.
+ * Overrides operation from LinkWidget.
+ */
+void AssociationWidget::resetTextPositions()
+{
+    if (m_role[RoleType::A].multiplicityWidget) {
+        setTextPosition(TextRole::MultiA);
+    }
+    if (m_role[RoleType::B].multiplicityWidget) {
+        setTextPosition(Uml::TextRole::MultiB);
+    }
+    if (m_role[RoleType::A].changeabilityWidget) {
+        setTextPosition(Uml::TextRole::ChangeA);
+    }
+    if (m_role[RoleType::B].changeabilityWidget) {
+        setTextPosition(Uml::TextRole::ChangeB);
+    }
+    if (m_nameWidget) {
+        setTextPosition(Uml::TextRole::Name);
+    }
+    if (m_role[RoleType::A].roleWidget) {
+        setTextPosition(Uml::TextRole::RoleAName);
+    }
+    if (m_role[RoleType::B].roleWidget) {
+        setTextPosition(Uml::TextRole::RoleBName);
+    }
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @param ft   The text widget which to update.
+ */
+void AssociationWidget::setMessageText(FloatingTextWidget *ft)
+{
+    if (isCollaboration()) {
+        ft->setSequenceNumber(m_SequenceNumber);
+        if (m_umlObject != NULL) {
+            ft->setText(operationText(m_scene));
+        } else {
+            ft->setText(name());
+        }
+    } else {
+        ft->setText(name());
+    }
+}
+
+/**
+ * Sets the text of the given FloatingTextWidget.
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+void AssociationWidget::setText(FloatingTextWidget *ft, const QString &text)
+{
+    Uml::TextRole::Enum role = ft->textRole();
+    switch (role) {
+        case Uml::TextRole::Name:
+            setName(text);
+            break;
+        case Uml::TextRole::RoleAName:
+            setRoleName(text, RoleType::A);
+            break;
+        case Uml::TextRole::RoleBName:
+            setRoleName(text, RoleType::B);
+            break;
+        case Uml::TextRole::MultiA:
+            setMultiplicity(text, RoleType::A);
+            break;
+        case Uml::TextRole::MultiB:
+            setMultiplicity(text, RoleType::B);
+            break;
+        default:
+            uWarning() << "Unhandled TextRole: " << Uml::TextRole::toString(role);
+            break;
+    }
+}
+
+/**
+ * Shows the association properties dialog and updates the
+ * corresponding texts if its execution is successful.
+ */
+void AssociationWidget::showPropertiesDialog()
+{
+    UMLApp::app()->docWindow()->updateDocumentation();
+    QPointer<AssociationPropertiesDialog> dlg = new AssociationPropertiesDialog(static_cast<QWidget*>(m_scene->activeView()), this);
+    if (dlg->exec()) {
+        //rules built into these functions to stop updating incorrect values
+        setName(name());
+
+        setRoleName(roleName(RoleType::A), RoleType::A);
+        setRoleName(roleName(RoleType::B), RoleType::B);
+
+        setDocumentation(documentation());
+
+        setRoleDocumentation(roleDocumentation(RoleType::A), RoleType::A);
+        setRoleDocumentation(roleDocumentation(RoleType::B), RoleType::B);
+
+        setMultiplicity(multiplicity(RoleType::A), RoleType::A);
+        setMultiplicity(multiplicity(RoleType::B), RoleType::B);
+
+        setVisibility(visibility(RoleType::A), RoleType::A);
+        setVisibility(visibility(RoleType::B), RoleType::B);
+
+        setChangeability(changeability(RoleType::A), RoleType::A);
+        setChangeability(changeability(RoleType::B), RoleType::B);
+
+        UMLApp::app()->docWindow()->showDocumentation(this, true);
+    }
+    delete dlg;
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @param op        Return this AssociationWidget's operation string.
+ */
+QString AssociationWidget::lwOperationText()
+{
+    return name();
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @return classifier
+ */
+UMLClassifier* AssociationWidget::lwClassifier()
+{
+    UMLObject *o = widgetForRole(RoleType::B)->umlObject();
+    UMLClassifier *c = dynamic_cast<UMLClassifier*>(o);
+    return c;
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @param op       The new operation string to set.
+ */
+void AssociationWidget::setOperationText(const QString &op)
+{
+    if (!op.isEmpty()) {
+        setName(op);
+    }
+}
+
+/**
+ * Calculates the m_unNameLineSegment value according to the new
+ * NameText topleft corner PT.
+ * It iterates through all AssociationLine's segments and for each one
+ * calculates the sum of PT's distance to the start point + PT's
+ * distance to the end point. The segment with the smallest sum will
+ * be the RoleTextSegment (if this segment moves then the RoleText
+ * will move with it). It sets m_unNameLineSegment to the start point
+ * of the chosen segment.
+ *
+ * Overrides operation from LinkWidget (i.e. this method is also
+ * required by FloatingTextWidget.)
+ */
+void AssociationWidget::calculateNameTextSegment()
+{
+    if (!m_nameWidget) {
+        return;
+    }
+    //changed to use the middle of the text
+    //i think this will give a better result.
+    //never know what sort of lines people come up with
+    //and text could be long to give a false reading
+    qreal xt = m_nameWidget->x();
+    qreal yt = m_nameWidget->y();
+    xt += m_nameWidget->width() / 2;
+    yt += m_nameWidget->height() / 2;
+    int size = m_associationLine->count();
+    //sum of length(PTP1) and length(PTP2)
+    qreal total_length = 0;
+    qreal smallest_length = 0;
+    for (int i = 0; i < size - 1; ++i) {
+        QPointF pi = m_associationLine->point( i );
+        QPointF pj = m_associationLine->point( i+1 );
+        qreal xtiDiff = xt - pi.x();
+        qreal xtjDiff = xt - pj.x();
+        qreal ytiDiff = yt - pi.y();
+        qreal ytjDiff = yt - pj.y();
+        total_length =  sqrt( double(xtiDiff * xtiDiff + ytiDiff * ytiDiff) )
+                        + sqrt( double(xtjDiff * xtjDiff + ytjDiff * ytjDiff) );
+        //this gives the closest point
+        if (total_length < smallest_length || i == 0) {
+            smallest_length = total_length;
+            m_unNameLineSegment = i;
+        }
+    }
+}
+
+/**
+ * Returns the UMLAssociation representation of this object.
+ *
+ * @return  Pointer to the UMLAssociation that is represented by
+ *          this AsociationWidget.
+ */
+UMLAssociation* AssociationWidget::association() const
+{
+    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
+        return NULL;
+    return static_cast<UMLAssociation*>(m_umlObject);
+}
+
+/**
+ * Returns the UMLAttribute representation of this object.
+ *
+ * @return  Pointer to the UMLAttribute that is represented by
+ *          this AsociationWidget.
+ */
+UMLAttribute* AssociationWidget::attribute() const
+{
+    if (m_umlObject == NULL)
+        return NULL;
+    UMLObject::ObjectType ot = m_umlObject->baseType();
+    if (ot != UMLObject::ot_Attribute && ot != UMLObject::ot_EntityAttribute)
+        return NULL;
+    return static_cast<UMLAttribute*>(m_umlObject);
+}
+
+#if 0  //:TODO:
+/**
+ * Overrides the assignment operator.
+ */
+AssociationWidget& AssociationWidget::operator=(const AssociationWidget& other)
+{
+    *m_associationLine = *other.m_associationLine;
+
+    if (other.m_nameWidget) {
+        m_nameWidget = new FloatingTextWidget(m_scene);
+        *m_nameWidget = *(other.m_nameWidget);
+    } else {
+        m_nameWidget = NULL;
+    }
+
+    for (unsigned r = (unsigned)A; r <= (unsigned)B; ++r) {
+        WidgetRole& lhs = m_role[r];
+        const WidgetRole& rhs = other.m_role[r];
+        lhs.m_nIndex = rhs.m_nIndex;
+        lhs.m_nTotalCount = rhs.m_nTotalCount;
+
+        if (rhs.multiplicityWidget) {
+            lhs.multiplicityWidget = new FloatingTextWidget(m_scene);
+            *(lhs.multiplicityWidget) = *(rhs.multiplicityWidget);
+        } else {
+            lhs.multiplicityWidget = NULL;
+        }
+
+        if (rhs.roleWidget) {
+            lhs.roleWidget = new FloatingTextWidget(m_scene);
+            *(lhs.roleWidget) = *(rhs.roleWidget);
+        } else {
+            lhs.roleWidget = NULL;
+        }
+
+        if (rhs.changeabilityWidget) {
+            lhs.changeabilityWidget = new FloatingTextWidget(m_scene);
+            *(lhs.changeabilityWidget) = *(rhs.changeabilityWidget);
+        } else {
+            lhs.changeabilityWidget = NULL;
+        }
+
+        lhs.umlWidget = rhs.umlWidget;
+        lhs.m_WidgetRegion = rhs.m_WidgetRegion;
+    }
+
+    m_activated = other.m_activated;
+    m_unNameLineSegment = other.m_unNameLineSegment;
+    m_pMenu = other.m_pMenu;
+    setUMLAssociation(other.association());
+    setSelected(other.isSelected());
+
+    return *this;
+}
+#endif  //:TODO:
+
+/**
+ * Overrides the equality test operator.
+ */
+bool AssociationWidget::operator==(const AssociationWidget& other) const
+{
+    if (this == &other)
+        return true;
+
+    // if no model representation exists, then the widgets are not equal
+    if (association() == NULL && other.association() == NULL)
+        return false;
+
+    if (!m_umlObject || !other.m_umlObject ) {
+        if (!other.m_umlObject && m_umlObject)
+            return false;
+        if (other.m_umlObject && !m_umlObject)
+            return false;
+
+    } else if (m_umlObject != other.m_umlObject)
+        return false;
+
+    if (associationType() != other.associationType())
+        return false;
+
+    if (widgetIDForRole(RoleType::A) != other.widgetIDForRole(RoleType::A))
+        return false;
+
+    if (widgetIDForRole(RoleType::B) != other.widgetIDForRole(RoleType::B))
+        return false;
+
+    if (widgetForRole(RoleType::A)->baseType() == WidgetBase::wt_Object &&
+            other.widgetForRole(RoleType::A)->baseType() == WidgetBase::wt_Object) {
+        ObjectWidget *ownA = static_cast<ObjectWidget*>(widgetForRole(RoleType::A));
+        ObjectWidget *otherA = static_cast<ObjectWidget*>(other.widgetForRole(RoleType::A));
+        if (ownA->localID() != otherA->localID())
+            return false;
+    }
+
+    if (widgetForRole(RoleType::B)->baseType() == WidgetBase::wt_Object &&
+            other.widgetForRole(RoleType::B)->baseType() == WidgetBase::wt_Object) {
+        ObjectWidget *ownB = static_cast<ObjectWidget*>(widgetForRole(RoleType::B));
+        ObjectWidget *otherB = static_cast<ObjectWidget*>(other.widgetForRole(RoleType::B));
+        if (ownB->localID() != otherB->localID())
+            return false;
+    }
+
+    // Two objects in a collaboration can have multiple messages between each other.
+    // Here we depend on the messages having names, and the names must be different.
+    // That is the reason why collaboration messages have strange initial names like
+    // "m29997" or similar.
+    return (name() == other.name());
+}
+
+/**
+ * Overrides the != operator.
+ */
+bool AssociationWidget::operator!=(AssociationWidget& other) const
+{
+    return !(*this == other);
+}
+
+/**
+ * Returns a pointer to the association widget's line path.
+ */
+AssociationLine* AssociationWidget::associationLine() const
+{
+    return m_associationLine;
+}
+
+/**
+ * Activates the AssociationWidget after a load.
+ *
+ * @return  true for success
+ */
+bool AssociationWidget::activate()
+{
+    if (m_umlObject == NULL &&
+        AssociationType::hasUMLRepresentation(m_associationType)) {
+        UMLObject *myObj = umlDoc()->findObjectById(m_nId);
+        if (myObj == NULL) {
+            uError() << "cannot find UMLObject " << Uml::ID::toString(m_nId);
+            return false;
+        } else {
+            const UMLObject::ObjectType ot = myObj->baseType();
+            if (ot == UMLObject::ot_Association) {
+                UMLAssociation * myAssoc = static_cast<UMLAssociation*>(myObj);
+                setUMLAssociation(myAssoc);
+            } else {
+                setUMLObject(myObj);
+                setAssociationType(m_associationType);
+            }
+        }
+    }
+
+    if (m_activated)
+        return true;
+
+    Uml::AssociationType::Enum type = associationType();
+
+    if (m_role[RoleType::A].umlWidget == NULL)
+        setWidgetForRole(m_scene->findWidget(widgetIDForRole(RoleType::A)), RoleType::A);
+    if (m_role[RoleType::B].umlWidget == NULL)
+        setWidgetForRole(m_scene->findWidget(widgetIDForRole(RoleType::B)), RoleType::B);
+
+    if (!m_role[RoleType::A].umlWidget || !m_role[RoleType::B].umlWidget) {
+        DEBUG(DBG_SRC) << "Cannot make association!";
+        return false;
+    }
+
+    calculateEndingPoints();
+
+    if (AssocRules::allowRole(type)) {
+        for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
+            WidgetRole& robj = m_role[r];
+            if (robj.roleWidget == NULL)
+                continue;
+            robj.roleWidget->setLink(this);
+            TextRole::Enum tr = (r == RoleType::A ? TextRole::RoleAName : TextRole::RoleBName);
+            robj.roleWidget->setTextRole(tr);
+            Uml::Visibility::Enum vis = visibility(Uml::RoleType::fromInt(r));
+            robj.roleWidget->setPreText(Uml::Visibility::toString(vis, true));
+
+            if (FloatingTextWidget::isTextValid(robj.roleWidget->text()))
+                robj.roleWidget->show();
+            else
+                robj.roleWidget->hide();
+            if (m_scene->type() == DiagramType::Collaboration)
+                robj.roleWidget->setUMLObject(robj.umlWidget->umlObject());
+            robj.roleWidget->activate();
+        }
+    }
+
+    if (m_nameWidget != NULL) {
+        m_nameWidget->setLink(this);
+        m_nameWidget->setTextRole(calculateNameType(TextRole::Name));
+
+        if (FloatingTextWidget::isTextValid(m_nameWidget->text())) {
+            m_nameWidget->show();
+        } else {
+            m_nameWidget->hide();
+        }
+        m_nameWidget->activate();
+        calculateNameTextSegment();
+    }
+
+    for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
+        WidgetRole& robj = m_role[r];
+
+        FloatingTextWidget* pMulti = robj.multiplicityWidget;
+        if (pMulti != NULL &&
+                AssocRules::allowMultiplicity(type, robj.umlWidget->baseType())) {
+            pMulti->setLink(this);
+            TextRole::Enum tr = (r == RoleType::A ? TextRole::MultiA : TextRole::MultiB);
+            pMulti->setTextRole(tr);
+            if (FloatingTextWidget::isTextValid(pMulti->text()))
+                pMulti->show();
+            else
+                pMulti->hide();
+            pMulti->activate();
+        }
+
+        FloatingTextWidget* pChangeWidget = robj.changeabilityWidget;
+        if (pChangeWidget != NULL) {
+            pChangeWidget->setLink(this);
+            TextRole::Enum tr = (r == RoleType::A ? TextRole::ChangeA : TextRole::ChangeB);
+            pChangeWidget->setTextRole(tr);
+            if (FloatingTextWidget::isTextValid(pChangeWidget->text()))
+                pChangeWidget->show();
+            else
+                pChangeWidget->hide ();
+            pChangeWidget->activate();
+        }
+    }
+
+    // Prepare the association class line if needed.
+    if (m_associationClass && !m_pAssocClassLine) {
+        createAssocClassLine();
+    }
+
+    m_activated = true;
+    return true;
+}
+
+/**
+ * Set the widget of the given role.
+ * Add this AssociationWidget at the widget.
+ * If this AssociationWidget has an underlying UMLAssociation then set
+ * the widget's underlying UMLObject at the UMLAssociation's role object.
+ *
+ * @param widget    Pointer to the UMLWidget.
+ * @param role      Role for which to set the widget.
+ */
+void AssociationWidget::setWidgetForRole(UMLWidget* widget, Uml::RoleType::Enum role)
+{
+    m_role[role].umlWidget = widget;
+    if (widget) {
+        m_role[role].umlWidget->addAssoc(this);
+        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
+            association()->setObject(widget->umlObject(), role);
+    }
+}
+
+/**
+ * Return the multiplicity FloatingTextWidget widget of the given role.
+ *
+ * @return  Pointer to the multiplicity FloatingTextWidget object.
+ */
+FloatingTextWidget* AssociationWidget::multiplicityWidget(Uml::RoleType::Enum role) const
+{
+    return m_role[role].multiplicityWidget;
+}
+
+/**
+ * Read property of FloatingTextWidget* m_nameWidget.
+ *
+ * @return  Pointer to the FloatingTextWidget name widget.
+ */
+FloatingTextWidget* AssociationWidget::nameWidget() const
+{
+    return m_nameWidget;
+}
+
+/**
+ * Return the given role's FloatingTextWidget object.
+ *
+ * @return  Pointer to the role's FloatingTextWidget widget.
+ */
+FloatingTextWidget* AssociationWidget::roleWidget(Uml::RoleType::Enum role) const
+{
+    return m_role[role].roleWidget;
+}
+
+/**
+ * Return the given role's changeability FloatingTextWidget widget.
+ */
+FloatingTextWidget* AssociationWidget::changeabilityWidget(Uml::RoleType::Enum role) const
+{
+    return m_role[role].changeabilityWidget;
+}
+
+/**
+ * Return the FloatingTextWidget object indicated by the given TextRole::Enum.
+ *
+ * @return  Pointer to the text role's FloatingTextWidget widget.
+ */
+FloatingTextWidget* AssociationWidget::textWidgetByRole(Uml::TextRole::Enum tr) const
+{
+    switch (tr) {
+        case Uml::TextRole::MultiA:
+            return m_role[RoleType::A].multiplicityWidget;
+        case Uml::TextRole::MultiB:
+            return m_role[RoleType::B].multiplicityWidget;
+        case Uml::TextRole::Name:
+        case Uml::TextRole::Coll_Message:
+            return m_nameWidget;
+        case Uml::TextRole::RoleAName:
+            return m_role[RoleType::A].roleWidget;
+        case Uml::TextRole::RoleBName:
+            return m_role[RoleType::B].roleWidget;
+        case Uml::TextRole::ChangeA:
+            return m_role[RoleType::A].changeabilityWidget;
+        case Uml::TextRole::ChangeB:
+            return m_role[RoleType::B].changeabilityWidget;
+        default:
+            break;
+    }
+    return NULL;
+}
+
+/**
+ * Returns the m_nameWidget's text.
+ *
+ * @return  Text of the FloatingTextWidget name widget.
+ */
+QString AssociationWidget::name() const
+{
+    if (m_nameWidget == NULL)
+        return QString();
+    return m_nameWidget->text();
+}
+
+/**
+ * Sets the text in the FloatingTextWidget widget representing the Name
+ * of this association.
+ */
+void AssociationWidget::setName(const QString &strName)
+{
+    // set attribute of UMLAssociation associated with this associationwidget
+    UMLAssociation *umla = association();
+    if (umla)
+        umla->setName(strName);
+
+    bool newLabel = false;
+    if (!m_nameWidget) {
+        // Don't construct the FloatingTextWidget if the string is empty.
+        if (! FloatingTextWidget::isTextValid(strName))
+            return;
+
+        newLabel = true;
+        m_nameWidget = new FloatingTextWidget(m_scene, calculateNameType(Uml::TextRole::Name), strName);
+        m_nameWidget->setParentItem(this);
+        m_nameWidget->setLink(this);
+    } else {
+        m_nameWidget->setText(strName);
+        if (! FloatingTextWidget::isTextValid(strName)) {
+            //m_nameWidget->hide();
+            m_scene->removeWidget(m_nameWidget);
+            m_nameWidget = NULL;
+            return;
+        }
+    }
+
+    setTextPosition(Uml::TextRole::Name);
+    if (newLabel) {
+        m_nameWidget->setActivated();
+        m_scene->addFloatingTextWidget(m_nameWidget);
+    }
+
+    m_nameWidget->show();
+}
+
+void AssociationWidget::setStereotype(const QString &stereo) {
+    UMLAssociation *umlassoc = association();
+    if (umlassoc) {
+        umlassoc->setStereotype(stereo);
+        if (m_nameWidget) {
+            m_nameWidget->setText(umlassoc->stereotype(true));
+        } else {
+            uDebug() << "not setting " << stereo << " because m_nameWidget is NULL";
+        }
+    } else {
+        uDebug() << "not setting " << stereo << " because association is NULL";
+    }
+}
+
+/**
+ * Return the given role's FloatingTextWidget widget text.
+ *
+ * @return  The name set at the FloatingTextWidget.
+ */
+QString AssociationWidget::roleName(Uml::RoleType::Enum role) const
+{
+    if (m_role[role].roleWidget == NULL)
+        return QString();
+    return m_role[role].roleWidget->text();
+}
+
+/**
+ * Sets the text to the FloatingTextWidget that display the Role text of this
+ * association.
+ * For this function to work properly, the associated widget
+ *  should already be set.
+ */
+void AssociationWidget::setRoleName(const QString &strRole, Uml::RoleType::Enum role)
+{
+    Uml::AssociationType::Enum type = associationType();
+    //if the association is not supposed to have a Role FloatingTextWidget
+    if (!AssocRules::allowRole(type))  {
+        return;
+    }
+
+    TextRole::Enum tr = (role == RoleType::A ? TextRole::RoleAName : TextRole::RoleBName);
+    setFloatingText(tr, strRole, m_role[role].roleWidget);
+    if (m_role[role].roleWidget) {
+        Uml::Visibility::Enum vis = visibility(role);
+        if (FloatingTextWidget::isTextValid(m_role[role].roleWidget->text())) {
+            m_role[role].roleWidget->setPreText(Uml::Visibility::toString(vis, true));
+            //m_role[role].roleWidget->show();
+        } else {
+            m_role[role].roleWidget->setPreText(QString());
+            //m_role[role].roleWidget->hide();
+        }
+    }
+
+    // set attribute of UMLAssociation associated with this associationwidget
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
+        association()->setRoleName(strRole, role);
+}
+
+/**
+ * Set the documentation on the given role.
+ */
+void AssociationWidget::setRoleDocumentation(const QString &doc, Uml::RoleType::Enum role)
+{
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
+        association()->setRoleDoc(doc, role);
+    else
+        m_role[role].roleDocumentation = doc;
+}
+
+/**
+ * Returns the given role's documentation.
+ */
+QString AssociationWidget::roleDocumentation(Uml::RoleType::Enum role) const
+{
+    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
+        return QString();
+    UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
+    return umla->getRoleDoc(role);
+}
+
+/**
+ * Change, create, or delete the FloatingTextWidget indicated by the given TextRole::Enum.
+ *
+ * @param tr    TextRole::Enum of the FloatingTextWidget to change or create.
+ * @param text  Text string that controls the action:
+ *              If empty and ft is NULL then setFloatingText() is a no-op.
+ *              If empty and ft is non-NULL then the existing ft is deleted.
+ *              If non-empty and ft is NULL then a new FloatingTextWidget is created
+ *              and returned in ft with the text set.
+ *              If non-empty and ft is non-NULL then the existing ft text is modified.
+ * @param ft    Reference to the pointer to FloatingTextWidget to change or create.
+ *              On creation/deletion, the pointer value will be changed.
+ */
+void AssociationWidget::setFloatingText(Uml::TextRole::Enum role,
+                                        const QString &text,
+                                        FloatingTextWidget* &ft)
+{
+    if (! FloatingTextWidget::isTextValid(text)) {
+        if (ft) {
+            // Remove preexisting FloatingTextWidget
+            m_scene->removeWidget(ft);  // physically deletes ft
+            ft = NULL;
+        }
+        return;
+    }
+
+    if (ft == NULL) {
+        ft = new FloatingTextWidget(m_scene, role, text);
+        ft->setParentItem(this);
+        ft->setLink(this);
+        ft->activate();
+        setTextPosition(role);
+        m_scene->addFloatingTextWidget(ft);
+    } else {
+        bool newLabel = ft->text().isEmpty();
+        ft->setText(text);
+        if (newLabel)
+            setTextPosition(role);
+    }
+
+    ft->show();
+}
+
+/**
+ * Return the given role's multiplicity text.
+ *
+ * @return  Text of the given role's multiplicity widget.
+ */
+QString AssociationWidget::multiplicity(Uml::RoleType::Enum role) const
+{
+    if (m_role[role].multiplicityWidget == NULL)
+        return QString();
+    return m_role[role].multiplicityWidget->text();
+}
+
+/**
+ * Sets the text in the FloatingTextWidget representing the multiplicity
+ * at the given side of the association.
+ */
+void AssociationWidget::setMultiplicity(const QString& text, Uml::RoleType::Enum role)
+{
+    TextRole::Enum tr = (role == RoleType::A ? TextRole::MultiA : TextRole::MultiB);
+
+    setFloatingText(tr, text, m_role[role].multiplicityWidget);
+
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
+        association()->setMultiplicity(text, role);
+}
+
+/**
+ * Gets the visibility on the given role of the association.
+ */
+Visibility::Enum AssociationWidget::visibility(Uml::RoleType::Enum role) const
+{
+    const UMLAssociation *assoc = association();
+    if (assoc)
+        return assoc->visibility(role);
+    const UMLAttribute *attr = attribute();
+    if (attr)
+        return attr->visibility();
+    return m_role[role].visibility;
+}
+
+/**
+ * Sets the visibility on the given role of the association.
+ */
+void AssociationWidget::setVisibility(Visibility::Enum value, Uml::RoleType::Enum role)
+{
+    if (value == visibility(role)) {
+        return;
+    }
+    if (m_umlObject) {
+        // update our model object
+        const UMLObject::ObjectType ot = m_umlObject->baseType();
+        if (ot == UMLObject::ot_Association)
+            association()->setVisibility(value, role);
+        else if (ot == UMLObject::ot_Attribute)
+            attribute()->setVisibility(value);
+    }
+    m_role[role].visibility = value;
+    // update role pre-text attribute as appropriate
+    if (m_role[role].roleWidget) {
+        QString scopeString = Visibility::toString(value, true);
+        m_role[role].roleWidget->setPreText(scopeString);
+    }
+}
+
+/**
+ * Gets the changeability on the given end of the Association.
+ */
+Uml::Changeability::Enum AssociationWidget::changeability(Uml::RoleType::Enum role) const
+{
+    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
+        return m_role[role].changeability;
+    UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
+    return umla->changeability(role);
+}
+
+/**
+ * Sets the changeability on the given end of the Association.
+ */
+void AssociationWidget::setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role)
+{
+    if (value == changeability(role))
+        return;
+    QString changeString = Uml::Changeability::toString(value);
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)  // update our model object
+        association()->setChangeability(value, role);
+    m_role[role].changeability = value;
+    // update our string representation
+    setChangeWidget(changeString, role);
+}
+
+/**
+ * For internal purposes only.
+ * Other classes/users should use setChangeability() instead.
+ */
+void AssociationWidget::setChangeWidget(const QString &strChangeWidget, Uml::RoleType::Enum role)
+{
+    bool newLabel = false;
+    TextRole::Enum tr = (role == RoleType::A ? TextRole::ChangeA : TextRole::ChangeB);
+
+    if (!m_role[role].changeabilityWidget) {
+        // Don't construct the FloatingTextWidget if the string is empty.
+        if (strChangeWidget.isEmpty())
+            return;
+
+        newLabel = true;
+        m_role[role].changeabilityWidget = new FloatingTextWidget(m_scene, tr, strChangeWidget);
+        m_role[role].changeabilityWidget->setParentItem(this);
+        m_role[role].changeabilityWidget->setLink(this);
+        m_scene->addFloatingTextWidget(m_role[role].changeabilityWidget);
+        m_role[role].changeabilityWidget->setPreText(QLatin1String("{")); // all types have this
+        m_role[role].changeabilityWidget->setPostText(QLatin1String("}")); // all types have this
+    } else {
+        if (m_role[role].changeabilityWidget->text().isEmpty()) {
+            newLabel = true;
+        }
+        m_role[role].changeabilityWidget->setText(strChangeWidget);
+    }
+    m_role[role].changeabilityWidget->setActivated();
+
+    if (newLabel) {
+        setTextPosition(tr);
+    }
+
+    if (FloatingTextWidget::isTextValid(m_role[role].changeabilityWidget->text()))
+        m_role[role].changeabilityWidget->show();
+    else
+        m_role[role].changeabilityWidget->hide();
+}
+
+/**
+ * Returns true if the line path starts at the given widget.
+ */
+bool AssociationWidget::linePathStartsAt(const UMLWidget* widget)
+{
+//:TODO:
+//    QPointF lpStart = m_associationLine->point(0);
+//    int startX = lpStart.x();
+//    int startY = lpStart.y();
+//    int wX = widget->x();
+//    int wY = widget->y();
+//    int wWidth = widget->width();
+//    int wHeight = widget->height();
+//    bool result = (startX >= wX && startX <= wX + wWidth &&
+//                   startY >= wY && startY <= wY + wHeight);
+//    return result;
+    bool result = widget->contains(m_associationLine->point(0));
+    DEBUG(DBG_SRC) << "widget=" << widget->name() << " / result=" << result;
+    return result;
+}
+
+/**
+ * This function calculates which role should be set for the m_nameWidget FloatingTextWidget.
+ */
+Uml::TextRole::Enum AssociationWidget::calculateNameType(Uml::TextRole::Enum defaultRole)
+{
+    TextRole::Enum result = defaultRole;
+    if (m_scene->type() == DiagramType::Collaboration) {
+        if (m_role[RoleType::A].umlWidget == m_role[RoleType::B].umlWidget) {
+            result = TextRole::Coll_Message;//for now same as other Coll_Message
+        } else {
+            result = TextRole::Coll_Message;
+        }
+    } else if (m_scene->type() == DiagramType::Sequence) {
+        if (m_role[RoleType::A].umlWidget == m_role[RoleType::B].umlWidget) {
+            result = TextRole::Seq_Message_Self;
+        } else {
+            result = TextRole::Seq_Message;
+        }
+    }
+
+    return result;
+}
+
+/**
+ * Gets the given role widget.
+ *
+ * @return  Pointer to the role's UMLWidget.
+ */
+UMLWidget* AssociationWidget::widgetForRole(Uml::RoleType::Enum role) const
+{
+    return m_role[role].umlWidget;
+}
+
+/**
+ * Sets the associated widgets.
+ *
+ * @param widgetA   Pointer the role A widget for the association.
+ * @param assocType The AssociationType::Enum for this association.
+ * @param widgetB   Pointer the role B widget for the association.
+ */
+bool AssociationWidget::setWidgets(UMLWidget* widgetA,
+                                   Uml::AssociationType::Enum assocType,
+                                   UMLWidget* widgetB)
+{
+    //if the association already has a WidgetB or WidgetA associated, then
+    //it cannot be changed to other widget, that would require a  deletion
+    //of the association and the creation of a new one
+    if ((m_role[RoleType::A].umlWidget && (m_role[RoleType::A].umlWidget != widgetA)) ||
+            (m_role[RoleType::B].umlWidget && (m_role[RoleType::B].umlWidget != widgetB))) {
+        return false;
+    }
+    setWidgetForRole(widgetA, RoleType::A);
+    setAssociationType(assocType);
+    setWidgetForRole(widgetB, RoleType::B);
+
+    calculateEndingPoints();
+    return true;
+}
+
+/**
+ * CleansUp all the association's data in the related widgets.
+ */
+void AssociationWidget::cleanup()
+{
+    //let any other associations know we are going so they can tidy their positions up
+    if (m_role[RoleType::A].m_nTotalCount > 2)
+        updateAssociations(m_role[RoleType::A].m_nTotalCount - 1, m_role[RoleType::A].m_WidgetRegion, RoleType::A);
+    if (m_role[RoleType::B].m_nTotalCount > 2)
+        updateAssociations(m_role[RoleType::B].m_nTotalCount - 1, m_role[RoleType::B].m_WidgetRegion, RoleType::B);
+
+    for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
+        WidgetRole& robj = m_role[r];
+
+        if (robj.umlWidget) {
+            robj.umlWidget->removeAssoc(this);
+            robj.umlWidget = 0;
+        }
+        if (robj.roleWidget) {
+            m_scene->removeWidget(robj.roleWidget);
+            robj.roleWidget = 0;
+        }
+        if (robj.multiplicityWidget) {
+            m_scene->removeWidget(robj.multiplicityWidget);
+            robj.multiplicityWidget = 0;
+        }
+        if (robj.changeabilityWidget) {
+            m_scene->removeWidget(robj.changeabilityWidget);
+            robj.changeabilityWidget = 0;
+        }
+    }
+
+    if (m_nameWidget) {
+        m_scene->removeWidget(m_nameWidget);
+        m_nameWidget = 0;
+    }
+
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
+        /*
+           We do not remove the UMLAssociation from the document.
+           Why? - Well, for example we might be in the middle of
+           a cut/paste. If the UMLAssociation is removed by the cut
+           then upon pasteing we have a problem.
+           This is not quite clean yet - there should be a way to
+           explicitly delete a UMLAssociation.  The Right Thing would
+           be to have a ListView representation for UMLAssociation.
+        `
+                IF we are cut n pasting, why are we handling this association as a pointer?
+                We should be using the XMI representation for a cut and paste. This
+                allows us to be clean here, AND a choice of recreating the object
+                w/ same id IF its a "cut", or a new object if its a "copy" operation
+                (in which case we wouldnt be here, in cleanup()).
+         */
+        setUMLAssociation(0);
+    }
+
+    m_associationLine->cleanup();
+    removeAssocClassLine();
+}
+
+/**
+ * @brief Return state if the assocation line point in the near of the last context
+ *        menu event position is addable or not.
+ * A point is addable if the association is not an Exception and there is no point in the near.
+ *
+ * @return true if point is addable
+ */
+bool AssociationWidget::isPointAddable()
+{
+    if (!isSelected() || associationType() == Uml::AssociationType::Exception)
+        return false;
+    int i = m_associationLine->closestPointIndex(m_eventScenePos);
+    return i == -1;
+}
+
+/**
+ * @brief Return state if the assocation line point in the near of the last context
+ *        menu event position is removable or not.
+ * A point is removable if the association is not an Exception and is not the start or end point.
+ *
+ * @return true if point is removable
+ */
+bool AssociationWidget::isPointRemovable()
+{
+    if (!isSelected() || associationType() == Uml::AssociationType::Exception || m_associationLine->count() <= 2)
+        return false;
+    int i = m_associationLine->closestPointIndex(m_eventScenePos);
+    return i > 0 && i < m_associationLine->count() - 1;
+}
+
+/**
+ * Set our internal umlAssociation.
+ */
+void AssociationWidget::setUMLAssociation (UMLAssociation * assoc)
+{
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
+        UMLAssociation *umla = association();
+
+        // safety check. Did some num-nuts try to set the existing
+        // association again? If so, just bail here
+        if (umla == assoc)
+            return;
+
+        //umla->disconnect(this);  //Qt does disconnect automatically upon destruction.
+        umla->nrof_parent_widgets--;
+
+        // ANSWER: This is the wrong treatment of cut and paste. Associations that
+        // are being cut/n pasted should be serialized to XMI, then reconstituted
+        // (IF a paste operation) rather than passing around object pointers. Its
+        // just too hard otherwise to prevent problems in the code. Bottom line: we need to
+        // delete orphaned associations or we well get code crashes and memory leaks.
+        if (umla->nrof_parent_widgets <= 0) {
+            //umla->deleteLater();
+        }
+
+        m_umlObject = NULL;
+    }
+
+    if (assoc) {
+        m_umlObject = assoc;
+
+        // move counter to "0" from "-1" (which means, no assocwidgets)
+        if (assoc->nrof_parent_widgets < 0)
+            assoc->nrof_parent_widgets = 0;
+
+        assoc->nrof_parent_widgets++;
+        connect(assoc, SIGNAL(modified()), this, SLOT(syncToModel()));
+    }
+
+}
+
+/**
+ * Returns true if the Widget is either at the starting or ending side of the association.
+ */
+bool AssociationWidget::containsAsEndpoint(UMLWidget* widget)
+{
+    return (widget == m_role[RoleType::A].umlWidget || widget == m_role[RoleType::B].umlWidget);
+}
+
+/**
+ * Returns true if this AssociationWidget represents a collaboration message.
+ */
+bool AssociationWidget::isCollaboration() const
+{
+    Uml::AssociationType::Enum at = associationType();
+    return (at == AssociationType::Coll_Message_Synchronous
+            || at == AssociationType::Coll_Message_Asynchronous
+            || at == AssociationType::Coll_Message_Self);
+}
+
+/**
+ * Returns true if this AssociationWidget represents a self message.
+ */
+bool AssociationWidget::isSelf() const
+{
+    return widgetForRole(Uml::RoleType::A) == widgetForRole(Uml::RoleType::B);
+}
+
+/**
+ * Gets the association's type.
+ *
+ * @return  This AssociationWidget's AssociationType::Enum.
+ */
+Uml::AssociationType::Enum AssociationWidget::associationType() const
+{
+    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
+        return m_associationType;
+    UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
+    return umla->getAssocType();
+}
+
+/**
+ * Sets the association's type.
+ *
+ * @param type   The AssociationType::Enum to set.
+ */
+void AssociationWidget::setAssociationType(Uml::AssociationType::Enum type)
+{
+    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
+        association()->setAssociationType(type);
+    }
+    m_associationType = type;
+    // If the association new type is not supposed to have Multiplicity
+    // FloatingTexts and a Role FloatingTextWidget then set the texts
+    // to empty.
+    // NB We do not physically delete the floatingtext widgets here because
+    // those widgets are also stored in the UMLView::m_WidgetList.
+    if (!AssocRules::allowMultiplicity(type, widgetForRole(RoleType::A)->baseType())) {
+        if (m_role[RoleType::A].multiplicityWidget) {
+            m_role[RoleType::A].multiplicityWidget->setName(QString());
+        }
+        if (m_role[RoleType::B].multiplicityWidget) {
+            m_role[RoleType::B].multiplicityWidget->setName(QString());
+        }
+    }
+    if (!AssocRules::allowRole(type)) {
+        if (m_role[RoleType::A].roleWidget) {
+            m_role[RoleType::A].roleWidget->setName(QString());
+        }
+        if (m_role[RoleType::B].roleWidget) {
+            m_role[RoleType::B].roleWidget->setName(QString());
+        }
+        setRoleDocumentation(QString(), RoleType::A);
+        setRoleDocumentation(QString(), RoleType::B);
+    }
+    m_associationLine->reconstructSymbols();
+}
+
+/**
+ * Gets the ID of the given role widget.
+ */
+Uml::ID::Type AssociationWidget::widgetIDForRole(Uml::RoleType::Enum role) const
+{
+    if (m_role[role].umlWidget == NULL) {
+        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
+            UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
+            return umla->getObjectId(role);
+        }
+        uError() << "umlWidget is NULL";
+        return Uml::ID::None;
+    }
+    if (m_role[role].umlWidget->baseType() == WidgetBase::wt_Object)
+        return static_cast<ObjectWidget*>(m_role[role].umlWidget)->localID();
+    Uml::ID::Type id = m_role[role].umlWidget->id();
+    return id;
+}
+
+/**
+ * Gets the local ID of the given role widget.
+ */
+Uml::ID::Type AssociationWidget::widgetLocalIDForRole(Uml::RoleType::Enum role) const
+{
+    if (m_role[role].umlWidget == NULL) {
+        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
+            UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
+            return umla->getObjectId(role);
+        }
+        uError() << "umlWidget is NULL";
+        return Uml::ID::None;
+    }
+    if (m_role[role].umlWidget->baseType() == WidgetBase::wt_Object)
+        return static_cast<ObjectWidget*>(m_role[role].umlWidget)->localID();
+    Uml::ID::Type id = m_role[role].umlWidget->localID();
+    return id;
+}
+
+/**
+ * Returns a QString Object representing this AssociationWidget.
+ */
+QString AssociationWidget::toString() const
+{
+    QString string;
+    static const QChar colon(QLatin1Char(':'));
+
+    if (widgetForRole(RoleType::A)) {
+        string = widgetForRole(RoleType::A)->name();
+    }
+    string.append(colon);
+
+    if (m_role[RoleType::A].roleWidget) {
+        string += m_role[RoleType::A].roleWidget->text();
+    }
+    string.append(colon);
+    string.append(Uml::AssociationType::toStringI18n(associationType()));
+    string.append(colon);
+
+    if (widgetForRole(RoleType::B)) {
+        string += widgetForRole(RoleType::B)->name();
+    }
+
+    string.append(colon);
+    if (m_role[RoleType::B].roleWidget) {
+        string += m_role[RoleType::B].roleWidget->text();
+    }
+
+    return string;
+}
+
+/**
+ * Adds a break point (if left mouse button).
+ */
+void AssociationWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        uDebug() << "widget = " << name() << " / type = " << baseTypeStr();
+        showPropertiesDialog();
+        event->accept();
+    }
+}
+
+/**
+ * Overrides moveEvent.
+ */
+void AssociationWidget::moveEvent(QGraphicsSceneMouseEvent *me)
+{
+    // 2004-04-30: Achim Spangler
+    // Simple Approach to block moveEvent during load of XMI
+    /// @todo avoid trigger of this event during load
+
+    if (umlDoc()->loading()) {
+        // hmmh - change of position during load of XMI
+        // -> there is something wrong
+        // -> avoid movement during opening
+        // -> print warn and stay at old position
+        uWarning() << "called during load of XMI for ViewType: "
+            << m_scene->type() << ", and BaseType: " << baseType();
+        return;
+    }
+    /*to be here a line segment has moved.
+      we need to see if the three text widgets needs to be moved.
+      there are a few things to check first though:
+
+      1) Do they exist
+      2) does it need to move:
+      2a) for the multi widgets only move if they changed region, otherwise they are close enough
+      2b) for role name move if the segment it is on moves.
+    */
+    //first see if either the first or last segments moved, else no need to recalculate their point positions
+
+    QPointF oldNamePoint = calculateTextPosition(TextRole::Name);
+    QPointF oldMultiAPoint = calculateTextPosition(TextRole::MultiA);
+    QPointF oldMultiBPoint = calculateTextPosition(TextRole::MultiB);
+    QPointF oldChangeAPoint = calculateTextPosition(TextRole::ChangeA);
+    QPointF oldChangeBPoint = calculateTextPosition(TextRole::ChangeB);
+    QPointF oldRoleAPoint = calculateTextPosition(TextRole::RoleAName);
+    QPointF oldRoleBPoint = calculateTextPosition(TextRole::RoleBName);
+
+    int movingPoint = m_associationLine->closestPointIndex(me->scenePos());
+    if (movingPoint != -1)
+        m_associationLine->setPoint(movingPoint, me->scenePos());
+    int pos = m_associationLine->count() - 1;//set to last point for widget b
+
+    if ( movingPoint == 1 || (movingPoint == pos-1) ) {
+        calculateEndingPoints();
+    }
+    if (m_role[RoleType::A].changeabilityWidget && (movingPoint == 1)) {
+        setTextPositionRelatively(TextRole::ChangeA, oldChangeAPoint);
+    }
+    if (m_role[RoleType::B].changeabilityWidget && (movingPoint == 1)) {
+        setTextPositionRelatively(TextRole::ChangeB, oldChangeBPoint);
+    }
+    if (m_role[RoleType::A].multiplicityWidget && (movingPoint == 1)) {
+        setTextPositionRelatively(TextRole::MultiA, oldMultiAPoint);
+    }
+    if (m_role[RoleType::B].multiplicityWidget && (movingPoint == pos-1)) {
+        setTextPositionRelatively(TextRole::MultiB, oldMultiBPoint);
+    }
+
+    if (m_nameWidget) {
+        if (movingPoint == m_unNameLineSegment ||
+                movingPoint - 1 == m_unNameLineSegment) {
+            setTextPositionRelatively(TextRole::Name, oldNamePoint);
+        }
+    }
+
+    if (m_role[RoleType::A].roleWidget) {
+        setTextPositionRelatively(TextRole::RoleAName, oldRoleAPoint);
+    }
+    if (m_role[RoleType::B].roleWidget) {
+        setTextPositionRelatively(TextRole::RoleBName, oldRoleBPoint);
+    }
+
+    if (m_pAssocClassLine) {
+        computeAssocClassLine();
+    }
+}
+
+/**
+ * Calculates and sets the first and last point in the Association's AssociationLine.
+ * Each point is a middle point of its respecting UMLWidget's Bounding rectangle
+ * or a corner of it.
+ * This method picks which sides to use for the association.
+ */
+void AssociationWidget::calculateEndingPoints()
+{
+    /*
+     * For each UMLWidget the diagram is divided in four regions by its diagonals
+     * as indicated below
+     *                              Region 2
+     *                         \                /
+     *                           \            /
+     *                             +--------+
+     *                             | \    / |
+     *                Region 1     |   ><   |    Region 3
+     *                             | /    \ |
+     *                             +--------+
+     *                           /            \
+     *                         /                \
+     *                              Region 4
+     *
+     * Each diagonal is defined by two corners of the bounding rectangle
+     *
+     * To calculate the first point in the AssociationLine we have to find out in which
+     * Region (defined by WidgetA's diagonals) is WidgetB's center
+     * (let's call it Region M.) After that the first point will be the middle
+     * point of the rectangle's side contained in Region M.
+     *
+     * To calculate the last point in the AssociationLine we repeat the above but
+     * in the opposite direction (from widgetB to WidgetA)
+     */
+
+    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
+    UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
+    if (!pWidgetA || !pWidgetB) {
+        uWarning() << "Returning - one of the role widgets is not set.";
+        return;
+    }
+
+    int size = m_associationLine->count();
+    if (size < 2) {
+        QPointF pA = pWidgetA->pos();
+        QPointF pB = pWidgetB->pos();
+        QPolygonF polyA = pWidgetA->shape().toFillPolygon().translated(pA);
+        QPolygonF polyB = pWidgetB->shape().toFillPolygon().translated(pB);
+        QLineF nearestPoints = Widget_Utils::closestPoints(polyA, polyB);
+        if (nearestPoints.isNull()) {
+            uError() << "Widget_Utils::closestPoints failed, falling back to simple widget positions";
+        } else {
+            pA = nearestPoints.p1();
+            pB = nearestPoints.p2();
+        }
+        m_associationLine->setEndPoints(pA, pB);
+    }
+
+    // See if an association to self.
+    // See if it needs to be set up before we continue:
+    // If self association/message and doesn't have the minimum 4 points
+    // then create it. Make sure no points are out of bounds of viewing area.
+    // This only happens on first time through that we are worried about.
+    if (isSelf() && size < 4) {
+        createPointsSelfAssociation();
+        return;
+    }
+
+    if (associationType() == AssociationType::Exception && size < 4) {
+        createPointsException();
+        updatePointsException();
+        return;
+    }
+
+    // If the line has more than one segment change the values to calculate
+    // from widget to point 1.
+    qreal xB = pWidgetB->x() + pWidgetB->width() / 2;
+    qreal yB = pWidgetB->y() + pWidgetB->height() / 2;
+    if (size > 2) {
+        QPointF p = m_associationLine->point(1);
+        xB = p.x();
+        yB = p.y();
+    }
+    doUpdates(QPointF(xB, yB), RoleType::A);
+
+    // Now do the same for widgetB.
+    // If the line has more than one segment change the values to calculate
+    // from widgetB to the last point away from it.
+    qreal xA = pWidgetA->x() + pWidgetA->width() / 2;
+    qreal yA = pWidgetA->y() + pWidgetA->height() / 2;
+    if (size > 2 ) {
+        QPointF p = m_associationLine->point(size - 2);
+        xA = p.x();
+        yA = p.y();
+    }
+    doUpdates(QPointF(xA, yA), RoleType::B);
+
+    computeAssocClassLine();
+}
+
+/**
+ * Used by @ref calculateEndingPoints.
+ */
+void AssociationWidget::doUpdates(const QPointF &otherP, RoleType::Enum role)
+{
+    // Find widget region.
+    Uml::Region::Enum oldRegion = m_role[role].m_WidgetRegion;
+    UMLWidget *pWidget = m_role[role].umlWidget;
+    QRectF rc(pWidget->x(), pWidget->y(),
+              pWidget->width(), pWidget->height());
+    Uml::Region::Enum region = m_role[role].m_WidgetRegion;  // alias for brevity
+    region = findPointRegion(rc, otherP);
+    // Move some regions to the standard ones.
+    switch( region ) {
+    case Uml::Region::NorthWest:
+        region = Uml::Region::North;
+        break;
+    case Uml::Region::NorthEast:
+        region = Uml::Region::East;
+        break;
+    case Uml::Region::SouthEast:
+        region = Uml::Region::South;
+        break;
+    case Uml::Region::SouthWest:
+    case Uml::Region::Center:
+        region = Uml::Region::West;
+        break;
+    default:
+        break;
+    }
+    int regionCount = getRegionCount(region, role) + 2; //+2 = (1 for this one and one to halve it)
+    int totalCount = m_role[role].m_nTotalCount;
+    if (oldRegion != region) {
+        updateRegionLineCount(regionCount - 1, regionCount, region, role);
+        updateAssociations(totalCount - 1, oldRegion, role);
+    } else if (totalCount != regionCount) {
+        updateRegionLineCount(regionCount - 1, regionCount, region, role);
+    } else {
+        updateRegionLineCount(m_role[role].m_nIndex, totalCount, region, role);
+    }
+    updateAssociations(regionCount, region, role);
+}
+
+/**
+ * Read property of bool m_activated.
+ */
+bool AssociationWidget::isActivated() const
+{
+    return m_activated;
+}
+
+/**
+ * Set the m_activated flag of a widget but does not perform the Activate method.
+ */
+void AssociationWidget::setActivated(bool active)
+{
+    m_activated = active;
+}
+
+/**
+ * Synchronize this widget from the UMLAssociation.
+ */
+void AssociationWidget::syncToModel()
+{
+    UMLAssociation *uml = association();
+
+    if (uml == NULL) {
+        UMLAttribute *attr = attribute();
+        if (attr == NULL)
+            return;
+        setVisibility(attr->visibility(), RoleType::B);
+        setRoleName(attr->name(), RoleType::B);
+        return;
+    }
+    // block signals until finished
+    uml->blockSignals(true);
+
+    setName(uml->name());
+    setRoleName(uml->getRoleName(RoleType::A), RoleType::A);
+    setRoleName(uml->getRoleName(RoleType::B), RoleType::B);
+    setVisibility(uml->visibility(RoleType::A), RoleType::A);
+    setVisibility(uml->visibility(RoleType::B), RoleType::B);
+    setChangeability(uml->changeability(RoleType::A), RoleType::A);
+    setChangeability(uml->changeability(RoleType::B), RoleType::B);
+    setMultiplicity(uml->getMultiplicity(RoleType::A), RoleType::A);
+    setMultiplicity(uml->getMultiplicity(RoleType::B), RoleType::B);
+
+    uml->blockSignals(false);
+}
+
+/**
+ * Merges/syncs the association widget data into UML object
+ * representation.
+ * This will synchronize UMLAssociation w/ this new Widget
+ * CHECK: Can we get rid of this.
+ */
+void AssociationWidget::mergeAssociationDataIntoUMLRepresentation()
+{
+    UMLAssociation *umlassoc = association();
+    UMLAttribute *umlattr = attribute();
+    if (umlassoc == NULL && umlattr == NULL)
+        return;
+
+    // block emit modified signal, or we get a horrible loop
+    m_umlObject->blockSignals(true);
+
+    // would be desirable to do the following
+    // so that we can be sure its back to initial state
+    // in case we missed something here.
+    //uml->init();
+
+    // floating text widgets
+    FloatingTextWidget *text = nameWidget();
+    if (text)
+        m_umlObject->setName(text->text());
+
+    text = roleWidget(RoleType::A);
+    if (text && umlassoc)
+        umlassoc->setRoleName(text->text(), RoleType::A);
+
+    text = roleWidget(RoleType::B);
+    if (text) {
+        if (umlassoc)
+            umlassoc->setRoleName(text->text(), RoleType::B);
+        else if (umlattr)
+            umlattr->setName(text->text());
+    }
+
+    text = multiplicityWidget(RoleType::A);
+    if (text && umlassoc)
+        umlassoc->setMultiplicity(text->text(), RoleType::A);
+
+    text = multiplicityWidget(RoleType::B);
+    if (text && umlassoc)
+        umlassoc->setMultiplicity(text->text(), RoleType::B);
+
+    // unblock
+    m_umlObject->blockSignals(false);
+}
+
+/**
+ * Auxiliary method for widgetMoved():
+ * Saves all ideally computed floatingtext positions before doing any
+ * kind of change.  This is necessary because a single invocation of
+ * calculateEndingPoints() modifies the AssociationLine ending points on ALL
+ * AssociationWidgets.  This means that if we don't save the old ideal
+ * positions then they are irretrievably lost as soon as
+ * calculateEndingPoints() is invoked.
+ */
+void AssociationWidget::saveIdealTextPositions()
+{
+    m_oldNamePoint    = calculateTextPosition(TextRole::Name);
+    m_oldMultiAPoint  = calculateTextPosition(TextRole::MultiA);
+    m_oldMultiBPoint  = calculateTextPosition(TextRole::MultiB);
+    m_oldChangeAPoint = calculateTextPosition(TextRole::ChangeA);
+    m_oldChangeBPoint = calculateTextPosition(TextRole::ChangeB);
+    m_oldRoleAPoint   = calculateTextPosition(TextRole::RoleAName);
+    m_oldRoleBPoint   = calculateTextPosition(TextRole::RoleBName);
+}
+
+/**
+ * Adjusts the ending point of the association that connects to Widget.
+ */
+void AssociationWidget::widgetMoved(UMLWidget* widget, qreal dx, qreal dy)
+{
+    Q_UNUSED(dx); Q_UNUSED(dy);
+
+    // Simple Approach to block moveEvent during load of XMI
+    /// @todo avoid trigger of this event during load
+    if (umlDoc()->loading()) {
+        // change of position during load of XMI
+        // -> there is something wrong
+        // -> avoid movement during opening
+        // -> print warn and stay at old position
+        DEBUG(DBG_SRC) << "called during load of XMI for ViewType: " << m_scene->type()
+                       << ", and BaseType: " << baseTypeStr();
+        return;
+    }
+
+    DEBUG(DBG_SRC) << "association type=" << Uml::AssociationType::toString(associationType());
+    if (associationType() == AssociationType::Exception) {
+        updatePointsException();
+        setTextPosition(TextRole::Name);
+    }
+    else {
+        calculateEndingPoints();
+        computeAssocClassLine();
+    }
+
+    // Assoc to self - move all points:
+    if (isSelf()) {
+        updatePointsSelfAssociation();
+
+        if (m_nameWidget && !m_nameWidget->isSelected()) {
+            setTextPositionRelatively(TextRole::Name, m_oldNamePoint);
+        }
+
+    }//end if widgetA = widgetB
+    else if (m_role[RoleType::A].umlWidget == widget) {
+        if (m_nameWidget && m_unNameLineSegment == 0 && !m_nameWidget->isSelected() ) {
+            //only calculate position and move text if the segment it is on is moving
+            setTextPositionRelatively(TextRole::Name, m_oldNamePoint);
+        }
+    }//end if widgetA moved
+    else if (m_role[RoleType::B].umlWidget == widget) {
+        const int size = m_associationLine->count();
+        if (m_nameWidget && (m_unNameLineSegment == size-2) && !m_nameWidget->isSelected() ) {
+            //only calculate position and move text if the segment it is on is moving
+            setTextPositionRelatively(TextRole::Name, m_oldNamePoint);
+        }
+    }//end if widgetB moved
+
+    if (m_role[RoleType::A].roleWidget && !m_role[RoleType::A].roleWidget->isSelected()) {
+        setTextPositionRelatively(TextRole::RoleAName, m_oldRoleAPoint);
+    }
+    if (m_role[RoleType::B].roleWidget && !m_role[RoleType::B].roleWidget->isSelected()) {
+        setTextPositionRelatively(TextRole::RoleBName, m_oldRoleBPoint);
+    }
+    if (m_role[RoleType::A].multiplicityWidget && !m_role[RoleType::A].multiplicityWidget->isSelected()) {
+        setTextPositionRelatively(TextRole::MultiA, m_oldMultiAPoint);
+    }
+    if (m_role[RoleType::B].multiplicityWidget && !m_role[RoleType::B].multiplicityWidget->isSelected()) {
+        setTextPositionRelatively(TextRole::MultiB, m_oldMultiBPoint);
+    }
+    if (m_role[RoleType::A].changeabilityWidget && !m_role[RoleType::A].changeabilityWidget->isSelected()) {
+        setTextPositionRelatively(TextRole::ChangeA, m_oldChangeAPoint);
+    }
+    if (m_role[RoleType::B].changeabilityWidget && !m_role[RoleType::B].changeabilityWidget->isSelected()) {
+        setTextPositionRelatively(TextRole::ChangeB, m_oldChangeBPoint);
+    }
+}
+
+/**
+ * Creates the points of the self association.
+ * Method called when a widget end points are calculated by calculateEndingPoints().
+ */
+void AssociationWidget::createPointsSelfAssociation()
+{
+    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
+
+    const int DISTANCE = 50;
+    qreal x = pWidgetA->x();
+    qreal y = pWidgetA->y();
+    qreal h = pWidgetA->height();
+    qreal w = pWidgetA->width();
+    // see if above widget ok to start
+    if (y - DISTANCE > 0) {
+        m_associationLine->setEndPoints(QPointF(x + w / 4, y) , QPointF(x + w * 3 / 4, y));
+        m_associationLine->insertPoint(1, QPointF(x + w / 4, y - DISTANCE));
+        m_associationLine->insertPoint(2, QPointF(x + w * 3 / 4, y - DISTANCE));
+        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::North;
+    } else {
+        m_associationLine->setEndPoints(QPointF(x + w / 4, y + h), QPointF(x + w * 3 / 4, y + h));
+        m_associationLine->insertPoint(1, QPointF(x + w / 4, y + h + DISTANCE));
+        m_associationLine->insertPoint(2, QPointF(x + w * 3 / 4, y + h + DISTANCE));
+        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::South;
+    }
+}
+
+/**
+ * Adjusts the points of the self association.
+ * Method called when a widget was moved by widgetMoved(widget, x, y).
+ */
+void AssociationWidget::updatePointsSelfAssociation()
+{
+    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
+
+    const int DISTANCE = 50;
+    qreal x = pWidgetA->x();
+    qreal y = pWidgetA->y();
+    qreal h = pWidgetA->height();
+    qreal w = pWidgetA->width();
+    // see if above widget ok to start
+    if (y - DISTANCE > 0) {
+        m_associationLine->setEndPoints(QPointF(x + w / 4, y) , QPointF(x + w * 3 / 4, y));
+        m_associationLine->setPoint(1, QPointF(x + w / 4, y - DISTANCE));
+        m_associationLine->setPoint(2, QPointF(x + w * 3 / 4, y - DISTANCE));
+        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::North;
+    } else {
+        m_associationLine->setEndPoints(QPointF(x + w / 4, y + h), QPointF(x + w * 3 / 4, y + h));
+        m_associationLine->setPoint(1, QPointF(x + w / 4, y + h + DISTANCE));
+        m_associationLine->setPoint(2, QPointF(x + w * 3 / 4, y + h + DISTANCE));
+        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::South;
+    }
+}
+
+/**
+ * Creates the points of the association exception.
+ * Method called when a widget end points are calculated by calculateEndingPoints().
+ */
+void AssociationWidget::createPointsException()
+{
+    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
+    UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
+
+    qreal xa = pWidgetA->x();
+    qreal ya = pWidgetA->y();
+    qreal ha = pWidgetA->height();
+    qreal wa = pWidgetA->width();
+
+    qreal xb = pWidgetB->x();
+    qreal yb = pWidgetB->y();
+    qreal hb = pWidgetB->height();
+    //qreal wb = pWidgetB->width();
+
+    m_associationLine->setEndPoints(QPointF(xa + wa , ya + ha/2) , QPointF(xb , yb + hb/2));
+    m_associationLine->insertPoint(1, QPointF(xa + wa , ya + ha/2));
+    m_associationLine->insertPoint(2, QPointF(xb , yb + hb/2));
+}
+
+/**
+ * Adjusts the points of the association exception.
+ * Method called when a widget was moved by widgetMoved(widget, x, y).
+ */
+void AssociationWidget::updatePointsException()
+{
+    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
+    UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
+
+    qreal xa = pWidgetA->x();
+    qreal ya = pWidgetA->y();
+    qreal ha = pWidgetA->height();
+    qreal wa = pWidgetA->width();
+
+    qreal xb = pWidgetB->x();
+    qreal yb = pWidgetB->y();
+    qreal hb = pWidgetB->height();
+    qreal wb = pWidgetB->width();
+    qreal xmil, ymil;
+    qreal xdeb, ydeb;
+    qreal xfin, yfin;
+    qreal ESPACEX, ESPACEY;
+    QPointF p1;
+    QPointF p2;
+    //calcul des coordonnées au milieu de la flèche eclair
+    if (xb - xa - wa >= 45) {
+        ESPACEX = 0;
+        xdeb = xa + wa;
+        xfin = xb;
+    } else if (xa - xb - wb > 45) {
+        ESPACEX = 0;
+        xdeb = xa;
+        xfin = xb + wb;
+    } else {
+        ESPACEX = 15;
+        xdeb = xa + wa/2;
+        xfin = xb + wb/2;
+    }
+
+    xmil = xdeb + (xfin - xdeb)/2;
+
+    if (yb - ya - ha >= 45)  {
+        ESPACEY = 0;
+        ydeb = ya + ha;
+        yfin = yb;
+    } else if (ya - yb - hb > 45) {
+        ESPACEY = 0;
+        ydeb = ya;
+        yfin = yb + hb;
+    } else {
+        ESPACEY = 15;
+        ydeb = ya + ha/2;
+        yfin = yb + hb/2;
+    }
+
+    ymil = ydeb + (yfin - ydeb)/2;
+
+    p1.setX(xmil + (xfin - xmil)*1/2); p1.setY(ymil + (yfin - ymil)*1/3);
+    p2.setX(xmil - (xmil - xdeb)*1/2); p2.setY(ymil - (ymil - ydeb)*1/3);
+
+    if (abs(p1.x() - p2.x()) <= 10)
+        ESPACEX = 15;
+    if (abs(p1.y() - p2.y()) <= 10)
+        ESPACEY = 15;
+
+    m_associationLine->setEndPoints(QPointF(xdeb, ydeb), QPointF(xfin, yfin));
+    m_associationLine->setPoint(1, QPointF(p1.x() + ESPACEX, p1.y() + ESPACEY));
+    m_associationLine->setPoint(2, QPointF(p2.x() - ESPACEX, p2.y() - ESPACEY));
+
+    m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::North;
+}
+
+/**
+ * Finds out which region of rectangle 'rect' contains the point 'pos' and returns the region
+ * number:
+ * 1 = Region 1
+ * 2 = Region 2
+ * 3 = Region 3
+ * 4 = Region 4
+ * 5 = On diagonal 2 between Region 1 and 2
+ * 6 = On diagonal 1 between Region 2 and 3
+ * 7 = On diagonal 2 between Region 3 and 4
+ * 8 = On diagonal 1 between Region 4 and 1
+ * 9 = On diagonal 1 and On diagonal 2 (the center)
+ */
+Uml::Region::Enum AssociationWidget::findPointRegion(const QRectF& rect, const QPointF &pos)
+{
+    qreal w = rect.width();
+    qreal h = rect.height();
+    qreal x = rect.x();
+    qreal y = rect.y();
+    qreal slope2 = w / h;
+    qreal slope1 = slope2 *(-1.0);
+    qreal b1 = x + w - (slope1 * y);
+    qreal b2 = x - (slope2 * y);
+
+    qreal eval1 = slope1 * pos.y() + b1;
+    qreal eval2 = slope2 * pos.y() + b2;
+
+    Uml::Region::Enum result = Uml::Region::Error;
+    //if inside region 1
+    if (eval1 > pos.x() && eval2 > pos.x()) {
+        result = Uml::Region::West;
+    }
+    //if inside region 2
+    else if (eval1 > pos.x() && eval2 < pos.x()) {
+        result = Uml::Region::North;
+    }
+    //if inside region 3
+    else if (eval1 < pos.x() && eval2 < pos.x()) {
+        result = Uml::Region::East;
+    }
+    //if inside region 4
+    else if (eval1 < pos.x() && eval2 > pos.x()) {
+        result = Uml::Region::South;
+    }
+    //if inside region 5
+    else if (eval1 == pos.x() && eval2 < pos.x()) {
+        result = Uml::Region::NorthWest;
+    }
+    //if inside region 6
+    else if (eval1 < pos.x() && eval2 == pos.x()) {
+        result = Uml::Region::NorthEast;
+    }
+    //if inside region 7
+    else if (eval1 == pos.x() && eval2 > pos.x()) {
+        result = Uml::Region::SouthEast;
+    }
+    //if inside region 8
+    else if (eval1 > pos.x() && eval2 == pos.x()) {
+        result = Uml::Region::SouthWest;
+    }
+    //if inside region 9
+    else if (eval1 == pos.x() && eval2 == pos.x()) {
+        result = Uml::Region::Center;
+    }
+    return result;
+}
+
+/**
+ * Returns a point with interchanged X and Y coordinates.
+ */
+QPointF AssociationWidget::swapXY(const QPointF &p)
+{
+    QPointF swapped( p.y(), p.x() );
+    return swapped;
+}
+
+#if 0  // not used at the moment
+/**
+ * Calculates which point of segment P1P2 has a distance equal to
+ * Distance from P1.
+ * Let's say such point is PX, the distance from P1 to PX must be equal
+ * to Distance and if PX is not a point of the segment P1P2 then the
+ * function returns (-1, -1).
+ */
+QPointF AssociationWidget::calculatePointAtDistance(const QPointF &P1, const QPointF &P2, float Distance)
+{
+    /*
+      the distance D between points (x1, y1) and (x3, y3) has the following formula:
+          ---     ------------------------------
+      D =    \   /         2         2
+              \ /   (x3 - x1)  +  (y3 - y1)
+
+      D, x1 and y1 are known and the point (x3, y3) is inside line (x1, y1)(x2, y2), so if the
+      that line has the formula y = mx + b
+      then y3 = m*x3 + b
+
+       2             2             2
+      D   = (x3 - x1)  +  (y3 - y1)
+
+       2       2                 2      2                 2
+      D    = x3    - 2*x3*x1 + x1   + y3   - 2*y3*y1  + y1
+
+       2       2       2       2                  2
+      D    - x1    - y1    = x3    - 2*x3*x1  + y3   - 2*y3*y1
+
+       2       2       2       2                          2
+      D    - x1    - y1    = x3    - 2*x3*x1  + (m*x3 + b)  - 2*(m*x3 + b)*y1
+
+       2       2       2              2       2 2
+      D    - x1    - y1   + 2*b*y1 - b   =  (m  + 1)*x3   + (-2*x1 + 2*m*b -2*m*y1)*x3
+
+       2      2       2       2
+      C  = - D    + x1    + y1   - 2*b*y1 + b
+
+
+       2
+      A  = (m    + 1)
+
+      B  = (-2*x1 + 2*m*b -2*m*y1)
+
+      and we have
+       2
+      A * x3 + B * x3 - C = 0
+
+                         ---------------
+             -B +  ---  /  2
+                      \/  B   - 4*A*C
+      sol_1  = --------------------------------
+                       2*A
+
+
+                         ---------------
+             -B -  ---  /  2
+                      \/  B   - 4*A*C
+      sol_2  = --------------------------------
+                       2*A
+
+
+      then in the distance formula we have only one variable x3 and that is easy
+      to calculate
+    */
+    int x1 = P1.y();
+    int y1 = P1.x();
+    int x2 = P2.y();
+    int y2 = P2.x();
+
+    if (x2 == x1) {
+        return QPointF(x1, y1 + (int)Distance);
+    }
+    float slope = ((float)y2 - (float)y1) / ((float)x2 - (float)x1);
+    float b = (y1 - slope*x1);
+    float A = (slope * slope) + 1;
+    float B = (2*slope*b) - (2*x1)  - (2*slope*y1);
+    float C = (b*b) - (Distance*Distance) + (x1*x1) + (y1*y1) - (2*b*y1);
+    float t = B*B - 4*A*C;
+
+    if (t < 0) {
+        return QPointF(-1, -1);
+    }
+    float sol_1 = ((-1* B) + sqrt(t)) / (2*A);
+    float sol_2 = ((-1*B) - sqrt(t)) / (2*A);
+
+    if (sol_1 < 0.0 && sol_2 < 0.0) {
+        return QPointF(-1, -1);
+    }
+    QPointF sol1Point((int)(slope*sol_1 + b), (int)(sol_1));
+    QPointF sol2Point((int)(slope*sol_2 + b), (int)(sol_2));
+    if (sol_1 < 0 && sol_2 >=0) {
+        if (x2 > x1) {
+            if (x1 <= sol_2 && sol_2 <= x2)
+                return sol2Point;
+        } else {
+            if (x2 <= sol_2 && sol_2 <= x1)
+                return sol2Point;
+        }
+    } else if (sol_1 >= 0 && sol_2 < 0) {
+        if (x2 > x1) {
+            if (x1 <= sol_1 && sol_1 <= x2)
+                return sol1Point;
+        } else {
+            if (x2 <= sol_1 && sol_1 <= x1)
+                return sol1Point;
+        }
+    } else {
+        if (x2 > x1) {
+            if (x1 <= sol_1 && sol_1 <= x2)
+                return sol1Point;
+            if (x1 <= sol_2 && sol_2 <= x2)
+                return sol2Point;
+        } else {
+            if (x2 <= sol_1 && sol_1 <= x1)
+                return sol1Point;
+            if (x2 <= sol_2 && sol_2 <= x1)
+                return sol2Point;
+        }
+    }
+    return QPointF(-1, -1);
+}
+
+/**
+ * Calculates which point of a perpendicular line to segment P1P2 that contains P2
+ *  has a distance equal to Distance from P2,
+ * Lets say such point is P3,  the distance from P2 to P3 must be equal to Distance
+ */
+QPointF AssociationWidget::calculatePointAtDistanceOnPerpendicular(const QPointF &P1, const QPointF &P2, float Distance)
+{
+    /*
+      the distance D between points (x2, y2) and (x3, y3) has the following formula:
+
+          ---     ------------------------------
+      D =    \   /         2             2
+              \ / (x3 - x2)  +  (y3 - y2)
+
+      D, x2 and y2 are known and line P2P3 is perpendicular to line (x1, y1)(x2, y2), so if the
+      line P1P2 has the formula y = m*x + b,
+      then      (x1 - x2)
+          m =  -----------, because it is perpendicular to line P1P2
+                (y2 - y1)
+
+      also y2 = m*x2 + b
+      => b = y2 - m*x2
+
+      then P3 = (x3, m*x3 + b)
+
+       2            2            2
+      D  = (x3 - x2)  + (y3 - y2)
+
+       2     2               2     2               2
+      D  = x3  - 2*x3*x2 + x2  + y3  - 2*y3*y2 + y2
+
+       2     2     2     2               2
+      D  - x2  - y2  = x3  - 2*x3*x2 + y3  - 2*y3*y2
+
+
+
+       2     2     2     2                       2
+      D  - x2  - y2  = x3  - 2*x3*x2 + (m*x3 + b)  - 2*(m*x3 + b)*y2
+
+       2     2     2                   2        2       2
+      D  - x2  - y2  + 2*b*y2 - b  = (m  + 1)*x3  + (-2*x2 + 2*m*b -2*m*y2)*x3
+
+              2       2       2              2
+      C  = - D    + x2    + y2   - 2*b*y2 + b
+
+             2
+      A  = (m  + 1)
+
+      B  = (-2*x2 + 2*m*b -2*m*y2)
+
+      and we have
+       2
+      A * x3 + B * x3 - C = 0
+
+
+                           ---------------
+                     ---  /  2
+                -B +    \/  B   - 4*A*C
+      sol_1 = --------------------------------
+                        2*A
+
+
+                           ---------------
+                     ---  /  2
+                -B -    \/  B   - 4*A*C
+      sol_2 = --------------------------------
+                        2*A
+
+      then in the distance formula we have only one variable x3 and that is easy
+      to calculate
+    */
+    if (P1.x() == P2.x()) {
+        return QPointF((int)(P2.x() + Distance), P2.y());
+    }
+    const int x1 = P1.y();
+    const int y1 = P1.x();
+    const int x2 = P2.y();
+    const int y2 = P2.x();
+
+    float slope = ((float)x1 - (float)x2) / ((float)y2 - (float)y1);
+    float b = (y2 - slope*x2);
+    float A = (slope * slope) + 1;
+    float B = (2*slope*b) - (2*x2) - (2*slope*y2);
+    float C = (b*b) - (Distance*Distance) + (x2*x2) + (y2*y2) - (2*b*y2);
+    float t = B*B - 4*A*C;
+    if (t < 0) {
+        return QPointF(-1, -1);
+    }
+    float sol_1 = ((-1* B) + sqrt(t)) / (2*A);
+
+    float sol_2 = ((-1*B) - sqrt(t)) / (2*A);
+
+    if (sol_1 < 0 && sol_2 < 0) {
+        return QPointF(-1, -1);
+    }
+    QPointF sol1Point((int)(slope*sol_1 + b), (int)sol_1);
+    QPointF sol2Point((int)(slope*sol_2 + b), (int)sol_2);
+    if (sol_1 < 0 && sol_2 >=0) {
+        return sol2Point;
+    } else if (sol_1 >= 0 && sol_2 < 0) {
+        return sol1Point;
+    } else {    // Choose one solution, either will work fine
+        if (slope >= 0) {
+            if (sol_1 <= sol_2)
+                return sol2Point;
+            else
+                return sol1Point;
+        } else {
+            if (sol_1 <= sol_2)
+                return sol1Point;
+            else
+                return sol2Point;
+        }
+
+    }
+    return QPointF(-1, -1);  // never reached, just keep compilers happy
+}
+
+/**
+ * Calculates the intersection (PS) between line P1P2 and a perpendicular line containing
+ * P3, the result is returned in ResultingPoint. and result value represents the distance
+ * between ResultingPoint and P3; if this value is negative an error ocurred.
+ */
+float AssociationWidget::perpendicularProjection(const QPointF& P1, const QPointF& P2, const QPointF& P3,
+        QPointF& ResultingPoint)
+{
+    //line P1P2 is Line 1 = y=slope1*x + b1
+
+    //line P3PS is Line 1 = y=slope2*x + b2
+
+    float slope2 = 0;
+    float slope1 = 0;
+    float sx = 0, sy = 0;
+    int y2 = P2.x();
+    int y1 = P1.x();
+    int x2 = P2.y();
+    int x1 = P1.y();
+    int y3 = P3.x();
+    int x3 = P3.y();
+    float distance = 0;
+    float b1 = 0;
+
+    float b2 = 0;
+
+    if (x2 == x1) {
+        sx = x2;
+        sy = y3;
+    } else if (y2 == y1) {
+        sy = y2;
+        sx = x3;
+    } else {
+        slope1 = (y2 - y1)/ (x2 - x1);
+        slope2 = (x1 - x2)/ (y2 - y1);
+        b1 = y2 - (slope1 * x2);
+        b2 = y3 - (slope2 * x3);
+        sx = (b2 - b1) / (slope1 - slope2);
+        sy = slope1*sx + b1;
+    }
+    distance = (int)(sqrt(((x3 - sx)*(x3 - sx)) + ((y3 - sy)*(y3 - sy))));
+
+    ResultingPoint.setX((int)sy);
+    ResultingPoint.setY((int)sx);
+
+    return distance;
+}
+#endif
+
+/**
+ * Calculates the position of the text widget depending on the role
+ * that widget is playing.
+ * Returns the point at which to put the widget.
+ */
+QPointF AssociationWidget::calculateTextPosition(Uml::TextRole::Enum role)
+{
+    const int SPACE = 2;
+    QPointF p(-1, -1), q(-1, -1);
+
+    // used to find out if association end point (p)
+    // is at top or bottom edge of widget.
+
+    if (role == TextRole::MultiA || role == TextRole::ChangeA || role == TextRole::RoleAName) {
+        p = m_associationLine->point(0);
+        q = m_associationLine->point(1);
+    } else if (role == TextRole::MultiB || role == TextRole::ChangeB || role == TextRole::RoleBName) {
+        const int lastSegment = m_associationLine->count() - 1;
+        p = m_associationLine->point(lastSegment);
+        q = m_associationLine->point(lastSegment - 1);
+    } else if (role != TextRole::Name) {
+        uError() << "called with unsupported TextRole::Enum " << role;
+        return QPointF(-1, -1);
+    }
+
+    FloatingTextWidget *text = textWidgetByRole(role);
+    int textW = 0, textH = 0;
+    if (text) {
+        textW = text->width();
+        textH = text->height();
+    }
+
+    qreal x = 0.0, y = 0.0;
+
+    if (role == TextRole::MultiA || role == TextRole::MultiB) {
+        const bool isHorizontal = (p.y() == q.y());
+        const int atBottom = p.y() + SPACE;
+        const int atTop = p.y() - SPACE - textH;
+        const int atLeft = p.x() - SPACE - textW;
+        const int atRight = p.x() + SPACE;
+        y = (p.y() > q.y()) == isHorizontal ? atBottom : atTop;
+        x = (p.x() < q.x()) == isHorizontal ? atRight : atLeft;
+
+    } else if (role == TextRole::ChangeA || role == TextRole::ChangeB) {
+
+        if (p.y() > q.y())
+            y = p.y() - SPACE - (textH * 2);
+        else
+            y = p.y() + SPACE + textH;
+
+        if (p.x() < q.x())
+            x = p.x() + SPACE;
+        else
+            x = p.x() - SPACE - textW;
+
+    } else if (role == TextRole::RoleAName || role == TextRole::RoleBName) {
+
+        if (p.y() > q.y())
+            y = p.y() - SPACE - textH;
+        else
+            y = p.y() + SPACE;
+
+        if (p.x() < q.x())
+            x = p.x() + SPACE;
+        else
+            x = p.x() - SPACE - textW;
+
+    } else if (role == TextRole::Name) {
+
+        calculateNameTextSegment();
+        if (m_unNameLineSegment == -1) {
+            uWarning() << "TODO:negative line segment index";
+            m_unNameLineSegment = 0;
+        }
+        x = ( m_associationLine->point(m_unNameLineSegment).x() +
+                     m_associationLine->point(m_unNameLineSegment + 1).x() ) / 2;
+        y = ( m_associationLine->point(m_unNameLineSegment).y() +
+                     m_associationLine->point(m_unNameLineSegment + 1).y() ) / 2;
+    }
+
+    if (text) {
+        constrainTextPos(x, y, textW, textH, role);
+    }
+    p = QPointF( x, y );
+    return p;
+}
+
+/**
+ * Return the mid point between p0 and p1
+ */
+QPointF AssociationWidget::midPoint(const QPointF& p0, const QPointF& p1)
+{
+    QPointF midP;
+    if (p0.x() < p1.x())
+        midP.setX(p0.x() + (p1.x() - p0.x()) / 2);
+    else
+        midP.setX(p1.x() + (p0.x() - p1.x()) / 2);
+    if (p0.y() < p1.y())
+        midP.setY(p0.y() + (p1.y() - p0.y()) / 2);
+    else
+        midP.setY(p1.y() + (p0.y() - p1.y()) / 2);
+    return midP;
+}
+
+/**
+ * Constrains the FloatingTextWidget X and Y values supplied.
+ * Implements the abstract operation from LinkWidget.
+ *
+ * @param textX       Candidate X value (may be modified by the constraint.)
+ * @param textY       Candidate Y value (may be modified by the constraint.)
+ * @param textWidth   Width of the text.
+ * @param textHeight  Height of the text.
+ * @param tr          Uml::Text_Role of the text.
+ */
+void AssociationWidget::constrainTextPos(qreal &textX, qreal &textY,
+                                         qreal textWidth, qreal textHeight,
+                                         Uml::TextRole::Enum tr)
+{
+    const int textCenterX = textX + textWidth / 2;
+    const int textCenterY = textY + textHeight / 2;
+    const int lastSegment = m_associationLine->count() - 1;
+    QPointF p0, p1;
+    switch (tr) {
+        case TextRole::RoleAName:
+        case TextRole::MultiA:
+        case TextRole::ChangeA:
+            p0 = m_associationLine->point(0);
+            p1 = m_associationLine->point(1);
+            // If we are dealing with a single line then tie the
+            // role label to the proper half of the line, i.e.
+            // the role label must be closer to the "other"
+            // role object.
+            if (lastSegment == 1)
+                p1 = midPoint(p0, p1);
+            break;
+        case TextRole::RoleBName:
+        case TextRole::MultiB:
+        case TextRole::ChangeB:
+            p0 = m_associationLine->point(lastSegment - 1);
+            p1 = m_associationLine->point(lastSegment);
+            if (lastSegment == 1)
+                p0 = midPoint(p0, p1);
+            break;
+        case TextRole::Name:
+        case TextRole::Coll_Message:  // CHECK: collab.msg texts seem to be TextRole::Name
+        case TextRole::State:         // CHECK: is this used?
+            // Find the linepath segment to which the (textX, textY) is closest
+            // and constrain to the corridor of that segment (see farther below)
+            {
+                int minDistSquare = 100000;  // utopian initial value
+                int lpIndex = 0;
+                for (int i = 0; i < lastSegment; ++i) {
+                    p0 = m_associationLine->point(i);
+                    p1 = m_associationLine->point(i + 1);
+                    QPointF midP = midPoint(p0, p1);
+                    const int deltaX = textCenterX - midP.x();
+                    const int deltaY = textCenterY - midP.y();
+                    const int cSquare = deltaX * deltaX + deltaY * deltaY;
+                    if (cSquare < minDistSquare) {
+                        minDistSquare = cSquare;
+                        lpIndex = i;
+                    }
+                }
+                p0 = m_associationLine->point(lpIndex);
+                p1 = m_associationLine->point(lpIndex + 1);
+            }
+            break;
+        default:
+            uError() << "unexpected TextRole::Enum " << tr;
+            return;
+            break;
+    }
+    /* Constraint:
+       The midpoint between p0 and p1 is taken to be the center of a circle
+       with radius D/2 where D is the distance between p0 and p1.
+       The text center needs to be within this circle else it is constrained
+       to the nearest point on the circle.
+     */
+    p0 = swapXY(p0);    // go to the natural coordinate system
+    p1 = swapXY(p1);    // with (0,0) in the lower left corner
+    QPointF midP = midPoint(p0, p1);
+    // If (textX,textY) is not inside the circle around midP then
+    // constrain (textX,textY) to the nearest point on that circle.
+    const int x0 = p0.x();
+    const int y0 = p0.y();
+    const int x1 = p1.x();
+    const int y1 = p1.y();
+    double r = sqrt((double)((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0))) / 2;
+    if (textWidth > r)
+        r = textWidth;
+    // swap textCenter{X,Y} to convert from Qt coord.system.
+    const QPointF origTextCenter(textCenterY, textCenterX);
+    const int relX = abs(origTextCenter.x() - midP.x());
+    const int relY = abs(origTextCenter.y() - midP.y());
+    const double negativeWhenInsideCircle = relX * relX + relY * relY - r * r;
+    if (negativeWhenInsideCircle <= 0.0) {
+        return;
+    }
+    /*
+     The original constraint was to snap the text position to the
+     midpoint but that creates unpleasant visual jitter:
+    textX = midP.y() - textWidth / 2;   // go back to Qt coord.sys.
+    textY = midP.x() - textHeight / 2;  // go back to Qt coord.sys.
+
+     Rather, we project the text position onto the closest point
+     on the circle:
+
+     Circle equation:
+       relX^2 + relY^2 - r^2 = 0, or in other words
+       relY^2 = r^2 - relX^2, or
+       relY = sqrt(r^2 - relX^2)
+     Line equation:
+       relY = a * relX + b
+         We can omit "b" because relX and relY are already relative to
+         the circle origin, therefore we can also write:
+       a = relY / relX
+     To obtain the point of intersection between the circle of radius r
+     and the line connecting the circle origin with the point (relX, relY),
+     we equate the relY:
+       a * x = sqrt(r^2 - x^2), or in other words
+       a^2 * x^2 = r^2 - x^2, or
+       x^2 * (a^2 + 1) = r^2, or
+       x^2 = r^2 / (a^2 + 1), or
+       x = sqrt(r^2 / (a^2 + 1))
+     and then
+       y = a * x
+     The resulting x and y are relative to the circle origin so we just add
+     the circle origin (X, Y) to obtain the constrained (textX, textY).
+     */
+    // Handle the special case, relX = 0.
+    if (relX == 0) {
+        if (origTextCenter.y() > midP.y())
+            textX = midP.y() + (int)r;   // go back to Qt coord.sys.
+        else
+            textX = midP.y() - (int)r;   // go back to Qt coord.sys.
+        textX -= textWidth / 2;
+        return;
+    }
+    const double a = (double)relY / (double)relX;
+    const double x = sqrt(r*r / (a*a + 1));
+    const double y = a * x;
+    if (origTextCenter.x() > midP.x())
+        textY = midP.x() + (int)x;   // go back to Qt coord.sys.
+    else
+        textY = midP.x() - (int)x;   // go back to Qt coord.sys.
+    textY -= textHeight / 2;
+    if (origTextCenter.y() > midP.y())
+        textX = midP.y() + (int)y;   // go back to Qt coord.sys.
+    else
+        textX = midP.y() - (int)y;   // go back to Qt coord.sys.
+    textX -= textWidth / 2;
+}
+
+/**
+ * Puts the text widget with the given role at the given position.
+ * This method calls @ref calculateTextPostion to get the needed position.
+ * I.e. the line segment it is on has moved and it should move the same
+ * amount as the line.
+ */
+void AssociationWidget::setTextPosition(Uml::TextRole::Enum role)
+{
+    bool startMove = false;
+    if (m_role[RoleType::A].multiplicityWidget && m_role[RoleType::A].multiplicityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::B].multiplicityWidget && m_role[RoleType::B].multiplicityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::A].changeabilityWidget && m_role[RoleType::A].changeabilityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::B].changeabilityWidget && m_role[RoleType::B].changeabilityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::A].roleWidget  && m_role[RoleType::A].roleWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::B].roleWidget  && m_role[RoleType::B].roleWidget->getStartMove())
+        startMove = true;
+    else if (m_nameWidget && m_nameWidget->getStartMove())
+        startMove = true;
+    if (startMove) {
+        return;
+    }
+    FloatingTextWidget *ft = textWidgetByRole(role);
+    if (ft == NULL)
+        return;
+    QPointF pos = calculateTextPosition(role);
+    ft->setX(pos.x());
+    ft->setY(pos.y());
+}
+
+/**
+ * Moves the text widget with the given role by the difference between
+ * the two points.
+ */
+void AssociationWidget::setTextPositionRelatively(Uml::TextRole::Enum role, const QPointF &oldPosition)
+{
+    bool startMove = false;
+    if (m_role[RoleType::A].multiplicityWidget && m_role[RoleType::A].multiplicityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::B].multiplicityWidget && m_role[RoleType::B].multiplicityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::A].changeabilityWidget && m_role[RoleType::A].changeabilityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::B].changeabilityWidget && m_role[RoleType::B].changeabilityWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::A].roleWidget  && m_role[RoleType::A].roleWidget->getStartMove())
+        startMove = true;
+    else if (m_role[RoleType::B].roleWidget  && m_role[RoleType::B].roleWidget->getStartMove())
+        startMove = true;
+    else if (m_nameWidget && m_nameWidget->getStartMove())
+        startMove = true;
+
+    if (startMove) {
+        return;
+    }
+    FloatingTextWidget *ft = textWidgetByRole(role);
+    if (ft == NULL)
+        return;
+    qreal ftX = ft->x();
+    qreal ftY = ft->y();
+
+    QPointF pos = calculateTextPosition(role);
+    int relX = pos.x() - oldPosition.x();
+    int relY = pos.y() - oldPosition.y();
+    qreal ftNewX = ftX + relX;
+    qreal ftNewY = ftY + relY;
+
+    bool oldIgnoreSnapToGrid = ft->getIgnoreSnapToGrid();
+    ft->setIgnoreSnapToGrid(true);
+    ft->setX(ftNewX);
+    ft->setY(ftNewY);
+    ft->setIgnoreSnapToGrid(oldIgnoreSnapToGrid);
+}
+
+/**
+ * Remove dashed connecting line for association class.
+ */
+void AssociationWidget::removeAssocClassLine()
+{
+    delete m_pAssocClassLineSel0;
+    m_pAssocClassLineSel0 = 0;
+    delete m_pAssocClassLineSel1;
+    m_pAssocClassLineSel1 = 0;
+    delete m_pAssocClassLine;
+    m_pAssocClassLine = 0;
+    if (m_associationClass) {
+        m_associationClass->setClassAssociationWidget(0);
+        m_associationClass = 0;
+    }
+}
+
+/**
+ * Creates the association class connecting line.
+ */
+void AssociationWidget::createAssocClassLine()
+{
+    if (m_pAssocClassLine == NULL) {
+        m_pAssocClassLine = new QGraphicsLineItem(this);
+    }
+    QPen pen(lineColor(), lineWidth(), Qt::DashLine);
+    m_pAssocClassLine->setPen(pen);
+    // decoration points
+    m_pAssocClassLineSel0 = Widget_Utils::decoratePoint(m_pAssocClassLine->line().p1(),
+                                                        m_pAssocClassLine);
+    m_pAssocClassLineSel1 = Widget_Utils::decoratePoint(m_pAssocClassLine->line().p2(),
+                                                        m_pAssocClassLine);
+    computeAssocClassLine();
+    selectAssocClassLine(false);
+}
+
+/**
+ * Creates the association class connecting line using the specified
+ * ClassifierWidget.
+ *
+ * @param classifier The ClassifierWidget to use.
+ * @param linePathSegmentIndex The index of the segment where the
+ *        association class is created.
+ */
+void AssociationWidget::createAssocClassLine(ClassifierWidget* classifier,
+                                             int linePathSegmentIndex)
+{
+    m_nLinePathSegmentIndex = linePathSegmentIndex;
+
+    if (m_nLinePathSegmentIndex < 0) {
+        return;
+    }
+
+    m_associationClass = classifier;
+    m_associationClass->setClassAssociationWidget(this);
+    m_associationClass->addAssoc(this);  // to get widgetMoved(...) for association classes
+
+    createAssocClassLine();
+}
+
+/**
+ * Compute the end points of m_pAssocClassLine in case this
+ * association has an attached association class.
+ * TODO: The decoration points make no sense for now, because they are not movable.
+ */
+void AssociationWidget::computeAssocClassLine()
+{
+    if (m_associationClass == NULL || m_pAssocClassLine == NULL) {
+        return;
+    }
+    if (m_nLinePathSegmentIndex < 0) {
+        uError() << "m_nLinePathSegmentIndex is not set";
+        return;
+    }
+
+    QPointF segStart = m_associationLine->point(m_nLinePathSegmentIndex);
+    QPointF segEnd = m_associationLine->point(m_nLinePathSegmentIndex + 1);
+    const qreal midSegX = segStart.x() + (segEnd.x() - segStart.x()) / 2.0;
+    const qreal midSegY = segStart.y() + (segEnd.y() - segStart.y()) / 2.0;
+    QPointF segmentMidPoint(midSegX, midSegY);
+
+    QLineF possibleAssocLine = QLineF(segmentMidPoint,
+                                      m_associationClass->mapRectToScene(m_associationClass->rect()).center());
+    QPointF intersectionPoint;
+    QLineF::IntersectType type = intersect(m_associationClass->mapRectToScene(m_associationClass->boundingRect()),
+                                           possibleAssocLine,
+                                           &intersectionPoint);
+    // DEBUG(DBG_SRC) << "intersect type=" << type << " / point=" << intersectionPoint;
+
+    if (type == QLineF::BoundedIntersection) {
+        m_pAssocClassLine->setLine(midSegX, midSegY,
+                                   intersectionPoint.x(), intersectionPoint.y());
+
+        if (m_pAssocClassLineSel0 && m_pAssocClassLineSel1) {
+            m_pAssocClassLineSel0->setPos(m_pAssocClassLine->line().p1());
+            m_pAssocClassLineSel1->setPos(m_pAssocClassLine->line().p2());
+        }
+    }
+}
+
+/**
+ * Renders the association class connecting line selected.
+ */
+void AssociationWidget::selectAssocClassLine(bool sel)
+{
+    if (m_pAssocClassLineSel0 && m_pAssocClassLineSel1) {
+        m_pAssocClassLineSel0->setVisible(sel);
+        m_pAssocClassLineSel1->setVisible(sel);
+    }
+}
+
+/**
+ * Sets the association to be selected.
+ */
+void AssociationWidget::mousePressEvent(QGraphicsSceneMouseEvent * me)
+{
+    // clear other selected stuff on the screen of ShiftKey
+    if (me->modifiers() != Qt::ShiftModifier) {
+        m_scene->clearSelected();
+    }
+
+    if (me->button() == Qt::LeftButton && me->modifiers() == Qt::ControlModifier) {
+        if (checkRemovePoint(me->scenePos()))
+            return;
+    }
+
+    // make sure we should be here depending on the button
+    if (me->button() != Qt::RightButton && me->button() != Qt::LeftButton) {
+        return;
+    }
+    QPointF mep = me->scenePos();
+    // see if `mep' is on the connecting line to the association class
+    if (onAssocClassLine(mep)) {
+        setSelected(true);
+        selectAssocClassLine();
+        return;
+    }
+    setSelected(!isSelected());
+    associationLine()->mousePressEvent(me);
+}
+
+/**
+ * Displays the right mouse buttom menu if right button is pressed.
+ */
+void AssociationWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent * me)
+{
+    associationLine()->mouseReleaseEvent(me);
+}
+
+/**
+ * Handles the selection from the popup menu.
+ */
+void AssociationWidget::slotMenuSelection(QAction* action)
+{
+    QString oldText, newText;
+    QRegExpValidator v(QRegExp(QLatin1String(".*")), 0);
+    Uml::AssociationType::Enum atype = associationType();
+    Uml::RoleType::Enum r = RoleType::B;
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    DEBUG(DBG_SRC) << "menu selection = " << ListPopupMenu::toString(sel);
+
+    // if it's a collaboration message we now just use the code in floatingtextwidget
+    // this means there's some redundant code below but that's better than duplicated code
+    if (isCollaboration() && sel != ListPopupMenu::mt_Delete) {
+        m_nameWidget->slotMenuSelection(action);
+        return;
+    }
+
+    switch(sel) {
+    case ListPopupMenu::mt_Properties:
+        if (atype == AssociationType::Seq_Message || atype == AssociationType::Seq_Message_Self) {
+            // show op dlg for seq. diagram here
+            // don't worry about here, I don't think it can get here as
+            // line is widget on seq. diagram
+            // here just in case - remove later after testing
+            DEBUG(DBG_SRC) << "mt_Properties: assoctype is " << atype;
+        } else {  //standard assoc dialog
+            UMLApp::app()->docWindow()->updateDocumentation(false);
+            showPropertiesDialog();
+        }
+        break;
+
+    case ListPopupMenu::mt_Add_Point:
+        checkAddPoint(m_eventScenePos);
+        break;
+
+    case ListPopupMenu::mt_Delete_Point:
+        checkRemovePoint(m_eventScenePos);
+        break;
+
+    case ListPopupMenu::mt_Delete:
+        if (m_pAssocClassLineSel0)
+            removeAssocClassLine();
+        else if (association())
+            m_scene->removeAssocInViewAndDoc(this);
+        else
+            m_scene->removeAssoc(this);
+        break;
+
+    case ListPopupMenu::mt_Rename_MultiA:
+        r = RoleType::A;   // fall through
+    case ListPopupMenu::mt_Rename_MultiB:
+        if (m_role[r].multiplicityWidget)
+            oldText = m_role[r].multiplicityWidget->text();
+        else
+            oldText = QString();
+#if QT_VERSION >= 0x050000
+        newText = QInputDialog::getText(m_scene->activeView(),
+                                        i18n("Multiplicity"),
+                                        i18n("Enter multiplicity:"),
+                                        QLineEdit::Normal,
+                                        oldText, NULL);
+#else
+        newText = KInputDialog::getText(i18n("Multiplicity"),
+                                        i18n("Enter multiplicity:"),
+                                        oldText, NULL, m_scene->activeView(), &v);
+#endif
+        if (newText != oldText) {
+            if (FloatingTextWidget::isTextValid(newText)) {
+                setMultiplicity(newText, r);
+            } else {
+                m_scene->removeWidget(m_role[r].multiplicityWidget);
+                m_role[r].multiplicityWidget = NULL;
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Rename_Name:
+        if (m_nameWidget)
+            oldText = m_nameWidget->text();
+        else
+            oldText = QString();
+#if QT_VERSION >= 0x050000
+        newText = QInputDialog::getText(m_scene->activeView(),
+                                        i18n("Association Name"),
+                                        i18n("Enter association name:"),
+                                        QLineEdit::Normal,
+                                        oldText, NULL);
+#else
+        newText = KInputDialog::getText(i18n("Association Name"),
+                                        i18n("Enter association name:"),
+                                        oldText, NULL, m_scene->activeView(), &v);
+#endif
+        if (newText != oldText) {
+            if (FloatingTextWidget::isTextValid(newText)) {
+                setName(newText);
+            } else if (m_nameWidget) {
+                m_scene->removeWidget(m_nameWidget);
+                m_nameWidget = NULL;
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Rename_RoleAName:
+        r = RoleType::A;   // fall through
+    case ListPopupMenu::mt_Rename_RoleBName:
+        if (m_role[r].roleWidget)
+            oldText = m_role[r].roleWidget->text();
+        else
+            oldText = QString();
+#if QT_VERSION >= 0x050000
+        newText = QInputDialog::getText(m_scene->activeView(),
+                                        i18n("Role Name"),
+                                        i18n("Enter role name:"),
+                                        QLineEdit::Normal,
+                                        oldText, NULL);
+#else
+        newText = KInputDialog::getText(i18n("Role Name"),
+                                        i18n("Enter role name:"),
+                                        oldText, NULL, m_scene->activeView(), &v);
+#endif
+        if (newText != oldText) {
+            if (FloatingTextWidget::isTextValid(newText)) {
+                setRoleName(newText, r);
+            } else {
+                m_scene->removeWidget(m_role[r].roleWidget);
+                m_role[r].roleWidget = NULL;
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Change_Font:
+        {
+#if QT_VERSION >= 0x050000
+            bool ok = false;
+            QFont fnt = QFontDialog::getFont(&ok, font(), m_scene->activeView());
+            if (ok)
+#else
+            QFont fnt = font();
+            if (KFontDialog::getFont(fnt, KFontChooser::NoDisplayFlags, m_scene->activeView()))
+#endif
+                lwSetFont(fnt);
+        }
+        break;
+
+    case ListPopupMenu::mt_Line_Color:
+        {
+#if QT_VERSION >= 0x050000
+            QColor newColor = QColorDialog::getColor(lineColor());
+            if (newColor != lineColor()) {
+#else
+            QColor newColor;
+            if (KColorDialog::getColor(newColor)) {
+#endif
+                m_scene->selectionSetLineColor(newColor);
+                umlDoc()->setModified(true);
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Cut:
+        m_scene->setStartedCut();
+        UMLApp::app()->slotEditCut();
+        break;
+
+    case ListPopupMenu::mt_Copy:
+        UMLApp::app()->slotEditCopy();
+        break;
+
+    case ListPopupMenu::mt_Paste:
+        UMLApp::app()->slotEditPaste();
+        break;
+
+    case ListPopupMenu::mt_Reset_Label_Positions:
+        resetTextPositions();
+        break;
+
+    case ListPopupMenu::mt_LayoutDirect:
+        m_associationLine->setLayout(AssociationLine::Direct);
+        break;
+    case ListPopupMenu::mt_LayoutSpline:
+        m_associationLine->setLayout(AssociationLine::Spline);
+        break;
+    case ListPopupMenu::mt_LayoutOrthogonal:
+        m_associationLine->setLayout(AssociationLine::Orthogonal);
+        break;
+    case ListPopupMenu::mt_LayoutPolyline:
+        m_associationLine->setLayout(AssociationLine::Polyline);
+        break;
+
+    default:
+        DEBUG(DBG_SRC) << "MenuType " << ListPopupMenu::toString(sel) << " not implemented";
+        break;
+    }//end switch
+}
+
+/**
+ * Return the first font found being used by any child widget. (They
+ * could be different fonts, so this is a slightly misleading method.)
+ */
+QFont AssociationWidget::font() const
+{
+    //:TODO: find a general font for the association
+    QFont font;
+
+    if (m_role[RoleType::A].roleWidget)
+        font = m_role[RoleType::A].roleWidget->font();
+    else    if (m_role[RoleType::B].roleWidget)
+        font = m_role[RoleType::B].roleWidget->font();
+    else    if (m_role[RoleType::A].multiplicityWidget)
+        font = m_role[RoleType::A].multiplicityWidget->font();
+    else    if (m_role[RoleType::B].multiplicityWidget)
+        font = m_role[RoleType::B].multiplicityWidget->font();
+    else    if (m_role[RoleType::A].changeabilityWidget)
+        font = m_role[RoleType::A].changeabilityWidget->font();
+    else    if (m_role[RoleType::B].changeabilityWidget)
+        font = m_role[RoleType::B].changeabilityWidget->font();
+    else    if (m_nameWidget)
+        font = m_nameWidget->font();
+    else
+        font = m_role[RoleType::A].umlWidget->font();
+
+    return font;
+}
+
+/**
+ * Set all 'owned' child widgets to this text color.
+ */
+void AssociationWidget::setTextColor(const QColor &color)
+{
+    WidgetBase::setTextColor(color);
+    if (m_nameWidget) {
+        m_nameWidget->setTextColor(color);
+    }
+    if (m_role[RoleType::A].roleWidget) {
+        m_role[RoleType::A].roleWidget->setTextColor(color);
+    }
+    if (m_role[RoleType::B].roleWidget) {
+        m_role[RoleType::B].roleWidget->setTextColor(color);
+    }
+    if (m_role[RoleType::A].multiplicityWidget) {
+        m_role[RoleType::A].multiplicityWidget->setTextColor(color);
+    }
+    if (m_role[RoleType::B].multiplicityWidget) {
+        m_role[RoleType::B].multiplicityWidget->setTextColor(color);
+    }
+    if (m_role[RoleType::A].changeabilityWidget)
+        m_role[RoleType::A].changeabilityWidget->setTextColor(color);
+    if (m_role[RoleType::B].changeabilityWidget)
+        m_role[RoleType::B].changeabilityWidget->setTextColor(color);
+}
+
+bool AssociationWidget::checkAddPoint(const QPointF &scenePos)
+{
+    if (associationType() == AssociationType::Exception) {
+        return false;
+    }
+
+    // if there is no point around the mouse pointer, we insert a new one
+    if (m_associationLine->closestPointIndex(scenePos) < 0) {
+        int i = m_associationLine->closestSegmentIndex(scenePos);
+        if (i < 0) {
+            DEBUG(DBG_SRC) << "no closest segment found!";
+            return false;
+        }
+        m_associationLine->insertPoint(i + 1, scenePos);
+        if (m_nLinePathSegmentIndex == i) {
+            QPointF segStart = m_associationLine->point(i);
+            QPointF segEnd = m_associationLine->point(i + 2);
+            const int midSegX = segStart.x() + (segEnd.x() - segStart.x()) / 2;
+            const int midSegY = segStart.y() + (segEnd.y() - segStart.y()) / 2;
+            /*
+            DEBUG(DBG_SRC) << "segStart=" << segStart << ", segEnd=" << segEnd
+                           << ", midSeg=(" << midSegX << "," << midSegY
+                           << "), mp=" << mp;
+             */
+            if (midSegX > scenePos.x() || midSegY < scenePos.y()) {
+                m_nLinePathSegmentIndex++;
+                DEBUG(DBG_SRC) << "setting m_nLinePathSegmentIndex to "
+                               << m_nLinePathSegmentIndex;
+                computeAssocClassLine();
+            }
+            m_associationLine->update();
+            calculateNameTextSegment();
+            umlDoc()->setModified(true);
+            setSelected(true);
+        }
+        return true;
+    }
+    else {
+        DEBUG(DBG_SRC) << "found point already close enough!";
+        return false;
+    }
+}
+
+/**
+ * Remove point close to the given point and redraw the association.
+ * @param scenePos   point which should be removed
+ * @return   success status of the remove action
+ */
+bool AssociationWidget::checkRemovePoint(const QPointF &scenePos)
+{
+    int i = m_associationLine->closestPointIndex(scenePos);
+    if (i == -1)
+        return false;
+
+    m_associationLine->setSelected(false);
+
+    // there was a point so we remove the point
+    m_associationLine->removePoint(i);
+
+    // Maybe reattach association class connecting line
+    // to different association linepath segment.
+    const int numberOfLines = m_associationLine->count() - 1;
+    if (m_nLinePathSegmentIndex >= numberOfLines) {
+        m_nLinePathSegmentIndex = numberOfLines - 1;
+    }
+    calculateEndingPoints();
+
+    // select the line path
+    m_associationLine->setSelected(true);
+
+    m_associationLine->update();
+
+    calculateNameTextSegment();
+    umlDoc()->setModified(true);
+    return true;
+}
+
+/**
+ * Moves the break point being dragged.
+ */
+void AssociationWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* me)
+{
+    if (me->buttons() != Qt::LeftButton) {
+        return;
+    }
+
+    setSelected(true);
+
+    associationLine()->mouseMoveEvent(me);
+    moveEvent(me);
+    m_scene->resizeSceneToItems();
+}
+
+/**
+ * Returns the Region the widget to line intersection is for the given
+ * widget in this Association.  If the given widget is not in the
+ * Association then Region::Error is returned.
+ * Used by @ref calculateEndingPoints to work these positions out for
+ * another Association - since the number of Associations on the same
+ * region for the same widget will mean the lines will need to be
+ * spread out across the region.
+ */
+//Uml::Region::Enum AssociationWidget::getWidgetRegion(AssociationWidget * widget) const
+//{
+//    if (widget->widgetForRole(RoleType::A) == m_role[RoleType::A].umlWidget)
+//        return m_role[RoleType::A].m_WidgetRegion;
+//    if (widget->widgetForRole(RoleType::B) == m_role[RoleType::B].umlWidget)
+//        return m_role[RoleType::B].m_WidgetRegion;
+//    return Uml::Region::Error;
+//}
+
+/**
+ * Returns the number of lines there are on the given region for
+ * either widget A or B of the association.
+ */
+int AssociationWidget::getRegionCount(Uml::Region::Enum region, Uml::RoleType::Enum role)
+{
+    if ((region == Uml::Region::Error) | (umlScene() == NULL)) {
+        return 0;
+    }
+    int widgetCount = 0;
+    AssociationWidgetList list = m_scene->associationList();
+    foreach (AssociationWidget* assocwidget, list) {
+        //don't count this association
+        if (assocwidget == this)
+            continue;
+        const WidgetRole& otherA = assocwidget->m_role[RoleType::A];
+        const WidgetRole& otherB = assocwidget->m_role[RoleType::B];
+        const UMLWidget *a = otherA.umlWidget;
+        const UMLWidget *b = otherB.umlWidget;
+        /*
+        //don't count associations to self if both of their end points are on the same region
+        //they are different and placement won't interfere with them
+        if (a == b && otherA.m_WidgetRegion == otherB.m_WidgetRegion)
+                continue;
+         */
+        if (m_role[role].umlWidget == a && region == otherA.m_WidgetRegion)
+            widgetCount++;
+        else if (m_role[role].umlWidget == b && region == otherB.m_WidgetRegion)
+            widgetCount++;
+    }//end foreach
+    return widgetCount;
+}
+
+/**
+ * Find the border point of the given rect when a line is drawn from the
+ * given point to the rect.
+ * @param rect   rect of a classifier
+ * @param line   a line to the rect
+ * @param intersectionPoint   the intercept point on the border of the rect
+ * @return   the type of the intersection @ref QLineF::IntersectType
+ */
+QLineF::IntersectType AssociationWidget::intersect(const QRectF &rect, const QLineF &line,
+                                                   QPointF* intersectionPoint)
+{
+    QList<QLineF> lines;
+    lines << QLineF(rect.topLeft(), rect.topRight());
+    lines << QLineF(rect.topRight(), rect.bottomRight());
+    lines << QLineF(rect.bottomRight(), rect.bottomLeft());
+    lines << QLineF(rect.bottomLeft(), rect.topLeft());
+    foreach (const QLineF& rectLine, lines) {
+        QLineF::IntersectType type = rectLine.intersect(line, intersectionPoint);
+        if (type == QLineF::BoundedIntersection) {
+            return type;
+        }
+    }
+    return QLineF::NoIntersection;
+}
+
+/**
+ * Given a rectangle and a point, findInterceptOnEdge computes the
+ * connecting line between the middle point of the rectangle and
+ * the point, and returns the intercept of this line with the
+ * the edge of the rectangle identified by `region'.
+ * When the region is North or South, the X value is returned (Y is
+ * constant.)
+ * When the region is East or West, the Y value is returned (X is
+ * constant.)
+ * @todo This is buggy. Try replacing by intersect()
+ */
+qreal AssociationWidget::findInterceptOnEdge(const QRectF &rect,
+                                             Uml::Region::Enum region,
+                                             const QPointF &point)
+{
+    // The Qt coordinate system has (0, 0) in the top left corner.
+    // In order to go to the regular XY coordinate system with (0, 0)
+    // in the bottom left corner, we swap the X and Y axis.
+    // That's why the following assignments look twisted.
+    const qreal rectHalfWidth = rect.height() / 2.0;
+    const qreal rectHalfHeight = rect.width() / 2.0;
+    const qreal rectMidX = rect.y() + rectHalfWidth;
+    const qreal rectMidY = rect.x() + rectHalfHeight;
+    const qreal dX = rectMidX - point.y();
+    const qreal dY = rectMidY - point.x();
+    switch (region) {
+    case Uml::Region::West:
+        region = Uml::Region::South;
+        break;
+    case Uml::Region::North:
+        region = Uml::Region::West;
+        break;
+    case Uml::Region::East:
+        region = Uml::Region::North;
+        break;
+    case Uml::Region::South:
+        region = Uml::Region::East;
+        break;
+    default:
+        break;
+    }
+    // Now we have regular coordinates with the point (0, 0) in the
+    // bottom left corner.
+    if (region == Uml::Region::North || region == Uml::Region::South) {
+        if (dX == 0)
+            return rectMidY;
+        // should be rectMidX, but we go back to Qt coord.sys.
+        if (dY == 0) {
+            uError() << "usage error: " << "North/South (dY == 0)";
+            return -1.0;
+        }
+        const qreal m = dY / dX;
+        qreal relativeX;
+        if (region == Uml::Region::North)
+            relativeX = rectHalfHeight / m;
+        else
+            relativeX = -rectHalfHeight / m;
+        return (rectMidY + relativeX);
+        // should be rectMidX, but we go back to Qt coord.sys.
+    } else {
+        if (dY == 0)
+            return rectMidX;
+        // should be rectMidY, but we go back to Qt coord.sys.
+        if (dX == 0) {
+            uError() << "usage error: " << "East/West (dX == 0)";
+            return -1.0;
+        }
+        const qreal m = dY / dX;
+        qreal relativeY = m * rectHalfWidth;
+        if (region == Uml::Region::West)
+            relativeY = -relativeY;
+        return (rectMidX + relativeY);
+        // should be rectMidY, but we go back to Qt coord.sys.
+    }
+}
+
+/**
+ * Auxiliary method for updateAssociations():
+ * Put position into m_positions and assoc into m_ordered at the
+ * correct index.
+ * m_positions and m_ordered move in parallel and are sorted by
+ * ascending position.
+ */
+void AssociationWidget::insertIntoLists(qreal position, const AssociationWidget* assoc)
+{
+    bool did_insertion = false;
+    for (int index = 0; index < m_positions_len; ++index) {
+        if (position < m_positions[index]) {
+            for (int moveback = m_positions_len; moveback > index; moveback--)
+                m_positions[moveback] = m_positions[moveback - 1];
+            m_positions[index] = position;
+            m_ordered.insert(index, const_cast<AssociationWidget*>(assoc));
+            did_insertion = true;
+            break;
+        }
+    }
+    if (! did_insertion) {
+        m_positions[m_positions_len] = position;
+        m_ordered.append(const_cast<AssociationWidget*>(assoc));
+    }
+    m_positions_len++;
+}
+
+/**
+ * Tells all the other view associations the new count for the
+ * given widget on a certain region. And also what index they should be.
+ */
+void AssociationWidget::updateAssociations(int totalCount,
+                                           Uml::Region::Enum region,
+                                           Uml::RoleType::Enum role)
+{
+    if ((region == Uml::Region::Error) | (umlScene() == NULL)) {
+        return;
+    }
+    AssociationWidgetList list = m_scene->associationList();
+
+    UMLWidget *ownWidget = m_role[role].umlWidget;
+    m_positions_len = 0;
+    m_ordered.clear();
+    // we order the AssociationWidget list by region and x/y value
+    foreach (AssociationWidget* assocwidget, list) {
+        WidgetRole *roleA = &assocwidget->m_role[RoleType::A];
+        WidgetRole *roleB = &assocwidget->m_role[RoleType::B];
+        UMLWidget *wA = roleA->umlWidget;
+        UMLWidget *wB = roleB->umlWidget;
+        // Skip self associations.
+        if (wA == wB)
+            continue;
+        // Now we must find out with which end the assocwidget connects
+        // to the input widget (ownWidget).
+        bool inWidgetARegion = (ownWidget == wA &&
+                                 region == roleA->m_WidgetRegion);
+        bool inWidgetBRegion = (ownWidget == wB &&
+                                 region == roleB->m_WidgetRegion);
+        if (!inWidgetARegion && !inWidgetBRegion)
+            continue;
+        // Determine intercept position on the edge indicated by `region'.
+        UMLWidget * otherWidget = (inWidgetARegion ? wB : wA);
+        AssociationLine *linepath = assocwidget->associationLine();
+        QPointF refpoint;
+        if (assocwidget->linePathStartsAt(otherWidget))
+            refpoint = linepath->point(linepath->count() - 2);
+        else
+            refpoint = linepath->point(1);
+        // The point is authoritative if we're called for the second time
+        // (i.e. role==B) or it is a waypoint on the line path.
+        bool pointIsAuthoritative = (role == RoleType::B || linepath->count() > 2);
+        if (! pointIsAuthoritative) {
+            // If the point is not authoritative then we use the other
+            // widget's center.
+            refpoint.setX(otherWidget->x() + otherWidget->width() / 2);
+            refpoint.setY(otherWidget->y() + otherWidget->height() / 2);
+        }
+        qreal intercept = findInterceptOnEdge(ownWidget->rect(), region, refpoint);
+        if (intercept < 0) {
+            DEBUG(DBG_SRC) << "error from findInterceptOnEdge for"
+                           << " assocType=" << assocwidget->associationType()
+                           << " ownWidget=" << ownWidget->name()
+                           << " otherWidget=" << otherWidget->name();
+            continue;
+        }
+        insertIntoLists(intercept, assocwidget);
+    } // while ((assocwidget = assoc_it.current()))
+
+    // we now have an ordered list and we only have to call updateRegionLineCount
+    int index = 1;
+    foreach (AssociationWidget* assocwidget, m_ordered ) {
+        if (ownWidget == assocwidget->widgetForRole(RoleType::A)) {
+            assocwidget->updateRegionLineCount(index++, totalCount, region, RoleType::A);
+        } else if (ownWidget == assocwidget->widgetForRole(RoleType::B)) {
+            assocwidget->updateRegionLineCount(index++, totalCount, region, RoleType::B);
+        }
+    } // for (assocwidget = ordered.first(); ...)
+}
+
+/**
+ * Called to tell the association that another association has added
+ * a line to the region of one of its widgets. The widget is identified
+ * by its role (A or B).
+ *
+ * Called by @ref updateAssociations which is called by
+ * @ref calculateEndingPoints when required.
+ */
+void AssociationWidget::updateRegionLineCount(int index, int totalCount,
+                                              Uml::Region::Enum region,
+                                              Uml::RoleType::Enum role)
+{
+    if ((region == Uml::Region::Error) | (umlScene() == NULL)) {
+        return;
+    }
+    // If the association is to self and the line ends are on the same region then
+    // use a different calculation.
+    if (isSelf() &&
+            m_role[RoleType::A].m_WidgetRegion == m_role[RoleType::B].m_WidgetRegion) {
+        UMLWidget * pWidget = m_role[RoleType::A].umlWidget;
+        qreal x = pWidget->x();
+        qreal y = pWidget->y();
+        qreal wh = pWidget->height();
+        qreal ww = pWidget->width();
+        int size = m_associationLine->count();
+        // See if above widget ok to place assoc.
+        switch( m_role[RoleType::A].m_WidgetRegion ) {
+        case Uml::Region::North:
+            m_associationLine->setPoint( 0, QPointF( x + ( ww / 4 ), y ) );
+            m_associationLine->setPoint( size - 1, QPointF(x + ( ww * 3 / 4 ), y ) );
+            break;
+
+        case Uml::Region::South:
+            m_associationLine->setPoint( 0, QPointF( x + ( ww / 4 ), y + wh ) );
+            m_associationLine->setPoint( size - 1, QPointF( x + ( ww * 3 / 4 ), y + wh ) );
+            break;
+
+        case Uml::Region::East:
+            m_associationLine->setPoint( 0, QPointF( x + ww, y + ( wh / 4 ) ) );
+            m_associationLine->setPoint( size - 1, QPointF( x + ww, y + ( wh * 3 / 4 ) ) );
+            break;
+
+        case Uml::Region::West:
+            m_associationLine->setPoint( 0, QPointF( x, y + ( wh / 4 ) ) );
+            m_associationLine->setPoint( size - 1, QPointF( x, y + ( wh * 3 / 4 ) ) );
+            break;
+        default:
+            break;
+        }//end switch
+
+        return;
+    }
+
+    WidgetRole& robj = m_role[role];
+    UMLWidget * pWidget = robj.umlWidget;
+
+    robj.m_nIndex = index;
+    robj.m_nTotalCount = totalCount;
+    qreal x = pWidget->x();
+    qreal y = pWidget->y();
+    qreal ww = pWidget->width();
+    qreal wh = pWidget->height();
+    const bool angular = Settings::optionState().generalState.angularlines;
+    qreal ch = 0;
+    qreal cw = 0;
+    if (angular) {
+        uint nind = (role == RoleType::A ? 1 : m_associationLine->count() - 2);
+        QPointF neighbour = m_associationLine->point(nind);
+        if (neighbour.x() < x)
+            cw = 0;
+        else if (neighbour.x() > x + ww)
+            cw = 0 + ww;
+        else
+            cw = neighbour.x() - x;
+        if (neighbour.y() < y)
+            ch = 0;
+        else if (neighbour.y() > y + wh)
+            ch = 0 + wh;
+        else
+            ch = neighbour.y() - y;
+    } else {
+        ch = wh * index / totalCount;
+        cw = ww * index / totalCount;
+    }
+
+    qreal newX = x + cw;
+    qreal newY = y + ch;
+
+    QPointF pt;
+    if (angular) {
+        pt = QPointF(newX, newY);
+    } else {
+        UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
+        UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
+        QList<QPolygonF> polyListA = pWidgetA->shape().toSubpathPolygons();
+        QPolygonF polyA = polyListA.at(0);
+        if (polyListA.size() > 1) {
+            for (int i = 1; i < polyListA.size(); i++) {
+                 polyA = polyA.united(polyListA.at(i));
+            }
+        }
+        polyA = polyA.translated(pWidgetA->pos());
+        QList<QPolygonF> polyListB = pWidgetB->shape().toSubpathPolygons();
+        QPolygonF polyB = polyListB.at(0);
+        if (polyListB.size() > 1) {
+            for (int i = 1; i < polyListB.size(); i++) {
+                 polyB = polyB.united(polyListB.at(i));
+            }
+        }
+        polyB = polyB.translated(pWidgetB->pos());
+        QLineF nearestPoints = Widget_Utils::closestPoints(polyA, polyB);
+        if (nearestPoints.isNull()) {
+            uError() << "Widget_Utils::closestPoints failed, falling back to simple widget positions";
+            switch(region) {
+                case Uml::Region::West:
+                    pt.setX(x);
+                    pt.setY(newY);
+                    break;
+                case Uml::Region::North:
+                    pt.setX(newX);
+                    pt.setY(y);
+                    break;
+                case Uml::Region::East:
+                    pt.setX(x + ww);
+                    pt.setY(newY);
+                    break;
+                case Uml::Region::South:
+                    pt.setX(newX);
+                    pt.setY(y + wh);
+                    break;
+                case Uml::Region::Center:
+                    pt.setX(x + ww / 2);
+                    pt.setY(y + wh / 2);
+                    break;
+                default:
+                    break;
+            }
+        } else {
+            if (role == RoleType::A)
+                pt = nearestPoints.p1();
+            else
+                pt = nearestPoints.p2();
+        }
+    }
+    if (role == RoleType::A) {
+        m_associationLine->setPoint(0, pt);
+    }
+    else {
+        m_associationLine->setPoint(m_associationLine->count() - 1, pt);
+    }
+}
+
+/**
+ * Sets the state of whether the widget is selected.
+ *
+ * @param _select   The state of whether the widget is selected.
+ */
+void AssociationWidget::setSelected(bool _select /* = true */)
+{
+    WidgetBase::setSelected(_select);
+    if ( m_nameWidget)
+        m_nameWidget->setSelected( _select );
+    if ( m_role[RoleType::A].roleWidget )
+        m_role[RoleType::A].roleWidget->setSelected( _select );
+    if ( m_role[RoleType::B].roleWidget )
+        m_role[RoleType::B].roleWidget->setSelected( _select );
+    if ( m_role[RoleType::A].multiplicityWidget )
+        m_role[RoleType::A].multiplicityWidget->setSelected( _select );
+    if ( m_role[RoleType::B].multiplicityWidget )
+        m_role[RoleType::B].multiplicityWidget->setSelected( _select );
+    if ( m_role[RoleType::A].changeabilityWidget)
+        m_role[RoleType::A].changeabilityWidget->setSelected( _select );
+    if ( m_role[RoleType::B].changeabilityWidget)
+        m_role[RoleType::B].changeabilityWidget->setSelected( _select );
+
+    // Update the docwindow for this association.
+    // This is done last because each of the above setSelected calls
+    // overwrites the docwindow, but we want the main association doc
+    // to win.
+    if (_select) {
+        if (m_scene->selectedCount() == 0)
+                UMLApp::app()->docWindow()->showDocumentation(this, false);
+    } else
+        UMLApp::app()->docWindow()->updateDocumentation(true);
+
+    m_associationLine->setSelected(_select);
+    if (! _select) {
+        // For now, if _select is true we don't make the assoc class line
+        // selected. But that's certainly open for discussion.
+        // At any rate, we need to deselect the assoc class line
+        // if _select is false.
+        selectAssocClassLine(false);
+    }
+    UMLApp::app()->document()->writeToStatusBar(_select ? i18n("Press Ctrl with left mouse click to delete a point") : QString());
+}
+
+/**
+ * Reimplement method from WidgetBase in order to check owned floating texts.
+ *
+ * @param p Point to be checked.
+ *
+ * @return m_nameWidget if m_nameWidget is non NULL and m_nameWidget->onWidget(p) returns non NULL;
+ *         m_role[0].(multiplicity|changeability|role)Widget if the resp. widget is non NULL and
+ *         its onWidget(p) returns non NULL;
+ *         m_role[1].(multiplicity|changeability|role)Widget if the resp. widget is non NULL and
+ *         its onWidget(p) returns non NULL;
+ *         else NULL.
+ */
+UMLWidget* AssociationWidget::onWidget(const QPointF &p)
+{
+    if (m_nameWidget && m_nameWidget->onWidget(p)) {
+        return m_nameWidget;
+    }
+    for (int i = 0; i <= 1; i++) {
+        const WidgetRole& r = m_role[i];
+        if (r.multiplicityWidget && r.multiplicityWidget->onWidget(p))
+            return r.multiplicityWidget;
+        if (r.changeabilityWidget && r.changeabilityWidget->onWidget(p))
+            return r.changeabilityWidget;
+        if (r.roleWidget && r.roleWidget->onWidget(p))
+            return r.roleWidget;
+    }
+    return NULL;
+}
+
+/**
+ * Returns true if the given point is on the connecting line to
+ * the association class. Returns false if there is no association
+ * class attached, or if the given point is not on the connecting
+ * line.
+ */
+bool AssociationWidget::onAssocClassLine(const QPointF &point)
+{
+    bool onLine = false;
+    if (m_pAssocClassLine) {
+//:TODO:
+//        const QPointF mapped = m_pAssocClassLine->mapFromParent(point);
+//        bool onLine = m_pAssocClassLine->contains(mapped);
+//        return onLine;
+        UMLSceneItemList list = m_scene->collisions(point);
+        UMLSceneItemList::iterator end(list.end());
+        for (UMLSceneItemList::iterator item_it(list.begin()); item_it != end; ++item_it) {
+            if (*item_it == m_pAssocClassLine) {
+                onLine = true;
+                break;
+            }
+        }
+    }
+    DEBUG(DBG_SRC) << onLine;
+    return onLine;
+}
+
+/**
+ * Returns true if the given point is on the association line.
+ * A circle (rectangle) around the point is used to obtain more tolerance.
+ * @param point   the point to check
+ * @return   flag whether point is on association line
+ */
+bool AssociationWidget::onAssociation(const QPointF& point)
+{
+    // check the path
+    const qreal diameter(4.0);
+    QPainterPath path = m_associationLine->shape();
+    if (path.contains(point)) {
+        DEBUG(DBG_SRC) << "on path";
+        return true;
+    }
+    // check also the points
+    if (m_associationLine->layout() == AssociationLine::Spline) {
+        if (m_associationLine->closestPointIndex(point, diameter) > -1) {
+            DEBUG(DBG_SRC) << "on spline point";
+            return true;
+        }
+    }
+    return onAssocClassLine(point);
+}
+
+/**
+ * Set all association points to x coordinate.
+ */
+void AssociationWidget::setXEntireAssoc(qreal x)
+{
+    for (int i = 0; i < m_associationLine->count(); ++i) {
+        QPointF p = m_associationLine->point(i);
+        p.setX(x);
+        m_associationLine->setPoint(i, p);
+    }
+}
+
+/**
+ * Set all association points to y coordinate.
+ */
+void AssociationWidget::setYEntireAssoc(qreal y)
+{
+    for (int i = 0; i < m_associationLine->count(); ++i) {
+        QPointF p = m_associationLine->point(i);
+        p.setY(y);
+        m_associationLine->setPoint(i, p);
+    }
+}
+
+/**
+ * Moves all the mid points (all expcept start /end) by the given amount.
+ */
+void AssociationWidget::moveMidPointsBy(qreal x, qreal y)
+{
+    int pos = m_associationLine->count() - 1;
+    for (int i = 1; i < (int)pos; ++i) {
+        QPointF p = m_associationLine->point( i );
+        qreal newX = p.x() + x;
+        qreal newY = p.y() + y;
+        p.setX( newX );
+        p.setY( newY );
+        m_associationLine->setPoint( i, p );
+    }
+}
+
+/**
+ * Moves the entire association by the given offset.
+ */
+void AssociationWidget::moveEntireAssoc(qreal x, qreal y)
+{
+    //TODO: ADD SUPPORT FOR ASSOC. ON SEQ. DIAGRAMS WHEN NOTES BACK IN.
+    moveMidPointsBy(x, y);
+    calculateEndingPoints();
+    calculateNameTextSegment();
+    resetTextPositions();
+}
+
+/**
+ * Returns the bounding rectangle of all segments of the association.
+ */
+QRectF AssociationWidget::boundingRect() const
+{
+    return m_associationLine->boundingRect();
+}
+
+/**
+ * Returns the shape of all segments of the association.
+ */
+QPainterPath AssociationWidget::shape() const
+{
+    return m_associationLine->shape();
+}
+
+/**
+ * Connected to UMLClassifier::attributeRemoved() or UMLEntity::constraintRemoved()
+ * in case this AssociationWidget is linked to a clasifier list item
+ * (an attribute or a foreign key constraint)
+ *
+ * @param obj   The UMLClassifierListItem removed.
+ */
+void AssociationWidget::slotClassifierListItemRemoved(UMLClassifierListItem* obj)
+{
+    if (obj != m_umlObject) {
+        DEBUG(DBG_SRC) << "obj=" << obj << ": m_umlObject=" << m_umlObject;
+        return;
+    }
+    m_umlObject = 0;
+    m_scene->removeAssoc(this);
+}
+
+/**
+ * Connected to UMLObject::modified() in case this
+ * AssociationWidget is linked to a classifer's attribute type.
+ */
+void AssociationWidget::slotAttributeChanged()
+{
+    UMLAttribute *attr = attribute();
+    if (attr == NULL) {
+        uError() << "attribute() returns NULL";
+        return;
+    }
+    setVisibility(attr->visibility(), RoleType::B);
+    setRoleName(attr->name(), RoleType::B);
+}
+
+void AssociationWidget::clipSize()
+{
+    if (m_nameWidget)
+        m_nameWidget->clipSize();
+
+    if (m_role[RoleType::A].multiplicityWidget)
+        m_role[RoleType::A].multiplicityWidget->clipSize();
+
+    if (m_role[RoleType::B].multiplicityWidget)
+        m_role[RoleType::B].multiplicityWidget->clipSize();
+
+    if (m_role[RoleType::A].roleWidget)
+        m_role[RoleType::A].roleWidget->clipSize();
+
+    if (m_role[RoleType::B].roleWidget)
+        m_role[RoleType::B].roleWidget->clipSize();
+
+    if (m_role[RoleType::A].changeabilityWidget)
+        m_role[RoleType::A].changeabilityWidget->clipSize();
+
+    if (m_role[RoleType::B].changeabilityWidget)
+        m_role[RoleType::B].changeabilityWidget->clipSize();
+
+    if (m_associationClass)
+        m_associationClass->clipSize();
+}
+
+/**
+ * Event handler for context menu events, called from the line segments.
+ */
+void AssociationWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+    const Uml::AssociationType::Enum type = associationType();
+    ListPopupMenu::MenuType menuType = ListPopupMenu::mt_Association_Selected;
+    if ((type == Uml::AssociationType::Anchor) ||
+            onAssocClassLine(event->scenePos())) {
+        menuType = ListPopupMenu::mt_Anchor;
+    } else if (isCollaboration()) {
+        menuType = ListPopupMenu::mt_Collaboration_Message;
+    } else if (!association()) {
+        menuType = ListPopupMenu::mt_AttributeAssociation;
+    } else if (AssocRules::allowRole(type)) {
+        menuType = ListPopupMenu::mt_FullAssociation;
+    }
+
+    event->accept();
+    DEBUG(DBG_SRC) << "menue type = " << ListPopupMenu::toString(menuType)
+                   << " / association = " << Uml::AssociationType::toString(type);
+
+    UMLScene *scene = umlScene();
+    QWidget *parent = 0;
+    if (scene) {
+        parent = scene->activeView();
+    }
+
+    if (!isSelected() && scene && !scene->selectedItems().isEmpty()) {
+        Qt::KeyboardModifiers forSelection = (Qt::ControlModifier | Qt::ShiftModifier);
+        if ((event->modifiers() & forSelection) == 0) {
+            scene->clearSelection();
+        }
+    }
+    setSelected(true);
+    m_eventScenePos = event->scenePos();
+    ListPopupMenu popup(parent, menuType, this);
+    QAction *triggered = popup.exec(event->screenPos());
+    ListPopupMenu *parentMenu = ListPopupMenu::menuFromAction(triggered);
+
+    if (!parentMenu) {
+        uWarning() << "Action's data field does not contain ListPopupMenu pointer";
+        return;
+    }
+
+    WidgetBase *ownerWidget = parentMenu->ownerWidget();
+    // assert because logic is based on only WidgetBase being the owner of
+    // ListPopupMenu actions executed in this context menu.
+    Q_ASSERT_X(ownerWidget != 0, "AssociationWidget::contextMenuEvent",
+            "ownerWidget is null which means action belonging to UMLView, UMLScene"
+            " or UMLObject is the one triggered in ListPopupMenu");
+
+    ownerWidget->slotMenuSelection(triggered);
+}
+
+/**
+ * Reimplemented event handler for hover enter events.
+ */
+void AssociationWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+    associationLine()->hoverEnterEvent(event);
+}
+
+/**
+ * Reimplemented event handler for hover leave events.
+ */
+void AssociationWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+    associationLine()->hoverLeaveEvent(event);
+}
+
+/**
+ * Reimplemented event handler for hover move events.
+ */
+void AssociationWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+    associationLine()->hoverMoveEvent(event);
+}
+
+/**
+ * Saves this widget to the "assocwidget" XMI element.
+ */
+void AssociationWidget::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
+{
+    QDomElement assocElement = qDoc.createElement(QLatin1String("assocwidget"));
+
+    WidgetBase::saveToXMI(qDoc, assocElement);
+    LinkWidget::saveToXMI(qDoc, assocElement);
+    if (m_umlObject) {
+        assocElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(m_umlObject->id()));
+    }
+    assocElement.setAttribute(QLatin1String("type"), associationType());
+    if (!association()) {
+        assocElement.setAttribute(QLatin1String("visibilityA"), visibility(RoleType::A));
+        assocElement.setAttribute(QLatin1String("visibilityB"), visibility(RoleType::B));
+        assocElement.setAttribute(QLatin1String("changeabilityA"), changeability(RoleType::A));
+        assocElement.setAttribute(QLatin1String("changeabilityB"), changeability(RoleType::B));
+        if (m_umlObject == NULL) {
+            assocElement.setAttribute(QLatin1String("roleAdoc"), roleDocumentation(RoleType::A));
+            assocElement.setAttribute(QLatin1String("roleBdoc"), roleDocumentation(RoleType::B));
+            assocElement.setAttribute(QLatin1String("documentation"), documentation());
+        }
+    }
+    assocElement.setAttribute(QLatin1String("widgetaid"), Uml::ID::toString(widgetIDForRole(RoleType::A)));
+    assocElement.setAttribute(QLatin1String("widgetbid"), Uml::ID::toString(widgetIDForRole(RoleType::B)));
+    assocElement.setAttribute(QLatin1String("indexa"), m_role[RoleType::A].m_nIndex);
+    assocElement.setAttribute(QLatin1String("indexb"), m_role[RoleType::B].m_nIndex);
+    assocElement.setAttribute(QLatin1String("totalcounta"), m_role[RoleType::A].m_nTotalCount);
+    assocElement.setAttribute(QLatin1String("totalcountb"), m_role[RoleType::B].m_nTotalCount);
+    m_associationLine->saveToXMI(qDoc, assocElement);
+
+    if (m_nameWidget) {
+        m_nameWidget->saveToXMI(qDoc, assocElement);
+    }
+
+    if (multiplicityWidget(RoleType::A)) {
+        multiplicityWidget(RoleType::A)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (multiplicityWidget(RoleType::B)) {
+        multiplicityWidget(RoleType::B)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (roleWidget(RoleType::A)) {
+        roleWidget(RoleType::A)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (roleWidget(RoleType::B)) {
+        roleWidget(RoleType::B)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (changeabilityWidget(RoleType::A)) {
+        changeabilityWidget(RoleType::A)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (changeabilityWidget(RoleType::B)) {
+        changeabilityWidget(RoleType::B)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (m_associationClass) {
+        QString acid = Uml::ID::toString(m_associationClass->id());
+        assocElement.setAttribute(QLatin1String("assocclass"), acid);
+        assocElement.setAttribute(QLatin1String("aclsegindex"), m_nLinePathSegmentIndex);
+    }
+
+    qElement.appendChild(assocElement);
+}
+
+/**
+ * Uses the supplied widgetList for resolving
+ * the role A and role B widgets. (The other loadFromXMI() queries
+ * the UMLView for these widgets.)
+ * Required for clipboard operations.
+ */
+bool AssociationWidget::loadFromXMI(QDomElement& qElement,
+                                    const UMLWidgetList& widgets,
+                                    const MessageWidgetList* messages)
+{
+    if (!WidgetBase::loadFromXMI(qElement)) {
+        return false;
+    }
+
+    if (!LinkWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+
+    // load child widgets first
+    QString widgetaid = qElement.attribute(QLatin1String("widgetaid"), QLatin1String("-1"));
+    QString widgetbid = qElement.attribute(QLatin1String("widgetbid"), QLatin1String("-1"));
+    Uml::ID::Type aId = Uml::ID::fromString(widgetaid);
+    Uml::ID::Type bId = Uml::ID::fromString(widgetbid);
+    UMLWidget *pWidgetA = Widget_Utils::findWidget(aId, widgets, messages);
+    if (!pWidgetA) {
+        uError() << "cannot find widget for roleA id " << Uml::ID::toString(aId);
+        return false;
+    }
+    UMLWidget *pWidgetB = Widget_Utils::findWidget(bId, widgets, messages);
+    if (!pWidgetB) {
+        uError() << "cannot find widget for roleB id " << Uml::ID::toString(bId);
+        return false;
+    }
+    setWidgetForRole(pWidgetA, RoleType::A);
+    setWidgetForRole(pWidgetB, RoleType::B);
+
+    QString type = qElement.attribute(QLatin1String("type"), QLatin1String("-1"));
+    Uml::AssociationType::Enum aType = Uml::AssociationType::fromInt(type.toInt());
+
+    QString id = qElement.attribute(QLatin1String("xmi.id"), QLatin1String("-1"));
+    bool oldStyleLoad = false;
+    if (id == QLatin1String("-1")) {
+        // xmi.id not present, ergo either a pure widget association,
+        // or old (pre-1.2) style:
+        // Everything is loaded from the AssociationWidget.
+        // UMLAssociation may or may not be saved - if it is, it's a dummy.
+        // Create the UMLAssociation if both roles are UML objects;
+        // else load the info locally.
+
+        if (Uml::AssociationType::hasUMLRepresentation(aType)) {
+            // lack of an association in our widget AND presence of
+            // both uml objects for each role clearly identifies this
+            // as reading in an old-school file. Note it as such, and
+            // create, and add, the UMLAssociation for this widget.
+            // Remove this special code when backwards compatibility
+            // with older files isn't important anymore. -b.t.
+            UMLObject* umlRoleA = pWidgetA->umlObject();
+            UMLObject* umlRoleB = pWidgetB->umlObject();
+            if (!m_umlObject && umlRoleA && umlRoleB) {
+                oldStyleLoad = true; // flag for further special config below
+                if (aType == AssociationType::Aggregation || aType == AssociationType::Composition) {
+                    uWarning()<<" Old Style save file? swapping roles on association widget"<<this;
+                    // We have to swap the A and B widgets to compensate
+                    // for the long standing bug in AssociationLine of drawing
+                    // the diamond at the wrong end which was fixed
+                    // just before the 1.2 release.
+                    // The logic here is that the user has understood
+                    // that the diamond belongs at the SOURCE end of the
+                    // the association (i.e. at the container, not at the
+                    // contained), and has compensated for this anomaly
+                    // by drawing the aggregations/compositions from
+                    // target to source.
+                    UMLWidget *tmpWidget = pWidgetA;
+                    pWidgetA = pWidgetB;
+                    pWidgetB = tmpWidget;
+                    setWidgetForRole(pWidgetA, RoleType::A);
+                    setWidgetForRole(pWidgetB, RoleType::B);
+                    umlRoleA = pWidgetA->umlObject();
+                    umlRoleB = pWidgetB->umlObject();
+                }
+
+                setUMLAssociation(umlDoc()->createUMLAssociation(umlRoleA, umlRoleB, aType));
+            }
+        }
+
+        setDocumentation(qElement.attribute(QLatin1String("documentation")));
+        setRoleDocumentation(qElement.attribute(QLatin1String("roleAdoc")), RoleType::A);
+        setRoleDocumentation(qElement.attribute(QLatin1String("roleBdoc")), RoleType::B);
+
+        // visibility defaults to Public if it cant set it here..
+        QString visibilityA = qElement.attribute(QLatin1String("visibilityA"), QLatin1String("0"));
+        int vis = visibilityA.toInt();
+        if (vis >= 200) {  // bkwd compat.
+            vis -= 200;
+        }
+        setVisibility((Uml::Visibility::Enum)vis, RoleType::A);
+
+        QString visibilityB = qElement.attribute(QLatin1String("visibilityB"), QLatin1String("0"));
+        vis = visibilityB.toInt();
+        if (vis >= 200) { // bkwd compat.
+            vis -= 200;
+        }
+        setVisibility((Uml::Visibility::Enum)vis, RoleType::B);
+
+        // Changeability defaults to "Changeable" if it cant set it here..
+        QString changeabilityA = qElement.attribute(QLatin1String("changeabilityA"), QLatin1String("0"));
+        if (changeabilityA.toInt() > 0)
+            setChangeability(Uml::Changeability::fromInt(changeabilityA.toInt()), RoleType::A);
+
+        QString changeabilityB = qElement.attribute(QLatin1String("changeabilityB"), QLatin1String("0"));
+        if (changeabilityB.toInt() > 0)
+            setChangeability(Uml::Changeability::fromInt(changeabilityB.toInt()), RoleType::B);
+
+    } else {
+
+        // we should disconnect any prior association (can this happen??)
+        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
+            UMLAssociation *umla = association();
+            umla->disconnect(this);
+            umla->nrof_parent_widgets--;
+        }
+
+        // New style: The xmi.id is a reference to the UMLAssociation.
+        // If the UMLObject is not found right now, we try again later
+        // during the type resolution pass - see activate().
+        m_nId = Uml::ID::fromString(id);
+        UMLObject *myObj = umlDoc()->findObjectById(m_nId);
+        if (myObj) {
+            const UMLObject::ObjectType ot = myObj->baseType();
+            if (ot != UMLObject::ot_Association) {
+                setUMLObject(myObj);
+            } else {
+                UMLAssociation * myAssoc = static_cast<UMLAssociation*>(myObj);
+                setUMLAssociation(myAssoc);
+                if (type == QLatin1String("-1"))
+                    aType = myAssoc->getAssocType();
+            }
+        }
+    }
+
+    setAssociationType(aType);
+
+    QString indexa = qElement.attribute(QLatin1String("indexa"), QLatin1String("0"));
+    QString indexb = qElement.attribute(QLatin1String("indexb"), QLatin1String("0"));
+    QString totalcounta = qElement.attribute(QLatin1String("totalcounta"), QLatin1String("0"));
+    QString totalcountb = qElement.attribute(QLatin1String("totalcountb"), QLatin1String("0"));
+    m_role[RoleType::A].m_nIndex = indexa.toInt();
+    m_role[RoleType::B].m_nIndex = indexb.toInt();
+    m_role[RoleType::A].m_nTotalCount = totalcounta.toInt();
+    m_role[RoleType::B].m_nTotalCount = totalcountb.toInt();
+
+    QString assocclassid = qElement.attribute(QLatin1String("assocclass"));
+    if (! assocclassid.isEmpty()) {
+        Uml::ID::Type acid = Uml::ID::fromString(assocclassid);
+        UMLWidget *w = Widget_Utils::findWidget(acid, widgets);
+        if (w) {
+            ClassifierWidget* aclWidget = static_cast<ClassifierWidget*>(w);
+            QString aclSegIndex = qElement.attribute(QLatin1String("aclsegindex"), QLatin1String("0"));
+            createAssocClassLine(aclWidget, aclSegIndex.toInt());
+        } else {
+            uError() << "cannot find assocclass " << assocclassid;
+        }
+    }
+
+    //now load child elements
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    while (!element.isNull()) {
+        QString tag = element.tagName();
+        if (tag == QLatin1String("linepath")) {
+            if (!m_associationLine->loadFromXMI(element)) {
+                return false;
+            }
+        } else if (tag == QLatin1String("floatingtext") ||
+                   tag == QLatin1String("UML:FloatingTextWidget")) {  // for bkwd compatibility
+            QString r = element.attribute(QLatin1String("role"), QLatin1String("-1"));
+            if (r == QLatin1String("-1"))
+                return false;
+            Uml::TextRole::Enum role = Uml::TextRole::fromInt(r.toInt());
+            FloatingTextWidget *ft = new FloatingTextWidget(m_scene, role, QString(), Uml::ID::Reserved);
+            if (! ft->loadFromXMI(element)) {
+                // Most likely cause: The FloatingTextWidget is empty.
+                delete ft;
+                node = element.nextSibling();
+                element = node.toElement();
+                continue;
+            }
+            // always need this
+            ft->setParentItem(this);
+            ft->setLink(this);
+            ft->setSequenceNumber(m_SequenceNumber);
+            ft->setFontCmd(ft->font());
+
+            switch(role) {
+            case Uml::TextRole::MultiA:
+                m_role[RoleType::A].multiplicityWidget = ft;
+                if (oldStyleLoad)
+                    setMultiplicity(m_role[RoleType::A].multiplicityWidget->text(), RoleType::A);
+                break;
+
+            case Uml::TextRole::MultiB:
+                m_role[RoleType::B].multiplicityWidget = ft;
+                if (oldStyleLoad)
+                    setMultiplicity(m_role[RoleType::B].multiplicityWidget->text(), RoleType::B);
+                break;
+
+            case Uml::TextRole::ChangeA:
+                m_role[RoleType::A].changeabilityWidget = ft;
+                break;
+
+            case Uml::TextRole::ChangeB:
+                m_role[RoleType::B].changeabilityWidget = ft;
+                break;
+
+            case Uml::TextRole::Name:
+                m_nameWidget = ft;
+                if (oldStyleLoad)
+                    setName(m_nameWidget->text());
+                break;
+
+            case Uml::TextRole::Coll_Message:
+            case Uml::TextRole::Coll_Message_Self:
+                m_nameWidget = ft;
+                ft->setLink(this);
+                ft->setActivated();
+                if (FloatingTextWidget::isTextValid(ft->text()))
+                    ft->show();
+                else
+                    ft->hide();
+                break;
+
+            case Uml::TextRole::RoleAName:
+                m_role[RoleType::A].roleWidget = ft;
+                setRoleName(ft->text(), RoleType::A);
+                break;
+            case Uml::TextRole::RoleBName:
+                m_role[RoleType::B].roleWidget = ft;
+                setRoleName(ft->text(), RoleType::B);
+                break;
+            default:
+                DEBUG(DBG_SRC) << "unexpected FloatingTextWidget (TextRole::Enum " << role << ")";
+                delete ft;
+                break;
+            }
+        }
+        node = element.nextSibling();
+        element = node.toElement();
+    }
+
+    return true;
+}
+
+/**
+ * Queries the UMLView for resolving the role A and role B widgets.
+ * ....
+ */
+bool AssociationWidget::loadFromXMI(QDomElement& qElement)
+{
+    UMLScene *scene = umlScene();
+    if (scene) {
+        const UMLWidgetList& widgetList = scene->widgetList();
+        const MessageWidgetList& messageList = scene->messageList();
+        return loadFromXMI(qElement, widgetList, &messageList);
+    }
+    else {
+        DEBUG(DBG_SRC) << "This isn't on UMLScene yet, so can neither fetch"
+            "messages nor widgets on umlscene";
+        return false;
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/associationwidget.h umbrello-15.08.1/umbrello/umlwidgets/associationwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/associationwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/associationwidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,328 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ASSOCIATIONWIDGET_H
+#define ASSOCIATIONWIDGET_H
+
+#include "associationwidgetlist.h"
+#include "linkwidget.h"
+#include "messagewidgetlist.h"
+#include "umlwidgetlist.h"
+#include "widgetbase.h"
+
+class AssociationLine;
+class ClassifierWidget;
+class UMLScene;
+class UMLAssociation;
+class UMLAttribute;
+class UMLClassifierListItem;
+class UMLOperation;
+
+/**
+ * This class represents an association inside a diagram.
+ *
+ * Constructor is made non accessible:
+ * Users shall use the static create() methods for constructing AssociationWidgets.
+ *
+ * Associations exist not only between UML objects. For example, when a Note is
+ * attached to a UML object, the Note itself is not a UML object.
+ * This class supports both kinds of associations. An association where one or
+ * both roles are not a UML object is called a "pure widget association".
+ *
+ * An AssociationWidget where both roles are UML objects has a corresponding
+ * UMLAssociation. The UMLAssociation can be retrieved using the getAssociation
+ * method.
+ * A pure widget association does not have a corresponding UMLAssociation.
+ * The getAssociation method returns NULL in this case.
+ *
+ * @author Gustavo Madrigal
+ * @author Gopala Krishna
+ * @short This class represents an association inside a diagram.
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class AssociationWidget : public WidgetBase, public LinkWidget
+{
+    Q_OBJECT
+public:
+    static AssociationWidget* create(UMLScene *scene);
+    static AssociationWidget* create
+                     (UMLScene *scene, UMLWidget* WidgetA,
+                      Uml::AssociationType::Enum assocType, UMLWidget* WidgetB,
+                      UMLObject *umlobject = NULL);
+
+    virtual ~AssociationWidget();
+
+    virtual void setUMLObject(UMLObject *obj);
+
+    //---------- LinkWidget Interface methods implementation from now on.
+
+    virtual void lwSetFont(QFont font);
+    virtual UMLClassifier *operationOwner();
+
+    virtual UMLOperation *operation();
+    virtual void setOperation(UMLOperation *op);
+
+    virtual QString customOpText();
+    virtual void setCustomOpText(const QString &opText);
+
+    virtual void resetTextPositions();
+
+    virtual void setMessageText(FloatingTextWidget *ft);
+    virtual void setText(FloatingTextWidget *ft, const QString &newText);
+
+    virtual void showPropertiesDialog();
+
+    virtual QString lwOperationText();
+    virtual UMLClassifier *lwClassifier();
+    virtual void setOperationText(const QString &op);
+
+    virtual void constrainTextPos(qreal &textX, qreal &textY,
+                                  qreal textWidth, qreal textHeight,
+                                  Uml::TextRole::Enum tr);
+
+    virtual void calculateNameTextSegment();
+
+    //---------- End LinkWidget Interface methods implementation.
+
+    UMLAssociation* association() const;
+    UMLAttribute* attribute() const;
+
+//    AssociationWidget& operator=(const AssociationWidget& other);
+    bool operator==(const AssociationWidget& other) const;
+    bool operator!=(AssociationWidget& other) const;
+
+    FloatingTextWidget* textWidgetByRole(Uml::TextRole::Enum tr) const;
+
+    FloatingTextWidget* nameWidget() const;
+    QString name() const;
+    void setName(const QString &strRole);
+    void setStereotype(const QString &stereo);
+
+    FloatingTextWidget* roleWidget(Uml::RoleType::Enum role) const;
+    QString roleName(Uml::RoleType::Enum role) const;
+    void setRoleName(const QString &strRole, Uml::RoleType::Enum role);
+
+    QString roleDocumentation(Uml::RoleType::Enum role) const;
+    void setRoleDocumentation(const QString& doc, Uml::RoleType::Enum role);
+
+    FloatingTextWidget* multiplicityWidget(Uml::RoleType::Enum role) const;
+    QString multiplicity(Uml::RoleType::Enum role) const;
+    void setMultiplicity(const QString& text, Uml::RoleType::Enum role);
+
+    Uml::Visibility::Enum visibility(Uml::RoleType::Enum role) const;
+    void setVisibility(Uml::Visibility::Enum value, Uml::RoleType::Enum role);
+
+    FloatingTextWidget* changeabilityWidget(Uml::RoleType::Enum role) const;
+    Uml::Changeability::Enum changeability(Uml::RoleType::Enum role) const;
+    void setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role);
+
+    Uml::ID::Type widgetIDForRole(Uml::RoleType::Enum role) const;
+    Uml::ID::Type widgetLocalIDForRole(Uml::RoleType::Enum role) const;
+    UMLWidget* widgetForRole(Uml::RoleType::Enum role) const;
+    void setWidgetForRole(UMLWidget* widget, Uml::RoleType::Enum role);
+
+    bool setWidgets(UMLWidget* widgetA, Uml::AssociationType::Enum assocType, UMLWidget* widgetB);
+
+    bool containsAsEndpoint(UMLWidget* widget);
+
+    Uml::AssociationType::Enum associationType() const;
+    void setAssociationType(Uml::AssociationType::Enum type);
+
+    bool isCollaboration() const;
+    bool isSelf() const;
+
+    QString toString() const;
+
+    bool isActivated() const;
+    void setActivated(bool active);
+
+    AssociationLine* associationLine() const;
+
+    virtual bool activate();
+    virtual QRectF boundingRect() const;
+    virtual QPainterPath shape() const;
+
+    void widgetMoved(UMLWidget* widget, qreal x, qreal y);
+
+    void saveIdealTextPositions();
+
+    UMLWidget* onWidget(const QPointF &p);
+    bool onAssociation(const QPointF& point);
+    bool onAssocClassLine(const QPointF& point);
+
+    void createAssocClassLine();
+    void createAssocClassLine(ClassifierWidget* classifierWidget,
+                              int linePathSegmentIndex);
+
+    void selectAssocClassLine(bool sel = true);
+    void removeAssocClassLine();
+    void computeAssocClassLine();
+
+    void setXEntireAssoc(qreal x);
+    void setYEntireAssoc(qreal y);
+
+    void moveMidPointsBy(qreal x, qreal y);
+    void moveEntireAssoc(qreal x, qreal y);
+
+    QFont font() const;
+
+    virtual void setTextColor(const QColor &color);
+
+    void calculateEndingPoints();
+
+    void clipSize();
+
+    bool loadFromXMI(QDomElement& qElement, const UMLWidgetList& widgets,
+                     const MessageWidgetList* messages);
+    virtual bool loadFromXMI(QDomElement& qElement);
+    virtual void saveToXMI(QDomDocument &qDoc, QDomElement &qElement);
+
+    void cleanup();
+
+    bool isPointAddable();
+    bool isPointRemovable();
+
+    //:TODO: the following four methods should be protected
+    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+    virtual void setSelected(bool _select);
+public Q_SLOTS:  //:TODO: all virtual?
+    virtual void slotMenuSelection(QAction* action);
+    void slotClassifierListItemRemoved(UMLClassifierListItem* obj);
+    void slotAttributeChanged();
+
+    void syncToModel();
+
+protected:
+    virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+
+    virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+    virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+
+private:
+    QPointF calculateTextPosition(Uml::TextRole::Enum role);
+    void setTextPosition(Uml::TextRole::Enum role);
+    void setTextPositionRelatively(Uml::TextRole::Enum role, const QPointF &oldPosition);
+    void setFloatingText(Uml::TextRole::Enum role, const QString& text, FloatingTextWidget* &ft);
+
+    AssociationWidget(UMLScene *scene);
+
+    void setUMLAssociation(UMLAssociation * assoc);
+
+    void mergeAssociationDataIntoUMLRepresentation();
+
+    static Uml::Region::Enum findPointRegion(const QRectF& rect, const QPointF& pos);
+    static qreal findInterceptOnEdge(const QRectF &rect, Uml::Region::Enum region, const QPointF &point);
+    static QLineF::IntersectType intersect(const QRectF &rect, const QLineF &line,
+                                           QPointF* intersectionPoint);
+
+    void moveEvent(QGraphicsSceneMouseEvent *me);
+
+    Uml::TextRole::Enum calculateNameType(Uml::TextRole::Enum defaultRoleType);
+
+    static QPointF swapXY(const QPointF &p);
+
+    // not used at the moment
+    // static QPointF calculatePointAtDistance(const QPointF &P1, const QPointF &P2, float Distance);
+    // static QPointF calculatePointAtDistanceOnPerpendicular(const QPointF &P1, const QPointF &P2, float Distance);
+    // static float perpendicularProjection(const QPointF& P1, const QPointF& P2, const QPointF& P3, QPointF& ResultingPoint);
+
+    static QPointF midPoint(const QPointF& p0, const QPointF& p1);
+
+    void createPointsSelfAssociation();
+    void updatePointsSelfAssociation();
+    void createPointsException();
+    void updatePointsException();
+
+    /**
+     * The WidgetRole struct gathers all information pertaining to the role.
+     * The AssociationWidget class contains two WidgetRole objects, one for each
+     * side of the association (A and B).
+     */
+    struct WidgetRole {
+
+        FloatingTextWidget* multiplicityWidget;   ///< information regarding multiplicity
+        FloatingTextWidget* changeabilityWidget;  ///< information regarding changeability
+        FloatingTextWidget* roleWidget;           ///< role's label of this association
+
+        UMLWidget* umlWidget;    ///< UMLWidget at this role's side of this association
+
+        Uml::Region::Enum     m_WidgetRegion;   ///< region of this role's widget
+
+        int m_nIndex;        ///< the index of where the line is on the region for this role
+        int m_nTotalCount;   ///< total amount of associations on the region this role's line is on
+
+        // The following items are only used if m_pObject is not set.
+        Uml::Visibility::Enum     visibility;
+        Uml::Changeability::Enum  changeability;
+        QString                   roleDocumentation;
+
+    };
+
+    void updateRegionLineCount(int index, int totalCount,
+                               Uml::Region::Enum region, Uml::RoleType::Enum role);
+
+    void updateAssociations(int totalCount, Uml::Region::Enum region, Uml::RoleType::Enum role);
+
+    int getRegionCount(Uml::Region::Enum region, Uml::RoleType::Enum role);
+
+    void doUpdates(const QPointF &otherP, Uml::RoleType::Enum role);
+
+    void setChangeWidget(const QString &strChangeWidget, Uml::RoleType::Enum role);
+
+    bool checkAddPoint(const QPointF &scenePos);
+    bool checkRemovePoint(const QPointF &scenePos);
+
+    bool linePathStartsAt(const UMLWidget* widget);
+
+    void insertIntoLists(qreal position, const AssociationWidget* assoc);
+
+    qreal m_positions[100];           ///< auxiliary variable for updateAssociations()
+    int m_positions_len;              ///< auxiliary variable for updateAssociations()
+    AssociationWidgetList m_ordered;  ///< auxiliary variable for updateAssociations()
+
+    bool m_activated;   ///< flag which is true if the activate method has been called for this class instance
+
+    /**
+     * When the association has a Role Floating Text this text should move
+     * when the AssociationLine moves but only if the closest segment to the
+     * role text moves.
+     * This segment is:
+     * m_associationLine[m_unNameLineSegment] -- m_associationLine[m_unNameLineSegment+1]
+     */
+    int                 m_unNameLineSegment;
+
+    QPointF m_oldNamePoint;    ///< Position of name floatingtext saved by saveIdealTextPositions()
+    QPointF m_oldMultiAPoint;  ///< Position of role A multiplicity floatingtext saved by saveIdealTextPositions()
+    QPointF m_oldMultiBPoint;  ///< Position of role B multiplicity floatingtext saved by saveIdealTextPositions()
+    QPointF m_oldChangeAPoint; ///< Position of role A changeability floatingtext saved by saveIdealTextPositions()
+    QPointF m_oldChangeBPoint; ///< Position of role B changeability floatingtext saved by saveIdealTextPositions()
+    QPointF m_oldRoleAPoint;   ///< Position of role A name floatingtext saved by saveIdealTextPositions()
+    QPointF m_oldRoleBPoint;   ///< Position of role B name floatingtext saved by saveIdealTextPositions()
+
+    int m_nLinePathSegmentIndex;               ///< anchor for m_pAssocClassLine
+    QGraphicsLineItem *m_pAssocClassLine;      ///< used for connecting assoc. class
+    QGraphicsRectItem *m_pAssocClassLineSel0;  ///< selection decoration for the start point of the assoc. class line
+    QGraphicsRectItem *m_pAssocClassLineSel1;  ///< selection decoration for the end point of the assoc. class line
+
+    AssociationLine *m_associationLine;      ///< the definition points for the association line
+    ClassifierWidget *m_associationClass;    ///< used if we have an assoc. class
+    Uml::AssociationType::Enum m_associationType;  ///< is only used if m_pObject is not set
+    WidgetRole  m_role[2];
+    FloatingTextWidget* m_nameWidget;  ///< displays the name of this association
+    QPointF m_eventScenePos;           ///< holds scene pos of contextMenuEvent()
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/boxwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/boxwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/boxwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/boxwidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,79 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "boxwidget.h"
+
+// app includes
+#include "uml.h"
+#include "umldoc.h"
+
+// qt includes
+#include <QColorDialog>
+
+/**
+ * Constructs a BoxWidget.
+ *
+ * @param scene   The parent to this widget.
+ * @param id      The ID to assign (-1 will prompt a new ID.)
+ * @param type    The WidgetType (wt_Box.)
+ */
+BoxWidget::BoxWidget(UMLScene * scene, Uml::ID::Type id, WidgetType type)
+  : UMLWidget(scene, type, id)
+{
+    setSize(100, 80);
+    m_usesDiagramLineColor = false;  // boxes be black
+    m_lineColor = QColor("black");
+    setZValue(-10);
+}
+
+/**
+ * Destructor.
+ */
+BoxWidget::~BoxWidget()
+{
+}
+
+/**
+ * Draws a rectangle.
+ */
+void BoxWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+    setPenFromSettings(painter);
+    painter->drawRect(0, 0, width(), height());
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Saves the widget to the "boxwidget" XMI element.
+ * Note: For loading from XMI, the inherited parent method is used.
+ */
+void BoxWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement boxElement = qDoc.createElement(QLatin1String("boxwidget"));
+    UMLWidget::saveToXMI(qDoc, boxElement);
+    qElement.appendChild(boxElement);
+}
+
+/**
+ * Show a properties dialog for a BoxWidget.
+ */
+void BoxWidget::showPropertiesDialog()
+{
+    QColor newColor = QColorDialog::getColor(lineColor()); // krazy:exclude=qclasses
+    if (newColor != lineColor()) {
+        setLineColor(newColor);
+        setUsesDiagramLineColor(false);
+        umlDoc()->setModified(true);
+    }
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/boxwidget.h umbrello-15.08.1/umbrello/umlwidgets/boxwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/boxwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/boxwidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,39 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef BOXWIDGET_H
+#define BOXWIDGET_H
+
+//app includes
+#include "umlwidget.h"
+
+/**
+ * Displays a rectangular box.
+ * These widgets are diagram specific.  They will still need a unique id
+ * from the @ref UMLDoc class for deletion and other purposes.
+ *
+ * @short Displays a box.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class BoxWidget : public UMLWidget
+{
+public:
+    explicit BoxWidget(UMLScene * scene, Uml::ID::Type id = Uml::ID::None, WidgetType type = WidgetBase::wt_Box);
+    virtual ~BoxWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    virtual void showPropertiesDialog();
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/categorywidget.cpp umbrello-15.08.1/umbrello/umlwidgets/categorywidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/categorywidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/categorywidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,148 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header file
+#include "categorywidget.h"
+
+// local includes
+#include "category.h"
+#include "debug_utils.h"
+#include "umlview.h"
+#include "listpopupmenu.h"
+
+// qt includes
+#include <QPainter>
+
+/**
+ *  Creates a Category widget.
+ *
+ *  @param  scene  The parent of the widget.
+ *  @param  o      The UMLCategory to represent.
+ */
+CategoryWidget::CategoryWidget(UMLScene * scene, UMLCategory *o)
+  : UMLWidget(scene, WidgetBase::wt_Category, o)
+{
+    m_fixedAspectRatio = true;
+}
+
+/**
+ * Destructor.
+ */
+CategoryWidget::~CategoryWidget()
+{
+}
+
+/**
+ *   Overrides the standard paint event.
+ */
+void CategoryWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    UMLWidget::setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    QFont font = UMLWidget::font();
+    font.setUnderline(false);
+    font.setBold(false);
+    font.setItalic(m_umlObject->isAbstract());
+    painter->setFont(font);
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    // the height is our radius
+    const int h = height();
+    const int w = width();
+    const int r = h > w ? h : w;
+
+    //int middleX = w / 2;
+    const int textStartY = (r / 2) - (fontHeight / 2);
+
+    // draw a circle
+    painter->drawEllipse(0, 0, r, r);
+    painter->setPen(textColor());
+
+    QString letterType(QLatin1Char('D'));
+    switch(static_cast<UMLCategory*>(m_umlObject)->getType()) {
+       case UMLCategory::ct_Disjoint_Specialisation:
+           letterType = QLatin1Char('D');
+           break;
+       case UMLCategory::ct_Overlapping_Specialisation:
+           letterType = QLatin1Char('O');
+           break;
+       case UMLCategory::ct_Union:
+           letterType = QLatin1Char('U');
+           break;
+       default:
+           break;
+    }
+
+    painter->drawText(UC_MARGIN, textStartY, r - UC_MARGIN * 2, fontHeight, Qt::AlignCenter, letterType);
+    UMLWidget::setPenFromSettings(painter);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF CategoryWidget::minimumSize() const
+{
+    const UMLWidget::FontType ft = (m_umlObject->isAbstract() ? FT_BOLD_ITALIC : FT_BOLD);
+    const QFontMetrics &fm = UMLWidget::getFontMetrics(ft);
+    const int fontHeight = fm.lineSpacing();
+    int radius = UC_RADIUS + fontHeight + UC_MARGIN;
+
+    return QSizeF(radius, radius);
+}
+
+/**
+ * Saves this Category to file.
+ */
+void CategoryWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement categoryElement = qDoc.createElement(QLatin1String("categorywidget"));
+    UMLWidget::saveToXMI(qDoc, categoryElement);
+    qElement.appendChild(categoryElement);
+}
+
+/**
+ * Will be called when a menu selection has been made from the
+ * popup menu.
+ *
+ * @param action    The action that has been selected.
+ */
+void CategoryWidget::slotMenuSelection(QAction* action)
+{
+    UMLCategory* catObj = static_cast<UMLCategory*>(umlObject());
+    if (!catObj) {
+        uWarning() << "No UMLCategory for this widget.";
+        return;
+    }
+
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+      case ListPopupMenu::mt_DisjointSpecialisation:
+          catObj->setType(UMLCategory::ct_Disjoint_Specialisation);
+          break;
+
+      case ListPopupMenu::mt_OverlappingSpecialisation:
+          catObj->setType(UMLCategory::ct_Overlapping_Specialisation);
+          break;
+
+      case ListPopupMenu::mt_Union:
+          catObj->setType(UMLCategory::ct_Union);
+          break;
+
+      default:
+          UMLWidget::slotMenuSelection(action);
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/categorywidget.h umbrello-15.08.1/umbrello/umlwidgets/categorywidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/categorywidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/categorywidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,56 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef CATEGORYWIDGET_H
+#define CATEGORYWIDGET_H
+
+#include "umlwidget.h"
+
+#define UC_MARGIN 5
+#define UC_RADIUS 30
+
+class UMLCategory;
+
+/**
+ * This class is the graphical version of a UMLCategory.  A CategoryWidget is created
+ * by a @ref UMLView.  An CategoryWidget belongs to only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
+ *
+ * If the Category class that this CategoryWidget is displaying is deleted, the @ref UMLView will
+ * make sure that this instance is also deleted.
+ *
+ * The CategoryWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @short  A graphical version of a UMLCategory.
+ * @author Sharan Rao
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class CategoryWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    CategoryWidget(UMLScene * scene, UMLCategory *o);
+    virtual ~CategoryWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+    // For loading we can use the loadFromXMI() inherited from UMLWidget.
+
+protected:
+    QSizeF minimumSize() const;
+
+public slots:
+    void slotMenuSelection(QAction* action);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/classifierwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/classifierwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/classifierwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/classifierwidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,1426 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "classifierwidget.h"
+
+// app includes
+#include "floatingtextwidget.h"
+#include "associationwidget.h"
+#include "associationline.h"
+#include "classifier.h"
+#include "cmds.h"
+#include "debug_utils.h"
+#include "listpopupmenu.h"
+#include "object_factory.h"
+#include "operation.h"
+#include "template.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlview.h"
+
+#define PACKAGE_MARGIN 5
+
+// qt includes
+#include <QPainter>
+
+DEBUG_REGISTER_DISABLED(ClassifierWidget)
+
+const int ClassifierWidget::MARGIN = 5;
+const int ClassifierWidget::CIRCLE_SIZE = 30;
+const int ClassifierWidget::SOCKET_INCREMENT = 10;
+
+/**
+ * Constructs a ClassifierWidget.
+ *
+ * @param scene   The parent of this ClassifierWidget.
+ * @param c       The UMLClassifier to represent.
+ */
+ClassifierWidget::ClassifierWidget(UMLScene * scene, UMLClassifier *c)
+  : UMLWidget(scene, WidgetBase::wt_Class, c),
+    m_pAssocWidget(0), m_pInterfaceName(0)
+{
+    const Settings::OptionState& ops = m_scene->optionState();
+    setVisualPropertyCmd(ShowVisibility, ops.classState.showVisibility);
+    setVisualPropertyCmd(ShowOperations, ops.classState.showOps);
+    setVisualPropertyCmd(ShowPublicOnly, ops.classState.showPublicOnly);
+    setVisualPropertyCmd(ShowPackage,    ops.classState.showPackage);
+    m_attributeSignature = Uml::SignatureType::ShowSig;
+    /*:TODO:
+    setVisualProperty(ShowOperationSignature, ops.classState.showOpSig);
+      Cannot do that because we get "pure virtual method called". Open code:
+     */
+    if(!ops.classState.showOpSig) {
+        if (visualProperty(ShowVisibility))
+            m_operationSignature = Uml::SignatureType::NoSig;
+        else
+            m_operationSignature = Uml::SignatureType::NoSigNoVis;
+
+    } else if (visualProperty(ShowVisibility))
+        m_operationSignature = Uml::SignatureType::ShowSig;
+    else
+        m_operationSignature = Uml::SignatureType::SigNoVis;
+
+    setVisualPropertyCmd(ShowAttributes, ops.classState.showAtts);
+    setVisualPropertyCmd(ShowStereotype, ops.classState.showStereoType);
+    setVisualPropertyCmd(DrawAsCircle, false);
+
+    setShowAttSigs(ops.classState.showAttSig);
+
+    if (c && c->isInterface()) {
+        m_baseType = WidgetBase::wt_Interface;
+        m_visualProperties = ShowOperations | ShowVisibility | ShowStereotype;
+        setShowStereotype(true);
+        updateSignatureTypes();
+    }
+}
+
+/**
+ * Constructs a ClassifierWidget.
+ *
+ * @param scene   The parent of this ClassifierWidget.
+ * @param c       The UMLClassifier to represent.
+ */
+ClassifierWidget::ClassifierWidget(UMLScene * scene, UMLPackage *o)
+  : UMLWidget(scene, WidgetBase::wt_Package, o),
+    m_pAssocWidget(0),
+    m_pInterfaceName(0)
+{
+    const Settings::OptionState& ops = m_scene->optionState();
+    setVisualPropertyCmd(ShowVisibility, ops.classState.showVisibility);
+    setVisualPropertyCmd(ShowOperations, ops.classState.showOps);
+    setVisualPropertyCmd(ShowPublicOnly, ops.classState.showPublicOnly);
+    setVisualPropertyCmd(ShowPackage,    ops.classState.showPackage);
+    m_attributeSignature = Uml::SignatureType::ShowSig;
+
+    if(!ops.classState.showOpSig) {
+        if (visualProperty(ShowVisibility))
+            m_operationSignature = Uml::SignatureType::NoSig;
+        else
+            m_operationSignature = Uml::SignatureType::NoSigNoVis;
+
+    } else if (visualProperty(ShowVisibility))
+        m_operationSignature = Uml::SignatureType::ShowSig;
+    else
+        m_operationSignature = Uml::SignatureType::SigNoVis;
+
+    setVisualPropertyCmd(ShowAttributes, ops.classState.showAtts);
+    setVisualPropertyCmd(ShowStereotype, ops.classState.showStereoType);
+    setVisualPropertyCmd(DrawAsPackage, true);
+
+    setShowAttSigs(ops.classState.showAttSig);
+}
+
+/**
+ * Destructor.
+ */
+ClassifierWidget::~ClassifierWidget()
+{
+    if (m_pAssocWidget)
+        m_pAssocWidget->removeAssocClassLine();
+    if (m_pInterfaceName) {
+        delete m_pInterfaceName;
+        m_pInterfaceName = 0;
+    }
+}
+
+/**
+ * Return the UMLClassifier which this ClassifierWidget
+ * represents.
+ */
+UMLClassifier *ClassifierWidget::classifier() const
+{
+    return dynamic_cast<UMLClassifier*>(m_umlObject);
+}
+
+/**
+ * @return the visual properties
+ */
+ClassifierWidget::VisualProperties ClassifierWidget::visualProperties() const
+{
+    return m_visualProperties;
+}
+
+/**
+ * Set an OR combination of properties stored in \a properties on this
+ * widget.
+ */
+void ClassifierWidget::setVisualProperties(VisualProperties properties)
+{
+    // Don't do anything if the argument is equal to current status.
+    if (quint32(m_visualProperties) == quint32(properties)) {
+        return;
+    }
+
+    m_visualProperties = properties;
+    updateSignatureTypes();
+}
+
+/**
+ * @return The status of the property passed in.
+ *
+ * @note Use @ref attributeSignature() and @ref
+ *       operationSignature() to get signature status.  This
+ *       method only indicates whether signature is visible or not.
+ */
+bool ClassifierWidget::visualProperty(VisualProperty property) const
+{
+    if (property == ShowAttributeSignature) {
+        return (m_attributeSignature == Uml::SignatureType::ShowSig
+                || m_attributeSignature == Uml::SignatureType::SigNoVis);
+    }
+
+    else if(property == ShowOperationSignature) {
+        return (m_operationSignature == Uml::SignatureType::ShowSig
+                || m_operationSignature == Uml::SignatureType::SigNoVis);
+    }
+
+    return m_visualProperties.testFlag(property);
+}
+
+/**
+ * A convenient method to set and reset individual VisualProperty
+ *
+ * Undo command.
+ *
+ * @param property The property to be set/reset.
+ * @param enable   True/false to set/reset. (default = true)
+ *
+ * @note This method handles ShowAttributeSignature and
+ *       ShowOperationSignature specially.
+ */
+void ClassifierWidget::setVisualProperty(VisualProperty property, bool enable)
+{
+    if (visualProperty(property) != enable) {
+        UMLApp::app()->executeCommand(new Uml::CmdChangeVisualProperty(this, property, enable));
+    }
+}
+
+/**
+ * A convenient method to set and reset individual VisualProperty
+ *
+ * @param property The property to be set/reset.
+ * @param enable   True/false to set/reset. (default = true)
+ *
+ * @note This method handles ShowAttributeSignature and
+ *       ShowOperationSignature specially.
+ */
+void ClassifierWidget::setVisualPropertyCmd(VisualProperty property, bool enable)
+{
+    // Handle ShowAttributeSignature and ShowOperationSignature
+    // specially.
+
+    if (property == ShowAttributeSignature) {
+        if (!enable) {
+            m_attributeSignature = visualProperty(ShowVisibility) ?
+                Uml::SignatureType::NoSig : Uml::SignatureType::NoSigNoVis;
+        } else {
+            m_attributeSignature = visualProperty(ShowVisibility) ?
+                Uml::SignatureType::ShowSig : Uml::SignatureType::SigNoVis;
+        }
+        //:TODO: updateTextItemGroups();
+        updateSignatureTypes();
+    }
+
+    else if (property == ShowOperationSignature) {
+        if (!enable) {
+            m_operationSignature = visualProperty(ShowVisibility) ?
+                Uml::SignatureType::NoSig : Uml::SignatureType::NoSigNoVis;
+        } else {
+            m_operationSignature = visualProperty(ShowVisibility) ?
+                Uml::SignatureType::ShowSig : Uml::SignatureType::SigNoVis;
+        }
+        //:TODO: updateTextItemGroups();
+        updateSignatureTypes();
+    }
+
+    else if (property == ShowStereotype) {
+        // Now just update flag and use base method for actual work.
+        if (enable) {
+            m_visualProperties |= property;
+        } else {
+            m_visualProperties &= ~property;
+        }
+        setShowStereotype(enable);
+    }
+
+    else if (property == DrawAsCircle) {
+        // Don't do anything if the flag status is same.
+        if (visualProperty(property) == enable)
+            return;
+        if (enable) {
+            m_visualProperties |= property;
+        } else {
+            m_visualProperties &= ~property;
+        }
+        setDrawAsCircle(enable);
+    }
+
+    // Some other flag.
+    else {
+        // Don't do anything if the flag status is same.
+        if (visualProperty(property) == enable) {
+            return;
+        }
+
+        // Call setVisualProperties appropriately based on enbable.
+        if (enable) {
+            setVisualProperties(visualProperties() | property);
+        } else {
+            setVisualProperties(visualProperties() & ~property);
+        }
+    }
+}
+
+/**
+ * A convenient method to toggle individual VisualProperty of this
+ * widget.
+ *
+ * @param property The property to be toggled.
+ *
+ * @note This method handles ShowAttributeSignature and
+ *       ShowOperationSignature specially.
+ */
+void ClassifierWidget::toggleVisualProperty(VisualProperty property)
+{
+    bool oppositeStatus;
+    if (property == ShowOperationSignature) {
+        oppositeStatus = !(m_operationSignature == Uml::SignatureType::ShowSig
+                           || m_operationSignature == Uml::SignatureType::SigNoVis);
+    }
+    else if (property == ShowAttributeSignature) {
+        oppositeStatus = !(m_attributeSignature == Uml::SignatureType::ShowSig
+                           || m_attributeSignature == Uml::SignatureType::SigNoVis);
+    }
+    else {
+        oppositeStatus = !visualProperty(property);
+    }
+
+    DEBUG(DBG_SRC) << "VisualProperty: " << property << " to opposite status " << oppositeStatus;
+    setVisualProperty(property, oppositeStatus);
+}
+
+/**
+ * Updates m_operationSignature to match m_showVisibility.
+ */
+void ClassifierWidget::updateSignatureTypes()
+{
+    //turn on scope
+    if (visualProperty(ShowVisibility)) {
+        if (m_operationSignature == Uml::SignatureType::NoSigNoVis) {
+            m_operationSignature = Uml::SignatureType::NoSig;
+        } else if (m_operationSignature == Uml::SignatureType::SigNoVis) {
+            m_operationSignature = Uml::SignatureType::ShowSig;
+        }
+    }
+    //turn off scope
+    else {
+        if (m_operationSignature == Uml::SignatureType::ShowSig) {
+            m_operationSignature = Uml::SignatureType::SigNoVis;
+        } else if (m_operationSignature == Uml::SignatureType::NoSig) {
+            m_operationSignature = Uml::SignatureType::NoSigNoVis;
+        }
+    }
+    if (visualProperty(ShowVisibility)) {
+        if (m_attributeSignature == Uml::SignatureType::NoSigNoVis)
+            m_attributeSignature = Uml::SignatureType::NoSig;
+        else if (m_attributeSignature == Uml::SignatureType::SigNoVis)
+            m_attributeSignature = Uml::SignatureType::ShowSig;
+    } else {
+        if (m_attributeSignature == Uml::SignatureType::ShowSig)
+            m_attributeSignature = Uml::SignatureType::SigNoVis;
+        else if(m_attributeSignature == Uml::SignatureType::NoSig)
+            m_attributeSignature = Uml::SignatureType::NoSigNoVis;
+    }
+    updateGeometry();
+    update();
+}
+
+/**
+ * Returns whether to show attribute signatures.
+ * Only applies when m_umlObject->getBaseType() is ot_Class.
+ *
+ * @return  Status of how attribute signatures are shown.
+ */
+Uml::SignatureType::Enum ClassifierWidget::attributeSignature() const
+{
+    return m_attributeSignature;
+}
+
+/**
+ * Sets the type of signature to display for an attribute.
+ * Only applies when m_umlObject->getBaseType() is ot_Class.
+ *
+ * @param sig   Type of signature to display for an attribute.
+ */
+void ClassifierWidget::setAttributeSignature(Uml::SignatureType::Enum sig)
+{
+    m_attributeSignature = sig;
+    updateSignatureTypes();
+    updateGeometry();
+    update();
+}
+
+/**
+ * @return The Uml::SignatureType::Enum value for the operations.
+ */
+Uml::SignatureType::Enum ClassifierWidget::operationSignature() const
+{
+    return m_operationSignature;
+}
+
+/**
+ * Set the type of signature to display for an Operation
+ *
+ * @param sig   Type of signature to display for an operation.
+ */
+void ClassifierWidget::setOperationSignature(Uml::SignatureType::Enum sig)
+{
+    m_operationSignature = sig;
+    updateSignatureTypes();
+    updateGeometry();
+    update();
+}
+
+/**
+ * Sets whether to show attribute signature
+ * Only applies when m_umlObject->getBaseType() is ot_Class.
+ *
+ * @param _status  True if attribute signatures shall be shown.
+ */
+void ClassifierWidget::setShowAttSigs(bool _status)
+{
+    if(!_status) {
+        if (visualProperty(ShowVisibility))
+            m_attributeSignature = Uml::SignatureType::NoSig;
+        else
+            m_attributeSignature = Uml::SignatureType::NoSigNoVis;
+    }
+    else if (visualProperty(ShowVisibility))
+        m_attributeSignature = Uml::SignatureType::ShowSig;
+    else
+        m_attributeSignature = Uml::SignatureType::SigNoVis;
+    if (UMLApp::app()->document()->loading())
+        return;
+    updateGeometry();
+    update();
+}
+
+/**
+ * Toggles whether to show attribute signatures.
+ * Only applies when m_umlObject->getBaseType() is ot_Class.
+ */
+void ClassifierWidget::toggleShowAttSigs()
+{
+    if (m_attributeSignature == Uml::SignatureType::ShowSig ||
+            m_attributeSignature == Uml::SignatureType::SigNoVis) {
+        if (visualProperty(ShowVisibility)) {
+            m_attributeSignature = Uml::SignatureType::NoSig;
+        } else {
+            m_attributeSignature = Uml::SignatureType::NoSigNoVis;
+        }
+    } else if (visualProperty(ShowVisibility)) {
+        m_attributeSignature = Uml::SignatureType::ShowSig;
+    } else {
+        m_attributeSignature = Uml::SignatureType::SigNoVis;
+    }
+    updateGeometry();
+    update();
+}
+
+/**
+ * Return the number of displayed members of the given ObjectType.
+ * Takes into consideration m_showPublicOnly but not other settings.
+ */
+int ClassifierWidget::displayedMembers(UMLObject::ObjectType ot) const
+{
+    int count = 0;
+    UMLClassifier *umlc = this->classifier();
+    if (!umlc)
+        return count;
+    UMLClassifierListItemList list = umlc->getFilteredList(ot);
+    foreach (UMLClassifierListItem *m, list) {
+      if (!(visualProperty(ShowPublicOnly) && m->visibility() != Uml::Visibility::Public))
+            count++;
+    }
+    return count;
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF ClassifierWidget::minimumSize() const
+{
+    return calculateSize();
+}
+
+/**
+ * Calculate content related size of widget.
+ * Overrides method from UMLWidget.
+ */
+QSizeF ClassifierWidget::calculateSize(bool withExtensions /* = true */) const
+{
+    if (!m_umlObject) {
+        return UMLWidget::minimumSize();
+    }
+    if (m_umlObject->baseType() == UMLObject::ot_Package) {
+        return calculateAsPackageSize();
+    }
+    UMLClassifier *umlc = this->classifier();
+    if (!umlc) {
+        uError() << "Internal error - classifier() returns NULL";
+        return UMLWidget::minimumSize();
+    }
+    if (umlc->isInterface() && visualProperty(DrawAsCircle)) {
+        return calculateAsCircleSize();
+    }
+
+    const bool showNameOnly = !visualProperty(ShowAttributes) &&
+                              !visualProperty(ShowOperations) &&
+                              !visualProperty(ShowDocumentation);
+
+    const QFontMetrics &fm = getFontMetrics(UMLWidget::FT_NORMAL);
+    const int fontHeight = fm.lineSpacing();
+    // width is the width of the longest 'word'
+    int width = 0, height = 0;
+    // consider stereotype
+    if (visualProperty(ShowStereotype) && !m_umlObject->stereotype().isEmpty()) {
+        height += fontHeight;
+        // ... width
+        const QFontMetrics &bfm = UMLWidget::getFontMetrics(UMLWidget::FT_BOLD);
+        const int stereoWidth = bfm.size(0, m_umlObject->stereotype(true)).width();
+        if (stereoWidth > width)
+            width = stereoWidth;
+    } else if (showNameOnly) {
+        height += MARGIN;
+    }
+
+    // consider name
+    height += fontHeight;
+    // ... width
+    QString displayedName;
+    if (visualProperty(ShowPackage))
+        displayedName = m_umlObject->fullyQualifiedName();
+    else
+        displayedName = m_umlObject->name();
+    const UMLWidget::FontType nft = (m_umlObject->isAbstract() ? FT_BOLD_ITALIC : FT_BOLD);
+    const int nameWidth = UMLWidget::getFontMetrics(nft).size(0, displayedName).width();
+    if (nameWidth > width)
+        width = nameWidth;
+
+#ifdef ENABLE_WIDGET_SHOW_DOC
+    // consider documentation
+    if (visualProperty(ShowDocumentation)) {
+        if (!documentation().isEmpty()) {
+            QRect brect = fm.boundingRect(QRect(0, 0, this->width()-2*MARGIN, this->height()-height), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, documentation());
+            height += brect.height();
+            if (!visualProperty(ShowOperations) && !visualProperty(ShowAttributes)) {
+                if (brect.width() >= width)
+                    width = brect.width();
+            }
+        }
+        else
+            height += fontHeight / 2;
+    }
+#endif
+
+    // consider attributes
+    if (visualProperty(ShowAttributes)) {
+        const int numAtts = displayedAttributes();
+        if (numAtts > 0) {
+            height += fontHeight * numAtts;
+            // calculate width of the attributes
+            UMLClassifierListItemList list = umlc->getFilteredList(UMLObject::ot_Attribute);
+            foreach (UMLClassifierListItem *a, list) {
+                if (visualProperty(ShowPublicOnly) && a->visibility() != Uml::Visibility::Public)
+                    continue;
+                const int attWidth = fm.size(0, a->toString(m_attributeSignature)).width();
+                if (attWidth > width)
+                    width = attWidth;
+            }
+        }
+        else
+            height += fontHeight / 2;
+    }
+
+    // consider operations
+    if (visualProperty(ShowOperations)) {
+        const int numOps = displayedOperations();
+        if (numOps > 0) {
+            height += numOps * fontHeight;
+            // ... width
+            UMLOperationList list(umlc->getOpList());
+            foreach (UMLOperation* op,  list) {
+                      if (visualProperty(ShowPublicOnly) && op->visibility() != Uml::Visibility::Public)
+                    continue;
+                const QString displayedOp = op->toString(m_operationSignature);
+                UMLWidget::FontType oft;
+                oft = (op->isAbstract() ? UMLWidget::FT_ITALIC : UMLWidget::FT_NORMAL);
+                const int w = UMLWidget::getFontMetrics(oft).size(0, displayedOp).width();
+                if (w > width)
+                    width = w;
+            }
+        }
+        else
+            height += fontHeight / 2;
+    }
+
+    if (withExtensions) {
+        // consider template box _as last_ !
+        QSize templatesBoxSize = calculateTemplatesBoxSize();
+        if (templatesBoxSize.width() != 0) {
+            // add width to largest 'word'
+            width += templatesBoxSize.width() / 2;
+        }
+        if (templatesBoxSize.height() != 0) {
+            height += templatesBoxSize.height() - MARGIN;
+        }
+    }
+
+    // allow for height margin
+    if (showNameOnly) {
+        height += MARGIN;
+    }
+
+    // allow for width margin
+    width += MARGIN * 2;
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Calculcates the size of the templates box in the top left
+ * if it exists, returns QSize(0, 0) if it doesn't.
+ *
+ * @return  QSize of the templates flap.
+ */
+QSize ClassifierWidget::calculateTemplatesBoxSize() const
+{
+    if (!classifier())
+        return QSize(0, 0);
+    UMLTemplateList list = classifier()->getTemplateList();
+    int count = list.count();
+    if (count == 0) {
+        return QSize(0, 0);
+    }
+
+    QFont font = UMLWidget::font();
+    font.setItalic(false);
+    font.setUnderline(false);
+    font.setBold(false);
+    const QFontMetrics fm(font);
+
+    int width = 0;
+    int height = count * fm.lineSpacing() + (MARGIN*2);
+
+    foreach (UMLTemplate *t, list) {
+        int textWidth = fm.size(0, t->toString()).width();
+        if (textWidth > width)
+            width = textWidth;
+    }
+
+    width += (MARGIN*2);
+    return QSize(width, height);
+}
+
+/**
+ * Return the number of displayed attributes.
+ */
+int ClassifierWidget::displayedAttributes() const
+{
+    if (!visualProperty(ShowAttributes))
+        return 0;
+    return displayedMembers(UMLObject::ot_Attribute);
+}
+
+/**
+ * Return the number of displayed operations.
+ */
+int ClassifierWidget::displayedOperations() const
+{
+    if (!visualProperty(ShowOperations))
+        return 0;
+    return displayedMembers(UMLObject::ot_Operation);
+}
+
+/**
+ * Set the AssociationWidget when this ClassWidget acts as
+ * an association class.
+ */
+void ClassifierWidget::setClassAssociationWidget(AssociationWidget *assocwidget)
+{
+    if (!classifier()) {
+        uError() << "Class association cannot be applied to package";
+        return;
+    }
+    m_pAssocWidget = assocwidget;
+    UMLAssociation *umlassoc = NULL;
+    if (assocwidget)
+        umlassoc = assocwidget->association();
+    classifier()->setClassAssoc(umlassoc);
+}
+
+/**
+ * Return the AssociationWidget when this classifier acts as
+ * an association class (else return NULL.)
+ */
+AssociationWidget *ClassifierWidget::classAssociationWidget() const
+{
+    return m_pAssocWidget;
+}
+
+/**
+ * Overrides standard method.
+ * Auxiliary to reimplementations in the derived classes.
+ */
+void ClassifierWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    else {
+        painter->setBrush(m_scene->backgroundColor());
+    }
+    if (m_umlObject->baseType() == UMLObject::ot_Package) {
+        drawAsPackage(painter, option);
+        UMLWidget::paint(painter, option, widget);
+        return;
+    }
+    UMLClassifier *umlc = this->classifier();
+    if (!umlc) {
+        uError() << "Internal error - classifier() returns NULL";
+        return;
+    }
+    if (umlc->isInterface() && visualProperty(DrawAsCircle)) {
+        drawAsCircle(painter, option);
+        UMLWidget::paint(painter, option, widget);
+        return;
+    }
+
+    // Draw the bounding rectangle
+    QSize templatesBoxSize = calculateTemplatesBoxSize();
+    int bodyOffsetY = 0;
+    if (templatesBoxSize.height() > 0)
+        bodyOffsetY += templatesBoxSize.height() - MARGIN;
+    int w = width();
+    if (templatesBoxSize.width() > 0)
+        w -= templatesBoxSize.width() / 2;
+    int h = height();
+    if (templatesBoxSize.height() > 0)
+        h -= templatesBoxSize.height() - MARGIN;
+    painter->drawRect(0, bodyOffsetY, w, h);
+
+    QFont font = UMLWidget::font();
+    font.setUnderline(false);
+    font.setItalic(false);
+    const QFontMetrics &fm = UMLWidget::getFontMetrics(UMLWidget::FT_NORMAL);
+    const int fontHeight = fm.lineSpacing();
+
+    //If there are any templates then draw them
+    UMLTemplateList tlist = umlc->getTemplateList();
+    if (tlist.count() > 0) {
+        setPenFromSettings(painter);
+        QPen pen = painter->pen();
+        pen.setStyle(Qt::DotLine);
+        painter->setPen(pen);
+        painter->drawRect(width() - templatesBoxSize.width(), 0,
+                    templatesBoxSize.width(), templatesBoxSize.height());
+        painter->setPen(QPen(textColor()));
+        font.setBold(false);
+        painter->setFont(font);
+        const int x = width() - templatesBoxSize.width() + MARGIN;
+        int y = MARGIN;
+        foreach (UMLTemplate *t, tlist) {
+            QString text = t->toString();
+            painter->drawText(x, y, fm.size(0, text).width(), fontHeight, Qt::AlignVCenter, text);
+            y += fontHeight;
+        }
+    }
+
+    const int textX = MARGIN;
+    const int textWidth = w - MARGIN * 2;
+
+    painter->setPen(QPen(textColor()));
+
+    // draw stereotype
+    font.setBold(true);
+    const bool showNameOnly = !visualProperty(ShowAttributes) &&
+                              !visualProperty(ShowOperations) &&
+                              !visualProperty(ShowDocumentation);
+
+    int nameHeight = fontHeight;
+    if (visualProperty(ShowStereotype) && !m_umlObject->stereotype().isEmpty()) {
+        painter->setFont(font);
+        painter->drawText(textX, bodyOffsetY, textWidth, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true));
+        bodyOffsetY += fontHeight;
+    } else if (showNameOnly) {
+        nameHeight = h;
+    }
+
+    // draw name
+    QString name;
+    if (visualProperty(ShowPackage)) {
+        name = m_umlObject->fullyQualifiedName();
+    } else {
+        name = this->name();
+    }
+    font.setItalic(m_umlObject->isAbstract());
+    painter->setFont(font);
+    painter->drawText(textX, bodyOffsetY, textWidth, nameHeight, Qt::AlignCenter, name);
+    bodyOffsetY += fontHeight;
+    font.setBold(false);
+    font.setItalic(false);
+    painter->setFont(font);
+
+#ifdef ENABLE_WIDGET_SHOW_DOC
+    // draw documentation
+    if (visualProperty(ShowDocumentation)) {
+        setPenFromSettings(painter);
+        painter->drawLine(0, bodyOffsetY, w, bodyOffsetY);
+        painter->setPen(textColor());
+
+        if (!documentation().isEmpty()) {
+            QRect brect = fm.boundingRect(QRect(0, 0, w-2*MARGIN, h-bodyOffsetY), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, documentation());
+            if (brect.width() > width() + 2*MARGIN)
+                brect.setWidth(width()-2*MARGIN);
+            brect.adjust(textX, bodyOffsetY, textX, bodyOffsetY);
+            painter->drawText(brect, Qt::AlignCenter | Qt::TextWordWrap, documentation());
+            bodyOffsetY += brect.height();
+        }
+        else
+            bodyOffsetY += fontHeight / 2;
+    }
+#endif
+    // draw attributes
+    if (visualProperty(ShowAttributes)) {
+        // draw dividing line between doc/name and attributes
+        setPenFromSettings(painter);
+        painter->drawLine(0, bodyOffsetY, w, bodyOffsetY);
+        painter->setPen(textColor());
+
+        const int numAtts = displayedAttributes();
+        if (numAtts > 0) {
+            drawMembers(painter, UMLObject::ot_Attribute, m_attributeSignature, textX,
+                        bodyOffsetY, fontHeight);
+            bodyOffsetY += fontHeight * numAtts;
+        }
+        else
+            bodyOffsetY += fontHeight / 2;
+    }
+
+    // draw operations
+    if (visualProperty(ShowOperations)) {
+        // draw dividing line between attributes and operations
+        setPenFromSettings(painter);
+        painter->drawLine(0, bodyOffsetY, w, bodyOffsetY);
+        painter->setPen(QPen(textColor()));
+
+        const int numOps = displayedOperations();
+        if (numOps >= 0) {
+            drawMembers(painter, UMLObject::ot_Operation, m_operationSignature, textX,
+                        bodyOffsetY, fontHeight);
+        }
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * @return The shape of the ClassifierWidget.
+ */
+QPainterPath ClassifierWidget::shape() const
+{
+    QPainterPath path;
+    if (classifier() && classifier()->isInterface() && visualProperty(DrawAsCircle)) {
+        path.addEllipse(rect());
+        return path;
+    }
+#ifdef ENABLE_WIDGET_SHOW_DOC
+    QSizeF mainSize = rect().size();
+#else
+    QSizeF mainSize = calculateSize(false);
+#endif
+    QSize templatesBoxSize = calculateTemplatesBoxSize();
+    qreal mainY = 0.0;
+    if (templatesBoxSize.height() > 0) {
+        mainY += templatesBoxSize.height() - MARGIN;
+        path.addRect(QRectF(mainSize.width() - templatesBoxSize.width() / 2, 0.0,
+                            templatesBoxSize.width(), templatesBoxSize.height()));
+    }
+    path.addRect(QRectF(0.0, mainY, mainSize.width(), mainSize.height()));
+    return path;
+}
+
+/**
+ * Draws the interface as a circle.
+ * Only applies when m_umlObject->getBaseType() is ot_Interface.
+ */
+void ClassifierWidget::drawAsCircle(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    const int w = width();
+
+    if (m_Assocs.size() > 1) {
+        painter->drawEllipse(w/2 - CIRCLE_SIZE/2, SOCKET_INCREMENT / 2, CIRCLE_SIZE, CIRCLE_SIZE);
+        // Draw socket for required interface.
+        const qreal angleSpan = 180;   // 360.0 / (m_Assocs.size() + 1.0);
+        const int arcDiameter = CIRCLE_SIZE + SOCKET_INCREMENT;
+        QRect requireArc(w/2 - arcDiameter/2, 0, arcDiameter, arcDiameter);
+        const QPointF center(x() + w/2, y() + arcDiameter/2);
+        const qreal cX = center.x();
+        const qreal cY = center.y();
+        foreach (AssociationWidget *aw, m_Assocs) {
+            const Uml::AssociationType::Enum aType = aw->associationType();
+            if (aType == Uml::AssociationType::UniAssociation ||
+                   aType == Uml::AssociationType::Association)  // provider
+                continue;
+            UMLWidget *otherEnd = aw->widgetForRole(Uml::RoleType::A);
+            const WidgetBase::WidgetType oType = otherEnd->baseType();
+            if (oType != WidgetBase::wt_Component && oType != WidgetBase::wt_Port)
+                continue;
+
+            AssociationLine *assocLine = aw->associationLine();
+            const QPointF p(assocLine->endPoint());
+            const qreal tolerance = 18.0;
+            bool drawArc = true;
+            qreal midAngle;
+            if (p.x() < cX - tolerance) {
+                if (p.y() < cY - tolerance)
+                    midAngle = 135;
+                else if (p.y() > cY + tolerance)
+                    midAngle = 225;
+                else
+                    midAngle = 180;
+            } else if (p.x() > cX + tolerance) {
+                if (p.y() < cY - tolerance)
+                    midAngle = 45;
+                else if (p.y() > cY + tolerance)
+                    midAngle = 315;
+                else
+                    midAngle = 0;
+            } else {
+                if (p.y() < cY - tolerance)
+                    midAngle = 90;
+                else if (p.y() > cY + tolerance)
+                    midAngle = 270;
+                else
+                    drawArc = false;
+            }
+            if (drawArc) {
+                // uDebug() << "number of assocs: " << m_Assocs.size()
+                //          << ", p: " << p << ", center: " << center
+                //          << ", midAngle: " << midAngle << ", angleSpan: " << angleSpan;
+                painter->drawArc(requireArc, 16 * (midAngle - angleSpan/2), 16 * angleSpan);
+            } else {
+                uError() << "socket: assocLine endPoint " << p
+                         << " too close to own center" << center;
+            }
+        }
+    }
+    else
+        painter->drawEllipse(w/2 - CIRCLE_SIZE/2, 0, CIRCLE_SIZE, CIRCLE_SIZE);
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * Calculates the size of the object when drawn as a circle.
+ * Only applies when m_umlObject->getBaseType() is ot_Interface.
+ */
+QSize ClassifierWidget::calculateAsCircleSize() const
+{
+    int circleSize = CIRCLE_SIZE;
+    if (m_Assocs.size() > 1)
+        circleSize += SOCKET_INCREMENT;
+    return QSize(circleSize, circleSize);
+}
+
+void ClassifierWidget::drawAsPackage(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    Q_UNUSED(option);
+
+    int w = width();
+    int h = height();
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    //FIXME italic is true when a package is first created until you click elsewhere, not sure why
+    font.setItalic(false);
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+    const int fontHeight  = fm.lineSpacing();
+
+    painter->drawRect(0, 0, 50, fontHeight);
+    if (m_umlObject->stereotype() == QLatin1String("subsystem")) {
+        const int fHalf = fontHeight / 2;
+        const int symY = fHalf;
+        const int symX = 38;
+        painter->drawLine(symX, symY, symX, symY + fHalf - 2);          // left leg
+        painter->drawLine(symX + 8, symY, symX + 8, symY + fHalf - 2);  // right leg
+        painter->drawLine(symX, symY, symX + 8, symY);                  // waist
+        painter->drawLine(symX + 4, symY, symX + 4, symY - fHalf + 2);  // head
+    }
+    painter->drawRect(0, fontHeight - 1, w, h - fontHeight);
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    int lines = 1;
+    QString stereotype = m_umlObject->stereotype();
+    if (!stereotype.isEmpty()) {
+        painter->drawText(0, fontHeight + PACKAGE_MARGIN,
+                   w, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true));
+        lines = 2;
+    }
+
+    painter->drawText(0, (fontHeight*lines) + PACKAGE_MARGIN,
+               w, fontHeight, Qt::AlignCenter, name());
+}
+
+QSize ClassifierWidget::calculateAsPackageSize() const
+{
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
+    const int fontHeight = fm.lineSpacing();
+
+    int lines = 1;
+
+    int width = fm.width(m_umlObject->name());
+
+    int tempWidth = 0;
+    if (!m_umlObject->stereotype().isEmpty()) {
+        tempWidth = fm.width(m_umlObject->stereotype(true));
+        lines = 2;
+    }
+    if (tempWidth > width)
+        width = tempWidth;
+    width += PACKAGE_MARGIN * 2;
+    if (width < 70)
+        width = 70;  // minumin width of 70
+
+    int height = (lines*fontHeight) + fontHeight + (PACKAGE_MARGIN * 2);
+
+    return QSize(width, height);
+}
+
+/**
+ * Auxiliary method for draw() of child classes:
+ * Draw the attributes or operations.
+ *
+ * @param p          QPainter to paint to.
+ * @param ot         Object type to draw, either ot_Attribute or ot_Operation.
+ * @param sigType    Governs details of the member display.
+ * @param x          X coordinate at which to draw the texts.
+ * @param y          Y coordinate at which text drawing commences.
+ * @param fontHeight The font height.
+ */
+void ClassifierWidget::drawMembers(QPainter * painter, UMLObject::ObjectType ot, Uml::SignatureType::Enum sigType,
+                                   int x, int y, int fontHeight)
+{
+    UMLClassifier *umlc = classifier();
+    if (!umlc) {
+        return;
+    }
+    QFont f = UMLWidget::font();
+    f.setBold(false);
+    UMLClassifierListItemList list = umlc->getFilteredList(ot);
+    painter->setClipping(true);
+    painter->setClipRect(rect());
+    foreach (UMLClassifierListItem *obj, list) {
+          if (visualProperty(ShowPublicOnly) && obj->visibility() != Uml::Visibility::Public)
+            continue;
+        QString text = obj->toString(sigType);
+        f.setItalic(obj->isAbstract());
+        f.setUnderline(obj->isStatic());
+        painter->setFont(f);
+        QFontMetrics fontMetrics(f);
+        painter->drawText(x, y, fontMetrics.size(0, text).width(), fontHeight, Qt::AlignVCenter, text);
+        f.setItalic(false);
+        f.setUnderline(false);
+        painter->setFont(f);
+        y += fontHeight;
+    }
+    painter->setClipping(false);
+}
+
+/**
+ * Override method from UMLWidget in order to additionally check m_pInterfaceName.
+ *
+ * @param p Point to be checked.
+ *
+ * @return 'this' if UMLWidget::onWidget(p) returns non NULL;
+ *         m_pInterfaceName if m_pName is non NULL and
+ *         m_pInterfaceName->onWidget(p) returns non NULL; else NULL.
+ */
+UMLWidget* ClassifierWidget::onWidget(const QPointF &p)
+{
+    if (UMLWidget::onWidget(p) != NULL)
+        return this;
+    if (getDrawAsCircle() && m_pInterfaceName) {
+        uDebug() << "floatingtext: " << m_pInterfaceName->text();
+        return m_pInterfaceName->onWidget(p);
+    }
+    return NULL;
+}
+
+/**
+ * Reimplement function from UMLWidget.
+ */
+UMLWidget* ClassifierWidget::widgetWithID(Uml::ID::Type id)
+{
+    if (UMLWidget::widgetWithID(id))
+        return this;
+    if (getDrawAsCircle() && m_pInterfaceName && m_pInterfaceName->widgetWithID(id))
+        return m_pInterfaceName;
+    return NULL;
+}
+
+void ClassifierWidget::setDocumentation(const QString &doc)
+{
+    WidgetBase::setDocumentation(doc);
+    updateGeometry();
+}
+
+/**
+ * Sets whether to draw as circle.
+ * Only applies when m_umlObject->getBaseType() is ot_Interface.
+ *
+ * @param drawAsCircle   True if widget shall be drawn as circle.
+ */
+void ClassifierWidget::setDrawAsCircle(bool drawAsCircle)
+{
+    setVisualPropertyCmd(DrawAsCircle, drawAsCircle);
+    const int circleSize = CIRCLE_SIZE + SOCKET_INCREMENT;
+    if (drawAsCircle) {
+        setX(x() + (width()/2 - circleSize/2));
+        setY(y() + (height()/2 - circleSize/2));
+        setSize(circleSize, circleSize);
+        if (m_pInterfaceName) {
+            m_pInterfaceName->show();
+        } else {
+            m_pInterfaceName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating, name());
+            m_pInterfaceName->setParentItem(this);
+            m_pInterfaceName->setText(name());  // to get geometry update
+            m_pInterfaceName->setX(circleSize/2 - m_pInterfaceName->width() / 2);
+            m_pInterfaceName->setY(circleSize + SOCKET_INCREMENT);
+        }
+        m_resizable = false;
+    } else {
+        setSize(ClassifierWidget::minimumSize());
+        setX(x() - (width()/2 - circleSize/2));
+        setY(y() - (height()/2 - circleSize/2));
+        if (m_pInterfaceName)
+            m_pInterfaceName->hide();
+        m_resizable = true;
+    }
+    updateGeometry();
+    update();
+}
+
+/**
+ * Returns whether to draw as circle.
+ * Only applies when m_umlObject->getBaseType() is ot_Interface.
+ *
+ * @return   True if widget is drawn as circle.
+ */
+bool ClassifierWidget::getDrawAsCircle() const
+{
+    return visualProperty(DrawAsCircle);
+}
+
+/**
+ * Toggles whether to draw as circle.
+ * Only applies when m_umlObject->getBaseType() is ot_Interface.
+ */
+void ClassifierWidget::toggleDrawAsCircle()
+{
+    toggleVisualProperty(DrawAsCircle);
+    updateSignatureTypes();
+    updateGeometry();
+    update();
+}
+
+/**
+ * Changes this classifier from an interface to a class.
+ * Attributes and stereotype visibility is got from the view OptionState.
+ * This widget is also updated.
+ */
+void ClassifierWidget::changeToClass()
+{
+    m_baseType = WidgetBase::wt_Class;
+    m_umlObject->setBaseType(UMLObject::ot_Class);
+    setVisualPropertyCmd(DrawAsCircle, false);
+    const Settings::OptionState& ops = m_scene->optionState();
+    setVisualProperty(ShowAttributes, ops.classState.showAtts);
+    setVisualProperty(ShowStereotype, ops.classState.showStereoType);
+
+    updateGeometry();
+    update();
+}
+
+/**
+ * Changes this classifier from a class to an interface.
+ * Attributes are hidden and stereotype is shown.
+ * This widget is also updated.
+ */
+void ClassifierWidget::changeToInterface()
+{
+    m_baseType = WidgetBase::wt_Interface;
+    m_umlObject->setBaseType(UMLObject::ot_Interface);
+
+    setVisualProperty(ShowAttributes, false);
+    setVisualProperty(ShowStereotype, true);
+
+    updateGeometry();
+    update();
+}
+
+/**
+ * Changes this classifier from an "class-or-package" to a package.
+ * This widget is also updated.
+ */
+void ClassifierWidget::changeToPackage()
+{
+    m_baseType = WidgetBase::wt_Package;
+    m_umlObject->setBaseType(UMLObject::ot_Package);
+
+    setVisualProperty(ShowAttributes, false);
+    setVisualProperty(ShowStereotype, true);
+
+    updateGeometry();
+    update();
+}
+
+/**
+ * Extends base method to adjust also the association of a class
+ * association.
+ * Executes the base method and then, if file isn't loading and the
+ * classifier acts as a class association, the association position is
+ * updated.
+ * TODO: This is never called.
+ *
+ *  param x The x-coordinate.
+ *  param y The y-coordinate.
+ */
+//void ClassifierWidget::adjustAssociations(int x, int y)
+//{
+//    DEBUG(DBG_SRC) << "x=" << x << " / y=" << y;
+//    UMLWidget::adjustAssocs(x, y);
+
+//    if (m_doc->loading() || m_pAssocWidget == 0) {
+//        return;
+//    }
+
+//    //:TODO: the following is also called from UMLWidgetr::ajdustAssocs(...)
+//    //       and then AssociationWidget::widgetMoved(...)
+//    //m_pAssocWidget->computeAssocClassLine();
+//}
+
+/**
+ * Loads the "classwidget" or "interfacewidget" XML element.
+ */
+bool ClassifierWidget::loadFromXMI(QDomElement & qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+
+    QString showatts = qElement.attribute(QLatin1String("showattributes"), QLatin1String("0"));
+    QString showops = qElement.attribute(QLatin1String("showoperations"), QLatin1String("1"));
+    QString showpubliconly = qElement.attribute(QLatin1String("showpubliconly"), QLatin1String("0"));
+    QString showattsigs = qElement.attribute(QLatin1String("showattsigs"), QLatin1String("600"));
+    QString showopsigs = qElement.attribute(QLatin1String("showopsigs"), QLatin1String("600"));
+    QString showpackage = qElement.attribute(QLatin1String("showpackage"), QLatin1String("0"));
+    QString showscope = qElement.attribute(QLatin1String("showscope"), QLatin1String("0"));
+    QString drawascircle = qElement.attribute(QLatin1String("drawascircle"), QLatin1String("0"));
+#ifdef ENABLE_WIDGET_SHOW_DOC
+    QString showDocumentation = qElement.attribute(QLatin1String("showdocumentation"), QLatin1String("0"));
+#endif
+
+    setVisualPropertyCmd(ShowAttributes, (bool)showatts.toInt());
+    setVisualPropertyCmd(ShowOperations, (bool)showops.toInt());
+    setVisualPropertyCmd(ShowPublicOnly, (bool)showpubliconly.toInt());
+    setVisualPropertyCmd(ShowPackage,    (bool)showpackage.toInt());
+    setVisualPropertyCmd(ShowVisibility, (bool)showscope.toInt());
+    setVisualPropertyCmd(DrawAsCircle,   (bool)drawascircle.toInt());
+#ifdef ENABLE_WIDGET_SHOW_DOC
+    setVisualPropertyCmd(ShowDocumentation, (bool)showDocumentation.toInt());
+#endif
+
+    m_attributeSignature = Uml::SignatureType::fromInt(showattsigs.toInt());
+    m_operationSignature = Uml::SignatureType::fromInt(showopsigs.toInt());
+
+    if (!getDrawAsCircle())
+        return true;
+
+    // Optional child element: floatingtext
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    if (!element.isNull()) {
+        QString tag = element.tagName();
+        if (tag == QLatin1String("floatingtext")) {
+            if (m_pInterfaceName == NULL) {
+                m_pInterfaceName = new FloatingTextWidget(m_scene,
+                                                          Uml::TextRole::Floating,
+                                                          name(), Uml::ID::Reserved);
+                m_pInterfaceName->setParentItem(this);
+            }
+            if (!m_pInterfaceName->loadFromXMI(element)) {
+                // Most likely cause: The FloatingTextWidget is empty.
+                delete m_pInterfaceName;
+                m_pInterfaceName = NULL;
+            } else {
+                m_pInterfaceName->activate();
+                m_pInterfaceName->update();
+            }
+        } else {
+            uError() << "unknown tag " << tag;
+        }
+    }
+
+    return true;
+}
+
+/**
+ * Creates the "classwidget" or "interfacewidget" XML element.
+ */
+void ClassifierWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement conceptElement;
+    UMLClassifier *umlc = classifier();
+    if (umlObject() && umlObject()->baseType() == UMLObject::ot_Package) {
+        conceptElement = qDoc.createElement(QLatin1String("packagewidget"));
+        UMLWidget::saveToXMI(qDoc, conceptElement);
+        qElement.appendChild(conceptElement);
+        return;
+    }
+    else if (umlc && umlc->isInterface())
+        conceptElement = qDoc.createElement(QLatin1String("interfacewidget"));
+    else
+        conceptElement = qDoc.createElement(QLatin1String("classwidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    conceptElement.setAttribute(QLatin1String("showoperations"), visualProperty(ShowOperations));
+    conceptElement.setAttribute(QLatin1String("showpubliconly"), visualProperty(ShowPublicOnly));
+    conceptElement.setAttribute(QLatin1String("showopsigs"),     m_operationSignature);
+    conceptElement.setAttribute(QLatin1String("showpackage"),    visualProperty(ShowPackage));
+    conceptElement.setAttribute(QLatin1String("showscope"),      visualProperty(ShowVisibility));
+    conceptElement.setAttribute(QLatin1String("showattributes"), visualProperty(ShowAttributes));
+    conceptElement.setAttribute(QLatin1String("showattsigs"),    m_attributeSignature);
+#ifdef ENABLE_WIDGET_SHOW_DOC
+    conceptElement.setAttribute(QLatin1String("showdocumentation"),visualProperty(ShowDocumentation));
+#endif
+    if (umlc && (umlc->isInterface() || umlc->isAbstract())) {
+        conceptElement.setAttribute(QLatin1String("drawascircle"), visualProperty(DrawAsCircle));
+        if (visualProperty(DrawAsCircle) && m_pInterfaceName) {
+            m_pInterfaceName->saveToXMI(qDoc, conceptElement);
+        }
+    }
+    qElement.appendChild(conceptElement);
+}
+
+/**
+ * Will be called when a menu selection has been made from the
+ * popup menu.
+ *
+ * @param action   The action that has been selected.
+ */
+void ClassifierWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch (sel) {
+    case ListPopupMenu::mt_Attribute:
+    case ListPopupMenu::mt_Operation:
+    case ListPopupMenu::mt_Template:
+        {
+            UMLObject::ObjectType ot = ListPopupMenu::convert_MT_OT(sel);
+            UMLClassifier *umlc = classifier();
+            if (!umlc) {
+                uError() << "Internal error - classifier() returns NULL";
+                return;
+            }
+            if (Object_Factory::createChildObject(umlc, ot)) {
+                updateGeometry();
+                update();
+                UMLApp::app()->document()->setModified();
+            }
+            break;
+        }
+    case ListPopupMenu::mt_Show_Operations:
+        toggleVisualProperty(ShowOperations);
+        break;
+
+    case ListPopupMenu::mt_Show_Attributes:
+        toggleVisualProperty(ShowAttributes);
+        break;
+
+    case ListPopupMenu::mt_Show_Documentation:
+        toggleVisualProperty(ShowDocumentation);
+        break;
+
+    case ListPopupMenu::mt_Show_Public_Only:
+        toggleVisualProperty(ShowPublicOnly);
+        break;
+
+    case ListPopupMenu::mt_Show_Operation_Signature:
+        toggleVisualProperty(ShowOperationSignature);
+        break;
+
+    case ListPopupMenu::mt_Show_Attribute_Signature:
+        toggleVisualProperty(ShowAttributeSignature);
+        break;
+
+    case ListPopupMenu::mt_Visibility:
+        toggleVisualProperty(ShowVisibility);
+        break;
+
+    case ListPopupMenu::mt_Show_Packages:
+        toggleVisualProperty(ShowPackage);
+        break;
+
+    case ListPopupMenu::mt_Show_Stereotypes:
+        toggleVisualProperty(ShowStereotype);
+        break;
+
+    case ListPopupMenu::mt_DrawAsCircle:
+        toggleVisualProperty(DrawAsCircle);
+        break;
+
+    case ListPopupMenu::mt_ChangeToClass:
+        changeToClass();
+        break;
+
+    case ListPopupMenu::mt_ChangeToInterface:
+        changeToInterface();
+        break;
+
+    case ListPopupMenu::mt_ChangeToPackage:
+        changeToPackage();
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+        break;
+    }
+}
+
+/**
+ * Slot to show/hide attributes based on \a state.
+ */
+void ClassifierWidget::slotShowAttributes(bool state)
+{
+    setVisualProperty(ShowAttributes, state);
+}
+
+/**
+ * Slot to show/hide operations based on \a state.
+ */
+void ClassifierWidget::slotShowOperations(bool state)
+{
+    setVisualProperty(ShowOperations, state);
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/classifierwidget.h umbrello-15.08.1/umbrello/umlwidgets/classifierwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/classifierwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/classifierwidget.h	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,146 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef CLASSIFIERWIDGET_H
+#define CLASSIFIERWIDGET_H
+
+#include "basictypes.h"
+#include "umlobject.h"
+#include "umlwidget.h"
+
+class AssociationWidget;
+class FloatingTextWidget;
+class QPainter;
+class UMLClassifier;
+
+/**
+ * @short Common implementation for class widget and interface widget
+ *
+ * @author Oliver Kellogg
+ * @author Gopala Krishna
+ *
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ClassifierWidget : public UMLWidget
+{
+    Q_OBJECT
+    Q_ENUMS(VisualProperty)
+public:
+    /**
+     * This enumeration lists the visual properties that can be easily
+     * set, reset and toggled and all these operate on an integer
+     * which stores all the flag status.
+     */
+    enum VisualProperty {
+        ShowStereotype         = 0x1,
+        ShowOperations         = 0x2,
+        ShowPublicOnly         = 0x4,
+        ShowVisibility         = 0x8,
+        ShowPackage            = 0x10,
+        ShowAttributes         = 0x20,
+        DrawAsCircle           = 0x40,
+        ShowOperationSignature = 0x60,  ///< only in setter
+        ShowAttributeSignature = 0x80,   ///< only in setter
+        DrawAsPackage          = 0x100,
+        ShowDocumentation      = 0x200,
+    };
+
+    Q_DECLARE_FLAGS(VisualProperties, VisualProperty)
+
+    ClassifierWidget(UMLScene * scene, UMLClassifier * o);
+    ClassifierWidget(UMLScene * scene, UMLPackage * o);
+    virtual ~ClassifierWidget();
+
+    UMLClassifier *classifier() const;
+
+    VisualProperties visualProperties() const;
+    void setVisualProperties(VisualProperties properties);
+
+    bool visualProperty(VisualProperty property) const;
+    void setVisualProperty(VisualProperty property, bool enable = true);
+    void setVisualPropertyCmd(VisualProperty property, bool enable = true);
+    void toggleVisualProperty(VisualProperty property);
+
+    int displayedAttributes() const;
+    int displayedOperations() const;
+
+    Uml::SignatureType::Enum attributeSignature() const;
+    void setAttributeSignature(Uml::SignatureType::Enum sig);
+
+    Uml::SignatureType::Enum operationSignature() const;
+    void setOperationSignature(Uml::SignatureType::Enum sig);
+
+    void setShowAttSigs(bool _show);
+    void toggleShowAttSigs();
+
+    bool getDrawAsCircle() const;
+    void setDrawAsCircle(bool drawAsCircle);
+    void toggleDrawAsCircle();
+
+    void changeToClass();
+    void changeToInterface();
+    void changeToPackage();
+
+    AssociationWidget *classAssociationWidget() const;
+    void setClassAssociationWidget(AssociationWidget *assocwidget);
+//    virtual void adjustAssociations(int x, int y);
+
+    UMLWidget* onWidget(const QPointF& p);
+    UMLWidget* widgetWithID(Uml::ID::Type id);
+
+    virtual void setDocumentation(const QString& doc);
+
+    QSizeF calculateSize(bool withExtensions = true) const;
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    virtual QPainterPath shape() const;
+
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+    virtual bool loadFromXMI(QDomElement & qElement);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+private Q_SLOTS:
+    void slotShowAttributes(bool state);
+    void slotShowOperations(bool state);
+
+private:
+    void updateSignatureTypes();
+    QSize calculateTemplatesBoxSize() const;
+
+    QSizeF minimumSize() const;
+
+    void drawAsCircle(QPainter *p, const QStyleOptionGraphicsItem *option);
+    QSize calculateAsCircleSize() const;
+
+    void drawAsPackage(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    QSize calculateAsPackageSize() const;
+
+    int displayedMembers(UMLObject::ObjectType ot) const;
+    void drawMembers(QPainter *painter, UMLObject::ObjectType ot, Uml::SignatureType::Enum sigType,
+                     int x, int y, int fontHeight);
+
+    static const int MARGIN;           ///< text width margin
+    static const int CIRCLE_SIZE;      ///< size of circle when interface is rendered as such
+    static const int SOCKET_INCREMENT; ///< augmentation of circle for socket (required interface)
+
+    VisualProperties   m_visualProperties;
+    Uml::SignatureType::Enum m_attributeSignature;   ///< Loaded/saved item.
+    Uml::SignatureType::Enum m_operationSignature;   ///< Loaded/saved item.
+    AssociationWidget *m_pAssocWidget; ///< related AssociationWidget in case this classifier acts as an association class
+    FloatingTextWidget *m_pInterfaceName;  ///< Separate widget for name in case of interface drawn as circle
+
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(ClassifierWidget::VisualProperties)
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/combinedfragmentwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/combinedfragmentwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/combinedfragmentwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/combinedfragmentwidget.cpp	2015-10-08 11:48:59.508089026 +0300
@@ -0,0 +1,477 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "combinedfragmentwidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "dialog_utils.h"
+#include "listpopupmenu.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPainter>
+#include <QString>
+
+/**
+ * Creates a Combined Fragment widget.
+ *
+ * @param scene              The parent of the widget.
+ * @param combinedfragmentType      The type of combined fragment.
+ * @param id                The ID to assign (-1 will prompt a new ID.)
+ */
+CombinedFragmentWidget::CombinedFragmentWidget(UMLScene * scene, CombinedFragmentType combinedfragmentType, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_CombinedFragment, id)
+{
+    setCombinedFragmentType(combinedfragmentType);
+}
+
+/**
+ * Destructor.
+ */
+CombinedFragmentWidget::~CombinedFragmentWidget()
+{
+    for (QList<FloatingDashLineWidget*>::iterator it=m_dashLines.begin() ; it!=m_dashLines.end() ; ++it) {
+        delete(*it);
+    }
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void CombinedFragmentWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    int w = width();
+    int h = height();
+    int line_width = 45;
+    int old_Y;
+
+    setPenFromSettings(painter);
+
+    if (m_CombinedFragment == Ref) {
+        if (UMLWidget::useFillColor()) {
+            painter->setBrush(UMLWidget::fillColor());
+        }
+    }
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    const QString combined_fragment_value =  name();
+    int textStartY = (h / 2) - (fontHeight / 2);
+    painter->drawRect(0, 0, w, h);
+
+    painter->setPen(textColor());
+    painter->setFont(UMLWidget::font());
+        QString temp = QLatin1String("loop");
+
+    switch (m_CombinedFragment)
+    {
+        case Ref :
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, textStartY, w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignCenter, combined_fragment_value);
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0, w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("ref"));
+        break;
+
+        case Opt :
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("opt"));
+        break;
+
+        case Break :
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("break"));
+        break;
+
+        case Loop :
+                if (combined_fragment_value != QLatin1String("-"))
+                {
+                     temp += QLatin1String(" [") + combined_fragment_value + QLatin1Char(']');
+                     line_width += (combined_fragment_value.size() + 2) * 8;
+                }
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0, w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, temp);
+
+        break;
+
+        case Neg :
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("neg"));
+        break;
+
+        case Crit :
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("critical"));
+        break;
+
+        case Ass :
+        painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("assert"));
+        break;
+
+        case Alt :
+                if (combined_fragment_value != QLatin1String("-"))
+                {
+                     temp = QLatin1Char('[') + combined_fragment_value + QLatin1Char(']');
+            painter->drawText(COMBINED_FRAGMENT_MARGIN, 20, w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, temp);
+                    if (m_dashLines.size() == 1 && m_dashLines.first()->y() < y() + 20 + fontHeight)
+                        m_dashLines.first()->setY(y() + h/2);
+                }
+                painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("alt"));
+                // dash lines
+                //m_dashLines.first()->paint(painter);
+                // TODO: move to UMLWidget::calculateSize api
+                for (QList<FloatingDashLineWidget*>::iterator it=m_dashLines.begin() ; it!=m_dashLines.end() ; ++it) {
+                    (*it)->setX(x());
+                    old_Y = (*it)->getYMin();
+                    (*it)->setYMin(y());
+                    (*it)->setYMax(y() + height());
+                    (*it)->setY(y() + (*it)->y() - old_Y);
+                    (*it)->setSize(w, (*it)->height());
+                    (*it)->setLineColor(lineColor());
+                    (*it)->setLineWidth(lineWidth());
+                }
+
+        break;
+
+        case Par :
+                painter->drawText(COMBINED_FRAGMENT_MARGIN, 0,
+            w - COMBINED_FRAGMENT_MARGIN * 2, fontHeight, Qt::AlignLeft, QLatin1String("parallel"));
+                // dash lines
+                if (m_dashLines.size() != 0) {
+                    //m_dashLines.first()->paint(painter);
+                    // TODO: move to UMLWidget::calculateSize api
+                    for (QList<FloatingDashLineWidget*>::iterator it=m_dashLines.begin() ; it!=m_dashLines.end() ; ++it) {
+                        (*it)->setX(x());
+                        old_Y = (*it)->getYMin();
+                        (*it)->setYMin(y());
+                        (*it)->setYMax(y() + height());
+                        (*it)->setY(y() + (*it)->y() - old_Y);
+                        (*it)->setSize(w, (*it)->height());
+                        (*it)->setLineColor(lineColor());
+                        (*it)->setLineWidth(lineWidth());
+                    }
+                }
+        break;
+
+    default : break;
+    }
+
+    setPenFromSettings(painter);
+    painter->drawLine(0, 20, line_width, 20);
+    painter->drawLine(line_width, 20, line_width + 10, 10);
+    painter->drawLine(line_width + 10, 10, line_width + 10, 0);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF CombinedFragmentWidget::minimumSize() const
+{
+    int width = 10, height = 10;
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    const int textWidth = fm.width(name());
+    height = fontHeight;
+    width = textWidth + 60 > COMBINED_FRAGMENT_WIDTH ? textWidth + 60: COMBINED_FRAGMENT_WIDTH;
+    if (m_CombinedFragment == Loop)
+         width += int((float)textWidth * 0.4f);
+    if (m_CombinedFragment == Alt)
+         height += fontHeight + 40;
+    height = height > COMBINED_FRAGMENT_HEIGHT ? height : COMBINED_FRAGMENT_HEIGHT;
+    width += COMBINED_FRAGMENT_MARGIN * 2;
+    height += COMBINED_FRAGMENT_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Returns the type of combined fragment.
+ */
+CombinedFragmentWidget::CombinedFragmentType CombinedFragmentWidget::combinedFragmentType() const
+{
+    return m_CombinedFragment;
+}
+
+/**
+ * Sets the type of combined fragment.
+ */
+void CombinedFragmentWidget::setCombinedFragmentType(CombinedFragmentType combinedfragmentType)
+{
+    m_CombinedFragment = combinedfragmentType;
+    UMLWidget::m_resizable =  true ; //(m_CombinedFragment == Normal);
+    // creates a dash line if the combined fragment type is alternative or parallel
+    if (m_CombinedFragment == Alt  && m_dashLines.isEmpty())
+    {
+        m_dashLines.push_back(new FloatingDashLineWidget(m_scene, Uml::ID::None, this));
+        if (m_CombinedFragment == Alt)
+        {
+            m_dashLines.back()->setText(QLatin1String("else"));
+        }
+        // TODO: move to UMLWidget::calculateSize api
+        m_dashLines.back()->setX(x());
+        m_dashLines.back()->setYMin(y());
+        m_dashLines.back()->setYMax(y() + height());
+        m_dashLines.back()->setY(y() + height()/2);
+        m_dashLines.back()->setSize(width(), m_dashLines.back()->height());
+        m_scene->widgetList().append(m_dashLines.back());
+    }
+}
+
+/**
+ * Returns the type of combined fragment.
+ */
+CombinedFragmentWidget::CombinedFragmentType CombinedFragmentWidget::combinedFragmentType(const QString& type) const
+{
+    if (type == QLatin1String("Reference"))
+        return (CombinedFragmentWidget::Ref);
+    if (type == QLatin1String("Option"))
+        return (CombinedFragmentWidget::Opt);
+    if (type == QLatin1String("Break"))
+        return (CombinedFragmentWidget::Break);
+    if (type == QLatin1String("Loop"))
+        return (CombinedFragmentWidget::Loop);
+    if (type == QLatin1String("Negative"))
+        return (CombinedFragmentWidget::Neg);
+    if (type == QLatin1String("Critical"))
+        return (CombinedFragmentWidget::Crit);
+    if (type == QLatin1String("Assertion"))
+        return (CombinedFragmentWidget::Ass);
+    if (type == QLatin1String("Alternative"))
+        return (CombinedFragmentWidget::Alt);
+    if (type == QLatin1String("Parallel"))
+        return (CombinedFragmentWidget::Par);
+    // Shouldn't happen
+    Q_ASSERT(0);
+    return (CombinedFragmentWidget::Ref);
+}
+
+/**
+ * Sets the type of combined fragment.
+ */
+void CombinedFragmentWidget::setCombinedFragmentType(const QString& combinedfragmentType)
+{
+    setCombinedFragmentType(combinedFragmentType(combinedfragmentType));
+}
+
+/**
+ * ...
+ */
+void CombinedFragmentWidget::askNameForWidgetType(UMLWidget* &targetWidget, const QString& dialogTitle,
+    const QString& dialogPrompt, const QString& defaultName)
+{
+    Q_UNUSED(defaultName);
+    bool pressedOK = false;
+    const QStringList list = QStringList()
+                             << QLatin1String("Reference")
+                             << QLatin1String("Option")
+                             << QLatin1String("Break")
+                             << QLatin1String("Loop")
+                             << QLatin1String("Negative")
+                             << QLatin1String("Critical")
+                             << QLatin1String("Assertion")
+                             << QLatin1String("Alternative")
+                             << QLatin1String("Parallel") ;
+#if QT_VERSION >= 0x050000
+    QPointer<QInputDialog> inputDlg = new QInputDialog();
+    inputDlg->setComboBoxItems(list);
+    inputDlg->setOptions(QInputDialog::UseListViewForComboBoxItems);
+    inputDlg->setWindowTitle(dialogTitle);
+    inputDlg->setLabelText(dialogPrompt);
+    pressedOK = inputDlg->exec();
+    QStringList result;
+    result.append(inputDlg->textValue());
+    delete inputDlg;
+#else
+    const QStringList select = list;
+    QStringList result = KInputDialog::getItemList (dialogTitle, dialogPrompt, list, select, false, &pressedOK, UMLApp::app());
+#endif
+    if (pressedOK) {
+        QString type = result.join(QString());
+        dynamic_cast<CombinedFragmentWidget*>(targetWidget)->setCombinedFragmentType(type);
+        if (type == QLatin1String("Reference"))
+            Dialog_Utils::askNameForWidget(targetWidget, i18n("Enter the name of the diagram referenced"), i18n("Enter the name of the diagram referenced"), i18n("Diagram name"));
+        else if (type == QLatin1String(QLatin1String("Loop")))
+            Dialog_Utils::askNameForWidget(targetWidget, i18n("Enter the guard of the loop"), i18n("Enter the guard of the loop"), i18n("-"));
+        else if (type == QLatin1String("Alternative"))
+            Dialog_Utils::askNameForWidget(targetWidget, i18n("Enter the first alternative name"), i18n("Enter the first alternative name"), i18n("-"));
+    } else {
+        targetWidget->cleanup();
+        delete targetWidget;
+        targetWidget = NULL;
+    }
+}
+
+/**
+ * Saves the widget to the "combinedFragmentwidget" XMI element.
+ */
+void CombinedFragmentWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement combinedFragmentElement = qDoc.createElement(QLatin1String("combinedFragmentwidget"));
+    UMLWidget::saveToXMI(qDoc, combinedFragmentElement);
+    combinedFragmentElement.setAttribute(QLatin1String("combinedFragmentname"), m_Text);
+    combinedFragmentElement.setAttribute(QLatin1String("documentation"), m_Doc);
+    combinedFragmentElement.setAttribute(QLatin1String("CombinedFragmenttype"), m_CombinedFragment);
+
+    // save the corresponding floating dash lines
+    for (QList<FloatingDashLineWidget*>::iterator it = m_dashLines.begin() ; it != m_dashLines.end() ; ++it) {
+        (*it)-> saveToXMI(qDoc, combinedFragmentElement);
+    }
+
+    qElement.appendChild(combinedFragmentElement);
+}
+
+/**
+ * Loads the widget from the "CombinedFragmentwidget" XMI element.
+ */
+bool CombinedFragmentWidget::loadFromXMI(QDomElement & qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement))
+        return false;
+    m_Text = qElement.attribute(QLatin1String("combinedFragmentname"));
+    m_Doc = qElement.attribute(QLatin1String("documentation"));
+    QString type = qElement.attribute(QLatin1String("CombinedFragmenttype"));
+
+    //now load child elements
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    while (!element.isNull()) {
+        QString tag = element.tagName();
+        if (tag == QLatin1String("floatingdashlinewidget")) {
+            FloatingDashLineWidget * fdlwidget = new FloatingDashLineWidget(m_scene, Uml::ID::None, this);
+            m_dashLines.push_back(fdlwidget);
+            if (!fdlwidget->loadFromXMI(element)) {
+              // Most likely cause: The FloatingTextWidget is empty.
+                delete m_dashLines.back();
+                return false;
+            }
+            else {
+                m_scene->widgetList().append(fdlwidget);
+                fdlwidget->clipSize();
+            }
+        } else {
+            uError() << "unknown tag " << tag;
+        }
+        node = node.nextSibling();
+        element = node.toElement();
+    }
+   // m_dashLines = listline;
+    setCombinedFragmentType((CombinedFragmentType)type.toInt());
+
+    return true;
+}
+
+void CombinedFragmentWidget::removeDashLine(FloatingDashLineWidget *line)
+{
+    if (m_dashLines.contains(line))
+        m_dashLines.removeOne(line);
+}
+
+/**
+ * Overrides the function from UMLWidget. Deletes all FloatingDashLineWidgets
+ * that are associated with this instance.
+ */
+void CombinedFragmentWidget::cleanup()
+{
+  foreach (FloatingDashLineWidget* w, m_dashLines)
+  {
+    if (!w->isSelected()) {
+      // no need to make this undoable, since the dashlines will be
+      // reconstructed when deleting the combined fragment is undone.
+      umlScene()->removeWidgetCmd(w);
+    }
+  }
+}
+
+/**
+ * Overrides the function from UMLWidget.
+ *
+ * @param action  The command to be executed.
+ */
+void CombinedFragmentWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch (sel) {
+          // for alternative or parallel combined fragments
+    case ListPopupMenu::mt_AddInteractionOperand:
+        m_dashLines.push_back(new FloatingDashLineWidget(m_scene, Uml::ID::None, this));
+        if (m_CombinedFragment == Alt)
+        {
+            m_dashLines.back()->setText(QLatin1String("else"));
+        }
+        // TODO: move to UMLWidget::calculateSize api
+        m_dashLines.back()->setX(x());
+        m_dashLines.back()->setYMin(y());
+        m_dashLines.back()->setYMax(y() + height());
+        m_dashLines.back()->setY(y() + height() / 2);
+        m_dashLines.back()->setSize(width(), m_dashLines.back()->height());
+        m_scene->setupNewWidget(m_dashLines.back());
+        break;
+
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString name = m_Text;
+
+#if QT_VERSION >= 0x050000
+            if (m_CombinedFragment == Alt) {
+                name = QInputDialog::getText(Q_NULLPTR,
+                                             i18n("Enter first alternative"), i18n("Enter first alternative :"),
+                                             QLineEdit::Normal,
+                                             m_Text, &ok);
+            }
+            else if (m_CombinedFragment == Ref) {
+            name = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter referenced diagram name"), i18n("Enter referenced diagram name :"),
+                                         QLineEdit::Normal,
+                                         m_Text, &ok);
+            }
+            else if (m_CombinedFragment == Loop) {
+            name = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter the guard of the loop"), i18n("Enter the guard of the loop:"),
+                                         QLineEdit::Normal,
+                                         m_Text, &ok);
+            }
+#else
+            if (m_CombinedFragment == Alt) {
+                name = KInputDialog::getText(i18n("Enter first alternative"), i18n("Enter first alternative :"), m_Text, &ok);
+            }
+            else if (m_CombinedFragment == Ref) {
+            name = KInputDialog::getText(i18n("Enter referenced diagram name"), i18n("Enter referenced diagram name :"), m_Text, &ok);
+            }
+            else if (m_CombinedFragment == Loop) {
+            name = KInputDialog::getText(i18n("Enter the guard of the loop"), i18n("Enter the guard of the loop:"), m_Text, &ok);
+            }
+#endif
+            if (ok && name.length() > 0)
+                m_Text = name;
+        }
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/combinedfragmentwidget.h umbrello-15.08.1/umbrello/umlwidgets/combinedfragmentwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/combinedfragmentwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/combinedfragmentwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,91 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef COMBINEDFRAGMENTWIDGET_H
+#define COMBINEDFRAGMENTWIDGET_H
+
+#include "umlwidget.h"
+#include "worktoolbar.h"
+#include "floatingdashlinewidget.h"
+
+#include <QList>
+
+#define COMBINED_FRAGMENT_MARGIN 5
+#define COMBINED_FRAGMENT_WIDTH 100
+#define COMBINED_FRAGMENT_HEIGHT 50
+
+/**
+ * This class is the graphical version of a UML combined fragment.  A combinedfragmentWidget is created
+ * by a @ref UMLView.  An combinedfragmentWidget belongs to only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
+ *
+ * The combinedfragmentWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @short  A graphical version of a UML combined fragment.
+ * @author Hassan KOUCH <hkouch@hotmail.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class CombinedFragmentWidget : public UMLWidget
+{
+    Q_OBJECT
+
+public:
+    enum CombinedFragmentType
+    {
+        Ref = 0,
+        Opt,
+        Break,
+        Loop,
+        Neg,
+        Crit,
+        Ass,
+        Alt,
+        Par
+    };
+
+    explicit CombinedFragmentWidget(UMLScene * scene,
+                                    CombinedFragmentType combinedfragmentType = Ref,
+                                    Uml::ID::Type id = Uml::ID::None);
+    virtual ~CombinedFragmentWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    CombinedFragmentType combinedFragmentType() const;
+    CombinedFragmentType combinedFragmentType(const QString& combinedfragmentType) const;
+    void setCombinedFragmentType(CombinedFragmentType combinedfragmentType);
+    void setCombinedFragmentType(const QString& combinedfragmentType);
+
+    void askNameForWidgetType(UMLWidget* &targetWidget, const QString& dialogTitle,
+                      const QString& dialogPrompt, const QString& defaultName);
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+    bool loadFromXMI(QDomElement & qElement);
+    void removeDashLine(FloatingDashLineWidget *line);
+
+    virtual void cleanup();
+
+public slots:
+    void slotMenuSelection(QAction* action);
+
+
+protected:
+    QSizeF minimumSize() const;
+
+    /// Type of CombinedFragment.
+    CombinedFragmentType m_CombinedFragment;
+
+private:
+    /// Dash lines of an alternative or parallel combined fragment
+    QList<FloatingDashLineWidget*> m_dashLines ;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/componentwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/componentwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/componentwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/componentwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,207 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "componentwidget.h"
+
+// app includes
+#include "component.h"
+#include "debug_utils.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "optionstate.h"
+#include "umldoc.h"
+#include "package.h"
+#include "portwidget.h"
+
+/**
+ * Constructs a ComponentWidget.
+ *
+ * @param scene      The parent of this ComponentWidget.
+ * @param c The UMLComponent this will be representing.
+ */
+ComponentWidget::ComponentWidget(UMLScene * scene, UMLComponent *c)
+  : UMLWidget(scene, WidgetBase::wt_Component, c)
+{
+    setSize(100, 30);
+    //set defaults from m_scene
+    if (m_scene) {
+        //check to see if correct
+        const Settings::OptionState& ops = m_scene->optionState();
+        m_showStereotype = ops.classState.showStereoType;
+    }
+}
+
+/**
+ * Destructor.
+ */
+ComponentWidget::~ComponentWidget()
+{
+}
+
+/**
+ * Reimplemented from UMLWidget::paint to paint component
+ * widget.
+ */
+void ComponentWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    UMLComponent *umlcomp = static_cast<UMLComponent*>(m_umlObject);
+    if (umlcomp == NULL)
+        return;
+    setPenFromSettings(painter);
+    QPen origPen = painter->pen();
+    QPen pen = origPen;
+    if (umlcomp->getExecutable()) {
+        pen.setWidth(origPen.width() + 2);
+        painter->setPen(pen);
+    }
+    if (UMLWidget::useFillColor()) {
+        painter->setBrush(UMLWidget::fillColor());
+    } else {
+        painter->setBrush(m_scene->backgroundColor());
+    }
+
+    const int w = width();
+    const int h = height();
+    const int halfHeight = h / 2;
+    int   textXOffset = 0;
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+    const int fontHeight = fm.lineSpacing();
+    QString nameStr = name();
+    const QString stereotype = m_umlObject->stereotype();
+
+    if (Settings::optionState().generalState.uml2) {
+        painter->drawRect(0, 0, w, h);
+        // draw small component symbol in upper right corner
+        painter->setPen(origPen);
+        painter->drawRect(w - 17,  5, 11, 13);
+        painter->drawRect(w - 19,  7,  2,  2);
+        painter->drawRect(w - 19, 11,  2,  2);
+        painter->setPen(pen);
+    } else {
+        painter->drawRect(2*COMPONENT_MARGIN, 0, w - 2*COMPONENT_MARGIN, h);
+        painter->drawRect(0, halfHeight - fontHeight/2 - fontHeight, COMPONENT_MARGIN*4, fontHeight);
+        painter->drawRect(0, halfHeight + fontHeight/2, COMPONENT_MARGIN*4, fontHeight);
+        textXOffset = COMPONENT_MARGIN * 4;
+    }
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    int lines = 1;
+
+    if (!stereotype.isEmpty()) {
+        painter->drawText(textXOffset, halfHeight - fontHeight,
+                   w - textXOffset, fontHeight, Qt::AlignCenter,
+                   m_umlObject->stereotype(true));
+        lines = 2;
+    }
+
+    if (UMLWidget::isInstance()) {
+        font.setUnderline(true);
+        painter->setFont(font);
+        nameStr = UMLWidget::instanceName() + QLatin1String(" : ") + nameStr;
+    }
+
+    if (lines == 1) {
+        painter->drawText(textXOffset, halfHeight - (fontHeight/2),
+                   w - textXOffset, fontHeight, Qt::AlignCenter, nameStr);
+    } else {
+        painter->drawText(textXOffset, halfHeight,
+                   w - textXOffset, fontHeight, Qt::AlignCenter, nameStr);
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overridden from UMLWidget due to emission of signal sigCompMoved()
+ */
+void ComponentWidget::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    UMLWidget::moveWidgetBy(diffX, diffY);
+    emit sigCompMoved(diffX, diffY);
+}
+
+/**
+ * Override method from UMLWidget for adjustment of attached PortWidgets.
+ */
+void ComponentWidget::adjustAssocs(qreal dx, qreal dy)
+{
+    if (m_doc->loading()) {
+        // don't recalculate the assocs during load of XMI
+        // -> return immediately without action
+        return;
+    }
+    UMLWidget::adjustAssocs(dx, dy);
+    UMLPackage *comp = static_cast<UMLPackage*>(m_umlObject);
+    foreach (UMLObject *o, comp->containedObjects()) {
+        uIgnoreZeroPointer(o);
+        if (o->baseType() != UMLObject::ot_Port)
+            continue;
+        UMLWidget *portW = m_scene->widgetOnDiagram(o->id());
+        if (portW)
+            portW->adjustAssocs(dx, dy);
+    }
+}
+
+/**
+ * Saves to the "componentwidget" XMI element.
+ */
+void ComponentWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("componentwidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF ComponentWidget::minimumSize() const
+{
+    if (!m_umlObject) {
+        return QSizeF(70, 70);
+    }
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
+    const int fontHeight = fm.lineSpacing();
+
+    QString name = m_umlObject->name();
+    if (UMLWidget::isInstance()) {
+        name = UMLWidget::instanceName() + QLatin1String(" : ") + name;
+    }
+
+    int width = fm.width(name);
+
+    int stereoWidth = 0;
+    if (!m_umlObject->stereotype().isEmpty()) {
+        stereoWidth = fm.width(m_umlObject->stereotype(true));
+    }
+    if (stereoWidth > width)
+        width = stereoWidth;
+    width += COMPONENT_MARGIN * 6;
+    width = 70>width ? 70 : width; //minumin width of 70
+
+    int height = (2*fontHeight) + (COMPONENT_MARGIN * 3);
+
+    UMLComponent *umlcomp = static_cast<UMLComponent*>(m_umlObject);
+    if (umlcomp && umlcomp->getExecutable()) {
+        width  += 2;
+        height += 2;
+    }
+
+    return QSizeF(width, height);
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/componentwidget.h umbrello-15.08.1/umbrello/umlwidgets/componentwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/componentwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/componentwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef COMPONENTWIDGET_H
+#define COMPONENTWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLComponent;
+
+#define COMPONENT_MARGIN 10
+
+/**
+ * Defines a graphical version of the Component.  Most of the functionality
+ * will come from the @ref UMLComponent class.
+ *
+ * @short A graphical version of a Component.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ComponentWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    ComponentWidget(UMLScene * scene, UMLComponent *c);
+    virtual ~ComponentWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+    virtual void moveWidgetBy(qreal diffX, qreal diffY);
+    virtual void adjustAssocs(qreal dx, qreal dy);
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+signals:
+    /**
+     * Emitted when the component widget is moved.
+     * Provides the delta X and delta Y amount by which the widget was moved
+     * relative to the previous position.
+     * Slots into PortWidget::slotCompMoved()
+     * @param diffX The difference between previous and new X value.
+     * @param diffY The difference between previous and new Y value.
+     */
+    void sigCompMoved(qreal diffX, qreal diffY);
+
+protected:
+    QSizeF minimumSize() const;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/datatypewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/datatypewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/datatypewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/datatypewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,129 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "datatypewidget.h"
+
+// app includes
+#include "classifier.h"
+#include "classifierlistitem.h"
+#include "debug_utils.h"
+#include "operation.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// qt includes
+#include <QPainter>
+
+/**
+ * Constructs an DatatypeWidget.
+ *
+ * @param scene   The parent of this DatatypeWidget.
+ * @param d       The UMLClassifier this will be representing.
+ */
+DatatypeWidget::DatatypeWidget(UMLScene *scene, UMLClassifier *d)
+  : UMLWidget(scene, WidgetBase::wt_Datatype, d)
+{
+    setSize(100, 30);
+}
+
+/**
+ * Standard deconstructor.
+ */
+DatatypeWidget::~DatatypeWidget()
+{
+}
+
+/**
+ * Overrides standard method.
+ */
+void DatatypeWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())  {
+        painter->setBrush(UMLWidget::fillColor());
+    } else {
+        painter->setBrush(m_scene->backgroundColor());
+    }
+
+    int w = width();
+    int h = height();
+
+    QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    int fontHeight  = fm.lineSpacing();
+
+    painter->drawRect(0, 0, w, h);
+    painter->setPen(textColor());
+
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    painter->setFont(font);
+    painter->drawText(DATATYPE_MARGIN, 0,
+               w - DATATYPE_MARGIN* 2, fontHeight,
+               Qt::AlignCenter, m_umlObject->stereotype(true));
+
+    font.setItalic(m_umlObject->isAbstract());
+    painter->setFont(font);
+    painter->drawText(DATATYPE_MARGIN, fontHeight,
+               w - DATATYPE_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Loads from a "datatypewidget" XMI element.
+ */
+bool DatatypeWidget::loadFromXMI(QDomElement & qElement)
+{
+    return UMLWidget::loadFromXMI(qElement);
+}
+
+/**
+ * Saves to the "datatypewidget" XMI element.
+ */
+void DatatypeWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("datatypewidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF DatatypeWidget::minimumSize() const
+{
+    if (!m_umlObject)  {
+        return UMLWidget::minimumSize();
+    }
+    int width, height;
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight = fm.lineSpacing();
+
+    int lines = 1;//always have one line - for name
+    lines++; //for the stereotype
+
+    height = width = 0;
+    height += lines * fontHeight;
+
+    //now set the width of the concept
+    //set width to name to start with
+    //set width to name to start with
+    width = getFontMetrics(FT_BOLD_ITALIC).boundingRect(m_umlObject->fullyQualifiedName()).width();
+    int w = getFontMetrics(FT_BOLD).boundingRect(m_umlObject->stereotype(true)).width();
+
+    width = w > width?w:width;
+
+    //allow for width margin
+    width += DATATYPE_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/datatypewidget.h umbrello-15.08.1/umbrello/umlwidgets/datatypewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/datatypewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/datatypewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef DATATYPEWIDGET_H
+#define DATATYPEWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLClassifier;
+
+#define DATATYPE_MARGIN 5
+
+/**
+ * Defines a graphical version of the datatype.  Most of the functionality
+ * will come from the @ref UMLWidget class from which class inherits from.
+ *
+ * @short A graphical version of an datatype.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class DatatypeWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    DatatypeWidget(UMLScene *scene, UMLClassifier *d);
+    virtual ~DatatypeWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    bool loadFromXMI(QDomElement& qElement);
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+public Q_SLOTS:
+
+protected:
+    QSizeF minimumSize() const;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/entitywidget.cpp umbrello-15.08.1/umbrello/umlwidgets/entitywidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/entitywidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/entitywidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,246 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "entitywidget.h"
+
+// app includes
+#include "classifier.h"
+#include "classifierlistitem.h"
+#include "debug_utils.h"
+#include "entity.h"
+#include "entityattribute.h"
+#include "foreignkeyconstraint.h"
+#include "listpopupmenu.h"
+#include "object_factory.h"
+#include "uml.h"
+#include "umlclassifierlistitemlist.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "uniqueconstraint.h"
+
+/**
+ * Constructs an EntityWidget.
+ *
+ * @param scene   The parent of this EntityWidget.
+ * @param o       The UMLObject this will be representing.
+ */
+EntityWidget::EntityWidget(UMLScene *scene, UMLObject* o)
+  : UMLWidget(scene, WidgetBase::wt_Entity, o)
+{
+    setSize(100, 30);
+}
+
+/**
+ * Destructor.
+ */
+EntityWidget::~EntityWidget()
+{
+}
+
+/**
+ * Draws the entity as a rectangle with a box underneith with a list of literals
+ */
+void EntityWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    setPenFromSettings(painter);
+    if(UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    else
+        painter->setBrush(m_scene->backgroundColor());
+
+    const int w = width();
+    const int h = height();
+
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    int fontHeight  = fm.lineSpacing();
+    const QString name = this->name();
+
+    painter->drawRect(0, 0, w, h);
+    painter->setPen(textColor());
+
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    painter->setFont(font);
+    int y = 0;
+    if (!m_umlObject->stereotype().isEmpty()) {
+        painter->drawText(ENTITY_MARGIN, 0,
+                   w - ENTITY_MARGIN * 2, fontHeight,
+                   Qt::AlignCenter, m_umlObject->stereotype(true));
+        font.setItalic(m_umlObject->isAbstract());
+        painter->setFont(font);
+        painter->drawText(ENTITY_MARGIN, fontHeight,
+                   w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name);
+        font.setBold(false);
+        font.setItalic(false);
+        painter->setFont(font);
+        y = fontHeight * 2;
+    } else {
+        font.setItalic(m_umlObject->isAbstract());
+        painter->setFont(font);
+        painter->drawText(ENTITY_MARGIN, 0,
+                   w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name);
+        font.setBold(false);
+        font.setItalic(false);
+        painter->setFont(font);
+
+        y = fontHeight;
+    }
+
+    setPenFromSettings(painter);
+
+    painter->drawLine(0, y, w, y);
+
+    QFontMetrics fontMetrics(font);
+    UMLClassifier *classifier = (UMLClassifier*)m_umlObject;
+    UMLClassifierListItem* entityattribute = 0;
+    UMLClassifierListItemList list = classifier->getFilteredList(UMLObject::ot_EntityAttribute);
+    foreach (entityattribute, list) {
+        QString text = entityattribute->name();
+        painter->setPen(textColor());
+        UMLEntityAttribute* casted = dynamic_cast<UMLEntityAttribute*>(entityattribute);
+        if(casted && casted->indexType() == UMLEntityAttribute::Primary)
+        {
+            font.setUnderline(true);
+            painter->setFont(font);
+            font.setUnderline(false);
+        }
+        painter->drawText(ENTITY_MARGIN, y,
+                   fontMetrics.width(text), fontHeight, Qt::AlignVCenter, text);
+        painter->setFont(font);
+        y+=fontHeight;
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Saves to the "entitywidget" XMI element.
+ */
+void EntityWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("entitywidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
+
+/**
+ * Will be called when a menu selection has been made from the popup
+ * menu.
+ *
+ * @param action   The action that has been selected.
+ */
+void EntityWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_EntityAttribute:
+        if (Object_Factory::createChildObject(static_cast<UMLClassifier*>(m_umlObject),
+                                              UMLObject::ot_EntityAttribute))  {
+            UMLApp::app()->document()->setModified();
+        }
+        break;
+
+    case ListPopupMenu::mt_PrimaryKeyConstraint:
+    case ListPopupMenu::mt_UniqueConstraint:
+        if (UMLObject* obj = Object_Factory::createChildObject(static_cast<UMLEntity*>(m_umlObject),
+                                               UMLObject::ot_UniqueConstraint)) {
+            UMLApp::app()->document()->setModified();
+
+            if (sel == ListPopupMenu::mt_PrimaryKeyConstraint) {
+                UMLUniqueConstraint* uc = static_cast<UMLUniqueConstraint*>(obj);
+                static_cast<UMLEntity*>(m_umlObject)->setAsPrimaryKey(uc);
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_ForeignKeyConstraint:
+         if (Object_Factory::createChildObject(static_cast<UMLEntity*>(m_umlObject),
+                                               UMLObject::ot_ForeignKeyConstraint)) {
+             UMLApp::app()->document()->setModified();
+
+        }
+        break;
+
+    case ListPopupMenu::mt_CheckConstraint:
+         if (Object_Factory::createChildObject(static_cast<UMLEntity*>(m_umlObject),
+                                               UMLObject::ot_CheckConstraint)) {
+             UMLApp::app()->document()->setModified();
+
+        }
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF EntityWidget::minimumSize() const
+{
+    if (!m_umlObject) {
+        return UMLWidget::minimumSize();
+    }
+
+    int width, height;
+    QFont font = UMLWidget::font();
+    font.setItalic(false);
+    font.setUnderline(false);
+    font.setBold(false);
+    const QFontMetrics fm(font);
+
+    const int fontHeight = fm.lineSpacing();
+
+    int lines = 1;//always have one line - for name
+    if (!m_umlObject->stereotype().isEmpty()) {
+        lines++;
+    }
+
+    const int numberOfEntityAttributes = ((UMLEntity*)m_umlObject)->entityAttributes();
+
+    height = width = 0;
+    //set the height of the entity
+
+    lines += numberOfEntityAttributes;
+    if (numberOfEntityAttributes == 0) {
+        height += fontHeight / 2; //no entity literals, so just add a bit of space
+    }
+
+    height += lines * fontHeight;
+
+    //now set the width of the concept
+    //set width to name to start with
+    // FIXME spaces to get round beastie with font width,
+    // investigate UMLWidget::getFontMetrics()
+    width = getFontMetrics(FT_BOLD_ITALIC).boundingRect(QLatin1Char(' ') + name() +
+                                                        QLatin1Char(' ')).width();
+    const int w = getFontMetrics(FT_BOLD).boundingRect(m_umlObject->stereotype(true)).width();
+
+    width = w > width ? w : width;
+
+    UMLClassifier* classifier = (UMLClassifier*)m_umlObject;
+    UMLClassifierListItemList list = classifier->getFilteredList(UMLObject::ot_EntityAttribute);
+    UMLClassifierListItem* listItem = 0;
+    foreach (listItem, list) {
+        int w = fm.width(listItem->name());
+        width = w > width?w:width;
+    }
+
+    //allow for width margin
+    width += ENTITY_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/entitywidget.h umbrello-15.08.1/umbrello/umlwidgets/entitywidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/entitywidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/entitywidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,49 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENTITYWIDGET_H
+#define ENTITYWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLScene;
+
+#define ENTITY_MARGIN 5
+
+/**
+ * Defines a graphical version of the entity.  Most of the functionality
+ * will come from the @ref UMLWidget class from which class inherits from.
+ *
+ * @short A graphical version of an entity.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class EntityWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    explicit EntityWidget(UMLScene *scene, UMLObject* o);
+    virtual ~EntityWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    // UMLWidget::loadFromXMI is used to load this widget.
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+protected:
+    QSizeF minimumSize() const;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/enumwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/enumwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/enumwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/enumwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,262 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "enumwidget.h"
+
+// app includes
+#include "classifier.h"
+#include "classifierlistitem.h"
+#include "debug_utils.h"
+#include "enum.h"
+#include "enumliteral.h"
+#include "listpopupmenu.h"
+#include "object_factory.h"
+#include "uml.h"
+#include "umlclassifierlistitemlist.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+/**
+ * Constructs an instance of EnumWidget.
+ *
+ * @param scene   The parent of this EnumWidget.
+ * @param o       The UMLObject this will be representing.
+ */
+EnumWidget::EnumWidget(UMLScene *scene, UMLObject* o)
+  : UMLWidget(scene, WidgetBase::wt_Enum, o),
+    m_showPackage(false)
+{
+    setSize(100, 30);
+    //set defaults from m_scene
+    if (m_scene) {
+        //check to see if correct
+        const Settings::OptionState& ops = m_scene->optionState();
+        m_showPackage = ops.classState.showPackage;
+    } else {
+        // For completeness only. Not supposed to happen.
+        m_showPackage = false;
+    }
+}
+
+/**
+ * Destructor.
+ */
+EnumWidget::~EnumWidget()
+{
+}
+
+/**
+ * Returns the status of whether to show Package.
+ *
+ * @return  True if package is shown.
+ */
+bool EnumWidget::showPackage() const
+{
+    return m_showPackage;
+}
+
+/**
+ * Set the status of whether to show Package.
+ *
+ * @param _status             True if package shall be shown.
+ */
+void EnumWidget::setShowPackage(bool _status)
+{
+    m_showPackage = _status;
+    updateGeometry();
+    update();
+}
+
+/**
+ * Toggles the status of whether to show package.
+ */
+void EnumWidget::toggleShowPackage()
+{
+    m_showPackage = !m_showPackage;
+    updateGeometry();
+    update();
+}
+
+/**
+ * Draws the enum as a rectangle with a box underneith with a list of literals
+ * Reimplemented from UMLWidget::paint
+ */
+void EnumWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    setPenFromSettings(painter);
+    if(UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    else
+        painter->setBrush(m_scene->backgroundColor());
+
+    const int w = width();
+    const int h = height();
+
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    QString name;
+    if (m_showPackage) {
+        name = m_umlObject->fullyQualifiedName();
+    } else {
+        name = this->name();
+    }
+
+    painter->drawRect(0, 0, w, h);
+    painter->setPen(textColor());
+
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    painter->setFont(font);
+    painter->drawText(ENUM_MARGIN, 0,
+               w - ENUM_MARGIN * 2, fontHeight,
+               Qt::AlignCenter, m_umlObject->stereotype(true));
+
+    font.setItalic(m_umlObject->isAbstract());
+    painter->setFont(font);
+    painter->drawText(ENUM_MARGIN, fontHeight,
+               w - ENUM_MARGIN * 2, fontHeight, Qt::AlignCenter, name);
+    font.setBold(false);
+    font.setItalic(false);
+    painter->setFont(font);
+
+    int y = fontHeight * 2;
+
+    setPenFromSettings(painter);
+
+    painter->drawLine(0, y, w, y);
+
+    QFontMetrics fontMetrics(font);
+    UMLClassifier *classifier = (UMLClassifier*)m_umlObject;
+    UMLClassifierListItem* enumLiteral = 0;
+    UMLClassifierListItemList list = classifier->getFilteredList(UMLObject::ot_EnumLiteral);
+    foreach (enumLiteral, list) {
+        QString text = enumLiteral->name();
+        painter->setPen(textColor());
+        painter->drawText(ENUM_MARGIN, y,
+                   fontMetrics.width(text), fontHeight, Qt::AlignVCenter, text);
+        y+=fontHeight;
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Loads from an "enumwidget" XMI element.
+ */
+bool EnumWidget::loadFromXMI(QDomElement & qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+    QString showpackage = qElement.attribute(QLatin1String("showpackage"), QLatin1String("0"));
+
+    m_showPackage = (bool)showpackage.toInt();
+
+    return true;
+}
+
+/**
+ * Saves to the "enumwidget" XMI element.
+ */
+void EnumWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("enumwidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+
+    conceptElement.setAttribute(QLatin1String("showpackage"), m_showPackage);
+    qElement.appendChild(conceptElement);
+}
+
+/**
+ * Will be called when a menu selection has been made from the
+ * popup menu.
+ *
+ * @param action   The action that has been selected.
+ */
+void EnumWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    if (sel == ListPopupMenu::mt_EnumLiteral) {
+        if (Object_Factory::createChildObject(static_cast<UMLClassifier*>(m_umlObject),
+                                              UMLObject::ot_EnumLiteral))  {
+            /* I don't know why it works without these calls:
+            updateComponentSize();
+            update();
+             */
+            UMLApp::app()->document()->setModified();
+        }
+        return;
+    }
+    UMLWidget::slotMenuSelection(action);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF EnumWidget::minimumSize() const
+{
+    if (!m_umlObject) {
+        return UMLWidget::minimumSize();
+    }
+
+    int width, height;
+    QFont font = UMLWidget::font();
+    font.setItalic(false);
+    font.setUnderline(false);
+    font.setBold(false);
+    const QFontMetrics fm(font);
+
+    const int fontHeight = fm.lineSpacing();
+
+    int lines = 1;//always have one line - for name
+    lines++; //for the stereotype
+
+    const int numberOfEnumLiterals = ((UMLEnum*)m_umlObject)->enumLiterals();
+
+    height = width = 0;
+    //set the height of the enum
+
+    lines += numberOfEnumLiterals;
+    if (numberOfEnumLiterals == 0) {
+        height += fontHeight / 2; //no enum literals, so just add a bit of space
+    }
+
+    height += lines * fontHeight;
+
+    //now set the width of the concept
+    //set width to name to start with
+    if (m_showPackage)  {
+        width = getFontMetrics(FT_BOLD_ITALIC).boundingRect(m_umlObject->fullyQualifiedName()).width();
+    } else {
+        width = getFontMetrics(FT_BOLD_ITALIC).boundingRect(name()).width();
+    }
+    int w = getFontMetrics(FT_BOLD).boundingRect(m_umlObject->stereotype(true)).width();
+
+
+    width = w > width?w:width;
+
+    UMLClassifier *classifier = (UMLClassifier*)m_umlObject;
+    UMLClassifierListItemList list = classifier->getFilteredList(UMLObject::ot_EnumLiteral);
+    UMLClassifierListItem* listItem = 0;
+    foreach (listItem, list) {
+        int w = fm.width(listItem->name());
+        width = w > width?w:width;
+    }
+
+    //allow for width margin
+    width += ENUM_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/enumwidget.h umbrello-15.08.1/umbrello/umlwidgets/enumwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/enumwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/enumwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef ENUMWIDGET_H
+#define ENUMWIDGET_H
+
+#include "umlwidget.h"
+
+#define ENUM_MARGIN 5
+
+/**
+ * Defines a graphical version of the enum.  Most of the functionality
+ * will come from the @ref UMLWidget class from which class inherits from.
+ *
+ * @short A graphical version of an enum.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class EnumWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    explicit EnumWidget(UMLScene *scene, UMLObject* o);
+    virtual ~EnumWidget();
+
+    bool showPackage() const;
+    void setShowPackage(bool _status);
+    void toggleShowPackage();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    virtual bool loadFromXMI(QDomElement& qElement);
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+protected:
+    QSizeF minimumSize() const;
+
+    bool m_showPackage;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/floatingdashlinewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/floatingdashlinewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/floatingdashlinewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/floatingdashlinewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,199 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+// own header
+#include "floatingdashlinewidget.h"
+#include "combinedfragmentwidget.h"
+
+//kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+//app includes
+#include "debug_utils.h"
+#include "umlview.h"
+#include "widget_utils.h"
+#include "listpopupmenu.h"
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPainter>
+
+DEBUG_REGISTER_DISABLED(FloatingDashLineWidget)
+
+/**
+ * Creates a floating dash line.
+ * @param scene   The parent of the widget
+ * @param id      The ID to assign (-1 will prompt a new ID)
+ * @param parent  The CombinedFragmentWidget which acts as the parent
+ */
+FloatingDashLineWidget::FloatingDashLineWidget(UMLScene * scene, Uml::ID::Type id, CombinedFragmentWidget *parent)
+  : UMLWidget(scene, WidgetBase::wt_FloatingDashLine, id),
+    m_yMin(0),
+    m_yMax(0),
+    m_parent(parent)
+{
+    m_resizable = false;
+    m_Text = QString();
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight = fm.lineSpacing();
+    setSize(10, fontHeight);
+}
+
+/**
+ * Destructor.
+ */
+FloatingDashLineWidget::~FloatingDashLineWidget()
+{
+    if (m_parent)
+        m_parent->removeDashLine(this);
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void FloatingDashLineWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    painter->setPen(textColor());
+    painter->setFont(UMLWidget::font());
+    painter->drawText(FLOATING_DASH_LINE_TEXT_MARGIN, 0,
+               width() - FLOATING_DASH_LINE_TEXT_MARGIN * 2, fontHeight,
+               Qt::AlignLeft, QLatin1Char('[') + m_Text + QLatin1Char(']'));
+    painter->setPen(QPen(UMLWidget::lineColor(), 0, Qt::DashLine));
+    painter->drawLine(0, 0, width(), 0);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Sets m_text.
+ */
+void FloatingDashLineWidget::setText(const QString& text)
+{
+    m_Text = text;
+}
+
+/**
+ * Returns true if the given point is near the floatingdashline.
+ */
+bool FloatingDashLineWidget::onLine(const QPointF& point)
+{
+    // check if the given point is the start or end point of the line
+    if (((abs((long)(y() + height() - point.y()))) <= POINT_DELTA) || (abs((long)(y() - point.y())) <= POINT_DELTA)) {
+        return true;
+    }
+    // check if the given point is the start or end point of the line
+   return false;
+}
+
+void FloatingDashLineWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString name = m_Text;
+#if QT_VERSION >= 0x050000
+            name = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter alternative Name"), i18n("Enter the alternative:"),
+                                         QLineEdit::Normal,
+                                         m_Text, &ok);
+#else
+            name = KInputDialog::getText(i18n("Enter alternative Name"), i18n("Enter the alternative:"), m_Text, &ok);
+#endif
+            if (ok && name.length() > 0)
+                m_Text = name;
+        }
+        break;
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Overrides the setY method.
+ */
+void FloatingDashLineWidget::setY(qreal y)
+{
+    if(y >= m_yMin + FLOATING_DASH_LINE_MARGIN && y <= m_yMax - FLOATING_DASH_LINE_MARGIN)
+        UMLWidget::setY(y);
+}
+
+/**
+ * Sets m_yMin.
+ */
+void FloatingDashLineWidget::setYMin(qreal yMin)
+{
+    m_yMin = yMin;
+}
+
+/**
+ * Sets m_yMax.
+ */
+void FloatingDashLineWidget::setYMax(qreal yMax)
+{
+    m_yMax = yMax;
+}
+
+/**
+ * Returns m_yMin.
+ */
+qreal FloatingDashLineWidget::getYMin() const
+{
+    return m_yMin;
+}
+
+/**
+ * Returns the difference between the y-coordinate of the dash line and m_yMin.
+ */
+qreal FloatingDashLineWidget::getDiffY() const
+{
+    return (y() - getYMin());
+}
+
+/**
+ * Creates the "floatingdashline" XMI element.
+ */
+void FloatingDashLineWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement textElement = qDoc.createElement(QLatin1String("floatingdashlinewidget"));
+    UMLWidget::saveToXMI(qDoc, textElement);
+    textElement.setAttribute(QLatin1String("text"), m_Text);
+    textElement.setAttribute(QLatin1String("y"), y());
+    textElement.setAttribute(QLatin1String("minY"), m_yMin);
+    textElement.setAttribute(QLatin1String("maxY"), m_yMax);
+
+    qElement.appendChild(textElement);
+}
+
+/**
+ * Loads the "floatingdashline" XMI element.
+ */
+bool FloatingDashLineWidget::loadFromXMI(QDomElement & qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+    DEBUG(DBG_SRC) << "load.......";
+    m_yMax = qElement.attribute(QLatin1String("maxY")).toFloat();
+    m_yMin = qElement.attribute(QLatin1String("minY")).toFloat();
+    m_Text = qElement.attribute(QLatin1String("text"));
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/floatingdashlinewidget.h umbrello-15.08.1/umbrello/umlwidgets/floatingdashlinewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/floatingdashlinewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/floatingdashlinewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,77 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef FLOATINGDASHLINEWIDGET_H
+#define FLOATINGDASHLINEWIDGET_H
+
+#include "umlwidget.h"
+class CombinedFragmentWidget;
+
+#define FLOATING_DASH_LINE_MARGIN 25
+#define FLOATING_DASH_LINE_TEXT_MARGIN 5
+
+/* how many pixels a user could click around a point */
+#define POINT_DELTA 5
+
+/**
+ * This class is used to draw dash lines for UML combined fragments. A FloatingDashLineWidget
+ * belongs to one @ref CombinedFragmentWidget instance.
+ *
+ * The FloatingDashLineWidget class inherits from the @ref UMLWidget class.
+ *
+ * @short  A dash line for UML combined fragments.
+ * @author Thomas GALLINARI <tg8187@yahoo.fr>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class FloatingDashLineWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    explicit FloatingDashLineWidget(UMLScene * scene, Uml::ID::Type id = Uml::ID::None, CombinedFragmentWidget *parent = 0);
+    ~FloatingDashLineWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option = 0, QWidget *widget = 0);
+
+    void slotMenuSelection(QAction* action);
+
+    bool onLine(const QPointF& point);
+
+    void setText(const QString& text);
+
+    void setY(qreal y);
+    void setYMin(qreal yMin);
+    void setYMax(qreal yMax);
+    qreal getYMin() const;
+    qreal getDiffY() const;
+
+    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+    bool loadFromXMI(QDomElement & qElement);
+
+private:
+    /**
+     * Text associated to the dash line
+     */
+    QString m_text;
+
+    /**
+     * Minimum value of the Y-coordinate of the dash line
+     * (= y-coordinate of the combined fragment)
+     */
+    int m_yMin;
+
+    /**
+     * Maximum value of the Y-coordinate of the dash line
+     * (= y-coordinate of the combined fragment + height of the combined fragment)
+     */
+    int m_yMax;
+    CombinedFragmentWidget *m_parent;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/floatingtextwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/floatingtextwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/floatingtextwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/floatingtextwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,854 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "floatingtextwidget.h"
+
+// local includes
+#include "association.h"
+#include "associationwidget.h"
+#include "associationpropertiesdialog.h"
+#include "classifier.h"
+#include "cmds.h"
+#include "debug_utils.h"
+#include "linkwidget.h"
+#include "classifierwidget.h"
+#include "listpopupmenu.h"
+#include "messagewidget.h"
+#include "model_utils.h"
+#include "object_factory.h"
+#include "operation.h"
+#include "selectoperationdialog.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlview.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kfontdialog.h>
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QFontDialog>
+#include <QInputDialog>
+#endif
+#include <QPointer>
+#include <QRegExp>
+#include <QPainter>
+#include <QValidator>
+
+DEBUG_REGISTER_DISABLED(FloatingTextWidget)
+
+/**
+ * Constructs a FloatingTextWidget instance.
+ *
+ * @param scene The parent of this FloatingTextWidget.
+ * @param role The role this FloatingTextWidget will take up.
+ * @param text The main text to display.
+ * @param id The ID to assign (-1 will prompt a new ID.)
+ */
+FloatingTextWidget::FloatingTextWidget(UMLScene * scene, Uml::TextRole::Enum role, const QString& text, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Text, id),
+    m_linkWidget(0),
+    m_preText(QString()),
+    m_postText(QString()),
+    m_textRole(role),
+    m_unconstrainedPositionX(0),
+    m_unconstrainedPositionY(0),
+    m_movementDirectionX(0),
+    m_movementDirectionY(0)
+{
+    m_Text = text;
+    m_resizable = false;
+    setZValue(10); //make sure always on top.
+}
+
+/**
+ * Destructor.
+ */
+FloatingTextWidget::~FloatingTextWidget()
+{
+}
+
+/**
+ * Use to get the _main body_ of text (e.g. prepended and appended
+ * text is omitted) as currently displayed by the widget.
+ *
+ * @return The main text currently being displayed by the widget.
+ */
+QString FloatingTextWidget::text() const
+{
+    // test to make sure not just the ":" between the seq number and
+    // the actual message widget
+
+    // hmm. this section looks like it could have been avoided by
+    // using pre-, post- text instead of storing in the main body of
+    // the text -b.t.
+    if (m_textRole == Uml::TextRole::Seq_Message || m_textRole == Uml::TextRole::Seq_Message_Self ||
+            m_textRole == Uml::TextRole::Coll_Message || m_textRole == Uml::TextRole::Coll_Message_Self) {
+        if (m_Text.length() <= 1 || m_Text == QLatin1String(": "))
+            return QString();
+    }
+    return m_Text;
+}
+
+/**
+ * Set the main body of text to display.
+ *
+ * @param t The text to display.
+ */
+void FloatingTextWidget::setText(const QString &t)
+{
+    if (m_textRole == Uml::TextRole::Seq_Message || m_textRole == Uml::TextRole::Seq_Message_Self) {
+        QString op;
+        if (m_linkWidget)
+            op = m_linkWidget->lwOperationText();
+        if (op.length() > 0) {
+            if (!m_scene->showOpSig())
+                op.replace(QRegExp(QLatin1String("\\(.*\\)")), QLatin1String("()"));
+            m_Text = op;
+        }
+        else
+            m_Text = t;
+    }
+    else {
+        m_Text = t;
+    }
+
+    QSizeF s = minimumSize();
+    setSize(s.width(), s.height());
+
+    updateGeometry();
+    update();
+}
+
+/**
+ * Set some text to be prepended to the main body of text.
+ * @param t The text to prepend to main body which is displayed.
+ */
+void FloatingTextWidget::setPreText(const QString &t)
+{
+    m_preText = t;
+    updateGeometry();
+    update();
+}
+
+/**
+ * Set some text to be appended to the main body of text.
+ * @param t The text to append to main body which is displayed.
+ */
+void FloatingTextWidget::setPostText(const QString &t)
+{
+    m_postText = t;
+    updateGeometry();
+    update();
+}
+
+/**
+ * Use to get the total text (prepended + main body + appended)
+ * currently displayed by the widget.
+ *
+ * @return The text currently being displayed by the widget.
+ */
+QString FloatingTextWidget::displayText() const
+{
+    QString displayText;
+    if (!m_SequenceNumber.isEmpty())
+        displayText = m_SequenceNumber + QLatin1String(": ") + m_Text;
+    else
+        displayText = m_Text;
+    displayText.prepend(m_preText);
+    displayText.append(m_postText);
+    return displayText;
+}
+
+/**
+ * Return state if no pre, post and main text is empty
+ * @return true if widget contains no text
+ */
+bool FloatingTextWidget::isEmpty()
+{
+    return m_Text.isEmpty() && m_preText.isEmpty() && m_postText.isEmpty();
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF FloatingTextWidget::minimumSize() const
+{
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    int h = fm.lineSpacing();
+    int w = fm.width(displayText());
+    return QSizeF(w + 8, h + 4);  // give a small margin
+}
+
+/**
+ * Method used by setText: its called by  cmdsetTxt, Don't use it!
+ *
+ * @param t The text to display.
+ */
+void FloatingTextWidget::setTextcmd(const QString &t)
+{
+    UMLApp::app()->executeCommand(new Uml::CmdSetTxt(this, t));
+}
+
+/**
+ * Displays a dialog box to change the text.
+ */
+void FloatingTextWidget::showChangeTextDialog()
+{
+    bool ok = false;
+#if QT_VERSION >= 0x050000
+    QString newText = QInputDialog::getText(m_scene->activeView(),
+                                            i18n("Change Text"), i18n("Enter new text:"),
+                                            QLineEdit::Normal,
+                                            text(), &ok);
+#else
+    QString newText = KInputDialog::getText(i18n("Change Text"), i18n("Enter new text:"), text(), &ok, m_scene->activeView());
+#endif
+    if (ok && newText != text() && isTextValid(newText)) {
+        setText(newText);
+        setVisible(!text().isEmpty());
+        updateGeometry();
+        update();
+    }
+    if (!isTextValid(newText))
+        hide();
+}
+
+/**
+ * Shows an operation dialog box.
+ *
+ * @param enableAutoIncrement Enable auto increment checkbox
+ */
+void FloatingTextWidget::showOperationDialog(bool enableAutoIncrement)
+{
+    if (!m_linkWidget) {
+        uError() << "m_linkWidget is NULL";
+        return;
+    }
+    QString seqNum = m_linkWidget->sequenceNumber();
+    UMLClassifier* c = m_linkWidget->lwClassifier();
+    QString opText = m_linkWidget->lwOperationText();
+    if (!c) {
+        uError() << "m_linkWidget->lwClassifier() returns a NULL classifier";
+        return;
+    }
+
+    QPointer<SelectOperationDialog> selectDialog = new SelectOperationDialog(m_scene->activeView(), c, enableAutoIncrement);
+    if (enableAutoIncrement && m_scene->autoIncrementSequence()) {
+        seqNum = m_scene->autoIncrementSequenceValue();
+        selectDialog->setAutoIncrementSequence(true);
+    }
+    selectDialog->setSeqNumber(seqNum);
+    if (m_linkWidget->operation() == 0) {
+        selectDialog->setCustomOp(opText);
+    } else {
+        selectDialog->setClassOp(opText);
+    }
+    if (selectDialog->exec()) {
+        seqNum = selectDialog->getSeqNumber();
+        opText = selectDialog->getOpText();
+        if (selectDialog->isClassOp()) {
+            Model_Utils::OpDescriptor od;
+            Model_Utils::Parse_Status st = Model_Utils::parseOperation(opText, od, c);
+            if (st == Model_Utils::PS_OK) {
+                UMLClassifierList selfAndAncestors = c->findSuperClassConcepts();
+                selfAndAncestors.prepend(c);
+                UMLOperation *op = 0;
+                foreach (UMLClassifier *cl, selfAndAncestors) {
+                    op = cl->findOperation(od.m_name, od.m_args);
+                    if (op) {
+                        break;
+                    }
+                }
+                if (!op) {
+                    // The op does not yet exist. Create a new one.
+                    UMLObject *o = c->createOperation(od.m_name, 0, &od.m_args);
+                    op = static_cast<UMLOperation*>(o);
+                }
+                if (od.m_pReturnType) {
+                    op->setType(od.m_pReturnType);
+                }
+
+                m_linkWidget->setOperation(op);
+                opText.clear();
+            } else {
+                m_linkWidget->setOperation(0);
+            }
+        } else {
+            m_linkWidget->setOperation(0);
+        }
+        m_linkWidget->setSequenceNumber(seqNum);
+        m_linkWidget->setOperationText(opText);
+        if (enableAutoIncrement) {
+            m_scene->setAutoIncrementSequence(selectDialog->autoIncrementSequence());
+        }
+        setMessageText();
+    }
+    delete selectDialog;
+}
+
+/**
+ * Show the properties for a FloatingTextWidget.
+ * Depending on the role of the floating text wiget, the options dialog
+ * for the floating text widget, the rename dialog for floating text or
+ * the options dialog for the link widget are shown.
+ */
+void FloatingTextWidget::showPropertiesDialog()
+{
+    if (m_textRole == Uml::TextRole::Coll_Message || m_textRole == Uml::TextRole::Coll_Message_Self ||
+            m_textRole == Uml::TextRole::Seq_Message || m_textRole == Uml::TextRole::Seq_Message_Self) {
+        showOperationDialog(false);
+    } else if (m_textRole == Uml::TextRole::Floating) {
+        // double clicking on a text line opens the dialog to change the text
+        handleRename();
+    } else if (m_linkWidget) {
+        m_linkWidget->showPropertiesDialog();
+    }
+}
+
+/**
+ * Use to get the pre-text which is prepended to the main body of
+ * text to be displayed.
+ *
+ * @return The pre-text currently displayed by the widget.
+ */
+QString FloatingTextWidget::preText() const
+{
+    return m_preText;
+}
+
+/**
+ * Use to get the post-text which is appended to the main body of
+ * text to be displayed.
+ *
+ * @return The post-text currently displayed by the widget.
+ */
+QString FloatingTextWidget::postText() const
+{
+    return m_postText;
+}
+
+/**
+ * Activate the FloatingTextWidget after the saved data has been loaded
+ *
+ * @param ChangeLog Pointer to the IDChangeLog.
+ * @return  true for success
+ */
+bool FloatingTextWidget::activate(IDChangeLog* ChangeLog /*= 0 */)
+{
+    if (! UMLWidget::activate(ChangeLog))
+        return false;
+    update();
+    return true;
+}
+
+/**
+ * Set the LinkWidget that this FloatingTextWidget is related to.
+ *
+ * @param l The related LinkWidget.
+ */
+void FloatingTextWidget::setLink(LinkWidget * l)
+{
+    m_linkWidget = l;
+}
+
+/**
+ * Returns the LinkWidget this floating text is related to.
+ *
+ * @return The LinkWidget this floating text is related to.
+ */
+LinkWidget * FloatingTextWidget::link() const
+{
+    return m_linkWidget;
+}
+
+/**
+ * Sets the role type of this FloatingTextWidget.
+ *
+ * @param role  The TextRole::Enum of this FloatingTextWidget.
+ */
+void FloatingTextWidget::setTextRole(Uml::TextRole::Enum role)
+{
+    m_textRole = role;
+}
+
+/**
+ * Return the role of the text widget
+ * @return The TextRole::Enum of this FloatingTextWidget.
+ */
+Uml::TextRole::Enum FloatingTextWidget::textRole() const
+{
+    return m_textRole;
+}
+
+/**
+ * Handle the ListPopupMenu::mt_Rename case of the slotMenuSelection.
+ * Given an own method because it requires rather lengthy code.
+ */
+void FloatingTextWidget::handleRename()
+{
+    QRegExpValidator v(QRegExp(QLatin1String(".*")), 0);
+    QString t;
+    if (m_textRole == Uml::TextRole::RoleAName || m_textRole == Uml::TextRole::RoleBName) {
+        t = i18n("Enter role name:");
+    } else if (m_textRole == Uml::TextRole::MultiA || m_textRole == Uml::TextRole::MultiB) {
+        t = i18n("Enter multiplicity:");
+        /*
+        // NO! shouldn't be allowed
+        } else if (m_textRole == Uml::TextRole::ChangeA || m_textRole == Uml::TextRole::ChangeB) {
+        t = i18n("Enter changeability");
+        */
+    } else if (m_textRole == Uml::TextRole::Name) {
+        t = i18n("Enter association name:");
+    } else if (m_textRole == Uml::TextRole::Floating) {
+        t = i18n("Enter new text:");
+    } else {
+        t = i18n("ERROR");
+    }
+    bool ok = false;
+#if QT_VERSION >= 0x050000
+    QString newText = QInputDialog::getText(m_scene->activeView(),
+                                            i18n("Rename"), t,
+                                            QLineEdit::Normal,
+                                            text(), &ok);
+#else
+    QString newText = KInputDialog::getText(i18n("Rename"), t, text(), &ok, m_scene->activeView(), &v);
+#endif
+    if (!ok || newText == text()) {
+        return;
+    }
+
+    UMLApp::app()->executeCommand(new Uml::CmdHandleRename(this, newText));
+}
+
+/**
+ * Changes the text of linked widget.
+ * @param newText   the new text
+ */
+void FloatingTextWidget::changeName(const QString& newText)
+{
+    if (m_linkWidget && !isTextValid(newText)) {
+        AssociationWidget *assoc = dynamic_cast<AssociationWidget*>(m_linkWidget);
+        if (assoc) {
+            switch (m_textRole) {
+              case Uml::TextRole::MultiA:
+                assoc->setMultiplicity(QString(), Uml::RoleType::A);
+                break;
+              case Uml::TextRole::MultiB:
+                assoc->setMultiplicity(QString(), Uml::RoleType::B);
+                break;
+              case Uml::TextRole::RoleAName:
+                assoc->setRoleName(QString(), Uml::RoleType::A);
+                break;
+              case Uml::TextRole::RoleBName:
+                assoc->setRoleName(QString(), Uml::RoleType::B);
+                break;
+              case Uml::TextRole::ChangeA:
+                assoc->setChangeability(Uml::Changeability::Changeable, Uml::RoleType::A);
+                break;
+              case Uml::TextRole::ChangeB:
+                assoc->setChangeability(Uml::Changeability::Changeable, Uml::RoleType::B);
+                break;
+              default:
+                assoc->setName(QString());
+                break;
+            }
+        }
+        else {
+            MessageWidget *msg = dynamic_cast<MessageWidget*>(m_linkWidget);
+            if (msg) {
+                msg->setName(QString());
+                m_scene->removeWidget(this);
+            }
+        }
+        return;
+    }
+
+    if (m_linkWidget && m_textRole != Uml::TextRole::Seq_Message
+                     && m_textRole != Uml::TextRole::Seq_Message_Self) {
+        m_linkWidget->setText(this, newText);
+    }
+    else {
+        setText(newText);
+        UMLApp::app()->document()->setModified(true);
+    }
+
+    setVisible(true);
+    updateGeometry();
+    update();
+}
+
+/**
+ * Write property of QString m_SequenceNumber.
+ */
+void FloatingTextWidget::setSequenceNumber(const QString &sequenceNumber)
+{
+    m_SequenceNumber = sequenceNumber;
+}
+
+/**
+ * Read property of QString m_SequenceNumber.
+ */
+QString FloatingTextWidget::sequenceNumber() const
+{
+    return m_SequenceNumber;
+}
+
+/**
+ * For a text to be valid it must be non-empty, i.e. have a length
+ * larger than zero, and have at least one non whitespace character.
+ *
+ * @param text The string to analyze.
+ * @return True if the given text is valid.
+ */
+bool FloatingTextWidget::isTextValid(const QString &text)
+{
+    int length = text.length();
+    if(length < 1)
+        return false;
+    for(int i=0;i<length;i++) {
+        if(!text.at(i).isSpace()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Returns a constrained position for the widget after applying the position
+ * difference.
+ * If no link widget exists, the position returned is the current widget
+ * position with the difference applied. If there's a link, the position
+ * to be returned is constrained using constrainTextPos method from the
+ * LinkWidget, if any.
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ * @return A QPointF with the constrained new position.
+ */
+QPointF FloatingTextWidget::constrainPosition(qreal diffX, qreal diffY)
+{
+    qreal newX = x() + diffX;
+    qreal newY = y() + diffY;
+
+    if (link()) {
+        link()->constrainTextPos(newX, newY, width(), height(), textRole());
+    }
+
+    return QPointF(newX, newY);
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Moves the widget to a new position using the difference between the
+ * current position and the new position.
+ * If the floating text widget is part of a sequence message, and the
+ * message widget is selected, it does nothing: the message widget will
+ * update the text position when it's moved.
+ * In any other case, the floating text widget constrains its move using
+ * constrainPosition. When the position of the floating text is constrained,
+ * it's kept at that position until it can be moved to another valid
+ * position (m_unconstrainedPositionX/Y and m_movementDirectionX/Y are
+ * used for that).
+ * Moreover, if is part of a sequence message (and the message widget
+ * isn't selected), it updates the position of the message widget.
+ * @see constrainPosition
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void FloatingTextWidget::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    if (textRole() == Uml::TextRole::Seq_Message_Self)
+        return;
+
+    if (textRole() == Uml::TextRole::Seq_Message
+                    && ((MessageWidget*)link())->isSelected()) {
+        return;
+    }
+
+    m_unconstrainedPositionX += diffX;
+    m_unconstrainedPositionY += diffY;
+    QPointF constrainedPosition = constrainPosition(diffX, diffY);
+
+    qreal newX = constrainedPosition.x();
+    qreal newY = constrainedPosition.y();
+
+    if (!m_movementDirectionX) {
+        if (m_unconstrainedPositionX != constrainedPosition.x()) {
+            m_movementDirectionX = (diffX > 0)? 1: -1;
+        }
+    } else if ((m_movementDirectionX < 0 && m_unconstrainedPositionX > x()) ||
+               (m_movementDirectionX > 0 && m_unconstrainedPositionX < x()) ) {
+        newX = m_unconstrainedPositionX;
+        m_movementDirectionX = 0;
+    }
+
+    if (!m_movementDirectionY) {
+        if (m_unconstrainedPositionY != constrainedPosition.y()) {
+            m_movementDirectionY = (diffY > 0)? 1: -1;
+        }
+    } else if ((m_movementDirectionY < 0 && m_unconstrainedPositionY > y()) ||
+               (m_movementDirectionY > 0 && m_unconstrainedPositionY < y()) ) {
+        newY = m_unconstrainedPositionY;
+        m_movementDirectionY = 0;
+    }
+
+    setX(newX);
+    setY(newY);
+
+    if (link()) {
+        link()->calculateNameTextSegment();
+        if (textRole() == Uml::TextRole::Seq_Message) {
+            MessageWidget* messageWidget = (MessageWidget*)link();
+            messageWidget->setY(newY + height());
+        }
+    }
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Modifies the value of the diffX and diffY variables used to move the
+ * widgets.
+ * The values are constrained using constrainPosition.
+ * @see constrainPosition
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void FloatingTextWidget::constrainMovementForAllWidgets(qreal &diffX, qreal &diffY)
+{
+    QPointF constrainedPosition = constrainPosition(diffX, diffY);
+
+    diffX = constrainedPosition.x() - x();
+    diffY = constrainedPosition.y() - y();
+}
+
+/**
+ * Override method from UMLWidget in order to additionally check widget parentage.
+ *
+ * @param p Point to be checked.
+ *
+ * @return 'this' if UMLWidget::onWidget(p) returns non NULL;
+ *         else NULL.
+ */
+UMLWidget* FloatingTextWidget::onWidget(const QPointF &p)
+{
+    WidgetBase *pw = dynamic_cast<WidgetBase*>(parentItem());
+    if (pw == NULL) {
+        return WidgetBase::onWidget(p);
+    }
+    const WidgetBase::WidgetType t = pw->baseType();
+    bool isWidgetChild = false;
+    if (t == WidgetBase::wt_Interface) {
+        ClassifierWidget *cw = static_cast<ClassifierWidget*>(pw);
+        isWidgetChild = cw->getDrawAsCircle();
+    } else if (t == wt_Association ||
+               t == WidgetBase::wt_Port || t == WidgetBase::wt_Pin) {
+        isWidgetChild = true;
+    }
+    if (!isWidgetChild) {
+        return WidgetBase::onWidget(p);
+    }
+    const qreal w = width();
+    const qreal h = height();
+    const qreal left = pw->x() + x();
+    const qreal right = left + w;
+    const qreal top = pw->y() + y();
+    const qreal bottom = top + h;
+    // uDebug() << "child_of_pw; p=(" << p.x() << "," << p.y() << "), "
+    //          << "x=" << left << ", y=" << top << ", w=" << w << ", h=" << h
+    //          << "; right=" << right << ", bottom=" << bottom;
+    if (p.x() >= left && p.x() <= right &&
+        p.y() >= top && p.y() <= bottom) { // Qt coord.sys. origin in top left corner
+        // uDebug() << "floatingtext: " << m_Text;
+        return this;
+    }
+    return NULL;
+}
+
+/**
+ * Overrides default method
+ */
+void FloatingTextWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    int w = width();
+    int h = height();
+    painter->setFont(UMLWidget::font());
+    painter->setPen(textColor());
+    painter->drawText(0, 0, w, h, Qt::AlignCenter, displayText());
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Loads the "floatingtext" XMI element.
+ */
+bool FloatingTextWidget::loadFromXMI(QDomElement & qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement))
+        return false;
+
+    m_unconstrainedPositionX = x();
+    m_unconstrainedPositionY = y();
+    QString role = qElement.attribute(QLatin1String("role"));
+    if(!role.isEmpty())
+        m_textRole = Uml::TextRole::fromInt(role.toInt());
+
+    m_preText = qElement.attribute(QLatin1String("pretext"));
+    m_postText = qElement.attribute(QLatin1String("posttext"));
+    setText(qElement.attribute(QLatin1String("text")));  // use setText for geometry update
+    // If all texts are empty then this is a useless widget.
+    // In that case we return false.
+    // CAVEAT: The caller should not interpret the false return value
+    //  as an indication of failure since previous umbrello versions
+    //  saved lots of these empty FloatingTexts.
+    bool usefulWidget = !isEmpty();
+    return usefulWidget;
+}
+
+/**
+ * Reimplemented from UMLWidget::saveToXMI to save the widget
+ * data into XMI 'floatingtext' element.
+ */
+void FloatingTextWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    if (isEmpty())
+        return;
+
+    QDomElement textElement = qDoc.createElement(QLatin1String("floatingtext"));
+    UMLWidget::saveToXMI(qDoc, textElement);
+    textElement.setAttribute(QLatin1String("text"), m_Text);
+    textElement.setAttribute(QLatin1String("pretext"), m_preText);
+    textElement.setAttribute(QLatin1String("posttext"), m_postText);
+
+    /* No need to save these - the messagewidget already did it.
+    m_Operation  = qElement.attribute("operation");
+    m_SeqNum = qElement.attribute("seqnum");
+     */
+
+    textElement.setAttribute(QLatin1String("role"), m_textRole);
+    qElement.appendChild(textElement);
+}
+
+/**
+ * Called when a menu selection has been made.
+ *
+ * @param action  The action that has been selected.
+ */
+void FloatingTextWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Properties:
+        showPropertiesDialog();
+        break;
+
+    case ListPopupMenu::mt_Delete:
+        hide();   // This is only a workaround; if set then m_linkWidget should
+                  // really delete this FloatingTextWidget.
+        update();
+        m_scene->removeWidget(this);
+        break;
+
+    case ListPopupMenu::mt_New_Operation: // needed by AssociationWidget
+    case ListPopupMenu::mt_Operation:
+        {
+            if (m_linkWidget == 0) {
+                DEBUG(DBG_SRC) << "mt_Operation: m_linkWidget is NULL";
+                return;
+            }
+            UMLClassifier* c = m_linkWidget->operationOwner();
+            if (c == 0) {
+                bool ok = false;
+#if QT_VERSION >= 0x050000
+                QString opText = QInputDialog::getText(m_scene->activeView(),
+                                                       i18nc("operation name", "Name"),
+                                                       i18n("Enter operation name:"),
+                                                       QLineEdit::Normal,
+                                                       text(), &ok);
+#else
+                QString opText = KInputDialog::getText(i18nc("operation name", "Name"),
+                                                       i18n("Enter operation name:"),
+                                                       text(), &ok, m_scene->activeView());
+#endif
+                if (ok)
+                    m_linkWidget->setCustomOpText(opText);
+                return;
+            }
+            UMLClassifierListItem* umlObj = Object_Factory::createChildObject(c, UMLObject::ot_Operation);
+            if (umlObj) {
+                UMLOperation* newOperation = static_cast<UMLOperation*>(umlObj);
+                m_linkWidget->setOperation(newOperation);
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Select_Operation:
+        showOperationDialog(false);
+        break;
+
+    case ListPopupMenu::mt_Rename:
+        handleRename();
+        break;
+
+    case ListPopupMenu::mt_Change_Font:
+        {
+#if QT_VERSION >= 0x050000
+            bool ok = false;
+            QFont fnt = QFontDialog::getFont(&ok, font(), m_scene->activeView());
+            if (ok) {
+#else
+            QFont fnt = font();
+            if(KFontDialog::getFont(fnt, KFontChooser::NoDisplayFlags, m_scene->activeView())) {
+#endif
+                if(m_textRole == Uml::TextRole::Floating || m_textRole == Uml::TextRole::Seq_Message) {
+                    setFont(fnt);
+                } else if (m_linkWidget) {
+                    m_linkWidget->lwSetFont(fnt);
+                }
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Reset_Label_Positions:
+        if (m_linkWidget)
+            m_linkWidget->resetTextPositions();
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+        break;
+    }//end switch
+}
+
+/**
+ * Sets the text for this label if it is acting as a sequence diagram
+ * message or a collaboration diagram message.
+ */
+void FloatingTextWidget::setMessageText()
+{
+    if (m_linkWidget) {
+        m_linkWidget->setMessageText(this);
+        QSizeF s = minimumSize();
+        setSize(s.width(), s.height());
+
+    }
+    setVisible(!text().isEmpty());
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/floatingtextwidget.h umbrello-15.08.1/umbrello/umlwidgets/floatingtextwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/floatingtextwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/floatingtextwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,131 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef FLOATINGTEXTWIDGET_H
+#define FLOATINGTEXTWIDGET_H
+
+#include "basictypes.h"
+#include "umlwidget.h"
+
+class LinkWidget;
+class UMLScene;
+
+/**
+ * @short Displays a line of text or an operation.
+ *
+ * This is a multipurpose class. In its simplest form it will display a
+ * line of text.
+ * It can also be setup to be the text for an operation with regard to the
+ * @ref MessageWidget on the sequence diagram.
+ * It is also used for the text required for an association.
+ *
+ * The differences between all these different uses will be the popup menu
+ * that is associated with it.
+ *
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class FloatingTextWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    explicit FloatingTextWidget(UMLScene * scene, Uml::TextRole::Enum role = Uml::TextRole::Floating,
+                                const QString& text = QString(), Uml::ID::Type id = Uml::ID::None);
+    virtual ~FloatingTextWidget();
+
+    QString text() const;
+    void setText(const QString &t);
+
+    void setTextcmd(const QString &t);
+
+    QString preText() const;
+    void setPreText(const QString &t);
+
+    QString postText() const;
+    void setPostText(const QString &t);
+
+    QString displayText() const;
+
+    bool isEmpty();
+
+    void showChangeTextDialog();
+    void showOperationDialog(bool enableAutoIncrement = true);
+    virtual void showPropertiesDialog();
+
+    LinkWidget* link() const;
+    void setLink(LinkWidget * l);
+
+    bool activate(IDChangeLog* ChangeLog = 0);
+
+    Uml::TextRole::Enum textRole() const;
+    void setTextRole(Uml::TextRole::Enum role);
+
+    void handleRename();
+    void changeName(const QString& newText);
+
+    void setSequenceNumber(const QString &sequenceNumber);
+    QString sequenceNumber() const;
+
+    static bool isTextValid(const QString &text);
+
+    UMLWidget* onWidget(const QPointF& p);
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+    virtual bool loadFromXMI(QDomElement& qElement);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+    void setMessageText();
+
+protected:
+    QSizeF minimumSize() const;
+
+    virtual void moveWidgetBy(qreal diffX, qreal diffY);
+    virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY);
+
+private:
+    QPointF constrainPosition(qreal diffX, qreal diffY);
+
+    /// The association or message widget we may be linked to.
+    LinkWidget * m_linkWidget;
+
+    //////////////////// Data loaded/saved:
+
+    /// Prepended text (such as for scope of association Role or method)
+    QString m_preText;
+    /// Ending text (such as bracket on changability notation for association Role)
+    QString m_postText;
+    /// The role the text widget will enact.
+    Uml::TextRole::Enum m_textRole;
+
+    ////////
+
+    /// The horizontal position the widget would have if its move wasn't constrained.
+    qreal m_unconstrainedPositionX;
+
+    /// The vertical position the widget would have if its move wasn't constrained.
+    qreal m_unconstrainedPositionY;
+
+    /// The X direction the widget was moved when the constrain was applied.
+    /// -1 means left, 1 means right.
+    int m_movementDirectionX;
+
+    /// The Y direction the widget was moved when the constrain was applied.
+    /// -1 means up, 1 means down.
+    int m_movementDirectionY;
+
+    /// Contains sequence number for sequence or collaboration diagram message.
+    QString m_SequenceNumber;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/forkjoinwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/forkjoinwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/forkjoinwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/forkjoinwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,205 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2005-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "forkjoinwidget.h"
+
+//app includes
+#include "debug_utils.h"
+#include "umlview.h"
+#include "umldoc.h"
+#include "listpopupmenu.h"
+
+// qt includes
+#include <QColorDialog>
+
+/**
+ * Constructs a ForkJoinWidget.
+ *
+ * @param scene   The parent to this widget.
+ * @param ori     Whether to draw the plate horizontally or vertically.
+ * @param id      The ID to assign (-1 will prompt a new ID.)
+ */
+ForkJoinWidget::ForkJoinWidget(UMLScene * scene, Qt::Orientation ori, Uml::ID::Type id)
+  : BoxWidget(scene, id, WidgetBase::wt_ForkJoin),
+    m_orientation(ori)
+{
+    setSize(10, 40);
+    m_usesDiagramFillColor = false;
+    setFillColorCmd(QColor("black"));
+}
+
+/**
+ * Destructor.
+ */
+ForkJoinWidget::~ForkJoinWidget()
+{
+}
+
+/**
+ * Get whether to draw the plate vertically or horizontally.
+ */
+Qt::Orientation ForkJoinWidget::orientation() const
+{
+    return m_orientation;
+}
+
+/**
+ * Set whether to draw the plate vertically or horizontally.
+ */
+void ForkJoinWidget::setOrientation(Qt::Orientation ori)
+{
+    m_orientation = ori;
+    updateGeometry();
+    UMLWidget::adjustAssocs(x(), y());
+}
+
+/**
+ * Reimplemented from UMLWidget::paint to draw the plate of
+ * fork join.
+ */
+void ForkJoinWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    painter->fillRect(0, 0, width(), height(), fillColor());
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Reimplemented from UMLWidget::loadFromXMI to load widget
+ * info from XMI element - 'forkjoin'.
+ */
+bool ForkJoinWidget::loadFromXMI(QDomElement& qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+
+    QString drawVerticalStr = qElement.attribute(QLatin1String("drawvertical"), QLatin1String("0"));
+    bool drawVertical = (bool)drawVerticalStr.toInt();
+    if (drawVertical) {
+        setOrientation(Qt::Vertical);
+    }
+    else {
+        setOrientation(Qt::Horizontal);
+    }
+
+    return true;
+}
+
+/**
+ * Reimplemented from UMLWidget::saveToXMI to save widget info
+ * into XMI element - 'forkjoin'.
+ */
+void ForkJoinWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement fjElement = qDoc.createElement(QLatin1String("forkjoin"));
+    UMLWidget::saveToXMI(qDoc, fjElement);
+    bool drawVertical = true;
+    if (m_orientation == Qt::Horizontal) {
+        drawVertical = false;
+    }
+    fjElement.setAttribute(QLatin1String("drawvertical"), drawVertical);
+    qElement.appendChild(fjElement);
+}
+
+/**
+ * Show a properties dialog for a Fork/Join Widget.
+ */
+void ForkJoinWidget::showPropertiesDialog()
+{
+    QColor newColor = QColorDialog::getColor(fillColor()); // krazy:exclude=qclasses
+    if (newColor != fillColor()) {
+        setFillColor(newColor);
+        setUsesDiagramFillColor(false);
+        umlDoc()->setModified(true);
+    }
+}
+
+/**
+ * Reimplemented form UMLWidget::slotMenuSelection to handle
+ * Flip action.
+ */
+void ForkJoinWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch (sel) {
+    case ListPopupMenu::mt_Fill_Color:
+        showPropertiesDialog();
+        break;
+
+    case ListPopupMenu::mt_Flip:
+        switch (m_orientation) {
+        case Qt::Vertical:
+            setOrientation(Qt::Horizontal);
+            break;
+        case Qt::Horizontal:
+        default:
+            setOrientation(Qt::Vertical);
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+/**
+ * Overrides the function from UMLWidget.
+ */
+QSizeF ForkJoinWidget::minimumSize() const
+{
+    if (m_orientation == Qt::Vertical) {
+        return QSizeF(4, 40);
+    } else {
+        return QSizeF(40, 4);
+    }
+}
+
+/**
+ * Reimplement method from UMLWidget to suppress the resize corner.
+ * Although the ForkJoinWidget supports resizing, we suppress the
+ * resize corner because it is too large for this very slim widget.
+ */
+void ForkJoinWidget::paintSelected(QPainter * p, int offsetX, int offsetY)
+{
+    Q_UNUSED(p);
+    Q_UNUSED(offsetX);
+    Q_UNUSED(offsetY);
+}
+
+/**
+ * Reimplement method from UMLWidget.
+ */
+void ForkJoinWidget::constrain(qreal& width, qreal& height)
+{
+    if (m_orientation == Qt::Vertical) {
+        if (width < 4)
+            width = 4;
+        else if (width > 10)
+            width = 10;
+        if (height < 40)
+            height = 40;
+        else if (height > 100)
+            height = 100;
+    } else {
+        if (height < 4)
+            height = 4;
+        else if (height > 10)
+            height = 10;
+        if (width < 40)
+            width = 40;
+        else if (width > 100)
+            width = 100;
+    }
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/forkjoinwidget.h umbrello-15.08.1/umbrello/umlwidgets/forkjoinwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/forkjoinwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/forkjoinwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,57 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2005-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef FORKJOINWIDGET_H
+#define FORKJOINWIDGET_H
+
+//app includes
+#include "boxwidget.h"
+
+/**
+ * @short Displays a fork/join plate in a state diagram.
+ *
+ * @author Oliver Kellogg  <okellogg@users.sourceforge.net>
+ *
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ForkJoinWidget : public BoxWidget
+{
+    Q_OBJECT
+    Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+public:
+    explicit ForkJoinWidget(UMLScene * scene, Qt::Orientation ori = Qt::Horizontal, Uml::ID::Type id = Uml::ID::None);
+    virtual ~ForkJoinWidget();
+
+    Qt::Orientation orientation() const;
+    void setOrientation(Qt::Orientation ori);
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    virtual bool loadFromXMI(QDomElement & qElement);
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+    void showPropertiesDialog();
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+protected:
+    QSizeF minimumSize() const;
+
+    virtual void paintSelected(QPainter * p, int offsetX = 0, int offsetY = 0);
+
+    void constrain(qreal& width, qreal& height);
+
+private:
+    Qt::Orientation m_orientation;   ///< whether to draw the plate horizontally or vertically
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/layoutgrid.cpp umbrello-15.08.1/umbrello/umlwidgets/layoutgrid.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/layoutgrid.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/layoutgrid.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Andi Fischer <andi.fischer@hispeed.ch>            *
+ * Copyright (C) 2012 by Ralf Habacker <ralf.habacker@freenet.de>          *
+ *                                                                         *
+ * This is free software; you can redistribute it and/or modify            *
+ * it under the terms of the GNU General Public License as published by    *
+ * the Free Software Foundation; either version 2, or (at your option)     *
+ * any later version.                                                      *
+ *                                                                         *
+ * This software is distributed in the hope that it will be useful,        *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ * GNU General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License       *
+ * along with this package; see the file COPYING.  If not, write to        *
+ * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,   *
+ * Boston, MA 02110-1301, USA.                                             *
+ ***************************************************************************/
+
+#include "layoutgrid.h"
+
+#include "debug_utils.h"
+#include "umlscene.h"
+
+#include <QPainter>
+#include <QVarLengthArray>
+
+#define DBG_LOG() DEBUG(QLatin1String("LayoutGrid"))
+DEBUG_REGISTER_DISABLED(LayoutGrid)
+
+/**
+ * Constructor.
+ */
+LayoutGrid::LayoutGrid(UMLScene *scene)
+  : m_scene(scene),
+    m_gridSpacingX(25),
+    m_gridSpacingY(25),
+    m_gridDotColor(Qt::gray),
+    m_isVisible(false)
+{
+}
+
+/**
+ * Destructor.
+ */
+LayoutGrid::~LayoutGrid()
+{
+}
+
+void LayoutGrid::paint(QPainter *painter, const QRectF &rect)
+{
+    if (!isVisible())
+        return;
+
+    int gridSizeX = gridSpacingX();
+    int gridSizeY = gridSpacingY();
+
+    qreal left = int(rect.left()) - (int(rect.left()) % gridSizeX);
+    qreal top = int(rect.top()) - (int(rect.top()) % gridSizeY);
+
+    QVarLengthArray<QLineF, 200> lines;
+
+    for (qreal x = left; x < rect.right(); x += gridSizeX)
+        lines.append(QLineF(x, rect.top(), x, rect.bottom()));
+    for (qreal y = top; y < rect.bottom(); y += gridSizeY)
+        lines.append(QLineF(rect.left(), y, rect.right(), y));
+
+    painter->setPen(m_gridDotColor);
+    painter->drawLines(lines.data(), lines.size());
+}
+
+int LayoutGrid::gridSpacingX() const
+{
+    return m_gridSpacingX;
+}
+
+int LayoutGrid::gridSpacingY() const
+{
+    return m_gridSpacingY;
+}
+
+void LayoutGrid::setGridSpacing(int sizeX, int sizeY)
+{
+    DBG_LOG() << "x = " << sizeX << " / y = " << sizeY;
+    m_gridSpacingX= sizeX;
+    m_gridSpacingY= sizeY;
+}
+
+const QColor& LayoutGrid::gridDotColor() const
+{
+    return m_gridDotColor;
+}
+
+void LayoutGrid::setGridDotColor(const QColor& color)
+{
+    DBG_LOG() << "color = " << color;
+    m_gridDotColor = color;
+}
+
+bool LayoutGrid::isVisible() const
+{
+    return m_isVisible;
+}
+
+void LayoutGrid::setVisible(bool visible)
+{
+    if (m_isVisible != visible) {
+        DBG_LOG() << "visible = " << visible;
+        m_isVisible = visible;
+        m_scene->update();
+    }
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/layoutgrid.h umbrello-15.08.1/umbrello/umlwidgets/layoutgrid.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/layoutgrid.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/layoutgrid.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Andi Fischer <andi.fischer@hispeed.ch>            *
+ * Copyright (C) 2012 by Ralf Habacker <ralf.habacker@freenet.de>          *
+ *                                                                         *
+ * This is free software; you can redistribute it and/or modify            *
+ * it under the terms of the GNU General Public License as published by    *
+ * the Free Software Foundation; either version 2, or (at your option)     *
+ * any later version.                                                      *
+ *                                                                         *
+ * This software is distributed in the hope that it will be useful,        *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ * GNU General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License       *
+ * along with this package; see the file COPYING.  If not, write to        *
+ * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,   *
+ * Boston, MA 02110-1301, USA.                                             *
+ ***************************************************************************/
+
+#ifndef LAYOUTGRID_H
+#define LAYOUTGRID_H
+
+#include <QColor>
+#include <QFont>
+
+class UMLScene;
+class QRectF;
+
+/**
+ * @author Andi Fischer
+ * This class handles the layout grid, which is drawn in the background
+ * of the scene. It is used only in UMLScene.
+ */
+class LayoutGrid
+{
+public:
+    explicit LayoutGrid(UMLScene *scene);
+    ~LayoutGrid();
+
+    void paint(QPainter *painter, const QRectF &rect);
+
+    QRect gridRect() const;
+    void setGridRect(const QRect& rect);
+
+    int gridSpacingX() const;
+    int gridSpacingY() const;
+    void setGridSpacing(int sizeX, int sizeY);
+
+    const QColor& gridDotColor() const;
+    void setGridDotColor(const QColor& color);
+
+    const QColor& gridCrossColor() const;
+    void setGridCrossColor(const QColor& color);
+
+    const QColor& textColor() const;
+    void setTextColor(const QColor& color);
+
+    QFont textFont() const;
+    void setTextFont(const QFont& font);
+
+    bool isVisible() const;
+    void setVisible(bool visible);
+
+    bool isTextVisible() const;
+    void setTextVisible(bool visible);
+
+private:
+    UMLScene           *m_scene;
+    int                 m_gridSpacingX;
+    int                 m_gridSpacingY;
+    QColor              m_gridDotColor;
+    bool                m_isVisible;
+};
+
+#endif  // LAYOUTGRID_H
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/linkwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/linkwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/linkwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/linkwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,121 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "linkwidget.h"
+
+// app includes
+#include "classifier.h"
+#include "operation.h"
+#include "uml.h"
+#include "umlobject.h"
+#include "umlview.h"
+
+LinkWidget::LinkWidget()
+{
+}
+
+LinkWidget::~LinkWidget()
+{
+}
+
+/**
+ * Motivated by FloatingTextWidget::slotMenuSelection(mt_Operation)
+ */
+UMLClassifier *LinkWidget::operationOwner()
+{
+    UMLOperation *op = operation();
+    if (op == NULL)
+        return NULL;
+    return static_cast<UMLClassifier*>(op->parent());
+}
+
+/**
+ * Return the operation text.
+ * When no scene parameter is given, the scene of the current view
+ * is taken instead.
+ * @param scene   the given scene
+ * @return the operation text
+ */
+QString LinkWidget::operationText(UMLScene *scene)
+{
+    UMLOperation *op = operation();
+    if (op == NULL)
+        return customOpText();
+    if (scene == NULL)
+        scene = UMLApp::app()->currentView()->umlScene();
+    Uml::SignatureType::Enum sigType;
+    if (scene && scene->showOpSig())
+        sigType = Uml::SignatureType::SigNoVis;
+    else
+        sigType = Uml::SignatureType::NoSigNoVis;
+    QString opText = op->toString(sigType);
+    return opText;
+}
+
+/**
+ * Motivated by FloatingTextWidget::slotMenuSelection(mt_Reset_Label_Positions)
+ * Only applies to AssociationWidget.
+ */
+void LinkWidget::resetTextPositions()
+{
+}
+
+/**
+ * Motivated by FloatingTextWidget::mouseDoubleClickEvent()
+ * Only applies to AssociationWidget.
+ */
+void LinkWidget::showPropertiesDialog()
+{
+}
+
+/**
+ * Motivated by FloatingTextWidget::setLink().
+ * Only applies to AssociationWidget.
+ */
+void LinkWidget::calculateNameTextSegment()
+{
+}
+
+
+/**
+ * Write property of QString m_SequenceNumber.
+ */
+void LinkWidget::setSequenceNumber(const QString &sequenceNumber)
+{
+    m_SequenceNumber = sequenceNumber;
+}
+
+/**
+ * Read property of QString m_SequenceNumber.
+ */
+QString LinkWidget::sequenceNumber() const
+{
+    return m_SequenceNumber;
+}
+
+/**
+ * Load data from XMI.
+ */
+bool LinkWidget::loadFromXMI(QDomElement &qElement)
+{
+    m_SequenceNumber = qElement.attribute(QLatin1String("seqnum"));
+    return true;
+}
+
+/**
+ * Save data to XMI.
+ */
+void LinkWidget::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
+{
+    Q_UNUSED(qDoc);
+
+    qElement.setAttribute(QLatin1String("seqnum"), m_SequenceNumber);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/linkwidget.h umbrello-15.08.1/umbrello/umlwidgets/linkwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/linkwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/linkwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,123 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef LINKWIDGET_H
+#define LINKWIDGET_H
+
+#include "basictypes.h"
+#include "umlscene.h"
+
+#include <QFont>
+
+// forward declarations
+class UMLClassifier;
+class UMLOperation;
+class FloatingTextWidget;
+
+/**
+ * This is an interface realized by AssociationWidget and MessageWidget.
+ * The design of this interface was driven by the requirements of
+ * class FloatingTextWidget. As the architecture of Umbrello evolves (for
+ * example, if the class FloatingTextWidget is redesigned), it can be
+ * cleaned up.
+ *
+ * @short       Interface to FloatingTextWidget for AssociationWidget and MessageWidget.
+ * @author      Oliver Kellogg <okellogg@users.sourceforge.net>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class LinkWidget
+{
+public:
+    LinkWidget();
+    virtual ~LinkWidget();
+
+    /**
+     * Sets the font the widget is to use.
+     * Abstract operation implemented by inheriting classes.
+     * Motivated by FloatingTextWidget::slotMenuSelection(mt_Operation)
+     *
+     * @param font   Font to be set.
+     */
+    virtual void lwSetFont(QFont font) = 0;
+
+    virtual UMLClassifier *operationOwner();
+
+    /**
+     * Motivated by FloatingTextWidget::slotMenuSelection(mt_Operation)
+     */
+    virtual UMLOperation *operation() = 0;
+
+    /**
+     * Motivated by FloatingTextWidget::slotMenuSelection(mt_Operation)
+     */
+    virtual void setOperation(UMLOperation *op) = 0;
+
+    /**
+     * Motivated by getOperationText()
+     */
+    virtual QString customOpText() = 0;
+
+    /**
+     * Motivated by FloatingTextWidget::slotMenuSelection(mt_Operation)
+     */
+    virtual void setCustomOpText(const QString &opText) = 0;
+
+    QString operationText(UMLScene *scene = 0);
+
+    virtual void resetTextPositions();
+
+    /**
+     * Motivated by FloatingTextWidget::setMessageText()
+     */
+    virtual void setMessageText(FloatingTextWidget *ft) = 0;
+
+    /**
+     * Motivated by FloatingTextWidget::handleRename()
+     */
+    virtual void setText(FloatingTextWidget *ft, const QString &newText) = 0;
+
+    virtual void showPropertiesDialog();
+
+    /**
+     * Motivated by FloatingTextWidget::showOpDialog()
+     */
+    virtual QString lwOperationText() = 0;
+
+    /**
+     * Motivated by FloatingTextWidget::showOpDialog()
+     */
+    virtual UMLClassifier *lwClassifier() = 0;
+
+    /**
+     * Motivated by FloatingTextWidget::showOpDialog()
+     */
+    virtual void setOperationText(const QString &op) = 0;
+
+    /**
+     * Abstract operation implemented by inheriting classes.
+     * Motivated by FloatingTextWidget::mouseMoveEvent()
+     */
+    virtual void constrainTextPos(qreal &textX, qreal &textY,
+                                  qreal textWidth, qreal textHeight,
+                                  Uml::TextRole::Enum tr) = 0;
+
+    virtual void calculateNameTextSegment();
+
+    void setSequenceNumber(const QString &sequenceNumber);
+    QString sequenceNumber() const;
+
+    virtual bool loadFromXMI(QDomElement &qElement);
+    virtual void saveToXMI(QDomDocument &qDoc, QDomElement &qElement);
+
+protected:
+    QString m_SequenceNumber;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/messagewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/messagewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/messagewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/messagewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,1385 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// onw header
+#include "messagewidget.h"
+
+//app includes
+#include "classifier.h"
+#include "debug_utils.h"
+#include "floatingtextwidget.h"
+#include "listpopupmenu.h"
+#include "objectwidget.h"
+#include "operation.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlview.h"
+#include "uniqueid.h"
+#include "idchangelog.h"
+
+//qt includes
+#include <QMoveEvent>
+#include <QPainter>
+#include <QPolygon>
+#include <QResizeEvent>
+
+//kde includes
+#include <KLocalizedString>
+
+DEBUG_REGISTER_DISABLED(MessageWidget)
+
+static const int circleWidth = 10;
+
+/**
+ * Constructs a MessageWidget.
+ *
+ * This method is used for creation, synchronous and synchronous message types.
+ *
+ * @param scene   The parent to this class.
+ * @param a       The role A widget for this message.
+ * @param b       The role B widget for this message.
+ * @param y       The vertical position to display this message.
+ * @param sequenceMessageType Whether synchronous or asynchronous
+ * @param id      A unique id used for deleting this object cleanly.
+ *                The default (-1) will prompt generation of a new ID.
+ */
+MessageWidget::MessageWidget(UMLScene * scene, ObjectWidget* a, ObjectWidget* b,
+                             int y, Uml::SequenceMessage::Enum sequenceMessageType,
+                             Uml::ID::Type id /* = Uml::id_None */)
+  : UMLWidget(scene, WidgetBase::wt_Message, id)
+{
+    init();
+    m_pOw[Uml::RoleType::A] = a;
+    m_pOw[Uml::RoleType::B] = b;
+    m_sequenceMessageType = sequenceMessageType;
+    if (m_sequenceMessageType == Uml::SequenceMessage::Creation) {
+        y -= m_pOw[Uml::RoleType::B]->height() / 2;
+        m_pOw[Uml::RoleType::B]->setY(y);
+    }
+    updateResizability();
+    calculateWidget();
+    y = y < getMinY() ? getMinY() : y;
+    y = y > getMaxY() ? getMaxY() : y;
+    setY(y);
+
+    this->activate();
+}
+
+/**
+ * Constructs a MessageWidget.
+ *
+ * @param scene       The parent to this class.
+ * @param seqMsgType  The Uml::SequenceMessage::Enum of this message widget
+ * @param id          The ID to assign (-1 will prompt a new ID.)
+ */
+MessageWidget::MessageWidget(UMLScene * scene, Uml::SequenceMessage::Enum seqMsgType,
+                             Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Message, id)
+{
+    init();
+    m_sequenceMessageType = seqMsgType;
+}
+
+/**
+ * Constructs a Lost or Found MessageWidget.
+ *
+ * @param scene  The parent to this class.
+ * @param a      The role A widget for this message.
+ * @param xclick The horizontal position clicked by the user
+ * @param yclick The vertical position clicked by the user
+ * @param sequenceMessageType Whether lost or found
+ * @param id     The ID to assign (-1 will prompt a new ID.)
+ */
+MessageWidget::MessageWidget(UMLScene * scene, ObjectWidget* a, int xclick, int yclick,
+                             Uml::SequenceMessage::Enum sequenceMessageType,
+                             Uml::ID::Type id /*= Uml::id_None*/)
+  : UMLWidget(scene, WidgetBase::wt_Message, id)
+{
+    init();
+    m_pOw[Uml::RoleType::A] = a;
+    m_pOw[Uml::RoleType::B] = a;
+
+    m_sequenceMessageType = sequenceMessageType;
+
+    m_xclicked = xclick;
+    m_yclicked = yclick;
+
+    updateResizability();
+    calculateWidget();
+    yclick = yclick < getMinY() ? getMinY() : yclick;
+    yclick = yclick > getMaxY() ? getMaxY() : yclick;
+    setY(yclick);
+    m_yclicked = yclick;
+
+    this->activate();
+}
+
+/**
+ * Initializes key variables of the class.
+ */
+void MessageWidget::init()
+{
+    m_xclicked = -1;
+    m_yclicked = -1;
+    m_ignoreSnapToGrid = true;
+    m_ignoreSnapComponentSizeToGrid = true;
+    m_pOw[Uml::RoleType::A] = m_pOw[Uml::RoleType::B] = NULL;
+    m_pFText = NULL;
+}
+
+/**
+ * Standard destructor.
+ */
+MessageWidget::~MessageWidget()
+{
+}
+
+/**
+ * Sets the y-coordinate.
+ * Reimplemented from UMLWidget.
+ *
+ * @param y The y-coordinate to be set.
+ */
+void MessageWidget::setY(qreal y)
+{
+    if (y < getMinY()) {
+        DEBUG(DBG_SRC) << "got out of bounds y position, check the reason" << this->y() << getMinY();
+        return;
+    }
+
+    UMLWidget::setY(y);
+    if (m_sequenceMessageType == Uml::SequenceMessage::Creation) {
+        const qreal objWidgetHalfHeight = m_pOw[Uml::RoleType::B]->height() / 2;
+        m_pOw[Uml::RoleType::B]->setY(y - objWidgetHalfHeight);
+    }
+
+    if (m_pFText && !UMLApp::app()->document()->loading()) {
+        setTextPosition();
+        emit sigMessageMoved();
+    }
+}
+
+/**
+ * Update the UMLWidget::m_resizable flag according to the
+ * charactersitics of this message.
+ */
+void MessageWidget::updateResizability()
+{
+    if (m_sequenceMessageType == Uml::SequenceMessage::Synchronous)
+        UMLWidget::m_resizable = true;
+    else
+        UMLWidget::m_resizable = false;
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Returns the cursor to be shown when resizing the widget.
+ * The cursor shown is KCursor::sizeVerCursor().
+ *
+ * @return The cursor to be shown when resizing the widget.
+ */
+QCursor MessageWidget::resizeCursor() const
+{
+    return Qt::SizeVerCursor;
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Resizes the height of the message widget and emits the message moved signal.
+ * Message widgets can only be resized vertically, so width isn't modified.
+ *
+ * @param newW   The new width for the widget (isn't used).
+ * @param newH   The new height for the widget.
+ */
+void MessageWidget::resizeWidget(qreal newW, qreal newH)
+{
+    if (sequenceMessageType() == Uml::SequenceMessage::Creation)
+        setSize(width(), newH);
+    else {
+        qreal x1 = m_pOw[Uml::RoleType::A]->x();
+        qreal x2 = getxclicked();
+        qreal diffX = 0;
+        if (x1 < x2) {
+            diffX = x2 + (newW - width());
+        }
+        else {
+            diffX = x2 - (newW - width());
+        }
+        if (diffX <= 0 )
+            diffX = 10;
+        setxclicked (diffX);
+        setSize(newW, newH);
+        calculateWidget();
+
+    }
+    emit sigMessageMoved();
+}
+
+/**
+ * Constrains the vertical position of the message widget so it doesn't go
+ * upper than the bottom side of the lower object.
+ * The height of the floating text widget in the message is taken in account
+ * if there is any and isn't empty.
+ *
+ * @param diffY The difference between current Y position and new Y position.
+ * @return The new Y position, constrained.
+ */
+qreal MessageWidget::constrainPositionY(qreal diffY)
+{
+    qreal newY = y() + diffY;
+
+    qreal minY = getMinY();
+    if (m_pFText && !m_pFText->displayText().isEmpty()) {
+        minY += m_pFText->height();
+    }
+
+    if (newY < minY) {
+        newY = minY;
+    }
+
+    return newY;
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Moves the widget to a new position using the difference between the
+ * current position and the new position. X position is ignored, and widget
+ * is only moved along Y axis. If message goes upper than the object, it's
+ * kept at this position until it should be lowered again (the unconstrained
+ * Y position is saved to know when it's the time to lower it again).
+ * If the message is a creation message, the object created is also moved to
+ * the new vertical position.
+ * @see constrainPositionY
+ *
+ * @param diffX The difference between current X position and new X position
+ *                          (isn't used).
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void MessageWidget::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    Q_UNUSED(diffX);
+    qreal newY = constrainPositionY(diffY);
+    setY(newY);
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Modifies the value of the diffX and diffY variables used to move the widgets.
+ * All the widgets are constrained to be moved only in Y axis (diffX is set to 0).
+ * @see constrainPositionY
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void MessageWidget::constrainMovementForAllWidgets(qreal &diffX, qreal &diffY)
+{
+    diffX = 0;
+    diffY = constrainPositionY(diffY) - y();
+}
+
+/**
+ * Reimplemented from UMLWidget and calls other paint...() methods
+ * depending on the message type.
+ */
+void MessageWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    if(!m_pOw[Uml::RoleType::A] || !m_pOw[Uml::RoleType::B]) {
+        return;
+    }
+    setPenFromSettings(painter);
+    if (m_sequenceMessageType == Uml::SequenceMessage::Synchronous) {
+        paintSynchronous(painter, option);
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Asynchronous) {
+        paintAsynchronous(painter, option);
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Creation) {
+        paintCreation(painter, option);
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Lost) {
+        paintLost(painter, option);
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Found) {
+        paintFound(painter, option);
+    } else {
+        uWarning() << "Unknown message type";
+    }
+}
+
+/**
+ * Draw a solid (triangular) arrowhead pointing in the given direction.
+ * The direction can be either Qt::LeftArrow or Qt::RightArrow.
+ */
+void MessageWidget::paintSolidArrowhead(QPainter *p, int x, int y, Qt::ArrowType direction)
+{
+    int arrowheadExtentX = 4;
+    if (direction == Qt::RightArrow) {
+        arrowheadExtentX = -arrowheadExtentX;
+    }
+    QPolygon points;
+    points.putPoints(0, 3, x, y, x + arrowheadExtentX, y - 3, x + arrowheadExtentX, y + 3);
+    p->setBrush(QBrush(p->pen().color()));
+    p->drawPolygon(points);
+}
+
+/**
+ * Draw an arrow pointing in the given direction.
+ * The arrow head is not solid, i.e. it is made up of two lines
+ * like so:  --->
+ * The direction can be either Qt::LeftArrow or Qt::RightArrow.
+ */
+void MessageWidget::paintArrow(QPainter *p, int x, int y, int w,
+                              Qt::ArrowType direction, bool useDottedLine /* = false */)
+{
+    if (w > 3) {
+        int arrowheadStartX = x;
+        int arrowheadExtentX = 4;
+        if (direction == Qt::RightArrow) {
+            arrowheadStartX += w;
+            arrowheadExtentX = -arrowheadExtentX;
+        }
+        // draw upper half of arrowhead
+        p->drawLine(arrowheadStartX, y, arrowheadStartX + arrowheadExtentX, y - 3);
+        // draw lower half of arrowhead
+        p->drawLine(arrowheadStartX, y, arrowheadStartX + arrowheadExtentX, y + 3);
+    }
+    // draw arrow line
+    if (useDottedLine) {
+        QPen pen = p->pen();
+        pen.setStyle(Qt::DotLine);
+        p->setPen(pen);
+    }
+    p->drawLine(x, y, x + w, y);
+}
+
+/**
+ * Draws the calling arrow with filled in arrowhead, the
+ * timeline box and the returning arrow with a dashed line and
+ * stick arrowhead.
+ */
+void MessageWidget::paintSynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    int x1 = m_pOw[Uml::RoleType::A]->x();
+    int x2 = m_pOw[Uml::RoleType::B]->x();
+    int w = width() - 1;
+    int h = height();
+    int offsetX = 0;
+    int offsetY = 0;
+
+    bool messageOverlaps = m_pOw[Uml::RoleType::A]->messageOverlap(y(), this);
+    const int boxWidth = 17;
+    const int wr = w < boxWidth ? w : boxWidth;
+    const int arrowWidth = 4;
+
+    if(isSelf()) {
+        painter->fillRect(offsetX, offsetY, wr, h,  QBrush(Qt::white));              //box
+        painter->drawRect(offsetX, offsetY, wr, h);                                    //box
+        offsetX += wr;
+        w -= wr;
+        offsetY += 3;
+        const int lowerLineY = offsetY + h - 6;
+        // draw upper line segment (leaving the life line)
+        painter->drawLine(offsetX, offsetY, offsetX + w, offsetY);
+        // draw line segment parallel to (and at the right of) the life line
+        painter->drawLine(offsetX + w, offsetY, offsetX + w, lowerLineY);
+        // draw lower line segment (back to the life line)
+        paintArrow(painter, offsetX, lowerLineY, w, Qt::LeftArrow);
+        offsetX -= wr;
+        offsetY -= 3;
+    } else if(x1 < x2) {
+        if (messageOverlaps)  {
+            offsetX += 8;
+            w -= 8;
+        }
+        QPen pen = painter->pen();
+        int startX = offsetX + w - wr + 1;
+        painter->fillRect(startX, offsetY, wr, h,  QBrush(Qt::white));         //box
+        painter->drawRect(startX, offsetY, wr, h);                             //box
+        painter->drawLine(offsetX, offsetY + arrowWidth, startX, offsetY + arrowWidth);          //arrow line
+        if (w > boxWidth + arrowWidth)
+            paintSolidArrowhead(painter, startX - 1, offsetY + arrowWidth, Qt::RightArrow);
+        paintArrow(painter, offsetX, offsetY + h - arrowWidth + 1, w - wr + 1, Qt::LeftArrow, true); // return arrow
+        if (messageOverlaps)  {
+            offsetX -= 8; //reset for drawSelected()
+        }
+    } else      {
+        if (messageOverlaps)  {
+            w -=8;
+        }
+        QPen pen = painter->pen();
+        painter->fillRect(offsetX, offsetY, wr, h,  QBrush(Qt::white));              //box
+        painter->drawRect(offsetX, offsetY, wr, h);                                    //box
+        painter->drawLine(offsetX + wr + 1, offsetY + arrowWidth, offsetX + w, offsetY + arrowWidth);    //arrow line
+        if (w > boxWidth + arrowWidth)
+            paintSolidArrowhead(painter, offsetX + wr, offsetY + arrowWidth, Qt::LeftArrow);
+        paintArrow(painter, offsetX + wr + 1, offsetY + h - arrowWidth + 1, w - wr - 1, Qt::RightArrow, true); // return arrow
+    }
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * Draws a solid arrow line and a stick arrow head.
+ */
+void MessageWidget::paintAsynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    int x1 = m_pOw[Uml::RoleType::A]->x();
+    int x2 = m_pOw[Uml::RoleType::B]->x();
+    int w = width() - 1;
+    int h = height() - 1;
+    int offsetX = 0;
+    int offsetY = 0;
+    bool messageOverlapsA = m_pOw[Uml::RoleType::A]->messageOverlap(y(), this);
+    //bool messageOverlapsB = m_pOw[Uml::RoleType::B]->messageOverlap(y(), this);
+
+    if(isSelf()) {
+        if (messageOverlapsA)  {
+            offsetX += 7;
+            w -= 7;
+        }
+        const int lowerLineY = offsetY + h - 3;
+        // draw upper line segment (leaving the life line)
+        painter->drawLine(offsetX, offsetY, offsetX + w, offsetY);
+        // draw line segment parallel to (and at the right of) the life line
+        painter->drawLine(offsetX + w, offsetY, offsetX + w, lowerLineY);
+        // draw lower line segment (back to the life line)
+        paintArrow(painter, offsetX, lowerLineY, w, Qt::LeftArrow);
+        if (messageOverlapsA)  {
+            offsetX -= 7; //reset for drawSelected()
+        }
+    } else if(x1 < x2) {
+        if (messageOverlapsA) {
+            offsetX += 7;
+            w -= 7;
+        }
+        paintArrow(painter, offsetX, offsetY + 4, w, Qt::RightArrow);
+        if (messageOverlapsA) {
+            offsetX -= 7;
+        }
+    } else      {
+        if (messageOverlapsA) {
+            w -= 7;
+        }
+        paintArrow(painter, offsetX, offsetY + 4, w, Qt::LeftArrow);
+    }
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * Draws a solid arrow line and a stick arrow head to the
+ * edge of the target object widget instead of to the
+ * sequence line.
+ */
+void MessageWidget::paintCreation(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    int x1 = m_pOw[Uml::RoleType::A]->x();
+    int x2 = m_pOw[Uml::RoleType::B]->x();
+    int w = width();
+    //int h = height() - 1;
+    int offsetX = 0;
+    int offsetY = 0;
+    bool messageOverlapsA = m_pOw[Uml::RoleType::A]->messageOverlap(y(), this);
+    //bool messageOverlapsB = m_pOw[Uml::RoleType::B]->messageOverlap(y(), this);
+
+    const int lineY = offsetY + 4;
+    if (x1 < x2) {
+        if (messageOverlapsA) {
+            offsetX += 7;
+            w -= 7;
+        }
+        paintArrow(painter, offsetX, lineY, w, Qt::RightArrow);
+        if (messageOverlapsA) {
+            offsetX -= 7;
+        }
+    } else      {
+        if (messageOverlapsA) {
+            w -= 7;
+        }
+        paintArrow(painter, offsetX, lineY, w, Qt::LeftArrow);
+    }
+
+    UMLWidget::paint(painter, option);
+}
+
+
+/**
+ * Draws a solid arrow line and a stick arrow head
+ * and a circle
+ */
+void MessageWidget::paintLost(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_xclicked;
+    int w = width();
+    int h = height();
+    int offsetX = 0;
+    int offsetY = 0;
+    bool messageOverlapsA = m_pOw[Uml::RoleType::A]->messageOverlap(y(), this);
+    //bool messageOverlapsB = m_pOw[Uml::RoleType::B]->messageOverlap(y(), this);
+
+    if(x1 < x2) {
+        if (messageOverlapsA)  {
+            offsetX += 7;
+            w -= 7;
+        }
+
+        setPenFromSettings(painter);
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(offsetX + w - h, offsetY, h, h);
+        paintArrow(painter, offsetX, offsetY + h/2, w - h, Qt::RightArrow);
+
+        if (messageOverlapsA)  {
+            offsetX -= 7;
+        }
+    } else      {
+        setPenFromSettings(painter);
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(offsetX, offsetY, h, h);
+        paintArrow(painter, offsetX + h, offsetY + h/2, w - h, Qt::LeftArrow);
+    }
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * Draws a circle and a solid arrow line and a stick arrow head.
+ */
+void MessageWidget::paintFound(QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_xclicked;
+    int w = width();
+    int h = height();
+    int offsetX = 0;
+    int offsetY = 0;
+    bool messageOverlapsA = m_pOw[Uml::RoleType::A]->messageOverlap(y(), this);
+    //bool messageOverlapsB = m_pOw[Uml::RoleType::B]->messageOverlap(y(), this);
+
+    if(x1 < x2) {
+        if (messageOverlapsA)  {
+            offsetX += 7;
+            w -= 7;
+        }
+        setPenFromSettings(painter);
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(offsetX + w - h, offsetY, h, h);
+        paintArrow(painter, offsetX, offsetY + h/2, w, Qt::LeftArrow);
+        if (messageOverlapsA)  {
+            offsetX -= 7;
+        }
+    } else {
+        if (messageOverlapsA)  {
+            w -= 7;
+        }
+        setPenFromSettings(painter);
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(offsetX, offsetY, h, h);
+        paintArrow(painter, offsetX, offsetY + h/2, w, Qt::RightArrow);
+    }
+
+    UMLWidget::paint(painter, option);
+}
+
+/**
+ * Overrides operation from UMLWidget.
+ *
+ * @param p Point to be checked.
+ *
+ * @return 'this' if the point is on a part of the MessageWidget.
+ *         NB In case of a synchronous message, the empty space
+ *         between call line and return line does not count, i.e. if
+ *         the point is located in that space the function returns NULL.
+ */
+UMLWidget* MessageWidget::onWidget(const QPointF& p)
+{
+    if (m_sequenceMessageType != Uml::SequenceMessage::Synchronous) {
+        return UMLWidget::onWidget(p);
+    }
+    // Synchronous message:
+    // Consists of top arrow (call) and bottom arrow (return.)
+    if (p.x() < x() || p.x() > x() + width())
+        return NULL;
+    const int tolerance = 5;  // pixels
+    const int pY = p.y();
+    const int topArrowY = y() + 3;
+    const int bottomArrowY = y() + height() - 3;
+    if (pY < topArrowY - tolerance || pY > bottomArrowY + tolerance)
+        return NULL;
+    if (height() <= 2 * tolerance)
+        return this;
+    if (pY > topArrowY + tolerance && pY < bottomArrowY - tolerance)
+        return NULL;
+    return this;
+}
+
+/**
+ * Sets the text position relative to the sequence message.
+ */
+void MessageWidget::setTextPosition()
+{
+    if (m_pFText == NULL) {
+        DEBUG(DBG_SRC) << "m_pFText is NULL";
+        return;
+    }
+    if (m_pFText->displayText().isEmpty()) {
+        return;
+    }
+    m_pFText->updateGeometry();
+    int ftX = constrainX(m_pFText->x(), m_pFText->width(), m_pFText->textRole());
+    int ftY = y() - m_pFText->height();
+    m_pFText->setX(ftX);
+    m_pFText->setY(ftY);
+}
+
+/**
+ * Returns the textX arg with constraints applied.
+ * Auxiliary to setTextPosition() and constrainTextPos().
+ */
+int MessageWidget::constrainX(int textX, int textWidth, Uml::TextRole::Enum tr)
+{
+    int result = textX;
+    const int minTextX = x() + 5;
+    if (textX < minTextX || tr == Uml::TextRole::Seq_Message_Self) {
+        result = minTextX;
+    } else {
+        ObjectWidget *objectAtRight = NULL;
+        if (m_pOw[Uml::RoleType::B]->x() > m_pOw[Uml::RoleType::A]->x())
+            objectAtRight = m_pOw[Uml::RoleType::B];
+        else
+            objectAtRight = m_pOw[Uml::RoleType::A];
+        const int objRight_seqLineX = objectAtRight->centerX();
+        const int maxTextX = objRight_seqLineX - textWidth - 5;
+        if (maxTextX <= minTextX)
+            result = minTextX;
+        else if (textX > maxTextX)
+            result = maxTextX;
+    }
+    return result;
+}
+
+/**
+ * Constrains the FloatingTextWidget X and Y values supplied.
+ * Overrides operation from LinkWidget.
+ *
+ * @param textX        candidate X value (may be modified by the constraint)
+ * @param textY        candidate Y value (may be modified by the constraint)
+ * @param textWidth    width of the text
+ * @param textHeight   height of the text
+ * @param tr           Uml::TextRole::Enum of the text
+ */
+void MessageWidget::constrainTextPos(qreal &textX, qreal &textY, qreal textWidth, qreal textHeight,
+                                     Uml::TextRole::Enum tr)
+{
+    textX = constrainX(textX, textWidth, tr);
+    // Constrain Y.
+    const qreal minTextY = getMinY();
+    const qreal maxTextY = getMaxY() - textHeight - 5;
+    if (textY < minTextY)
+        textY = minTextY;
+    else if (textY > maxTextY)
+        textY = maxTextY;
+//     setY(textY + textHeight);   // NB: side effect
+}
+
+/**
+ * Shortcut for calling m_pFText->setLink() followed by
+ * this->setTextPosition().
+ */
+void MessageWidget::setLinkAndTextPos()
+{
+    if (m_pFText) {
+        m_pFText->setLink(this);
+        setTextPosition();
+    }
+}
+
+void MessageWidget::resizeEvent(QResizeEvent* /*re*/)
+{
+}
+
+/**
+ * Calculate the geometry of the widget.
+ */
+void MessageWidget::calculateWidget()
+{
+    setMessageText(m_pFText);
+    calculateDimensions();
+    setVisible(true);
+}
+
+void MessageWidget::slotWidgetMoved(Uml::ID::Type id)
+{
+    const Uml::ID::Type idA = m_pOw[Uml::RoleType::A]->localID();
+    const Uml::ID::Type idB = m_pOw[Uml::RoleType::B]->localID();
+    if (idA != id && idB != id) {
+        DEBUG(DBG_SRC) << "id=" << Uml::ID::toString(id) << ": ignoring for idA=" << Uml::ID::toString(idA)
+            << ", idB=" << Uml::ID::toString(idB);
+        return;
+    }
+    qreal y = this->y();
+    if (y < getMinY())
+        y = getMinY();
+    if (y > getMaxY())
+        y = getMaxY();
+    setPos(x(), y);
+    calculateWidget();
+    if(!m_pFText)
+        return;
+    if (m_scene->selectedCount(true) > 1)
+        return;
+    setTextPosition();
+}
+
+/**
+ * Check to see if the given ObjectWidget is involved in the message.
+ *
+ * @param w The ObjectWidget to check for.
+ * @return  true - if is contained, false - not contained.
+ */
+bool MessageWidget::hasObjectWidget(ObjectWidget * w)
+{
+    if(m_pOw[Uml::RoleType::A] == w || m_pOw[Uml::RoleType::B] == w)
+        return true;
+    else
+        return false;
+}
+
+/**
+ * This method determines whether the message is for "Self" for
+ * an ObjectWidget.
+ *
+ * @retval True If both ObjectWidgets for this widget exists and
+ *              are same.
+ */
+bool MessageWidget::isSelf() const
+{
+    return (m_pOw[Uml::RoleType::A] && m_pOw[Uml::RoleType::B] &&
+            m_pOw[Uml::RoleType::A] == m_pOw[Uml::RoleType::B]);
+}
+
+void MessageWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    if (sel == ListPopupMenu::mt_Delete) {
+        // This will clean up this widget and the text widget:
+        m_scene->removeWidget(this);
+    } else {
+
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Activates a MessageWidget.  Connects its m_pOw[] pointers
+ * to UMLObjects and also send signals about its FloatingTextWidget.
+ */
+bool MessageWidget::activate(IDChangeLog * /*Log = 0*/)
+{
+    m_scene->resetPastePoint();
+    // UMLWidget::activate(Log);   CHECK: I don't think we need this ?
+    if (m_pOw[Uml::RoleType::A] == NULL) {
+        UMLWidget *pWA = m_scene->findWidget(m_widgetAId);
+        if (pWA == NULL) {
+            DEBUG(DBG_SRC) << "role A object " << Uml::ID::toString(m_widgetAId) << " not found";
+            return false;
+        }
+        m_pOw[Uml::RoleType::A] = dynamic_cast<ObjectWidget*>(pWA);
+        if (m_pOw[Uml::RoleType::A] == NULL) {
+            DEBUG(DBG_SRC) << "role A widget " << Uml::ID::toString(m_widgetAId)
+                << " is not an ObjectWidget";
+            return false;
+        }
+    }
+    if (m_pOw[Uml::RoleType::B] == NULL) {
+        UMLWidget *pWB = m_scene->findWidget(m_widgetBId);
+        if (pWB == NULL) {
+            DEBUG(DBG_SRC) << "role B object " << Uml::ID::toString(m_widgetBId) << " not found";
+            return false;
+        }
+        m_pOw[Uml::RoleType::B] = dynamic_cast<ObjectWidget*>(pWB);
+        if (m_pOw[Uml::RoleType::B] == NULL) {
+            DEBUG(DBG_SRC) << "role B widget " << Uml::ID::toString(m_widgetBId)
+                << " is not an ObjectWidget";
+            return false;
+        }
+    }
+    updateResizability();
+
+    UMLClassifier *c = dynamic_cast<UMLClassifier*>(m_pOw[Uml::RoleType::B]->umlObject());
+    UMLOperation *op = NULL;
+    if (c && !m_CustomOp.isEmpty()) {
+        Uml::ID::Type opId = Uml::ID::fromString(m_CustomOp);
+        op = dynamic_cast<UMLOperation*>(c->findChildObjectById(opId, true));
+        if (op) {
+            // If the UMLOperation is set, m_CustomOp isn't used anyway.
+            // Just setting it empty for the sake of sanity.
+            m_CustomOp.clear();
+        }
+    }
+
+    if(!m_pFText) {
+        Uml::TextRole::Enum tr = Uml::TextRole::Seq_Message;
+        if (isSelf())
+            tr = Uml::TextRole::Seq_Message_Self;
+        m_pFText = new FloatingTextWidget(m_scene, tr, operationText(m_scene));
+        m_scene->addFloatingTextWidget(m_pFText);
+        m_pFText->setFontCmd(UMLWidget::font());
+    }
+    if (op)
+        setOperation(op);  // This requires a valid m_pFText.
+    setLinkAndTextPos();
+    m_pFText->setText(QString());
+    m_pFText->setActivated();
+    QString messageText = m_pFText->text();
+    m_pFText->setVisible(messageText.length() > 1);
+
+    connect(m_pOw[Uml::RoleType::A], SIGNAL(sigWidgetMoved(Uml::ID::Type)), this, SLOT(slotWidgetMoved(Uml::ID::Type)));
+    connect(m_pOw[Uml::RoleType::B], SIGNAL(sigWidgetMoved(Uml::ID::Type)), this, SLOT(slotWidgetMoved(Uml::ID::Type)));
+
+    connect(this, SIGNAL(sigMessageMoved()), m_pOw[Uml::RoleType::A], SLOT(slotMessageMoved()));
+    connect(this, SIGNAL(sigMessageMoved()), m_pOw[Uml::RoleType::B], SLOT(slotMessageMoved()));
+    m_pOw[Uml::RoleType::A]->messageAdded(this);
+    if (!isSelf())
+        m_pOw[Uml::RoleType::B]->messageAdded(this);
+
+    // Calculate the size and position of the message widget
+    calculateDimensions();
+
+    // Position the floating text accordingly
+    setTextPosition();
+
+    emit sigMessageMoved();
+    return true;
+}
+
+/**
+ * Resolve references of this message so they reference the correct
+ * new object widgets after paste.
+ */
+void MessageWidget::resolveObjectWidget(IDChangeLog* log) {
+    m_widgetAId = log->findNewID(m_widgetAId);
+    m_widgetBId = log->findNewID(m_widgetBId);
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @param ft   The text widget which to update.
+ */
+void MessageWidget::setMessageText(FloatingTextWidget *ft)
+{
+    if (ft == NULL)
+        return;
+    ft->setSequenceNumber(m_SequenceNumber);
+    ft->setText(operationText(m_scene));
+    setTextPosition();
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @param ft        The text widget which to update.
+ * @param newText   The new text to set.
+ */
+void MessageWidget::setText(FloatingTextWidget *ft, const QString &newText)
+{
+    ft->setText(newText);
+    UMLApp::app()->document()->setModified(true);
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ *
+ * @param op        The new operation string to set.
+ */
+void MessageWidget::setOperationText(const QString &op)
+{
+    m_CustomOp = op;   ///FIXME m_pOperation
+}
+
+/**
+ * Implements operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+void MessageWidget::lwSetFont (QFont font)
+{
+    UMLWidget::setFont(font);
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ * @todo Move to LinkWidget.
+ */
+UMLClassifier *MessageWidget::operationOwner()
+{
+    UMLObject *pObject = m_pOw[Uml::RoleType::B]->umlObject();
+    if (pObject == NULL)
+        return NULL;
+    UMLClassifier *c = dynamic_cast<UMLClassifier*>(pObject);
+    return c;
+}
+
+/**
+ * Implements operation from LinkWidget.
+ * Motivated by FloatingTextWidget.
+ */
+UMLOperation *MessageWidget::operation()
+{
+    return static_cast<UMLOperation*>(m_umlObject);
+}
+
+/**
+ * Implements operation from LinkWidget.
+ * Motivated by FloatingTextWidget.
+ */
+void MessageWidget::setOperation(UMLOperation *op)
+{
+    if (m_umlObject && m_pFText)
+        disconnect(m_umlObject, SIGNAL(modified()), m_pFText, SLOT(setMessageText()));
+    m_umlObject = op;
+    if (m_umlObject && m_pFText) {
+        connect(m_umlObject, SIGNAL(modified()), m_pFText, SLOT(setMessageText()));
+        m_pFText->setMessageText();
+    }
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+QString MessageWidget::customOpText()
+{
+    return m_CustomOp;
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+void MessageWidget::setCustomOpText(const QString &opText)
+{
+    m_CustomOp = opText;
+    m_pFText->setMessageText();
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+QString MessageWidget::lwOperationText()
+{
+    UMLOperation *pOperation = operation();
+    if (pOperation != NULL) {
+        return pOperation->toString(Uml::SignatureType::SigNoVis);
+    } else {
+        return customOpText();
+    }
+}
+
+/**
+ * Overrides operation from LinkWidget.
+ * Required by FloatingTextWidget.
+ */
+UMLClassifier *MessageWidget::lwClassifier()
+{
+    UMLObject *o = m_pOw[Uml::RoleType::B]->umlObject();
+    UMLClassifier *c = dynamic_cast<UMLClassifier*>(o);
+    return c;
+}
+
+/**
+ * Calculates the size of the widget by calling
+ * calculateDimensionsSynchronous(),
+ * calculateDimensionsAsynchronous(), or
+ * calculateDimensionsCreation()
+ */
+void MessageWidget::calculateDimensions()
+{
+    if (m_sequenceMessageType == Uml::SequenceMessage::Synchronous) {
+        calculateDimensionsSynchronous();
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Asynchronous) {
+        calculateDimensionsAsynchronous();
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Creation) {
+        calculateDimensionsCreation();
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Lost) {
+        calculateDimensionsLost();
+    } else if (m_sequenceMessageType == Uml::SequenceMessage::Found) {
+        calculateDimensionsFound();
+    } else {
+        uWarning() << "Unknown message type";
+    }
+    if (! UMLApp::app()->document()->loading()) {
+        adjustAssocs(x(), y());  // adjust assoc lines
+    }
+}
+
+/**
+ * Calculates and sets the size of the widget for a synchronous message.
+ */
+void MessageWidget::calculateDimensionsSynchronous()
+{
+    int x = 0;
+
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_pOw[Uml::RoleType::B]->centerX();
+
+    int widgetWidth = 0;
+    int widgetHeight = 0;
+    if(isSelf()) {
+        widgetWidth = 50;
+        x = x1 - 2;
+    } else if(x1 < x2) {
+        x = x1;
+        widgetWidth = x2 - x1 + 8;
+    } else {
+        x = x2 - 8;
+        widgetWidth = x1 - x2 + 8;
+    }
+
+    if (height() < 20) {
+        widgetHeight = 20;
+    } else {
+        widgetHeight = height();
+    }
+
+    setX(x);
+    setSize(widgetWidth, widgetHeight);
+}
+
+/**
+ * Calculates and sets the size of the widget for an asynchronous message.
+ */
+void MessageWidget::calculateDimensionsAsynchronous()
+{
+    int x = 0;
+
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_pOw[Uml::RoleType::B]->centerX();
+
+    int widgetWidth = 0;
+    int widgetHeight = 8;
+    if(isSelf()) {
+        widgetWidth = 50;
+        x = x1;
+        if(height() < 20) {
+            widgetHeight = 20;
+        } else {
+            widgetHeight = height();
+        }
+    } else if(x1 < x2) {
+        x = x1;
+        widgetWidth = x2 - x1;
+    } else {
+        x = x2;
+        widgetWidth = x1 - x2;
+    }
+    x += 1;
+    widgetWidth -= 2;
+    setX(x);
+    setSize(widgetWidth, widgetHeight);
+}
+
+/**
+ * Calculates and sets the size of the widget for a creation message.
+ */
+void MessageWidget::calculateDimensionsCreation()
+{
+    int x = 0;
+
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_pOw[Uml::RoleType::B]->x();
+    int w2 = m_pOw[Uml::RoleType::B]->width();
+
+    if (x1 > x2)
+        x2 += w2;
+
+    int widgetWidth = 0;
+    int widgetHeight = 8;
+    if (x1 < x2) {
+        x = x1;
+        widgetWidth = x2 - x1;
+    } else {
+        x = x2;
+        widgetWidth = x1 - x2;
+    }
+    x += 1;
+    widgetWidth -= 2;
+    setPos(x, m_pOw[Uml::RoleType::B]->y() + m_pOw[Uml::RoleType::B]->height() / 2);
+    setSize(widgetWidth, widgetHeight);
+}
+
+/**
+ * Calculates and sets the size of the widget for a lost message.
+ */
+void MessageWidget::calculateDimensionsLost()
+{
+    int x = 0;
+
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_xclicked;
+
+    int widgetWidth = 0;
+    int widgetHeight = 10;
+    if(x1 < x2) {
+        x = x1;
+        widgetWidth = x2 - x1 + circleWidth/2;
+    } else {
+        x = x2 - circleWidth/2;
+        widgetWidth = x1 - x2 + circleWidth/2;
+    }
+    setX(x);
+    setSize(widgetWidth, widgetHeight);
+}
+
+/**
+ * Calculates and sets the size of the widget for a found message.
+ */
+void MessageWidget::calculateDimensionsFound()
+{
+    int x = 0;
+
+    int x1 = m_pOw[Uml::RoleType::A]->centerX();
+    int x2 = m_xclicked;
+
+    int widgetWidth = 0;
+    int widgetHeight = 10;
+    if(x1 < x2) {
+        x = x1;
+        widgetWidth = x2 - x1 + circleWidth/2;
+    } else {
+        x = x2 - circleWidth/2;
+        widgetWidth = x1 - x2 + circleWidth/2;
+    }
+
+    setX(x);
+    setSize(widgetWidth, widgetHeight);
+}
+
+/**
+ * Used to cleanup any other widget it may need to delete.
+ */
+void MessageWidget::cleanup()
+{
+    if (m_pOw[Uml::RoleType::A]) {
+        disconnect(this, SIGNAL(sigMessageMoved()), m_pOw[Uml::RoleType::A], SLOT(slotMessageMoved()));
+        m_pOw[Uml::RoleType::A]->messageRemoved(this);
+    }
+    if (m_pOw[Uml::RoleType::B]) {
+        disconnect(this, SIGNAL(sigMessageMoved()), m_pOw[Uml::RoleType::B], SLOT(slotMessageMoved()));
+        m_pOw[Uml::RoleType::B]->messageRemoved(this);
+    }
+
+    UMLWidget::cleanup();
+    if (m_pFText) {
+        m_scene->removeWidgetCmd(m_pFText);
+        m_pFText = NULL;
+    }
+}
+
+/**
+ * Sets the state of whether the widget is selected.
+ *
+ * @param _select   True if the widget is selected.
+ */
+void MessageWidget::setSelected(bool _select)
+{
+    UMLWidget::setSelected(_select);
+    if(!m_pFText || m_pFText->displayText().isEmpty())
+        return;
+    if(isSelected() && m_pFText->isSelected())
+        return;
+    if(!isSelected() && !m_pFText->isSelected())
+        return;
+
+    m_pFText->setSelected(isSelected());
+}
+
+/**
+ * Returns the minimum height this widget should be set at on
+ * a sequence diagrams.  Takes into account the widget positions
+ * it is related to.
+ */
+int MessageWidget::getMinY()
+{
+    if (!m_pOw[Uml::RoleType::A] || !m_pOw[Uml::RoleType::B]) {
+        return 0;
+    }
+    if (m_sequenceMessageType == Uml::SequenceMessage::Creation) {
+        return m_pOw[Uml::RoleType::A]->y() + m_pOw[Uml::RoleType::A]->height();
+    }
+    int heightA = m_pOw[Uml::RoleType::A]->y() + m_pOw[Uml::RoleType::A]->height();
+    int heightB = m_pOw[Uml::RoleType::B]->y() + m_pOw[Uml::RoleType::B]->height();
+    int height = heightA;
+    if(heightA < heightB) {
+        height = heightB;
+    }
+    return height;
+}
+
+/**
+ * Returns the maximum height this widget should be set at on
+ * a sequence diagrams.  Takes into account the widget positions
+ * it is related to.
+ */
+int MessageWidget::getMaxY()
+{
+    if(!m_pOw[Uml::RoleType::A] || !m_pOw[Uml::RoleType::B]) {
+        return 0;
+    }
+    int heightA = (int)((ObjectWidget*)m_pOw[Uml::RoleType::A])->getEndLineY();
+    int heightB = (int)((ObjectWidget*)m_pOw[Uml::RoleType::B])->getEndLineY();
+    int height = heightA;
+    if(heightA > heightB) {
+        height = heightB;
+    }
+    return (height - this->height());
+}
+
+/**
+ * Sets the related widget on the given side.
+ *
+ * @param ow     The ObjectWidget we are related to.
+ * @param role   The Uml::RoleType::Enum to be set for the ObjectWidget
+ */
+void MessageWidget::setObjectWidget(ObjectWidget * ow, Uml::RoleType::Enum role)
+{
+    m_pOw[role] = ow;
+    updateResizability();
+}
+
+/**
+ * Returns the related widget on the given side.
+ *
+ * @return  The ObjectWidget we are related to.
+ */
+ObjectWidget* MessageWidget::objectWidget(Uml::RoleType::Enum role)
+{
+    return m_pOw[role];
+}
+
+/**
+ * Set the xclicked
+ */
+void MessageWidget::setxclicked(int xclick)
+{
+    m_xclicked = xclick;
+}
+
+/**
+ * Set the yclicked
+ */
+void MessageWidget::setyclicked(int yclick)
+{
+    m_yclicked = yclick;
+}
+
+/**
+ * Event handler for mouse double click events.
+ * @param event QGraphicsSceneMouseEvent which triggered the double click event
+ */
+void MessageWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+    DEBUG(DBG_SRC) << "NOT IMPLEMENTED YET!";
+    if (m_pFText != NULL) {
+        DEBUG(DBG_SRC) << "NOT IMPLEMENTED YET - on floating text widget!";
+//        QAction* action = m_pMenu->getAction(ListPopupMenu::mt_Select_Operation);
+//        m_pFText->slotMenuSelection(action);
+    }
+}
+
+/**
+ * Saves to the "messagewidget" XMI element.
+ */
+void MessageWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement messageElement = qDoc.createElement(QLatin1String("messagewidget"));
+    UMLWidget::saveToXMI(qDoc, messageElement);
+    LinkWidget::saveToXMI(qDoc, messageElement);
+    if (m_pOw[Uml::RoleType::A])
+        messageElement.setAttribute(QLatin1String("widgetaid"), Uml::ID::toString(m_pOw[Uml::RoleType::A]->localID()));
+    if (m_pOw[Uml::RoleType::B])
+        messageElement.setAttribute(QLatin1String("widgetbid"), Uml::ID::toString(m_pOw[Uml::RoleType::B]->localID()));
+    UMLOperation *pOperation = operation();
+    if (pOperation)
+        messageElement.setAttribute(QLatin1String("operation"), Uml::ID::toString(pOperation->id()));
+    else
+        messageElement.setAttribute(QLatin1String("operation"), m_CustomOp);
+    messageElement.setAttribute(QLatin1String("sequencemessagetype"), m_sequenceMessageType);
+    if (m_sequenceMessageType == Uml::SequenceMessage::Lost || m_sequenceMessageType == Uml::SequenceMessage::Found) {
+        messageElement.setAttribute(QLatin1String("xclicked"), m_xclicked);
+        messageElement.setAttribute(QLatin1String("yclicked"), m_yclicked);
+    }
+
+    // save the corresponding message text
+    if (m_pFText && !m_pFText->text().isEmpty()) {
+        messageElement.setAttribute(QLatin1String("textid"), Uml::ID::toString(m_pFText->id()));
+        m_pFText->saveToXMI(qDoc, messageElement);
+    }
+
+    qElement.appendChild(messageElement);
+}
+
+/**
+ * Loads from the "messagewidget" XMI element.
+ */
+bool MessageWidget::loadFromXMI(QDomElement& qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+    if (!LinkWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+    QString textid = qElement.attribute(QLatin1String("textid"), QLatin1String("-1"));
+    QString widgetaid = qElement.attribute(QLatin1String("widgetaid"), QLatin1String("-1"));
+    QString widgetbid = qElement.attribute(QLatin1String("widgetbid"), QLatin1String("-1"));
+    m_CustomOp = qElement.attribute(QLatin1String("operation"));
+    QString sequenceMessageType = qElement.attribute(QLatin1String("sequencemessagetype"), QLatin1String("1001"));
+    m_sequenceMessageType = Uml::SequenceMessage::fromInt(sequenceMessageType.toInt());
+    if (m_sequenceMessageType == Uml::SequenceMessage::Lost || m_sequenceMessageType == Uml::SequenceMessage::Found) {
+        m_xclicked = qElement.attribute(QLatin1String("xclicked"), QLatin1String("-1")).toFloat();
+        m_yclicked = qElement.attribute(QLatin1String("yclicked"), QLatin1String("-1")).toFloat();
+    }
+
+    m_widgetAId = Uml::ID::fromString(widgetaid);
+    m_widgetBId = Uml::ID::fromString(widgetbid);
+    m_textId = Uml::ID::fromString(textid);
+
+    Uml::TextRole::Enum tr = Uml::TextRole::Seq_Message;
+    if (m_widgetAId == m_widgetBId)
+        tr = Uml::TextRole::Seq_Message_Self;
+
+    //now load child elements
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    if (!element.isNull()) {
+        QString tag = element.tagName();
+        if (tag == QLatin1String("floatingtext") || tag == QLatin1String("UML::FloatingTextWidget")) {
+            m_pFText = new FloatingTextWidget(m_scene, tr, operationText(m_scene), m_textId);
+            m_scene->addFloatingTextWidget(m_pFText);
+            if(! m_pFText->loadFromXMI(element)) {
+                // Most likely cause: The FloatingTextWidget is empty.
+                delete m_pFText;
+                m_pFText = NULL;
+            }
+            else
+                m_pFText->setSequenceNumber(m_SequenceNumber);
+        } else {
+            uError() << "unknown tag " << tag;
+        }
+    }
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/messagewidget.h umbrello-15.08.1/umbrello/umlwidgets/messagewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/messagewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/messagewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,212 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef MESSAGEWIDGET_H
+#define MESSAGEWIDGET_H
+
+#include "umlwidget.h"
+#include "linkwidget.h"
+
+// forward declarations
+class FloatingTextWidget;
+class ObjectWidget;
+class QResizeEvent;
+class UMLOperation;
+
+/**
+ * Used to display a message on a sequence diagram.  The message
+ * could be between two objects or a message that calls itself on
+ * an object.  This class will only display the line that is
+ * required and the text will be setup by the @ref FloatingTextWidget
+ * widget that is passed in the constructor.  A message can be
+ * synchronous (calls a method and gains control back on return,
+ * as happens in most programming languages) or asynchronous
+ * (calls a method and gains back control immediately).
+ *
+ * @short Displays a message.
+ * @author Paul Hensgen
+ * @see UMLWidget
+ * @see ObjectWidget
+ * @see FloatingTextWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class MessageWidget : public UMLWidget, public LinkWidget
+{
+    Q_OBJECT
+public:
+    MessageWidget(UMLScene * scene, ObjectWidget* a, ObjectWidget* b,
+                  int y, Uml::SequenceMessage::Enum sequenceMessageType,
+                  Uml::ID::Type id = Uml::ID::None);
+    MessageWidget(UMLScene * scene, Uml::SequenceMessage::Enum sequenceMessageType,
+                  Uml::ID::Type id = Uml::ID::None);
+    MessageWidget(UMLScene * scene, ObjectWidget* a, int xclick, int yclick,
+                  Uml::SequenceMessage::Enum sequenceMessageType,
+                  Uml::ID::Type id = Uml::ID::None);
+    virtual ~MessageWidget();
+
+    virtual void setY(qreal y);
+
+    //---------- LinkWidget Interface methods implemementation from now on.
+
+    virtual void lwSetFont (QFont font);
+    virtual UMLClassifier *operationOwner();
+
+    virtual UMLOperation *operation();
+    virtual void setOperation(UMLOperation *op);
+
+    virtual QString customOpText();
+    virtual void setCustomOpText(const QString &opText);
+
+    virtual void setMessageText(FloatingTextWidget *ft);
+    virtual void setText(FloatingTextWidget *ft, const QString &newText);
+
+    virtual QString lwOperationText();
+    virtual UMLClassifier *lwClassifier();
+    virtual void setOperationText(const QString &op);
+
+    virtual void constrainTextPos(qreal &textX, qreal &textY, qreal textWidth, qreal textHeight,
+                                  Uml::TextRole::Enum tr);
+
+    //---------- End LinkWidget Interface methods implemementation.
+
+    /// @return Whether the message is synchronous or asynchronous
+    Uml::SequenceMessage::Enum sequenceMessageType() const {
+        return m_sequenceMessageType;
+    }
+
+    bool hasObjectWidget(ObjectWidget * w);
+
+    ObjectWidget* objectWidget(Uml::RoleType::Enum role);
+    void setObjectWidget(ObjectWidget * ow, Uml::RoleType::Enum role) ;
+
+    bool isSelf() const;
+
+    /**
+     * Returns the text widget it is related to.
+     *
+     * @return  The text widget we are related to.
+     */
+    FloatingTextWidget * floatingTextWidget() {
+        return m_pFText;
+    }
+
+    /**
+     * Sets the text widget it is related to.
+     *
+     * @param f The text widget we are related to.
+     */
+    void setFloatingTextWidget(FloatingTextWidget * f) {
+        m_pFText = f;
+    }
+
+    void calculateWidget();
+
+    virtual bool activate(IDChangeLog * Log = 0);
+    void resolveObjectWidget(IDChangeLog* log);
+
+    void calculateDimensions();
+    void calculateDimensionsSynchronous();
+    void calculateDimensionsAsynchronous();
+    void calculateDimensionsCreation();
+    void calculateDimensionsLost();
+    void calculateDimensionsFound();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    void setTextPosition();
+
+    void cleanup();
+
+    void setSelected(bool _select);
+
+    int getMinY();
+    int getMaxY();
+
+    UMLWidget* onWidget(const QPointF& p);
+
+    virtual void resizeWidget(qreal newW, qreal newH);
+
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+    virtual bool loadFromXMI(QDomElement & qElement);
+
+    void setxclicked(int xclick);
+    void setyclicked(int yclick);
+
+    /**
+     * Return the xclicked
+     */
+    int getxclicked() const {
+        return m_xclicked;
+    }
+
+protected:
+    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+
+    virtual void moveWidgetBy(qreal diffX, qreal diffY);
+    virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY);
+
+    virtual QCursor resizeCursor() const;
+
+    void setLinkAndTextPos();
+
+    int constrainX(int textX, int textWidth, Uml::TextRole::Enum tr);
+
+    static void paintArrow(QPainter *p, int x, int y, int w,
+                           Qt::ArrowType direction, bool useDottedLine = false);
+    static void paintSolidArrowhead(QPainter *p, int x, int y, Qt::ArrowType direction);
+
+    void updateResizability();
+
+    void paintSynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintAsynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintCreation(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintLost(QPainter *painter, const QStyleOptionGraphicsItem *option);
+    void paintFound(QPainter *painter, const QStyleOptionGraphicsItem *option);
+
+    // Data loaded/saved
+    QString m_CustomOp;
+    /**
+     * Whether the message is synchronous or asynchronous
+     */
+    Uml::SequenceMessage::Enum m_sequenceMessageType;
+
+private:
+    void resizeEvent(QResizeEvent *re);
+
+    qreal constrainPositionY(qreal diffY);
+
+    void init();
+
+    ObjectWidget * m_pOw[2];
+    FloatingTextWidget * m_pFText;
+
+    int m_xclicked;
+    int m_yclicked;
+
+    /**
+     * The following variables are used by loadFromXMI() as an intermediate
+     * store. activate() resolves the IDs, i.e. after activate() the variables
+     * m_pOw[] and m_pFText can be used.
+     */
+    Uml::ID::Type m_widgetAId, m_widgetBId, m_textId;
+
+public slots:
+    void slotWidgetMoved(Uml::ID::Type id);
+    void slotMenuSelection(QAction* action);
+
+signals:
+    /**
+     * emitted when the message widget is moved up or down
+     * slots into ObjectWidget::slotMessageMoved()
+     */
+    void sigMessageMoved();
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/nodewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/nodewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/nodewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/nodewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,156 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "nodewidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "node.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// qt includes
+#include <QPainter>
+#include <QPolygon>
+
+DEBUG_REGISTER_DISABLED(NodeWidget)
+
+/**
+ * Constructs a NodeWidget.
+ *
+ * @param scene   The parent of this NodeWidget.
+ * @param n       The UMLNode this will be representing.
+ */
+NodeWidget::NodeWidget(UMLScene * scene, UMLNode *n)
+  : UMLWidget(scene, WidgetBase::wt_Node, n)
+{
+    setSize(100, 30);
+    setZValue(1);  // above box but below UMLWidget because may embed widgets
+}
+
+/**
+ * Destructor.
+ */
+NodeWidget::~NodeWidget()
+{
+}
+
+/**
+ * Overrides standard method.
+ */
+void NodeWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor()) {
+        painter->setBrush(UMLWidget::fillColor());
+    } else {
+        painter->setBrush(m_scene->backgroundColor());
+    }
+    const int w = width();
+    const int h = height();
+    const int wDepth = (w/3 > DEPTH ? DEPTH : w/3);
+    const int hDepth = (h/3 > DEPTH ? DEPTH : h/3);
+    const int bodyOffsetY = hDepth;
+    const int bodyWidth = w - wDepth;
+    const int bodyHeight = h - hDepth;
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+    const int fontHeight  = fm.lineSpacing();
+    QString nameStr = name();
+
+    QPolygon pointArray(5);
+    pointArray.setPoint(0, 0, bodyOffsetY);
+    pointArray.setPoint(1, wDepth, 0);
+    pointArray.setPoint(2, w, 0);
+    pointArray.setPoint(3, w, bodyHeight);
+    pointArray.setPoint(4, bodyWidth, h);
+    painter->drawPolygon(pointArray);
+    painter->drawRect(0, bodyOffsetY, bodyWidth, bodyHeight);
+    painter->drawLine(w, 0, bodyWidth, bodyOffsetY);
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    int lines = 1;
+    if (m_umlObject) {
+        QString stereotype = m_umlObject->stereotype();
+        if (!stereotype.isEmpty()) {
+            painter->drawText(0, bodyOffsetY + (bodyHeight/2) - fontHeight,
+                       bodyWidth, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true));
+            lines = 2;
+        }
+    }
+
+    if (UMLWidget::isInstance()) {
+        font.setUnderline(true);
+        painter->setFont(font);
+        nameStr = UMLWidget::instanceName() + QLatin1String(" : ") + nameStr;
+    }
+
+    if (lines == 1) {
+        painter->drawText(0, bodyOffsetY + (bodyHeight/2) - (fontHeight/2),
+                   bodyWidth, fontHeight, Qt::AlignCenter, nameStr);
+    } else {
+        painter->drawText(0, bodyOffsetY + (bodyHeight/2),
+                   bodyWidth, fontHeight, Qt::AlignCenter, nameStr);
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF NodeWidget::minimumSize() const
+{
+    if (m_umlObject == NULL) {
+        DEBUG(DBG_SRC) << "m_umlObject is NULL";
+        return UMLWidget::minimumSize();
+    }
+
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
+    const int fontHeight  = fm.lineSpacing();
+
+    QString name = m_umlObject->name();
+    if (UMLWidget::isInstance()) {
+        name = UMLWidget::instanceName() + QLatin1String(" : ") + name;
+    }
+
+    int width = fm.width(name) + 2 * defaultMargin;
+
+    int tempWidth = 0;
+    if (!m_umlObject->stereotype().isEmpty()) {
+        tempWidth = fm.width(m_umlObject->stereotype(true));
+    }
+    if (tempWidth > width)
+        width = tempWidth;
+    width += DEPTH;
+
+    int height = (2*fontHeight) + DEPTH;
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Saves to the "nodewidget" XMI element.
+ * Note: For loading we use the method inherited from UMLWidget.
+ */
+void NodeWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("nodewidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/nodewidget.h umbrello-15.08.1/umbrello/umlwidgets/nodewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/nodewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/nodewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,44 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef NODEWIDGET_H
+#define NODEWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLNode;
+
+/**
+ * Defines a graphical version of the Node.  Most of the functionality
+ * will come from the @ref UMLNode class.
+ *
+ * @short A graphical version of a Node.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class NodeWidget : public UMLWidget
+{
+public:
+
+    NodeWidget(UMLScene * scene, UMLNode *n);
+    virtual ~NodeWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+protected:
+    QSizeF minimumSize() const;
+
+    static const int DEPTH = 30;  ///< pixels on Z axis
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/notewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/notewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/notewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/notewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,517 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "notewidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "listpopupmenu.h"
+#include "notedialog.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kcolordialog.h>
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#include <QPainter>
+#if QT_VERSION >= 0x050000
+#include <QColorDialog>
+#include <QInputDialog>
+#endif
+
+NoteWidget * NoteWidget::s_pCurrentNote;
+
+/**
+ * Constructs a NoteWidget.
+ *
+ * @param scene      The parent to this widget.
+ * @param noteType   The NoteWidget::NoteType of this NoteWidget
+ * @param id         The unique id of the widget.
+ *                   The default (-1) will prompt a new ID.
+ */
+NoteWidget::NoteWidget(UMLScene * scene, NoteType noteType , Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Note, id),
+    m_diagramLink(Uml::ID::None),
+    m_noteType(noteType)
+{
+    setZValue(20); //make sure always on top.
+}
+
+/**
+ * Destructor.
+ */
+NoteWidget::~NoteWidget()
+{
+}
+
+/**
+ * Override default method.
+ */
+void NoteWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    const int margin = 10;
+    int w = width();
+    int h = height();
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    QPolygon poly(6);
+    poly.setPoint(0, 0, 0);
+    poly.setPoint(1, 0, h);
+    poly.setPoint(2, w, h);
+    poly.setPoint(3, w, margin);
+    poly.setPoint(4, w - margin, 0);
+    poly.setPoint(5, 0, 0);
+
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor()) {
+        QBrush brush(UMLWidget::fillColor());
+        painter->setBrush(brush);
+        painter->drawPolygon(poly);
+    } else
+        painter->drawPolyline(poly);
+    painter->drawLine(w - margin, 0, w - margin, margin);
+    painter->drawLine(w - margin, margin, w, margin);
+    painter->setPen(textColor());
+    switch(m_noteType) {
+    case NoteWidget::PreCondition :
+        painter->drawText(0, margin, w, fontHeight, Qt::AlignCenter, QLatin1String("<< precondition >>"));
+        break;
+    case NoteWidget::PostCondition :
+        painter->drawText(0, margin, w, fontHeight, Qt::AlignCenter, QLatin1String("<< postcondition >>"));
+        break;
+    case NoteWidget::Transformation :
+        painter->drawText(0, margin, w, fontHeight, Qt::AlignCenter, QLatin1String("<< transformation >>"));
+        break;
+    case NoteWidget::Normal :
+    default :
+        break;
+    }
+
+    UMLWidget::paint(painter, option, widget);
+
+//    paintText(&p, 0, 0);
+    paintTextWordWrap(painter);
+}
+
+/**
+ * Returns the type of note.
+ */
+NoteWidget::NoteType NoteWidget::noteType() const
+{
+    return m_noteType;
+}
+
+/**
+ * Converts a string to NoteWidget::NoteType.
+ */
+NoteWidget::NoteType NoteWidget::stringToNoteType(const QString& noteType)
+{
+    if (noteType == QLatin1String("Precondition"))
+        return NoteWidget::PreCondition;
+    else if (noteType == QLatin1String("Postcondition"))
+        return NoteWidget::PostCondition;
+    else if (noteType == QLatin1String("Transformation"))
+        return NoteWidget::Transformation;
+    else
+        return NoteWidget::Normal;
+}
+
+/**
+ * Sets the type of note.
+ */
+void NoteWidget::setNoteType(NoteType noteType)
+{
+    m_noteType = noteType;
+}
+
+/**
+ * Sets the type of note.
+ */
+void NoteWidget::setNoteType(const QString& noteType)
+{
+    setNoteType(stringToNoteType(noteType));
+}
+
+/**
+ * Return the ID of the diagram hyperlinked to this note.
+ *
+ * @return  ID of an UMLView, or Uml::ID::None if no
+ *          hyperlink is set.
+ */
+Uml::ID::Type NoteWidget::diagramLink() const
+{
+    return m_diagramLink;
+}
+
+/**
+ * Set the ID of the diagram hyperlinked to this note.
+ * To switch off the hyperlink, set this to Uml::id_None.
+ *
+ * @param viewID    ID of an UMLScene.
+ */
+void NoteWidget::setDiagramLink(Uml::ID::Type viewID)
+{
+    UMLDoc *umldoc = UMLApp::app()->document();
+    UMLView *view = umldoc->findView(viewID);
+    if (view == NULL) {
+        uError() << "no view found for viewID " << Uml::ID::toString(viewID);
+        return;
+    }
+    QString linkText(QLatin1String("Diagram: ") + view->umlScene()->name());
+    setDocumentation(linkText);
+    m_diagramLink = viewID;
+    update();
+}
+
+/**
+ * Display a dialog box to allow the user to choose the note's type.
+ */
+void NoteWidget::askForNoteType(UMLWidget* &targetWidget)
+{
+    static const QStringList list = QStringList() << i18n("Precondition")
+                                                  << i18n("Postcondition")
+                                                  << i18n("Transformation");
+    bool pressedOK = false;
+
+#if QT_VERSION >= 0x050000
+    QString type = QInputDialog::getItem (UMLApp::app(),
+                                          i18n("Note Type"), i18n("Select the Note Type"), list,
+                                          0, false, &pressedOK);
+#else
+    QString type = KInputDialog::getItem (i18n("Note Type"), i18n("Select the Note Type"), list,
+                                          0, false, &pressedOK, UMLApp::app());
+#endif
+
+    if (pressedOK) {
+        dynamic_cast<NoteWidget*>(targetWidget)->setNoteType(type);
+    } else {
+        targetWidget->cleanup();
+        delete targetWidget;
+        targetWidget = 0;
+    }
+}
+
+/**
+ * Loads a "notewidget" XMI element.
+ */
+bool NoteWidget::loadFromXMI(QDomElement & qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement))
+        return false;
+    setZValue(20); //make sure always on top.
+    setDocumentation(qElement.attribute(QLatin1String("text")));
+    QString diagramlink = qElement.attribute(QLatin1String("diagramlink"));
+    if (!diagramlink.isEmpty())
+        m_diagramLink = Uml::ID::fromString(diagramlink);
+    QString type = qElement.attribute(QLatin1String("noteType"));
+    setNoteType((NoteType)type.toInt());
+    return true;
+}
+
+/**
+ * Saves to the "notewidget" XMI element.
+ */
+void NoteWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement noteElement = qDoc.createElement(QLatin1String("notewidget"));
+    UMLWidget::saveToXMI(qDoc, noteElement);
+    noteElement.setAttribute(QLatin1String("text"), documentation());
+    if (m_diagramLink != Uml::ID::None)
+        noteElement.setAttribute(QLatin1String("diagramlink"), Uml::ID::toString(m_diagramLink));
+    noteElement.setAttribute(QLatin1String("noteType"), m_noteType);
+    qElement.appendChild(noteElement);
+}
+
+/**
+ * Show a properties dialog for a NoteWidget.
+ */
+void NoteWidget::showPropertiesDialog()
+{
+    NoteDialog * dlg = 0;
+    UMLApp::app()->docWindow()->updateDocumentation(false);
+    dlg = new NoteDialog(umlScene()->activeView(), this);
+    if (dlg->exec()) {
+        UMLApp::app()->docWindow()->showDocumentation(this, true);
+        UMLApp::app()->document()->setModified(true);
+        update();
+    }
+    delete dlg;
+}
+
+/**
+ * Will be called when a menu selection has been made from the popup
+ * menu.
+ *
+ * @param action   The action that has been selected.
+ */
+void NoteWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        showPropertiesDialog();
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+        break;
+    }
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF NoteWidget::minimumSize() const
+{
+    int width = 60;
+    int height = 30;
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int textWidth = fm.width(documentation());
+    if (m_noteType == PreCondition) {
+        const int widthtemp = fm.width(QLatin1String("<< precondition >>"));
+        width = textWidth > widthtemp ? textWidth : widthtemp;
+        width += 10;
+    }
+    else if (m_noteType == PostCondition) {
+        const int widthtemp = fm.width(QLatin1String("<< postcondition >>"));
+        width = textWidth > widthtemp ? textWidth : widthtemp;
+        width += 10;
+    }
+    else if (m_noteType == Transformation) {
+        const int widthtemp = fm.width(QLatin1String("<< transformation >>"));
+        width = textWidth > widthtemp ? textWidth : widthtemp;
+        width += 10;
+    }
+    return QSizeF(width, height);
+}
+
+/**
+ * Calculate content related size of widget.
+ * Overrides method from UMLWidget.
+ */
+QSizeF NoteWidget::calculateSize(bool withExtensions /* = true */) const
+{
+    Q_UNUSED(withExtensions)
+    int width = this->width();
+    int height = this->height();
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int margin = fm.width(QLatin1String("W"));
+    QSize size = fm.size (0, documentation());
+    const int textWidth = size.width();
+    if (m_noteType == PreCondition) {
+        const int widthtemp = fm.width(QLatin1String("<< precondition >>"));
+        width = textWidth > widthtemp ? textWidth : widthtemp;
+        width += 2 * margin;
+    }
+    else if (m_noteType == PostCondition) {
+        const int widthtemp = fm.width(QLatin1String("<< postcondition >>"));
+        width = textWidth > widthtemp ? textWidth : widthtemp;
+        width += 2 * margin;
+    }
+    else if (m_noteType == Transformation) {
+        const int widthtemp = fm.width(QLatin1String("<< transformation >>"));
+        width = textWidth > widthtemp ? textWidth : widthtemp;
+        width += 2 * margin;
+    }
+    return QSizeF(width, height);
+}
+
+/**
+ * Paints the text. Auxiliary to paint().
+ * Implemented without word wrap.
+ */
+void NoteWidget::paintText(QPainter *painter)
+{
+    if (painter == 0) {
+        return;
+    }
+
+    QString text = documentation();
+    if (text.length() == 0) {
+        return;
+    }
+
+    painter->setPen(Qt::black);
+    QFont font = UMLWidget::font();
+    painter->setFont(font);
+
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    const int margin      = fm.width(QLatin1String("W"));
+    const QSize textSize  = fm.size(Qt::TextExpandTabs, text);
+
+    const int width = this->width() - margin * 2;
+    const int height = this->height() - fontHeight;
+    int textY = fontHeight / 2;
+    int textX = margin;
+
+    if ((textSize.width() < width) && (textSize.height() < height)) {
+        // the entire text is small enough - draw it
+        painter->drawText(textX, textY,
+                    textSize.width(), textSize.height(),
+                    Qt::AlignLeft, text);
+    }
+    else {
+        // not all text can be drawn
+        QStringList lines = text.split(QLatin1Char('\n'));
+        foreach(const QString& line, lines) {
+            int lineWidth = fm.width(line);
+            if (lineWidth < width) {
+                // line is small enough - draw it
+                painter->drawText(textX, textY,
+                            textSize.width(), fontHeight,
+                            Qt::AlignLeft, line);
+            }
+            else {
+                // draw a smaller line
+                for(int len = line.length(); len > 0; --len) {
+                    QString smallerLine = line.left(len);
+                    int smallerLineWidth = fm.width(smallerLine);
+                    if (smallerLineWidth < width) {
+                        // line is small enough - draw it
+                        painter->drawText(textX, textY,
+                                    width, fontHeight,
+                                    Qt::AlignLeft, smallerLine);
+                    }
+                }
+            }
+            textY += fontHeight;
+            if (textY > height) {
+                // skip the next lines - size is not enough
+                break;
+            }
+        }
+    }
+}
+
+/**
+ * Paints the text. Auxiliary to paint().
+ * Implemented with word wrap.
+ */
+void NoteWidget::paintTextWordWrap(QPainter *painter)
+{
+    if (painter == 0) {
+        return;
+    }
+    QString text = documentation();
+    if (text.length() == 0) {
+        return;
+    }
+    // Implement word wrap for text as follows:
+    // wrap at width on whole words.
+    // if word is wider than width then clip word
+    // if reach height exit and don't print anymore
+    // start new line on \n character
+    painter->setPen(Qt::black);
+    QFont font = UMLWidget::font();
+    painter->setFont(font);
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    QString word;
+    QString fullLine;
+    QString testCombineLine;
+    const int margin = fm.width(QLatin1String("W"));
+    int textY = fontHeight / 2;
+    int textX = margin;
+    const int width = this -> width() - margin * 2;
+    const int height = this -> height() - fontHeight;
+    QChar returnChar = QChar::fromLatin1('\n');
+    QChar c;
+
+    for (int i = 0; i <= text.length(); ++i) {
+        if (i < text.length()) {
+            c = text[i];
+        } else {
+            // all chars of text have been handled already ->
+            // perform this last run to spool current content of "word"
+            c = returnChar;
+        }
+        if (c == returnChar || c.isSpace()) {
+            // new word delimiter found -> it is time to decide on word wrap
+            testCombineLine = fullLine + QLatin1Char(' ') + word;
+            int textWidth = fm.width(testCombineLine);
+            if (textX + textWidth > width) {
+                // combination of "fullLine" and "word" doesn't fit into one line ->
+                // print "fullLine" in current line, update write position to next line
+                // and decide then on following actions
+                painter->drawText(textX, textY,
+                            textWidth, fontHeight, Qt::AlignLeft, fullLine);
+                fullLine = word;
+                word = QString();
+                // update write position
+                textX = margin;
+                textY += fontHeight;
+                if (textY > height)
+                    return;
+                // in case of c==newline ->
+                // print "word" and set write position one additional line lower
+                if (c == returnChar) {
+                    // print "word" - which is now "fullLine" and set to next line
+                    painter->drawText(textX, textY,
+                                textWidth, fontHeight, Qt::AlignLeft, fullLine);
+                    fullLine = QString();
+                    textX = margin;
+                    textY += fontHeight;
+                    if(textY > height) return;
+                }
+            }
+            else if (c == returnChar) {
+                // newline found and combination of "fullLine" and "word" fits
+                // in one line
+                painter->drawText(textX, textY,
+                            textWidth, fontHeight, Qt::AlignLeft, testCombineLine);
+                fullLine = word = QString();
+                textX = margin;
+                textY += fontHeight;
+                if (textY > height)
+                    return;
+            } else {
+                // word delimiter found, and combination of "fullLine", space and "word" fits into one line
+                fullLine = testCombineLine;
+                word = QString();
+            }
+        } else {
+            // no word delimiter found --> add current char to "word"
+            if (c != QLatin1Char('\0'))
+                word += c;
+        }
+    }//end for
+}
+
+/**
+ * Event handler for moude double click events.
+ *
+ * @param event The QGraphicsSceneMouseEvent event.
+ */
+void NoteWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        if (m_diagramLink == Uml::ID::None) {
+            showPropertiesDialog();
+        } else {
+            UMLDoc *umldoc = UMLApp::app()->document();
+            umldoc->changeCurrentView(m_diagramLink);
+        }
+        event->accept();
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/notewidget.h umbrello-15.08.1/umbrello/umlwidgets/notewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/notewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/notewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,83 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef NOTEWIDGET_H
+#define NOTEWIDGET_H
+
+//app includes
+#include "umlwidget.h"
+
+// Qt forward declarations
+class QPainter;
+
+/**
+ * Displays a note box to allow multiple lines of text to be displayed.
+ * These widgets are diagram specific.  They will still need a unique id
+ * from the @ref UMLDoc class for deletion and other purposes.
+ *
+ * @short Displays a note box.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class NoteWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+
+    /// This enum type is used to specify the type of note.
+    enum NoteType
+    {
+        Normal,
+        PreCondition,
+        PostCondition,
+        Transformation
+    };
+
+    explicit NoteWidget(UMLScene * scene, NoteWidget::NoteType noteType = Normal,
+                        Uml::ID::Type id = Uml::ID::None);
+    virtual ~NoteWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    static NoteType stringToNoteType(const QString& noteType);
+
+    NoteType noteType() const;
+    void setNoteType(NoteType noteType);
+    void setNoteType(const QString& noteType);
+
+    Uml::ID::Type diagramLink() const;
+    void setDiagramLink(Uml::ID::Type viewID);
+
+    void askForNoteType(UMLWidget* &targetWidget);
+
+    virtual void showPropertiesDialog();
+
+    virtual bool loadFromXMI(QDomElement & qElement);
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+    static NoteWidget *s_pCurrentNote;
+
+public Q_SLOTS:
+    void slotMenuSelection(QAction* action);
+
+protected:
+    virtual QSizeF minimumSize() const;
+    virtual QSizeF calculateSize(bool withExtensions = true) const;
+    void paintText(QPainter *painter);
+    void paintTextWordWrap(QPainter *painter);
+    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+    Uml::ID::Type m_diagramLink;  ///< The diagram/scene this note links to.
+    NoteType      m_noteType;     ///< The type of note. @see NoteWidget::NoteType
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/objectnodewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/objectnodewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/objectnodewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/objectnodewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,377 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "objectnodewidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "dialog_utils.h"
+#include "listpopupmenu.h"
+#include "objectnodedialog.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPainter>
+#include <QPointer>
+
+#define OBJECTNODE_MARGIN 5
+#define OBJECTNODE_WIDTH 30
+#define OBJECTNODE_HEIGHT 10
+
+/**
+ * Creates a Object Node widget.
+ *
+ * @param scene            The parent of the widget.
+ * @param objectNodeType   The type of object node
+ * @param id               The ID to assign (-1 will prompt a new ID.)
+ */
+ObjectNodeWidget::ObjectNodeWidget(UMLScene * scene, ObjectNodeType objectNodeType, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_ObjectNode, id)
+{
+    setObjectNodeType(objectNodeType);
+    setState(QString());
+}
+
+/**
+ * Destructor.
+ */
+ObjectNodeWidget::~ObjectNodeWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void ObjectNodeWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    int w = width();
+    int h = height();
+
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    int textStartY = (h / 2) - (fontHeight / 2);
+
+    setPenFromSettings(painter);
+
+    if (UMLWidget::useFillColor()) {
+        painter->setBrush(UMLWidget::fillColor());
+    }
+
+    painter->drawRect(0, 0, w, h);
+    painter->setFont(UMLWidget::font());
+
+    switch (m_objectNodeType)
+    {
+    case Normal : break;
+    case Buffer :
+        {
+            painter->setPen(textColor());
+            painter->drawText(OBJECTNODE_MARGIN, (textStartY/2), w - OBJECTNODE_MARGIN * 2, fontHeight, Qt::AlignHCenter, QLatin1String("<< centralBuffer >>"));
+            painter->drawText(OBJECTNODE_MARGIN, (textStartY/2) + fontHeight + 5, w - OBJECTNODE_MARGIN * 2, fontHeight, Qt::AlignHCenter, name());
+        }
+        break;
+    case Data :
+        {
+            painter->setPen(textColor());
+            painter->drawText(OBJECTNODE_MARGIN, (textStartY/2), w - OBJECTNODE_MARGIN * 2, fontHeight, Qt::AlignHCenter, QLatin1String("<< datastore >>"));
+            painter->drawText(OBJECTNODE_MARGIN, (textStartY/2) + fontHeight + 5, w - OBJECTNODE_MARGIN * 2, fontHeight, Qt::AlignHCenter, name());
+        }
+        break;
+    case Flow :
+        {
+            QString objectflow_value;
+            if (state() == QLatin1String("-") || state().isEmpty())
+            {
+                objectflow_value = QLatin1Char(' ');
+            }
+            else
+            {
+                objectflow_value = QLatin1Char('[') + state() + QLatin1Char(']');
+            }
+
+            painter->drawLine(10, h/2, w-10, h/2);
+            painter->setPen(textColor());
+            painter->setFont(UMLWidget::font());
+            painter->drawText(OBJECTNODE_MARGIN, textStartY/2 - OBJECTNODE_MARGIN, w - OBJECTNODE_MARGIN * 2, fontHeight, Qt::AlignHCenter, name());
+            painter->drawText(OBJECTNODE_MARGIN, textStartY/2 + textStartY + OBJECTNODE_MARGIN, w - OBJECTNODE_MARGIN * 2, fontHeight, Qt::AlignHCenter, objectflow_value);
+        }
+        break;
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF ObjectNodeWidget::minimumSize() const
+{
+    int widthtmp = 10, height = 10, width=10;
+    if (m_objectNodeType == Buffer) {
+        const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+        const int fontHeight  = fm.lineSpacing();
+        const int textWidth = fm.width(QLatin1String("<< centralBuffer >>"));
+        const int namewidth = fm.width(name());
+        height = fontHeight * 2;
+        widthtmp = textWidth > OBJECTNODE_WIDTH ? textWidth : OBJECTNODE_WIDTH;
+        width = namewidth > widthtmp ? namewidth : widthtmp;
+        height = height > OBJECTNODE_HEIGHT ? height : OBJECTNODE_HEIGHT;
+        width += OBJECTNODE_MARGIN * 2;
+        height += OBJECTNODE_MARGIN * 2 + 5;
+    } else if (m_objectNodeType == Data) {
+        const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+        const int fontHeight  = fm.lineSpacing();
+        const int textWidth = fm.width(QLatin1String("<< datastore >>"));
+        const int namewidth = fm.width(name());
+        height = fontHeight * 2;
+        widthtmp = textWidth > OBJECTNODE_WIDTH ? textWidth : OBJECTNODE_WIDTH;
+        width = namewidth > widthtmp ? namewidth : widthtmp;
+        height = height > OBJECTNODE_HEIGHT ? height : OBJECTNODE_HEIGHT;
+        width += OBJECTNODE_MARGIN * 2;
+        height += OBJECTNODE_MARGIN * 2 + 5;
+    } else if (m_objectNodeType == Flow) {
+        const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+        const int fontHeight  = fm.lineSpacing();
+        const int textWidth = fm.width(QLatin1Char('[') + state() + QLatin1Char(']'));
+        const int namewidth = fm.width(name());
+        height = fontHeight * 2;
+        widthtmp = textWidth > OBJECTNODE_WIDTH ? textWidth : OBJECTNODE_WIDTH;
+        width = namewidth > widthtmp ? namewidth : widthtmp;
+        height = height > OBJECTNODE_HEIGHT ? height : OBJECTNODE_HEIGHT;
+        width += OBJECTNODE_MARGIN * 2;
+        height += OBJECTNODE_MARGIN * 4;
+    }
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Returns the type of object node.
+ */
+ObjectNodeWidget::ObjectNodeType ObjectNodeWidget::objectNodeType() const
+{
+    return m_objectNodeType;
+}
+
+/**
+ * Returns the type of object node.
+ */
+ObjectNodeWidget::ObjectNodeType ObjectNodeWidget::toObjectNodeType(const QString& type)
+{
+    if (type == QLatin1String("Central buffer"))
+       return ObjectNodeWidget::Buffer;
+    if (type == QLatin1String("Data store"))
+       return ObjectNodeWidget::Data;
+    if (type == QLatin1String("Object Flow"))
+       return ObjectNodeWidget::Flow;
+    // Shouldn't happen
+    Q_ASSERT(0);
+    return ObjectNodeWidget::Flow;
+}
+
+/**
+ * Sets the type of object node.
+ */
+void ObjectNodeWidget::setObjectNodeType(ObjectNodeType objectNodeType)
+{
+    m_objectNodeType = objectNodeType;
+    UMLWidget::m_resizable = true;
+}
+
+/**
+ * Sets the type of object node.
+ */
+void ObjectNodeWidget::setObjectNodeType(const QString& type)
+{
+   setObjectNodeType(ObjectNodeWidget::toObjectNodeType(type));
+}
+
+/**
+ * Sets the state of an object node when it's an objectflow.
+ */
+void ObjectNodeWidget::setState(const QString& state)
+{
+    m_state = state;
+    updateGeometry();
+}
+
+/**
+ * Returns the state of object node.
+ */
+QString ObjectNodeWidget::state() const
+{
+    return m_state;
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void ObjectNodeWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString text = name();
+#if QT_VERSION >= 0x050000
+            text = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter Object Node Name"),
+                                         i18n("Enter the name of the object node :"),
+                                         QLineEdit::Normal,
+                                         name(), &ok);
+#else
+            text = KInputDialog::getText(i18n("Enter Object Node Name"),
+                                          i18n("Enter the name of the object node :"),
+                                          name(), &ok);
+#endif
+            if (ok && !text.isEmpty()) {
+                setName(text);
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Properties:
+        showPropertiesDialog();
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Show a properties dialog for an ObjectNodeWidget.
+ */
+void ObjectNodeWidget::showPropertiesDialog()
+{
+    UMLApp::app()->docWindow()->updateDocumentation(false);
+
+    QPointer<ObjectNodeDialog> dialog = new ObjectNodeDialog(UMLApp::app()->currentView(), this);
+    if (dialog->exec() && dialog->getChangesMade()) {
+        UMLApp::app()->docWindow()->showDocumentation(this, true);
+        UMLApp::app()->document()->setModified(true);
+    }
+    delete dialog;
+}
+
+/**
+ * Saves the widget to the "objectnodewidget" XMI element.
+ */
+void ObjectNodeWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement objectNodeElement = qDoc.createElement(QLatin1String("objectnodewidget"));
+    UMLWidget::saveToXMI(qDoc, objectNodeElement);
+    objectNodeElement.setAttribute(QLatin1String("objectnodename"), m_Text);
+    objectNodeElement.setAttribute(QLatin1String("documentation"), m_Doc);
+    objectNodeElement.setAttribute(QLatin1String("objectnodetype"), m_objectNodeType);
+    objectNodeElement.setAttribute(QLatin1String("objectnodestate"), m_state);
+    qElement.appendChild(objectNodeElement);
+}
+
+/**
+ * Loads the widget from the "objectnodewidget" XMI element.
+ */
+bool ObjectNodeWidget::loadFromXMI(QDomElement& qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement) )
+        return false;
+    m_Text = qElement.attribute(QLatin1String("objectnodename"));
+    m_Doc = qElement.attribute(QLatin1String("documentation"));
+    QString type = qElement.attribute(QLatin1String("objectnodetype"), QLatin1String("1"));
+    m_state = qElement.attribute(QLatin1String("objectnodestate"));
+    setObjectNodeType((ObjectNodeType)type.toInt());
+    return true;
+}
+
+/**
+ * Open a dialog box to select the objectNode type (Data, Buffer or Flow).
+ */
+void ObjectNodeWidget::askForObjectNodeType(UMLWidget* &targetWidget)
+{
+    bool pressedOK = false;
+    int current = 0;
+    const QStringList list = QStringList()
+                             << QLatin1String("Central buffer")
+                             << QLatin1String("Data store")
+                             << QLatin1String("Object Flow");
+
+#if QT_VERSION >= 0x050000
+    QString type = QInputDialog::getItem (UMLApp::app(),
+                                          i18n("Select Object node type"),  i18n("Select the object node type"),
+                                          list, current, false, &pressedOK);
+
+#else
+    QString type = KInputDialog::getItem (i18n("Select Object node type"),  i18n("Select the object node type"), list, current, false, &pressedOK, UMLApp::app());
+#endif
+
+    if (pressedOK) {
+        dynamic_cast<ObjectNodeWidget*>(targetWidget)->setObjectNodeType(type);
+        if (type == QLatin1String("Data store"))
+            Dialog_Utils::askNameForWidget(targetWidget, i18n("Enter the name of the data store node"), i18n("Enter the name of the data store node"), i18n("data store name"));
+        if (type == QLatin1String("Central buffer"))
+            Dialog_Utils::askNameForWidget(targetWidget, i18n("Enter the name of the buffer node"), i18n("Enter the name of the buffer"), i18n("centralBuffer"));
+        if (type == QLatin1String("Object Flow")) {
+            Dialog_Utils::askNameForWidget(targetWidget, i18n("Enter the name of the object flow"), i18n("Enter the name of the object flow"), i18n("object flow"));
+            askStateForWidget();
+        }
+    } else {
+        targetWidget->cleanup();
+        delete targetWidget;
+        targetWidget = NULL;
+    }
+}
+
+/**
+ * Open a dialog box to input the state of the widget.
+ * This box is shown only if m_objectNodeType = Flow.
+ */
+void ObjectNodeWidget::askStateForWidget()
+{
+    bool pressedOK = false;
+#if QT_VERSION >= 0x050000
+    QString state = QInputDialog::getText(UMLApp::app(),
+                                          i18n("Enter Object Flow State"), i18n("Enter State (keep '-' if there is no state for the object) "),
+                                          QLineEdit::Normal,
+                                          i18n("-"), &pressedOK);
+#else
+    QString state = KInputDialog::getText(i18n("Enter Object Flow State"), i18n("Enter State (keep '-' if there is no state for the object) "), i18n("-"), &pressedOK, UMLApp::app());
+#endif
+
+    if (pressedOK) {
+        setState(state);
+    } else {
+        cleanup();
+    }
+}
+
+void ObjectNodeWidget::slotOk()
+{
+     //   KDialog::accept();
+}
+
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/objectnodewidget.h umbrello-15.08.1/umbrello/umlwidgets/objectnodewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/objectnodewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/objectnodewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,76 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef OBJECTNODEWIDGET_H
+#define OBJECTNODEWIDGET_H
+
+#include "umlwidget.h"
+
+/**
+ * This class is the graphical version of a UML Object Node.  A ObjectNodeWidget is created
+ * by a @ref UMLView.  An ObjectNodeWidget belongs to only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
+ *
+ * The ObjectNodeWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @short  A graphical version of a UML Activity.
+ * @author Florence Mattler <florence.mattler@libertysurf.fr>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ObjectNodeWidget : public UMLWidget
+{
+    Q_OBJECT
+
+public:
+    enum ObjectNodeType
+    {
+        Normal,
+        Data,
+        Buffer,
+        Flow
+    };
+
+    explicit ObjectNodeWidget(UMLScene * scene, ObjectNodeType objectNodeType = Normal, Uml::ID::Type id = Uml::ID::None);
+    virtual ~ObjectNodeWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    ObjectNodeType objectNodeType() const;
+    static ObjectNodeType toObjectNodeType(const QString& type);
+
+    void setObjectNodeType(ObjectNodeType objectNodeType);
+    void setObjectNodeType(const QString& type) ;
+
+    void setState(const QString& state);
+    QString state() const;
+
+    virtual void showPropertiesDialog();
+
+    void askStateForWidget();
+    void askForObjectNodeType(UMLWidget* &targetWidget);
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+    virtual bool loadFromXMI(QDomElement& qElement);
+
+protected:
+    QSizeF minimumSize() const;
+
+public slots:
+    void slotMenuSelection(QAction* action);
+    void slotOk();
+
+private:
+    ObjectNodeType m_objectNodeType;  ///< type of object node
+    QString        m_state;           ///< state of object node when it's an objectFlow
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/objectwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/objectwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/objectwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/objectwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,710 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header file
+#include "objectwidget.h"
+
+// local includes
+#include "classpropertiesdialog.h"
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "listpopupmenu.h"
+#include "messagewidget.h"
+#include "seqlinewidget.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlobject.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPointer>
+#include <QPainter>
+#include <QValidator>
+
+#define O_MARGIN 5
+#define O_WIDTH 40
+#define A_WIDTH 20
+#define A_HEIGHT 40
+#define A_MARGIN 5
+
+DEBUG_REGISTER_DISABLED(ObjectWidget)
+
+/**
+ * The number of pixels margin between the lowest message
+ * and the bottom of the vertical line
+ */
+static const int sequenceLineMargin = 20;
+
+/**
+ * Creates an ObjectWidget.
+ *
+ * @param scene   The parent to this object.
+ * @param o       The object it will be representing.
+ */
+ObjectWidget::ObjectWidget(UMLScene * scene, UMLObject *o)
+  : UMLWidget(scene, WidgetBase::wt_Object, o),
+    m_multipleInstance(false),
+    m_drawAsActor(false),
+    m_showDestruction(false),
+    m_isOnDestructionBox(false)
+{
+    if (m_scene && (m_scene->type() == Uml::DiagramType::Sequence)) {
+        m_pLine = new SeqLineWidget( m_scene, this );
+        m_pLine->setStartPoint(x() + width() / 2, y() + height());
+    } else {
+        m_pLine = 0;
+    }
+}
+
+/**
+ * Destructor.
+ */
+ObjectWidget::~ObjectWidget()
+{
+    cleanup();
+}
+
+/**
+ * Sets whether representing a multi-instance object.
+ *
+ * @param multiple  Object state. true- multi, false - single.
+ */
+void ObjectWidget::setMultipleInstance(bool multiple)
+{
+    //make sure only calling this in relation to an object on a collab. diagram
+    if (m_scene && (m_scene->type() == Uml::DiagramType::Collaboration)) {
+        m_multipleInstance = multiple;
+        updateGeometry();
+        update();
+    }
+}
+
+/**
+ * Returns whether object is representing a multi-object.
+ *
+ * @return  True if object is representing a multi-object.
+ */
+bool ObjectWidget::multipleInstance() const
+{
+    return m_multipleInstance;
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Moves the widget to a new position using the difference between the
+ * current position and the new position.
+ * Y position is ignored, and widget is only moved along X axis.
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position
+ *                          (isn't used).
+ */
+void ObjectWidget::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    setX(x() + diffX);
+    if (m_scene && (m_scene->type() != Uml::DiagramType::Sequence)) {
+        setY(y() + diffY);
+    }
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Modifies the value of the diffX and diffY variables used to move the widgets.
+ * All the widgets are constrained to be moved only in X axis (diffY is set to 0).
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void ObjectWidget::constrainMovementForAllWidgets(qreal &diffX, qreal &diffY)
+{
+    Q_UNUSED(diffX);
+    if (m_scene && (m_scene->type() == Uml::DiagramType::Sequence)) {
+        diffY = 0;
+    }
+}
+
+/**
+ * Override default method.
+ */
+void ObjectWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    if (m_drawAsActor)
+        paintActor(painter);
+    else
+        paintObject(painter);
+
+    setPenFromSettings(painter);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Handles a popup menu selection.
+ */
+void ObjectWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename_Object:
+        {
+            bool ok;
+            QRegExpValidator* validator = new QRegExpValidator(QRegExp(QLatin1String(".*")), 0);
+#if QT_VERSION >= 0x050000
+            QString name = QInputDialog::getText(m_scene->activeView(),
+                                                 i18n("Rename Object"),
+                                                 i18n("Enter object name:"),
+                                                 QLineEdit::Normal,
+                                                 m_instanceName,
+                                                 &ok);
+#else
+            QString name = KInputDialog::getText
+                   (i18n("Rename Object"),
+                    i18n("Enter object name:"),
+                    m_instanceName,
+                    &ok,
+                    m_scene->activeView(),
+                    validator);
+#endif
+            if (ok) {
+                m_instanceName = name;
+                updateGeometry();
+                moveEvent(0);
+                update();
+                UMLApp::app()->document()->setModified(true);
+            }
+            delete validator;
+            break;
+        }
+    case ListPopupMenu::mt_Properties:
+        showPropertiesDialog();
+        updateGeometry();
+        moveEvent(0);
+        update();
+        break;
+
+    case ListPopupMenu::mt_Up:
+        tabUp();
+        break;
+
+    case ListPopupMenu::mt_Down:
+        tabDown();
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+        break;
+    }
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF ObjectWidget::minimumSize() const
+{
+    int width, height;
+    const QFontMetrics &fm = getFontMetrics(FT_UNDERLINE);
+    const int fontHeight  = fm.lineSpacing();
+    const QString t = m_instanceName + QLatin1String(" : ") + name();
+    const int textWidth = fm.width(t);
+    if (m_drawAsActor) {
+        width = textWidth > A_WIDTH?textWidth:A_WIDTH;
+        height = A_HEIGHT + fontHeight + A_MARGIN;
+        width += A_MARGIN * 2;
+    } else {
+        width = textWidth > O_WIDTH?textWidth:O_WIDTH;
+        height = fontHeight + O_MARGIN * 2;
+        width += O_MARGIN * 2;
+        if (m_multipleInstance) {
+            width += 10;
+            height += 10;
+        }
+    }//end else drawasactor
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Sets whether to draw as an Actor.
+ *
+ * @param drawAsActor   True if widget shall be drawn as an actor.
+ */
+void ObjectWidget::setDrawAsActor(bool drawAsActor)
+{
+    m_drawAsActor = drawAsActor;
+    updateGeometry();
+}
+
+/**
+ * Returns whether to draw as an Actor or not.
+ *
+ * @return  True if widget is drawn as an actor.
+ */
+bool ObjectWidget::drawAsActor() const
+{
+    return m_drawAsActor;
+}
+
+/**
+ * Activate the object after serializing it from a QDataStream
+ */
+bool ObjectWidget::activate(IDChangeLog* ChangeLog /*= 0*/)
+{
+    if (! UMLWidget::activate(ChangeLog))
+        return false;
+    if (m_showDestruction && m_pLine)
+        m_pLine->setupDestructionBox();
+    moveEvent(0);
+    return true;
+}
+
+/**
+ * Sets the x-coordinate.
+ * Reimplements the method from UMLWidget.
+ *
+ * @param x The x-coordinate to be set.
+ */
+void ObjectWidget::setX(qreal x)
+{
+    UMLWidget::setX(x);
+    moveEvent(0);
+}
+
+/**
+ * Sets the y-coordinate.
+ * Reimplements the method from UMLWidget.
+ *
+ * @param y The y-coordinate to be set.
+ */
+void ObjectWidget::setY(qreal y)
+{
+    UMLWidget::setY(y);
+    if (!UMLApp::app()->document()->loading())
+        moveEvent(0);
+}
+
+/**
+ * Return the x coordinate of the widgets center.
+ * @return The x-coordinate of the widget center.
+ */
+qreal ObjectWidget::centerX()
+{
+    return x() + width()/2;
+}
+
+/**
+ * Overrides the standard operation.
+ */
+void ObjectWidget::moveEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+    emit sigWidgetMoved(m_nLocalID);
+    if (m_pLine) {
+        m_pLine->setStartPoint(x() + width() / 2, y() + height());
+    }
+}
+
+/**
+ * Overrides the standard operation.
+ */
+void ObjectWidget::mousePressEvent(QGraphicsSceneMouseEvent *me)
+{
+    UMLWidget::mousePressEvent(me);
+    m_isOnDestructionBox = false;
+    if (m_pLine && m_pLine->onDestructionBox(me->scenePos())) {
+        m_isOnDestructionBox = true;
+        qreal oldX = x() + width() / 2;
+        qreal oldY = getEndLineY() - 10;
+        m_oldPos = QPointF(oldX, oldY);
+    }
+}
+
+/**
+ * Overrides the standard operation.
+ */
+void ObjectWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* me)
+{
+    if (m_inResizeArea) {
+        DEBUG(DBG_SRC) << "resizing...";
+        resize(me);
+        moveEvent(0);
+        return;
+    }
+
+    if (m_isOnDestructionBox) {
+        qreal diffY = me->scenePos().y() - m_oldPos.y();
+        moveDestructionBy(diffY);
+    }
+    else {
+        UMLWidget::mouseMoveEvent(me);
+    }
+}
+
+/**
+ * Moves the destruction Box to a new position using the difference between the
+ * current position and the new position.
+ * The destruction box is only moved along Y axis.
+ *
+ * @param diffY The difference between current Y position and new Y position
+ */
+void ObjectWidget::moveDestructionBy(qreal diffY)
+{
+    // endLine = length of the life line + diffY - 10 to center on the destruction box
+    qreal endLine = getEndLineY() + diffY - 10;
+    SeqLineWidget *pLine = sequentialLine();
+    pLine->setEndOfLine(endLine);
+    m_oldPos.setY(endLine);
+}
+
+/**
+ * Handles a color change signal.
+ */
+void ObjectWidget::slotFillColorChanged(Uml::ID::Type /*viewID*/)
+{
+    UMLWidget::setFillColor(m_scene->fillColor());
+    UMLWidget::setLineColor(m_scene->lineColor());
+
+    if(m_pLine)
+        m_pLine->setPen(QPen(UMLWidget::lineColor(), UMLWidget::lineWidth(), Qt::DashLine));
+}
+
+/**
+ * Used to cleanup any other widget it may need to delete.
+ */
+void ObjectWidget::cleanup()
+{
+    UMLWidget::cleanup();
+    if(m_pLine) {
+        m_pLine->cleanup();
+        delete m_pLine;
+        m_pLine = 0;
+    }
+}
+
+/**
+ * Show a properties dialog for an ObjectWidget.
+ */
+void ObjectWidget::showPropertiesDialog()
+{
+    UMLApp::app()->docWindow()->updateDocumentation(false);
+    QPointer<ClassPropertiesDialog> dlg = new ClassPropertiesDialog((QWidget*)UMLApp::app(), this);
+    if (dlg->exec()) {
+        UMLApp::app()->docWindow()->showDocumentation(this, true);
+        UMLApp::app()->document()->setModified(true);
+    }
+    dlg->close();
+    delete dlg;
+}
+
+/**
+ * Draw the object as an object (default).
+ */
+void ObjectWidget::paintObject(QPainter *painter)
+{
+    QFont oldFont = painter->font();
+    QFont font = UMLWidget::font();
+    font.setUnderline(true);
+    painter->setFont(font);
+
+    setPenFromSettings(painter);
+    if(UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    else
+        painter->setBrush(m_scene->backgroundColor());
+    const int w = width();
+    const int h = height();
+
+    const QString t = m_instanceName + QLatin1String(" : ") + name();
+    int multiInstOfst = 0;
+    if (m_multipleInstance) {
+        painter->drawRect(10, 10, w - 10, h - 10);
+        painter->drawRect(5, 5, w - 10, h - 10);
+        multiInstOfst = 10;
+    }
+    painter->drawRect(0, 0, w - multiInstOfst, h - multiInstOfst);
+    painter->setPen(textColor());
+    painter->drawText(O_MARGIN, O_MARGIN,
+               w - O_MARGIN * 2 - multiInstOfst, h - O_MARGIN * 2 - multiInstOfst,
+               Qt::AlignCenter, t);
+
+    painter->setFont(oldFont);
+}
+
+/**
+ * Draw the object as an actor.
+ */
+void ObjectWidget::paintActor(QPainter *painter)
+{
+    const QFontMetrics &fm = getFontMetrics(FT_UNDERLINE);
+
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    const int w = width();
+    const int textStartY = A_HEIGHT + A_MARGIN;
+    const int fontHeight  = fm.lineSpacing();
+
+    const int middleX = w / 2;
+    const int thirdH = A_HEIGHT / 3;
+
+    //draw actor
+    painter->drawEllipse(middleX - A_WIDTH / 2, 0,  A_WIDTH, thirdH);//head
+    painter->drawLine(middleX, thirdH, middleX, thirdH * 2);//body
+    painter->drawLine(middleX, 2 * thirdH,
+               middleX - A_WIDTH / 2, A_HEIGHT);//left leg
+    painter->drawLine(middleX, 2 * thirdH,
+               middleX + A_WIDTH / 2, A_HEIGHT);//right leg
+    painter->drawLine(middleX - A_WIDTH / 2, thirdH + thirdH / 2,
+               middleX + A_WIDTH / 2, thirdH + thirdH / 2);//arms
+    //draw text
+    painter->setPen(textColor());
+    QString t = m_instanceName + QLatin1String(" : ") + name();
+    painter->drawText(A_MARGIN, textStartY,
+               w - A_MARGIN * 2, fontHeight, Qt::AlignCenter, t);
+}
+
+/**
+ * Move the object up on a sequence diagram.
+ */
+void ObjectWidget::tabUp()
+{
+    int newY = y() - height();
+    if (newY < topMargin())
+        newY = topMargin();
+    setY(newY);
+    adjustAssocs(x(), newY);
+}
+
+/**
+ * Move the object down on a sequence diagram.
+ */
+void ObjectWidget::tabDown()
+{
+    int newY = y() + height();
+    setY(newY);
+    adjustAssocs(x(), newY);
+}
+
+/**
+ * Returns the top margin constant (Y axis value)
+ *
+ * @return  Y coordinate of the space between the diagram top
+ *          and the upper edge of the ObjectWidget.
+ */
+int ObjectWidget::topMargin()
+{
+    return 80 - height();
+}
+
+/**
+ * Returns whether or not the widget can be moved vertically up.
+ *
+ * @return  True if widget can be moved upwards vertically.
+ */
+bool ObjectWidget::canTabUp()
+{
+    return (y() > topMargin());
+}
+
+/**
+ * Sets whether to show deconstruction on sequence line.
+ *
+ * @param bShow   True if destruction on line shall be shown.
+ */
+void ObjectWidget::setShowDestruction(bool bShow)
+{
+    m_showDestruction = bShow;
+    if(m_pLine)
+        m_pLine->setupDestructionBox();
+}
+
+/**
+ * Returns whether to show deconstruction on sequence line.
+ *
+ * @return  True if destruction on sequence line is shown.
+ */
+bool ObjectWidget::showDestruction() const
+{
+    return m_showDestruction;
+}
+
+/**
+ * Sets the y position of the bottom of the vertical line.
+ *
+ * @param yPosition The y coordinate for the bottom of the line.
+ */
+void ObjectWidget::setEndLine(int yPosition)
+{
+    if (m_pLine) {
+        m_pLine->setEndOfLine(yPosition);
+    }
+}
+
+/**
+ * Returns the end Y co-ord of the sequence line.
+ *
+ * @return  Y coordinate of the endpoint of the sequence line.
+ */
+int ObjectWidget::getEndLineY()
+{
+    int y = this->y() + height();
+    if(m_pLine)
+        y += m_pLine->getLineLength();
+    if (m_showDestruction)
+        y += 10;
+    return y;
+}
+
+/**
+ * Add a message widget to the list.
+ *
+ * @param message   Pointer to the MessageWidget to add.
+ */
+void ObjectWidget::messageAdded(MessageWidget* message)
+{
+    if (m_messages.count(message)) {
+        uError() << message->name() << ": duplicate entry !";
+        return ;
+    }
+    m_messages.append(message);
+}
+
+/**
+ * Remove a message widget from the list.
+ *
+ * @param message   Pointer to the MessageWidget to remove.
+ */
+void ObjectWidget::messageRemoved(MessageWidget* message)
+{
+    if (m_messages.removeAll(message) == false) {
+        uError() << message->name() << ": missing entry !";
+        return ;
+    }
+}
+
+/**
+ * Called when a message widget with an end on this object has
+ * moved up or down.
+ * Sets the bottom of the line to a nice position.
+ */
+void ObjectWidget::slotMessageMoved()
+{
+    if (m_pLine) {
+        int lowestMessage = 0;
+        foreach (MessageWidget* message, m_messages) {
+            int messageHeight = message->y() + message->height();
+            if (lowestMessage < messageHeight) {
+                lowestMessage = messageHeight;
+            }
+        }
+        m_pLine->setEndOfLine(lowestMessage + sequenceLineMargin);
+    }
+}
+
+/**
+ * Returns whether a message is overlapping with another message.
+ * Used by MessageWidget::paint() methods.
+ *
+ * @param y               top of your message
+ * @param messageWidget   pointer to your message so it doesn't check against itself
+ */
+bool ObjectWidget::messageOverlap(qreal y, MessageWidget* messageWidget)
+{
+    foreach (MessageWidget* message, m_messages) {
+        if (message == messageWidget) {
+            continue;
+        }
+        const qreal msgY = message->y();
+        const qreal msgHeight = msgY + message->height();
+        if (y >= msgY && y <= msgHeight) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Return the SeqLineWidget.
+ * Returns a non NULL pointer if this ObjectWidget is part of a
+ * sequence diagram.
+ */
+SeqLineWidget *ObjectWidget::sequentialLine() const
+{
+    return m_pLine;
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Returns the cursor to be shown when resizing the widget.
+ * The cursor shown is KCursor::sizeHorCursor().
+ *
+ * @return The cursor to be shown when resizing the widget.
+ */
+QCursor ObjectWidget::resizeCursor() const
+{
+    return Qt::SizeHorCursor;
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Resizes the width of the object widget.
+ * Object widgets can only be resized horizontally, so height isn't modified.
+ *
+ * @param newW   The new width for the widget.
+ * @param newH   The new height for the widget (isn't used).
+ */
+void ObjectWidget::resizeWidget(qreal newW, qreal newH)
+{
+    Q_UNUSED(newH);
+    setSize(newW, height());
+}
+
+/**
+ * Saves to the "objectwidget" XMI element.
+ */
+void ObjectWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement objectElement = qDoc.createElement(QLatin1String("objectwidget"));
+    UMLWidget::saveToXMI(qDoc, objectElement);
+    objectElement.setAttribute(QLatin1String("drawasactor"), m_drawAsActor);
+    objectElement.setAttribute(QLatin1String("multipleinstance"), m_multipleInstance);
+    objectElement.setAttribute(QLatin1String("decon"), m_showDestruction);
+    qElement.appendChild(objectElement);
+}
+
+/**
+ * Loads from a "objectwidget" XMI element.
+ */
+bool ObjectWidget::loadFromXMI(QDomElement& qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement))
+        return false;
+    QString draw = qElement.attribute(QLatin1String("drawasactor"), QLatin1String("0"));
+    QString multi = qElement.attribute(QLatin1String("multipleinstance"), QLatin1String("0"));
+    QString decon = qElement.attribute(QLatin1String("decon"), QLatin1String("0"));
+
+    m_drawAsActor = (bool)draw.toInt();
+    m_multipleInstance = (bool)multi.toInt();
+    m_showDestruction = (bool)decon.toInt();
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/objectwidget.h umbrello-15.08.1/umbrello/umlwidgets/objectwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/objectwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/objectwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,115 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef OBJECTWIDGET_H
+#define OBJECTWIDGET_H
+
+#include "messagewidgetlist.h"
+#include "umlwidget.h"
+
+class MessageWidget;
+class SeqLineWidget;
+class UMLScene;
+
+/**
+ * Displays an instance UMLObject of a concept.
+ *
+ * The local ID is needed as a it can represent a class
+ * that has many objects representing it.
+ *
+ * @short Displays an instance of a Concept.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class ObjectWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    ObjectWidget(UMLScene *scene, UMLObject *o);
+    virtual ~ObjectWidget();
+
+    virtual void setX(qreal x);
+    virtual void setY(qreal y);
+
+    qreal centerX();
+
+    void setMultipleInstance(bool multiple);
+    bool multipleInstance() const;
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    bool activate(IDChangeLog* ChangeLog = 0);
+
+    void cleanup();
+
+    void showPropertiesDialog();
+
+    void setDrawAsActor(bool drawAsActor);
+    bool drawAsActor() const;
+
+    void setShowDestruction(bool bShow);
+    bool showDestruction() const;
+
+    int topMargin();
+
+    void setEndLine(int yPosition);
+    int getEndLineY();
+
+    void messageAdded(MessageWidget* message);
+    void messageRemoved(MessageWidget* message);
+
+    bool canTabUp();
+
+    bool messageOverlap(qreal y, MessageWidget* messageWidget);
+
+    SeqLineWidget *sequentialLine() const;
+
+    virtual void resizeWidget(qreal newW, qreal newH);
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+    virtual bool loadFromXMI(QDomElement& qElement);
+
+public slots:
+    void slotMenuSelection(QAction* action);
+    virtual void slotFillColorChanged(Uml::ID::Type viewID);
+    void slotMessageMoved();
+
+protected:
+    virtual void mousePressEvent(QGraphicsSceneMouseEvent *me);
+    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *me);
+
+    QSizeF minimumSize() const;
+
+    virtual void moveEvent(QGraphicsSceneMouseEvent *event);
+    virtual void moveWidgetBy(qreal diffX, qreal diffY);
+    virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY);
+
+    virtual QCursor resizeCursor() const;
+
+    void paintActor(QPainter *p);
+    void paintObject(QPainter *p);
+
+private:
+    void tabUp();
+    void tabDown();
+
+    void moveDestructionBy(qreal diffY);
+
+    SeqLineWidget* m_pLine;
+    bool m_multipleInstance;   ///< draw an object as a multiple object
+    bool m_drawAsActor;        ///< object should be drawn as an Actor or an Object
+    bool m_showDestruction;    ///< show object destruction on sequence diagram line
+    bool m_isOnDestructionBox;  ///< true when a click occurred on the destruction box
+    MessageWidgetList m_messages;   ///< message widgets with an end on this widget
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/packagewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/packagewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/packagewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/packagewidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,149 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "packagewidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "package.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlobject.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+// qt includes
+#include <QPainter>
+
+/**
+ * Constructs a PackageWidget.
+ *
+ * @param scene   The parent of this PackageWidget.
+ * @param o       The UMLObject this will be representing.
+ */
+PackageWidget::PackageWidget(UMLScene * scene, UMLPackage *o)
+  : UMLWidget(scene, WidgetBase::wt_Package, o),
+    m_pMenu(0)
+{
+    setSize(100, 30);
+    setZValue(1);  // above box but below UMLWidget because may embed widgets
+    //set defaults from m_scene
+    if (m_scene) {
+        //check to see if correct
+        const Settings::OptionState& ops = m_scene->optionState();
+        m_showStereotype = ops.classState.showStereoType;
+    }
+}
+
+/**
+ * Destructor.
+ */
+PackageWidget::~PackageWidget()
+{
+}
+
+/**
+ * Overrides standard method.
+ */
+void PackageWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    else
+        painter->setBrush(m_scene->backgroundColor());
+
+    int w = width();
+    int h = height();
+    QFont font = UMLWidget::font();
+    font.setBold(true);
+    //FIXME italic is true when a package is first created until you click elsewhere, not sure why
+    font.setItalic(false);
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+    const int fontHeight  = fm.lineSpacing();
+
+    painter->drawRect(0, 0, 50, fontHeight);
+    if (m_umlObject != NULL
+         && m_umlObject->stereotype() == QLatin1String("subsystem")) {
+
+        const int fHalf = fontHeight / 2;
+        const int symY = fHalf;
+        const int symX = 38;
+        painter->drawLine(symX, symY, symX, symY + fHalf - 2);          // left leg
+        painter->drawLine(symX + 8, symY, symX + 8, symY + fHalf - 2);  // right leg
+        painter->drawLine(symX, symY, symX + 8, symY);                  // waist
+        painter->drawLine(symX + 4, symY, symX + 4, symY - fHalf + 2);  // head
+    }
+    painter->drawRect(0, fontHeight - 1, w, h - fontHeight);
+
+    painter->setPen(textColor());
+    painter->setFont(font);
+
+    int lines = 1;
+    if (m_umlObject != NULL) {
+        QString stereotype = m_umlObject->stereotype();
+        if (!stereotype.isEmpty()) {
+            painter->drawText(0, fontHeight + PACKAGE_MARGIN,
+                       w, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true));
+            lines = 2;
+        }
+    }
+
+    painter->drawText(0, (fontHeight*lines) + PACKAGE_MARGIN,
+               w, fontHeight, Qt::AlignCenter, name());
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF PackageWidget::minimumSize() const
+{
+    if (!m_umlObject) {
+        return UMLWidget::minimumSize();
+    }
+
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
+    const int fontHeight = fm.lineSpacing();
+
+    int lines = 1;
+
+    int width = fm.width(m_umlObject->name());
+
+    int tempWidth = 0;
+    if (!m_umlObject->stereotype().isEmpty()) {
+        tempWidth = fm.width(m_umlObject->stereotype(true));
+        lines = 2;
+    }
+    if (tempWidth > width)
+        width = tempWidth;
+    width += PACKAGE_MARGIN * 2;
+    if (width < 70)
+        width = 70;  // minumin width of 70
+
+    int height = (lines*fontHeight) + fontHeight + (PACKAGE_MARGIN * 2);
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Saves to the "packagewidget" XMI element.
+ */
+void PackageWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement(QLatin1String("packagewidget"));
+    UMLWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/packagewidget.h umbrello-15.08.1/umbrello/umlwidgets/packagewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/packagewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/packagewidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2003-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PACKAGEWIDGET_H
+#define PACKAGEWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLPackage;
+class ListPopupMenu;
+
+#define PACKAGE_MARGIN 5
+
+/**
+ * Defines a graphical version of the Package.  Most of the
+ * functionality will come from the @ref UMLPackage class.
+ *
+ * @short A graphical version of a Package.
+ * @author Jonathan Riddell
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class PackageWidget : public UMLWidget
+{
+public:
+    explicit PackageWidget(UMLScene * scene, UMLPackage * o);
+    virtual ~PackageWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+
+protected:
+    QSizeF minimumSize() const;
+
+private:
+    ListPopupMenu* m_pMenu;  ///< the right mouse button menu
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/pinportbase.cpp umbrello-15.08.1/umbrello/umlwidgets/pinportbase.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/pinportbase.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/pinportbase.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,378 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2014                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "pinportbase.h"
+
+// app includes
+#include "port.h"
+#include "package.h"
+#include "debug_utils.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "floatingtextwidget.h"
+
+// qt includes
+#include <QPainter>
+#include <QToolTip>
+
+// sys includes
+#include <cmath>
+
+PinPortBase::PinPortBase(UMLScene *scene, WidgetType type, UMLObject *o)
+    : UMLWidget(scene, type, o)
+{
+    init();
+}
+
+PinPortBase::PinPortBase(UMLScene *scene, WidgetType type, UMLWidget *a, Uml::ID::Type id)
+    : UMLWidget(scene, type, id)
+{
+    init(a);
+}
+
+/**
+ * Standard destructor.
+ */
+PinPortBase::~PinPortBase()
+{
+}
+
+/**
+ * Performs initializations which are common to PinWidget and PortWidget.
+ */
+void PinPortBase::init(UMLWidget *owner)
+{
+    m_ignoreSnapToGrid = true;
+    m_ignoreSnapComponentSizeToGrid = true;
+    m_resizable = false;
+    m_pOw = owner;
+    m_pName = NULL;
+    m_motionConnected = false;
+    const int edgeLength = 15;  // old: (m_baseType == wt_Pin ? 10 : 15);
+    const QSizeF FixedSize(edgeLength, edgeLength);
+    setMinimumSize(FixedSize);
+    setMaximumSize(FixedSize);
+    setSize(FixedSize);
+}
+
+UMLWidget* PinPortBase::ownerWidget()
+{
+    return m_pOw;
+}
+
+/**
+ * Overrides method from UMLWidget in order to set a tooltip.
+ * The tooltip is set to the name().
+ * The reason for using a tooltip for the name is that the size of this
+ * widget is not large enough to accommodate the average name.
+ */
+void PinPortBase::updateWidget()
+{
+    QString strName = name();
+    uDebug() << " port name is " << strName;
+    if (m_pName) {
+        m_pName->setText(strName);
+    } else {
+        setToolTip(strName);
+    }
+}
+
+/**
+ * Overrides method from UMLWidget to set the name.
+ */
+void PinPortBase::setName(const QString &strName)
+{
+    UMLWidget::setName(strName);
+    updateGeometry();
+    if (m_pName) {
+        m_pName->setText(strName);
+    }
+}
+
+/**
+ * Overridden from UMLWidget.
+ * Moves the widget to a new position using the difference between the
+ * current position and the new position.
+ * Movement is constrained such that the port is always attached to its
+ * owner widget.
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void PinPortBase::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    UMLWidget* owner = ownerWidget();
+    qreal newX = x() + diffX;
+    qreal newY = y() + diffY;
+    uDebug() << "PinPortBase::moveWidgetBy " << diffX << "," << diffY;
+    if (owner == NULL) {
+        uError() << "PinPortBase::moveWidgetBy: ownerWidget() returns NULL";
+        setX(newX);
+        setY(newY);
+        return;
+    }
+    const qreal deltaTop    = fabs(y() + height() - owner->y());
+    const qreal deltaBottom = fabs(owner->y() + owner->height() - y());
+    const qreal deltaLeft   = fabs(x() + width() - owner->x());
+    const qreal deltaRight  = fabs(owner->x() + owner->width() - x());
+    bool didAnyMovement = false;
+    if (deltaTop < 1.0 || deltaBottom < 1.0) {
+        if (newX < owner->x() - width())
+            newX = owner->x() - width();
+        else if (newX > owner->x() + owner->width())
+            newX = owner->x() + owner->width();
+        setX(newX);
+        didAnyMovement = true;
+    }
+    if (deltaLeft < 1.0 || deltaRight < 1.0) {
+        if (newY < owner->y() - height())
+            newY = owner->y() - height();
+        else if (newY > owner->y() + owner->height())
+            newY = owner->y() + owner->height();
+        setY(newY);
+        didAnyMovement = true;
+    }
+    if (!didAnyMovement) {
+        uDebug() << "constraint failed for (" << diffX << ", " << diffY << ")";
+        setX(newX);
+        setY(newY);
+    }
+}
+
+/**
+ * Align this widget's position such that it is attached at one of the
+ * sides of its owner's widget.
+ */
+void PinPortBase::attachToOwner() {
+    UMLWidget *owner = ownerWidget();
+    const QPointF scenePos = m_scene->pos();
+    if (owner == NULL) {
+        uError() << "PinPortBase::attachToOwner: ownerWidget() returns NULL";
+        setX(scenePos.x());
+        setY(scenePos.y());
+        return;
+    }
+    bool xIsWithinOwner = false;
+    if (scenePos.x() < owner->x() - width()) {
+        setX(owner->x() - width());
+    } else if (scenePos.x() <= owner->x() + owner->width()) {
+        setX(scenePos.x());
+        xIsWithinOwner = true;
+    } else {
+        setX(owner->x() + owner->width());
+    }
+    if (scenePos.y() < owner->y() - height()) {
+        setY(owner->y() - height());
+    } else if (scenePos.y() <= owner->y() + owner->height()) {
+        if (xIsWithinOwner) {
+            if (scenePos.y() <= owner->y() + owner->height() / 2.0)
+                setY(owner->y() - height());
+            else
+                setY(owner->y() + owner->height());
+        } else {
+            setY(scenePos.y());
+        }
+    } else {
+        setY(owner->y() + owner->height());
+    }
+
+    if (m_motionConnected) {
+        uDebug() << "connectOwnerMotion was already done";
+    } else {
+        connectOwnerMotion();
+        m_motionConnected = true;
+    }
+}
+
+/**
+ * Overrides standard method.
+ */
+void PinPortBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())  {
+        painter->setBrush(UMLWidget::fillColor());
+    } else {
+        painter->setBrush(m_scene->backgroundColor());
+    }
+
+    int w = width();
+    int h = height();
+
+    painter->drawRect(0, 0, w, h);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+void PinPortBase::slotOwnerMoved(qreal diffX, qreal diffY)
+{
+    setX(x() + diffX);
+    setY(y() + diffY);
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void PinPortBase::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_NameAsTooltip:
+        if (m_pName) {
+            action->setChecked(true);
+            delete m_pName;
+            m_pName = NULL;
+            setToolTip(name());
+        } else {
+            action->setChecked(false);
+            m_pName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating, name());
+            m_pName->setParentItem(this);
+            m_pName->setText(name());  // to get geometry update
+            m_pName->activate();
+            UMLWidget* owner = ownerWidget();
+            if (owner == NULL) {
+                uError() << "PinPortBase::slotMenuSelection: ownerWidget() returns NULL";
+                setX(x());
+                setY(y());
+            } else {
+                const qreal w = width();
+                const qreal h = height();
+                if (x() < owner->x())
+                    m_pName->setX(-m_pName->width());
+                else if (x() >= owner->x() + owner->width())
+                    m_pName->setX(w);
+                else
+                    m_pName->setX(-m_pName->width() / 2.0 + w / 2.0);
+                if (y() < owner->y())
+                    m_pName->setY(-m_pName->height() - 2);
+                else if (y() >= owner->y() + owner->height())
+                    m_pName->setY(h);
+                else
+                    m_pName->setY(-m_pName->height() / 2.0 + h / 2.0);
+            }
+            m_pName->update();
+            setToolTip(QString());
+            QToolTip::hideText();
+        }
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+FloatingTextWidget *PinPortBase::floatingTextWidget() {
+    return m_pName;
+}
+
+void PinPortBase::setFloatingTextWidget(FloatingTextWidget *ft) {
+    m_pName = ft;
+    if (m_pName)
+        m_pName->setParentItem(this);
+}
+
+/**
+ * Override method from UMLWidget in order to additionally check m_pName.
+ *
+ * @param p Point to be checked.
+ *
+ * @return 'this' if UMLWidget::onWidget(p) returns non NULL;
+ *         m_pName if m_pName is non NULL and m_pName->onWidget(p) returns non NULL;
+ *         else NULL.
+ */
+UMLWidget* PinPortBase::onWidget(const QPointF &p)
+{
+    if (UMLWidget::onWidget(p) != NULL)
+        return this;
+    if (m_pName) {
+        uDebug() << "floatingtext: " << m_pName->text();
+        return m_pName->onWidget(p);
+    }
+    return NULL;
+}
+
+/**
+ * Reimplement function from UMLWidget
+ */
+UMLWidget* PinPortBase::widgetWithID(Uml::ID::Type id)
+{
+    if (UMLWidget::widgetWithID(id))
+        return this;
+    if (m_pName && m_pName->widgetWithID(id))
+        return m_pName;
+    return NULL;
+}
+
+
+/**
+ * Saves the widget to the "pinwidget" or "portwidget" XMI element.
+ */
+void PinPortBase::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement element = qDoc.createElement(m_baseType == wt_Pin ? QLatin1String("pinwidget")
+                                                                  : QLatin1String("portwidget"));
+    element.setAttribute(QLatin1String("widgetaid"), Uml::ID::toString(ownerWidget()->id()));
+    UMLWidget::saveToXMI(qDoc, element);
+    if (m_pName && !m_pName->text().isEmpty()) {
+        m_pName->saveToXMI(qDoc, element);
+    }
+    qElement.appendChild(element);
+}
+
+/**
+ * Loads from a "pinwidget" or from a "portwidget" XMI element.
+ */
+bool PinPortBase::loadFromXMI(QDomElement & qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement))
+        return false;
+
+    QString widgetaid = qElement.attribute(QLatin1String("widgetaid"), QLatin1String("-1"));
+    Uml::ID::Type aId = Uml::ID::fromString(widgetaid);
+    UMLWidget *owner = m_scene->findWidget(aId);
+    if (owner == NULL) {
+        DEBUG(DBG_SRC) << "owner object " << Uml::ID::toString(aId) << " not found";
+        return false;
+    }
+    m_pOw = owner;
+
+    // Optional child element: floatingtext
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    if (!element.isNull()) {
+        QString tag = element.tagName();
+        if (tag == QLatin1String("floatingtext")) {
+            m_pName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating,
+                                             name(), Uml::ID::Reserved);
+            if (!m_pName->loadFromXMI(element)) {
+                // Most likely cause: The FloatingTextWidget is empty.
+                delete m_pName;
+                m_pName = NULL;
+            } else {
+                m_pName->setParentItem(this);
+                m_pName->activate();
+                m_pName->update();
+            }
+        } else {
+            uError() << "unknown tag " << tag;
+        }
+    }
+
+    if (m_motionConnected) {
+        uDebug() << "connectOwnerMotion was already done";
+    } else {
+        connectOwnerMotion();
+        m_motionConnected = true;
+    }
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/pinportbase.h umbrello-15.08.1/umbrello/umlwidgets/pinportbase.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/pinportbase.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/pinportbase.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,63 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2014                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PINPORTBASE_H
+#define PINPORTBASE_H
+
+#include "umlwidget.h"
+
+class FloatingTextWidget;
+
+/**
+ * @short Abstract base class for PinWidget and PortWidget
+ * @author Oliver Kellogg
+ * @see UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class PinPortBase : public UMLWidget
+{
+    Q_OBJECT
+public:
+    PinPortBase(UMLScene *scene, WidgetType type, UMLObject *o);
+    PinPortBase(UMLScene *scene, WidgetType type, UMLWidget *a, Uml::ID::Type id = Uml::ID::None);
+    virtual ~PinPortBase();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    virtual UMLWidget* ownerWidget();
+    virtual void connectOwnerMotion() = 0;
+
+    void setName(const QString &strName);
+    void updateWidget();
+    void moveWidgetBy(qreal diffX, qreal diffY);
+    void attachToOwner();
+
+    UMLWidget* onWidget(const QPointF& p);
+    UMLWidget* widgetWithID(Uml::ID::Type id);
+
+    FloatingTextWidget *floatingTextWidget();
+    void setFloatingTextWidget(FloatingTextWidget *ft);
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+    bool loadFromXMI(QDomElement& qElement);
+
+public slots:
+    void slotOwnerMoved(qreal diffX, qreal diffY);
+    virtual void slotMenuSelection(QAction* action);
+
+protected:
+    void init(UMLWidget *owner = 0);
+
+    UMLWidget* m_pOw;
+    FloatingTextWidget *m_pName;
+    bool m_motionConnected;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/pinwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/pinwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/pinwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/pinwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,103 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "pinwidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "floatingtextwidget.h"
+#include "listpopupmenu.h"
+#include "umlscene.h"
+#include "activitywidget.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPainter>
+
+DEBUG_REGISTER_DISABLED(PinWidget)
+
+/**
+ * Creates a Pin widget.
+ *
+ * @param scene   The parent of the widget.
+ * @param a       The widget to which this pin is attached.
+ * @param id      The ID to assign (-1 will prompt a new ID).
+ */
+PinWidget::PinWidget(UMLScene* scene, UMLWidget* a, Uml::ID::Type id)
+  : PinPortBase(scene, WidgetBase::wt_Pin, a, id)
+{
+    // setParent(a);
+    // m_nY = y() < getMinY() ? getMinY() : y();
+
+    m_pName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating, name());
+    m_pName->setParentItem(this);
+    m_pName->setText(name());  // to get geometry update
+    m_pName->activate();
+    setVisible(true);
+}
+
+/**
+ * Destructor.
+ */
+PinWidget::~PinWidget()
+{
+}
+
+/**
+ * Implement abstract function from PinPortWidget.
+ */
+void PinWidget::connectOwnerMotion()
+{
+    ActivityWidget *owner = static_cast<ActivityWidget*>(ownerWidget());
+    connect(owner, SIGNAL(sigActMoved(qreal,qreal)), this, SLOT(slotOwnerMoved(qreal,qreal)));
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void PinWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString name = m_Text;
+#if QT_VERSION >= 0x050000
+            name = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter Pin Name"),
+                                         i18n("Enter the pin name :"),
+                                         QLineEdit::Normal,
+                                         m_Text, &ok);
+#else
+            name = KInputDialog::getText(i18n("Enter Pin Name"),
+                                         i18n("Enter the pin name :"),
+                                         m_Text, &ok);
+#endif
+            if (ok) {
+                setName(name);
+            }
+        }
+        break;
+
+    default:
+        PinPortBase::slotMenuSelection(action);
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/pinwidget.h umbrello-15.08.1/umbrello/umlwidgets/pinwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/pinwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/pinwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,46 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PINWIDGET_H
+#define PINWIDGET_H
+
+#include "pinportbase.h"
+
+/**
+ * This class is the graphical version of a UML Pin. A pinWidget is created
+ * by a @ref UMLView.  An pinWidget belongs to only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
+ *
+ * The pinWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @short  A graphical version of a UML pin.
+ * @author Hassan KOUCH <hkouch@hotmail.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class PinWidget : public PinPortBase
+{
+    Q_OBJECT
+public:
+
+    PinWidget(UMLScene* scene, UMLWidget* a, Uml::ID::Type id = Uml::ID::None);
+    virtual ~PinWidget();
+
+    void connectOwnerMotion();
+    // int getMinY();
+
+public slots:
+    void slotMenuSelection(QAction* action);
+
+// private:
+    // int m_nY;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/portwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/portwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/portwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/portwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,106 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2014                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "portwidget.h"
+
+// app includes
+#include "port.h"
+#include "package.h"
+#include "debug_utils.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "componentwidget.h"
+#include "floatingtextwidget.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPainter>
+#include <QToolTip>
+
+/**
+ * Constructs a PortWidget.
+ *
+ * @param scene   The parent of this PortWidget.
+ * @param d       The UMLPort this will be representing.
+ */
+PortWidget::PortWidget(UMLScene *scene, UMLPort *d)
+  : PinPortBase(scene, WidgetBase::wt_Port, d)
+{
+    setToolTip(d->name());
+}
+
+/**
+ * Standard deconstructor.
+ */
+PortWidget::~PortWidget()
+{
+}
+
+/**
+ * Override function from PinPortWidget.
+ */
+UMLWidget* PortWidget::ownerWidget()
+{
+    if (m_pOw == NULL) {
+        const Uml::ID::Type compWidgetId = m_umlObject->umlPackage()->id();
+        m_pOw = m_scene->widgetOnDiagram(compWidgetId);
+    }
+    return m_pOw;
+}
+
+/**
+ * Implement abstract function from PinPortWidget.
+ */
+void PortWidget::connectOwnerMotion()
+{
+    ComponentWidget *owner = static_cast<ComponentWidget*>(ownerWidget());
+    connect(owner, SIGNAL(sigCompMoved(qreal,qreal)), this, SLOT(slotOwnerMoved(qreal,qreal)));
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void PortWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString newName;
+#if QT_VERSION >= 0x050000
+            newName = QInputDialog::getText(Q_NULLPTR,
+                                            i18n("Enter Port Name"), i18n("Enter the port name :"),
+                                            QLineEdit::Normal,
+                                            name(), &ok);
+#else
+            newName = KInputDialog::getText(i18n("Enter Port Name"), i18n("Enter the port name :"),
+                                            name(), &ok);
+#endif
+            if (ok) {
+                setName(newName);
+            }
+        }
+        break;
+
+    default:
+        PinPortBase::slotMenuSelection(action);
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/portwidget.h umbrello-15.08.1/umbrello/umlwidgets/portwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/portwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/portwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2014                                                    *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PORTWIDGET_H
+#define PORTWIDGET_H
+
+#include "pinportbase.h"
+
+class UMLPort;
+
+/**
+ * Defines a graphical version of the UML2 port.  Most of the functionality
+ * comes from the @ref PinPortBase class from which this class inherits.
+ *
+ * @short A graphical version of a port on a component.
+ * @author Oliver Kellogg
+ * @see PinPortBase, UMLWidget
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class PortWidget : public PinPortBase
+{
+    Q_OBJECT
+public:
+    PortWidget(UMLScene *scene, UMLPort *d);
+    virtual ~PortWidget();
+
+    UMLWidget* ownerWidget();
+    void connectOwnerMotion();
+
+public slots:
+    void slotMenuSelection(QAction* action);
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/preconditionwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/preconditionwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/preconditionwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/preconditionwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,335 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "preconditionwidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "listpopupmenu.h"
+#include "objectwidget.h"
+#include "uml.h"
+#include "umlscene.h"
+#include "uniqueid.h"
+#include "idchangelog.h"
+
+// kde includes
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+#include <KLocalizedString>
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPainter>
+
+DEBUG_REGISTER_DISABLED(PreconditionWidget)
+
+#define PRECONDITION_MARGIN 5
+#define PRECONDITION_WIDTH 30
+#define PRECONDITION_HEIGHT 10
+
+/**
+ * Creates a Precondition widget.
+ *
+ * @param scene   The parent of the widget.
+ * @param a       The role A widget for this precondition.
+ * @param id      The ID to assign (-1 will prompt a new ID).
+ */
+PreconditionWidget::PreconditionWidget(UMLScene* scene, ObjectWidget* a, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Precondition, id),
+    m_objectWidget(a)
+{
+    m_ignoreSnapToGrid = true;
+    m_ignoreSnapComponentSizeToGrid = true;
+    m_resizable =  true ;
+    setVisible(true);
+    //updateResizability();
+    // calculateWidget();
+    if (y() < minY())
+        m_nY = minY();
+    else if (y() > maxY())
+        m_nY = maxY();
+    else
+        m_nY = y();
+
+    activate();
+}
+
+/**
+ * Destructor.
+ */
+PreconditionWidget::~PreconditionWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void PreconditionWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    int w = width();
+    int h = height();
+
+    int x = m_objectWidget->x() + m_objectWidget->width() / 2;
+    x -= w/2;
+    setX(x);
+    int y = this->y();
+
+    //test if y isn't above the object
+    if (y <= m_objectWidget->y() + m_objectWidget->height()) {
+        y = m_objectWidget->y() + m_objectWidget->height() + 15;
+    }
+    if (y + h >= m_objectWidget->getEndLineY()) {
+        y = m_objectWidget->getEndLineY() - h;
+    }
+    setY(y);
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor()) {
+        painter->setBrush(UMLWidget::fillColor());
+    }
+    {
+        const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+        const int fontHeight  = fm.lineSpacing();
+        const QString precondition_value = QLatin1String("{ ") + name() + QLatin1String(" }");
+        //int middleX = w / 2;
+        int textStartY = (h / 2) - (fontHeight / 2);
+        painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
+        painter->setPen(textColor());
+        painter->setFont(UMLWidget::font());
+        painter->drawText(PRECONDITION_MARGIN, textStartY,
+                       w - PRECONDITION_MARGIN * 2, fontHeight, Qt::AlignCenter, precondition_value);
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget.
+ */
+QSizeF PreconditionWidget::minimumSize() const
+{
+    int width = 10, height = 10;
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    const int textWidth = fm.width(name()) + 25;
+    height = fontHeight;
+    width = textWidth > PRECONDITION_WIDTH ? textWidth : PRECONDITION_WIDTH;
+    height = height > PRECONDITION_HEIGHT ? height : PRECONDITION_HEIGHT;
+    width += PRECONDITION_MARGIN * 2;
+    height += PRECONDITION_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Calculate the geometry of the widget.
+ */
+void PreconditionWidget::calculateWidget()
+{
+    calculateDimensions();
+
+    setVisible(true);
+
+    setX(m_nPosX);
+    setY(m_nY);
+}
+
+/**
+ * Activates a PreconditionWidget.  Connects the WidgetMoved signal from
+ * its m_objectWidget pointer so that PreconditionWidget can adjust to the move of
+ * the object widget.
+ */
+bool PreconditionWidget::activate(IDChangeLog * Log /*= 0*/)
+{
+    m_scene->resetPastePoint();
+    UMLWidget::activate(Log);
+
+    loadObjectWidget();
+
+    if (!m_objectWidget) {
+        DEBUG(DBG_SRC) << "role A widget " << Uml::ID::toString(m_widgetAId)
+            << " could not be found";
+        return false;
+    }
+
+    connect(m_objectWidget, SIGNAL(sigWidgetMoved(Uml::ID::Type)), this, SLOT(slotWidgetMoved(Uml::ID::Type)));
+
+    calculateDimensions();
+    return true;
+}
+
+/**
+ * Resolve references of this precondition so it references the correct
+ * new object widget after paste.
+ */
+void PreconditionWidget::resolveObjectWidget(IDChangeLog* log) {
+    m_widgetAId = log->findNewID(m_widgetAId);
+}
+
+/**
+ * Calculates the size of the widget.
+ */
+void PreconditionWidget::calculateDimensions()
+{
+    int x = 0;
+    int w = 0;
+    int h = 0;
+    int x1 = m_objectWidget->x();
+    int w1 = m_objectWidget->width() / 2;
+
+    x1 += w1;
+
+    QSizeF q = minimumSize();
+    w = q.width() > width() ? q.width() : width();
+    h = q.height() > height() ? q.height() : height();
+
+    x = x1 - w/2;
+
+    m_nPosX = x;
+
+    setSize(w, h);
+}
+
+/**
+ * Slot when widget is moved.
+ */
+void PreconditionWidget::slotWidgetMoved(Uml::ID::Type id)
+{
+    const Uml::ID::Type idA = m_objectWidget->localID();
+    if (idA != id) {
+        DEBUG(DBG_SRC) << "id=" << Uml::ID::toString(id) << ": ignoring for idA=" << Uml::ID::toString(idA);
+        return;
+    }
+    m_nY = y();
+    if (m_nY < minY())
+        m_nY = minY();
+    if (m_nY > maxY())
+        m_nY = maxY();
+
+    calculateDimensions();
+    if (m_scene->selectedCount(true) > 1)
+        return;
+}
+
+/**
+ * Returns the minimum height this widget should be set at on
+ * a sequence diagrams. Takes into account the widget positions
+ * it is related to.
+ */
+int PreconditionWidget::minY() const
+{
+    if (m_objectWidget) {
+        return m_objectWidget->y() + m_objectWidget->height();
+    }
+    return 0;
+}
+
+/**
+ * Returns the maximum height this widget should be set at on
+ * a sequence diagrams. Takes into account the widget positions
+ * it is related to.
+ */
+int PreconditionWidget::maxY() const
+{
+    if (m_objectWidget) {
+        return ((int)m_objectWidget->getEndLineY() - height());
+    }
+    return 0;
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void PreconditionWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString text = name();
+#if QT_VERSION >= 0x050000
+            text = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter Precondition Name"),
+                                         i18n("Enter the precondition :"),
+                                         QLineEdit::Normal,
+                                         text, &ok);
+#else
+            text = KInputDialog::getText(i18n("Enter Precondition Name"),
+                                          i18n("Enter the precondition :"),
+                                          text, &ok);
+#endif
+            if (ok && !text.isEmpty()) {
+                setName(text);
+            }
+            calculateWidget();
+        }
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Saves the widget to the "preconditionwidget" XMI element.
+ */
+void PreconditionWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement preconditionElement = qDoc.createElement(QLatin1String("preconditionwidget"));
+    UMLWidget::saveToXMI(qDoc, preconditionElement);
+
+    preconditionElement.setAttribute(QLatin1String("widgetaid"), Uml::ID::toString(m_objectWidget->localID()));
+    preconditionElement.setAttribute(QLatin1String("preconditionname"), name());
+    preconditionElement.setAttribute(QLatin1String("documentation"), documentation());
+    qElement.appendChild(preconditionElement);
+}
+
+/**
+ * Loads the widget from the "preconditionwidget" XMI element.
+ */
+bool PreconditionWidget::loadFromXMI(QDomElement& qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement))
+        return false;
+    QString widgetaid = qElement.attribute(QLatin1String("widgetaid"), QLatin1String("-1"));
+    setName(qElement.attribute(QLatin1String("preconditionname")));
+    setDocumentation(qElement.attribute(QLatin1String("documentation")));
+
+    m_widgetAId = Uml::ID::fromString(widgetaid);
+
+    // Lookup the ObjectWidget, if it can't be found, assume it will be
+    // resolved later
+    loadObjectWidget();
+
+    return true;
+}
+
+/**
+ * Load the object widget from m_widgetAId
+ *
+ * This method is called in loadFromXMI() when loading an XMI file, and called
+ * from activate() when activating a widget after pasting.
+ */
+void PreconditionWidget::loadObjectWidget()
+{
+    if (m_objectWidget == 0) {
+        m_objectWidget = dynamic_cast<ObjectWidget*>(
+            umlScene()->findWidget(m_widgetAId)
+        );
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/preconditionwidget.h umbrello-15.08.1/umbrello/umlwidgets/preconditionwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/preconditionwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/preconditionwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,70 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef PRECONDITIONWIDGET_H
+#define PRECONDITIONWIDGET_H
+
+#include "umlwidget.h"
+
+class ObjectWidget;
+
+/**
+ * @short  A graphical version of a UML Precondition (new in UML 2.0).
+ *
+ * This class is the graphical version of a UML Precondition.  A PreconditionWidget is created
+ * by a @ref UMLView.  An PreconditionWidget belongs to only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
+ *
+ * The PreconditionWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @author Florence Mattler <florence.mattler@libertysurf.fr>
+ *
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class PreconditionWidget : public UMLWidget
+{
+    Q_OBJECT
+public:
+    PreconditionWidget(UMLScene* scene, ObjectWidget* a, Uml::ID::Type id = Uml::ID::None);
+    virtual ~PreconditionWidget();
+
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    int minY() const;
+    int maxY() const;
+
+    bool activate(IDChangeLog* Log = 0);
+    void resolveObjectWidget(IDChangeLog* log);
+
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+    virtual bool loadFromXMI(QDomElement& qElement);
+
+    void setObjectWidget(ObjectWidget* widget);
+
+public slots:
+    void slotMenuSelection(QAction* action);
+    void slotWidgetMoved(Uml::ID::Type id);
+
+protected:
+    QSizeF minimumSize() const;
+
+private:
+    void calculateWidget();
+    void calculateDimensions();
+
+    ObjectWidget* m_objectWidget;
+    int m_nY;
+
+    Uml::ID::Type m_widgetAId;
+    void loadObjectWidget();
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/regionwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/regionwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/regionwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/regionwidget.cpp	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,108 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "regionwidget.h"
+
+// app includes
+#include "basictypes.h"
+#include "debug_utils.h"
+
+// kde includes
+#include <KLocalizedString>
+
+#define REGION_MARGIN 5
+#define REGION_WIDTH 90
+#define REGION_HEIGHT 45
+
+/**
+ * Creates a Region widget.
+ *
+ * @param scene   The parent of the widget.
+ * @param id      The ID to assign (-1 will prompt a new ID.)
+ */
+RegionWidget::RegionWidget(UMLScene* scene, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Region, id)
+{
+}
+
+/**
+ * Destructor.
+ */
+RegionWidget::~RegionWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void RegionWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    const int w = width();
+    const int h = height();
+
+    setPenFromSettings(painter);
+    QPen pen = painter->pen();
+    pen.setColor(Qt::red);
+    pen.setStyle(Qt::DashLine);
+    painter->setPen(pen);
+    painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF RegionWidget::minimumSize() const
+{
+    int width = 10, height = 10;
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    int textWidth = fm.width(name());
+
+    height  = fontHeight;
+    width   = textWidth > REGION_WIDTH?textWidth:REGION_WIDTH;
+    height  = height > REGION_HEIGHT ? height : REGION_HEIGHT;
+    width  += REGION_MARGIN * 2;
+    height += REGION_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Saves region widget to XMI element.
+ */
+void RegionWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement regionElement = qDoc.createElement(QLatin1String("regionwidget"));
+    UMLWidget::saveToXMI(qDoc, regionElement);
+    regionElement.setAttribute(QLatin1String("regionname"), name());
+    regionElement.setAttribute(QLatin1String("documentation"), documentation());
+
+    qElement.appendChild(regionElement);
+}
+
+/**
+ * Loads region widget from XMI element.
+ */
+bool RegionWidget::loadFromXMI(QDomElement& qElement)
+{
+    if (!UMLWidget::loadFromXMI(qElement)) {
+        return false;
+    }
+    setName(qElement.attribute(QLatin1String("regionname")));
+    setDocumentation(qElement.attribute(QLatin1String("documentation")));
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/regionwidget.h umbrello-15.08.1/umbrello/umlwidgets/regionwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/regionwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/regionwidget.h	2015-10-08 11:48:59.509089026 +0300
@@ -0,0 +1,36 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+***************************************************************************/
+
+#ifndef REGIONWIDGET_H
+#define REGIONWIDGET_H
+
+#include "umlwidget.h"
+
+/**
+ * Represents a rectangular region on Activity diagram.
+ */
+class RegionWidget: public UMLWidget
+{
+    Q_OBJECT
+public:
+    explicit RegionWidget(UMLScene* scene, Uml::ID::Type id = Uml::ID::None);
+    virtual ~RegionWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+    bool loadFromXMI(QDomElement& qElement);
+
+protected:
+    QSizeF minimumSize() const;
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/seqlinewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/seqlinewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/seqlinewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/seqlinewidget.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,197 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "seqlinewidget.h"
+
+//app includes
+#include "messagewidget.h"
+#include "objectwidget.h"
+#include "umlscene.h"
+#include "umlview.h"
+
+//qt includes
+#include <QPainter>
+
+// class members
+int const SeqLineWidget::m_nMouseDownEpsilonX = 20;
+
+/**
+ * Constructor.
+ */
+SeqLineWidget::SeqLineWidget(UMLScene *scene, ObjectWidget * pObject)
+  : QGraphicsLineItem(),
+    m_scene(scene)
+{
+    scene->addItem(this);
+    m_pObject = pObject;
+    setPen(QPen(m_pObject->lineColor(), 0, Qt::DashLine));
+    setZValue(0);
+    setVisible(true);
+    m_DestructionBox.line1 = 0;
+    m_nLengthY = 250;
+    setupDestructionBox();
+}
+
+/**
+ * Destructor.
+ */
+SeqLineWidget::~SeqLineWidget()
+{
+}
+
+/**
+ * Return whether point is on sequence line.
+ * Takes into account destruction box if shown.
+ *
+ * @param p The point to investigate.
+ * @return  True if point is on this sequence line.
+ */
+bool SeqLineWidget::onWidget(const QPointF & p)
+{
+    bool isOnWidget = false;
+    QPointF sp = line().p1();
+    QPointF ep = line().p2();
+    //see if on widget (for message creation)
+    if (sp.x() - m_nMouseDownEpsilonX < p.x()
+            && ep.x() + m_nMouseDownEpsilonX > p.x()
+            && sp.y() < p.y() && ep.y() + 3 > p.y())
+    {
+        isOnWidget = true;
+    }
+    return isOnWidget;
+}
+
+/**
+ * Return whether point is on the destruction box.
+ *
+ * @param p The point to investigate.
+ * @return  True if point is on the destruction box of this sequence line.
+ */
+bool SeqLineWidget::onDestructionBox(const QPointF & p)
+{
+    bool isOnDestructionBox = false;
+    int x = m_pObject->x() + m_pObject->width() / 2;
+    int y = m_pObject->y() + m_pObject->height() + m_nLengthY;
+
+    //see if on destruction box
+    if (!m_pObject->showDestruction()) {
+        return false;
+    }
+    if (x - 10 < p.x() && x + 10 > p.x()
+            && y - 10 < p.y() && y + 10 > p.y())
+    {
+        isOnDestructionBox = true;
+    }
+    return isOnDestructionBox;
+}
+
+/**
+ * Clean up anything before deletion.
+ */
+void SeqLineWidget::cleanup()
+{
+    cleanupDestructionBox();
+}
+
+/**
+ * Set the start point of the line.
+ *
+ * @param startX    X coordinate of the start point.
+ * @param startY    Y coordinate of the start point.
+ */
+void SeqLineWidget::setStartPoint(int startX, int startY)
+{
+    int endX = startX;
+    int endY = startY + m_nLengthY;
+    QGraphicsLineItem::setLine(startX, startY, endX, endY);
+    moveDestructionBox();
+}
+
+/**
+ * Clean up destruction box.
+ */
+void SeqLineWidget::cleanupDestructionBox()
+{
+    if (m_DestructionBox.line1) {
+        delete m_DestructionBox.line1;
+        m_DestructionBox.line1 = 0;
+        delete m_DestructionBox.line2;
+        m_DestructionBox.line2 = 0;
+    }
+}
+
+/**
+ * Set up destruction box.
+ */
+void SeqLineWidget::setupDestructionBox()
+{
+    cleanupDestructionBox();
+    if(!m_pObject->showDestruction()) {
+        return;
+    }
+    QRect rect;
+    rect.setX(m_pObject->x() + m_pObject->width() / 2 - 10);
+    rect.setY(m_pObject->y() + m_pObject->height() + m_nLengthY);
+    rect.setWidth(14);
+    rect.setHeight(14);
+
+    m_DestructionBox.line1 = new QGraphicsLineItem;
+    m_scene->addItem(m_DestructionBox.line1);
+    m_DestructionBox.setLine1Points(rect);
+    m_DestructionBox.line1->setVisible(true);
+    m_DestructionBox.line1->setPen(QPen(m_pObject->lineColor(), 2));
+    m_DestructionBox.line1->setZValue(3);
+
+    m_DestructionBox.line2 = new QGraphicsLineItem;
+    m_scene->addItem(m_DestructionBox.line2);
+    m_DestructionBox.setLine2Points(rect);
+    m_DestructionBox.line2->setVisible(true);
+    m_DestructionBox.line2->setPen(QPen(m_pObject->lineColor(), 2));
+    m_DestructionBox.line2->setZValue(3);
+}
+
+/**
+ * Move destruction box.
+ */
+void SeqLineWidget::moveDestructionBox()
+{
+    if(!m_DestructionBox.line1) {
+        return;
+    }
+    QRect rect;
+    rect.setX(m_pObject->x() + m_pObject->width() / 2 - 7);
+    rect.setY(m_pObject->y() + m_pObject->height() + m_nLengthY - 7);
+    rect.setWidth(14);
+    rect.setHeight(14);
+    m_DestructionBox.setLine1Points(rect);
+    m_DestructionBox.setLine2Points(rect);
+}
+
+/**
+ * Sets the y position of the bottom of the vertical line.
+ *
+ * @param yPosition The y coordinate for the bottom of the line.
+ */
+void SeqLineWidget::setEndOfLine(int yPosition)
+{
+    QPointF sp = line().p1();
+    int newY = yPosition;
+    m_nLengthY = yPosition - m_pObject->y() - m_pObject->height();
+    // normally the managing Objectwidget is responsible for the call of this function
+    // but to be sure - make a double check _against current position_
+    if (m_nLengthY < 0) {
+        m_nLengthY = 0;
+        newY = m_pObject->y() + m_pObject->height();
+    }
+    setLine(sp.x(), sp.y(), sp.x(), newY);
+    moveDestructionBox();
+    m_scene->resizeSceneToItems();
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/seqlinewidget.h umbrello-15.08.1/umbrello/umlwidgets/seqlinewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/seqlinewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/seqlinewidget.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef SEQLINEWIDGET_H
+#define SEQLINEWIDGET_H
+
+#include <QGraphicsLineItem>
+
+class ObjectWidget;
+class UMLScene;
+
+/**
+ * @short Widget class for graphical representation of sequence lines
+ * @author Paul Hensgen
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class SeqLineWidget : public QGraphicsLineItem
+{
+public:
+    SeqLineWidget(UMLScene *scene, ObjectWidget * pObject);
+    virtual ~SeqLineWidget();
+
+    bool onWidget(const QPointF& p);
+
+    bool onDestructionBox(const QPointF& p);
+
+    void cleanup();
+
+    void setupDestructionBox();
+
+    void setStartPoint(int startX, int startY);
+
+    /**
+     * Gets the length of the line.
+     *
+     * @return  Length of the line.
+     */
+    int getLineLength() {
+        return m_nLengthY;
+    }
+
+    /**
+     * Returns the @ref ObjectWidget associated with this sequence line.
+     *
+     * @return  Pointer to the associated ObjectWidget.
+     */
+    ObjectWidget * getObjectWidget() {
+        return m_pObject;
+    }
+
+    void setEndOfLine(int yPosition);
+
+protected:
+    void cleanupDestructionBox();
+
+    void moveDestructionBox();
+
+    ObjectWidget* m_pObject;  ///< ObjectWidget associated with this sequence line
+    UMLScene*     m_scene;    ///< scene displayed on
+
+    struct DestructionBox {
+        QGraphicsLineItem * line1;
+        QGraphicsLineItem * line2;
+        void setLine1Points(QRect rect) {
+            line1->setLine(rect.x(), rect.y(),
+                            rect.x() + rect.width(), rect.y() + rect.height());
+        }
+        void setLine2Points(QRect rect) {
+            line2->setLine(rect.x(), rect.y() + rect.height(),
+                            rect.x() + rect.width(), rect.y());
+        }
+    } m_DestructionBox;  ///< the destruction box
+
+    int m_nLengthY;  ///< the length of the line
+
+    static int const m_nMouseDownEpsilonX;   ///< margin used for mouse clicks
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/signalwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/signalwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/signalwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/signalwidget.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,386 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "signalwidget.h"
+
+// app includes
+#include "basictypes.h"
+#include "debug_utils.h"
+#include "floatingtextwidget.h"
+#include "linkwidget.h"
+#include "listpopupmenu.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "uniqueid.h"
+#include "umlview.h"
+#include "umlwidget.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#include <QEvent>
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPolygon>
+
+/**
+ * Creates a Signal widget.
+ *
+ * @param scene        The parent of the widget.
+ * @param signalType   The type of Signal.
+ * @param id           The ID to assign (-1 will prompt a new ID.)
+ */
+SignalWidget::SignalWidget(UMLScene *scene, SignalType signalType, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_Signal, id),
+    m_oldX(0),
+    m_oldY(0)
+{
+    m_signalType = signalType;
+    m_pName = NULL;
+    if (signalType == SignalWidget::Time) {
+        m_pName = new FloatingTextWidget(scene, Uml::TextRole::Floating, QString());
+        scene->setupNewWidget(m_pName);
+        m_pName->setX(0);
+        m_pName->setY(0);
+        connect(m_pName, SIGNAL(destroyed()), this, SLOT(slotTextDestroyed()));
+    }
+}
+
+/**
+ * Destructor.
+ */
+SignalWidget::~SignalWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void SignalWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    setPenFromSettings(painter);
+    const int w = width();
+    const int h = height();
+    QPolygon a;
+    switch (m_signalType)
+    {
+    case Send :
+        if(UMLWidget::useFillColor())
+            painter->setBrush(UMLWidget::fillColor());
+        {
+            a.setPoints(5, 0,      0,
+                           (w*2)/3, 0,
+                            w,      h/2,
+                           (w*2)/3, h,
+                            0,      h);
+            painter->drawPolygon(a);
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing();
+            int textStartY = (h / 2) - (fontHeight / 2);
+
+            painter->setPen(textColor());
+            QFont font = UMLWidget::font();
+            font.setBold(false);
+            painter->setFont(font);
+            painter->drawText(SIGNAL_MARGIN, textStartY,
+                           w - SIGNAL_MARGIN * 2, fontHeight,
+                           Qt::AlignCenter, name());
+            setPenFromSettings(painter);
+        }
+        break;
+    case Accept :
+        if(UMLWidget::useFillColor())
+            painter->setBrush(UMLWidget::fillColor());
+        {
+            a.setPoints(5, 0,   0,
+                            w/3, h/2,
+                            0,   h,
+                            w,   h,
+                            w,   0);
+
+            painter->drawPolygon(a);
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing();
+            int textStartY = (h / 2) - (fontHeight / 2);
+
+            painter->setPen(textColor());
+            QFont font = UMLWidget::font();
+            font.setBold(false);
+            painter->setFont(font);
+            painter->drawText(SIGNAL_MARGIN, textStartY,
+                           w - SIGNAL_MARGIN * 2 + (w/3), fontHeight,
+                           Qt::AlignCenter, name());
+            setPenFromSettings(painter);
+        }
+        break;
+    case Time :
+        if(UMLWidget::useFillColor())
+            painter->setBrush(UMLWidget::fillColor());
+        {
+            a.setPoints(4, 0, 0,
+                            w,  h,
+                            0, h,
+                            w,  0);
+
+            painter->drawPolygon(a);
+            //const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            //const int fontHeight  = fm.lineSpacing();
+            //int textStartY = (h / 2) - (fontHeight / 2);
+            painter->setPen(textColor());
+            QFont font = UMLWidget::font();
+            font.setBold(false);
+            painter->setFont(font);
+
+            setPenFromSettings(painter);
+        }
+        if (m_pName) {
+            if (m_pName->x() == 0 && m_pName->y() == 0) {
+                //the floating text has not been linked with the signal
+                m_pName->setX(w/2 - m_pName->width()/2);
+                m_pName->setY(h);
+            }
+            m_pName->setVisible((m_pName->text().length() > 0));
+            m_pName->updateGeometry();
+        }
+
+        break;
+    default:
+        uWarning() << "Unknown signal type:" << m_signalType;
+        break;
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides the UMLWidget method.
+ */
+void SignalWidget::setX(qreal newX)
+{
+    m_oldX = x();
+    UMLWidget::setX(newX);
+}
+
+/**
+ * Overrides the UMLWidget method.
+ */
+void SignalWidget::setY(qreal newY)
+{
+    m_oldY = y();
+    UMLWidget::setY(newY);
+}
+
+/**
+ * Sets the name of the signal.
+ */
+void SignalWidget::setName(const QString &strName)
+{
+    UMLWidget::setName(strName);
+    updateGeometry();
+    if (signalType() == SignalWidget::Time) {
+        if (!m_pName) {
+            m_pName = new FloatingTextWidget(umlScene(), Uml::TextRole::Floating, m_Text);
+            umlScene()->setupNewWidget(m_pName);
+            m_pName->setX(0);
+            m_pName->setY(0);
+            connect(m_pName, SIGNAL(destroyed()), this, SLOT(slotTextDestroyed()));
+        }
+        else
+            m_pName->setText(m_Text);
+    }
+}
+
+/**
+ * Returns the type of Signal.
+ */
+SignalWidget::SignalType SignalWidget::signalType() const
+{
+    return m_signalType;
+}
+
+/**
+ * Returns the type string of Signal.
+ */
+QString SignalWidget::signalTypeStr() const
+{
+    return QLatin1String(ENUM_NAME(SignalWidget, SignalType, m_signalType));
+}
+
+/**
+ * Sets the type of Signal.
+ */
+void SignalWidget::setSignalType(SignalType signalType)
+{
+    m_signalType = signalType;
+}
+
+/**
+ * Show a properties dialog for a UMLWidget.
+ */
+void SignalWidget::showPropertiesDialog()
+{
+}
+
+/**
+ * Overrides mouseMoveEvent.
+ */
+void SignalWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* me)
+{
+    UMLWidget::mouseMoveEvent(me);
+    int diffX = m_oldX - x();
+    int diffY = m_oldY - y();
+    if (m_pName!=NULL) {
+        m_pName->setX(m_pName->x() - diffX);
+        m_pName->setY(m_pName->y() - diffY);
+    }
+}
+
+/**
+ * Loads a "signalwidget" XMI element.
+ */
+bool SignalWidget::loadFromXMI(QDomElement & qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement))
+        return false;
+    m_Text = qElement.attribute(QLatin1String("signalname"));
+    m_Doc = qElement.attribute(QLatin1String("documentation"));
+    QString type = qElement.attribute(QLatin1String("signaltype"));
+    QString textid = qElement.attribute(QLatin1String("textid"), QLatin1String("-1"));
+    Uml::ID::Type textId = Uml::ID::fromString(textid);
+
+    setSignalType((SignalType)type.toInt());
+    if (signalType() == Time) {
+
+        if (textId != Uml::ID::None) {
+            UMLWidget *flotext = m_scene -> findWidget(textId);
+            if (flotext != NULL) {
+            // This only happens when loading files produced by
+            // umbrello-1.3-beta2.
+                m_pName = static_cast<FloatingTextWidget*>(flotext);
+                return true;
+            }
+        } else {
+            // no textid stored -> get unique new one
+            textId = UniqueID::gen();
+        }
+    }
+     //now load child elements
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    if (!element.isNull()) {
+        QString tag = element.tagName();
+        if (tag == QLatin1String("floatingtext") || tag == QLatin1String("UML::FloatingTextWidget")) {
+            m_pName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating, m_Text, textId);
+            if(! m_pName->loadFromXMI(element)) {
+                // Most likely cause: The FloatingTextWidget is empty.
+                delete m_pName;
+                m_pName = NULL;
+            }
+            else
+                connect(m_pName, SIGNAL(destroyed()), this, SLOT(slotTextDestroyed()));
+        } else {
+            uError() << "unknown tag " << tag;
+        }
+    }
+   return true;
+}
+
+/**
+ * Creates the "signalwidget" XMI element.
+ */
+void SignalWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement signalElement = qDoc.createElement(QLatin1String("signalwidget"));
+    UMLWidget::saveToXMI(qDoc, signalElement);
+    signalElement.setAttribute(QLatin1String("signalname"), m_Text);
+    signalElement.setAttribute(QLatin1String("documentation"), m_Doc);
+    signalElement.setAttribute(QLatin1String("signaltype"), m_signalType);
+    if (m_pName && !m_pName->text().isEmpty()) {
+        signalElement.setAttribute(QLatin1String("textid"), Uml::ID::toString(m_pName->id()));
+        m_pName -> saveToXMI(qDoc, signalElement);
+    }
+    qElement.appendChild(signalElement);
+}
+
+/**
+ * Show a properties dialog for a SignalWidget.
+ *
+ */
+void SignalWidget::slotMenuSelection(QAction* action)
+{
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+        {
+            bool ok = false;
+            QString name = m_Text;
+#if QT_VERSION >= 0x050000
+            name = QInputDialog::getText(Q_NULLPTR,
+                                         i18n("Enter signal name"),
+                                         i18n("Enter the signal name :"),
+                                         QLineEdit::Normal,
+                                         m_Text, &ok);
+#else
+            name = KInputDialog::getText(i18n("Enter signal name"),
+                                         i18n("Enter the signal name :"),
+                                         m_Text, &ok);
+#endif
+            if (ok && name.length() > 0) {
+                setName(name);
+            }
+        }
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+    }
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF SignalWidget::minimumSize() const
+{
+    int width = SIGNAL_WIDTH, height = SIGNAL_HEIGHT;
+    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+    const int fontHeight  = fm.lineSpacing();
+    int textWidth = fm.width(name());
+
+    if (m_signalType == Accept)
+         textWidth = int((float)textWidth * 1.3f);
+    height  = fontHeight;
+    if (m_signalType != Time)
+    {
+          width   = textWidth > SIGNAL_WIDTH?textWidth:SIGNAL_WIDTH;
+          height  = height > SIGNAL_HEIGHT?height:SIGNAL_HEIGHT;
+    }
+    width  += SIGNAL_MARGIN * 2;
+    height += SIGNAL_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Called if user deletes text widget
+ */
+void SignalWidget::slotTextDestroyed()
+{
+    m_pName = 0;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/signalwidget.h umbrello-15.08.1/umbrello/umlwidgets/signalwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/signalwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/signalwidget.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+***************************************************************************/
+
+#ifndef SIGNALWIDGET_H
+#define SIGNALWIDGET_H
+
+#include "floatingtextwidget.h"
+#include "linkwidget.h"
+#include "umlwidget.h"
+#include "worktoolbar.h"
+
+#define SIGNAL_MARGIN 5
+#define SIGNAL_WIDTH 45
+#define SIGNAL_HEIGHT 15
+
+/**
+ * Represents a Send signal, Accept signal or Time event on an
+ * Activity diagram.
+ */
+class SignalWidget : public UMLWidget
+{
+    Q_OBJECT
+    Q_ENUMS(SignalType)
+public:
+    /// Enumeration that codes the different types of signal.
+    enum SignalType
+    {
+        Send = 0,
+        Accept,
+        Time
+    };
+
+    explicit SignalWidget(UMLScene * scene, SignalType signalType = Send, Uml::ID::Type id = Uml::ID::None);
+    virtual ~SignalWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    void setX(qreal newX);
+    void setY(qreal newY);
+
+    virtual void setName(const QString &strName);
+
+    SignalType signalType() const;
+    QString signalTypeStr() const;
+    void setSignalType(SignalType signalType);
+
+    virtual void  showPropertiesDialog();
+
+    void mouseMoveEvent(QGraphicsSceneMouseEvent *me);
+
+    virtual bool loadFromXMI(QDomElement & qElement);
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+protected:
+    QSizeF minimumSize() const;
+
+    /**
+     * Save the value of the widget to know how to move the floatingtext
+     */
+    int m_oldX;
+    int m_oldY;
+
+    // Only for the time event
+    /**
+     * This is a pointer to the Floating Text widget which displays the
+     * name of the signal widget.
+     */
+    FloatingTextWidget* m_pName;
+
+    SignalType m_signalType; ///< Type of signal
+
+protected Q_SLOTS:
+    void slotTextDestroyed();
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/statewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/statewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/statewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/statewidget.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,534 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "statewidget.h"
+
+// app includes
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "listpopupmenu.h"
+#include "statedialog.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "umlwidget.h"
+
+// kde includes
+#include <KLocalizedString>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+#include <QPointer>
+
+/**
+ * Creates a State widget.
+ *
+ * @param scene       The parent of the widget.
+ * @param stateType   The type of state.
+ * @param id          The ID to assign (-1 will prompt a new ID.)
+ */
+StateWidget::StateWidget(UMLScene * scene, StateType stateType, Uml::ID::Type id)
+  : UMLWidget(scene, WidgetBase::wt_State, id)
+{
+    m_stateType = stateType;
+    m_drawVertical = true;
+    setAspectRatioMode();
+    m_Text = QLatin1String("State");
+    QSizeF size = minimumSize();
+    setSize(size.width(), size.height());
+}
+
+/**
+ * Destructor.
+ */
+StateWidget::~StateWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void StateWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    const qreal w = width();
+    const qreal h = height();
+    if (w == 0 || h == 0)
+        return;
+
+    setPenFromSettings(painter);
+    switch (m_stateType) {
+    case StateWidget::Normal:
+        {
+            if (UMLWidget::useFillColor()) {
+                painter->setBrush(UMLWidget::fillColor());
+            }
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing();
+            int textStartY = (h / 2) - (fontHeight / 2);
+            const int count = m_Activities.count();
+            if (count == 0) {
+                painter->drawRoundRect(0, 0, w, h, (h*40)/w, (w*40)/h);
+                painter->setPen(textColor());
+                QFont font = UMLWidget::font();
+                font.setBold(false);
+                painter->setFont(font);
+                painter->drawText(STATE_MARGIN, textStartY,
+                           w - STATE_MARGIN * 2, fontHeight,
+                           Qt::AlignCenter, name());
+                setPenFromSettings(painter);
+            } else {
+                painter->drawRoundRect(0, 0, w, h, (h*40)/w, (w*40)/h);
+                textStartY = STATE_MARGIN;
+                painter->setPen(textColor());
+                QFont font = UMLWidget::font();
+                font.setBold(true);
+                painter->setFont(font);
+                painter->drawText(STATE_MARGIN, textStartY, w - STATE_MARGIN * 2,
+                           fontHeight, Qt::AlignCenter, name());
+                font.setBold(false);
+                painter->setFont(font);
+                setPenFromSettings(painter);
+                int linePosY = textStartY + fontHeight;
+
+                QStringList::Iterator end(m_Activities.end());
+                for(QStringList::Iterator it(m_Activities.begin()); it != end; ++it) {
+                    textStartY += fontHeight;
+                    painter->drawLine(0, linePosY, w, linePosY);
+                    painter->setPen(textColor());
+                    painter->drawText(STATE_MARGIN, textStartY, w - STATE_MARGIN * 2,
+                               fontHeight, Qt::AlignCenter, *it);
+                    setPenFromSettings(painter);
+                    linePosY += fontHeight;
+                }//end for
+            }//end else
+        }
+        break;
+    case StateWidget::Initial :
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(0, 0, w, h);
+        break;
+    case StateWidget::End :
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(0, 0, w, h);
+        painter->setBrush(Qt::white);
+        painter->drawEllipse(1, 1, w - 2, h - 2);
+        painter->setBrush(WidgetBase::lineColor());
+        painter->drawEllipse(3, 3, w - 6, h - 6);
+        break;
+    case StateWidget::Fork:
+    case StateWidget::Join:
+        {
+            painter->setPen(Qt::black);
+            painter->setBrush(Qt::black);
+            painter->drawRect(rect());
+        }
+        break;
+    case StateWidget::Junction:
+        {
+            painter->setPen(Qt::black);
+            painter->setBrush(Qt::black);
+            painter->drawEllipse(rect());
+        }
+        break;
+    case StateWidget::DeepHistory:
+        {
+            painter->setBrush(Qt::white);
+            painter->drawEllipse(rect());
+            painter->setPen(Qt::black);
+            painter->setFont(UMLWidget::font());
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing() / 2;
+            const int xStar = fm.boundingRect(QLatin1String("H")).width();
+            const int yStar = fontHeight / 4;
+            painter->drawText((w / 6),
+                       (h / 4) + fontHeight, QLatin1String("H"));
+            painter->drawText((w / 6) + xStar,
+                       (h / 4) + fontHeight - yStar, QLatin1String("*"));
+        }
+        break;
+    case StateWidget::ShallowHistory:
+        {
+            painter->setBrush(Qt::white);
+            painter->drawEllipse(rect());
+            painter->setPen(Qt::black);
+            painter->setFont(UMLWidget::font());
+            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+            const int fontHeight  = fm.lineSpacing() / 2;
+            painter->drawText((w / 6),
+                       (h / 4) + fontHeight, QLatin1String("H"));
+        }
+        break;
+    case StateWidget::Choice:
+        {
+            const qreal x = w / 2;
+            const qreal y = h / 2;
+            QPolygonF polygon;
+            polygon << QPointF(x, 0) << QPointF(w, y)
+                    << QPointF(x, h) << QPointF(0, y);
+            painter->setBrush(UMLWidget::fillColor());
+            painter->drawPolygon(polygon);
+        }
+        break;
+    default:
+        uWarning() << "Unknown state type: " << stateTypeStr();
+        break;
+    }
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF StateWidget::minimumSize() const
+{
+    int width = 10, height = 10;
+    switch (m_stateType) {
+        case StateWidget::Normal:
+        {
+            const QFontMetrics &fm = getFontMetrics(FT_BOLD);
+            const int fontHeight  = fm.lineSpacing();
+            int textWidth = fm.width(name());
+            const int count = m_Activities.count();
+            height = fontHeight;
+            if(count > 0) {
+                height = fontHeight * (count + 1);
+
+                QStringList::ConstIterator end(m_Activities.end());
+                for(QStringList::ConstIterator it(m_Activities.begin()); it != end; ++it) {
+                    int w = fm.width(*it);
+                    if(w > textWidth)
+                        textWidth = w;
+                }//end for
+            }//end if
+            width = textWidth > STATE_WIDTH?textWidth:STATE_WIDTH;
+            height = height > STATE_HEIGHT?height:STATE_HEIGHT;
+            width += STATE_MARGIN * 2;
+            height += STATE_MARGIN * 2;
+            break;
+        }
+        case StateWidget::Fork:
+        case StateWidget::Join:
+            if (m_drawVertical) {
+                width = 8;
+                height = 60;
+            } else {
+                width = 60;
+                height = 8;
+            }
+            break;
+        case StateWidget::Junction:
+            width = 18;
+            height = 18;
+            break;
+        case StateWidget::DeepHistory:
+        case StateWidget::ShallowHistory:
+            {
+                const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+                width = height = fm.lineSpacing();
+            }
+            break;
+        case StateWidget::Choice:
+            width = 25;
+            height = 25;
+            break;
+        default:
+            break;
+    }
+
+    return QSizeF(width, height);
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF StateWidget::maximumSize()
+{
+    switch (m_stateType) {
+        case StateWidget::Initial:
+        case StateWidget::End:
+        case StateWidget::Junction:
+        case StateWidget::Choice:
+            return QSizeF(35, 35);
+            break;
+        case StateWidget::DeepHistory:
+        case StateWidget::ShallowHistory:
+            {
+                const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+                const int fontHeight  = fm.lineSpacing();
+                return QSizeF(fontHeight + 10, fontHeight + 10);
+            }
+            break;
+        default:
+            break;
+    }
+    return UMLWidget::maximumSize();
+}
+
+/**
+ * Set the aspect ratio mode.
+ * Some state types have a fixed aspect ratio
+ */
+void StateWidget::setAspectRatioMode()
+{
+    switch (m_stateType) {
+        case StateWidget::Initial:
+        case StateWidget::End:
+        case StateWidget::Choice:
+        case StateWidget::DeepHistory:
+        case StateWidget::ShallowHistory:
+        case StateWidget::Fork:
+        case StateWidget::Join:
+        case StateWidget::Junction:
+            setFixedAspectRatio(true);
+            break;
+        default:
+            setFixedAspectRatio(false);
+            break;
+    }
+}
+
+/**
+ * Returns the type of state.
+ * @return StateType
+ */
+StateWidget::StateType StateWidget::stateType() const
+{
+    return m_stateType;
+}
+
+/**
+ * Returns the type string of state.
+ */
+QString StateWidget::stateTypeStr() const
+{
+    return QLatin1String(ENUM_NAME(StateWidget, StateType, m_stateType));
+}
+
+/**
+ * Sets the type of state.
+ */
+void StateWidget::setStateType(StateType stateType)
+{
+    m_stateType = stateType;
+    setAspectRatioMode();
+}
+
+/**
+ * Adds an activity to this widget.
+ * @return true on success
+ */
+bool StateWidget::addActivity(const QString &activity)
+{
+    m_Activities.append(activity);
+    updateGeometry();
+    return true;
+}
+
+/**
+ * Removes the given activity from the state.
+ */
+bool StateWidget::removeActivity(const QString &activity)
+{
+    if(m_Activities.removeAll(activity) == 0)
+        return false;
+    updateGeometry();
+    return true;
+}
+
+/**
+ * Renames the given activity.
+ */
+bool StateWidget::renameActivity(const QString &activity, const QString &newName)
+{
+    int index = - 1;
+    if((index = m_Activities.indexOf(activity)) == -1)
+        return false;
+    m_Activities[ index ] = newName;
+    return true;
+}
+
+/**
+ * Sets the states activities to the ones given.
+ */
+void StateWidget::setActivities(const QStringList &list)
+{
+    m_Activities = list;
+    updateGeometry();
+}
+
+/**
+ * Returns the list of activities.
+ */
+QStringList StateWidget::activities() const
+{
+    return m_Activities;
+}
+
+/**
+ * Get whether to draw a fork or join vertically.
+ */
+bool StateWidget::drawVertical() const
+{
+    return m_drawVertical;
+}
+
+/**
+ * Set whether to draw a fork or join vertically.
+ */
+void StateWidget::setDrawVertical(bool to)
+{
+    m_drawVertical = to;
+    setSize(height(), width());
+    updateGeometry();
+    UMLWidget::adjustAssocs(x(), y());
+}
+
+/**
+ * Show a properties dialog for a StateWidget.
+ */
+void StateWidget::showPropertiesDialog()
+{
+    UMLApp::app()->docWindow()->updateDocumentation(false);
+
+    QPointer<StateDialog> dialog = new StateDialog(m_scene->activeView(), this);
+    if (dialog->exec() && dialog->getChangesMade()) {
+        UMLApp::app()->docWindow()->showDocumentation(this, true);
+        UMLApp::app()->document()->setModified(true);
+    }
+    delete dialog;
+}
+
+/**
+ * Creates the "statewidget" XMI element.
+ */
+void StateWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement stateElement = qDoc.createElement(QLatin1String("statewidget"));
+    UMLWidget::saveToXMI(qDoc, stateElement);
+    stateElement.setAttribute(QLatin1String("statename"), m_Text);
+    stateElement.setAttribute(QLatin1String("documentation"), m_Doc);
+    stateElement.setAttribute(QLatin1String("statetype"), m_stateType);
+    if (m_stateType == Fork || m_stateType == Join)
+        stateElement.setAttribute(QLatin1String("drawvertical"), m_drawVertical);
+    //save states activities
+    QDomElement activitiesElement = qDoc.createElement(QLatin1String("Activities"));
+
+    QStringList::Iterator end(m_Activities.end());
+    for(QStringList::Iterator it(m_Activities.begin()); it != end; ++it) {
+        QDomElement tempElement = qDoc.createElement(QLatin1String("Activity"));
+        tempElement.setAttribute(QLatin1String("name"), *it);
+        activitiesElement.appendChild(tempElement);
+    }//end for
+    stateElement.appendChild(activitiesElement);
+    qElement.appendChild(stateElement);
+}
+
+/**
+ * Loads a "statewidget" XMI element.
+ */
+bool StateWidget::loadFromXMI(QDomElement & qElement)
+{
+    if(!UMLWidget::loadFromXMI(qElement))
+        return false;
+    m_Text = qElement.attribute(QLatin1String("statename"));
+    m_Doc = qElement.attribute(QLatin1String("documentation"));
+    QString type = qElement.attribute(QLatin1String("statetype"), QLatin1String("1"));
+    m_stateType = (StateType)type.toInt();
+    setAspectRatioMode();
+    QString drawVertical = qElement.attribute(QLatin1String("drawvertical"), QLatin1String("1"));
+    m_drawVertical = (bool)drawVertical.toInt();
+    //load states activities
+    QDomNode node = qElement.firstChild();
+    QDomElement tempElement = node.toElement();
+    if(!tempElement.isNull() && tempElement.tagName() == QLatin1String("Activities")) {
+        QDomNode node = tempElement.firstChild();
+        QDomElement activityElement = node.toElement();
+        while(!activityElement.isNull()) {
+            if(activityElement.tagName() == QLatin1String("Activity")) {
+                QString name = activityElement.attribute(QLatin1String("name"));
+                if(!name.isEmpty())
+                    m_Activities.append(name);
+            }//end if
+            node = node.nextSibling();
+            activityElement = node.toElement();
+        }//end while
+    }//end if
+    return true;
+}
+
+/**
+ * Captures any popup menu signals for menus it created.
+ */
+void StateWidget::slotMenuSelection(QAction* action)
+{
+    bool ok = false;
+    QString nameNew = name();
+
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
+    switch(sel) {
+    case ListPopupMenu::mt_Rename:
+#if QT_VERSION >= 0x050000
+        nameNew = QInputDialog::getText(Q_NULLPTR,
+                                        i18n("Enter State Name"),
+                                        i18n("Enter the name of the new state:"),
+                                        QLineEdit::Normal,
+                                        name(), &ok);
+#else
+        nameNew = KInputDialog::getText(i18n("Enter State Name"),
+                                         i18n("Enter the name of the new state:"),
+                                         name(), &ok);
+#endif
+        if (ok && nameNew.length() > 0) {
+            setName(nameNew);
+        }
+        break;
+
+    case ListPopupMenu::mt_Properties:
+        showPropertiesDialog();
+        break;
+
+    case ListPopupMenu::mt_New_Activity:
+#if QT_VERSION >= 0x050000
+        nameNew = QInputDialog::getText(Q_NULLPTR,
+                                        i18n("Enter Activity"),
+                                        i18n("Enter the name of the new activity:"),
+                                        QLineEdit::Normal,
+                                        i18n("new activity"), &ok);
+#else
+        nameNew = KInputDialog::getText(i18n("Enter Activity"),
+                                         i18n("Enter the name of the new activity:"),
+                                         i18n("new activity"), &ok);
+#endif
+        if (ok && nameNew.length() > 0) {
+            addActivity(nameNew);
+        }
+        break;
+
+    case ListPopupMenu::mt_Flip:
+        setDrawVertical(!m_drawVertical);
+        break;
+
+    default:
+        UMLWidget::slotMenuSelection(action);
+        break;
+    }
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/statewidget.h umbrello-15.08.1/umbrello/umlwidgets/statewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/statewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/statewidget.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,99 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+***************************************************************************/
+
+#ifndef STATEWIDGET_H
+#define STATEWIDGET_H
+
+#include "umlwidget.h"
+
+#include <QPainter>
+#include <QStringList>
+
+#define STATE_MARGIN 5
+#define STATE_WIDTH 30
+#define STATE_HEIGHT 10
+
+/**
+ * This class is the graphical version of a UML State.
+ *
+ * A StateWidget is created by a @ref UMLView.  A StateWidget belongs to
+ * only one @ref UMLView instance.
+ * When the @ref UMLView instance that this class belongs to is destroyed,
+ * it will be automatically deleted.
+ *
+ * The StateWidget class inherits from the @ref UMLWidget class
+ * which adds most of the functionality to this class.
+ *
+ * @short  A graphical version of a UML State.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class StateWidget : public UMLWidget
+{
+    Q_OBJECT
+    Q_ENUMS(StateType)
+public:
+    /// Enumeration that codes the different types of state.
+    enum StateType
+    {
+        Initial = 0,     // Pseudostate
+        Normal,
+        End,
+        Fork,            // Pseudostate
+        Join,            // Pseudostate
+        Junction,        // Pseudostate
+        DeepHistory,     // Pseudostate
+        ShallowHistory,  // Pseudostate
+        Choice           // Pseudostate
+        //Terminate        // Pseudostate
+        //EntryPoint       // Pseudostate
+        //ExitPoint        // Pseudostate
+    };
+
+    explicit StateWidget(UMLScene * scene, StateType stateType = Normal, Uml::ID::Type id = Uml::ID::None);
+    virtual ~StateWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    StateType stateType() const;
+    QString stateTypeStr() const;
+    void setStateType(StateType stateType);
+
+    bool addActivity(const QString &activity);
+    bool removeActivity(const QString &activity);
+    bool renameActivity(const QString &activity, const QString &newName);
+
+    QStringList activities() const;
+    void setActivities(const QStringList &list);
+
+    bool drawVertical() const;
+    void setDrawVertical(bool to = true);
+
+    virtual void showPropertiesDialog();
+
+    virtual bool loadFromXMI(QDomElement & qElement);
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+    QSizeF minimumSize() const;
+    QSizeF maximumSize();
+    void setAspectRatioMode();
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction* action);
+
+private:
+    StateType   m_stateType;   ///< Type of state.
+    bool m_drawVertical;   ///< whether to draw the fork/join horizontally or vertically
+    QStringList m_Activities;  ///< List of activities for the state.
+
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/statusbartoolbutton.cpp umbrello-15.08.1/umbrello/umlwidgets/statusbartoolbutton.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/statusbartoolbutton.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/statusbartoolbutton.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,122 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab:
+/*
+Widget taken from Gwenview
+Copyright 2007 Aurélien Gâteau <agateau@kde.org>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+// Self
+#include "statusbartoolbutton.h"
+
+// Qt
+#include <QAction>
+#include <QStyleOptionToolButton>
+#include <QStylePainter>
+#include <QToolButton>
+
+// KDE
+#include <KLocalizedString>
+
+StatusBarToolButton::StatusBarToolButton(QWidget* parent)
+  : QToolButton(parent),
+    mGroupPosition(NotGrouped)
+{
+    setToolButtonStyle(Qt::ToolButtonTextOnly);
+    setFocusPolicy(Qt::NoFocus);
+    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+}
+
+
+QSize StatusBarToolButton::minimumSizeHint() const
+{
+    return sizeHint();
+}
+
+
+QSize StatusBarToolButton::sizeHint() const
+{
+    QSize sh = QToolButton::sizeHint();
+    sh.setHeight(fontMetrics().height());
+    return sh;
+}
+
+
+void StatusBarToolButton::setGroupPosition(StatusBarToolButton::GroupPosition groupPosition)
+{
+    mGroupPosition = groupPosition;
+}
+
+
+void StatusBarToolButton::paintEvent(QPaintEvent* event)
+{
+    if (mGroupPosition == NotGrouped) {
+        QToolButton::paintEvent(event);
+        return;
+    }
+    QStylePainter painter(this);
+    QStyleOptionToolButton opt;
+    initStyleOption(&opt);
+    QStyleOptionToolButton panelOpt = opt;
+
+    // Panel
+    QRect& panelRect = panelOpt.rect;
+    switch (mGroupPosition) {
+    case GroupLeft:
+        panelRect.setWidth(panelRect.width() * 2);
+        break;
+    case GroupCenter:
+        panelRect.setLeft(panelRect.left() - panelRect.width());
+        panelRect.setWidth(panelRect.width() * 3);
+        break;
+    case GroupRight:
+        panelRect.setLeft(panelRect.left() - panelRect.width());
+        break;
+    case NotGrouped:
+        Q_ASSERT(0);
+    }
+    painter.drawPrimitive(QStyle::PE_PanelButtonTool, panelOpt);
+
+    // Separator
+    const int y1 = opt.rect.top() + 6;
+    const int y2 = opt.rect.bottom() - 6;
+    if (mGroupPosition & GroupRight) {
+        const int x = opt.rect.left();
+        painter.setPen(opt.palette.color(QPalette::Light));
+        painter.drawLine(x, y1, x, y2);
+    }
+    if (mGroupPosition & GroupLeft) {
+        const int x = opt.rect.right();
+        painter.setPen(opt.palette.color(QPalette::Mid));
+        painter.drawLine(x, y1, x, y2);
+    }
+
+    // Text
+    painter.drawControl(QStyle::CE_ToolButtonLabel, opt);
+
+    // Filtering message on tooltip text for CJK to remove accelerators.
+    // Quoting ktoolbar.cpp:
+    // """
+    // CJK languages use more verbose accelerator marker: they add a Latin
+    // letter in parenthesis, and put accelerator on that. Hence, the default
+    // removal of ampersand only may not be enough there, instead the whole
+    // parenthesis construct should be removed. Provide these filtering i18n
+    // messages so that translators can use Transcript for custom removal.
+    // """
+    if (!actions().isEmpty()) {
+        QAction* action = actions().first();
+        setToolTip(i18nc("@info:tooltip of custom toolbar button", "%1", action->toolTip()));
+    }
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/statusbartoolbutton.h umbrello-15.08.1/umbrello/umlwidgets/statusbartoolbutton.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/statusbartoolbutton.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/statusbartoolbutton.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,58 @@
+// vim: set tabstop=4 shiftwidth=4 noexpandtab:
+/*
+Gwenview: an image viewer
+Copyright 2007 Aurélien Gâteau <agateau@kde.org>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+#ifndef STATUSBARTOOLBUTTON_H
+#define STATUSBARTOOLBUTTON_H
+
+// Qt
+#include <QToolButton>
+
+/**
+ * A thin tool button which can be grouped with another and look like one solid
+ * bar:
+ *
+ * (button1 | button2)
+ */
+class StatusBarToolButton : public QToolButton
+{
+    Q_OBJECT
+public:
+    enum GroupPosition {
+        NotGrouped = 0,
+        GroupLeft = 1,
+        GroupRight = 2,
+        GroupCenter = 3
+    };
+
+    explicit StatusBarToolButton(QWidget* parent = 0);
+
+    virtual QSize minimumSizeHint() const;
+    virtual QSize sizeHint() const;
+
+    void setGroupPosition(StatusBarToolButton::GroupPosition groupPosition);
+
+protected:
+    virtual void paintEvent(QPaintEvent* event);
+
+private:
+    GroupPosition mGroupPosition;
+};
+
+#endif /* STATUSBARTOOLBUTTON_H */
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/toolbarstateonewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/toolbarstateonewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/toolbarstateonewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/toolbarstateonewidget.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,249 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "toolbarstateonewidget.h"
+
+// app includes
+#include "activitywidget.h"
+#include "dialog_utils.h"
+#include "floatingtextwidget.h"
+#include "messagewidget.h"
+#include "objectwidget.h"
+#include "pinwidget.h"
+#include "portwidget.h"
+#include "preconditionwidget.h"
+#include "regionwidget.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlwidget.h"
+#include "object_factory.h"
+#include "package.h"
+#include "widget_factory.h"
+
+// kde includes
+#include <KLocalizedString>
+#include <KMessageBox>
+#if QT_VERSION < 0x050000
+#include <kinputdialog.h>
+#endif
+
+// qt includes
+#if QT_VERSION >= 0x050000
+#include <QInputDialog>
+#endif
+
+// using namespace Uml;
+
+/**
+ * Creates a new ToolBarStateOneWidget.
+ *
+ * @param umlScene The UMLScene to use.
+ */
+ToolBarStateOneWidget::ToolBarStateOneWidget(UMLScene *umlScene)
+  : ToolBarStatePool(umlScene),
+    m_firstObject(0),
+    m_isObjectWidgetLine(false)
+{
+}
+
+/**
+ * Destroys this ToolBarStateOneWidget.
+ */
+ToolBarStateOneWidget::~ToolBarStateOneWidget()
+{
+}
+
+/**
+ * Called when the current tool is changed to use another tool.
+ * Executes base method and cleans the message.
+ */
+void ToolBarStateOneWidget::cleanBeforeChange()
+{
+    ToolBarStatePool::cleanBeforeChange();
+}
+
+/**
+ * Called when a mouse event happened.
+ * It executes the base method and then updates the position of the
+ * message line, if any.
+ */
+void ToolBarStateOneWidget::mouseMove(QGraphicsSceneMouseEvent* ome)
+{
+    ToolBarStatePool::mouseMove(ome);
+}
+
+/**
+ * A widget was removed from the UMLView.
+ * If the widget removed was the current widget, the current widget is set
+ * to 0.
+ * Also, if it was the first object, the message is cleaned.
+ */
+void ToolBarStateOneWidget::slotWidgetRemoved(UMLWidget* widget)
+{
+    ToolBarState::slotWidgetRemoved(widget);
+}
+
+/**
+ * Selects only widgets, but no associations.
+ * Overrides base class method.
+ * If the press event happened on the line of an object, the object is set
+ * as current widget. If the press event happened on a widget, the widget is
+ * set as current widget.
+ */
+void ToolBarStateOneWidget::setCurrentElement()
+{
+    m_isObjectWidgetLine = false;
+    ObjectWidget* objectWidgetLine = m_pUMLScene->onWidgetLine(m_pMouseEvent->scenePos());
+    if (objectWidgetLine) {
+        setCurrentWidget(objectWidgetLine);
+        m_isObjectWidgetLine = true;
+        return;
+    }
+
+    UMLWidget *widget = m_pUMLScene->widgetAt(m_pMouseEvent->scenePos());
+    if (widget) {
+        setCurrentWidget(widget);
+        return;
+    }
+}
+
+/**
+ * Called when the release event happened on a widget.
+ * If the button pressed isn't left button or the widget isn't an object
+ * widget, the message is cleaned.
+ * If the release event didn't happen on the line of an object and the first
+ * object wasn't selected, nothing is done. If the first object was already
+ * selected, a creation message is made.
+ * If the event happened on the line of an object, the first object or the
+ * second are set, depending on whether the first object was already set or
+ * not.
+ */
+void ToolBarStateOneWidget::mouseReleaseWidget()
+{
+    WidgetBase::WidgetType type = widgetType();
+
+    if (type == WidgetBase::wt_Precondition) {
+        m_firstObject = 0;
+    }
+    if (type == WidgetBase::wt_Pin) {
+        m_firstObject = 0;
+    }
+
+    if (m_pMouseEvent->button() != Qt::LeftButton ||
+               (currentWidget()->baseType() != WidgetBase::wt_Object &&
+                currentWidget()->baseType() != WidgetBase::wt_Activity &&
+                currentWidget()->baseType() != WidgetBase::wt_Component &&
+                currentWidget()->baseType() != WidgetBase::wt_Region)) {
+        return;
+    }
+
+    if (!m_firstObject && type == WidgetBase::wt_Pin) {
+        setWidget(currentWidget());
+        return ;
+    }
+
+    if (!m_isObjectWidgetLine && !m_firstObject) {
+        return;
+    }
+
+    if (!m_firstObject) {
+        setWidget(currentWidget());
+    }
+
+}
+
+/**
+ * Called when the release event happened on an empty space.
+ * Cleans the message.
+ * Empty spaces are not only actual empty spaces, but also associations.
+ */
+void ToolBarStateOneWidget::mouseReleaseEmpty()
+{
+}
+
+/**
+ * Sets the first object of the message using the specified object.
+ * The temporal visual message is created and mouse tracking enabled, so
+ * mouse events will be delivered.
+ *
+ * @param firstObject The first object of the message.
+ */
+void ToolBarStateOneWidget::setWidget(UMLWidget* firstObject)
+{
+    m_firstObject = firstObject;
+
+    UMLWidget * umlwidget = 0;
+    //m_pUMLScene->viewport()->setMouseTracking(true);
+    if (widgetType() == WidgetBase::wt_Precondition) {
+        umlwidget = new PreconditionWidget(m_pUMLScene, static_cast<ObjectWidget*>(m_firstObject));
+
+        Dialog_Utils::askNameForWidget(umlwidget, i18n("Enter Precondition Name"), i18n("Enter the precondition"), i18n("new precondition"));
+            // Create the widget. Some setup functions can remove the widget.
+    }
+
+    if (widgetType() == WidgetBase::wt_Pin) {
+        if (m_firstObject->baseType() == WidgetBase::wt_Activity) {
+            umlwidget = new PinWidget(m_pUMLScene, m_firstObject);
+            // Create the widget. Some setup functions can remove the widget.
+        } else if (m_firstObject->baseType() == WidgetBase::wt_Component) {
+            bool pressedOK = false;
+#if QT_VERSION >= 0x050000
+            QString name = QInputDialog::getText(UMLApp::app(),
+                                                 i18n("Enter Port Name"), i18n("Enter the port"),
+                                                 QLineEdit::Normal,
+                                                 i18n("new port"),
+                                                 &pressedOK);
+#else
+            QString name = KInputDialog::getText(i18n("Enter Port Name"), i18n("Enter the port"), i18n("new port"),
+                                                 &pressedOK, UMLApp::app());
+#endif
+            if (pressedOK) {
+                UMLPackage* component = static_cast<UMLPackage*>(m_firstObject->umlObject());
+                UMLObject *port = Object_Factory::createUMLObject(UMLObject::ot_Port, name, component);
+                umlwidget = Widget_Factory::createWidget(m_pUMLScene, port);
+            }
+        }
+    }
+
+    if (umlwidget) {
+        m_pUMLScene->setupNewWidget(umlwidget);
+    }
+
+}
+
+/**
+ * Returns the widget type of this tool.
+ *
+ * @return The widget type of this tool.
+ */
+WidgetBase::WidgetType ToolBarStateOneWidget::widgetType()
+{
+    if (getButton() == WorkToolBar::tbb_Seq_Precondition) {
+        return WidgetBase::wt_Precondition;
+    }
+
+    if (getButton() == WorkToolBar::tbb_Pin) {
+        return WidgetBase::wt_Pin;
+    }
+    // Shouldn't happen
+    Q_ASSERT(0);
+    return WidgetBase::wt_Pin;
+}
+
+/**
+ * Goes back to the initial state.
+ */
+void ToolBarStateOneWidget::init()
+{
+    ToolBarStatePool::init();
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/toolbarstateonewidget.h umbrello-15.08.1/umbrello/umlwidgets/toolbarstateonewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/toolbarstateonewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/toolbarstateonewidget.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef TOOLBARSTATEONEWIDGET_H
+#define TOOLBARSTATEONEWIDGET_H
+
+#include "toolbarstatepool.h"
+#include "widgetbase.h"
+
+/**
+ * Sequence tool to create components linked with one object in sequence diagram
+ * like precondition.
+ * With sequence tool, one objects is selected clicking with left button on
+ * it
+ */
+class ToolBarStateOneWidget : public ToolBarStatePool
+{
+    Q_OBJECT
+public:
+    explicit ToolBarStateOneWidget(UMLScene *umlScene);
+    virtual ~ToolBarStateOneWidget();
+
+    virtual void cleanBeforeChange();
+
+    // FIXME: obsolete
+    virtual void mouseMove(QGraphicsSceneMouseEvent* ome);
+
+public Q_SLOTS:
+    virtual void slotWidgetRemoved(UMLWidget* widget);
+
+protected:
+    virtual void setCurrentElement();
+
+    virtual void mouseReleaseWidget();
+    virtual void mouseReleaseEmpty();
+
+    void setWidget(UMLWidget* firstObject);
+    WidgetBase::WidgetType widgetType();
+
+    UMLWidget* m_firstObject;  ///< The first object in the message.
+
+    /**
+     * If there is a current widget, it is true if the press event happened on
+     * the line of an object, or false if it happened on a normal UMLWidget.
+     */
+    bool m_isObjectWidgetLine;
+
+private:
+    virtual void init();
+};
+
+#endif //TOOLBARSTATEONEWIDGET_H
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/umlwidget.cpp umbrello-15.08.1/umbrello/umlwidgets/umlwidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/umlwidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/umlwidget.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,1859 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "umlwidget.h"
+
+// local includes
+#include "associationwidget.h"
+#include "classifier.h"
+#include "classpropertiesdialog.h"
+#include "cmds.h"
+#include "debug_utils.h"
+#include "docwindow.h"
+#include "floatingtextwidget.h"
+#include "idchangelog.h"
+#include "listpopupmenu.h"
+#include "settingsdialog.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umllistview.h"
+#include "umlobject.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "uniqueid.h"
+
+// kde includes
+#include <KLocalizedString>
+#include <KMessageBox>
+
+// qt includes
+#include <QApplication>
+#include <QColor>
+#include <QPainter>
+#include <QPointer>
+
+using namespace Uml;
+
+DEBUG_REGISTER_DISABLED(UMLWidget)
+
+const QSizeF UMLWidget::DefaultMinimumSize(50, 20);
+const QSizeF UMLWidget::DefaultMaximumSize(1000, 5000);
+const qreal UMLWidget::defaultMargin = 5;
+
+/**
+ * Creates a UMLWidget object.
+ *
+ * @param scene The view to be displayed on.
+ * @param type  The WidgetType to construct.
+ *              This must be set to the appropriate value by the constructors of inheriting classes.
+ * @param o The UMLObject to represent.
+ */
+UMLWidget::UMLWidget(UMLScene * scene, WidgetType type, UMLObject * o)
+  : WidgetBase(scene, type)
+{
+    init();
+    m_umlObject = o;
+    if (m_umlObject) {
+        connect(m_umlObject, SIGNAL(modified()), this, SLOT(updateWidget()));
+        m_nId = m_umlObject->id();
+    }
+}
+
+/**
+ * Creates a UMLWidget object.
+ *
+ * @param scene The view to be displayed on.
+ * @param type  The WidgetType to construct.
+ *              This must be set to the appropriate value by the constructors of inheriting classes.
+ * @param id The id of the widget.
+ *  The default value (id_None) will prompt generation of a new ID.
+ */
+UMLWidget::UMLWidget(UMLScene *scene, WidgetType type, Uml::ID::Type id)
+  : WidgetBase(scene, type)
+{
+    init();
+    if (id == Uml::ID::None)
+        m_nId = UniqueID::gen();
+    else
+        m_nId = id;
+}
+
+/**
+ * Destructor.
+ */
+UMLWidget::~UMLWidget()
+{
+    cleanup();
+}
+
+/**
+ * Assignment operator
+ */
+UMLWidget& UMLWidget::operator=(const UMLWidget & other)
+{
+    if (this == &other)
+        return *this;
+
+    WidgetBase::operator=(other);
+
+    // assign members loaded/saved
+    m_useFillColor = other.m_useFillColor;
+    m_usesDiagramFillColor = other.m_usesDiagramFillColor;
+    m_usesDiagramUseFillColor = other.m_usesDiagramUseFillColor;
+    m_fillColor = other.m_fillColor;
+    m_Assocs = other.m_Assocs;
+    m_isInstance = other.m_isInstance;
+    m_instanceName = other.m_instanceName;
+    m_instanceName = other.m_instanceName;
+    m_showStereotype = other.m_showStereotype;
+    setX(other.x());
+    setY(other.y());
+    setRect(rect().x(), rect().y(), other.width(), other.height());
+
+    // assign volatile (non-saved) members
+    m_startMove = other.m_startMove;
+    m_nPosX = other.m_nPosX;
+    m_doc = other.m_doc;    //new
+    m_resizable = other.m_resizable;
+    for (unsigned i = 0; i < FT_INVALID; ++i)
+        m_pFontMetrics[i] = other.m_pFontMetrics[i];
+    m_activated = other.m_activated;
+    m_ignoreSnapToGrid = other.m_ignoreSnapToGrid;
+    m_ignoreSnapComponentSizeToGrid = other.m_ignoreSnapComponentSizeToGrid;
+    return *this;
+}
+
+/**
+ * Overload '==' operator
+ */
+bool UMLWidget::operator==(const UMLWidget& other) const
+{
+    if (this == &other)
+        return true;
+
+    if (m_baseType != other.m_baseType) {
+        return false;
+    }
+
+    if (id() != other.id())
+        return false;
+
+    /* Testing the associations is already an exaggeration, no?
+       The type and ID should uniquely identify an UMLWidget.
+     */
+    if (m_Assocs.count() != other.m_Assocs.count()) {
+        return false;
+    }
+
+    // if(getBaseType() != wt_Text) // DON'T do this for floatingtext widgets, an infinite loop will result
+    // {
+    AssociationWidgetListIt assoc_it(m_Assocs);
+    AssociationWidgetListIt assoc_it2(other.m_Assocs);
+    AssociationWidget * assoc = 0, *assoc2 = 0;
+    while (assoc_it.hasNext() &&  assoc_it2.hasNext()) {
+        assoc = assoc_it.next();
+        assoc2 = assoc_it2.next();
+
+        if (!(*assoc == *assoc2)) {
+            return false;
+        }
+    }
+    // }
+    return true;
+    // NOTE:  In the comparison tests we are going to do, we don't need these values.
+    // They will actually stop things functioning correctly so if you change these, be aware of that.
+    /*
+    if(m_useFillColor != other.m_useFillColor)
+        return false;
+    if(m_nId != other.m_nId)
+        return false;
+    if(m_nX  != other.m_nX)
+        return false;
+    if(m_nY != other.m_nY)
+        return false;
+     */
+}
+
+/**
+ * Sets the local id of the object.
+ *
+ * @param id   The local id of the object.
+ */
+void UMLWidget::setLocalID(Uml::ID::Type id)
+{
+    m_nLocalID = id;
+}
+
+/**
+ * Returns the local ID for this object.  This ID is used so that
+ * many objects of the same @ref UMLObject instance can be on the
+ * same diagram.
+ *
+ * @return  The local ID.
+ */
+Uml::ID::Type UMLWidget::localID() const
+{
+    return m_nLocalID;
+}
+
+/**
+ * Returns the widget with the given ID.
+ * The default implementation tests the following IDs:
+ * - m_nLocalID
+ * - if m_umlObject is non NULL: m_umlObject->id()
+ * - m_nID
+ * Composite widgets override this function to test further owned widgets.
+ *
+ * @param id  The ID to test this widget against.
+ * @return  'this' if id is either of m_nLocalID, m_umlObject->id(), or m_nId;
+ *           else NULL.
+ */
+UMLWidget* UMLWidget::widgetWithID(Uml::ID::Type id)
+{
+    if (id == m_nLocalID ||
+        (m_umlObject != NULL && id == m_umlObject->id()) ||
+        id == m_nId)
+        return this;
+    return NULL;
+}
+
+/**
+ * Compute the minimum possible width and height.
+ *
+ * @return QSizeF(mininum_width, minimum_height)
+ */
+QSizeF UMLWidget::minimumSize() const
+{
+    return m_minimumSize;
+}
+
+/**
+ * This method is used to set the minimum size variable for this
+ * widget.
+ *
+ * @param newSize The size being set as minimum.
+ */
+void UMLWidget::setMinimumSize(const QSizeF& newSize)
+{
+    m_minimumSize = newSize;
+}
+
+/**
+ * Compute the maximum possible width and height.
+ *
+ * @return maximum size
+ */
+QSizeF UMLWidget::maximumSize()
+{
+    return m_maximumSize;
+}
+
+/**
+ * This method is used to set the maximum size variable for this
+ * widget.
+ *
+ * @param newSize The size being set as maximum.
+ */
+void UMLWidget::setMaximumSize(const QSizeF& newSize)
+{
+    m_maximumSize = newSize;
+}
+
+/**
+ * Event handler for context menu events.
+ */
+void UMLWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+    WidgetBase::contextMenuEvent(event);
+}
+
+/**
+ * Moves the widget to a new position using the difference between the
+ * current position and the new position.
+ * This method doesn't adjust associations. It only moves the widget.
+ *
+ * It can be overridden to constrain movement only in one axis even when
+ * the user isn't constraining the movement with shift or control buttons, for example.
+ * The movement policy set here is applied whenever the widget is moved, being it
+ * moving it explicitly, or as a part of a selection but not receiving directly the
+ * mouse events.
+ *
+ * Default behaviour is move the widget to the new position using the diffs.
+ * @see constrainMovementForAllWidgets
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void UMLWidget::moveWidgetBy(qreal diffX, qreal diffY)
+{
+    setX(x() + diffX);
+    setY(y() + diffY);
+}
+
+/**
+ * Modifies the value of the diffX and diffY variables used to move the widgets.
+ *
+ * It can be overridden to constrain movement of all the selected widgets only in one
+ * axis even when the user isn't constraining the movement with shift or control
+ * buttons, for example.
+ * The difference with moveWidgetBy is that the diff positions used here are
+ * applied to all the selected widgets instead of only to m_widget, and that
+ * moveWidgetBy, in fact, moves the widget, and here simply the diff positions
+ * are modified.
+ *
+ * Default behaviour is do nothing.
+ * @see moveWidgetBy
+ *
+ * @param diffX The difference between current X position and new X position.
+ * @param diffY The difference between current Y position and new Y position.
+ */
+void UMLWidget::constrainMovementForAllWidgets(qreal &diffX, qreal &diffY)
+{
+    Q_UNUSED(diffX) Q_UNUSED(diffY)
+}
+
+/**
+ * Bring the widget at the pressed position to the foreground.
+ */
+void UMLWidget::toForeground()
+{
+    QRectF rect = QRectF(scenePos(), QSizeF(width(), height()));
+    QList<QGraphicsItem*> items = scene()->items(rect, Qt::IntersectsItemShape, Qt::DescendingOrder);
+    DEBUG(DBG_SRC) << "items at " << rect << " = " << items.count();
+    if (items.count() > 1) {
+        foreach(QGraphicsItem* i, items) {
+            UMLWidget* w = dynamic_cast<UMLWidget*>(i);
+            if (w) {
+                DEBUG(DBG_SRC) << "item=" << w->name() << " with zValue=" << w->zValue();
+                if (w->name() != name()) {
+                    if (w->zValue() >= zValue()) {
+                        setZValue(w->zValue() + 1.0);
+                        DEBUG(DBG_SRC) << "bring to foreground with zValue: " << zValue();
+                    }
+                }
+            }
+        }
+    }
+    else {
+        setZValue(0.0);
+    }
+    DEBUG(DBG_SRC) << "zValue is " << zValue();
+}
+
+/**
+ * Handles a mouse press event.
+ * It'll select the widget (or mark it to be deselected) and prepare it to
+ * be moved or resized. Go on reading for more info about this.
+ *
+ * Widget values and message bar status are saved.
+ *
+ * If shift or control buttons are pressed, we're in move area no matter
+ * where the button was pressed in the widget. Moreover, if the widget
+ * wasn't already selected, it's added to the selection. If already selected,
+ * it's marked to be deselected when releasing the button (provided it isn't
+ * moved).
+ * Also, if the widget is already selected with other widgets but shift nor
+ * control buttons are pressed, we're in move area. If finally we don't move
+ * the widget, it's selected and the other widgets deselected when releasing
+ * the left button.
+ *
+ * If shift nor control buttons are pressed, we're facing a single selection.
+ * Depending on the position of the cursor, we're in move or in resize area.
+ * If the widget wasn't selected (both when there are no widgets selected, or
+ * when there're other widgets selected but not the one receiving the press
+ * event) it's selected and the others deselected, if any. If already selected,
+ * it's marked to be deselected when releasing the button (provided it wasn't
+ * moved or resized).
+ *
+ * @param event The QGraphicsSceneMouseEvent event.
+ */
+void UMLWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (event->button() != Qt::LeftButton) {
+        event->ignore();
+        return;
+    }
+    event->accept();
+    DEBUG(DBG_SRC) << "widget = " << name() << " / type = " << baseTypeStr();
+
+    toForeground();
+
+    m_startMovePostion = pos();
+    m_startResizeSize = QSizeF(width(), height());
+
+    // saving the values of the widget
+    m_pressOffset = event->scenePos() - pos();
+    DEBUG(DBG_SRC) << "press offset=" << m_pressOffset;
+
+    m_oldStatusBarMsg = UMLApp::app()->statusBarMsg();
+
+    if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) {
+        m_shiftPressed = true;
+
+        if (event->button() == Qt::LeftButton) {
+            m_inMoveArea = true;
+        }
+
+        if (!isSelected()) {
+            selectMultiple(event);
+        }
+        return;
+    }
+
+    m_shiftPressed = false;
+
+    int count = m_scene->selectedCount(true);
+    if (event->button() == Qt::LeftButton) {
+        if (isSelected() && count > 1) {
+            // single selection is made in release event if the widget wasn't moved
+            m_inMoveArea = true;
+            m_oldPos = pos();
+            return;
+        }
+
+        if (isInResizeArea(event)) {
+            m_inResizeArea = true;
+            m_oldW = width();
+            m_oldH = height();
+        } else {
+            m_inMoveArea = true;
+        }
+    }
+
+    // if widget wasn't selected, or it was selected but with other widgets also selected
+    if (!isSelected() || count > 1) {
+        selectSingle(event);
+    }
+}
+
+/**
+ * Handles a mouse move event.
+ * It resizes or moves the widget, depending on where the cursor is pressed
+ * on the widget. Go on reading for more info about this.
+ *
+ * If resizing, the widget is resized using UMLWidget::resizeWidget (where specific
+ * widget resize constraint can be applied), and then the associations are
+ * adjusted.
+ * The resizing can be constrained also to a specific axis using control
+ * and shift buttons. If on or another is pressed, it's constrained to X axis.
+ * If both are pressed, it's constrained to Y axis.
+ *
+ * If not resizing, the widget is being moved. If the move is being started,
+ * the selection bounds are set (which includes updating the list of selected
+ * widgets).
+ * The difference between the previous position of the selection and the new
+ * one is got (taking in account the selection bounds so widgets don't go
+ * beyond the scene limits). Then, it's constrained to X or Y axis depending
+ * on shift and control buttons.
+ * A further constraint is made using constrainMovementForAllWidgets (for example,
+ * if the widget that receives the event can only be moved in Y axis, with this
+ * method the movement of all the widgets in the selection can be constrained to
+ * be moved only in Y axis).
+ * Then, all the selected widgets are moved using moveWidgetBy (where specific
+ * widget movement constraint can be applied) and, if a certain amount of time
+ * passed from the last move event, the associations are also updated (they're
+ * not updated always to be easy on the CPU). Finally, the scene is resized,
+ * and selection bounds updated.
+ *
+ * @param event The QGraphicsSceneMouseEvent event.
+ */
+void UMLWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
+{
+    if (m_inResizeArea) {
+        resize(event);
+        return;
+    }
+
+    if (!m_moved) {
+        UMLApp::app()->document()->writeToStatusBar(i18n("Hold shift or ctrl to move in X axis. Hold shift and control to move in Y axis. Right button click to cancel move."));
+
+        m_moved = true;
+        //Maybe needed by AssociationWidget
+        m_startMove = true;
+
+        setSelectionBounds();
+    }
+
+    QPointF position = event->scenePos() - m_pressOffset;
+    qreal diffX = position.x() - x();
+    qreal diffY = position.y() - y();
+
+    if ((event->modifiers() & Qt::ShiftModifier) && (event->modifiers() & Qt::ControlModifier)) {
+        // move only in Y axis
+        diffX = 0;
+    } else if ((event->modifiers() & Qt::ShiftModifier) || (event->modifiers() & Qt::ControlModifier)) {
+        // move only in X axis
+        diffY = 0;
+    }
+
+    constrainMovementForAllWidgets(diffX, diffY);
+
+    // nothing to move
+    if (diffX == 0 && diffY == 0) {
+        return;
+    }
+
+    QPointF delta = event->scenePos() - event->lastScenePos();
+    adjustUnselectedAssocs(delta.x(), delta.y());
+
+    DEBUG(DBG_SRC) << "diffX=" << diffX << " / diffY=" << diffY;
+    foreach(UMLWidget* widget, umlScene()->selectedWidgets()) {
+        widget->moveWidgetBy(diffX, diffY);
+        widget->slotSnapToGrid();
+    }
+
+    // Move any selected associations.
+    foreach(AssociationWidget* aw, m_scene->selectedAssocs()) {
+        if (aw->isSelected()) {
+            aw->moveEntireAssoc(diffX, diffY);
+        }
+    }
+
+    umlScene()->resizeSceneToItems();
+}
+
+/**
+ * Handles a mouse release event.
+ * It selects or deselects the widget and cancels or confirms the move or
+ * resize. Go on reading for more info about this.
+ * No matter which tool is selected, Z position of widget is updated.
+ *
+ * Middle button release resets the selection.
+ * Left button release, if it wasn't moved nor resized, selects the widget
+ * and deselect the others if it wasn't selected and there were other widgets
+ * selected. If the widget was marked to be deselected, deselects it.
+ * If it was moved or resized, the document is set to modified if position
+ * or size changed. Also, if moved, all the associations are adjusted because
+ * the timer could have prevented the adjustment in the last move event before
+ * the release.
+ * If mouse was pressed in resize area, cursor is set again to normal cursor
+ * Right button release if right button was pressed shows the pop up menu for
+ * the widget.
+ * If left button was pressed, it cancels the move or resize with a mouse move
+ * event at the same position than the cursor was when pressed. Another left
+ * button release is also sent.
+ *
+ * @param event The QGraphicsSceneMouseEvent event.
+ */
+void UMLWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (!m_moved && !m_resized) {
+        if (!m_shiftPressed && (m_scene->selectedCount(true) > 1)) {
+            selectSingle(event);
+        } else if (!isSelected()) {
+            deselect(event);
+        }
+    } else {
+        // Commands
+        if (m_moved) {
+            int selectionCount = umlScene()->selectedWidgets().count();
+            if (selectionCount > 1) {
+                UMLApp::app()->beginMacro(i18n("Move widgets"));
+            }
+            foreach(UMLWidget* widget, umlScene()->selectedWidgets()) {
+                UMLApp::app()->executeCommand(new Uml::CmdMoveWidget(widget));
+            }
+            if (selectionCount > 1) {
+                UMLApp::app()->endMacro();
+            }
+            m_moved = false;
+        } else {
+            UMLApp::app()->executeCommand(new Uml::CmdResizeWidget(this));
+            m_resized = false;
+        }
+
+        if ((m_inMoveArea && wasPositionChanged()) ||
+                (m_inResizeArea && wasSizeChanged())) {
+            umlDoc()->setModified(true);
+        }
+
+        UMLApp::app()->document()->writeToStatusBar(m_oldStatusBarMsg);
+    }
+
+    if (m_inResizeArea) {
+        m_inResizeArea = false;
+        m_scene->activeView()->setCursor(Qt::ArrowCursor);
+    } else {
+        m_inMoveArea = false;
+    }
+}
+
+/**
+ * Event handler for mouse double click events.
+ * @param event the QGraphicsSceneMouseEvent event.
+ */
+void UMLWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+    if (event->button() == Qt::LeftButton) {
+        DEBUG(DBG_SRC) << "widget = " << name() << " / type = " << baseTypeStr();
+        switch(baseType()) {
+        case WidgetBase::wt_Message:  // will be handled in its class
+            QGraphicsItem::mouseDoubleClickEvent(event);
+            break;
+        default:
+            showPropertiesDialog();
+            event->accept();
+            break;
+        }
+    }
+}
+
+/**
+ * Return the start position of the move action.
+ * @return   point where the move began
+ */
+QPointF UMLWidget::startMovePosition() const
+{
+    return m_startMovePostion;
+}
+
+/**
+ * Set the start position of the move action.
+ * @param position point where the move began
+ */
+void UMLWidget::setStartMovePosition(const QPointF &position)
+{
+    m_startMovePostion = position;
+}
+
+/**
+ * Return the start size of the resize action.
+ * @return   size where the resize began
+ */
+QSizeF UMLWidget::startResizeSize() const
+{
+    return m_startResizeSize;
+}
+
+/**
+ * Resizes the widget.
+ * It's called from resize, after the values are constrained and before
+ * the associations are adjusted.
+ *
+ * Default behaviour is resize the widget using the new size values.
+ * @see resize
+ *
+ * @param newW   The new width for the widget.
+ * @param newH   The new height for the widget.
+ */
+void UMLWidget::resizeWidget(qreal newW, qreal newH)
+{
+    setSize(newW, newH);
+}
+
+/**
+ * When a widget changes this slot captures that signal.
+ */
+void UMLWidget::updateWidget()
+{
+    updateGeometry();
+    switch (m_baseType) {
+    case WidgetBase::wt_Class:
+        m_scene->createAutoAttributeAssociations(this);
+        break;
+    case WidgetBase::wt_Entity:
+        m_scene->createAutoConstraintAssociations(this);
+        break;
+    default:
+        break;
+    }
+
+    if (isVisible())
+        update();
+}
+
+/**
+ * Apply possible constraints to the given candidate width and height.
+ * The default implementation limits input values to the bounds returned
+ * by minimumSize()/maximumSize().
+ *
+ * @param width  input value, may be modified by the constraint
+ * @param height input value, may be modified by the constraint
+ */
+void UMLWidget::constrain(qreal& width, qreal& height)
+{
+    QSizeF minSize = minimumSize();
+    if (width < minSize.width())
+        width = minSize.width();
+    if (height < minSize.height())
+        height = minSize.height();
+    QSizeF maxSize = maximumSize();
+    if (width > maxSize.width())
+        width = maxSize.width();
+    if (height > maxSize.height())
+        height = maxSize.height();
+
+    if (fixedAspectRatio()) {
+        QSizeF size = rect().size();
+        float aspectRatio = size.width() > 0 ? (float)size.height()/size.width() : 1;
+        height = width * aspectRatio;
+    }
+}
+
+/**
+ * Initializes key attributes of the class.
+ */
+void UMLWidget::init()
+{
+    m_nId = Uml::ID::None;
+    m_nLocalID = UniqueID::gen();
+    m_isInstance = false;
+    setMinimumSize(DefaultMinimumSize);
+    setMaximumSize(DefaultMaximumSize);
+
+    m_font = QApplication::font();
+    for (int i = (int)FT_INVALID - 1; i >= 0; --i) {
+        FontType fontType = (FontType)i;
+        setupFontType(m_font, fontType);
+        m_pFontMetrics[fontType] = new QFontMetrics(m_font);
+    }
+
+    if (m_scene) {
+        m_useFillColor = true;
+        m_usesDiagramFillColor = true;
+        m_usesDiagramUseFillColor = true;
+        const Settings::OptionState& optionState = m_scene->optionState();
+        m_fillColor = optionState.uiState.fillColor;
+        m_showStereotype = optionState.classState.showStereoType;
+    } else {
+        uError() << "SERIOUS PROBLEM - m_scene is NULL";
+        m_useFillColor = false;
+        m_usesDiagramFillColor = false;
+        m_usesDiagramUseFillColor = false;
+        m_showStereotype = false;
+    }
+
+    m_resizable = true;
+    m_fixedAspectRatio = false;
+
+    m_startMove = false;
+    m_activated = false;
+    m_ignoreSnapToGrid = false;
+    m_ignoreSnapComponentSizeToGrid = false;
+    m_doc = UMLApp::app()->document();
+    m_nPosX = 0;
+    connect(m_scene, SIGNAL(sigFillColorChanged(Uml::ID::Type)), this, SLOT(slotFillColorChanged(Uml::ID::Type)));
+    connect(m_scene, SIGNAL(sigLineColorChanged(Uml::ID::Type)), this, SLOT(slotLineColorChanged(Uml::ID::Type)));
+    connect(m_scene, SIGNAL(sigTextColorChanged(Uml::ID::Type)), this, SLOT(slotTextColorChanged(Uml::ID::Type)));
+    connect(m_scene, SIGNAL(sigLineWidthChanged(Uml::ID::Type)), this, SLOT(slotLineWidthChanged(Uml::ID::Type)));
+
+    m_umlObject = 0;
+
+    m_oldPos = QPointF();
+    m_pressOffset = QPointF();
+    m_oldW = 0;
+    m_oldH = 0;
+
+    m_shiftPressed = false;
+    m_inMoveArea = false;
+    m_inResizeArea = false;
+    m_moved = false;
+    m_resized = false;
+
+    setZValue(2.0);  // default for most widgets
+}
+
+/**
+ * This is usually called synchronously after menu.exec() and \a
+ * trigger's parent is always the ListPopupMenu which can be used to
+ * get the type of action of \a trigger.
+ *
+ * @note Subclasses can reimplement to handle specific actions and
+ *       leave the rest to WidgetBase::slotMenuSelection.
+ */
+void UMLWidget::slotMenuSelection(QAction *trigger)
+{
+    if (!trigger) {
+        return;
+    }
+
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(trigger);
+    switch (sel) {
+    case ListPopupMenu::mt_Resize:
+        umlScene()->resizeSelection();
+        break;
+
+    default:
+        WidgetBase::slotMenuSelection(trigger);
+        break;
+    }
+}
+
+/**
+ * Captures when another widget moves if this widget is linked to it.
+ * @see sigWidgetMoved
+ *
+ * @param id The id of object behind the widget.
+ */
+void UMLWidget::slotWidgetMoved(Uml::ID::Type /*id*/)
+{
+}
+
+/**
+ * Captures a color change signal.
+ *
+ * @param viewID  The id of the UMLScene behind the widget.
+ */
+void UMLWidget::slotFillColorChanged(Uml::ID::Type viewID)
+{
+    //only change if on the diagram concerned
+    if (m_scene->ID() != viewID) {
+        return;
+    }
+    if (m_usesDiagramFillColor) {
+        WidgetBase::setFillColor(m_scene->fillColor());
+    }
+    if (m_usesDiagramUseFillColor) {
+        WidgetBase::setUseFillColor(m_scene->useFillColor());
+    }
+    update();
+}
+
+/**
+ * Captures a text color change signal.
+ *
+ * @param viewID  The id of the UMLScene behind the widget.
+ */
+void UMLWidget::slotTextColorChanged(Uml::ID::Type viewID)
+{
+    //only change if on the diagram concerned
+    if (m_scene->ID() != viewID)
+        return;
+    WidgetBase::setTextColor(m_scene->textColor());
+    update();
+}
+
+
+/**
+ * Captures a line color change signal.
+ *
+ * @param viewID  The id of the UMLScene behind the widget.
+ */
+void UMLWidget::slotLineColorChanged(Uml::ID::Type viewID)
+{
+    //only change if on the diagram concerned
+    if (m_scene->ID() != viewID)
+        return;
+
+    if (m_usesDiagramLineColor) {
+        WidgetBase::setLineColor(m_scene->lineColor());
+    }
+    update();
+}
+
+/**
+ * Captures a linewidth change signal.
+ *
+ * @param viewID  The id of the UMLScene behind the widget.
+ */
+void UMLWidget::slotLineWidthChanged(Uml::ID::Type viewID)
+{
+    //only change if on the diagram concerned
+    if (m_scene->ID() != viewID) {
+        return;
+    }
+    if (m_usesDiagramLineWidth) {
+        WidgetBase::setLineWidth(m_scene->lineWidth());
+    }
+    update();
+}
+
+/**
+ * Set the status of using fill color (undo action)
+ *
+ * @param fc the status of using fill color.
+ */
+void UMLWidget::setUseFillColor(bool fc)
+{
+    if (useFillColor() != fc) {
+        UMLApp::app()->executeCommand(new CmdChangeUseFillColor(this, fc));
+    }
+}
+
+/**
+ * Set the status of using fill color.
+ *
+ * @param fc the status of using fill color.
+ */
+void UMLWidget::setUseFillColorCmd(bool fc)
+{
+    WidgetBase::setUseFillColor(fc);
+    update();
+}
+
+/**
+ * Overrides the method from WidgetBase.
+ */
+void UMLWidget::setTextColorCmd(const QColor &color)
+{
+    WidgetBase::setTextColor(color);
+    update();
+}
+
+/**
+ * Overrides the method from WidgetBase.
+ */
+void UMLWidget::setTextColor(const QColor &color)
+{
+    if (textColor() != color) {
+        UMLApp::app()->executeCommand(new CmdChangeTextColor(this, color));
+        update();
+    }
+}
+
+/**
+ * Overrides the method from WidgetBase.
+ */
+void UMLWidget::setLineColorCmd(const QColor &color)
+{
+    WidgetBase::setLineColor(color);
+    update();
+}
+
+/**
+ * Overrides the method from WidgetBase.
+ */
+void UMLWidget::setLineColor(const QColor &color)
+{
+    if (lineColor() != color) {
+        UMLApp::app()->executeCommand(new CmdChangeLineColor(this, color));
+    }
+}
+
+/**
+ * Overrides the method from WidgetBase, execute CmdChangeLineWidth
+ */
+void UMLWidget::setLineWidth(uint width)
+{
+    if (lineWidth() != width) {
+        UMLApp::app()->executeCommand(new CmdChangeLineWidth(this, width));
+    }
+}
+
+/**
+ * Overrides the method from WidgetBase.
+ */
+void UMLWidget::setLineWidthCmd(uint width)
+{
+    WidgetBase::setLineWidth(width);
+    update();
+}
+
+/**
+ * Sets the background fill color
+ *
+ * @param color the new fill color
+ */
+void UMLWidget::setFillColor(const QColor &color)
+{
+    if (fillColor() != color) {
+        UMLApp::app()->executeCommand(new CmdChangeFillColor(this, color));
+    }
+}
+
+/**
+ * Sets the background fill color
+ *
+ * @param color the new fill color
+ */
+void UMLWidget::setFillColorCmd(const QColor &color)
+{
+    WidgetBase::setFillColor(color);
+    update();
+}
+
+/**
+ * Activate the object after serializing it from a QDataStream
+ *
+ * @param ChangeLog
+ * @return  true for success
+ */
+bool UMLWidget::activate(IDChangeLog* /*ChangeLog  = 0 */)
+{
+    if (widgetHasUMLObject(m_baseType) && m_umlObject == NULL) {
+        m_umlObject = m_doc->findObjectById(m_nId);
+        if (m_umlObject == NULL) {
+            uError() << "cannot find UMLObject with id=" << Uml::ID::toString(m_nId);
+            return false;
+        }
+    }
+    setFontCmd(m_font);
+    setSize(width(), height());
+    m_activated = true;
+    updateGeometry();
+    if (m_scene->getPaste()) {
+        FloatingTextWidget * ft = 0;
+        QPointF point = m_scene->getPastePoint();
+        int x = point.x() + this->x();
+        int y = point.y() + this->y();
+        if (m_scene->type() == Uml::DiagramType::Sequence) {
+            switch (baseType()) {
+            case WidgetBase::wt_Object:
+            case WidgetBase::wt_Precondition :
+                setY(this->y());
+                setX(x);
+                break;
+
+            case WidgetBase::wt_Message:
+                setY(this->y());
+                setX(x);
+                break;
+
+            case WidgetBase::wt_Text:
+                ft = static_cast<FloatingTextWidget *>(this);
+                if (ft->textRole() == Uml::TextRole::Seq_Message) {
+                    setX(x);
+                    setY(this->y());
+                } else {
+                    setX(this->x());
+                    setY(this->y());
+                }
+                break;
+
+            default:
+                setY(y);
+                break;
+            }//end switch base type
+        }//end if sequence
+        else {
+            setX(x);
+            setY(y);
+        }
+    }//end if pastepoint
+    else {
+        setX(this->x());
+        setY(this->y());
+    }
+    if (m_scene->getPaste())
+        m_scene->createAutoAssociations(this);
+    updateGeometry();
+    return true;
+}
+
+/**
+ * Returns true if the Activate method has been called for this instance
+ *
+ * @return The activate status.
+ */
+bool UMLWidget::isActivated() const
+{
+    return m_activated;
+}
+
+/**
+ * Set the m_activated flag of a widget but does not perform the Activate method
+ *
+ * @param active  Status of activation is to be set.
+ */
+void UMLWidget::setActivated(bool active /*=true*/)
+{
+    m_activated = active;
+}
+
+/**
+ * Adds an already created association to the list of
+ * associations that include this UMLWidget
+ */
+void UMLWidget::addAssoc(AssociationWidget* pAssoc)
+{
+    if (pAssoc && !m_Assocs.contains(pAssoc)) {
+        m_Assocs.append(pAssoc);
+    }
+}
+
+/**
+ * Removes an already created association from the list of
+ * associations that include this UMLWidget
+ */
+void UMLWidget::removeAssoc(AssociationWidget* pAssoc)
+{
+    if (pAssoc) {
+        m_Assocs.removeAll(pAssoc);
+    }
+}
+
+/**
+ * Adjusts associations with the given co-ordinates
+ *
+ * @param dx  The amount by which the widget moved in X direction.
+ * @param dy  The amount by which the widget moved in Y direction.
+ */
+void UMLWidget::adjustAssocs(qreal dx, qreal dy)
+{
+    // don't adjust Assocs on file load, as
+    // the original positions, which are stored in XMI
+    // should be reproduced exactly
+    // (don't try to reposition assocs as long
+    //   as file is only partly loaded -> reposition
+    //   could be misguided)
+    /// @todo avoid trigger of this event during load
+    if (m_doc->loading()) {
+        // don't recalculate the assocs during load of XMI
+        // -> return immediately without action
+        return;
+    }
+
+    foreach(AssociationWidget* assocwidget, m_Assocs) {
+        assocwidget->saveIdealTextPositions();
+    }
+
+    foreach(AssociationWidget* assocwidget, m_Assocs) {
+        assocwidget->widgetMoved(this, dx, dy);
+    }
+}
+
+/**
+ * Adjusts all unselected associations with the given co-ordinates
+ *
+ * @param dx  The amount by which the widget moved in X direction.
+ * @param dy  The amount by which the widget moved in Y direction.
+ */
+void UMLWidget::adjustUnselectedAssocs(qreal dx, qreal dy)
+{
+    foreach(AssociationWidget* assocwidget, m_Assocs) {
+        if (!assocwidget->isSelected())
+            assocwidget->saveIdealTextPositions();
+    }
+
+    foreach(AssociationWidget* assocwidget, m_Assocs) {
+        if (!assocwidget->isSelected()) {
+            assocwidget->widgetMoved(this, dx, dy);
+        }
+    }
+}
+
+/**
+ * Show a properties dialog for a UMLWidget.
+ */
+void UMLWidget::showPropertiesDialog()
+{
+    // will already be selected so make sure docWindow updates the doc
+    // back it the widget
+    UMLApp::app()->docWindow()->updateDocumentation(false);
+    QPointer<ClassPropertiesDialog> dlg = new ClassPropertiesDialog((QWidget*)UMLApp::app(), this);
+
+    if (dlg->exec()) {
+        UMLApp::app()->docWindow()->showDocumentation(umlObject(), true);
+        m_doc->setModified(true);
+    }
+    dlg->close(); //wipe from memory
+    delete dlg;
+}
+
+/**
+ * Move the widget by an X and Y offset relative to
+ * the current position.
+ */
+void UMLWidget::moveByLocal(qreal dx, qreal dy)
+{
+    qreal newX = x() + dx;
+    qreal newY = y() + dy;
+    setX(newX);
+    setY(newY);
+    adjustAssocs(dx, dy);
+}
+
+/**
+ * Set the pen.
+ */
+void UMLWidget::setPenFromSettings(QPainter & p)
+{
+    p.setPen(QPen(m_lineColor, m_lineWidth));
+}
+
+/**
+ * Set the pen.
+ */
+void UMLWidget::setPenFromSettings(QPainter *p)
+{
+    p->setPen(QPen(m_lineColor, m_lineWidth));
+}
+
+/**
+ * Returns the cursor to be shown when resizing the widget.
+ * Default cursor is KCursor::sizeFDiagCursor().
+ *
+ * @return The cursor to be shown when resizing the widget.
+ */
+QCursor UMLWidget::resizeCursor() const
+{
+    return Qt::SizeFDiagCursor;
+}
+
+/**
+ * Checks if the mouse is in resize area (right bottom corner), and sets
+ * the cursor depending on that.
+ * The cursor used when resizing is gotten from resizeCursor().
+ *
+ * @param me The QMouseEVent to check.
+ * @return true if the mouse is in resize area, false otherwise.
+ */
+bool UMLWidget::isInResizeArea(QGraphicsSceneMouseEvent *me)
+{
+    qreal m = 10.0;
+    const qreal w = width();
+    const qreal h = height();
+
+    // If the widget itself is very small then make the resize area small, too.
+    // Reason: Else it becomes impossible to do a move instead of resize.
+    if (w - m < m || h - m < m) {
+        m = 2.0;
+    }
+
+    if (m_resizable &&
+            me->scenePos().x() >= (x() + w - m) &&
+            me->scenePos().y() >= (y() + h - m)) {
+        m_scene->activeView()->setCursor(resizeCursor());
+        return true;
+    } else {
+        m_scene->activeView()->setCursor(Qt::ArrowCursor);
+        return false;
+    }
+}
+
+/**
+ * calculate content related size of widget.
+ *
+ * @return calculated widget size
+ */
+QSizeF UMLWidget::calculateSize(bool withExtensions /* = true */) const
+{
+    Q_UNUSED(withExtensions)
+    return QSizeF(width(), height());
+}
+
+/**
+ * Resize widget to minimum size.
+ */
+void UMLWidget::resize()
+{
+    qreal oldW = width();
+    qreal oldH = height();
+    // @TODO minimumSize() do not work in all cases, we need a dedicated autoResize() method
+    QSizeF size = minimumSize();
+    setSize(size.width(), size.height());
+    DEBUG(DBG_SRC) << "size=" << size;
+    adjustAssocs(size.width()-oldW, size.height()-oldH);
+}
+
+/**
+ * Resizes the widget and adjusts the associations.
+ * It's called when a mouse move event happens and the cursor was
+ * in resize area when pressed.
+ * Resizing can be constrained to an specific axis using control and shift buttons.
+ *
+ * @param me The QGraphicsSceneMouseEvent to get the values from.
+ */
+void UMLWidget::resize(QGraphicsSceneMouseEvent *me)
+{
+    // TODO the status message lies for at least MessageWidget which could only be resized vertical
+    UMLApp::app()->document()->writeToStatusBar(i18n("Hold shift or ctrl to move in X axis. Hold shift and control to move in Y axis. Right button click to cancel resize."));
+
+    m_resized = true;
+
+    qreal newW = m_oldW + me->scenePos().x() - x() - m_pressOffset.x();
+    qreal newH = m_oldH + me->scenePos().y() - y() - m_pressOffset.y();
+
+    if ((me->modifiers() & Qt::ShiftModifier) && (me->modifiers() & Qt::ControlModifier)) {
+        //Move in Y axis
+        newW = m_oldW;
+    } else if ((me->modifiers() & Qt::ShiftModifier) || (me->modifiers() & Qt::ControlModifier)) {
+        //Move in X axis
+        newH = m_oldH;
+    }
+
+    constrain(newW, newH);
+    resizeWidget(newW, newH);
+    DEBUG(DBG_SRC) << "event=" << me->scenePos() << "/ pos=" << pos() << " / newW=" << newW << " / newH=" << newH;
+    QPointF delta = me->scenePos() - me->lastScenePos();
+    adjustAssocs(delta.x(), delta.y());
+
+    m_scene->resizeSceneToItems();
+}
+
+/**
+ * Checks if the size of the widget changed respect to the size that
+ * it had when press event was fired.
+ *
+ * @return true if was resized, false otherwise.
+ */
+bool UMLWidget::wasSizeChanged()
+{
+    return m_oldW != width() || m_oldH != height();
+}
+
+/**
+ * Checks if the position of the widget changed respect to the position that
+ * it had when press event was fired.
+ *
+ * @return true if was moved, false otherwise.
+ */
+bool UMLWidget::wasPositionChanged()
+{
+    return m_oldPos != pos();
+}
+
+/**
+ * Fills m_selectedWidgetsList and sets the selection bounds ((m_min/m_max)X/Y attributes).
+ */
+void UMLWidget::setSelectionBounds()
+{
+}
+
+void UMLWidget::setSelectedFlag(bool _select)
+{
+    WidgetBase::setSelected(_select);
+}
+
+/**
+ * Sets the state of whether the widget is selected.
+ *
+ * @param _select The state of whether the widget is selected.
+ */
+void UMLWidget::setSelected(bool _select)
+{
+    WidgetBase::setSelected(_select);
+    const WidgetBase::WidgetType wt = m_baseType;
+    if (_select) {
+        if (m_scene->selectedCount() == 0) {
+            if (widgetHasUMLObject(wt)) {
+                UMLApp::app()->docWindow()->showDocumentation(m_umlObject, false);
+            } else {
+                UMLApp::app()->docWindow()->showDocumentation(this, false);
+            }
+        }//end if
+        /* if (wt != wt_Text && wt != wt_Box) {
+            setZ(9);//keep text on top and boxes behind so don't touch Z value
+        } */
+    } else {
+        /* if (wt != wt_Text && wt != wt_Box) {
+            setZ(m_origZ);
+        } */
+        if (isSelected())
+            UMLApp::app()->docWindow()->updateDocumentation(true);
+    }
+
+    // TODO: isn't this handled by toForeground() ?
+    const QPoint pos(x(), y());
+    UMLWidget *bkgnd = m_scene->widgetAt(pos);
+    if (bkgnd && bkgnd != this && _select) {
+        DEBUG(DBG_SRC) << "setting Z to " << bkgnd->zValue() + 1.0 << ", SelectState: " << _select;
+        setZValue(bkgnd->zValue() + 1.0);
+    }
+
+    update();
+
+    // selection changed, we have to make sure the copy and paste items
+    // are correctly enabled/disabled
+    UMLApp::app()->slotCopyChanged();
+
+    // select in tree view as done for diagrams
+    if (_select) {
+        UMLListViewItem * item = UMLApp::app()->listView()->findItem(id());
+        if (item)
+            UMLApp::app()->listView()->setCurrentItem(item);
+        else
+            UMLApp::app()->listView()->clearSelection();
+    }
+}
+
+/**
+ * Selects the widget and clears the other selected widgets, if any.
+ *
+ * @param me The QGraphicsSceneMouseEvent which made the selection.
+ */
+void UMLWidget::selectSingle(QGraphicsSceneMouseEvent *me)
+{
+    m_scene->clearSelected();
+
+    // Adds the widget to the selected widgets list, but as it has been cleared
+    // only the current widget is selected.
+    selectMultiple(me);
+}
+
+/**
+ * Selects the widget and adds it to the list of selected widgets.
+ *
+ * @param me The QGraphicsSceneMouseEvent which made the selection.
+ */
+void UMLWidget::selectMultiple(QGraphicsSceneMouseEvent *me)
+{
+    Q_UNUSED(me);
+
+    setSelected(true);
+}
+
+/**
+ * Deselects the widget and removes it from the list of selected widgets.
+ *
+ * @param me The QGraphicsSceneMouseEvent which made the selection.
+ */
+void UMLWidget::deselect(QGraphicsSceneMouseEvent *me)
+{
+    Q_UNUSED(me);
+
+    setSelected(false);
+}
+
+/**
+ * Clears the selection, resets the toolbar and deselects the widget.
+ */
+//void UMLWidget::resetSelection()
+//{
+//    m_scene->clearSelected();
+//    m_scene->resetToolbar();
+//    setSelected(false);
+//}
+
+/**
+ * Sets the view the widget is on.
+ *
+ * @param scene  The UMLScene the widget is on.
+ */
+void UMLWidget::setScene(UMLScene *scene)
+{
+    //remove signals from old view - was probably 0 anyway
+    disconnect(m_scene, SIGNAL(sigFillColorChanged(Uml::ID::Type)), this, SLOT(slotFillColorChanged(Uml::ID::Type)));
+    disconnect(m_scene, SIGNAL(sigTextColorChanged(Uml::ID::Type)), this, SLOT(slotTextColorChanged(Uml::ID::Type)));
+    disconnect(m_scene, SIGNAL(sigLineWidthChanged(Uml::ID::Type)), this, SLOT(slotLineWidthChanged(Uml::ID::Type)));
+    m_scene = scene;
+    connect(m_scene, SIGNAL(sigFillColorChanged(Uml::ID::Type)), this, SLOT(slotFillColorChanged(Uml::ID::Type)));
+    connect(m_scene, SIGNAL(sigTextColorChanged(Uml::ID::Type)), this, SLOT(slotTextColorChanged(Uml::ID::Type)));
+    connect(m_scene, SIGNAL(sigLineWidthChanged(Uml::ID::Type)), this, SLOT(slotLineWidthChanged(Uml::ID::Type)));
+}
+
+/**
+ * Sets the x-coordinate.
+ * Currently, the only class that reimplements this method is
+ * ObjectWidget.
+ *
+ * @param x The x-coordinate to be set.
+ */
+void UMLWidget::setX(qreal x)
+{
+    QGraphicsObject::setX(x);
+}
+
+/**
+ * Sets the y-coordinate.
+ * Currently, the only class that reimplements this method is
+ * ObjectWidget.
+ *
+ * @param y The y-coordinate to be set.
+ */
+void UMLWidget::setY(qreal y)
+{
+    QGraphicsObject::setY(y);
+}
+
+/**
+ * Used to cleanup any other widget it may need to delete.
+ * Used by child classes.  This should be called before deleting a widget of a diagram.
+ */
+void UMLWidget::cleanup()
+{
+}
+
+/**
+ * Tells the widget to snap to grid.
+ * Will use the grid settings of the @ref UMLView it belongs to.
+ */
+void UMLWidget::slotSnapToGrid()
+{
+    if (!m_ignoreSnapToGrid) {
+        qreal newX = m_scene->snappedX(x());
+        setX(newX);
+        qreal newY = m_scene->snappedY(y());
+        setY(newY);
+    }
+}
+
+/**
+ * Returns whether the widget type has an associated UMLObject
+ */
+bool UMLWidget::widgetHasUMLObject(WidgetBase::WidgetType type)
+{
+    if (type == WidgetBase::wt_Actor         ||
+            type == WidgetBase::wt_UseCase   ||
+            type == WidgetBase::wt_Class     ||
+            type == WidgetBase::wt_Interface ||
+            type == WidgetBase::wt_Enum      ||
+            type == WidgetBase::wt_Datatype  ||
+            type == WidgetBase::wt_Package   ||
+            type == WidgetBase::wt_Component ||
+            type == WidgetBase::wt_Port ||
+            type == WidgetBase::wt_Node      ||
+            type == WidgetBase::wt_Artifact  ||
+            type == WidgetBase::wt_Object) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Set m_ignoreSnapToGrid.
+ */
+void UMLWidget::setIgnoreSnapToGrid(bool to)
+{
+    m_ignoreSnapToGrid = to;
+}
+
+/**
+ * Return the value of m_ignoreSnapToGrid.
+ */
+bool UMLWidget::getIgnoreSnapToGrid() const
+{
+    return m_ignoreSnapToGrid;
+}
+
+/**
+ * Sets the size.
+ * If m_scene->snapComponentSizeToGrid() is true, then
+ * set the next larger size that snaps to the grid.
+ */
+void UMLWidget::setSize(qreal width, qreal height)
+{
+    // snap to the next larger size that is a multiple of the grid
+    if (!m_ignoreSnapComponentSizeToGrid
+            && m_scene->snapComponentSizeToGrid()) {
+        // integer divisions
+        int numX = width / m_scene->snapX();
+        int numY = height / m_scene->snapY();
+        // snap to the next larger valid value
+        if (width > numX * m_scene->snapX())
+            width = (numX + 1) * m_scene->snapX();
+        if (height > numY * m_scene->snapY())
+            height = (numY + 1) * m_scene->snapY();
+    }
+
+    setRect(rect().x(), rect().y(), width, height);
+}
+
+/**
+ * Sets the size with another size.
+ */
+void UMLWidget::setSize(const QSizeF& size)
+{
+    setSize(size.width(), size.height());
+}
+
+/**
+ * Update the size of this widget.
+ */
+void UMLWidget::updateGeometry()
+{
+    if (m_doc->loading()) {
+        return;
+    }
+    qreal oldW = width();
+    qreal oldH = height();
+    QSizeF size = calculateSize();
+    qreal clipWidth = size.width();
+    qreal clipHeight = size.height();
+    constrain(clipWidth, clipHeight);
+    setSize(clipWidth, clipHeight);
+    slotSnapToGrid();
+    adjustAssocs(size.width()-oldW, size.height()-oldH);
+}
+
+/**
+ * clip the size of this widget against the
+ * minimal and maximal limits.
+ */
+void UMLWidget::clipSize()
+{
+    qreal clipWidth = width();
+    qreal clipHeight = height();
+    constrain(clipWidth, clipHeight);
+    setSize(clipWidth, clipHeight);
+}
+
+/**
+ * Template Method, override this to set the default font metric.
+ */
+void UMLWidget::setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType)
+{
+    setupFontType(font, fontType);
+    setFontMetrics(fontType, QFontMetrics(font));
+}
+
+void UMLWidget::setupFontType(QFont &font, UMLWidget::FontType fontType)
+{
+    switch (fontType) {
+    case FT_NORMAL:
+        font.setBold(false);
+        font.setItalic(false);
+        font.setUnderline(false);
+        break;
+    case FT_BOLD:
+        font.setBold(true);
+        font.setItalic(false);
+        font.setUnderline(false);
+        break;
+    case FT_ITALIC:
+        font.setBold(false);
+        font.setItalic(true);
+        font.setUnderline(false);
+        break;
+    case FT_UNDERLINE:
+        font.setBold(false);
+        font.setItalic(false);
+        font.setUnderline(true);
+        break;
+    case FT_BOLD_ITALIC:
+        font.setBold(true);
+        font.setItalic(true);
+        font.setUnderline(false);
+        break;
+    case FT_BOLD_UNDERLINE:
+        font.setBold(true);
+        font.setItalic(false);
+        font.setUnderline(true);
+        break;
+    case FT_ITALIC_UNDERLINE:
+        font.setBold(false);
+        font.setItalic(true);
+        font.setUnderline(true);
+        break;
+    case FT_BOLD_ITALIC_UNDERLINE:
+        font.setBold(true);
+        font.setItalic(true);
+        font.setUnderline(true);
+        break;
+    default: return;
+    }
+}
+
+void UMLWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    if (option->state & QStyle::State_Selected) {
+        const qreal w = width();
+        const qreal h = height();
+        const qreal s = 4;
+        QBrush brush(Qt::blue);
+        painter->fillRect(0, 0, s,  s, brush);
+        painter->fillRect(0, 0 + h - s, s, s, brush);
+        painter->fillRect(0 + w - s, 0, s, s, brush);
+
+        // Draw the resize anchor in the lower right corner.
+        // Don't draw it if the widget is so small that the
+        // resize anchor would cover up most of the widget.
+        if (m_resizable && w >= s+8 && h >= s+8) {
+            brush.setColor(Qt::red);
+            const int right = 0 + w;
+            const int bottom = 0 + h;
+            painter->drawLine(right - s, 0 + h - 1, 0 + w - 1, 0 + h - s);
+            painter->drawLine(right - (s*2), bottom - 1, right - 1, bottom - (s*2));
+            painter->drawLine(right - (s*3), bottom - 1, right - 1, bottom - (s*3));
+        } else {
+            painter->fillRect(0 + w - s, 0 + h - s, s, s, brush);
+        }
+        // debug info
+        if (Tracer::instance()->isEnabled(QLatin1String(metaObject()->className()))) {
+            painter->setPen(Qt::green);
+            painter->setBrush(Qt::NoBrush);
+            painter->drawPath(shape());
+            painter->setPen(Qt::red);
+            painter->drawRect(boundingRect());
+            // origin
+            painter->drawLine(-10, 0, 10, 0);
+            painter->drawLine(0, -10, 0, 10);
+        }
+    }
+
+    if (umlScene()->isShowDocumentationIndicator() && hasDocumentation()) {
+        const qreal h = height();
+        const qreal d = 8;
+        QPolygonF p;
+        p << QPointF(0, h - d) << QPointF(d, h) << QPointF(0, h);
+        painter->setPen(Qt::blue);
+        painter->setBrush(Qt::red);
+        painter->drawPolygon(p);
+    }
+}
+
+/**
+ * Template Method, override this to set the default font metric.
+ */
+void UMLWidget::setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType, QPainter &painter)
+{
+    setupFontType(font, fontType);
+    painter.setFont(font);
+    setFontMetrics(fontType, painter.fontMetrics());
+}
+
+/**
+ * Returns the font metric used by this object for Text
+ * which uses bold/italic fonts.
+ */
+QFontMetrics &UMLWidget::getFontMetrics(UMLWidget::FontType fontType) const
+{
+    return *m_pFontMetrics[fontType];
+}
+
+/**
+ * Set the font metric to use.
+ */
+void UMLWidget::setFontMetrics(UMLWidget::FontType fontType, QFontMetrics fm)
+{
+    delete m_pFontMetrics[fontType];
+    m_pFontMetrics[fontType] = new QFontMetrics(fm);
+}
+
+/**
+ * Sets the font the widget is to use.
+ *
+ * @param font Font to be set.
+ */
+void UMLWidget::setFont(const QFont &font)
+{
+    QFont newFont = font;
+    forceUpdateFontMetrics(newFont, 0);
+
+    if (m_font != newFont) {
+        UMLApp::app()->executeCommand(new CmdChangeFont(this, font));
+    }
+}
+
+/**
+ * Sets the font the widget is to use.
+ *
+ * @param font Font to be set.
+ */
+void UMLWidget::setFontCmd(const QFont &font)
+{
+    WidgetBase::setFont(font);
+    forceUpdateFontMetrics(0);
+    if (m_doc->loading())
+        return;
+    update();
+}
+
+/**
+ * Updates font metrics for widgets current m_font
+ */
+void UMLWidget::forceUpdateFontMetrics(QPainter *painter)
+{
+    forceUpdateFontMetrics(m_font, painter);
+}
+
+/**
+ * @note For performance Reasons, only FontMetrics for already used
+ *  font types are updated. Not yet used font types will not get a font metric
+ *  and will get the same font metric as if painter was zero.
+ *  This behaviour is acceptable, because diagrams will always be shown on Display
+ *  first before a special painter like a printer device is used.
+ */
+void UMLWidget::forceUpdateFontMetrics(QFont& font, QPainter *painter)
+{
+    if (painter == 0) {
+        for (int i = (int)FT_INVALID - 1; i >= 0; --i) {
+            if (m_pFontMetrics[(UMLWidget::FontType)i] != 0)
+                setDefaultFontMetrics(font, (UMLWidget::FontType)i);
+        }
+    } else {
+        for (int i2 = (int)FT_INVALID - 1; i2 >= 0; --i2) {
+            if (m_pFontMetrics[(UMLWidget::FontType)i2] != 0)
+                setDefaultFontMetrics(font, (UMLWidget::FontType)i2, *painter);
+        }
+    }
+    if (m_doc->loading())
+        return;
+    // calculate the size, based on the new font metric
+    updateGeometry();
+}
+
+/**
+ * Set the status of whether to show Stereotype.
+ *
+ * @param flag   True if stereotype shall be shown.
+ */
+void UMLWidget::setShowStereotype(bool flag)
+{
+    m_showStereotype = flag;
+    updateGeometry();
+    update();
+}
+
+/**
+ * Returns the status of whether to show Stereotype.
+ *
+ * @return  True if stereotype is shown.
+ */
+bool UMLWidget::showStereotype() const
+{
+    return m_showStereotype;
+}
+
+/**
+ * Overrides the standard operation.
+ *
+ * @param me The move event.
+ */
+void UMLWidget::moveEvent(QGraphicsSceneMouseEvent* me)
+{
+  Q_UNUSED(me)
+}
+
+void UMLWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    /*
+      Call after required actions in child class.
+      Type must be set in the child class.
+    */
+    WidgetBase::saveToXMI(qDoc, qElement);
+    qElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(id()));
+    qElement.setAttribute(QLatin1String("x"), x());
+    qElement.setAttribute(QLatin1String("y"), y());
+    qElement.setAttribute(QLatin1String("width"), width());
+    qElement.setAttribute(QLatin1String("height"), height());
+    qElement.setAttribute(QLatin1String("isinstance"), m_isInstance);
+    if (!m_instanceName.isEmpty())
+        qElement.setAttribute(QLatin1String("instancename"), m_instanceName);
+    if (m_showStereotype)
+        qElement.setAttribute(QLatin1String("showstereotype"), m_showStereotype);
+
+    // Unique identifier for widget (todo: id() should be unique, new attribute
+    // should indicate the UMLObject's ID it belongs to)
+    qElement.setAttribute(QLatin1String("localid"), Uml::ID::toString(m_nLocalID));
+}
+
+bool UMLWidget::loadFromXMI(QDomElement & qElement)
+{
+    QString id = qElement.attribute(QLatin1String("xmi.id"), QLatin1String("-1"));
+    m_nId = Uml::ID::fromString(id);
+
+    WidgetBase::loadFromXMI(qElement);
+    QString x = qElement.attribute(QLatin1String("x"), QLatin1String("0"));
+    QString y = qElement.attribute(QLatin1String("y"), QLatin1String("0"));
+    QString h = qElement.attribute(QLatin1String("height"), QLatin1String("0"));
+    QString w = qElement.attribute(QLatin1String("width"), QLatin1String("0"));
+
+    setSize(w.toFloat(), h.toFloat());
+    setX(x.toFloat());
+    setY(y.toFloat());
+    QString isinstance = qElement.attribute(QLatin1String("isinstance"), QLatin1String("0"));
+    m_isInstance = (bool)isinstance.toInt();
+    m_instanceName = qElement.attribute(QLatin1String("instancename"));
+    QString showstereo = qElement.attribute(QLatin1String("showstereotype"), QLatin1String("0"));
+    m_showStereotype = (bool)showstereo.toInt();
+
+    QString localid = qElement.attribute(QLatin1String("localid"), QLatin1String("0"));
+    if (localid != QLatin1String("0")) {
+        m_nLocalID = Uml::ID::fromString(localid);
+    }
+
+    return true;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/umlwidget.h umbrello-15.08.1/umbrello/umlwidgets/umlwidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/umlwidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/umlwidget.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,347 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef UMLWIDGET_H
+#define UMLWIDGET_H
+
+#include "associationwidgetlist.h"
+#include "basictypes.h"
+#include "optionstate.h"
+#include "umlwidgetlist.h"
+#include "widgetbase.h"
+
+#include <QCursor>
+#include <QFont>
+
+class IDChangeLog;
+class UMLDoc;
+class UMLObject;
+class UMLScene;
+
+class QPainter;
+class QFontMetrics;
+
+/**
+ * This is the base class for nearly all graphical widgets.
+ *
+ * @short The base class for graphical UML objects.
+ * @author  Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UMLWidget : public WidgetBase
+{
+    Q_OBJECT
+public:
+
+    friend class ToolBarStateArrow;  // for calling the mouse*Event handlers
+
+    static const QSizeF DefaultMinimumSize;
+    static const QSizeF DefaultMaximumSize;
+    static const qreal defaultMargin;
+
+    explicit UMLWidget(UMLScene *scene, WidgetType type = wt_UMLWidget, UMLObject *o = 0);
+    explicit UMLWidget(UMLScene *scene, WidgetType type = wt_UMLWidget, Uml::ID::Type id = Uml::ID::None);
+    virtual ~UMLWidget();
+
+    // Copy constructor - not implemented.
+    // UMLWidget(const UMLWidget& other);
+
+    UMLWidget& operator=(const UMLWidget& other);
+
+    bool operator==(const UMLWidget& other) const;
+
+    void setLocalID(Uml::ID::Type id);
+    Uml::ID::Type localID() const;
+
+    virtual UMLWidget* widgetWithID(Uml::ID::Type id);
+
+    virtual QSizeF minimumSize() const;
+    void setMinimumSize(const QSizeF &size);
+
+    virtual QSizeF maximumSize();
+    void setMaximumSize(const QSizeF &size);
+
+    virtual void setUseFillColor(bool fc);
+    void setUseFillColorCmd(bool fc);
+
+    virtual void setTextColor(const QColor &color);
+    void setTextColorCmd(const QColor &color);
+
+    virtual void setLineColor(const QColor &color);
+    void setLineColorCmd(const QColor &color);
+
+    virtual void setLineWidth(uint width);
+    void setLineWidthCmd(uint width);
+
+    virtual void setFillColor(const QColor &color);
+    void setFillColorCmd(const QColor &color);
+
+    void setSelectedFlag(bool _select);
+    virtual void setSelected(bool _select);
+
+    void setScene(UMLScene *scene);
+
+    virtual bool activate(IDChangeLog* ChangeLog = 0);
+
+    void setPenFromSettings(QPainter &p);
+    void setPenFromSettings(QPainter *p);
+
+    virtual void setFont(const QFont &font);
+    void setFontCmd(const QFont &font);
+
+    /**
+     * Returns whether we triggered the update of position movement.
+     * If so, you probably don't want to move it.
+     *
+     * @return The moving state.
+     */
+    bool getStartMove() const {
+        return m_startMove;
+    }
+
+    virtual void setX(qreal x);
+    virtual void setY(qreal y);
+
+    /**
+     * Returns the height of widget.
+     */
+    qreal height() const {
+        return rect().height();
+    }
+
+    /**
+     * Returns the width of the widget.
+     */
+    qreal width() const {
+        return rect().width();
+    }
+
+    void setSize(qreal width, qreal height);
+    void setSize(const QSizeF& size);
+
+    virtual void resizeWidget(qreal newW, qreal newH);
+
+    bool getIgnoreSnapToGrid() const;
+    void setIgnoreSnapToGrid(bool to);
+
+    void moveByLocal(qreal dx, qreal dy);
+
+    void removeAssoc(AssociationWidget* pAssoc);
+    void addAssoc(AssociationWidget* pAssoc);
+
+    /**
+     *  Returns the list of associations connected to this widget.
+     */
+    AssociationWidgetList & associationWidgetList() {
+        return m_Assocs;
+    }
+
+    /**
+     * Read property of bool m_isInstance
+     */
+    bool isInstance() const {
+        return m_isInstance;
+    }
+
+    /**
+     * Write property of bool m_isInstance
+     */
+    void setIsInstance(bool isInstance) {
+        m_isInstance = isInstance;
+    }
+
+    /**
+     * Write property of m_instanceName
+     */
+    void setInstanceName(const QString &instanceName) {
+        m_instanceName = instanceName;
+    }
+
+    /**
+     * Read property of m_instanceName
+     */
+    QString instanceName() const {
+        return m_instanceName;
+    }
+
+    bool showStereotype() const;
+    virtual void setShowStereotype(bool flag);
+
+    virtual void showPropertiesDialog();
+
+    virtual void adjustAssocs(qreal dx, qreal dy);
+    void adjustUnselectedAssocs(qreal dx, qreal dy);
+
+    bool isActivated() const;
+    void setActivated(bool active = true);
+
+    virtual void cleanup();
+
+    static bool widgetHasUMLObject(WidgetBase::WidgetType type);
+
+    void updateGeometry();
+
+    void clipSize();
+
+    void forceUpdateFontMetrics(QPainter *painter);
+    void forceUpdateFontMetrics(QFont &font, QPainter *painter);
+
+    virtual bool loadFromXMI(QDomElement &qElement);
+    virtual void saveToXMI(QDomDocument &qDoc, QDomElement &qElement);
+
+    QPointF startMovePosition() const;
+    void setStartMovePosition(const QPointF &position);
+
+    QSizeF startResizeSize() const;
+
+    virtual QSizeF calculateSize(bool withExtensions = true) const;
+    void resize();
+
+    bool fixedAspectRatio() const {
+        return m_fixedAspectRatio;
+    }
+
+    void setFixedAspectRatio(bool state) {
+        m_fixedAspectRatio = state;
+    }
+
+    typedef enum {
+        FT_NORMAL = 0,
+        FT_BOLD  = 1,
+        FT_ITALIC = 2,
+        FT_UNDERLINE = 3,
+        FT_BOLD_ITALIC = 4,
+        FT_BOLD_UNDERLINE = 5,
+        FT_ITALIC_UNDERLINE = 6,
+        FT_BOLD_ITALIC_UNDERLINE = 7,
+        FT_INVALID = 8
+    } FontType;
+
+    virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType);
+    virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType, QPainter &painter);
+
+    QFontMetrics &getFontMetrics(UMLWidget::FontType fontType) const;
+    void setFontMetrics(UMLWidget::FontType fontType, QFontMetrics fm);
+    void setupFontType(QFont &font, UMLWidget::FontType fontType);
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+public Q_SLOTS:
+    virtual void updateWidget();
+    virtual void slotMenuSelection(QAction* action);
+    virtual void slotWidgetMoved(Uml::ID::Type id);
+    virtual void slotFillColorChanged(Uml::ID::Type viewID);
+    virtual void slotLineColorChanged(Uml::ID::Type viewID);
+    virtual void slotTextColorChanged(Uml::ID::Type viewID);
+    virtual void slotLineWidthChanged(Uml::ID::Type viewID);
+
+    void slotSnapToGrid();
+
+signals:
+    /**
+     * Emit when the widget moves its' position.
+     * @param id The id of the object behind the widget.
+     */
+    void sigWidgetMoved(Uml::ID::Type id);
+
+protected:
+    virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
+    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+    virtual void moveEvent(QGraphicsSceneMouseEvent *event);
+    virtual void moveWidgetBy(qreal diffX, qreal diffY);
+    virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY);
+    virtual void constrain(qreal& width, qreal& height);
+
+    virtual bool isInResizeArea(QGraphicsSceneMouseEvent *me);
+    virtual QCursor resizeCursor() const;
+
+    void selectSingle(QGraphicsSceneMouseEvent *me);
+    void selectMultiple(QGraphicsSceneMouseEvent *me);
+    void deselect(QGraphicsSceneMouseEvent *me);
+    // void resetSelection();
+
+    void setSelectionBounds();
+
+    void resize(QGraphicsSceneMouseEvent *me);
+
+    bool wasSizeChanged();
+    bool wasPositionChanged();
+
+    ///////////////// Data Loaded/Saved /////////////////////////////////
+
+    /// A list of AssociationWidgets between the UMLWidget and other UMLWidgets in the diagram
+    AssociationWidgetList m_Assocs;
+
+    QString m_instanceName;  ///< instance name (used if on a deployment diagram)
+    bool m_isInstance;       ///< holds whether this widget is a component instance (i.e. on a deployment diagram)
+    bool m_showStereotype;   ///< should the stereotype be displayed
+
+    ///////////////// End of Data Loaded/Saved //////////////////////////
+
+    Uml::ID::Type  m_nLocalID;
+    bool           m_startMove;
+    QPointF        m_startMovePostion;
+    QSizeF         m_startResizeSize;
+    int            m_nPosX;
+    UMLDoc        *m_doc;  ///< shortcut for UMLApp::app()->getDocument()
+    bool           m_resizable;
+    QFontMetrics  *m_pFontMetrics[FT_INVALID];
+    QSizeF         m_minimumSize;
+    QSizeF         m_maximumSize;
+
+    /// true if the activate function has been called for this class instance
+    bool m_activated;
+
+    /**
+     * Change Widget Behaviour
+     */
+    bool m_ignoreSnapToGrid;
+    bool m_ignoreSnapComponentSizeToGrid;
+    bool m_fixedAspectRatio;
+
+    /// The text in the status bar when the cursor was pressed.
+    QString m_oldStatusBarMsg;
+
+    /// The X/Y offset from the position of the cursor when it was pressed to the
+    /// upper left corner of the widget.
+    QPointF m_pressOffset;
+
+    /// The X/Y position the widget had when the movement started.
+    QPointF m_oldPos;
+
+    /// The width/height the widget had when the resize started.
+    qreal m_oldW, m_oldH;
+
+    /// If shift or control button were pressed in mouse press event.
+    bool m_shiftPressed;
+
+    /**
+     * If cursor was in move/resize area when left button was pressed (and no
+     * other widgets were selected).
+     */
+    bool m_inMoveArea, m_inResizeArea;
+
+    /**
+     * If the widget was selected/moved/resized in the press and release cycle.
+     * Moved/resized is true if the widget was moved/resized even if the final
+     * position/size is the same as the starting one.
+     */
+    bool m_moved, m_resized;
+
+private:
+    void init();
+    void toForeground();
+
+};
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/usecasewidget.cpp umbrello-15.08.1/umbrello/umlwidgets/usecasewidget.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/usecasewidget.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/usecasewidget.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,96 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header file
+#include "usecasewidget.h"
+
+// app includes
+#include "usecase.h"
+#include "umlview.h"
+
+/**
+ *  Creates a UseCase widget.
+ *  @param  scene  The parent of the widget.
+ *  @param  o      The UMLUseCase to represent.
+ */
+UseCaseWidget::UseCaseWidget(UMLScene * scene, UMLUseCase *o)
+  : UMLWidget(scene, WidgetBase::wt_UseCase, o)
+{
+}
+
+/**
+ * Destructor.
+ */
+UseCaseWidget::~UseCaseWidget()
+{
+}
+
+/**
+ * Overrides the standard paint event.
+ */
+void UseCaseWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(option);
+    Q_UNUSED(widget);
+
+    setPenFromSettings(painter);
+    if (UMLWidget::useFillColor())
+        painter->setBrush(UMLWidget::fillColor());
+    QFont font = UMLWidget::font();
+    font.setUnderline(false);
+    font.setBold(false);
+    font.setItalic(m_umlObject->isAbstract());
+    painter->setFont(font);
+    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
+    const int fontHeight  = fm.lineSpacing();
+    const int w = width();
+    const int h = height();
+    //int middleX = w / 2;
+    bool drawStereotype = umlObject() && !umlObject()->stereotype().isEmpty();
+    const int textStartY = (h / 2) - (drawStereotype ? fontHeight / 4 : fontHeight / 2);
+
+    painter->drawEllipse(0, 0, w, h);
+    painter->setPen(textColor());
+    if (drawStereotype)
+        painter->drawText(UC_MARGIN, textStartY-fontHeight, w - UC_MARGIN * 2, fontHeight, Qt::AlignCenter, umlObject()->stereotype(true));
+
+    painter->drawText(UC_MARGIN, textStartY, w - UC_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
+    setPenFromSettings(painter);
+
+    UMLWidget::paint(painter, option, widget);
+}
+
+/**
+ * Saves this UseCase to file.
+ */
+void UseCaseWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
+{
+    QDomElement usecaseElement = qDoc.createElement(QLatin1String("usecasewidget"));
+    UMLWidget::saveToXMI(qDoc, usecaseElement);
+    qElement.appendChild(usecaseElement);
+}
+
+/**
+ * Overrides method from UMLWidget
+ */
+QSizeF UseCaseWidget::minimumSize() const
+{
+    const UMLWidget::FontType ft = (m_umlObject->isAbstract() ? FT_BOLD_ITALIC : FT_BOLD);
+    const QFontMetrics &fm = UMLWidget::getFontMetrics(ft);
+    const int fontHeight = fm.lineSpacing();
+    const int textWidth = fm.width(name());
+    bool drawStereotype = umlObject() && !umlObject()->stereotype().isEmpty();
+    int width = textWidth > UC_WIDTH?textWidth:UC_WIDTH;
+    int height = UC_HEIGHT + (drawStereotype ? 2 * fontHeight : fontHeight) + UC_MARGIN;
+
+    width += UC_MARGIN * 2;
+
+    return QSizeF(width, height);
+}
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/usecasewidget.h umbrello-15.08.1/umbrello/umlwidgets/usecasewidget.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/usecasewidget.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/usecasewidget.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2002-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef USECASEWIDGET_H
+#define USECASEWIDGET_H
+
+#include "umlwidget.h"
+
+class UMLUseCase;
+
+#define UC_MARGIN 5
+#define UC_WIDTH 60
+#define UC_HEIGHT 30
+
+
+/**
+ * This class is the graphical version of a UMLUseCase. The
+ * UseCaseWidget class inherits from the @ref UMLWidget class
+ * which adds most of the functionality to this class.
+
+ * A UseCaseWidget is created  by a @ref UMLView.  An UseCaseWidget belongs to only one
+ * @ref UMLView instance. When the @ref UMLView  instance that this class belongs to,
+ * it will be automatically deleted.
+ *
+ * If the @ref UMLUseCase class that this UseCaseWidget is displaying is deleted, the @ref UMLView will
+ * make sure that this instance is also deleted.
+ *
+ * The UseCaseWidget class inherits from the @ref UMLWidget class which adds most of the functionality
+ * to this class.
+ *
+ * @short  A graphical version of a UMLUseCase.
+ * @author Paul Hensgen <phensgen@techie.com>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class UseCaseWidget : public UMLWidget
+{
+public:
+    UseCaseWidget(UMLScene * scene, UMLUseCase *o);
+    virtual ~UseCaseWidget();
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+    // For loading we can use the loadFromXMI() inherited from
+    // UMLWidget.
+    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
+
+protected:
+    QSizeF minimumSize() const;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widgetbase.cpp umbrello-15.08.1/umbrello/umlwidgets/widgetbase.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widgetbase.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widgetbase.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,1119 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#include "widgetbase.h"
+
+#include "classifier.h"
+#include "debug_utils.h"
+#include "floatingtextwidget.h"
+#include "optionstate.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlobject.h"
+#include "umlscene.h"
+
+#if QT_VERSION < 0x050000
+#include <kcolordialog.h>
+#include <kfontdialog.h>
+#endif
+#include <KLocalizedString>
+
+#include <QAction>
+#if QT_VERSION >= 0x050000
+#include <QColorDialog>
+#include <QFontDialog>
+#endif
+#include <QPointer>
+
+/**
+ * Creates a WidgetBase object.
+ *
+ * @param scene   The view to be displayed on.
+ * @param type    The WidgetType to construct.  This must be set to the appropriate
+ *                value by the constructors of inheriting classes.
+ */
+WidgetBase::WidgetBase(UMLScene *scene, WidgetType type)
+  : QGraphicsObject(),
+    m_baseType(type),
+    m_scene(scene),
+    m_umlObject(0),
+    m_textColor(QColor("black")),
+    m_lineColor(QColor("black")),
+    m_fillColor(QColor("yellow")),
+    m_brush(m_fillColor),
+    m_lineWidth(0), // initialize with 0 to have valid start condition
+    m_useFillColor(true),
+    m_usesDiagramTextColor(true),
+    m_usesDiagramLineColor(true),
+    m_usesDiagramLineWidth(true)
+{
+    setSelected(false);
+    scene->addItem(this);
+
+    // TODO 310283
+    setFlags(ItemIsSelectable);
+    //setFlags(ItemIsSelectable | ItemIsMovable |ItemSendsGeometryChanges);
+    if (m_scene) {
+        m_usesDiagramLineColor = true;
+        m_usesDiagramLineWidth  = true;
+        m_usesDiagramTextColor = true;
+        const Settings::OptionState& optionState = m_scene->optionState();
+        m_textColor = optionState.uiState.textColor;
+        m_lineColor = optionState.uiState.lineColor;
+        m_lineWidth  = optionState.uiState.lineWidth;
+        m_font = optionState.uiState.font;
+    } else {
+        uError() << "WidgetBase constructor: SERIOUS PROBLEM - m_scene is NULL";
+    }
+}
+
+/**
+ * Destructor.
+ */
+WidgetBase::~WidgetBase()
+{
+}
+
+/**
+ * Read property of m_baseType.
+ */
+WidgetBase::WidgetType WidgetBase::baseType() const
+{
+    return m_baseType;
+}
+
+/**
+ * @return The type used for rtti as string.
+ */
+QLatin1String WidgetBase::baseTypeStr() const
+{
+    return QLatin1String(ENUM_NAME(WidgetBase, WidgetType, m_baseType));
+}
+
+/*
+ * Sets the state of whether the widget is selected.
+ *
+ * @param select   The state of whether the widget is selected.
+ */
+void WidgetBase::setSelected(bool select)
+{
+    QGraphicsObject::setSelected(select);
+}
+
+/**
+ * Deliver a pointer to the connected UMLView
+ * (needed esp. by event handling of AssociationLine).
+ */
+UMLScene* WidgetBase::umlScene() const
+{
+    return m_scene;
+}
+
+/**
+ * This is shortcut method for UMLApp::app()->document().
+ *
+ * @return Pointer to the UMLDoc object.
+ */
+UMLDoc* WidgetBase::umlDoc() const
+{
+    return UMLApp::app()->document();
+}
+
+/**
+ * Returns the @ref UMLObject set to represent.
+ *
+ * @return the UMLObject to represent.
+ */
+UMLObject* WidgetBase::umlObject() const
+{
+    return m_umlObject;
+}
+
+/**
+ * Sets the @ref UMLObject to represent.
+ *
+ * @param obj  The object to represent.
+ */
+void WidgetBase::setUMLObject(UMLObject *obj)
+{
+    m_umlObject = obj;
+}
+
+/**
+ * Write property of m_nId.
+ */
+void WidgetBase::setID(Uml::ID::Type id)
+{
+    if (m_umlObject) {
+        if (m_umlObject->id() != Uml::ID::None)
+            uWarning() << "changing old UMLObject " << Uml::ID::toString(m_umlObject->id())
+                << " to " << Uml::ID::toString(id);
+        m_umlObject->setID(id);
+    }
+    m_nId = id;
+}
+
+/**
+ * Read property of m_nId.
+ */
+Uml::ID::Type WidgetBase::id() const
+{
+    if (m_umlObject)
+        return m_umlObject->id();
+    return m_nId;
+}
+
+/**
+ * Used by some child classes to get documentation.
+ *
+ * @return  The documentation from the UMLObject (if m_umlObject is set.)
+ */
+QString WidgetBase::documentation() const
+{
+    if (m_umlObject)
+        return m_umlObject->doc();
+    return m_Doc;
+}
+
+/**
+ * Returns state of documentation for the widget.
+ *
+ * @return false if documentation is empty
+ */
+bool WidgetBase::hasDocumentation()
+{
+    if (m_umlObject)
+        return m_umlObject->hasDoc();
+    return !m_Doc.isEmpty();
+}
+
+/**
+ * Used by some child classes to set documentation.
+ *
+ * @param doc   The documentation to be set in the UMLObject
+ *              (if m_umlObject is set.)
+ */
+void WidgetBase::setDocumentation(const QString& doc)
+{
+    if (m_umlObject)
+        m_umlObject->setDoc(doc);
+    else
+        m_Doc = doc;
+}
+
+/**
+ * Gets the name from the corresponding UMLObject if this widget has an
+ * underlying UMLObject; if it does not, then it returns the local
+ * m_Text (notably the case for FloatingTextWidget.)
+ *
+ * @return the currently set name
+ */
+QString WidgetBase::name() const
+{
+    if (m_umlObject)
+        return m_umlObject->name();
+    return m_Text;
+}
+
+/**
+ * Sets the name in the corresponding UMLObject.
+ * Sets the local m_Text if m_umlObject is NULL.
+ *
+ * @param strName The name to be set.
+ */
+void WidgetBase::setName(const QString &strName)
+{
+    if (m_umlObject)
+        m_umlObject->setName(strName);
+    else
+        m_Text = strName;
+}
+
+/**
+ * Returns text color
+ *
+ * @return currently used text color
+ */
+QColor WidgetBase::textColor() const
+{
+    return m_textColor;
+}
+
+/**
+ * Sets the text color
+ *
+ * @param color the new text color
+ */
+void WidgetBase::setTextColor(const QColor &color)
+{
+    m_textColor = color;
+    m_usesDiagramTextColor = false;
+}
+
+/**
+ * Returns line color
+ *
+ * @return currently used line color
+ */
+QColor WidgetBase::lineColor() const
+{
+    return m_lineColor;
+}
+
+/**
+ * Sets the line color
+ *
+ * @param color   The new line color
+ */
+void WidgetBase::setLineColor(const QColor &color)
+{
+    m_lineColor = color;
+    m_usesDiagramLineColor = false;
+}
+
+/**
+ * Returns fill color
+ *
+ * @return currently used fill color
+ */
+QColor WidgetBase::fillColor() const
+{
+    return m_fillColor;
+}
+
+/**
+ * Sets the fill color
+ *
+ * @param color   The new fill color
+ */
+void WidgetBase::setFillColor(const QColor &color)
+{
+    m_fillColor = color;
+    m_usesDiagramFillColor = false;
+}
+
+/**
+ * Returns line width
+ *
+ * @return currently used line with
+ */
+uint WidgetBase::lineWidth() const
+{
+    return m_lineWidth;
+}
+
+/**
+ * Sets the line width
+ *
+ * @param width  The new line width
+ */
+void WidgetBase::setLineWidth(uint width)
+{
+    m_lineWidth = width;
+    m_usesDiagramLineWidth = false;
+}
+
+/**
+ * Return state of fill color usage
+ *
+ * @return True if fill color is used
+ */
+bool WidgetBase::useFillColor()
+{
+    return m_useFillColor;
+}
+
+/**
+ * Set state if fill color is used
+ *
+ * @param state  The state to set
+ */
+void WidgetBase::setUseFillColor(bool state)
+{
+    m_useFillColor = state;
+    m_usesDiagramUseFillColor = false;
+}
+
+/**
+ * Returns state if diagram text color is used
+ *
+ * @return True means diagram text color is used
+ */
+bool WidgetBase::usesDiagramTextColor() const
+{
+    return m_usesDiagramTextColor;
+}
+
+/**
+ * Set state if diagram text color is used
+ *
+ * @param state  The state to set
+ */
+void WidgetBase::setUsesDiagramTextColor(bool state)
+{
+    if (m_usesDiagramTextColor == state) {
+        return;
+    }
+    m_usesDiagramTextColor = state;
+    setTextColor(m_textColor);
+}
+
+/**
+ * Returns state of diagram line color is used
+ *
+ * @return True means diagrams line color is used
+*/
+bool WidgetBase::usesDiagramLineColor() const
+{
+    return m_usesDiagramLineColor;
+}
+
+/**
+ * Set state of diagram line color is used
+ *
+ * @param state  The state to set
+ */
+void WidgetBase::setUsesDiagramLineColor(bool state)
+{
+    m_usesDiagramLineColor = state;
+}
+
+/**
+ * Returns state of diagram fill color is used
+ *
+ * @return True means diagrams fill color is used
+*/
+bool WidgetBase::usesDiagramFillColor() const
+{
+    return m_usesDiagramFillColor;
+}
+
+/**
+ * Set state if diagram fill color is used
+ *
+ * @param state  The state to set
+ */
+void WidgetBase::setUsesDiagramFillColor(bool state)
+{
+    m_usesDiagramFillColor = state;
+}
+
+/**
+ * Returns state of diagram use fill color is used
+ *
+ * @return True means diagrams fill color is used
+*/
+bool WidgetBase::usesDiagramUseFillColor() const
+{
+    return m_usesDiagramUseFillColor;
+}
+
+/**
+ * Set state of diagram use fill color is used
+ *
+ * @param state  The state to set
+ */
+void WidgetBase::setUsesDiagramUseFillColor(bool state)
+{
+    m_usesDiagramUseFillColor = state;
+}
+
+/**
+ * Returns state of diagram line width is used
+ *
+ * @return True means diagrams line width is used
+ */
+bool WidgetBase::usesDiagramLineWidth() const
+{
+    return m_usesDiagramLineWidth;
+}
+
+/**
+ * Set state of diagram line width is used
+ *
+ * @param state  The state to set
+ */
+void WidgetBase::setUsesDiagramLineWidth(bool state)
+{
+    m_usesDiagramLineWidth = state;
+}
+
+/**
+ * Returns the font used for diaplaying any text.
+ * @return the font
+ */
+QFont WidgetBase::font() const
+{
+    return m_font;
+}
+
+/**
+ * Set the font used to display text inside this widget.
+ */
+void WidgetBase::setFont(const QFont& font)
+{
+    m_font = font;
+}
+
+/**
+ * A virtual method for the widget to display a property dialog box.
+ * Subclasses should reimplment this appropriately.
+ */
+void WidgetBase::showPropertiesDialog()
+{
+}
+
+/**
+ * A virtual method to save the properties of this widget into a
+ * QDomElement i.e xml.
+ *
+ * Subclasses should first create a new dedicated element as the child
+ * of \a qElement parameter passed.  Then this base method should be
+ * called to save basic widget properties.
+ *
+ * @param qDoc A QDomDocument object representing the xml document.
+ * @param qElement A QDomElement representing xml element data.
+ */
+void WidgetBase::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+ {
+    Q_UNUSED(qDoc)
+
+    qElement.setAttribute(QLatin1String("textcolor"), m_usesDiagramTextColor ? QLatin1String("none")
+                                                                             : m_textColor.name());
+    if (m_usesDiagramLineColor) {
+        qElement.setAttribute(QLatin1String("linecolor"), QLatin1String("none"));
+    } else {
+        qElement.setAttribute(QLatin1String("linecolor"), m_lineColor.name());
+    }
+    if (m_usesDiagramLineWidth) {
+        qElement.setAttribute(QLatin1String("linewidth"), QLatin1String("none"));
+    } else {
+        qElement.setAttribute(QLatin1String("linewidth"), m_lineWidth);
+    }
+    qElement.setAttribute(QLatin1String("usefillcolor"), m_useFillColor);
+    // for consistency the following attributes now use american spelling for "color"
+    qElement.setAttribute(QLatin1String("usesdiagramfillcolor"), m_usesDiagramFillColor);
+    qElement.setAttribute(QLatin1String("usesdiagramusefillcolor"), m_usesDiagramUseFillColor);
+    if (m_usesDiagramFillColor) {
+        qElement.setAttribute(QLatin1String("fillcolor"), QLatin1String("none"));
+    } else {
+        qElement.setAttribute(QLatin1String("fillcolor"), m_fillColor.name());
+    }
+    qElement.setAttribute(QLatin1String("font"), m_font.toString());
+}
+
+/**
+ * A virtual method to load the properties of this widget from a
+ * QDomElement into this widget.
+ *
+ * Subclasses should reimplement this to load addtional properties
+ * required, calling this base method to load the basic properties of
+ * the widget.
+ *
+ * @param qElement A QDomElement which contains xml info for this widget.
+ *
+ * @todo Add support to load older version.
+ */
+bool WidgetBase::loadFromXMI(QDomElement& qElement)
+{
+    // first load from "linecolour" and then overwrite with the "linecolor"
+    // attribute if that one is present. The "linecolour" name was a "typo" in
+    // earlier versions of Umbrello
+    QString lineColor = qElement.attribute(QLatin1String("linecolour"), QLatin1String("none"));
+    lineColor = qElement.attribute(QLatin1String("linecolor"), lineColor);
+    if (lineColor != QLatin1String("none")) {
+        m_lineColor = QColor(lineColor);
+        m_usesDiagramLineColor = false;
+    } else if (m_baseType != WidgetBase::wt_Box && m_scene != NULL) {
+        m_lineColor = m_scene->lineColor();
+        m_usesDiagramLineColor = true;
+    }
+    QString lineWidth = qElement.attribute(QLatin1String("linewidth"), QLatin1String("none"));
+    if (lineWidth != QLatin1String("none")) {
+        m_lineWidth = lineWidth.toInt();
+        m_usesDiagramLineWidth = false;
+    } else if (m_scene) {
+        m_lineWidth = m_scene->lineWidth();
+        m_usesDiagramLineWidth = true;
+    }
+    QString textColor = qElement.attribute(QLatin1String("textcolor"), QLatin1String("none"));
+    if (textColor != QLatin1String("none")) {
+        m_textColor = QColor(textColor);
+        m_usesDiagramTextColor = false;
+    } else if (m_scene) {
+        m_textColor = m_scene->textColor();
+        m_usesDiagramTextColor = true;
+    }
+    QString usefillcolor = qElement.attribute(QLatin1String("usefillcolor"), QLatin1String("1"));
+    m_useFillColor = (bool)usefillcolor.toInt();
+    /*
+      For the next three *color attributes, there was a mixup of american and english spelling for "color".
+      So first we need to keep backward compatibility and try to retrieve the *colour attribute.
+      Next we overwrite this value if we find a *color, otherwise the former *colour is kept.
+    */
+    QString fillColor = qElement.attribute(QLatin1String("fillcolour"), QLatin1String("none"));
+    fillColor = qElement.attribute(QLatin1String("fillcolor"), fillColor);
+    if (fillColor != QLatin1String("none")) {
+        m_fillColor = QColor(fillColor);
+    }
+
+    QString usesDiagramFillColor = qElement.attribute(QLatin1String("usesdiagramfillcolour"), QLatin1String("1"));
+    usesDiagramFillColor = qElement.attribute(QLatin1String("usesdiagramfillcolor"), usesDiagramFillColor);
+    m_usesDiagramFillColor = (bool)usesDiagramFillColor.toInt();
+
+    QString usesDiagramUseFillColor = qElement.attribute(QLatin1String("usesdiagramusefillcolour"), QLatin1String("1"));
+    usesDiagramUseFillColor = qElement.attribute(QLatin1String("usesdiagramusefillcolor"), usesDiagramUseFillColor);
+    m_usesDiagramUseFillColor = (bool)usesDiagramUseFillColor.toInt();
+
+    QString font = qElement.attribute(QLatin1String("font"));
+    if (!font.isEmpty()) {
+        QFont newFont;
+        newFont.fromString(font);
+        m_font = newFont;
+    } else {
+        uWarning() << "Using default font " << m_font.toString()
+                   << " for widget with xmi.id " << Uml::ID::toString(m_nId);
+    }
+
+    return true;
+}
+
+/**
+ * Assignment operator
+ */
+WidgetBase& WidgetBase::operator=(const WidgetBase& other)
+{
+    m_baseType = other.m_baseType;
+    m_scene = other.m_scene;
+    m_umlObject = other.m_umlObject;
+    m_Doc = other.m_Doc;
+    m_Text = other.m_Text;
+    m_nId = other.m_nId;
+    m_textColor = other.m_textColor;
+    m_lineColor = other.m_lineColor;
+    m_fillColor = other.m_fillColor;
+    m_brush = other.m_brush;
+    m_font = other.m_font;
+    m_lineWidth  = other.m_lineWidth;
+    m_useFillColor = other.m_useFillColor;
+    m_usesDiagramTextColor = other.m_usesDiagramTextColor;
+    m_usesDiagramLineColor = other.m_usesDiagramLineColor;
+    m_usesDiagramFillColor = other.m_usesDiagramFillColor;
+    m_usesDiagramLineWidth  = other.m_usesDiagramLineWidth;
+    setSelected(other.isSelected());
+
+    return *this;
+}
+
+/**
+ * return drawing rectangle of widget in local coordinates
+ */
+QRectF WidgetBase::rect() const
+{
+    return m_rect;
+}
+
+/**
+ * set widget rectangle in item coordinates
+ */
+void WidgetBase::setRect(const QRectF& rect)
+{
+    if (m_rect == rect)
+        return;
+    prepareGeometryChange();
+    m_rect = rect;
+    update();
+}
+
+/**
+ * set widget rectangle in item coordinates
+ */
+void WidgetBase::setRect(qreal x, qreal y, qreal width, qreal height)
+{
+    setRect(QRectF(x, y, width, height));
+}
+
+/**
+ * @return The bounding rectangle for this widget.
+ * @see setRect
+ */
+QRectF WidgetBase::boundingRect() const
+{
+    int halfWidth = lineWidth()/2;
+    return m_rect.adjusted(-halfWidth, -halfWidth, halfWidth, halfWidth);
+}
+
+/**
+ * Test if point is inside the bounding rectangle of the widget.
+ * Inheriting classes may reimplement this to test possible child widgets.
+ *
+ * @param p Point to be checked.
+ *
+ * @return 'this' if the given point is in the boundaries of the widget;
+ *         else NULL.
+ */
+UMLWidget* WidgetBase::onWidget(const QPointF &p)
+{
+    UMLWidget *uw = dynamic_cast<UMLWidget*>(this);
+    if (uw == NULL)
+        return NULL;
+    const qreal w = m_rect.width();
+    const qreal h = m_rect.height();
+    const qreal left = x();  // don't use m_rect.x() for this, it is always 0
+    const qreal right = left + w;
+    const qreal top = y();   // don't use m_rect.y() for this, it is always 0
+    const qreal bottom = top + h;
+    // uDebug() << "p=(" << p.x() << "," << p.y()
+    //          << "), x=" << left << ", y=" << top << ", w=" << w << ", h=" << h
+    //          << "; right=" << right << ", bottom=" << bottom;
+    if (p.x() < left || p.x() > right ||
+            p.y() < top || p.y() > bottom) { // Qt coord.sys. origin in top left corner
+        // uDebug() << "returning NULL";
+        return NULL;
+    }
+    // uDebug() << "returning this";
+    return uw;
+}
+
+/**
+ * Draws the UMLWidget on the given paint device
+ *
+ * @param painter The painter for the drawing device
+ * @param option  Painting related options
+ * @param widget  Background widget on which to paint (optional)
+ *
+ */
+void WidgetBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+    Q_UNUSED(painter); Q_UNUSED(option); Q_UNUSED(widget);
+}
+
+/**
+ * Reimplemented to show appropriate context menu.
+ */
+void WidgetBase::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+    event->accept();
+    uDebug() << "widget = " << name() << " / type = " << baseTypeStr();
+
+    UMLScene *scene = umlScene();
+
+    // If right-click was done on a widget that was not selected, clear the
+    // current selection and select the new widget. The context menu is shown
+    // with actions for that single widget.
+    // If a keyboard modifier was used, add the widget to the current selection
+    // and show the menu with actions for the whole selection.
+    if (!isSelected()) {
+        Qt::KeyboardModifiers forSelection = (Qt::ControlModifier | Qt::ShiftModifier);
+        if ((event->modifiers() & forSelection) == 0) {
+            scene->clearSelected();
+        }
+
+        if (umlObject() != 0) {
+            scene->selectWidget(dynamic_cast<UMLWidget*>(this));
+        } else {
+            setSelected(true);
+        }
+    }
+
+    int count = scene->selectedCount(true);
+
+    // Determine multi state
+    bool multi = (isSelected() && count > 1);
+
+    ListPopupMenu popup(0, this, multi, scene->getUniqueSelectionType());
+
+    // Disable the "view code" menu for simple code generators
+    if (UMLApp::app()->isSimpleCodeGeneratorActive()) {
+        popup.setActionEnabled(ListPopupMenu::mt_ViewCode, false);
+    }
+
+    QAction *triggered = popup.exec(event->screenPos());
+    ListPopupMenu *parentMenu = ListPopupMenu::menuFromAction(triggered);
+
+    if (!parentMenu) {
+        uDebug() << "Action's data field does not contain ListPopupMenu pointer";
+        return;
+    }
+
+    WidgetBase *ownerWidget = parentMenu->ownerWidget();
+    // assert because logic is based on only WidgetBase being the owner of
+    // ListPopupMenu actions executed in this context menu.
+    Q_ASSERT_X(ownerWidget != 0, "WidgetBase::contextMenuEvent",
+            "ownerWidget is null which means action belonging to UMLView, UMLScene"
+            " or UMLObject is the one triggered in ListPopupMenu");
+
+    ownerWidget->slotMenuSelection(triggered);
+}
+
+/**
+ * This is usually called synchronously after menu.exec() and \a
+ * trigger's parent is always the ListPopupMenu which can be used to
+ * get the type of action of \a trigger.
+ *
+ * @note Subclasses can reimplement to handle specific actions and
+ *       leave the rest to WidgetBase::slotMenuSelection.
+ */
+void WidgetBase::slotMenuSelection(QAction *trigger)
+{
+    if (!trigger) {
+        return;
+    }
+    QColor newColor;
+
+    const WidgetType wt = m_baseType; // short hand name
+
+    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(trigger);
+    switch (sel) {
+    case ListPopupMenu::mt_Rename:
+        umlDoc()->renameUMLObject(umlObject());
+        break;
+
+    case ListPopupMenu::mt_Properties:
+        if (wt == WidgetBase::wt_Actor     || wt == WidgetBase::wt_UseCase   ||
+            wt == WidgetBase::wt_Package   || wt == WidgetBase::wt_Interface ||
+            wt == WidgetBase::wt_Datatype  || wt == WidgetBase::wt_Node      ||
+            wt == WidgetBase::wt_Component || wt == WidgetBase::wt_Artifact  ||
+            wt == WidgetBase::wt_Enum      || wt == WidgetBase::wt_Entity    ||
+            wt == WidgetBase::wt_Port      ||
+            (wt == WidgetBase::wt_Class && umlScene()->type() == Uml::DiagramType::Class)) {
+
+            showPropertiesDialog();
+
+        } else if (wt == WidgetBase::wt_Object) {
+            m_umlObject->showPropertiesDialog();
+        } else {
+            uWarning() << "making properties dialog for unknown widget type";
+        }
+        break;
+
+    case ListPopupMenu::mt_Line_Color:
+    case ListPopupMenu::mt_Line_Color_Selection:
+#if QT_VERSION >= 0x050000
+        newColor = QColorDialog::getColor(lineColor());
+        if (newColor != lineColor()) {
+#else
+        newColor = lineColor();
+        if (KColorDialog::getColor(newColor)) {
+#endif
+            if (sel == ListPopupMenu::mt_Line_Color_Selection) {
+                umlScene()->selectionSetLineColor(newColor);
+            } else {
+                setLineColor(newColor);
+            }
+            setUsesDiagramLineColor(false);
+            umlDoc()->setModified(true);
+        }
+        break;
+
+    case ListPopupMenu::mt_Fill_Color:
+    case ListPopupMenu::mt_Fill_Color_Selection:
+#if QT_VERSION >= 0x050000
+        newColor = QColorDialog::getColor(fillColor());
+        if (newColor != fillColor()) {
+#else
+        newColor = fillColor();
+        if (KColorDialog::getColor(newColor)) {
+#endif
+            if (sel == ListPopupMenu::mt_Fill_Color_Selection) {
+                umlScene()->selectionSetFillColor(newColor);
+            } else {
+                setFillColor(newColor);
+            }
+            umlDoc()->setModified(true);
+        }
+        break;
+
+    case ListPopupMenu::mt_Use_Fill_Color:
+        setUseFillColor(!m_useFillColor);
+        break;
+
+    case ListPopupMenu::mt_Set_Use_Fill_Color_Selection:
+        umlScene()->selectionUseFillColor(true);
+        break;
+
+    case ListPopupMenu::mt_Unset_Use_Fill_Color_Selection:
+        umlScene()->selectionUseFillColor(false);
+        break;
+
+    case ListPopupMenu::mt_Show_Attributes_Selection:
+    case ListPopupMenu::mt_Hide_Attributes_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowAttributes, sel != ListPopupMenu::mt_Hide_Attributes_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Show_Operations_Selection:
+    case ListPopupMenu::mt_Hide_Operations_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowOperations, sel != ListPopupMenu::mt_Hide_Operations_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Show_Visibility_Selection:
+    case ListPopupMenu::mt_Hide_Visibility_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowVisibility, sel != ListPopupMenu::mt_Hide_Visibility_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Show_Operation_Signature_Selection:
+    case ListPopupMenu::mt_Hide_Operation_Signature_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowOperationSignature, sel != ListPopupMenu::mt_Hide_Operation_Signature_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Show_Attribute_Signature_Selection:
+    case ListPopupMenu::mt_Hide_Attribute_Signature_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowAttributeSignature, sel != ListPopupMenu::mt_Hide_Attribute_Signature_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Show_Packages_Selection:
+    case ListPopupMenu::mt_Hide_Packages_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowPackage, sel != ListPopupMenu::mt_Hide_Packages_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Show_Stereotypes_Selection:
+    case ListPopupMenu::mt_Hide_Stereotypes_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowStereotype, sel != ListPopupMenu::mt_Hide_Stereotypes_Selection
+        );
+        break;
+
+    case ListPopupMenu::mt_Hide_NonPublic_Selection:
+    case ListPopupMenu::mt_Show_NonPublic_Selection:
+        umlScene()->selectionSetVisualProperty(
+            ClassifierWidget::ShowPublicOnly, sel != ListPopupMenu::mt_Show_NonPublic_Selection
+        );
+        break;
+
+
+    case ListPopupMenu::mt_ViewCode: {
+        UMLClassifier *c = dynamic_cast<UMLClassifier*>(umlObject());
+        if (c) {
+            UMLApp::app()->viewCodeDocument(c);
+        }
+        break;
+    }
+
+    case ListPopupMenu::mt_Delete:
+        umlScene()->deleteSelection();
+        break;
+
+    case ListPopupMenu::mt_Change_Font:
+    case ListPopupMenu::mt_Change_Font_Selection: {
+#if QT_VERSION >= 0x050000
+        bool ok = false;
+        QFont newFont = QFontDialog::getFont(&ok, font());
+        if (ok) {
+#else
+        QFont newFont = font();
+        if (KFontDialog::getFont(newFont, KFontChooser::NoDisplayFlags, 0) == KFontDialog::Accepted) {
+#endif
+            if (sel == ListPopupMenu::mt_Change_Font_Selection) {
+                m_scene->selectionSetFont(newFont);
+            } else {
+                setFont(newFont);
+            }
+        }
+    }
+        break;
+
+    case ListPopupMenu::mt_Cut:
+        umlScene()->setStartedCut();
+        UMLApp::app()->slotEditCut();
+        break;
+
+    case ListPopupMenu::mt_Copy:
+        UMLApp::app()->slotEditCopy();
+        break;
+
+    case ListPopupMenu::mt_Paste:
+        UMLApp::app()->slotEditPaste();
+        break;
+
+    case ListPopupMenu::mt_Refactoring:
+        //check if we are operating on a classifier, or some other kind of UMLObject
+        if (dynamic_cast<UMLClassifier*>(umlObject())) {
+            UMLApp::app()->refactor(static_cast<UMLClassifier*>(umlObject()));
+        }
+        break;
+
+     case ListPopupMenu::mt_Clone:
+        {
+            foreach (UMLWidget* widget, umlScene()->selectedWidgets()) {
+                if (Model_Utils::isCloneable(widget->baseType())) {
+                    UMLObject *clone = widget->umlObject()->clone();
+                    umlScene()->addObject(clone);
+                }
+            }
+        }
+        break;
+
+    case ListPopupMenu::mt_Rename_MultiA:
+    case ListPopupMenu::mt_Rename_MultiB:
+    case ListPopupMenu::mt_Rename_Name:
+    case ListPopupMenu::mt_Rename_RoleAName:
+    case ListPopupMenu::mt_Rename_RoleBName: {
+        FloatingTextWidget *ft = static_cast<FloatingTextWidget*>(this);
+        ft->handleRename();
+        break;
+    }
+    case ListPopupMenu::mt_Align_Right:
+        umlScene()->alignRight();
+        break;
+    case ListPopupMenu::mt_Align_Left:
+        umlScene()->alignLeft();
+        break;
+    case ListPopupMenu::mt_Align_Top:
+        umlScene()->alignTop();
+        break;
+    case ListPopupMenu::mt_Align_Bottom:
+        umlScene()->alignBottom();
+        break;
+    case ListPopupMenu::mt_Align_VerticalMiddle:
+        umlScene()->alignVerticalMiddle();
+        break;
+    case ListPopupMenu::mt_Align_HorizontalMiddle:
+        umlScene()->alignHorizontalMiddle();
+        break;
+    case ListPopupMenu::mt_Align_VerticalDistribute:
+        umlScene()->alignVerticalDistribute();
+        break;
+    case ListPopupMenu::mt_Align_HorizontalDistribute:
+        umlScene()->alignHorizontalDistribute();
+        break;
+    default:
+        uDebug() << "MenuType " << ListPopupMenu::toString(sel) << " not implemented";
+        break;
+    }
+}
+
+/**
+ * Helper function for debug output.
+ * Returns the given enum value as string.
+ * @param wt   WidgetType of which a string representation is wanted
+ * @return   the WidgetType as string
+ */
+QString WidgetBase::toString(WidgetType wt)
+{
+    return QLatin1String(ENUM_NAME(WidgetBase, WidgetType, wt));
+}
+
+/**
+ * Returns the given enum value as localized string.
+ * @param wt   WidgetType of which a string representation is wanted
+ * @return   the WidgetType as localized string
+ */
+QString WidgetBase::toI18nString(WidgetType wt)
+{
+    QString name;
+
+    switch (wt) {
+    case wt_Activity:
+        name = i18n("Activity");
+        break;
+    case wt_Actor:
+        name = i18n("Actor");
+        break;
+    case wt_Artifact:
+        name = i18n("Artifact");
+        break;
+    case wt_Association:
+        name = i18n("Association");
+        break;
+    case wt_Box:
+        name = i18n("Box");
+        break;
+    case wt_Category:
+        name = i18n("Category");
+        break;
+    case wt_CombinedFragment:
+        name = i18n("CombinedFragment");
+        break;
+    case wt_Component:
+        name = i18n("Component");
+        break;
+    case wt_Class:
+        name = i18n("Class");
+        break;
+    case wt_Datatype:
+        name = i18n("Datatype");
+        break;
+    case wt_Entity:
+        name = i18n("Entity");
+        break;
+    case wt_Enum:
+        name = i18n("Enum");
+        break;
+    case wt_FloatingDashLine:
+        name = i18n("FloatingDashLine");
+        break;
+    case wt_ForkJoin:
+        name = i18n("ForkJoin");
+        break;
+    case wt_Interface:
+        name = i18n("Interface");
+        break;
+    case wt_Message:
+        name = i18n("Message");
+        break;
+    case wt_Node:
+        name = i18n("Node");
+        break;
+    case wt_Note:
+        name = i18n("Note");
+        break;
+    case wt_Object:
+        name = i18n("Object");
+        break;
+    case wt_ObjectNode:
+        name = i18n("ObjectNode");
+        break;
+    case wt_Package:
+        name = i18n("Package");
+        break;
+    case wt_Pin:
+        name = i18n("Pin");
+        break;
+    case wt_Port:
+        name = i18n("Port");
+        break;
+    case wt_Precondition:
+        name = i18n("Precondition");
+        break;
+    case wt_Region:
+        name = i18n("Region");
+        break;
+    case wt_Signal:
+        name = i18n("Signal");
+        break;
+    case wt_State:
+        name = i18n("State");
+        break;
+    case wt_Text:
+        name = i18n("Text");
+        break;
+    case wt_UseCase:
+        name = i18n("UseCase");
+        break;
+    default:
+        name = QLatin1String("<unknown> &name:");
+        uWarning() << "unknown widget type";
+        break;
+    }
+    return name;
+}
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widgetbase.h umbrello-15.08.1/umbrello/umlwidgets/widgetbase.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widgetbase.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widgetbase.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,192 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef WIDGETBASE_H
+#define WIDGETBASE_H
+
+#include "basictypes.h"
+
+#include <QColor>
+#include <QDomDocument>
+#include <QFont>
+#include <QGraphicsObject>
+#include <QObject>
+#include <QPainter>
+
+// forward declarations
+class QAction;
+class UMLDoc;
+class UMLObject;
+class UMLScene;
+class UMLWidget;   // required by function onWidget()
+
+/**
+ * @short       Common base class for UMLWidget and AssociationWidget
+ * @author      Oliver Kellogg <okellogg@users.sourceforge.net>
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+class WidgetBase : public QGraphicsObject
+{
+    Q_OBJECT
+    Q_ENUMS(WidgetType)
+
+public:
+    enum WidgetType
+    {
+        wt_UMLWidget = 300,         // does not have UMLObject representation
+        wt_Actor,                   // has UMLObject representation
+        wt_UseCase,                 // has UMLObject representation
+        wt_Class,                   // has UMLObject representation
+        wt_Interface,               // has UMLObject representation
+        wt_Datatype,                // has UMLObject representation
+        wt_Enum,                    // has UMLObject representation
+        wt_Entity,                  // has UMLObject representation
+        wt_Package,                 // has UMLObject representation
+        wt_Object,                  // has UMLObject representation
+        wt_Note,                    // does not have UMLObject representation
+        wt_Box,                     // does not have UMLObject representation
+        wt_Message,                 // does not have UMLObject representation
+        wt_Text,                    // does not have UMLObject representation
+        wt_State,                   // does not have UMLObject representation
+        wt_Activity,                // does not have UMLObject representation
+        wt_Component,               // has UMLObject representation
+        wt_Artifact,                // has UMLObject representation
+        wt_Node,                    // has UMLObject representation
+        wt_Association,             // has UMLObject representation
+        wt_ForkJoin,                // does not have UMLObject representation
+        wt_Precondition,            // does not have UMLObject representation
+        wt_CombinedFragment,        // does not have UMLObject representation
+        wt_FloatingDashLine,        // does not have UMLObject representation
+        wt_Signal,                  // does not have UMLObject representation
+        wt_Pin,
+        wt_ObjectNode,
+        wt_Region,
+        wt_Category,                // has UMLObject representation
+        wt_Port                     // has UMLObject representation
+    };
+
+    static QString toString(WidgetType wt);
+    static QString toI18nString(WidgetType wt);
+
+    explicit WidgetBase(UMLScene * scene, WidgetType type= wt_UMLWidget);
+    virtual ~WidgetBase();
+
+    UMLObject* umlObject() const;
+    virtual void setUMLObject(UMLObject *obj);
+
+    Uml::ID::Type id() const;
+    void setID(Uml::ID::Type id);
+
+    WidgetType baseType() const;
+    QLatin1String baseTypeStr() const;
+
+    virtual void setSelected(bool select);
+
+    UMLScene* umlScene() const;
+    UMLDoc* umlDoc() const;
+
+    QString documentation() const;
+    bool hasDocumentation();
+    virtual void setDocumentation(const QString& doc);
+
+    QString name() const;
+    virtual void setName(const QString &strName);
+
+    QColor lineColor() const;
+    virtual void setLineColor(const QColor& color);
+
+    uint lineWidth() const;
+    virtual void setLineWidth(uint width);
+
+    QColor textColor() const;
+    virtual void setTextColor(const QColor& color);
+
+    QColor fillColor() const;
+    virtual void setFillColor(const QColor& color);
+
+    bool usesDiagramLineColor() const;
+    void setUsesDiagramLineColor(bool state);
+
+    bool usesDiagramLineWidth() const;
+    void setUsesDiagramLineWidth(bool state);
+
+    bool useFillColor();
+    virtual void setUseFillColor(bool state);
+
+    bool usesDiagramTextColor() const;
+    void setUsesDiagramTextColor(bool state);
+
+    bool usesDiagramFillColor() const;
+    void setUsesDiagramFillColor(bool state);
+
+    bool usesDiagramUseFillColor() const;
+    void setUsesDiagramUseFillColor(bool state);
+
+    virtual QFont font() const;
+    virtual void setFont(const QFont& font);
+
+    virtual void showPropertiesDialog();
+
+    virtual bool loadFromXMI(QDomElement &qElement);
+    virtual void saveToXMI(QDomDocument &qDoc, QDomElement &qElement);
+
+    WidgetBase& operator=(const WidgetBase& other);
+
+    QRectF rect() const;
+    void setRect(const QRectF& rect);
+    void setRect(qreal x, qreal y, qreal width, qreal height);
+
+    virtual QRectF boundingRect() const;
+
+    virtual UMLWidget* onWidget(const QPointF &p);
+
+    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+public Q_SLOTS:
+    virtual void slotMenuSelection(QAction *trigger);
+
+protected:
+    virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+
+    WidgetType  m_baseType;  ///< Type of widget.
+    UMLScene   *m_scene;
+    UMLObject  *m_umlObject;
+    QString     m_Doc;   ///< Only used if m_umlObject is not set.
+    QString     m_Text;
+    QRectF      m_rect;  ///< widget size
+
+    /**
+     * This ID is only used when the widget does not have a
+     * corresponding UMLObject (i.e. the m_umlObject pointer is NULL.)
+     * For UMLObjects, the ID from the UMLObject is used.
+     */
+    Uml::ID::Type m_nId;
+
+    QColor m_textColor;  ///< Color of the text of the widget. Is saved to XMI.
+    QColor m_lineColor;  ///< Color of the lines of the widget. Is saved to XMI.
+    QColor m_fillColor;  ///< color of the background of the widget
+    QBrush m_brush;
+    QFont  m_font;
+    uint   m_lineWidth;  ///< Width of the lines of the widget. Is saved to XMI.
+    bool   m_useFillColor;  ///< flag indicates if the UMLWidget uses the Diagram FillColour
+
+    /**
+     * true by default, false if the colors have
+     * been explicitly set for this widget.
+     * These are saved to XMI.
+     */
+    bool m_usesDiagramTextColor;
+    bool m_usesDiagramLineColor;
+    bool m_usesDiagramFillColor;
+    bool m_usesDiagramUseFillColor;
+    bool m_usesDiagramLineWidth;
+};
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widget_factory.cpp umbrello-15.08.1/umbrello/umlwidgets/widget_factory.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widget_factory.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widget_factory.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,298 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2006-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "widget_factory.h"
+
+// app includes
+#include "activitywidget.h"
+#include "actor.h"
+#include "actorwidget.h"
+#include "artifact.h"
+#include "artifactwidget.h"
+#include "associationwidget.h"
+#include "boxwidget.h"
+#include "category.h"
+#include "categorywidget.h"
+#include "classifier.h"
+#include "classifierwidget.h"
+#include "cmds.h"
+#include "combinedfragmentwidget.h"
+#include "component.h"
+#include "componentwidget.h"
+#include "datatypewidget.h"
+#include "debug_utils.h"
+#include "entity.h"
+#include "entitywidget.h"
+#include "enum.h"
+#include "enumwidget.h"
+#include "floatingdashlinewidget.h"
+#include "floatingtextwidget.h"
+#include "folder.h"
+#include "forkjoinwidget.h"
+#include "messagewidget.h"
+#include "node.h"
+#include "nodewidget.h"
+#include "notewidget.h"
+#include "object_factory.h"
+#include "objectnodewidget.h"
+#include "objectwidget.h"
+#include "package.h"
+#include "packagewidget.h"
+#include "pinwidget.h"
+#include "port.h"
+#include "portwidget.h"
+#include "preconditionwidget.h"
+#include "regionwidget.h"
+#include "signalwidget.h"
+#include "statewidget.h"
+#include "uml.h"
+#include "umldoc.h"
+#include "umlscene.h"
+#include "umlview.h"
+#include "usecase.h"
+#include "usecasewidget.h"
+
+namespace Widget_Factory {
+
+/**
+ * Create a UMLWidget in the given view and representing the given document object.
+ */
+UMLWidget *createWidget(UMLScene *scene, UMLObject *o)
+{
+    QPointF pos = scene->pos();
+    int y = pos.y();
+    Uml::DiagramType::Enum diagramType = scene->type();
+    UMLObject::ObjectType type = o->baseType();
+    UMLWidget *newWidget = NULL;
+    switch (type) {
+    case UMLObject::ot_Actor:
+        if (diagramType == Uml::DiagramType::Sequence) {
+            ObjectWidget *ow = new ObjectWidget(scene, o);
+            ow->setDrawAsActor(true);
+            y = ow->topMargin();
+            newWidget = ow;
+        } else
+            newWidget = new ActorWidget(scene, static_cast<UMLActor*>(o));
+        break;
+    case UMLObject::ot_UseCase:
+        newWidget = new UseCaseWidget(scene, static_cast<UMLUseCase*>(o));
+        break;
+    case UMLObject::ot_Folder:
+        newWidget = new PackageWidget(scene, static_cast<UMLPackage*>(o));
+        break;
+    case UMLObject::ot_Package:
+        newWidget = new ClassifierWidget(scene, static_cast<UMLPackage*>(o));
+        break;
+    case UMLObject::ot_Component:
+        newWidget = new ComponentWidget(scene, static_cast<UMLComponent*>(o));
+        if (diagramType == Uml::DiagramType::Deployment) {
+            newWidget->setIsInstance(true);
+        }
+        break;
+    case UMLObject::ot_Port:
+        {
+            PinPortBase *pw = new PortWidget(scene, static_cast<UMLPort*>(o));
+            pw->attachToOwner();
+            newWidget = pw;
+        }
+        break;
+    case UMLObject::ot_Node:
+        newWidget = new NodeWidget(scene, static_cast<UMLNode*>(o));
+        break;
+    case UMLObject::ot_Artifact:
+        newWidget = new ArtifactWidget(scene, static_cast<UMLArtifact*>(o));
+        break;
+    case UMLObject::ot_Datatype:
+        newWidget = new DatatypeWidget(scene, static_cast<UMLClassifier*>(o));
+        break;
+    case UMLObject::ot_Enum:
+        newWidget = new EnumWidget(scene, static_cast<UMLEnum*>(o));
+        break;
+    case UMLObject::ot_Entity:
+        newWidget = new EntityWidget(scene, static_cast<UMLEntity*>(o));
+        break;
+    case UMLObject::ot_Interface:
+        if (diagramType == Uml::DiagramType::Sequence || diagramType == Uml::DiagramType::Collaboration) {
+            ObjectWidget *ow = new ObjectWidget(scene, o);
+            if (diagramType == Uml::DiagramType::Sequence) {
+                y = ow->topMargin();
+            }
+            newWidget = ow;
+        } else {
+            UMLClassifier *c = static_cast<UMLClassifier*>(o);
+            ClassifierWidget* interfaceWidget = new ClassifierWidget(scene, c);
+            if (diagramType == Uml::DiagramType::Component || diagramType == Uml::DiagramType::Deployment) {
+                interfaceWidget->setDrawAsCircle(true);
+            }
+            newWidget = interfaceWidget;
+        }
+        break;
+    case UMLObject::ot_Class:
+        //see if we really want an object widget or class widget
+        if (diagramType == Uml::DiagramType::Class || diagramType == Uml::DiagramType::Component) {
+            UMLClassifier *c = static_cast<UMLClassifier*>(o);
+            ClassifierWidget *cw = new ClassifierWidget(scene, c);
+            if (diagramType == Uml::DiagramType::Component)
+                cw->setDrawAsCircle(true);
+            newWidget = cw;
+        } else {
+            ObjectWidget *ow = new ObjectWidget(scene, o);
+            if (diagramType == Uml::DiagramType::Sequence) {
+                y = ow->topMargin();
+            }
+            newWidget = ow;
+        }
+        break;
+    case UMLObject::ot_Category:
+        newWidget = new CategoryWidget(scene, static_cast<UMLCategory*>(o));
+        break;
+    default:
+        uWarning() << "trying to create an invalid widget (" << UMLObject::toString(type) << ")";
+    }
+
+    if (newWidget) {
+        newWidget->setX(pos.x());
+        newWidget->setY(y);
+    }
+
+    return newWidget;
+}
+
+bool validateObjType(UMLObject::ObjectType expected, UMLObject* &o, Uml::ID::Type id)
+{
+    if (o == NULL) {
+        uDebug() << "Widget_Factory::validateObjType: creating new object of type "
+                 << expected;
+        QString artificialName = QLatin1String("LOST_") + Uml::ID::toString(id);
+        o = Object_Factory::createUMLObject(expected, artificialName, NULL, false);
+        if (o == NULL)
+            return false;
+        o->setID(id);
+        UMLPackage *parentPkg = o->umlPackage();
+        parentPkg->addObject(o);
+        return true;
+    }
+    UMLObject::ObjectType actual = o->baseType();
+    if (actual == expected)
+        return true;
+    uError() << "validateObjType(" << o->name()
+        << "): expected type " << UMLObject::toString(expected) << ", actual type "
+        << UMLObject::toString(actual);
+    return false;
+}
+
+/**
+ * Create a UMLWidget according to the given XMI tag.
+ */
+UMLWidget* makeWidgetFromXMI(const QString& tag,
+                             const QString& idStr, UMLScene *scene)
+{
+    UMLWidget *widget = NULL;
+
+        // Loading of widgets which do NOT represent any UMLObject,
+        // just graphic stuff with no real model information
+        //FIXME while boxes and texts are just diagram objects, activities and
+        // states should be UMLObjects
+    if (tag == QLatin1String("statewidget") || tag == QLatin1String("UML:StateWidget")) {
+        widget = new StateWidget(scene, StateWidget::Normal, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("notewidget") || tag == QLatin1String("UML:NoteWidget")) {
+        widget = new NoteWidget(scene, NoteWidget::Normal, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("boxwidget")) {
+        widget = new BoxWidget(scene, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("floatingtext") || tag == QLatin1String("UML:FloatingTextWidget")) {
+        widget = new FloatingTextWidget(scene, Uml::TextRole::Floating, QString(), Uml::ID::Reserved);
+    } else if (tag == QLatin1String("activitywidget") || tag == QLatin1String("UML:ActivityWidget")) {
+        widget = new ActivityWidget(scene, ActivityWidget::Initial, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("messagewidget")) {
+        widget = new MessageWidget(scene, Uml::SequenceMessage::Asynchronous, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("forkjoin")) {
+        widget = new ForkJoinWidget(scene, Qt::Vertical, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("preconditionwidget")) {
+        widget = new PreconditionWidget(scene, NULL, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("combinedFragmentwidget")) {
+        widget = new CombinedFragmentWidget(scene, CombinedFragmentWidget::Ref, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("signalwidget")) {
+        widget = new SignalWidget(scene, SignalWidget::Send,  Uml::ID::Reserved);
+    } else if (tag == QLatin1String("floatingdashlinewidget")) {
+        widget = new FloatingDashLineWidget(scene, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("objectnodewidget")) {
+        widget = new ObjectNodeWidget(scene, ObjectNodeWidget::Normal, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("regionwidget")) {
+        widget = new RegionWidget(scene, Uml::ID::Reserved);
+    } else if (tag == QLatin1String("pinwidget")) {
+        PinPortBase *pw = new PinWidget(scene, NULL, Uml::ID::Reserved);
+        pw->attachToOwner();
+        widget = pw;
+    }
+    else
+    {
+        // Loading of widgets which represent an UMLObject
+
+        // Find the UMLObject and create the Widget to represent it
+        Uml::ID::Type id = Uml::ID::fromString(idStr);
+        UMLDoc *umldoc = UMLApp::app()->document();
+        UMLObject *o = umldoc->findObjectById(id);
+        if (o == NULL) {
+            uDebug() << "makeWidgetFromXMI: cannot find object with id "
+                << Uml::ID::toString(id);
+        }
+
+        if (tag == QLatin1String("actorwidget") || tag == QLatin1String("UML:ActorWidget")) {
+            if (validateObjType(UMLObject::ot_Actor, o, id))
+                widget = new ActorWidget(scene, static_cast<UMLActor*>(o));
+        } else if (tag == QLatin1String("usecasewidget") || tag ==  QLatin1String("UML:UseCaseWidget")) {
+            if (validateObjType(UMLObject::ot_UseCase, o, id))
+                widget = new UseCaseWidget(scene, static_cast<UMLUseCase*>(o));
+        } else if (tag == QLatin1String("classwidget") ||
+                   tag == QLatin1String("UML:ClassWidget") || tag == QLatin1String("UML:ConceptWidget")) {
+            if (validateObjType(UMLObject::ot_Class, o, id) || validateObjType(UMLObject::ot_Package, o, id))
+                widget = new ClassifierWidget(scene, static_cast<UMLClassifier*>(o));
+        } else if (tag == QLatin1String("packagewidget")) {
+            if (validateObjType(UMLObject::ot_Package, o, id))
+                widget = new ClassifierWidget(scene, static_cast<UMLPackage*>(o));
+        } else if (tag == QLatin1String("componentwidget")) {
+            if (validateObjType(UMLObject::ot_Component, o, id))
+                widget = new ComponentWidget(scene, static_cast<UMLComponent*>(o));
+        } else if (tag == QLatin1String("portwidget")) {
+            if (validateObjType(UMLObject::ot_Port, o, id))
+                widget = new PortWidget(scene, static_cast<UMLPort*>(o));
+        } else if (tag == QLatin1String("nodewidget")) {
+            if (validateObjType(UMLObject::ot_Node, o, id))
+                widget = new NodeWidget(scene, static_cast<UMLNode*>(o));
+        } else if (tag == QLatin1String("artifactwidget")) {
+            if (validateObjType(UMLObject::ot_Artifact, o, id))
+                widget = new ArtifactWidget(scene, static_cast<UMLArtifact*>(o));
+        } else if (tag == QLatin1String("interfacewidget")) {
+            if (validateObjType(UMLObject::ot_Interface, o, id))
+                widget = new ClassifierWidget(scene, static_cast<UMLClassifier*>(o));
+        } else if (tag == QLatin1String("datatypewidget")) {
+            if (validateObjType(UMLObject::ot_Datatype, o, id))
+                widget = new DatatypeWidget(scene, static_cast<UMLClassifier*>(o));
+        } else if (tag == QLatin1String("enumwidget")) {
+            if (validateObjType(UMLObject::ot_Enum, o, id))
+                widget = new EnumWidget(scene, static_cast<UMLEnum*>(o));
+        } else if (tag == QLatin1String("entitywidget")) {
+            if (validateObjType(UMLObject::ot_Entity, o, id))
+                widget = new EntityWidget(scene, static_cast<UMLEntity*>(o));
+        } else if (tag == QLatin1String("categorywidget")) {
+            if (validateObjType(UMLObject::ot_Category, o, id))
+                widget = new CategoryWidget(scene, static_cast<UMLCategory*>(o));
+        } else if (tag == QLatin1String("objectwidget") || tag == QLatin1String("UML:ObjectWidget")) {
+            widget = new ObjectWidget(scene, o);
+        } else {
+            uWarning() << "Trying to create an unknown widget:" << tag;
+        }
+    }
+    return widget;
+}
+
+}   // end namespace Widget_Factory
+
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widget_factory.h umbrello-15.08.1/umbrello/umlwidgets/widget_factory.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widget_factory.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widget_factory.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,34 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2006-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef WIDGET_FACTORY_H
+#define WIDGET_FACTORY_H
+
+#include <QString>
+
+// forward declarations
+class UMLObject;
+class UMLScene;
+class UMLWidget;
+
+/**
+ * Widget factory methods.
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+namespace Widget_Factory {
+
+    UMLWidget *createWidget(UMLScene *scene, UMLObject *docObj);
+
+    UMLWidget* makeWidgetFromXMI(const QString& tag,
+                                 const QString& idStr, UMLScene *scene);
+
+}   // end namespace Widget_Factory
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widgetlist_utils.cpp umbrello-15.08.1/umbrello/umlwidgets/widgetlist_utils.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widgetlist_utils.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widgetlist_utils.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,157 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2009-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "widgetlist_utils.h"
+
+// app includes
+#include "debug_utils.h"
+#include "umlwidget.h"
+
+// qt/kde includes
+#include <QVector>
+
+namespace WidgetList_Utils
+{
+
+/**
+ * Looks for the smallest x-value of the given UMLWidgets.
+ * @param widgetList A list with UMLWidgets.
+ * @return The smallest X position.
+ */
+qreal getSmallestX(const UMLWidgetList &widgetList)
+{
+    qreal smallestX = 0;
+
+    int i = 1;
+    foreach(UMLWidget *widget,  widgetList) {
+        if (i == 1) {
+            smallestX = widget->x();
+        } else {
+            if (smallestX > widget->x())
+                smallestX = widget->x();
+        }
+        i++;
+    }
+
+    return smallestX;
+}
+
+/**
+ * Looks for the smallest y-value of the given UMLWidgets.
+ * @param widgetList A list with UMLWidgets.
+ * @return The smallest Y position.
+ */
+qreal getSmallestY(const UMLWidgetList &widgetList)
+{
+    if (widgetList.isEmpty())
+        return -1;
+
+    qreal smallestY = 0;
+
+    int i = 1;
+    foreach(UMLWidget *widget,  widgetList) {
+        if (i == 1) {
+            smallestY = widget->y();
+        } else {
+            if (smallestY > widget->y())
+                smallestY = widget->y();
+        }
+        i++;
+    }
+
+    return smallestY;
+}
+
+/**
+ * Looks for the biggest x-value of the given UMLWidgets.
+ * @param widgetList A list with UMLWidgets.
+ * @return The biggest X position.
+ */
+qreal getBiggestX(const UMLWidgetList &widgetList)
+{
+    if (widgetList.isEmpty())
+        return -1;
+
+    qreal biggestX = 0;
+
+    int i = 1;
+    foreach(UMLWidget *widget, widgetList) {
+        if (i == 1) {
+            biggestX = widget->x();
+            biggestX += widget->width();
+        } else {
+            if (biggestX < widget->x() + widget->width())
+                biggestX = widget->x() + widget->width();
+        }
+        i++;
+    }
+
+    return biggestX;
+}
+
+/**
+ * Looks for the biggest y-value of the given UMLWidgets.
+ * @param widgetList A list with UMLWidgets.
+ * @return The biggest Y position.
+ */
+qreal getBiggestY(const UMLWidgetList &widgetList)
+{
+    if (widgetList.isEmpty())
+        return -1;
+
+    qreal biggestY = 0;
+
+    int i = 1;
+    foreach(UMLWidget *widget, widgetList) {
+        if (i == 1) {
+            biggestY = widget->y();
+            biggestY += widget->height();
+        } else {
+            if (biggestY < widget->y() + widget->height())
+                biggestY = widget->y() + widget->height();
+        }
+        i++;
+    }
+
+    return biggestY;
+}
+
+/**
+ * Returns the sum of the heights of the given UMLWidgets
+ * @param widgetList A list with UMLWidgets.
+ */
+qreal getHeightsSum(const UMLWidgetList &widgetList)
+{
+    qreal heightsSum = 0;
+
+    foreach(UMLWidget *widget, widgetList) {
+        heightsSum += widget->height();
+    }
+
+    return heightsSum;
+}
+
+/**
+ * Returns the sum of the widths of the given UMLWidgets.
+ * @param widgetList A list with UMLWidgets.
+ */
+qreal getWidthsSum(const UMLWidgetList &widgetList)
+{
+    qreal widthsSum = 0;
+
+    foreach(UMLWidget *widget, widgetList) {
+        widthsSum += widget->width();
+    }
+
+    return widthsSum;
+}
+
+}  // namespace WidgetList_Utils
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widgetlist_utils.h umbrello-15.08.1/umbrello/umlwidgets/widgetlist_utils.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widgetlist_utils.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widgetlist_utils.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,30 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2009-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef WIDGETLIST_UTILS_H
+#define WIDGETLIST_UTILS_H
+
+#include "umlwidgetlist.h"
+
+/**
+ * General purpose widget list utilities.
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+namespace WidgetList_Utils
+{
+    qreal getSmallestX(const UMLWidgetList &widgetList);
+    qreal getSmallestY(const UMLWidgetList &widgetList);
+    qreal getBiggestX(const UMLWidgetList &widgetList);
+    qreal getBiggestY(const UMLWidgetList &widgetList);
+    qreal getHeightsSum(const UMLWidgetList &widgetList);
+    qreal getWidthsSum(const UMLWidgetList &widgetList);
+}  // namespace WidgetList_Utils
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widget_utils.cpp umbrello-15.08.1/umbrello/umlwidgets/widget_utils.cpp
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widget_utils.cpp	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widget_utils.cpp	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,827 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+// own header
+#include "widget_utils.h"
+
+// app includes
+#include "debug_utils.h"
+#include "objectwidget.h"
+#include "messagewidget.h"
+#include "umlwidget.h"
+
+// qt includes
+#include <QBuffer>
+#include <QImageReader>
+#include <QGraphicsItem>
+#include <QGraphicsRectItem>
+#include <QPolygonF>
+
+// c++ include
+#include <cmath>
+
+namespace Widget_Utils
+{
+
+    /**
+     * Find the widget identified by the given ID in the given widget
+     * or message list.
+     *
+     * @param id         The unique ID to find.
+     * @param widgets    The UMLWidgetList to search in.
+     * @param messages   Optional pointer to a MessageWidgetList to search in.
+     */
+    UMLWidget* findWidget(Uml::ID::Type id,
+                          const UMLWidgetList& widgets,
+                          const MessageWidgetList* messages /* = 0 */)
+    {
+        foreach (UMLWidget* obj, widgets) {
+            if (obj->baseType() == WidgetBase::wt_Object) {
+                if (static_cast<ObjectWidget *>(obj)->localID() == id)
+                    return obj;
+            } else if (obj->id() == id) {
+                return obj;
+            }
+        }
+
+        if (messages) {
+            foreach (UMLWidget* obj, *messages) {
+                if (obj->id() == id)
+                    return obj;
+            }
+        }
+        return NULL;
+    }
+
+    /**
+     * Creates the decoration point.
+     * @param p        base point to decorate
+     * @param parent   parent item
+     * @return         decoration point
+     */
+    QGraphicsRectItem* decoratePoint(const QPointF &p, QGraphicsItem* parent)
+    {
+        const qreal SIZE = 4.0;
+        const qreal SIZE_HALF = SIZE / 2.0;
+        QGraphicsRectItem *rect = new QGraphicsRectItem(p.x() - SIZE_HALF,
+                                                        p.y() - SIZE_HALF,
+                                                        SIZE, SIZE,
+                                                        parent);
+        rect->setBrush(QBrush(Qt::blue));
+        rect->setPen(QPen(Qt::blue));
+        return rect;
+    }
+
+    /**
+     * Calculates and draws a cross inside an ellipse
+     * @param p  Pointer to a QPainter object.
+     * @param r  The rectangle describing the ellipse.
+     */
+    void drawCrossInEllipse(QPainter *p, const QRectF& r)
+    {
+        QRectF ellipse = r;
+        ellipse.moveCenter(QPointF(0, 0));
+        qreal a = ellipse.width() * 0.5;
+        qreal b = ellipse.height() * .5;
+        qreal xc = ellipse.center().x();
+        qreal yc = ellipse.center().y();
+
+        // The first point's x value is chosen to be center.x() + 70% of x radius.
+        qreal x1 = ellipse.center().x() + .7 * .5 * ellipse.width();
+        // Calculate y1 corresponding to x1 using formula.
+        qreal y1_sqr = b*b*(1 - (x1 * x1) / (a*a));
+        qreal y1 = std::sqrt(y1_sqr);
+
+        // Mirror x1, y1 along both the axes to get 4 points for the cross.
+        QPointF p1(xc + x1, yc + y1);
+        QPointF p2(xc - x1, yc + y1);
+        QPointF p3(xc + x1, yc - y1);
+        QPointF p4(xc - x1, yc - y1);
+
+        // Translate as we calculate for ellipse with (0, 0) as center.
+        p->translate(r.center().x(), r.center().y());
+
+        // Draw the cross now
+        p->drawLine(QLineF(p1, p4));
+        p->drawLine(QLineF(p2, p3));
+
+        // Restore the translate on painter.
+        p->translate(-r.center().x(), -r.center().y());
+    }
+
+    /**
+     * Draws a polygon which is almost rectangular except for the top
+     * right corner. A triangle is drawn in top right corner of the
+     * rectangle.
+     *
+     * @param painter The painter with which this shape is to be drawn.
+     * @param rect    The rectangle dimensions.
+     * @param triSize The size of the triangle in the top-right corner.
+     */
+    void drawTriangledRect(QPainter *painter,
+                           const QRectF &rect, const QSizeF &triSize)
+    {
+        // Draw outer boundary defined by polygon "poly".
+        QPolygonF poly(5);
+        poly[0] = rect.topLeft();
+        poly[1] = rect.topRight() - QPointF(triSize.width(), 0);
+        poly[2] = rect.topRight() + QPointF(0, triSize.height());
+        poly[3] = rect.bottomRight();
+        poly[4] = rect.bottomLeft();
+        painter->drawPolygon(poly);
+
+        // Now draw the triangle base and height edges.
+        QLineF heightEdge(poly[1], poly[1] + QPointF(0, triSize.height()));
+        painter->drawLine(heightEdge);
+        QLineF baseEdge(heightEdge.p2(), poly[2]);
+        painter->drawLine(baseEdge);
+    }
+
+//    /**
+//     * Draws an arrow head with the given painter, with the arrow
+//     * sharp point at \a headPos.
+//     *
+//     *  param painter    The painter with which this arrow should be drawn.
+//     *  param headPos    The position where the head of the arrow should lie.
+//     *  param arrowSize  This indicates the size of the arrow head.
+//     *  param arrowType  This indicates direction of arrow as in LeftArrow, RightArrow..
+//     *  param solid      If true, a solid head is drawn. Otherwise 2 lines are drawn.
+//     */
+//    void drawArrowHead(QPainter *painter, const QPointF &arrowPos,
+//                       const QSizeF& arrowSize, Qt::ArrowType arrowType,
+//                       bool  solid)
+//    {
+//        QPolygonF poly;
+//        if (arrowType == Qt::LeftArrow) {
+//            poly << QPointF(arrowPos.x() + arrowSize.width(), arrowPos.y() - .5 * arrowSize.height())
+//                 << arrowPos
+//                 << QPointF(arrowPos.x() + arrowSize.width(), arrowPos.y() + .5 * arrowSize.height());
+//        }
+//        else if (arrowType == Qt::RightArrow) {
+//            poly << QPointF(arrowPos.x() - arrowSize.width(), arrowPos.y() - .5 * arrowSize.height())
+//                 << arrowPos
+//                 << QPointF(arrowPos.x() - arrowSize.width(), arrowPos.y() + .5 * arrowSize.height());
+//        }
+
+//        if (solid) {
+//            painter->drawPolygon(poly);
+//        }
+//        else {
+//            painter->drawPolyline(poly);
+//        }
+//    }
+
+//    /**
+//     * Draws a rounded rect rounded at specified corners.
+//     *
+//     *  param painter The painter with which this round rect should be drawn.
+//     *  param rect    The rectangle to be drawn.
+//     *  param xRadius The x radius of rounded corner.
+//     *  param yRadius The y radius of rounded corner.
+//     *  param corners The corners to be rounded.
+//     */
+//    void drawRoundedRect(QPainter *painter, const QRectF& rect, qreal xRadius,
+//            qreal yRadius, Uml::Corners corners)
+//    {
+//        if (xRadius < 0 || yRadius < 0) {
+//            painter->drawRect(rect);
+//            return;
+//        }
+//        QRectF arcRect(0, 0, 2 * xRadius, 2 * yRadius);
+
+//        QPainterPath path;
+//        path.moveTo(rect.left(), rect.top() + yRadius);
+//        if (corners.testFlag(Uml::Corner::TopLeft)) {
+//            arcRect.moveTopLeft(rect.topLeft());
+//            path.arcTo(arcRect, 180, -90);
+//        } else {
+//            path.lineTo(rect.topLeft());
+//        }
+
+//        path.lineTo(rect.right() - xRadius, rect.top());
+
+//        if (corners.testFlag(Uml::Corner::TopRight)) {
+//            arcRect.moveTopRight(rect.topRight());
+//            path.arcTo(arcRect, 90, -90);
+//        } else {
+//            path.lineTo(rect.topRight());
+//        }
+
+//        path.lineTo(rect.right(), rect.bottom() - yRadius);
+
+//        if (corners.testFlag(Uml::Corner::BottomRight)) {
+//            arcRect.moveBottomRight(rect.bottomRight());
+//            path.arcTo(arcRect, 0, -90);
+//        } else {
+//            path.lineTo(rect.bottomRight());
+//        }
+
+//        path.lineTo(rect.left() + xRadius, rect.bottom());
+
+//        if (corners.testFlag(Uml::Corner::BottomLeft)) {
+//            arcRect.moveBottomLeft(rect.bottomLeft());
+//            path.arcTo(arcRect, 270, 90);
+//        } else {
+//            path.lineTo(rect.bottomLeft());
+//        }
+
+//        path.closeSubpath();
+//        painter->drawPath(path);
+//    }
+
+    /**
+     * Converts a point to a comma separated string i.e "x,y"
+     * @param point  The QPointF to convert.
+     */
+    QString pointToString(const QPointF& point)
+    {
+        return QString::fromLatin1("%1,%2").arg(point.x()).arg(point.y());
+    }
+
+    /**
+     * Converts a comma separated string to point.
+     */
+    QPointF stringToPoint(const QString& str)
+    {
+        QPointF retVal;
+        QStringList list = str.split(QLatin1Char(','));
+
+        if(list.size() == 2) {
+            retVal.setX(list.first().toDouble());
+            retVal.setY(list.last().toDouble());
+        }
+        return retVal;
+    }
+
+    /**
+     * Loads pixmap from xmi.
+     *
+     * @param pixEle  The dom element from which pixmap should be loaded.
+     *
+     * @param pixmap  The pixmap into which the image should be loaded.
+     *
+     * @return  True or false based on success or failure of this method.
+     */
+    bool loadPixmapFromXMI(QDomElement &pixEle, QPixmap &pixmap)
+    {
+        if (pixEle.isNull()) {
+            return false;
+        }
+        QDomElement xpmElement = pixEle.firstChildElement(QLatin1String("xpm"));
+
+        QByteArray xpmData = xpmElement.text().toLatin1();
+        QBuffer buffer(&xpmData);
+        buffer.open(QIODevice::ReadOnly);
+
+        QImageReader reader(&buffer, "xpm");
+        QImage image;
+        if (!reader.read(&image)) {
+            return false;
+        }
+
+        pixmap = QPixmap::fromImage(image);
+        return true;
+    }
+
+    /**
+     * Saves pixmap information into DOM element \a qElement.
+     *
+     * @param qDoc The DOM document object.
+     *
+     * @param qElement The DOM element into which the pixmap should be
+     *                 saved.
+     *
+     * @param pixmap The pixmap to be saved.
+     */
+    void savePixmapToXMI(QDomDocument &qDoc, QDomElement &qElement, const QPixmap& pixmap)
+    {
+        QDomElement pixmapElement = qDoc.createElement(QLatin1String("pixmap"));
+
+        QDomElement xpmElement = qDoc.createElement(QLatin1String("xpm"));
+        pixmapElement.appendChild(xpmElement);
+
+        QBuffer buffer;
+        buffer.open(QIODevice::WriteOnly);
+        pixmap.save(&buffer, "xpm");
+        buffer.close();
+
+        xpmElement.appendChild(qDoc.createTextNode(QString::fromLatin1(buffer.data())));
+
+        qElement.appendChild(pixmapElement);
+    }
+
+    /**
+     * Loads gradient from xmi. The gradient pointer should be null
+     * and the new gradient object will be created inside this method.
+     * The gradient should later be deleted externally.
+     *
+     * @param gradientElement The DOM element from which gradient should be
+     *                        loaded.
+     *
+     * @param gradient The pointer to gradient into which the gradient
+     *                 should be loaded. (Allocated inside this
+     *                 method)
+     *
+     * @return True or false based on success or failure of this method.
+     */
+    bool loadGradientFromXMI(QDomElement &gradientElement, QGradient *&gradient)
+    {
+        if(gradientElement.isNull()) {
+            return false;
+        }
+
+        int type_as_int;
+        QGradient::Type type;
+        QGradientStops stops;
+        QGradient::CoordinateMode cmode = QGradient::LogicalMode;
+        QGradient::Spread spread = QGradient::PadSpread;
+
+        type_as_int = gradientElement.attribute(QLatin1String("type")).toInt();
+        type = QGradient::Type(type_as_int);
+        type_as_int = gradientElement.attribute(QLatin1String("spread")).toInt();
+        spread = QGradient::Spread(type_as_int);
+        type_as_int = gradientElement.attribute(QLatin1String("coordinatemode")).toInt();
+        cmode = QGradient::CoordinateMode(type_as_int);
+
+        QDomElement stopElement = gradientElement.firstChildElement(QLatin1String("stops"));
+        if(stopElement.isNull()) {
+            return false;
+        }
+        for(QDomNode node = stopElement.firstChild(); !node.isNull(); node = node.nextSibling()) {
+            QDomElement ele = node.toElement();
+            if(ele.tagName() != QLatin1String("stop")) {
+                continue;
+            }
+
+            qreal posn = ele.attribute(QLatin1String("position")).toDouble();
+            QColor color = QColor(ele.attribute(QLatin1String("color")));
+            stops << QGradientStop(posn, color);
+        }
+
+        if (type == QGradient::LinearGradient) {
+            QPointF p1 = stringToPoint(gradientElement.attribute(QLatin1String("start")));
+            QPointF p2 = stringToPoint(gradientElement.attribute(QLatin1String("finalstop")));
+            gradient = new QLinearGradient(p1, p2);
+        }
+        else if (type == QGradient::RadialGradient) {
+            QPointF center = stringToPoint(gradientElement.attribute(QLatin1String("center")));
+            QPointF focal = stringToPoint(gradientElement.attribute(QLatin1String("focalpoint")));
+            double radius = gradientElement.attribute(QLatin1String("radius")).toDouble();
+            gradient = new QRadialGradient(center, radius, focal);
+        }
+        else { // type == QGradient::ConicalGradient
+            QPointF center = stringToPoint(gradientElement.attribute(QLatin1String("center")));
+            double angle = gradientElement.attribute(QLatin1String("angle")).toDouble();
+            gradient = new QConicalGradient(center, angle);
+        }
+
+        if(gradient) {
+            gradient->setStops(stops);
+            gradient->setSpread(spread);
+            gradient->setCoordinateMode(cmode);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Saves gradient information into DOM element \a qElement.
+     *
+     * @param qDoc The DOM document object.
+     *
+     * @param qElement The DOM element into which the gradient should be
+     *                 saved.
+     *
+     * @param gradient The gradient to be saved.
+     */
+    void saveGradientToXMI(QDomDocument &qDoc, QDomElement &qElement, const QGradient *gradient)
+    {
+        QDomElement gradientElement = qDoc.createElement(QLatin1String("gradient"));
+
+        gradientElement.setAttribute(QLatin1String("type"), int(gradient->type()));
+        gradientElement.setAttribute(QLatin1String("spread"), int(gradient->spread()));
+        gradientElement.setAttribute(QLatin1String("coordinatemode"), int(gradient->coordinateMode()));
+
+        QDomElement stopsElement = qDoc.createElement(QLatin1String("stops"));
+        gradientElement.appendChild(stopsElement);
+
+        foreach(const QGradientStop& stop, gradient->stops()) {
+            QDomElement ele = qDoc.createElement(QLatin1String("stop"));
+            ele.setAttribute(QLatin1String("position"), stop.first);
+            ele.setAttribute(QLatin1String("color"), stop.second.name());
+            stopsElement.appendChild(ele);
+        }
+
+        QGradient::Type type = gradient->type();
+
+        if(type == QGradient::LinearGradient) {
+            const QLinearGradient *lg = static_cast<const QLinearGradient*>(gradient);
+            gradientElement.setAttribute(QLatin1String("start"), pointToString(lg->start()));
+            gradientElement.setAttribute(QLatin1String("finalstop"), pointToString(lg->finalStop()));
+        }
+        else if(type == QGradient::RadialGradient) {
+            const QRadialGradient *rg = static_cast<const QRadialGradient*>(gradient);
+            gradientElement.setAttribute(QLatin1String("center"), pointToString(rg->center()));
+            gradientElement.setAttribute(QLatin1String("focalpoint"), pointToString(rg->focalPoint()));
+            gradientElement.setAttribute(QLatin1String("radius"), rg->radius());
+        }
+        else { //type == QGradient::ConicalGradient
+            const QConicalGradient *cg = static_cast<const QConicalGradient*>(gradient);
+            gradientElement.setAttribute(QLatin1String("center"), pointToString(cg->center()));
+            gradientElement.setAttribute(QLatin1String("angle"), cg->angle());
+        }
+
+        qElement.appendChild(gradientElement);
+    }
+
+    /**
+     * Extracts the QBrush properties into brush from the XMI xml
+     * element qElement.
+     *
+     * @param qElement The DOM element from which the xmi info should
+     *                 be extracted.
+     *
+     * @param brush The QBrush object into which brush details should
+     *              be read into.
+     */
+    bool loadBrushFromXMI(QDomElement &qElement, QBrush &brush)
+    {
+        if(qElement.isNull()) {
+            return false;
+        }
+
+        quint8 style = qElement.attribute(QLatin1String("style")).toShort();
+        const QString colorString = qElement.attribute(QLatin1String("color"));
+        QColor color;
+        color.setNamedColor(colorString);
+
+        if(style == Qt::TexturePattern) {
+            QPixmap pixmap;
+            QDomElement pixElement = qElement.firstChildElement(QLatin1String("pixmap"));
+            if(!loadPixmapFromXMI(pixElement, pixmap)) {
+                return false;
+            }
+            brush = QBrush(color, pixmap);
+        }
+
+        else if(style == Qt::LinearGradientPattern
+                || style == Qt::RadialGradientPattern
+                || style == Qt::ConicalGradientPattern) {
+            QGradient *gradient = 0;
+            QDomElement gradElement = qElement.firstChildElement(QLatin1String("gradient"));
+
+            if(!loadGradientFromXMI(gradElement, gradient) || !gradient) {
+                delete gradient;
+                return false;
+            }
+
+            brush = QBrush(*gradient);
+            delete gradient;
+        }
+
+        else {
+            brush = QBrush(color, (Qt::BrushStyle)style);
+        }
+
+        //TODO: Checks if transform needs to be loaded.
+
+        return true;
+    }
+
+    /**
+     * Saves the brush info as xmi into the DOM element \a qElement.
+     *
+     * @param qDoc The QDomDocument object pointing to the xmi document.
+     *
+     * @param qElement The element into which the pen, brush and font
+     *                 info should be saved.
+     *
+     * @param brush The QBrush whose details should be saved.
+     */
+    void saveBrushToXMI(QDomDocument &qDoc, QDomElement &qElement,
+                        const QBrush& brush)
+    {
+        QDomElement brushElement = qDoc.createElement(QLatin1String("brush"));
+
+        brushElement.setAttribute(QLatin1String("style"), (quint8)brush.style());
+        brushElement.setAttribute(QLatin1String("color"), brush.color().name());
+
+        if(brush.style() == Qt::TexturePattern) {
+            savePixmapToXMI(qDoc, brushElement, brush.texture());
+        }
+        else if(brush.style() == Qt::LinearGradientPattern
+                || brush.style() == Qt::RadialGradientPattern
+                || brush.style() == Qt::ConicalGradientPattern) {
+            saveGradientToXMI(qDoc, brushElement, brush.gradient());
+        }
+
+        //TODO: Check if transform of this brush needs to be saved.
+        qElement.appendChild(brushElement);
+    }
+
+    /**
+     * Returns true if the first widget's X is smaller than second's.
+     * Used for sorting the UMLWidgetList.
+     * @param widget1 The widget to compare.
+     * @param widget2 The widget to compare with.
+     */
+    bool hasSmallerX(const UMLWidget* widget1, const UMLWidget* widget2)
+    {
+        return widget1->x() < widget2->x();
+    }
+
+    /**
+     * Returns true if the first widget's Y is smaller than second's.
+     * Used for sorting the UMLWidgetList.
+     * @param widget1 The widget to compare.
+     * @param widget2 The widget to compare with.
+     */
+    bool hasSmallerY(const UMLWidget* widget1, const UMLWidget* widget2)
+    {
+        return widget1->y() < widget2->y();
+    }
+
+    /**
+     * Find the region in which the rectangle \a other lies with respect to
+     * the rectangle \a self.
+     * Beware that the Qt coordinate system has its origin point (0,0) in
+     * the upper left corner with Y values growing downwards, thus the Y
+     * related comparisons might look inverted if your are used to the
+     * natural coordinate system with (0,0) in the lower left corner.
+     */
+    Uml::Region::Enum findRegion(const QRectF& self, const QRectF &other)
+    {
+        const qreal ownX      = self.x();
+        const qreal ownY      = self.y();
+        const qreal ownWidth  = self.width();
+        const qreal ownHeight = self.height();
+        const qreal otherX      = other.x();
+        const qreal otherY      = other.y();
+        const qreal otherWidth  = other.width();
+        const qreal otherHeight = other.height();
+        Uml::Region::Enum region = Uml::Region::Center;
+        if (otherX + otherWidth < ownX) {
+            if (otherY + otherHeight < ownY)
+                region = Uml::Region::NorthWest;
+            else if (otherY > ownY + ownHeight)
+                region = Uml::Region::SouthWest;
+            else
+                region = Uml::Region::West;
+        } else if (otherX > ownX + ownWidth) {
+            if (otherY + otherHeight < ownY)
+                region = Uml::Region::NorthEast;
+            else if (otherY > ownY + ownHeight)
+                region = Uml::Region::SouthEast;
+            else
+                region = Uml::Region::East;
+        } else {
+            if (otherY + otherHeight < ownY)
+                region = Uml::Region::North;
+            else if (otherY > ownY + ownHeight)
+                region = Uml::Region::South;
+            else
+                region = Uml::Region::Center;
+        }
+        return region;
+    }
+
+    /**
+     * Return the point in \a poly which precedes the point at index \a index.
+     * If \a index is 0 then return the last (or, if \a poly.isClosed() is
+     * true, the second to last) point.
+     */
+    QPointF prevPoint(int index, const QPolygonF& poly) {
+        if (poly.size() < 3 || index >= poly.size())
+            return QPoint();
+        if (index == 0)
+            return poly.at(poly.size() - 1 - (int)poly.isClosed());
+        return poly.at(index - 1);
+    }
+
+    /**
+     * Return the point in \a poly which follows the point at index \a index.
+     * If \a index is the last index then return the first (or, if
+     * \a poly.isClosed() is true, the second) point.
+     */
+    QPointF nextPoint(int index, const QPolygonF& poly) {
+        if (poly.size() < 3 || index >= poly.size())
+            return QPoint();
+        if (index == poly.size() - 1)
+            return poly.at((int)poly.isClosed());
+        return poly.at(index + 1);
+    }
+
+    /**
+     * Return the middle value between \a a and \a b.
+     */
+    qreal middle(qreal a, qreal b)
+    {
+        return (a + b) / 2.0;
+    }
+
+    /**
+     * Auxiliary type for function findLine()
+     */
+    enum Axis_Type { X , Y };
+
+    /**
+     * Auxiliary type for function findLine()
+     */
+    enum Comparison_Type { Smallest, Largest };
+
+    /**
+     * Find the line of \a poly with the smallest or largest value (controlled by \a seek)
+     * along the axis controlled by \a axis.
+     * In case \a axis is X, do not consider lines whose Y values lie outside the Y values
+     * defined by \a boundingRect.
+     * In case \a axis is Y, do not consider lines whose X values lie outside the X values
+     * defined by \a boundingRect.
+     */
+    QLineF findLine(const QPolygonF& poly, Axis_Type axis, Comparison_Type seek, const QRectF& boundingRect)
+    {
+        const int lastIndex = poly.size() - 1 - (int)poly.isClosed();
+        QPointF prev = poly.at(lastIndex), curr;
+        QPointF p1(seek == Smallest ? QPointF(1.0e6, 1.0e6) : QPointF(-1.0e6, -1.0e6));
+        QPointF p2;
+        for (int i = 0; i <= lastIndex; i++) {
+            curr = poly.at(i);
+            // uDebug() << "  poly[" << i << "] = " << curr;
+            if (axis == X) {
+                if (fmin(prev.y(), curr.y()) > boundingRect.y() + boundingRect.height() ||
+                    fmax(prev.y(), curr.y()) < boundingRect.y()) {
+                    // line is outside Y-axis range defined by boundingRect
+                } else if ((seek == Smallest && curr.x() <= p1.x()) ||
+                           (seek == Largest  && curr.x() >= p1.x())) {
+                    p1 = curr;
+                    p2 = prev;
+                }
+            } else {
+                if (fmin(prev.x(), curr.x()) > boundingRect.x() + boundingRect.width() ||
+                    fmax(prev.x(), curr.x()) < boundingRect.x()) {
+                    // line is outside X-axis range defined by boundingRect
+                } else if ((seek == Smallest && curr.y() <= p1.y()) ||
+                           (seek == Largest  && curr.y() >= p1.y())) {
+                    p1 = curr;
+                    p2 = prev;
+                }
+            }
+            prev = curr;
+        }
+        return QLineF(p1, p2);
+    }
+
+    /**
+     * Determine the approximate closest points of two polygons.
+     * @param self  First QPolygonF.
+     * @param other Second QPolygonF.
+     * @return  QLineF::p1() returns point of \a self;
+     *          QLineF::p2() returns point of \a other.
+     */
+    QLineF closestPoints(const QPolygonF& self, const QPolygonF& other)
+    {
+        const QRectF& selfRect = self.boundingRect();
+        const QRectF& otherRect = other.boundingRect();
+        Uml::Region::Enum region = findRegion(selfRect, otherRect);
+        if (region == Uml::Region::Center)
+            return QLineF();
+        if (self.size() < 3 || other.size() < 3)
+            return QLineF();
+        QLineF result;
+        const int selfLastIndex  = self.size()  - 1 - (int)self.isClosed();
+        const int otherLastIndex = other.size() - 1 - (int)other.isClosed();
+        QPointF selfPoint(self.at(selfLastIndex));
+        QPointF otherPoint(other.at(otherLastIndex));
+        QLineF selfLine, otherLine;
+        int i;
+
+        switch (region) {
+
+        case Uml::Region::North:
+            // Find other's line with largest Y values
+            otherLine = findLine(other, Y, Largest, selfRect);
+            // Find own line with smallest Y values
+            selfLine = findLine(self, Y, Smallest, otherRect);
+            // Use the middle value of the X values
+            result.setLine(middle(selfLine.p2().x(), selfLine.p1().x()), selfLine.p1().y(),
+                           middle(otherLine.p2().x(), otherLine.p1().x()), otherLine.p1().y());
+            break;
+
+        case Uml::Region::South:
+            // Find other's line with smallest Y values
+            otherLine = findLine(other, Y, Smallest, selfRect);
+            // Find own line with largest Y values
+            selfLine = findLine(self, Y, Largest, otherRect);
+            // Use the middle value of the X values
+            result.setLine(middle(selfLine.p2().x(), selfLine.p1().x()), selfLine.p1().y(),
+                           middle(otherLine.p2().x(), otherLine.p1().x()), otherLine.p1().y());
+            break;
+
+        case Uml::Region::West:
+            // Find other's line with largest X values
+            otherLine = findLine(other, X, Largest, selfRect);
+            // Find own line with smallest X values
+            selfLine = findLine(self, X, Smallest, otherRect);
+            // Use the middle value of the Y values
+            result.setLine(selfLine.p1().x(), middle(selfLine.p2().y(), selfLine.p1().y()),
+                           otherLine.p1().x(), middle(otherLine.p2().y(), otherLine.p1().y()));
+            break;
+
+        case Uml::Region::East:
+            // Find other's line with smallest X values
+            otherLine = findLine(other, X, Smallest, selfRect);
+            // Find own line with largest X values
+            selfLine = findLine(self, X, Largest, otherRect);
+            // Use the middle value of the Y values
+            result.setLine(selfLine.p1().x(), middle(selfLine.p2().y(), selfLine.p1().y()),
+                           otherLine.p1().x(), middle(otherLine.p2().y(), otherLine.p1().y()));
+            break;
+
+        case Uml::Region::NorthWest:
+            // Find other's point with largest X and largest Y value
+            for (i = 0; i < otherLastIndex; ++i) {
+                QPointF current(other.at(i));
+                if (current.x() + current.y() >= otherPoint.x() + otherPoint.y()) {
+                    otherPoint = current;
+                }
+            }
+            // Find own point with smallest X and smallest Y value
+            for (i = 0; i < selfLastIndex; ++i) {
+                QPointF current(self.at(i));
+                if (current.x() + current.y() <= selfPoint.x() + selfPoint.y()) {
+                    selfPoint = current;
+                }
+            }
+            result.setPoints(selfPoint, otherPoint);
+            break;
+
+        case Uml::Region::SouthWest:
+            // Find other's point with largest X and smallest Y value
+            for (i = 0; i < otherLastIndex; ++i) {
+                QPointF current(other.at(i));
+                if (current.x() >= otherPoint.x() && current.y() <= otherPoint.y()) {
+                    otherPoint = current;
+                }
+            }
+            // Find own point with smallest X and largest Y value
+            for (i = 0; i < selfLastIndex; ++i) {
+                QPointF current(self.at(i));
+                if (current.x() <= selfPoint.x() && current.y() >= selfPoint.y()) {
+                    selfPoint = current;
+                }
+            }
+            result.setPoints(selfPoint, otherPoint);
+            break;
+
+        case Uml::Region::NorthEast:
+            // Find other's point with smallest X and largest Y value
+            for (i = 0; i < otherLastIndex; ++i) {
+                QPointF current(other.at(i));
+                if (current.x() <= otherPoint.x() && current.y() >= otherPoint.y()) {
+                    otherPoint = current;
+                }
+            }
+            // Find own point with largest X and smallest Y value
+            for (i = 0; i < selfLastIndex; ++i) {
+                QPointF current(self.at(i));
+                if (current.x() >= selfPoint.x() && current.y() <= selfPoint.y()) {
+                    selfPoint = current;
+                }
+            }
+            result.setPoints(selfPoint, otherPoint);
+            break;
+
+        case Uml::Region::SouthEast:
+            // Find other's point with smallest X and smallest Y value
+            for (i = 0; i < otherLastIndex; ++i) {
+                QPointF current(other.at(i));
+                if (current.x() + current.y() <= otherPoint.x() + otherPoint.y()) {
+                    otherPoint = current;
+                }
+            }
+            // Find own point with largest X and largest Y value
+            for (i = 0; i < selfLastIndex; ++i) {
+                QPointF current(self.at(i));
+                if (current.x() + current.y() >= selfPoint.x() + selfPoint.y()) {
+                    selfPoint = current;
+                }
+            }
+            result.setPoints(selfPoint, otherPoint);
+            break;
+
+        default:
+            // Error
+            break;
+        }
+
+        return result;
+    }
+
+}  // namespace Widget_Utils
diff -Nuar umbrello-15.08.1.orig/umbrello/umlwidgets/widget_utils.h umbrello-15.08.1/umbrello/umlwidgets/widget_utils.h
--- umbrello-15.08.1.orig/umbrello/umlwidgets/widget_utils.h	1970-01-01 02:00:00.000000000 +0200
+++ umbrello-15.08.1/umbrello/umlwidgets/widget_utils.h	2015-10-08 11:48:59.553089025 +0300
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   copyright (C) 2004-2014                                               *
+ *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
+ ***************************************************************************/
+
+#ifndef WIDGET_UTILS_H
+#define WIDGET_UTILS_H
+
+#include "basictypes.h"
+#include "messagewidgetlist.h"
+#include "umlwidgetlist.h"
+
+#include <QBrush>
+#include <QDomDocument>
+#include <QPointF>
+#include <QLineF>
+#include <QPolygonF>
+
+class QGraphicsItem;
+class QGraphicsRectItem;
+
+/**
+ * General purpose widget utilities.
+ * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
+ */
+namespace Widget_Utils
+{
+    UMLWidget* findWidget(Uml::ID::Type id,
+                          const UMLWidgetList& widgets,
+                          const MessageWidgetList* messages = 0);
+
+    QGraphicsRectItem* decoratePoint(const QPointF& p, QGraphicsItem* parent = 0);
+
+    void drawCrossInEllipse(QPainter *p, const QRectF& ellipse);
+    void drawTriangledRect(QPainter *painter, const QRectF& rect, const QSizeF& triSize);
+//    void drawArrowHead(QPainter *painter, const QPointF& arrowPos,
+//                       const QSizeF& arrowSize, Qt::ArrowType arrowType,
+//                       bool solid = false);
+//    void drawRoundedRect(QPainter *painter, const QRectF& rect, qreal xRadius,
+//            qreal yRadius, Uml::Corners corners);
+
+    QString pointToString(const QPointF& point);
+    QPointF stringToPoint(const QString& str);
+
+    bool loadPixmapFromXMI(QDomElement &qElement, QPixmap &pixmap);
+    void savePixmapToXMI(QDomDocument &qDoc, QDomElement &qElement, const QPixmap& pixmap);
+
+    bool loadGradientFromXMI(QDomElement &qElement, QGradient *&gradient);
+    void saveGradientToXMI(QDomDocument &qDoc, QDomElement &qElement, const QGradient *gradient);
+
+    bool loadBrushFromXMI(QDomElement &qElement, QBrush &brush);
+    void saveBrushToXMI(QDomDocument &qDoc, QDomElement &qElement,
+                        const QBrush& brush);
+
+    bool hasSmallerX(const UMLWidget* widget1, const UMLWidget* widget2);
+    bool hasSmallerY(const UMLWidget* widget1, const UMLWidget* widget2);
+
+    QLineF closestPoints(const QPolygonF& self, const QPolygonF& other);
+}
+
+#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/uniqueconstraint.cpp umbrello-15.08.1/umbrello/uniqueconstraint.cpp
--- umbrello-15.08.1.orig/umbrello/uniqueconstraint.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/uniqueconstraint.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,325 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-//own header
-#include "uniqueconstraint.h"
-
-// app includes
-#include "debug_utils.h"
-#include "entity.h"
-#include "entityattribute.h"
-#include "umldoc.h"
-#include "uml.h"
-#include "umlattributedialog.h"
-#include "umluniqueconstraintdialog.h"
-#include "object_factory.h"
-
-/**
- * Sets up a constraint.
- *
- * @param parent    The parent of this UMLUniqueConstraint.
- * @param name      The name of this UMLUniqueConstraint.
- * @param id        The unique id given to this UMLUniqueConstraint.
- */
-UMLUniqueConstraint::UMLUniqueConstraint(UMLObject *parent, const QString& name, Uml::ID::Type id)
-  : UMLEntityConstraint(parent, name, id)
-{
-    init();
-}
-
-/**
- * Sets up a constraint.
- *
- * @param parent    The parent of this UMLUniqueConstraint.
- */
-UMLUniqueConstraint::UMLUniqueConstraint(UMLObject *parent)
-  : UMLEntityConstraint(parent)
-{
-    init();
-}
-
-/**
- * Overloaded '==' operator
- */
-bool UMLUniqueConstraint::operator==(const  UMLUniqueConstraint &rhs) const
-{
-    if(this == &rhs)
-        return true;
-
-    if(!UMLObject::operator==(rhs))
-        return false;
-
-    return true;
-}
-
-/**
- * Destructor.
- */
-UMLUniqueConstraint::~UMLUniqueConstraint()
-{
-}
-
-/**
- * Copy the internal presentation of this object into the UMLUniqueConstraint
- * object.
- */
-void UMLUniqueConstraint::copyInto(UMLObject *lhs) const
-{
-    UMLUniqueConstraint *target = static_cast<UMLUniqueConstraint*>(lhs);
-
-    // call the parent first.
-    UMLEntityConstraint::copyInto(target);
-
-    // Copy all datamembers
-    target->m_EntityAttributeList.clear();
-    bool valid = true;
-    foreach(UMLEntityAttribute* attr, m_EntityAttributeList) {
-       if (!valid)
-           break;
-       valid = target->addEntityAttribute(attr);
-    }
-
-    if (!valid) {
-        target->m_EntityAttributeList.clear();
-        uDebug() <<"Copying Attributes Failed : Target list cleared instead";
-    }
-}
-
-/**
- * Make a clone of the UMLUniqueConstraint.
- */
-UMLObject* UMLUniqueConstraint::clone() const
-{
-    //FIXME: The new attribute should be slaved to the NEW parent not the old.
-    UMLUniqueConstraint *clone = new UMLUniqueConstraint(static_cast<UMLObject*>(parent()));
-    copyInto(clone);
-    return clone;
-}
-
-/**
- * Returns a string representation of the UMLUniqueConstraint.
- *
- * @param sig  If true will show the attribute type and initial value.
- * @return  Returns a string representation of the UMLAttribute.
- */
-QString UMLUniqueConstraint::toString(Uml::SignatureType::Enum sig)
-{
-     QString s;
-
-    if (sig == Uml::SignatureType::ShowSig || sig == Uml::SignatureType::SigNoVis) {
-        s = name() + QLatin1Char(':');
-
-        if (static_cast<UMLEntity*>(parent())->isPrimaryKey(this)) {
-           s += QLatin1String("Primary Key (");
-        } else {
-           s += QLatin1String("Unique (");
-        }
-
-        bool first = true;
-        foreach(UMLEntityAttribute* att, m_EntityAttributeList) {
-            if (first) {
-               first = false;
-            } else
-                s += QLatin1Char(',');
-            s += att->name();
-        }
-        s +=  QLatin1Char(')') ;
-    }
-
-    return s;
-}
-
-QString UMLUniqueConstraint::getFullyQualifiedName(const QString& separator,
-                                                   bool includeRoot) const
-{
-    Q_UNUSED(separator); Q_UNUSED(includeRoot);
-    return this->name();
-}
-
-/**
- * Creates the <UML:UniqueConstraint> XMI element.
- */
-void UMLUniqueConstraint::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement uniqueConstraintElement = UMLObject::save(QLatin1String("UML:UniqueConstraint"), qDoc);
-
-    UMLEntity* parentEnt = static_cast<UMLEntity*>(parent());
-    if (parentEnt->isPrimaryKey(this)) {
-        uniqueConstraintElement.setAttribute(QLatin1String("isPrimary"), QLatin1String("1"));
-    } else {
-        uniqueConstraintElement.setAttribute(QLatin1String("isPrimary"), QLatin1String("0"));
-    }
-
-    foreach(UMLEntityAttribute* att, m_EntityAttributeList) {
-        att->saveToXMI(qDoc, uniqueConstraintElement);
-    }
-
-    qElement.appendChild(uniqueConstraintElement);
-}
-
-/**
- * Display the properties configuration dialog for the attribute.
- */
-bool UMLUniqueConstraint::showPropertiesDialog(QWidget* parent)
-{
-    UMLUniqueConstraintDialog dialog(parent, this);
-    return dialog.exec();
-}
-
-/**
- * Loads the <UML:UniqueConstraint> XMI element.
- */
-bool UMLUniqueConstraint::load(QDomElement & element)
-{
-    int isPrimary = element.attribute(QLatin1String("isPrimary"), QLatin1String("0")).toInt();
-    UMLEntity* parentEnt = static_cast<UMLEntity*>(parent());
-
-    if (isPrimary == 1) {
-        parentEnt->setAsPrimaryKey(this);
-    }
-
-    QDomNode node = element.firstChild();
-    while (!node.isNull()) {
-        if (node.isComment()) {
-            node = node.nextSibling();
-            continue;
-        }
-        QDomElement tempElement = node.toElement();
-        QString tag = tempElement.tagName();
-        if (UMLDoc::tagEq(tag, QLatin1String("EntityAttribute"))) {
-
-            QString attName = tempElement.attribute(QLatin1String("name"));
-            UMLObject* obj = parentEnt->findChildObject(attName);
-
-            UMLEntityAttribute* entAtt = static_cast<UMLEntityAttribute*>(obj);
-            if (entAtt == NULL)
-                continue;
-
-            m_EntityAttributeList.append(entAtt);
-
-        } else {
-            uWarning() << "unknown child type in UMLUniqueConstraint::load";
-        }
-
-        node = node.nextSibling();
-    }
-
-    return true;
-}
-
-
-/**
- * Check if a entity attribute is present in m_entityAttributeList
- *
- * @param attr The Entity Attribute to check for existence in list
- * @return true if it exists in the list, else false
- */
-bool UMLUniqueConstraint::hasEntityAttribute(UMLEntityAttribute* attr)
-{
-    if (m_EntityAttributeList.indexOf(attr) == -1) {
-        //not present
-        return false;
-    }
-
-    // else present
-    return true;
-}
-
-/**
- * Adds a UMLEntityAttribute to the list.
- * The UMLEntityAttribute should already exist and should
- * belong to the parent UMLEntity.
- *
- * @param attr The UMLEntityAttribute to add
- * @return false if it failed to add, else true
- */
-bool UMLUniqueConstraint::addEntityAttribute(UMLEntityAttribute* attr)
-{
-    UMLEntity *owningParent = dynamic_cast<UMLEntity*>(parent());
-
-    if (hasEntityAttribute(attr)) {
-        uDebug() << "Unique Constraint already contains" << attr->name();
-        return false;
-
-    }
-    if (owningParent == NULL) {
-        uError() << name() << ": parent is not a UMLEntity";
-        return false;
-    }
-
-    if (owningParent->findChildObjectById(attr->id()) == NULL) {
-        uError()
-            << " parent " << owningParent->name()
-            << " does not contain attribute " << attr->name();
-        return false;
-    }
-
-    //else add the attribute to the Entity Attribute List
-    m_EntityAttributeList.append(attr);
-
-    return true;
-}
-
-/**
- * Removes a UMLEntityAttribute from the list
- *
- * @param attr The UMLEntityAttribute to remove from list
- * @return false if it failed to remove the attribute from the list
- */
-bool UMLUniqueConstraint::removeEntityAttribute(UMLEntityAttribute* attr)
-{
-    UMLEntity *owningParent = dynamic_cast<UMLEntity*>(parent());
-
-    if (owningParent == NULL) {
-        uError() << name() << ": parent is not a UMLEntity";
-        return false;
-    }
-
-    /*
-     * The attribute may already be removed from the Entity when this function
-     * is called. So checking this is not right
-     *
-     * if (owningParent->findChildObjectById(attr->ID()) == NULL) {
-     *    uError()
-     *        << " parent " << owningParent->getName()
-     *        << " does not contain attribute " << attr->getName();
-     *    return false;
-     * }
-     */
-
-    //else remove the attribute from the Entity Attribute List
-    if (m_EntityAttributeList.removeAll(attr)) {
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * Get the Entity Attributes List.
- */
-UMLEntityAttributeList UMLUniqueConstraint::getEntityAttributeList() const
-{
-    return m_EntityAttributeList;
-}
-
-void UMLUniqueConstraint::init()
-{
-    m_BaseType = UMLObject::ot_UniqueConstraint;
-}
-
-/**
- * Clear the list of attributes contained in this UniqueConstraint
- */
-void UMLUniqueConstraint::clearAttributeList()
-{
-    m_EntityAttributeList.clear();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/uniqueconstraint.h umbrello-15.08.1/umbrello/uniqueconstraint.h
--- umbrello-15.08.1.orig/umbrello/uniqueconstraint.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/uniqueconstraint.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,77 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef UNIQUECONSTRAINT_H
-#define UNIQUECONSTRAINT_H
-
-#include "basictypes.h"
-#include "classifierlistitem.h"
-#include "entityconstraint.h"
-#include "umlclassifierlist.h"
-#include "umlentityattributelist.h"
-
-/**
- * This class is used to set up information for a unique entity constraint.
- *
- * @short Sets up Unique entity constraint information.
- * @author Sharan Rao
- * @see UMLObject UMLClassifierListItem UMLEntityConstraint
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLUniqueConstraint : public UMLEntityConstraint
-{
-public:
-
-    UMLUniqueConstraint(UMLObject *parent, const QString& name,
-                        Uml::ID::Type id = Uml::ID::None);
-    explicit UMLUniqueConstraint(UMLObject *parent);
-    virtual ~UMLUniqueConstraint();
-
-    bool operator==(const UMLUniqueConstraint &rhs) const;
-
-    virtual void copyInto(UMLObject *lhs) const;
-
-    virtual UMLObject* clone() const;
-
-    QString toString(Uml::SignatureType::Enum sig = Uml::SignatureType::NoSig);
-
-    QString getFullyQualifiedName(const QString& separator = QString(),
-                                  bool includeRoot = false) const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    virtual bool showPropertiesDialog(QWidget* parent = 0);
-
-    bool hasEntityAttribute(UMLEntityAttribute* attr);
-
-    bool addEntityAttribute(UMLEntityAttribute* attr);
-
-    bool removeEntityAttribute(UMLEntityAttribute* attr);
-
-    UMLEntityAttributeList getEntityAttributeList() const;
-
-    void clearAttributeList();
-
-protected:
-
-    bool load(QDomElement & element);
-
-private:
-
-    void init();
-
-    /**
-     * The list of entity attributes that together make up the unique constraint.
-     */
-    UMLEntityAttributeList m_EntityAttributeList;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/usecase.cpp umbrello-15.08.1/umbrello/usecase.cpp
--- umbrello-15.08.1.orig/umbrello/usecase.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/usecase.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,67 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#include "usecase.h"
-
-/**
- * Creates a UseCase object
- *
- * @param name   The name of the object.
- * @param id     The id of the object.
- */
-UMLUseCase::UMLUseCase(const QString & name, Uml::ID::Type id)
-  : UMLCanvasObject(name, id)
-{
-    init();
-}
-
-/**
- * Standard decstructor.
- */
-UMLUseCase::~UMLUseCase()
-{
-}
-
-/**
- * Initializes key variables of the class.
- */
-void UMLUseCase::init()
-{
-    m_BaseType = UMLObject::ot_UseCase;
-}
-
-/**
- * Make a clone of this object.
- */
-UMLObject* UMLUseCase::clone() const
-{
-    UMLUseCase *clone = new UMLUseCase();
-    UMLObject::copyInto(clone);
-    return clone;
-}
-
-/**
- * Creates the <UML:UseCase> element.
- */
-void UMLUseCase::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement usecaseElement = UMLObject::save(QLatin1String("UML:UseCase"), qDoc);
-    qElement.appendChild(usecaseElement);
-}
-
-/**
- * Loads the <UML:UseCase> element (TODO).
- */
-bool UMLUseCase::load(QDomElement&)
-{
-    return true;
-}
-
-
diff -Nuar umbrello-15.08.1.orig/umbrello/usecase.h umbrello-15.08.1/umbrello/usecase.h
--- umbrello-15.08.1.orig/umbrello/usecase.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/usecase.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,40 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef USECASE_H
-#define USECASE_H
-
-#include "umlcanvasobject.h"
-
-/**
- * This class contains the non-graphical information required for a UML UseCase.
- * This class inherits from @ref UMLCanvasObject which contains most of the information.
- *
- * @short Information for a non-graphical UML UseCase.
- * @author Paul Hensgen <phensgen@techie.com>
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class UMLUseCase : public UMLCanvasObject
-{
-public:
-    explicit UMLUseCase(const QString & name = QString(), Uml::ID::Type id = Uml::ID::None);
-    ~UMLUseCase();
-
-    virtual void init();
-
-    virtual UMLObject* clone() const;
-
-    void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-    bool load(QDomElement & element);
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/activitywidget.cpp umbrello-15.08.1/umbrello/widgets/activitywidget.cpp
--- umbrello-15.08.1.orig/umbrello/widgets/activitywidget.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/activitywidget.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,457 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "activitywidget.h"
-
-// app includes
-#include "activitydialog.h"
-#include "debug_utils.h"
-#include "docwindow.h"
-#include "listpopupmenu.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umlscene.h"
-#include "umlview.h"
-
-// kde includes
-#include <KLocalizedString>
-#if QT_VERSION < 0x050000
-#include <kinputdialog.h>
-#endif
-
-// qt includes
-#if QT_VERSION >= 0x050000
-#include <QInputDialog>
-#endif
-#include <QPointer>
-/**
- * Creates a Activity widget.
- *
- * @param scene          The parent of the widget.
- * @param activityType   The type of activity.
- * @param id             The ID to assign (-1 will prompt a new ID.)
- */
-ActivityWidget::ActivityWidget(UMLScene * scene, ActivityType activityType, Uml::ID::Type id)
-  : UMLWidget(scene, WidgetBase::wt_Activity, id),
-    m_activityType(activityType)
-{
-    // set non zero size to avoid crash on painting
-    setSize(1, 1);
-}
-
-/**
- *  Destructor.
- */
-ActivityWidget::~ActivityWidget()
-{
-}
-
-/**
- * Returns the type of activity.
- */
-ActivityWidget::ActivityType ActivityWidget::activityType() const
-{
-    return m_activityType;
-}
-
-/**
- * Returns the type string of activity.
- */
-QString ActivityWidget::activityTypeStr() const
-{
-    return QLatin1String(ENUM_NAME(ActivityWidget, ActivityType, m_activityType));
-}
-
-/**
- * Sets the type of activity.
- */
-void ActivityWidget::setActivityType(ActivityType activityType)
-{
-    m_activityType = activityType;
-    updateGeometry();
-    UMLWidget::m_resizable = true;
-}
-
-/**
- * Determines whether a toolbar button represents an Activity.
- * CHECK: currently unused - can this be removed?
- *
- * @param tbb               The toolbar button enum input value.
- * @param resultType        The ActivityType corresponding to tbb.
- *                  This is only set if tbb is an Activity.
- * @return  True if tbb represents an Activity.
- */
-bool ActivityWidget::isActivity(WorkToolBar::ToolBar_Buttons tbb,
-                                ActivityType& resultType)
-{
-    bool status = true;
-    switch (tbb) {
-    case WorkToolBar::tbb_Initial_Activity:
-        resultType = Initial;
-        break;
-    case WorkToolBar::tbb_Activity:
-        resultType = Normal;
-        break;
-    case WorkToolBar::tbb_End_Activity:
-        resultType = End;
-        break;
-    case WorkToolBar::tbb_Final_Activity:
-        resultType = Final;
-        break;
-    case WorkToolBar::tbb_Branch:
-        resultType = Branch;
-        break;
-    default:
-        status = false;
-        break;
-    }
-    return status;
-}
-
-/**
- * This method get the name of the preText attribute.
- */
-QString ActivityWidget::preconditionText() const
-{
-    return m_preconditionText;
-}
-
-/**
- * This method set the name of the preText attribute
- */
-void ActivityWidget::setPreconditionText(const QString& aPreText)
-{
-    m_preconditionText = aPreText;
-    updateGeometry();
-    adjustAssocs(x(), y());
-}
-
-/**
- * This method get the name of the postText attribute.
- */
-QString ActivityWidget::postconditionText() const
-{
-    return m_postconditionText;
-}
-
-/**
- * This method set the name of the postText attribute
- */
-void ActivityWidget::setPostconditionText(const QString& aPostText)
-{
-    m_postconditionText = aPostText;
-    updateGeometry();
-    adjustAssocs(x(), y());
-}
-
-/**
- * Reimplemented from UMLWidget::showPropertiesDialog to show a
- * properties dialog for an ActivityWidget.
- */
-void ActivityWidget::showPropertiesDialog()
-{
-    UMLApp::app()->docWindow()->updateDocumentation(false);
-
-    QPointer<ActivityDialog> dialog = new ActivityDialog(umlScene()->activeView(), this);
-    if (dialog->exec() && dialog->getChangesMade()) {
-        UMLApp::app()->docWindow()->showDocumentation(this, true);
-        UMLApp::app()->document()->setModified(true);
-    }
-    delete dialog;
-}
-
-/**
- * Overrides the standard paint event.
- */
-void ActivityWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
-    Q_UNUSED(option);
-    Q_UNUSED(widget);
-    int w = width();
-    int h = height();
-
-    // Only for the final activity
-    float x;
-    float y;
-    QPen pen = painter->pen();
-
-    switch (m_activityType)
-    {
-    case Normal:
-        UMLWidget::setPenFromSettings(painter);
-        if (UMLWidget::useFillColor()) {
-            painter->setBrush(UMLWidget::fillColor());
-        }
-        {
-            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-            const int fontHeight  = fm.lineSpacing();
-            int textStartY = (h / 2) - (fontHeight / 2);
-            painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
-            painter->setPen(textColor());
-            painter->setFont(UMLWidget::font());
-            painter->drawText(ACTIVITY_MARGIN, textStartY,
-                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
-        }
-        break;
-
-    case Initial:
-        painter->setPen(QPen(WidgetBase::lineColor(), 1));
-        painter->setBrush(WidgetBase::lineColor());
-        painter->drawEllipse(0, 0, w, h);
-        break;
-
-    case Final:
-        UMLWidget::setPenFromSettings(painter);
-        painter->setBrush(Qt::white);
-        pen.setWidth(2);
-        pen.setColor (Qt::red);
-        painter->setPen(pen);
-        painter->drawEllipse(0, 0, w, h);
-        x = w/2 ;
-        y = h/2 ;
-        {
-            const float w2 = 0.7071 * (float)w / 2.0;
-            painter->drawLine((int)(x - w2 + 1), (int)(y - w2 + 1), (int)(x + w2), (int)(y + w2));
-            painter->drawLine((int)(x + w2 - 1), (int)(y - w2 + 1), (int)(x - w2), (int)(y + w2));
-        }
-        break;
-
-    case End:
-        painter->setPen(QPen(WidgetBase::lineColor(), 1));
-        painter->setBrush(WidgetBase::lineColor());
-        painter->drawEllipse(0, 0, w, h);
-        painter->setBrush(Qt::white);
-        painter->drawEllipse(1, 1, w - 2, h - 2);
-        painter->setBrush(WidgetBase::lineColor());
-        painter->drawEllipse(3, 3, w - 6, h - 6);
-        break;
-
-    case Branch:
-        UMLWidget::setPenFromSettings(painter);
-        if (UMLWidget::useFillColor()) {
-            painter->setBrush(UMLWidget::fillColor());
-        }
-        {
-            QPolygon array(4);
-            array[ 0 ] = QPoint(w / 2, 0);
-            array[ 1 ] = QPoint(w, h / 2);
-            array[ 2 ] = QPoint(w / 2, h);
-            array[ 3 ] = QPoint(0, h / 2);
-            painter->drawPolygon(array);
-            painter->drawPolyline(array);
-        }
-        break;
-
-    case Invok:
-        UMLWidget::setPenFromSettings(painter);
-        if (UMLWidget::useFillColor()) {
-            painter->setBrush(UMLWidget::fillColor());
-        }
-        {
-            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-            const int fontHeight  = fm.lineSpacing();
-            int textStartY = (h / 2) - (fontHeight / 2);
-            painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
-            painter->setPen(textColor());
-            painter->setFont(UMLWidget::font());
-            painter->drawText(ACTIVITY_MARGIN, textStartY,
-                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
-
-        }
-        x = w - (w/5);
-        y = h - (h/3);
-
-        painter->drawLine((int)x, (int) y, (int)x, (int)(y + 20));
-        painter->drawLine((int)(x - 10), (int)(y + 10), (int)(x + 10), (int)(y + 10));
-        painter->drawLine((int)(x - 10), (int)(y + 10), (int)(x - 10), (int)(y + 20));
-        painter->drawLine((int)(x + 10), (int)(y + 10), (int)(x + 10), (int)(y + 20));
-        break;
-
-    case Param:
-        UMLWidget::setPenFromSettings(painter);
-        if (UMLWidget::useFillColor()) {
-            painter->setBrush(UMLWidget::fillColor());
-        }
-        {
-            const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-            const int fontHeight  = fm.lineSpacing();
-            QString preCond= QLatin1String("<<precondition>> ") + preconditionText();
-            QString postCond= QLatin1String("<<postcondition>> ") + postconditionText();
-            //int textStartY = (h / 2) - (fontHeight / 2);
-            painter->drawRoundRect(0, 0, w, h, (h * 60) / w, 60);
-            painter->setPen(textColor());
-            painter->setFont(UMLWidget::font());
-            painter->drawText(ACTIVITY_MARGIN, fontHeight + 10,
-                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, preCond);
-            painter->drawText(ACTIVITY_MARGIN, fontHeight * 2 + 10,
-                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, postCond);
-            painter->drawText(ACTIVITY_MARGIN, (fontHeight / 2),
-                       w - ACTIVITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
-        }
-
-        break;
-    }
-    UMLWidget::paint(painter, option, widget);
-}
-
-/**
- * Overridden from UMLWidget due to emission of signal sigActMoved()
- */
-void ActivityWidget::moveWidgetBy(qreal diffX, qreal diffY)
-{
-    UMLWidget::moveWidgetBy(diffX, diffY);
-    emit sigActMoved(diffX, diffY);
-}
-
-/**
- * Loads the widget from the "activitywidget" XMI element.
- */
-bool ActivityWidget::loadFromXMI(QDomElement& qElement)
-{
-    if(!UMLWidget::loadFromXMI(qElement))
-        return false;
-    setName(qElement.attribute(QLatin1String("activityname")));
-    setDocumentation(qElement.attribute(QLatin1String("documentation")));
-    setPreconditionText(qElement.attribute(QLatin1String("precondition")));
-    setPostconditionText(qElement.attribute(QLatin1String("postcondition")));
-
-    QString type = qElement.attribute(QLatin1String("activitytype"), QLatin1String("1"));
-    setActivityType((ActivityType)type.toInt());
-
-    return true;
-}
-
-/**
- * Saves the widget to the "activitywidget" XMI element.
- */
-void ActivityWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement activityElement = qDoc.createElement(QLatin1String("activitywidget"));
-    UMLWidget::saveToXMI(qDoc, activityElement);
-    activityElement.setAttribute(QLatin1String("activityname"), name());
-    activityElement.setAttribute(QLatin1String("documentation"), documentation());
-    activityElement.setAttribute(QLatin1String("precondition"), preconditionText());
-    activityElement.setAttribute(QLatin1String("postcondition"), postconditionText());
-    activityElement.setAttribute(QLatin1String("activitytype"), m_activityType);
-    qElement.appendChild(activityElement);
-}
-
-/**
- * Overrides Method from UMLWidget.
- */
-void ActivityWidget::constrain(qreal& width, qreal& height)
-{
-    if (m_activityType == Normal || m_activityType == Invok || m_activityType == Param) {
-        UMLWidget::constrain(width, height);
-        return;
-    }
-
-    if (width > height)
-        width = height;
-    else if (height > width)
-        height = width;
-
-    UMLWidget::constrain(width, height);
-}
-
-/**
- * Captures any popup menu signals for menus it created.
- */
-void ActivityWidget::slotMenuSelection(QAction* action)
-{
-    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
-
-    switch(sel) {
-    case ListPopupMenu::mt_Rename:
-        {
-            bool ok = false;
-            QString n = name();
-#if QT_VERSION >= 0x050000
-            n = QInputDialog::getText(Q_NULLPTR,
-                                      i18n("Enter Activity Name"),
-                                      i18n("Enter the name of the new activity:"),
-                                      QLineEdit::Normal,
-                                      n, &ok);
-#else
-            n = KInputDialog::getText(i18n("Enter Activity Name"),
-                                      i18n("Enter the name of the new activity:"),
-                                      n, &ok);
-#endif
-            if (ok && !n.isEmpty()) {
-                setName(n);
-            }
-        }
-        break;
-
-    case ListPopupMenu::mt_Properties:
-        showPropertiesDialog();
-        break;
-
-    default:
-        UMLWidget::slotMenuSelection(action);
-    }
-}
-
-/**
- * Overrides method from UMLWidget
- */
-QSizeF ActivityWidget::minimumSize() const
-{
-    if (m_activityType == Normal || m_activityType == Invok || m_activityType == Param) {
-        const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-        const int fontHeight  = fm.lineSpacing();
-
-        int textWidth = fm.width(name());
-        int height = fontHeight;
-        height = height > ACTIVITY_HEIGHT ? height : ACTIVITY_HEIGHT;
-        height += ACTIVITY_MARGIN * 2;
-
-        textWidth = textWidth > ACTIVITY_WIDTH ? textWidth : ACTIVITY_WIDTH;
-
-        if (m_activityType == Invok) {
-             height += 40;
-        } else if (m_activityType == Param) {
-            QString maxSize;
-
-            maxSize = name().length() > postconditionText().length() ? name() : postconditionText();
-            maxSize = maxSize.length() > preconditionText().length() ? maxSize : preconditionText();
-
-            textWidth = fm.width(maxSize);
-            textWidth = textWidth + 50;
-            height += 100;
-        }
-
-        int width = textWidth > ACTIVITY_WIDTH ? textWidth : ACTIVITY_WIDTH;
-
-        width += ACTIVITY_MARGIN * 4;
-        return QSizeF(width, height);
-    }
-    else if (m_activityType == Branch) {
-        return QSizeF(20, 20);
-    }
-    return QSizeF(15, 15);
-}
-
-/**
- * Overrides method from UMLWidget
- */
-QSizeF ActivityWidget::maximumSize()
-{
-    if (m_activityType == Normal || m_activityType == Invok || m_activityType == Param) {
-        return UMLWidget::maximumSize();
-    }
-    if (m_activityType == Branch) {
-        return QSizeF(50, 50);
-    }
-    return QSizeF(30, 30);
-}
-
-
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/activitywidget.h umbrello-15.08.1/umbrello/widgets/activitywidget.h
--- umbrello-15.08.1.orig/umbrello/widgets/activitywidget.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/activitywidget.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,98 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ACTIVITYWIDGET_H
-#define ACTIVITYWIDGET_H
-
-#include "umlwidget.h"
-#include "worktoolbar.h"
-
-#define ACTIVITY_MARGIN 5
-#define ACTIVITY_WIDTH 30
-#define ACTIVITY_HEIGHT 10
-
-/**
- * This class is the graphical version of a UML Activity.  A ActivityWidget is created
- * by a @ref UMLView.  An ActivityWidget belongs to only one @ref UMLView instance.
- * When the @ref UMLView instance that this class belongs to, it will be automatically deleted.
- *
- * The ActivityWidget class inherits from the @ref UMLWidget class which adds most of the functionality
- * to this class.
- *
- * @short  A graphical version of a UML Activity.
- * @author Paul Hensgen <phensgen@techie.com>
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class ActivityWidget : public UMLWidget
-{
-    Q_OBJECT
-    Q_ENUMS(ActivityType)
-public:
-    enum ActivityType
-    {
-        Initial = 0,
-        Normal,
-        End,
-        Final,
-        Branch,
-        Invok,
-        Param
-    };
-
-    explicit ActivityWidget(UMLScene * scene, ActivityType activityType = Normal, Uml::ID::Type id = Uml::ID::None);
-    virtual ~ActivityWidget();
-
-    ActivityType activityType() const;
-    QString activityTypeStr() const;
-    void setActivityType(ActivityType activityType);
-
-    static bool isActivity(WorkToolBar::ToolBar_Buttons tbb,
-                            ActivityType& resultType);
-
-    QString preconditionText() const;
-    void setPreconditionText(const QString&);
-
-    QString postconditionText() const;
-    void setPostconditionText(const QString&);
-
-    virtual void showPropertiesDialog();
-    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-    virtual void moveWidgetBy(qreal diffX, qreal diffY);
-
-    virtual bool loadFromXMI(QDomElement & qElement);
-    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-    void constrain(qreal& width, qreal& height);
-
-signals:
-    /**
-     * Emitted when the activity widget is moved.
-     * Provides the delta X and delta Y amount by which the widget was moved
-     * relative to the previous position.
-     * Slots into PinWidget::slotActMoved()
-     * @param diffX The difference between previous and new X value.
-     * @param diffY The difference between previous and new Y value.
-     */
-    void sigActMoved(qreal diffX, qreal diffY);
-
-public Q_SLOTS:
-    virtual void slotMenuSelection(QAction* action);
-
-protected:
-    virtual QSizeF minimumSize() const;
-    virtual QSizeF maximumSize();
-
-    ActivityType m_activityType; ///< Type of activity.
-
-    QString m_preconditionText;
-    QString m_postconditionText;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/actorwidget.cpp umbrello-15.08.1/umbrello/widgets/actorwidget.cpp
--- umbrello-15.08.1.orig/umbrello/widgets/actorwidget.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/actorwidget.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,104 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header file
-#include "actorwidget.h"
-
-// local includes
-#include "actor.h"
-#include "umlview.h"
-
-/**
- * Constructs an ActorWidget.
- *
- * @param scene   The parent of this ActorWidget.
- * @param a      The Actor class this ActorWidget will display.
- */
-ActorWidget::ActorWidget(UMLScene * scene, UMLActor *a)
-  : UMLWidget(scene, WidgetBase::wt_Actor, a)
-{
-    setFixedAspectRatio(true);
-}
-
-/**
- * Destructor.
- */
-ActorWidget::~ActorWidget()
-{
-}
-
-/**
- * Overrides the standard paint event.
- */
-void ActorWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
-    Q_UNUSED(option);
-    Q_UNUSED(widget);
-    UMLWidget::setPenFromSettings(painter);
-    if(UMLWidget::useFillColor())
-        painter->setBrush(UMLWidget::fillColor());
-    const int w = width();
-    const int h = height();
-    painter->setFont(UMLWidget::font());
-    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-    const int fontHeight = fm.lineSpacing();
-    bool drawStereotype = umlObject() && !umlObject()->stereotype().isEmpty();
-    const int a_height = h - (drawStereotype ? 2 * fontHeight : fontHeight) - A_MARGIN;
-    const int h2 = a_height / 2;
-    const int a_width = (h2);
-    const int middleX = w / 2;
-    const int thirdY = a_height / 3;
-
-    //draw actor
-    painter->drawEllipse(middleX - a_width / 2, 0, a_width, thirdY); //head
-    painter->drawLine(middleX, thirdY,
-               middleX, thirdY * 2); //body
-    painter->drawLine(middleX, 2 * thirdY,
-               middleX - a_width / 2, a_height); //left leg
-    painter->drawLine(middleX,  2 * thirdY,
-               middleX + a_width / 2, a_height); //right leg
-    painter->drawLine(middleX - a_width / 2, thirdY + thirdY / 2,
-               middleX + a_width / 2, thirdY + thirdY / 2); //arms
-    //draw text
-    painter->setPen(textColor());
-    if (drawStereotype)
-        painter->drawText(A_MARGIN, h - 2 * fontHeight, w - A_MARGIN * 2, fontHeight, Qt::AlignCenter, umlObject()->stereotype(true));
-    painter->drawText(A_MARGIN, h - fontHeight,
-               w - A_MARGIN * 2, fontHeight, Qt::AlignCenter, name());
-    UMLWidget::paint(painter, option, widget);
-}
-
-/**
- * Saves the widget to the "actorwidget" XMI element.
- * Note: For loading from XMI, the inherited parent method is used.
- */
-void ActorWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
-{
-    QDomElement actorElement = qDoc.createElement(QLatin1String("actorwidget"));
-    UMLWidget::saveToXMI(qDoc, actorElement);
-    qElement.appendChild(actorElement);
-}
-
-/**
- * Overrides method from UMLWidget.
- */
-QSizeF ActorWidget::minimumSize() const
-{
-    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-    const int fontHeight  = fm.lineSpacing();
-    const int textWidth = fm.width(name());
-    bool drawStereotype = umlObject() && !umlObject()->stereotype().isEmpty();
-    int width = textWidth > A_WIDTH ? textWidth : A_WIDTH;
-    int height = A_HEIGHT + (drawStereotype ? 2 * fontHeight : fontHeight) + A_MARGIN;
-    width += A_MARGIN * 2;
-    return QSizeF(width, height);
-}
-
-
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/actorwidget.h umbrello-15.08.1/umbrello/widgets/actorwidget.h
--- umbrello-15.08.1.orig/umbrello/widgets/actorwidget.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/actorwidget.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,55 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ACTORWIDGET_H
-#define ACTORWIDGET_H
-
-#include "umlwidget.h"
-
-#define A_WIDTH 20
-#define A_HEIGHT 40
-#define A_MARGIN 5
-
-class UMLActor;
-
-/**
- * This class is the graphical version of a UML Actor.
- * An ActorWidget is created by a @ref UMLView.  An ActorWidget belongs to only
- * one @ref UMLView instance.
- * When the @ref UMLView instance that this class belongs to is destroyed, the
- * ActorWidget will be automatically deleted.
- *
- * If the UMLActor class that this ActorWidget is displaying is deleted, the
- * @ref UMLView will make sure that this instance is also deleted.
- *
- * The ActorWidget class inherits from the @ref UMLWidget class
- * which adds most of the functionality to this class.
- *
- * @short A graphical version of a UML Actor.
- * @author Paul Hensgen <phensgen@techie.com>
- * @see UMLWidget
- * @see UMLView
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class ActorWidget : public UMLWidget
-{
-public:
-    ActorWidget(UMLScene * scene, UMLActor *o);
-    virtual ~ActorWidget();
-
-    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
-    virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
-
-protected:
-    QSizeF minimumSize() const;
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/artifactwidget.cpp umbrello-15.08.1/umbrello/widgets/artifactwidget.cpp
--- umbrello-15.08.1.orig/umbrello/widgets/artifactwidget.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/artifactwidget.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,293 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "artifactwidget.h"
-
-// app includes
-#include "artifact.h"
-#include "debug_utils.h"
-#include "umlscene.h"
-#include "umlview.h"
-
-/**
- * Constructs a ArtifactWidget.
- *
- * @param scene     The parent of this ArtifactWidget.
- * @param a         The Artifact this widget will be representing.
- */
-ArtifactWidget::ArtifactWidget(UMLScene *scene, UMLArtifact *a)
-  : UMLWidget(scene, WidgetBase::wt_Artifact, a)
-{
-    setSize(100, 30);
-}
-
-/**
- * Destructor.
- */
-ArtifactWidget::~ArtifactWidget()
-{
-}
-
-/**
- * Reimplemented to paint the articraft widget. Some part of specific
- * drawing is delegeted to private method like drawAsFile..
- */
-void ArtifactWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
-    Q_UNUSED(option);
-    Q_UNUSED(widget);
-
-    UMLWidget::setPenFromSettings(painter);
-    if (UMLWidget::useFillColor()) {
-        painter->setBrush(UMLWidget::fillColor());
-    } else {
-        painter->setBrush(m_scene->backgroundColor());
-    }
-
-    if (umlObject()) {
-        UMLArtifact *umlart = static_cast<UMLArtifact*>(m_umlObject);
-        UMLArtifact::Draw_Type drawType = umlart->getDrawAsType();
-        switch (drawType) {
-        case UMLArtifact::defaultDraw:
-            paintAsNormal(painter, option);
-            break;
-        case UMLArtifact::file:
-            paintAsFile(painter, option);
-            break;
-        case UMLArtifact::library:
-            paintAsLibrary(painter, option);
-            break;
-        case UMLArtifact::table:
-            paintAsTable(painter, option);
-            break;
-        default:
-            uWarning() << "Artifact drawn as unknown type";
-            break;
-        }
-    }
-    else {
-        uWarning() << "Cannot draw as there is no UMLArtifact for this widget.";
-    }
-}
-
-/**
- * Reimplemented from WidgetBase::saveToXMI to save the widget to
- * the "artifactwidget" XMI element.
- */
-void ArtifactWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
-{
-    QDomElement conceptElement = qDoc.createElement(QLatin1String("artifactwidget"));
-    UMLWidget::saveToXMI(qDoc, conceptElement);
-    qElement.appendChild(conceptElement);
-}
-
-/**
- * Overrides method from UMLWidget.
- */
-QSizeF ArtifactWidget::minimumSize() const
-{
-    if (!m_umlObject) {
-        return UMLWidget::minimumSize();
-    }
-    UMLArtifact *umlart = static_cast<UMLArtifact*>(m_umlObject);
-    if (umlart->getDrawAsType() == UMLArtifact::defaultDraw) {
-        return calculateNormalSize();
-    } else {
-        return calculateIconSize();
-    }
-}
-
-/**
- * calculates the size when drawing as an icon (it's the same size for all icons)
- */
-QSize ArtifactWidget::calculateIconSize() const
-{
-    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
-    const int fontHeight  = fm.lineSpacing();
-
-    int width = fm.width(m_umlObject->name());
-
-    width = width<50 ? 50 : width;
-
-    int height = 50 + fontHeight;
-
-    return QSize(width, height);
-}
-
-/**
- * calculates the size for drawing as a box
- */
-QSize ArtifactWidget::calculateNormalSize() const
-{
-    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
-    const int fontHeight  = fm.lineSpacing();
-
-    int width = fm.width(m_umlObject->name());
-
-    int tempWidth = 0;
-    if(!m_umlObject->stereotype().isEmpty()) {
-        tempWidth = fm.width(m_umlObject->stereotype(true));
-    }
-    width = tempWidth>width ? tempWidth : width;
-    width += ARTIFACT_MARGIN * 2;
-
-    int height = (2*fontHeight) + (ARTIFACT_MARGIN * 2);
-
-    return QSize(width, height);
-}
-
-/**
- * draw as a file icon
- */
-void ArtifactWidget::paintAsFile(QPainter *painter, const QStyleOptionGraphicsItem *option)
-{
-    const int w = width();
-    const int h = height();
-    QFont font = UMLWidget::font();
-    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-    const int fontHeight  = fm.lineSpacing();
-
-    int startX = (w/2) - 25;
-    int iconHeight = h - fontHeight;
-    QPolygon pointArray(5);
-    pointArray.setPoint(0, startX, 0);
-    pointArray.setPoint(1, startX + 40, 0);
-    pointArray.setPoint(2, startX + 50, 10);
-    pointArray.setPoint(3, startX + 50, iconHeight);
-    pointArray.setPoint(4, startX, iconHeight);
-    painter->drawPolygon(pointArray);
-
-    painter->drawLine(startX + 40, 0, startX + 40, 10);
-    painter->drawLine(startX + 40, 10, startX + 50, 10);
-    painter->drawLine(startX + 40, 0, startX + 50, 10);
-
-    painter->setPen(textColor());
-    painter->setFont(font);
-
-    painter->drawText(0, h - fontHeight,
-               w, fontHeight, Qt::AlignCenter, name());
-
-    UMLWidget::paint(painter, option);
-}
-
-/**
- * draw as a library file icon
- */
-void ArtifactWidget::paintAsLibrary(QPainter *painter, const QStyleOptionGraphicsItem *option)
-{
-    //FIXME this should have gears on it
-    const int w = width();
-    const int h = height();
-    const QFont font = UMLWidget::font();
-    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-    const int fontHeight  = fm.lineSpacing();
-
-    const int startX = (w/2) - 25;
-    const int iconHeight = h - fontHeight;
-    QPolygon pointArray(5);
-    pointArray.setPoint(0, startX, 0);
-    pointArray.setPoint(1, startX + 40, 0);
-    pointArray.setPoint(2, startX + 50, 10);
-    pointArray.setPoint(3, startX + 50, iconHeight);
-    pointArray.setPoint(4, startX, iconHeight);
-    painter->drawPolygon(pointArray);
-
-    painter->drawLine(startX + 40, 0, startX + 40, 10);
-    painter->drawLine(startX + 40, 10, startX + 50, 10);
-    painter->drawLine(startX + 40, 0, startX + 50, 10);
-
-    painter->setPen(textColor());
-    painter->setFont(font);
-
-    painter->drawText(0, h - fontHeight,
-               w, fontHeight, Qt::AlignCenter, name());
-
-    UMLWidget::paint(painter, option);
-}
-
-/**
- * draw as a database table icon
- */
-void ArtifactWidget::paintAsTable(QPainter *painter, const QStyleOptionGraphicsItem *option)
-{
-    const int w = width();
-    const int h = height();
-    const QFont font = UMLWidget::font();
-    const QFontMetrics &fm = getFontMetrics(FT_NORMAL);
-    const int fontHeight  = fm.lineSpacing();
-
-    const int startX = (w/2) - 25;
-    const int iconHeight = h - fontHeight;
-
-    painter->drawRect(startX, 0, 50, h - fontHeight + 1);
-    painter->drawLine(startX + 20, 0, startX + 20, iconHeight);
-    painter->drawLine(startX + 30, 0, startX + 30, iconHeight);
-    painter->drawLine(startX + 40, 0, startX + 40, iconHeight);
-    painter->drawLine(startX, (iconHeight/2), startX + 49, (iconHeight/2));
-    painter->drawLine(startX, (iconHeight/2) + (iconHeight/4),
-               startX + 49, (iconHeight/2) + (iconHeight/4));
-
-    QPen thickerPen = painter->pen();
-    thickerPen.setWidth(2);
-    painter->setPen(thickerPen);
-    painter->drawLine(startX + 10, 0, startX + 10, iconHeight);
-    painter->drawLine(startX, (iconHeight/4), startX + 50, (iconHeight/4));
-
-    painter->setPen(textColor());
-    painter->setFont(font);
-
-    painter->drawText(0, h - fontHeight,
-               w, fontHeight, Qt::AlignCenter, name());
-
-    UMLWidget::paint(painter, option);
-}
-
-/**
- * draw as a box
- */
-void ArtifactWidget::paintAsNormal(QPainter *painter, const QStyleOptionGraphicsItem *option)
-{
-    int w = width();
-    int h = height();
-    QFont font = UMLWidget::font();
-    font.setBold(true);
-    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
-    const int fontHeight  = fm.lineSpacing();
-    QString stereotype = m_umlObject->stereotype();
-
-    painter->drawRect(0, 0, w, h);
-
-    painter->setPen(textColor());
-    painter->setFont(font);
-
-    if (!stereotype.isEmpty()) {
-        painter->drawText(ARTIFACT_MARGIN, (h/2) - fontHeight,
-                   w, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true));
-    }
-
-    int lines;
-    if (!stereotype.isEmpty()) {
-        lines = 2;
-    } else {
-        lines = 1;
-    }
-
-    if (lines == 1) {
-        painter->drawText(0, (h/2) - (fontHeight/2),
-                   w, fontHeight, Qt::AlignCenter, name());
-    } else {
-        painter->drawText(0, (h/2),
-                   w, fontHeight, Qt::AlignCenter, name());
-    }
-
-    UMLWidget::paint(painter, option);
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/artifactwidget.h umbrello-15.08.1/umbrello/widgets/artifactwidget.h
--- umbrello-15.08.1.orig/umbrello/widgets/artifactwidget.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/artifactwidget.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,55 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2003-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ARTIFACTWIDGET_H
-#define ARTIFACTWIDGET_H
-
-#include "umlwidget.h"
-
-class UMLScene;
-class UMLArtifact;
-
-#define ARTIFACT_MARGIN 5
-
-/**
- * Defines a graphical version of the @ref UMLArtifact.
- * Most of the functionality will come from the @ref UMLWidget class.
- *
- * @short A graphical version of a Artifact.
- * @author Jonathan Riddell
- * @see UMLWidget
- * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
- */
-class ArtifactWidget : public UMLWidget
-{
-public:
-    ArtifactWidget(UMLScene *scene, UMLArtifact *a);
-    virtual ~ArtifactWidget();
-
-    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
-    // Note: For loading from XMI, the inherited parent method is used.
-    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
-
-protected:
-    QSizeF minimumSize() const;
-
-private:
-    void paintAsFile(QPainter *painter, const QStyleOptionGraphicsItem *option);
-    void paintAsLibrary(QPainter *painter, const QStyleOptionGraphicsItem *option);
-    void paintAsTable(QPainter *painter, const QStyleOptionGraphicsItem *option);
-    void paintAsNormal(QPainter *painter, const QStyleOptionGraphicsItem *option);
-
-    QSize calculateIconSize() const;
-    QSize calculateNormalSize() const;
-
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/associationline.cpp umbrello-15.08.1/umbrello/widgets/associationline.cpp
--- umbrello-15.08.1.orig/umbrello/widgets/associationline.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/associationline.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,1404 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "associationline.h"
-
-// application includes
-#include "associationwidget.h"
-#include "debug_utils.h"
-#include "umlwidget.h"
-
-// qt includes
-#include <QDomDocument>
-#include <QPainter>
-
-// system includes
-#include <cstdlib>
-#include <cmath>
-
-DEBUG_REGISTER_DISABLED(AssociationLine)
-
-// Initialize static variables.
-const qreal AssociationLine::Delta = 5;
-const qreal AssociationLine::SelectedPointDiameter = 4;
-const qreal AssociationLine::SelfAssociationMinimumHeight = 30;
-
-/**
- * Constructor.
- * Constructs an AssociationLine item with its parent being \a parent.
- */
-AssociationLine::AssociationLine(AssociationWidget *association)
-  : QGraphicsObject(association),
-    m_associationWidget(association),
-    m_activePointIndex(-1),
-    m_activeSegmentIndex(-1),
-    m_startSymbol(0),
-    m_endSymbol(0),
-    m_subsetSymbol(0),
-    m_collaborationLineItem(0),
-    m_collaborationLineHead(0),
-    m_layout(Polyline)
-{
-    Q_ASSERT(association);
-    setFlag(QGraphicsLineItem::ItemIsSelectable);
-    setAcceptHoverEvents(true);
-    setZValue(3);
-}
-
-/**
- * Destructor.
- */
-AssociationLine::~AssociationLine()
-{
-}
-
-/**
- * Returns the point at the point index.
- * @return point at given index
- */
-QPointF AssociationLine::point(int index) const
-{
-    if ((index < 0) | (index >= m_points.size())) {
-        uWarning() << "Index " << index << " out of range [0.." << m_points.size() - 1 << "].";
-        return QPointF(-1.0, -1.0);
-    }
-    return m_points.at(index);
-}
-
-/**
- * Sets the point value at given index to \a point.
- */
-bool AssociationLine::setPoint(int index, const QPointF &point)
-{
-    if ((index < 0) | (index >= m_points.size())) {
-        uWarning() << "Index " << index << " out of range [0.." << m_points.size() - 1 << "].";
-        return false;
-    }
-    if (m_points.at(index) == point) {
-        return false;  // nothing to change
-    }
-    prepareGeometryChange();
-    m_points[index] = point;
-    alignSymbols();
-    return true;
-}
-
-/**
- * Shortcut for point(0).
- */
-QPointF AssociationLine::startPoint() const
-{
-    return m_points.at(0);
-}
-
-/**
- * Shortcut for end point.
- */
-QPointF AssociationLine::endPoint() const
-{
-    return m_points.at(m_points.size()-1);
-}
-
-/**
- * Inserts the passed in \a point at the \a index passed in and
- * recalculates the bounding rect.
- */
-void AssociationLine::insertPoint(int index, const QPointF &point)
-{
-    prepareGeometryChange();
-    m_points.insert(index, point);
-    alignSymbols();
-}
-
-/**
- * Removes the point at \a index passed in.
- * @see removeNonEndPoint
- */
-void AssociationLine::removePoint(int index)
-{
-    prepareGeometryChange();
-    m_points.remove(index);
-    alignSymbols();
-}
-
-/**
- * Returns the amount of POINTS on the line.
- * Includes start and end points.
- * @return   number of points in the AssociationLine
- */
-int AssociationLine::count() const
-{
-    return m_points.size();
-}
-
-/**
- * Removes all the points and signals a geometry update.
- */
-void AssociationLine::cleanup()
-{
-    if (!m_points.isEmpty()) {
-        prepareGeometryChange();
-        m_points.clear();
-        alignSymbols();
-    }
-}
-
-/**
- * This method optimizes the number of points in the
- * AssociationLine. This can be used to reduce the clutter caused
- * due to too many points.
- * TODO: Use delta comparison 'closestPointIndex' instead of exact comparison.
- * TODO: Not used anywhere.
- */
-void AssociationLine::optimizeLinePoints()
-{
-    int i = 1;
-    prepareGeometryChange();
-    while (i < m_points.size()) {
-        if (m_points.at(i) == m_points.at(i-1)) {
-            m_points.remove(i);
-        }
-        else {
-            ++i;
-        }
-    }
-    alignSymbols();
-}
-
-/**
- * Return index of point closer a given delta.
- *
- * @param point The point which is to be tested for closeness.
- * @param delta The distance the point should be closer to.
- *
- * @retval "Index" of the first line point closer to the \a point passed.
- * @retval -1 If no line point is closer to passed in \a point.
- */
-int AssociationLine::closestPointIndex(const QPointF &point, qreal delta) const
-{
-    for(int i = 0; i < m_points.size(); ++i) {
-        const QPointF& linePoint = m_points.at(i);
-        // Apply distance formula to see point closeness.
-        qreal deltaXSquare = (point.x() - linePoint.x()) * (point.x() - linePoint.x());
-        qreal deltaYSquare = (point.y() - linePoint.y()) * (point.y() - linePoint.y());
-
-        qreal lhs = deltaXSquare + deltaYSquare;
-        qreal rhs = delta * delta;
-
-        if (lhs <= rhs) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-/**
- * Return index of closest segment.
- *
- * @param point The point which is to be tested for closeness.
- *
- * @return Index of the line segment closest to the \a point passed;
- *         -1 if no line segment is closer to passed in \a point.
- */
-int AssociationLine::closestSegmentIndex(const QPointF &point, qreal delta) const
-{
-    QPainterPathStroker stroker;
-    stroker.setWidth(delta);
-
-    for(int i = 1; i < m_points.size(); ++i) {
-        QLineF segment(m_points[i-1], m_points[i]);
-
-        QPainterPath path;
-        path.moveTo(segment.p1());
-        path.lineTo(segment.p2());
-
-        path = stroker.createStroke(path);
-
-        if (path.contains(point)) {
-            return i-1;
-        }
-    }
-    return -1;
-}
-
-/**
- * Retval True If point at \a index is start or end.
- */
-bool AssociationLine::isEndPointIndex(int index) const
-{
-    const int size = m_points.size();
-    Q_ASSERT(index >= 0 && index < size);
-
-    return (index == 0 || index == (size - 1));
-}
-
-/**
- * Retval True If segment at \a index is start or end.
- */
-bool AssociationLine::isEndSegmentIndex(int index) const
-{
-    // num of seg = num of points - 1
-    const int size = m_points.size() - 1;
-    Q_ASSERT(index >= 0 && index < size);
-
-    return (index == 0 || index == (size - 1));
-}
-
-/**
- * Sets the start and end points.
- */
-bool AssociationLine::setEndPoints(const QPointF &start, const QPointF &end)
-{
-    const int size = m_points.size();
-
-    prepareGeometryChange();
-
-    if (size == 0) {
-        m_points.insert(0, start);
-        m_points.insert(1, end);
-    }
-    else if (size == 1) {
-        m_points[0] = start;
-        m_points.insert(1, end);
-    }
-    else {
-        m_points[0] = start;
-        m_points[size-1] = end;
-    }
-
-    alignSymbols();
-    return true;
-}
-
-/**
- * Debug helper method to write out the points.
- */
-void AssociationLine::dumpPoints()
-{
-    for (int i = 1; i < m_points.size(); ++i) {
-        QPointF p = m_points.at(i);
-        DEBUG(DBG_SRC) << i << ". point x:" << p.x() << " / y:" << p.y();
-    }
-}
-
-/**
- * Loads AssociationLine information saved in \a qElement XMI element.
- */
-bool AssociationLine::loadFromXMI(QDomElement &qElement)
-{
-    QString layout = qElement.attribute(QLatin1String("layout"), QLatin1String("polyline"));
-    m_layout = fromString(layout);
-
-    QDomNode node = qElement.firstChild();
-
-    m_points.clear();
-
-    QDomElement startElement = node.toElement();
-    if(startElement.isNull() || startElement.tagName() != QLatin1String("startpoint")) {
-        return false;
-    }
-    QString x = startElement.attribute(QLatin1String("startx"), QLatin1String("0"));
-    qreal nX = x.toFloat();
-    QString y = startElement.attribute(QLatin1String("starty"), QLatin1String("0"));
-    qreal nY = y.toFloat();
-    QPointF startPoint(nX, nY);
-
-    node = startElement.nextSibling();
-    QDomElement endElement = node.toElement();
-    if(endElement.isNull() || endElement.tagName() != QLatin1String("endpoint")) {
-        return false;
-    }
-    x = endElement.attribute(QLatin1String("endx"), QLatin1String("0"));
-    nX = x.toFloat();
-    y = endElement.attribute(QLatin1String("endy"), QLatin1String("0"));
-    nY = y.toFloat();
-    QPointF endPoint(nX, nY);
-    setEndPoints(startPoint, endPoint);
-    QPointF point;
-    node = endElement.nextSibling();
-    QDomElement element = node.toElement();
-    int i = 1;
-    while(!element.isNull()) {
-        if(element.tagName() == QLatin1String("point")) {
-            x = element.attribute(QLatin1String("x"), QLatin1String("0"));
-            y = element.attribute(QLatin1String("y"), QLatin1String("0"));
-            point.setX(x.toFloat());
-            point.setY(y.toFloat());
-            insertPoint(i++, point);
-        }
-        node = element.nextSibling();
-        element = node.toElement();
-    }
-
-    return true;
-}
-
-/**
- * Saves association line information into XMI element named "linepath".
- * @note Stored as linepath for backwared compatibility
- */
-void AssociationLine::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
-{
-    QPointF point = m_associationWidget->mapToScene(startPoint());
-    QDomElement lineElement = qDoc.createElement(QLatin1String("linepath"));
-    lineElement.setAttribute(QLatin1String("layout"), toString(m_layout));
-    QDomElement startElement = qDoc.createElement(QLatin1String("startpoint"));
-    startElement.setAttribute(QLatin1String("startx"), point.x());
-    startElement.setAttribute(QLatin1String("starty"), point.y());
-    lineElement.appendChild(startElement);
-    QDomElement endElement = qDoc.createElement(QLatin1String("endpoint"));
-    point = m_associationWidget->mapToScene(endPoint());
-    endElement.setAttribute(QLatin1String("endx"), point.x());
-    endElement.setAttribute(QLatin1String("endy"), point.y());
-    lineElement.appendChild(endElement);
-    for(int i = 1; i < count()-1; ++i) {
-        QDomElement pointElement = qDoc.createElement(QLatin1String("point"));
-        point = m_associationWidget->mapToScene(this->point(i));
-        pointElement.setAttribute(QLatin1String("x"), point.x());
-        pointElement.setAttribute(QLatin1String("y"), point.y());
-        lineElement.appendChild(pointElement);
-    }
-    qElement.appendChild(lineElement);
-}
-
-/**
- * Returns the type of brush to use depending on the type of Association.
- */
-QBrush AssociationLine::brush() const
-{
-    QBrush brush(Qt::SolidPattern);
-    Uml::AssociationType::Enum type = m_associationWidget->associationType();
-    if (type == Uml::AssociationType::Aggregation    ||
-        type == Uml::AssociationType::Generalization ||
-        type == Uml::AssociationType::Realization) {
-        brush.setColor(Qt::white);
-    }
-    if (type == Uml::AssociationType::Composition) {
-        brush.setColor(m_associationWidget->lineColor());
-    }
-    return brush;
-}
-
-/**
- * Returns the type of pen to use depending on the type of Association.
- */
-QPen AssociationLine::pen() const
-{
-    QPen pen(m_associationWidget->lineColor(),
-             m_associationWidget->lineWidth(),
-             Qt::SolidLine,
-             Qt::RoundCap,
-             Qt::RoundJoin);
-    Uml::AssociationType::Enum type = m_associationWidget->associationType();
-    if (type == Uml::AssociationType::Dependency  ||
-        type == Uml::AssociationType::Realization ||
-        type == Uml::AssociationType::Anchor) {
-        pen.setStyle(Qt::DashLine);
-    }
-    return pen;
-}
-
-/**
- * This method simply ensures presence of two points and
- * adds the needed points for self associations.
- */
-void AssociationLine::calculateInitialEndPoints()
-{
-    if (m_associationWidget->isSelf() && count() < 4) {
-        for (int i = count(); i < 4; ++i) {
-            insertPoint(i, QPointF());
-        }
-        UMLWidget *wid = m_associationWidget->widgetForRole(Uml::RoleType::B);
-        if (!wid) {
-            uError() << "AssociationWidget is partially constructed."
-                "UMLWidget for role B is null.";
-            return;
-        }
-        const QRectF rect = m_associationWidget->mapFromScene(
-                mapToScene(wid->rect()).boundingRect()).boundingRect();
-
-        qreal l = rect.left() + .25 * rect.width();
-        qreal r = rect.left() + .75 * rect.width();
-        bool drawAbove = rect.top() >= SelfAssociationMinimumHeight;
-        qreal y = drawAbove ? rect.top() : rect.bottom();
-        qreal yOffset = SelfAssociationMinimumHeight;
-        if (drawAbove) {
-            yOffset *= -1.0;
-        }
-
-        setPoint(0, QPointF(l, y));
-        setPoint(1, QPointF(l, y + yOffset));
-        setPoint(2, QPointF(r, y + yOffset));
-        setPoint(3, QPointF(r, y));
-    } else if (!m_associationWidget->isSelf() && count() < 2) {
-        setEndPoints(QPointF(), QPointF());
-    }
-}
-
-/**
- * This method creates, deletes symbols and collaboration lines based on
- * m_associationWidget->associationType().
- *
- * Call this method when associationType of m_associationWidget changes.
- */
-void AssociationLine::reconstructSymbols()
-{
-    switch( m_associationWidget->associationType() ) {
-        case Uml::AssociationType::State:
-        case Uml::AssociationType::Activity:
-        case Uml::AssociationType::Exception:
-        case Uml::AssociationType::UniAssociation:
-        case Uml::AssociationType::Dependency:
-            setStartSymbol(Symbol::None);
-            setEndSymbol(Symbol::OpenArrow);
-            removeSubsetSymbol();
-            removeCollaborationLine();
-            break;
-
-        case Uml::AssociationType::Relationship:
-            setStartSymbol(Symbol::None);
-            setEndSymbol(Symbol::CrowFeet);
-            removeSubsetSymbol();
-            removeCollaborationLine();
-            break;
-
-        case Uml::AssociationType::Generalization:
-        case Uml::AssociationType::Realization:
-            setStartSymbol(Symbol::None);
-            setEndSymbol(Symbol::ClosedArrow);
-            removeSubsetSymbol();
-            removeCollaborationLine();
-            break;
-
-        case Uml::AssociationType::Composition:
-        case Uml::AssociationType::Aggregation:
-            setStartSymbol(Symbol::Diamond);
-            setEndSymbol(Symbol::None);
-            removeSubsetSymbol();
-            removeCollaborationLine();
-            break;
-
-        case Uml::AssociationType::Containment:
-            setStartSymbol(Symbol::Circle);
-            setEndSymbol(Symbol::None);
-            removeSubsetSymbol();
-            removeCollaborationLine();
-            break;
-
-        case Uml::AssociationType::Child2Category:
-            setStartSymbol(Symbol::None);
-            setEndSymbol(Symbol::None);
-            createSubsetSymbol();
-            removeCollaborationLine();
-            break;
-
-        case Uml::AssociationType::Coll_Message_Synchronous:
-        case Uml::AssociationType::Coll_Message_Asynchronous:
-        case Uml::AssociationType::Coll_Message_Self:
-            setStartSymbol(Symbol::None);
-            setEndSymbol(Symbol::None);
-            removeSubsetSymbol();
-            createCollaborationLine();
-            break;
-
-        default:
-            break;
-    }
-    alignSymbols();
-}
-
-/**
- * Sets the Symbol to appear at the first line segment to \a symbol.
- *
- * If symbol == Symbol::None , then it deletes the symbol item.
- */
-void AssociationLine::setStartSymbol(Symbol::SymbolType symbolType)
-{
-    Q_ASSERT(symbolType != Symbol::Count);
-    if (symbolType == Symbol::None) {
-        delete m_startSymbol;
-        m_startSymbol = 0;
-        return;
-    }
-
-    if (m_startSymbol) {
-        m_startSymbol->setSymbolType(symbolType);
-    }
-    else {
-        m_startSymbol = new Symbol(symbolType, m_associationWidget);
-    }
-    m_startSymbol->setPen(pen());
-    m_startSymbol->setBrush(brush());
-}
-
-/**
- * Sets the Symbol to appear at the last line segment to \a symbol.
- *
- * If symbol == Symbol::None , then it deletes the symbol item.
- */
-void AssociationLine::setEndSymbol(Symbol::SymbolType symbolType)
-{
-    Q_ASSERT(symbolType != Symbol::Count);
-    if (symbolType == Symbol::None) {
-        delete m_endSymbol;
-        m_endSymbol = 0;
-        return;
-    }
-
-    if (m_endSymbol) {
-        m_endSymbol->setSymbolType(symbolType);
-    }
-    else {
-        m_endSymbol = new Symbol(symbolType, m_associationWidget);
-    }
-    m_endSymbol->setPen(pen());
-    m_endSymbol->setBrush(brush());
-}
-
-/**
- * Constructs a new subset symbol.
- */
-void AssociationLine::createSubsetSymbol()
-{
-    delete m_subsetSymbol; // recreate
-    m_subsetSymbol = new Symbol(Symbol::Subset, m_associationWidget);
-    m_subsetSymbol->setPen(pen());
-    m_subsetSymbol->setBrush(brush());
-}
-
-/**
- * Removes the subset symbol if it existed by deleting appropriate items.
- */
-void AssociationLine::removeSubsetSymbol()
-{
-    delete m_subsetSymbol;
-    m_subsetSymbol = 0;
-}
-
-/**
- * Constructs the open arrow symbol and arrow line, that would represent Collaboration line.
- */
-void AssociationLine::createCollaborationLine()
-{
-    const QPen p = pen();
-
-    // recreate
-    delete m_collaborationLineItem;
-    delete m_collaborationLineHead;
-
-    m_collaborationLineItem = new QGraphicsLineItem(m_associationWidget);
-    m_collaborationLineItem->setPen(p);
-
-    if (m_associationWidget->associationType() == Uml::AssociationType::Coll_Message_Synchronous) {
-        m_collaborationLineHead = new Symbol(Symbol::ClosedArrow, m_associationWidget);
-        m_collaborationLineHead->setBrush(p.color());
-    }
-    else
-        m_collaborationLineHead = new Symbol(Symbol::OpenArrow, m_associationWidget);
-    m_collaborationLineHead->setPen(p);
-}
-
-/**
- * Removes collaboration line by deleting the head and line item.
- */
-void AssociationLine::removeCollaborationLine()
-{
-    delete m_collaborationLineItem;
-    m_collaborationLineItem = 0;
-
-    delete m_collaborationLineHead;
-    m_collaborationLineHead = 0;
-}
-
-/**
- * This method aligns both the \b "start" and \b "end" symbols to
- * the current angles of the \b "first" and the \b "last" line
- * segment respectively.
- */
-void AssociationLine::alignSymbols()
-{
-    const int sz = m_points.size();
-    if (sz < 2) {
-        // cannot align if there is no line (one line = 2 points)
-        return;
-    }
-
-    QList<QPolygonF> polygons = path().toSubpathPolygons();
-
-    if (m_startSymbol) {
-        QPolygonF firstLine = polygons.first();
-        QLineF segment(firstLine.at(1), firstLine.at(0));
-        m_startSymbol->alignTo(segment);
-    }
-
-    if (m_endSymbol) {
-        QPolygonF lastLine = polygons.last();
-        int maxIndex = lastLine.size();
-        QLineF segment(lastLine.at(maxIndex-2), lastLine.at(maxIndex-1));
-        m_endSymbol->alignTo(segment);
-    }
-
-    if (m_subsetSymbol) {
-        QPointF p1 = path().pointAtPercent(0.4);
-        QPointF p2 = path().pointAtPercent(0.5);
-        QLineF segment(p1, p2);
-        m_subsetSymbol->alignTo(segment);
-    }
-
-    if (m_collaborationLineItem) {
-        const qreal distance = 10;
-        const int midSegmentIndex = (sz - 1) / 2;
-
-        const QPointF a = m_points.at(midSegmentIndex);
-        const QPointF b = m_points.at(midSegmentIndex + 1);
-
-        if (a == b)
-            return;
-
-        const QPointF p1 = (a + b) / 2.0;
-        const QPointF p2 = (p1 + b) / 2.0;
-
-        // Reversed line as we want normal in opposite direction.
-        QLineF segment(p2, p1);
-        QLineF normal = segment.normalVector().unitVector();
-        normal.setLength(distance);
-
-        QLineF actualLine;
-        actualLine.setP2(normal.p2());
-
-        normal.translate(p1 - p2);
-        actualLine.setP1(normal.p2());
-
-        m_collaborationLineItem->setLine(actualLine);
-        m_collaborationLineHead->alignTo(actualLine);
-    }
-}
-
-/**
- * @return The path of the AssociationLine.
- */
-QPainterPath AssociationLine::path() const
-{
-    if (m_points.count() > 0) {
-        QPainterPath path;
-        switch (m_layout) {
-        case Direct:
-            path.moveTo(m_points.first());
-            path.lineTo(m_points.last());
-            break;
-
-        case Spline:
-            path = createBezierCurve(m_points);
-            break;
-
-        case Orthogonal:
-            path = createOrthogonalPath(m_points);
-            break;
-
-        case Polyline:
-        default:
-            QPolygonF polygon(m_points);
-            path.addPolygon(polygon);
-            break;
-        }
-        return path;
-    }
-    else {
-        return QPainterPath();
-    }
-}
-
-/**
- * The points are used for the bounding rect. The reason is,
- * that for splines the control points are further away from the path.
- * @return The bounding rectangle for the AssociationLine.
- */
-QRectF AssociationLine::boundingRect() const
-{
-    QPolygonF polygon(m_points);
-    QRectF rect = polygon.boundingRect();
-    const qreal margin(5.0);
-    rect.adjust(-margin, -margin, margin, margin);
-    return rect;
-}
-
-/**
- * @return The shape of the AssociationLine.
- */
-QPainterPath AssociationLine::shape() const
-{
-    QPainterPathStroker stroker;
-    stroker.setWidth(qMax<qreal>(2*SelectedPointDiameter, pen().widthF()) + 2.0);  // allow delta region
-    stroker.setCapStyle(Qt::FlatCap);
-    return stroker.createStroke(path());
-}
-
-/**
- * Convert enum LayoutType to string.
- */
-QString AssociationLine::toString(LayoutType layout)
-{
-    return QLatin1String(ENUM_NAME(AssociationLine, LayoutType, layout));
-}
-
-/**
- * Convert string to enum LayoutType.
- */
-AssociationLine::LayoutType AssociationLine::fromString(const QString &layout)
-{
-    if (layout == QLatin1String("Direct"))
-        return Direct;
-    if (layout == QLatin1String("Spline"))
-        return Spline;
-    if (layout == QLatin1String("Orthogonal"))
-        return Orthogonal;
-    return Polyline;
-}
-
-/**
- * Return the layout type of the association line.
- * @return   the currently used layout
- */
-AssociationLine::LayoutType AssociationLine::layout() const
-{
-    return m_layout;
-}
-
-/**
- * Set the layout type of the association line.
- * @param layout   the desired layout to set
- */
-void AssociationLine::setLayout(LayoutType layout)
-{
-    prepareGeometryChange();
-    m_layout = layout;
-    DEBUG(DBG_SRC) << "new layout = " << toString(m_layout);
-    if (m_layout == Spline) {
-        createSplinePoints();
-    }
-    alignSymbols();
-}
-
-/**
- * For a cubic Bezier curve at least four points are needed.
- * If there are less, the missing points will be created.
- * Note: Implementation is only for two points.
- */
-void AssociationLine::createSplinePoints()
-{
-    if (m_points.size() == 2) {  // create two points
-        QPointF p1 = m_points.first();  // start point
-        QPointF p2 = m_points.last();   // end point
-        qreal dx = p2.x() - p1.x();
-        qreal dy = p2.y() - p1.y();
-        qreal oneThirdX = 0.33 * dx;
-        qreal oneThirdY = 0.33 * dy;
-        QPointF c1(p1.x() + oneThirdX,  // control point 1
-                   p1.y() - oneThirdY);
-        QPointF c2(p2.x() - oneThirdX,  // control point 2
-                   p2.y() + oneThirdY);
-        insertPoint(1, c1);
-        insertPoint(2, c2);
-    }
-    if (m_points.size() == 3) {  // create one point
-        // insertPoint(1 or 2, );
-        // Note: For now we use a quadratic Bezier curve in createBezierCurve(...).
-    }
-}
-
-/**
- * Returns a Bézier path from given points.
- * @param points   points which define the Bézier curve
- * @return   cubic Bézier spline
- */
-QPainterPath AssociationLine::createBezierCurve(QVector<QPointF> points)
-{
-    QPainterPath path;
-    if (points.size() > 3) {  // cubic Bezier curve(s)
-        path.moveTo(points.at(0));
-        int i = 1;
-        while (i + 2 < points.size()) {
-            path.cubicTo(points.at(i), points.at(i+1), points.at(i+2));
-            i += 3;
-        }
-        while (i < points.size()) {  // draw a line if points are not modulo 3
-            path.lineTo(points.at(i));
-            ++i;
-        }
-    }
-    else {
-        if (points.size() == 3) {  // quadratic Bezier curve
-            path.moveTo(points.at(0));
-            path.quadTo(points.at(1), points.at(2));
-        }
-        else {  // should not be reached
-            QPolygonF polygon(points);
-            path.addPolygon(polygon);
-        }
-    }
-    return path;
-}
-
-/**
- * Returns an orthogonal path constructed of vertical and horizontal segments
- * through the given points.
- * @param points   base points for the path
- * @return   orthogonal path
- */
-QPainterPath AssociationLine::createOrthogonalPath(QVector<QPointF> points)
-{
-    QPainterPath path;
-    if (points.size() > 1) {
-        QPointF start  = points.first();
-        QPointF end    = points.last();
-        qreal deltaX = fabs(start.x() - end.x());
-        qreal deltaY = fabs(start.y() - end.y());
-        // DEBUG("AssociationLine") << "start=" << start << " / end=" << end
-        //               << " / deltaX=" << deltaX << " / deltaY=" << deltaY;
-        QVector<QPointF> vector;
-        for (int i = 0; i < points.size() - 1; ++i) {
-            QPointF curr = points.at(i);
-            QPointF next = points.at(i+1);
-            QPointF center = (next + curr)/2.0;
-
-            vector.append(curr);
-            if (deltaX < deltaY) {
-                // go vertical first
-                vector.append(QPointF(curr.x(), center.y()));
-                vector.append(QPointF(next.x(), center.y()));
-            }
-            else {
-                // go horizontal first
-                vector.append(QPointF(center.x(), curr.y()));
-                vector.append(QPointF(center.x(), next.y()));
-            }
-            vector.append(next);
-        }
-
-        QPolygonF rectLine(vector);
-        path.addPolygon(rectLine);
-    }
-    else {
-        QPolygonF polygon(points);
-        path.addPolygon(polygon);
-    }
-    return path;
-}
-
-/**
- * Reimplemented from QGraphicsItem::paint.
- * Draws the AssociationLine and also takes care of highlighting active point or line.
- */
-void AssociationLine::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
-{
-    Q_UNUSED(widget)
-    QPen _pen = pen();
-    const QColor orig = _pen.color().lighter();
-    QColor invertedColor(orig.green(), orig.blue(), orig.red());
-    if (invertedColor == _pen.color()) {
-        // Ensure different color.
-        invertedColor.setRed((invertedColor.red() + 50) % 256);
-    }
-    invertedColor.setAlpha(150);
-
-    int sz = m_points.size();
-    if (sz < 1) {
-        // not enough points - do nothing
-        return;
-    }
-
-    QPointF savedStart = m_points.first();
-    QPointF savedEnd = m_points.last();
-
-    // modify the m_points array not to include the Symbol, the value depends on Symbol
-    if (m_startSymbol) {
-        QPointF newStart = m_startSymbol->mapToParent(m_startSymbol->symbolEndPoints().first);
-        m_points[0] = newStart;
-    }
-
-    if (m_endSymbol) {
-        QPointF newEnd = m_endSymbol->mapToParent(m_endSymbol->symbolEndPoints().first);
-        m_points[sz - 1] = newEnd;
-    }
-
-    painter->setPen(_pen);
-    painter->setBrush(Qt::NoBrush);
-    painter->drawPath(path());
-
-    if (option->state & QStyle::State_Selected) {
-        // make the association broader in the selected state
-        QPainterPathStroker stroker;
-        stroker.setWidth(3.0);
-        QPainterPath outline = stroker.createStroke(path());
-        QColor shadowColor(Qt::lightGray);
-        shadowColor.setAlpha(80);
-        QBrush shadowBrush(shadowColor);
-        painter->setBrush(shadowBrush);
-        painter->setPen(Qt::NoPen);
-        painter->drawPath(outline);
-
-        // set color for selected painting
-        _pen.setColor(Qt::blue);
-        QRectF circle(0, 0, SelectedPointDiameter, SelectedPointDiameter);
-        painter->setBrush(_pen.color());
-        painter->setPen(Qt::NoPen);
-
-        // draw points
-        circle.moveCenter(savedStart);
-        painter->drawRect(circle);
-        for (int i = 1; i < sz-1; ++i) {
-            if (i != m_activePointIndex) {
-                circle.moveCenter(m_points.at(i));
-                painter->drawRect(circle);
-            }
-        }
-        circle.moveCenter(savedEnd);
-        painter->drawRect(circle);
-
-        if (m_activePointIndex != -1) {
-            painter->setBrush(invertedColor);
-            painter->setPen(Qt::NoPen);
-            circle.setWidth(1.5*SelectedPointDiameter);
-            circle.setHeight(1.5*SelectedPointDiameter);
-            circle.moveCenter(m_points.at(m_activePointIndex));
-            painter->drawEllipse(circle);
-        }
-        else if (m_activeSegmentIndex != -1) {
-            if (m_layout == Polyline) {
-                painter->setPen(QPen(invertedColor, _pen.widthF() + 1));
-                painter->setBrush(Qt::NoBrush);
-
-                QLineF segmentLine(m_points[m_activeSegmentIndex], m_points[m_activeSegmentIndex + 1]);
-                painter->drawLine(segmentLine);
-            }
-        }
-        // debug info
-        if (Tracer::instance()->isEnabled(QString::fromLatin1(metaObject()->className()))) {
-            painter->setPen(Qt::green);
-            painter->setBrush(Qt::NoBrush);
-            painter->drawPath(shape());
-            painter->setPen(Qt::red);
-            painter->drawRect(boundingRect());
-            // origin
-            painter->drawLine(-10, 0, 10, 0);
-            painter->drawLine(0, -10, 0, 10);
-        }
-
-    }
-
-    // now restore the points array
-    m_points[0] = savedStart;
-    m_points[sz - 1] = savedEnd;
-}
-
-/**
- * Determines the active point or segment, the latter being given more priority.
- */
-void AssociationLine::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
-    DEBUG(DBG_SRC) << "at " << event->scenePos();
-    if (event->buttons() & Qt::LeftButton) {
-        m_activePointIndex = closestPointIndex(event->scenePos());
-        if (m_activePointIndex != -1 && isEndPointIndex(m_activePointIndex)) {
-            // end points are not drawn and hence not active
-            m_activePointIndex = -1;
-        }
-        // calculate only if active point index is -1
-        m_activeSegmentIndex = (m_activePointIndex != -1) ? -1 : closestSegmentIndex(event->scenePos());
-    }
-    else if (event->buttons() & Qt::RightButton) {
-        DEBUG(DBG_SRC) << "call context menu of association widget at " << event->scenePos();
-    }
-    else {
-        m_activePointIndex   = -1;
-        m_activeSegmentIndex = -1;
-    }
-}
-
-/**
- * Moves the point or line if active.
- */
-void AssociationLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
-    UMLScene* scene = m_associationWidget->umlScene();
-
-    QPointF oldPos = event->scenePos();
-    QPointF newPos(
-        scene->snappedX(oldPos.x()),
-        scene->snappedY(oldPos.y())
-    );
-
-    // Prevent the moving vertex from disappearing underneath a widget
-    // (else there's no way to get it back.)
-    UMLWidget *onW = scene->widgetAt(newPos);
-    if (onW && onW->baseType() != WidgetBase::wt_Box) {  // boxes are transparent
-        const qreal pX = newPos.x();
-        const qreal pY = newPos.y();
-        const qreal wX = onW->x();
-        const qreal wY = onW->y();
-        const qreal wWidth = onW->width();
-        const qreal wHeight = onW->height();
-        if (pX > wX && pX < wX + wWidth) {
-            const qreal midX = wX + wWidth / 2.0;
-            if (pX <= midX)
-                newPos.setX(wX);
-            else
-                newPos.setX(wX + wWidth);
-        }
-        if (pY > wY && pY < wY + wHeight) {
-            const qreal midY = wY + wHeight / 2.0;
-            if (pY <= midY)
-                newPos.setY(wY);
-            else
-                newPos.setY(wY + wHeight);
-        }
-    }
-
-    if (m_activePointIndex != -1) {
-        // Move a single point (snap behaviour)
-        setPoint(m_activePointIndex, newPos);
-    }
-    else if (m_activeSegmentIndex != -1 && !isEndSegmentIndex(m_activeSegmentIndex)) {
-        // Move a segment (between two points, snap behaviour not implemented)
-        QPointF delta = event->scenePos() - event->lastScenePos();
-        setPoint(m_activeSegmentIndex, m_points[m_activeSegmentIndex] + delta);
-        setPoint(m_activeSegmentIndex + 1, m_points[m_activeSegmentIndex + 1] + delta);
-    }
-}
-
-/**
- * Reset active indices and also push undo command.
- */
-void AssociationLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
-    if (event->buttons() & Qt::LeftButton) {
-        m_activeSegmentIndex = -1;
-        m_activePointIndex   = -1;
-    }
-}
-
-/**
- * Calculates the "to be highlighted" point and segment indicies
- * and updates if necessary.
- */
-void AssociationLine::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
-{
-    DEBUG(DBG_SRC) << "at " << event->scenePos();
-    int oldPointIndex = m_activePointIndex;
-    int oldSegmentIndex = m_activeSegmentIndex;
-
-    m_activePointIndex = closestPointIndex(event->scenePos());
-    // End points are not drawn and hence not active.
-    if (m_activePointIndex != -1 && isEndPointIndex(m_activePointIndex)) {
-        m_activePointIndex = -1;
-    }
-    // Activate segment index only if point index is -1
-    m_activeSegmentIndex = (m_activePointIndex != -1) ? -1 : closestSegmentIndex(event->scenePos());
-
-    bool isChanged = (oldSegmentIndex != m_activeSegmentIndex || oldPointIndex != m_activePointIndex);
-    if (isChanged) {
-        m_associationWidget->update();
-    }
-}
-
-/**
- * Calculates the "to be highlighted" point and segment indicies
- * and updates if necessary.
- */
-void AssociationLine::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
-    int oldPointIndex = m_activePointIndex;
-    int oldSegmentIndex = m_activeSegmentIndex;
-
-    m_activePointIndex = closestPointIndex(event->scenePos());
-    // End points are not drawn and hence not active.
-    if (m_activePointIndex != -1 && isEndPointIndex(m_activePointIndex)) {
-        m_activePointIndex = -1;
-    }
-    // Activate segment index only if point index is -1
-    m_activeSegmentIndex = (m_activePointIndex != -1) ? -1 : closestSegmentIndex(event->scenePos());
-
-    bool isChanged = (oldSegmentIndex != m_activeSegmentIndex || oldPointIndex != m_activePointIndex);
-    if (isChanged) {
-        m_associationWidget->update();
-    }
-}
-
-/**
- * Reset active indicies and updates.
- */
-void AssociationLine::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
-    DEBUG(DBG_SRC) << "at " << event->scenePos();
-    //Q_UNUSED(event)
-    m_activePointIndex   = -1;
-    m_activeSegmentIndex = -1;
-    m_associationWidget->update();
-}
-
-//-----------------------------------------------------------------------------
-
-/**
- * SymbolEndPoints:
- * The first point is where the AssociationLine's visible line is
- * supposed to end.
- * The second points is where the actual symbol part is to appear.
- */
-Symbol::SymbolProperty Symbol::symbolTable[Count] =
-{
-    {
-        QRectF(-6, 0, 12, 10), QPainterPath(), QLineF(0, 0, 0, 10),
-        SymbolEndPoints(QPointF(0, 10), QPointF(0, 10))
-    },
-    {
-        QRectF(-6, 0, 12, 10), QPainterPath(), QLineF(0, 0, 0, 10),
-        SymbolEndPoints(QPointF(0, 0), QPointF(0, 10))
-    },
-    {
-        QRectF(-6, 0, 12, 10), QPainterPath(), QLineF(0, 0, 0, 10),
-        SymbolEndPoints(QPointF(0, 10), QPointF(0, 10))
-    },
-    {
-        QRectF(-5, -10, 10, 20), QPainterPath(), QLineF(0, -10, 0, 10),
-        SymbolEndPoints(QPointF(0, -10), QPointF(0, 10))
-    },
-    {
-        QRectF(-15, -10, 30, 20), QPainterPath(), QLineF(-10, 0, 0, 0),
-        SymbolEndPoints(QPointF(0, 0), QPointF(0, 0))
-    },
-    {
-        QRectF(-8, -8, 16, 16), QPainterPath(), QLineF(0, -8, 0, 8),
-        SymbolEndPoints(QPointF(0, -8), QPointF(0, 8))
-    }
-
-};
-
-/**
- * @internal A convenience method to setup shapes of all symbols.
- */
-void Symbol::setupSymbolTable()
-{
-    SymbolProperty &openArrow = symbolTable[OpenArrow];
-    if (openArrow.shape.isEmpty()) {
-        QRectF rect = openArrow.boundRect;
-        // Defines a 'V' shape arrow fitting in the bound rect.
-        openArrow.shape.moveTo(rect.topLeft());
-        openArrow.shape.lineTo(rect.center().x(), rect.bottom());
-        openArrow.shape.lineTo(rect.topRight());
-    }
-
-    SymbolProperty &closedArrow = symbolTable[ClosedArrow];
-    if (closedArrow.shape.isEmpty()) {
-        QRectF rect = closedArrow.boundRect;
-        // Defines a 'V' shape arrow fitting in the bound rect.
-        closedArrow.shape.moveTo(rect.topLeft());
-        closedArrow.shape.lineTo(rect.center().x(), rect.bottom());
-        closedArrow.shape.lineTo(rect.topRight());
-        closedArrow.shape.lineTo(rect.topLeft());
-    }
-
-    SymbolProperty &crowFeet = symbolTable[CrowFeet];
-    if (crowFeet.shape.isEmpty()) {
-        QRectF rect = crowFeet.boundRect;
-        // Defines a crowFeet fitting in the bound rect.
-        QPointF topMid(rect.center().x(), rect.top());
-
-        // left leg
-        crowFeet.shape.moveTo(rect.bottomLeft());
-        crowFeet.shape.lineTo(topMid);
-
-        // middle leg
-        crowFeet.shape.moveTo(rect.center().x(), rect.bottom());
-        crowFeet.shape.lineTo(topMid);
-
-        // right leg
-        crowFeet.shape.moveTo(rect.bottomRight());
-        crowFeet.shape.lineTo(topMid);
-    }
-
-    SymbolProperty &diamond = symbolTable[Diamond];
-    if (diamond.shape.isEmpty()) {
-        QRectF rect = diamond.boundRect;
-        // Defines a 'diamond' shape fitting in the bound rect.
-        diamond.shape.moveTo(rect.center().x(), rect.top());
-        diamond.shape.lineTo(rect.left(), rect.center().y());
-        diamond.shape.lineTo(rect.center().x(), rect.bottom());
-        diamond.shape.lineTo(rect.right(), rect.center().y());
-        diamond.shape.lineTo(rect.center().x(), rect.top());
-    }
-
-    SymbolProperty &subset = symbolTable[Subset];
-    if (subset.shape.isEmpty()) {
-        QRectF rect = subset.boundRect;
-        // Defines an arc fitting in bound rect.
-        qreal start = 90, span = 180;
-        subset.shape.arcMoveTo(rect, start);
-        subset.shape.arcTo(rect, start, span);
-    }
-
-    SymbolProperty &circle = symbolTable[Circle];
-    if (circle.shape.isEmpty()) {
-        QRectF rect = circle.boundRect;
-        // Defines a circle with a horizontal-vertical cross lines.
-        circle.shape.addEllipse(rect);
-
-        circle.shape.moveTo(rect.center().x(), rect.top());
-        circle.shape.lineTo(rect.center().x(), rect.bottom());
-
-        circle.shape.moveTo(rect.left(), rect.center().y());
-        circle.shape.lineTo(rect.right(), rect.center().y());
-    }
-
-}
-
-/**
- * Constructs a Symbol with current symbol being \a symbol and
- * parented to \a parent.
- */
-Symbol::Symbol(SymbolType symbolType, QGraphicsItem *parent)
-  : QGraphicsItem(parent),
-    m_symbolType(symbolType)
-{
-    // ensure SymbolTable is validly initialized
-    setupSymbolTable();
-}
-
-/**
- * Destructor.
- */
-Symbol::~Symbol()
-{
-}
-
-/**
- * @return The current symbol being represented.
- */
-Symbol::SymbolType Symbol::symbolType() const
-{
-    return m_symbolType;
-}
-
-/**
- * Sets the current symbol type to \a symbol and updates the geometry.
- */
-void Symbol::setSymbolType(SymbolType symbolType)
-{
-    prepareGeometryChange();  // calls update implicitly
-    m_symbolType = symbolType;
-}
-
-/**
- * Draws the current symbol using the QPainterPath stored for the current
- * symbol.
- */
-void Symbol::paint(QPainter *painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
-{
-    Q_UNUSED(option) Q_UNUSED(widget)
-    painter->setPen(m_pen);
-    switch (m_symbolType) {
-    case ClosedArrow:
-    case CrowFeet:
-    case Diamond:
-        painter->setBrush(m_brush);
-        break;
-    default:
-        break;
-    }
-    painter->drawPath(Symbol::symbolTable[m_symbolType].shape);
-}
-
-/**
- * @return The bound rectangle for this based on current symbol.
- */
-QRectF Symbol::boundingRect() const
-{
-    const qreal adj = .5 * m_pen.widthF();
-    return Symbol::symbolTable[m_symbolType].boundRect.
-        adjusted(-adj, -adj, adj, adj);
-}
-
-/**
- * @return The path for this based on current symbol.
- */
-QPainterPath Symbol::shape() const
-{
-    QPainterPath path;
-    path.addRect(boundingRect());
-    return path;
-}
-
-/**
- * This method aligns *this* Symbol to the line being
- * passed. That is, it ensures that the axis of this symbol aligns
- * exactly with the \a "to" line passed.
- *
- * Also this item is moved such that the second end point of the
- * SymbolEndPoints for the current symbol *collides* with the second end
- * point of \a "to" line.
- */
-void Symbol::alignTo(const QLineF& to)
-{
-    QLineF toMapped(mapFromParent(to.p1()), mapFromParent(to.p2()));
-
-    QLineF origAxis = Symbol::symbolTable[m_symbolType].axisLine;
-    QLineF translatedAxis = origAxis.translated(toMapped.p2() - origAxis.p2());
-
-    qreal angle = translatedAxis.angleTo(toMapped);
-    setRotation(rotation() - angle);
-
-    QPointF delta = to.p2() - mapToParent(symbolEndPoints().second);
-    moveBy(delta.x(), delta.y());
-}
-
-/**
- * @return The end points for the symbol.
- */
-Symbol::SymbolEndPoints Symbol::symbolEndPoints() const
-{
-    return Symbol::symbolTable[m_symbolType].endPoints;
-}
-
-/**
- * @return The pen used to draw symbol.
- */
-QPen Symbol::pen() const
-{
-    return m_pen;
-}
-
-/**
- * Sets the pen used to draw the symbol.
- */
-void Symbol::setPen(const QPen& pen)
-{
-    prepareGeometryChange();
-    m_pen = pen;
-    if (m_symbolType == ClosedArrow)
-        m_pen.setStyle(Qt::SolidLine);
-}
-
-/**
- * @return The brush used to fill symbol.
- */
-QBrush Symbol::brush() const
-{
-    return m_brush;
-}
-
-/**
- * Sets the brush used to fill symbol.
- */
-void Symbol::setBrush(const QBrush &brush)
-{
-    m_brush = brush;
-    update();
-}
-
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/associationline.h umbrello-15.08.1/umbrello/widgets/associationline.h
--- umbrello-15.08.1.orig/umbrello/widgets/associationline.h	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/associationline.h	1970-01-01 02:00:00.000000000 +0200
@@ -1,207 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-#ifndef ASSOCIATIONLINE_H
-#define ASSOCIATIONLINE_H
-
-#include "basictypes.h"
-
-#include <QGraphicsObject>
-#include <QList>
-#include <QPen>
-#include <QPoint>
-
-// forward declarations
-class AssociationWidget;
-class QDomDocument;
-class QDomElement;
-class QPainter;
-
-/**
- * This class provides with various symbols that can be embedded in
- * AssociationLine.  It also provides with convenience methods to align
- * the symbol to AssociationLine.
- */
-class Symbol : public QGraphicsItem
-{
-    public:
-        typedef QPair<QPointF, QPointF> SymbolEndPoints;
-
-        /**
-         * This enumeration lists all the symbols that can be used as
-         * embedded on AssociationLine.
-         */
-        enum SymbolType {
-            None = -1,
-            OpenArrow,
-            ClosedArrow,
-            CrowFeet,
-            Diamond,
-            Subset,
-            Circle,
-            Count
-        };
-
-        explicit Symbol(SymbolType symbolType, QGraphicsItem *parent = 0);
-        virtual ~Symbol();
-
-        SymbolType symbolType() const;
-        void setSymbolType(SymbolType symbolType);
-
-        virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
-        virtual QRectF boundingRect() const;
-        virtual QPainterPath shape() const;
-
-        void alignTo(const QLineF& line);
-        SymbolEndPoints symbolEndPoints() const;
-
-        QPen pen() const;
-        void setPen(const QPen &pen);
-
-        QBrush brush() const;
-        void setBrush(const QBrush& brush);
-
-    private:
-        QPen       m_pen;         ///< pen used to draw Symbol
-        QBrush     m_brush;       ///< brush used to fill Symbol
-        SymbolType m_symbolType;  ///< current symbol being represented by this item
-
-        /// A structure to hold a table of values for all symbols.
-        struct SymbolProperty {
-            QRectF boundRect;
-            QPainterPath shape;
-            QLineF axisLine;
-            SymbolEndPoints endPoints;
-        };
-
-        static SymbolProperty symbolTable[Symbol::Count];  ///< a table which stores all symbol properties
-        static void setupSymbolTable();
-};
-
-/**
- * A convenience class that encapsulates geometry management, handles
- * mouse and hover events, embeds and aligns symbols and finally draws the
- * lines and points.
- * Context menu events are handled in AssociationWidget.
- *
- * This class is infact a draw and event handling proxy for
- * AssociationWidget.
- *
- * @note m_activePointIndex and m_activeSegmentIndex can't be
- *       active at same time!
- *
- * @author Gopala Krishna
- * @author Andi Fischer
- * Bugs and comments to uml-devel@lists.sf.net or http://bugs.kde.org
- */
-class AssociationLine : public QGraphicsObject
-{
-    Q_OBJECT
-    Q_ENUMS(LayoutType)
-public:
-    enum LayoutType {
-        Direct = 1,
-        Orthogonal,
-        Polyline,
-        Spline
-    };
-
-    static QString toString(LayoutType layout);
-    static LayoutType fromString(const QString& layout);
-
-    explicit AssociationLine(AssociationWidget *association);
-    virtual ~AssociationLine();
-
-    QPointF point(int index) const;
-    bool setPoint(int index, const QPointF& point);
-    QPointF startPoint() const;
-    QPointF endPoint() const;
-
-    void insertPoint(int index, const QPointF& point);
-    void removePoint(int index);
-
-    int count() const;
-    void cleanup();
-
-    void optimizeLinePoints();
-
-    int closestPointIndex(const QPointF& point, qreal delta = Delta) const;
-    int closestSegmentIndex(const QPointF& point, qreal delta = Delta) const;
-
-    bool isEndPointIndex(int index) const;
-    bool isEndSegmentIndex(int index) const;
-
-    bool setEndPoints(const QPointF &start, const QPointF &end);
-
-    void dumpPoints();
-
-    bool loadFromXMI(QDomElement &qElement);
-    void saveToXMI(QDomDocument &qDoc, QDomElement &qElement);
-
-    QBrush brush() const;
-    QPen pen() const;
-
-    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
-
-    QPainterPath path() const;
-
-    QRectF boundingRect() const;
-    QPainterPath shape() const;
-
-    LayoutType layout() const;
-    void setLayout(LayoutType layout);
-
-    void mousePressEvent(QGraphicsSceneMouseEvent *event);
-    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
-    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
-
-    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
-    void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
-    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
-
-    void calculateInitialEndPoints();
-
-    void reconstructSymbols();
-
-private:
-    void setStartSymbol(Symbol::SymbolType symbolType);
-    void setEndSymbol(Symbol::SymbolType symbolType);
-
-    void createSubsetSymbol();
-    void removeSubsetSymbol();
-
-    void createCollaborationLine();
-    void removeCollaborationLine();
-
-    void alignSymbols();
-
-    void createSplinePoints();
-
-    AssociationWidget *m_associationWidget;      ///< association widget for which this line represents
-    QVector<QPointF>   m_points;                 ///< points representing the association line
-    int                m_activePointIndex;       ///< index of active point which can be dragged to modify association line
-    int                m_activeSegmentIndex;     ///< index of active segment
-    Symbol            *m_startSymbol;            ///< symbol drawn at the end of "first" line segment
-    Symbol            *m_endSymbol;              ///< symbol drawn at the end of "last" line segment
-    Symbol            *m_subsetSymbol;           ///< subset symbol
-    QGraphicsLineItem *m_collaborationLineItem;  ///< parallel arrow line drawn in case of collaboration message
-    Symbol            *m_collaborationLineHead;  ///< arrow head drawn at end of m_collaborationLineItem
-    LayoutType         m_layout;
-
-    static QPainterPath createBezierCurve(QVector<QPointF> points);
-    static QPainterPath createOrthogonalPath(QVector<QPointF> points);
-
-    static const qreal Delta;  ///< default delta for fuzzy recognition of points closer to point
-    static const qreal SelectedPointDiameter;         ///< radius of circles drawn to show "selection"
-    static const qreal SelfAssociationMinimumHeight;  ///< minimum height for self association's loop
-};
-
-#endif
diff -Nuar umbrello-15.08.1.orig/umbrello/widgets/associationwidget.cpp umbrello-15.08.1/umbrello/widgets/associationwidget.cpp
--- umbrello-15.08.1.orig/umbrello/widgets/associationwidget.cpp	2015-09-10 01:54:59.000000000 +0300
+++ umbrello-15.08.1/umbrello/widgets/associationwidget.cpp	1970-01-01 02:00:00.000000000 +0200
@@ -1,4407 +0,0 @@
-/***************************************************************************
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   copyright (C) 2002-2014                                               *
- *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
- ***************************************************************************/
-
-// own header
-#include "associationwidget.h"
-
-// app includes
-#include "association.h"
-#include "associationline.h"
-#include "associationpropertiesdialog.h"
-#include "assocrules.h"
-#include "attribute.h"
-#include "classifier.h"
-#include "classifierwidget.h"
-#include "debug_utils.h"
-#include "docwindow.h"
-#include "entity.h"
-#include "floatingtextwidget.h"
-#include "listpopupmenu.h"
-#include "messagewidget.h"
-#include "objectwidget.h"
-#include "operation.h"
-#include "optionstate.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umlscene.h"
-#include "umlview.h"
-#include "umlwidget.h"
-#include "widget_utils.h"
-
-// kde includes
-#if QT_VERSION < 0x050000
-#include <kcolordialog.h>
-#include <kfontdialog.h>
-#include <kinputdialog.h>
-#endif
-#include <KLocalizedString>
-
-// qt includes
-#if QT_VERSION >= 0x050000
-#include <QColorDialog>
-#include <QFontDialog>
-#include <QInputDialog>
-#endif
-#include <QPainterPath>
-#include <QPointer>
-#include <QRegExpValidator>
-#include <QApplication>
-
-// system includes
-#include <cmath>
-
-#define DBG_AW() DEBUG(QLatin1String("AssociationWidget"))
-DEBUG_REGISTER_DISABLED(AssociationWidget)
-
-using namespace Uml;
-
-/**
-  * Constructor is private because the static create() methods shall
-  * be used for constructing AssociationWidgets.
-  *
-  * @param scene   The parent view of this widget.
-  */
-AssociationWidget::AssociationWidget(UMLScene *scene)
-  : WidgetBase(scene, WidgetBase::wt_Association),
-    m_positions_len(0),
-    m_activated(false),
-    m_unNameLineSegment(-1),
-    m_nLinePathSegmentIndex(-1),
-    m_pAssocClassLine(0),
-    m_pAssocClassLineSel0(0),
-    m_pAssocClassLineSel1(0),
-    m_associationLine(new AssociationLine(this)),
-    m_associationClass(0),
-    m_associationType(Uml::AssociationType::Association),
-    m_nameWidget(0)
-{
-    // floating text widgets objects owned by this association
-    m_role[RoleType::A].changeabilityWidget = 0;
-    m_role[RoleType::B].changeabilityWidget = 0;
-    m_role[RoleType::A].multiplicityWidget = 0;
-    m_role[RoleType::B].multiplicityWidget = 0;
-    m_role[RoleType::A].roleWidget = 0;
-    m_role[RoleType::B].roleWidget = 0;
-    m_role[RoleType::A].umlWidget = 0;
-    m_role[RoleType::B].umlWidget = 0;
-
-    // associationwidget attributes
-    m_role[RoleType::A].m_WidgetRegion = Uml::Region::Error;
-    m_role[RoleType::B].m_WidgetRegion = Uml::Region::Error;
-    m_role[RoleType::A].m_nIndex = 0;
-    m_role[RoleType::B].m_nIndex = 0;
-    m_role[RoleType::A].m_nTotalCount = 0;
-    m_role[RoleType::B].m_nTotalCount = 0;
-    m_role[RoleType::A].visibility = Uml::Visibility::Public;
-    m_role[RoleType::B].visibility = Uml::Visibility::Public;
-    m_role[RoleType::A].changeability = Uml::Changeability::Changeable;
-    m_role[RoleType::B].changeability = Uml::Changeability::Changeable;
-
-    setFlag(QGraphicsLineItem::ItemIsSelectable);
-    setAcceptHoverEvents(true);
-}
-
-/**
- * This constructor is really only for loading from XMI, otherwise it
- * should not be allowed as it creates an incomplete associationwidget.
-  *
-  * @param scene   The parent view of this widget.
- */
-AssociationWidget* AssociationWidget::create(UMLScene *scene)
-{
-    AssociationWidget* instance = new AssociationWidget(scene);
-    return instance;
-}
-
-/**
-  * Preferred constructor (static factory method.)
-  *
-  * @param scene      The parent view of this widget.
-  * @param pWidgetA   Pointer to the role A widget for the association.
-  * @param assocType  The AssociationType::Enum for this association.
-  * @param pWidgetB   Pointer to the role B widget for the association.
-  * @param umlobject  Pointer to the underlying UMLObject (if applicable.)
-  */
-AssociationWidget* AssociationWidget::create
-                                    (UMLScene *scene, UMLWidget* pWidgetA,
-                                     Uml::AssociationType::Enum assocType, UMLWidget* pWidgetB,
-                                     UMLObject *umlobject /* = NULL */)
-{
-    AssociationWidget* instance = new AssociationWidget(scene);
-    if (umlobject) {
-        instance->setUMLObject(umlobject);
-    } else {
-        // set up UMLAssociation obj if assoc is represented and both roles are UML objects
-        if (Uml::AssociationType::hasUMLRepresentation(assocType)) {
-            UMLObject* umlRoleA = pWidgetA->umlObject();
-            UMLObject* umlRoleB = pWidgetB->umlObject();
-            if (umlRoleA != NULL && umlRoleB != NULL) {
-                bool swap;
-
-                // This is not correct. We could very easily have more than one
-                // of the same type of association between the same two objects.
-                // Just create the association. This search should have been
-                // done BEFORE creation of the widget, if it mattered to the code.
-                // But lets leave check in here for the time being so that debugging
-                // output is shown, in case there is a collision with code elsewhere.
-                UMLDoc *doc = UMLApp::app()->document();
-                UMLAssociation *myAssoc = doc->findAssociation(assocType, umlRoleA, umlRoleB, &swap);
-                if (myAssoc != NULL) {
-                    switch (assocType) {
-                        case Uml::AssociationType::Generalization:
-                        case Uml::AssociationType::Dependency:
-                        case Uml::AssociationType::Association_Self:
-                        case Uml::AssociationType::Coll_Message_Self:
-                        case Uml::AssociationType::Seq_Message_Self:
-                        case Uml::AssociationType::Containment:
-                        case Uml::AssociationType::Realization:
-                            DBG_AW() << "Ignoring second construction of same assoctype "
-                                     << assocType << " between " << umlRoleA->name()
-                                     << " and " << umlRoleB->name();
-                            break;
-                        default:
-                            DBG_AW() << "constructing a similar or exact same assoctype "
-                                     << assocType << " between " << umlRoleA->name() << " and "
-                                     << umlRoleB->name() << "as an already existing assoc (swap="
-                                     << swap << ")";
-                            // now, just create a new association anyways
-                            myAssoc = NULL;
-                            break;
-                    }
-                }
-                if (myAssoc == NULL) {
-                    myAssoc = new UMLAssociation(assocType, umlRoleA, umlRoleB);
-                    // CHECK: myAssoc is not yet inserted at any parent UMLPackage -
-                    // need to check carefully that all callers do this, lest it be
-                    // orphaned.
-                    // ToolBarStateAssociation::addAssociationInViewAndDoc() is
-                    // okay in this regard.
-                }
-                instance->setUMLAssociation(myAssoc);
-            }
-        }
-    }
-
-    instance->setWidgetForRole(pWidgetA, RoleType::A);
-    instance->setWidgetForRole(pWidgetB, RoleType::B);
-
-    instance->setAssociationType(assocType);
-
-    instance->calculateEndingPoints();
-
-    instance->associationLine()->calculateInitialEndPoints();
-    instance->associationLine()->reconstructSymbols();
-
-    //The AssociationWidget is set to Activated because it already has its side widgets
-    instance->setActivated(true);
-
-    // sync UML meta-data to settings here
-    instance->mergeAssociationDataIntoUMLRepresentation();
-
-    // Collaboration messages need a name label because it's that
-    // which lets operator== distinguish them, which in turn
-    // permits us to have more than one message between two objects.
-    if (instance->isCollaboration()) {
-        // Create a temporary name to bring on setName()
-        int collabID = instance->m_scene->generateCollaborationId();
-        instance->setName(QLatin1Char('m') + QString::number(collabID));
-    }
-
-    return instance;
-}
-
-/**
- * Destructor.
- */
-AssociationWidget::~AssociationWidget()
-{
-    delete m_associationLine;
-}
-
-/**
- * Overriding the method from WidgetBase because we need to do
- * something extra in case this AssociationWidget represents
- * an attribute of a classifier.
- */
-void AssociationWidget::setUMLObject(UMLObject *obj)
-{
-    WidgetBase::setUMLObject(obj);
-    if (obj == NULL)
-        return;
-    UMLClassifier *klass = NULL;
-    UMLAttribute *attr = NULL;
-    UMLEntity *ent = NULL;
-    const UMLObject::ObjectType ot = obj->baseType();
-    switch (ot) {
-        case UMLObject::ot_Association:
-            setUMLAssociation(dynamic_cast<UMLAssociation*>(obj));
-            break;
-        case UMLObject::ot_Operation:
-            setOperation(dynamic_cast<UMLOperation*>(obj));
-            break;
-        case UMLObject::ot_Attribute:
-            klass = static_cast<UMLClassifier*>(obj->parent());
-            connect(klass, SIGNAL(attributeRemoved(UMLClassifierListItem*)),
-                    this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
-            attr = static_cast<UMLAttribute*>(obj);
-            connect(attr, SIGNAL(attributeChanged()), this, SLOT(slotAttributeChanged()));
-            break;
-        case UMLObject::ot_EntityAttribute:
-            ent = static_cast<UMLEntity*>(obj->parent());
-            connect(ent, SIGNAL(entityAttributeRemoved(UMLClassifierListItem*)),
-                    this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
-            break;
-        case UMLObject::ot_ForeignKeyConstraint:
-            ent = static_cast<UMLEntity*>(obj->parent());
-            connect(ent, SIGNAL(entityConstraintRemoved(UMLClassifierListItem*)),
-                    this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
-            break;
-        default:
-            uError() << "cannot associate UMLObject of type " << UMLObject::toString(ot);
-            break;
-    }
-}
-
-/**
- * Set all 'owned' child widgets to this font.
- */
-void AssociationWidget::lwSetFont (QFont font)
-{
-    if (m_nameWidget) {
-        m_nameWidget->setFont(font);
-    }
-    if (m_role[RoleType::A].roleWidget) {
-        m_role[RoleType::A].roleWidget->setFont(font);
-    }
-    if (m_role[RoleType::B].roleWidget) {
-        m_role[RoleType::B].roleWidget->setFont(font);
-    }
-    if (m_role[RoleType::A].multiplicityWidget) {
-        m_role[RoleType::A].multiplicityWidget->setFont(font);
-    }
-    if (m_role[RoleType::B].multiplicityWidget) {
-        m_role[RoleType::B].multiplicityWidget->setFont(font);
-    }
-    if (m_role[RoleType::A].changeabilityWidget)
-        m_role[RoleType::A].changeabilityWidget->setFont(font);
-    if (m_role[RoleType::B].changeabilityWidget)
-        m_role[RoleType::B].changeabilityWidget->setFont(font);
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- * @todo Move to LinkWidget.
- */
-UMLClassifier *AssociationWidget::operationOwner()
-{
-    Uml::RoleType::Enum role = (isCollaboration() ? Uml::RoleType::B : Uml::RoleType::A);
-    UMLObject *o = widgetForRole(role)->umlObject();
-    if (!o) {
-        return 0;
-    }
-    UMLClassifier *c = dynamic_cast<UMLClassifier*>(o);
-    if (!c) {
-        uError() << "widgetForRole(" << role << ") is not a classifier";
-    }
-    return c;
-}
-
-/**
- * Implements operation from LinkWidget.
- * Motivated by FloatingTextWidget.
- */
-UMLOperation *AssociationWidget::operation()
-{
-    return dynamic_cast<UMLOperation*>(m_umlObject);
-}
-
-/**
- * Implements operation from LinkWidget.
- * Motivated by FloatingTextWidget.
- */
-void AssociationWidget::setOperation(UMLOperation *op)
-{
-    if (m_umlObject)
-        disconnect(m_umlObject, SIGNAL(modified()), m_nameWidget, SLOT(setMessageText()));
-    m_umlObject = op;
-    if (m_umlObject)
-        connect(m_umlObject, SIGNAL(modified()), m_nameWidget, SLOT(setMessageText()));
-    if (m_nameWidget)
-        m_nameWidget->setMessageText();
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- */
-QString AssociationWidget::customOpText()
-{
-    return name();
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- */
-void AssociationWidget::setCustomOpText(const QString &opText)
-{
-    setName(opText);
-}
-
-/**
- * Calls setTextPosition on all the labels.
- * Overrides operation from LinkWidget.
- */
-void AssociationWidget::resetTextPositions()
-{
-    if (m_role[RoleType::A].multiplicityWidget) {
-        setTextPosition(TextRole::MultiA);
-    }
-    if (m_role[RoleType::B].multiplicityWidget) {
-        setTextPosition(Uml::TextRole::MultiB);
-    }
-    if (m_role[RoleType::A].changeabilityWidget) {
-        setTextPosition(Uml::TextRole::ChangeA);
-    }
-    if (m_role[RoleType::B].changeabilityWidget) {
-        setTextPosition(Uml::TextRole::ChangeB);
-    }
-    if (m_nameWidget) {
-        setTextPosition(Uml::TextRole::Name);
-    }
-    if (m_role[RoleType::A].roleWidget) {
-        setTextPosition(Uml::TextRole::RoleAName);
-    }
-    if (m_role[RoleType::B].roleWidget) {
-        setTextPosition(Uml::TextRole::RoleBName);
-    }
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- *
- * @param ft   The text widget which to update.
- */
-void AssociationWidget::setMessageText(FloatingTextWidget *ft)
-{
-    if (isCollaboration()) {
-        ft->setSequenceNumber(m_SequenceNumber);
-        if (m_umlObject != NULL) {
-            ft->setText(operationText(m_scene));
-        } else {
-            ft->setText(name());
-        }
-    } else {
-        ft->setText(name());
-    }
-}
-
-/**
- * Sets the text of the given FloatingTextWidget.
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- */
-void AssociationWidget::setText(FloatingTextWidget *ft, const QString &text)
-{
-    Uml::TextRole::Enum role = ft->textRole();
-    switch (role) {
-        case Uml::TextRole::Name:
-            setName(text);
-            break;
-        case Uml::TextRole::RoleAName:
-            setRoleName(text, RoleType::A);
-            break;
-        case Uml::TextRole::RoleBName:
-            setRoleName(text, RoleType::B);
-            break;
-        case Uml::TextRole::MultiA:
-            setMultiplicity(text, RoleType::A);
-            break;
-        case Uml::TextRole::MultiB:
-            setMultiplicity(text, RoleType::B);
-            break;
-        default:
-            uWarning() << "Unhandled TextRole: " << Uml::TextRole::toString(role);
-            break;
-    }
-}
-
-/**
- * Shows the association properties dialog and updates the
- * corresponding texts if its execution is successful.
- */
-void AssociationWidget::showPropertiesDialog()
-{
-    UMLApp::app()->docWindow()->updateDocumentation();
-    QPointer<AssociationPropertiesDialog> dlg = new AssociationPropertiesDialog(static_cast<QWidget*>(m_scene->activeView()), this);
-    if (dlg->exec()) {
-        //rules built into these functions to stop updating incorrect values
-        setName(name());
-
-        setRoleName(roleName(RoleType::A), RoleType::A);
-        setRoleName(roleName(RoleType::B), RoleType::B);
-
-        setDocumentation(documentation());
-
-        setRoleDocumentation(roleDocumentation(RoleType::A), RoleType::A);
-        setRoleDocumentation(roleDocumentation(RoleType::B), RoleType::B);
-
-        setMultiplicity(multiplicity(RoleType::A), RoleType::A);
-        setMultiplicity(multiplicity(RoleType::B), RoleType::B);
-
-        setVisibility(visibility(RoleType::A), RoleType::A);
-        setVisibility(visibility(RoleType::B), RoleType::B);
-
-        setChangeability(changeability(RoleType::A), RoleType::A);
-        setChangeability(changeability(RoleType::B), RoleType::B);
-
-        UMLApp::app()->docWindow()->showDocumentation(this, true);
-    }
-    delete dlg;
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- *
- * @param op        Return this AssociationWidget's operation string.
- */
-QString AssociationWidget::lwOperationText()
-{
-    return name();
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- *
- * @return classifier
- */
-UMLClassifier* AssociationWidget::lwClassifier()
-{
-    UMLObject *o = widgetForRole(RoleType::B)->umlObject();
-    UMLClassifier *c = dynamic_cast<UMLClassifier*>(o);
-    return c;
-}
-
-/**
- * Overrides operation from LinkWidget.
- * Required by FloatingTextWidget.
- *
- * @param op       The new operation string to set.
- */
-void AssociationWidget::setOperationText(const QString &op)
-{
-    if (!op.isEmpty()) {
-        setName(op);
-    }
-}
-
-/**
- * Calculates the m_unNameLineSegment value according to the new
- * NameText topleft corner PT.
- * It iterates through all AssociationLine's segments and for each one
- * calculates the sum of PT's distance to the start point + PT's
- * distance to the end point. The segment with the smallest sum will
- * be the RoleTextSegment (if this segment moves then the RoleText
- * will move with it). It sets m_unNameLineSegment to the start point
- * of the chosen segment.
- *
- * Overrides operation from LinkWidget (i.e. this method is also
- * required by FloatingTextWidget.)
- */
-void AssociationWidget::calculateNameTextSegment()
-{
-    if (!m_nameWidget) {
-        return;
-    }
-    //changed to use the middle of the text
-    //i think this will give a better result.
-    //never know what sort of lines people come up with
-    //and text could be long to give a false reading
-    qreal xt = m_nameWidget->x();
-    qreal yt = m_nameWidget->y();
-    xt += m_nameWidget->width() / 2;
-    yt += m_nameWidget->height() / 2;
-    int size = m_associationLine->count();
-    //sum of length(PTP1) and length(PTP2)
-    qreal total_length = 0;
-    qreal smallest_length = 0;
-    for (int i = 0; i < size - 1; ++i) {
-        QPointF pi = m_associationLine->point( i );
-        QPointF pj = m_associationLine->point( i+1 );
-        qreal xtiDiff = xt - pi.x();
-        qreal xtjDiff = xt - pj.x();
-        qreal ytiDiff = yt - pi.y();
-        qreal ytjDiff = yt - pj.y();
-        total_length =  sqrt( double(xtiDiff * xtiDiff + ytiDiff * ytiDiff) )
-                        + sqrt( double(xtjDiff * xtjDiff + ytjDiff * ytjDiff) );
-        //this gives the closest point
-        if (total_length < smallest_length || i == 0) {
-            smallest_length = total_length;
-            m_unNameLineSegment = i;
-        }
-    }
-}
-
-/**
- * Returns the UMLAssociation representation of this object.
- *
- * @return  Pointer to the UMLAssociation that is represented by
- *          this AsociationWidget.
- */
-UMLAssociation* AssociationWidget::association() const
-{
-    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
-        return NULL;
-    return static_cast<UMLAssociation*>(m_umlObject);
-}
-
-/**
- * Returns the UMLAttribute representation of this object.
- *
- * @return  Pointer to the UMLAttribute that is represented by
- *          this AsociationWidget.
- */
-UMLAttribute* AssociationWidget::attribute() const
-{
-    if (m_umlObject == NULL)
-        return NULL;
-    UMLObject::ObjectType ot = m_umlObject->baseType();
-    if (ot != UMLObject::ot_Attribute && ot != UMLObject::ot_EntityAttribute)
-        return NULL;
-    return static_cast<UMLAttribute*>(m_umlObject);
-}
-
-#if 0  //:TODO:
-/**
- * Overrides the assignment operator.
- */
-AssociationWidget& AssociationWidget::operator=(const AssociationWidget& other)
-{
-    *m_associationLine = *other.m_associationLine;
-
-    if (other.m_nameWidget) {
-        m_nameWidget = new FloatingTextWidget(m_scene);
-        *m_nameWidget = *(other.m_nameWidget);
-    } else {
-        m_nameWidget = NULL;
-    }
-
-    for (unsigned r = (unsigned)A; r <= (unsigned)B; ++r) {
-        WidgetRole& lhs = m_role[r];
-        const WidgetRole& rhs = other.m_role[r];
-        lhs.m_nIndex = rhs.m_nIndex;
-        lhs.m_nTotalCount = rhs.m_nTotalCount;
-
-        if (rhs.multiplicityWidget) {
-            lhs.multiplicityWidget = new FloatingTextWidget(m_scene);
-            *(lhs.multiplicityWidget) = *(rhs.multiplicityWidget);
-        } else {
-            lhs.multiplicityWidget = NULL;
-        }
-
-        if (rhs.roleWidget) {
-            lhs.roleWidget = new FloatingTextWidget(m_scene);
-            *(lhs.roleWidget) = *(rhs.roleWidget);
-        } else {
-            lhs.roleWidget = NULL;
-        }
-
-        if (rhs.changeabilityWidget) {
-            lhs.changeabilityWidget = new FloatingTextWidget(m_scene);
-            *(lhs.changeabilityWidget) = *(rhs.changeabilityWidget);
-        } else {
-            lhs.changeabilityWidget = NULL;
-        }
-
-        lhs.umlWidget = rhs.umlWidget;
-        lhs.m_WidgetRegion = rhs.m_WidgetRegion;
-    }
-
-    m_activated = other.m_activated;
-    m_unNameLineSegment = other.m_unNameLineSegment;
-    m_pMenu = other.m_pMenu;
-    setUMLAssociation(other.association());
-    setSelected(other.isSelected());
-
-    return *this;
-}
-#endif  //:TODO:
-
-/**
- * Overrides the equality test operator.
- */
-bool AssociationWidget::operator==(const AssociationWidget& other) const
-{
-    if (this == &other)
-        return true;
-
-    // if no model representation exists, then the widgets are not equal
-    if (association() == NULL && other.association() == NULL)
-        return false;
-
-    if (!m_umlObject || !other.m_umlObject ) {
-        if (!other.m_umlObject && m_umlObject)
-            return false;
-        if (other.m_umlObject && !m_umlObject)
-            return false;
-
-    } else if (m_umlObject != other.m_umlObject)
-        return false;
-
-    if (associationType() != other.associationType())
-        return false;
-
-    if (widgetIDForRole(RoleType::A) != other.widgetIDForRole(RoleType::A))
-        return false;
-
-    if (widgetIDForRole(RoleType::B) != other.widgetIDForRole(RoleType::B))
-        return false;
-
-    if (widgetForRole(RoleType::A)->baseType() == WidgetBase::wt_Object &&
-            other.widgetForRole(RoleType::A)->baseType() == WidgetBase::wt_Object) {
-        ObjectWidget *ownA = static_cast<ObjectWidget*>(widgetForRole(RoleType::A));
-        ObjectWidget *otherA = static_cast<ObjectWidget*>(other.widgetForRole(RoleType::A));
-        if (ownA->localID() != otherA->localID())
-            return false;
-    }
-
-    if (widgetForRole(RoleType::B)->baseType() == WidgetBase::wt_Object &&
-            other.widgetForRole(RoleType::B)->baseType() == WidgetBase::wt_Object) {
-        ObjectWidget *ownB = static_cast<ObjectWidget*>(widgetForRole(RoleType::B));
-        ObjectWidget *otherB = static_cast<ObjectWidget*>(other.widgetForRole(RoleType::B));
-        if (ownB->localID() != otherB->localID())
-            return false;
-    }
-
-    // Two objects in a collaboration can have multiple messages between each other.
-    // Here we depend on the messages having names, and the names must be different.
-    // That is the reason why collaboration messages have strange initial names like
-    // "m29997" or similar.
-    return (name() == other.name());
-}
-
-/**
- * Overrides the != operator.
- */
-bool AssociationWidget::operator!=(AssociationWidget& other) const
-{
-    return !(*this == other);
-}
-
-/**
- * Returns a pointer to the association widget's line path.
- */
-AssociationLine* AssociationWidget::associationLine() const
-{
-    return m_associationLine;
-}
-
-/**
- * Activates the AssociationWidget after a load.
- *
- * @return  true for success
- */
-bool AssociationWidget::activate()
-{
-    if (m_umlObject == NULL &&
-        AssociationType::hasUMLRepresentation(m_associationType)) {
-        UMLObject *myObj = umlDoc()->findObjectById(m_nId);
-        if (myObj == NULL) {
-            uError() << "cannot find UMLObject " << Uml::ID::toString(m_nId);
-            return false;
-        } else {
-            const UMLObject::ObjectType ot = myObj->baseType();
-            if (ot == UMLObject::ot_Association) {
-                UMLAssociation * myAssoc = static_cast<UMLAssociation*>(myObj);
-                setUMLAssociation(myAssoc);
-            } else {
-                setUMLObject(myObj);
-                setAssociationType(m_associationType);
-            }
-        }
-    }
-
-    if (m_activated)
-        return true;
-
-    Uml::AssociationType::Enum type = associationType();
-
-    if (m_role[RoleType::A].umlWidget == NULL)
-        setWidgetForRole(m_scene->findWidget(widgetIDForRole(RoleType::A)), RoleType::A);
-    if (m_role[RoleType::B].umlWidget == NULL)
-        setWidgetForRole(m_scene->findWidget(widgetIDForRole(RoleType::B)), RoleType::B);
-
-    if (!m_role[RoleType::A].umlWidget || !m_role[RoleType::B].umlWidget) {
-        DEBUG(DBG_SRC) << "Cannot make association!";
-        return false;
-    }
-
-    calculateEndingPoints();
-
-    if (AssocRules::allowRole(type)) {
-        for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
-            WidgetRole& robj = m_role[r];
-            if (robj.roleWidget == NULL)
-                continue;
-            robj.roleWidget->setLink(this);
-            TextRole::Enum tr = (r == RoleType::A ? TextRole::RoleAName : TextRole::RoleBName);
-            robj.roleWidget->setTextRole(tr);
-            Uml::Visibility::Enum vis = visibility(Uml::RoleType::fromInt(r));
-            robj.roleWidget->setPreText(Uml::Visibility::toString(vis, true));
-
-            if (FloatingTextWidget::isTextValid(robj.roleWidget->text()))
-                robj.roleWidget->show();
-            else
-                robj.roleWidget->hide();
-            if (m_scene->type() == DiagramType::Collaboration)
-                robj.roleWidget->setUMLObject(robj.umlWidget->umlObject());
-            robj.roleWidget->activate();
-        }
-    }
-
-    if (m_nameWidget != NULL) {
-        m_nameWidget->setLink(this);
-        m_nameWidget->setTextRole(calculateNameType(TextRole::Name));
-
-        if (FloatingTextWidget::isTextValid(m_nameWidget->text())) {
-            m_nameWidget->show();
-        } else {
-            m_nameWidget->hide();
-        }
-        m_nameWidget->activate();
-        calculateNameTextSegment();
-    }
-
-    for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
-        WidgetRole& robj = m_role[r];
-
-        FloatingTextWidget* pMulti = robj.multiplicityWidget;
-        if (pMulti != NULL &&
-                AssocRules::allowMultiplicity(type, robj.umlWidget->baseType())) {
-            pMulti->setLink(this);
-            TextRole::Enum tr = (r == RoleType::A ? TextRole::MultiA : TextRole::MultiB);
-            pMulti->setTextRole(tr);
-            if (FloatingTextWidget::isTextValid(pMulti->text()))
-                pMulti->show();
-            else
-                pMulti->hide();
-            pMulti->activate();
-        }
-
-        FloatingTextWidget* pChangeWidget = robj.changeabilityWidget;
-        if (pChangeWidget != NULL) {
-            pChangeWidget->setLink(this);
-            TextRole::Enum tr = (r == RoleType::A ? TextRole::ChangeA : TextRole::ChangeB);
-            pChangeWidget->setTextRole(tr);
-            if (FloatingTextWidget::isTextValid(pChangeWidget->text()))
-                pChangeWidget->show();
-            else
-                pChangeWidget->hide ();
-            pChangeWidget->activate();
-        }
-    }
-
-    // Prepare the association class line if needed.
-    if (m_associationClass && !m_pAssocClassLine) {
-        createAssocClassLine();
-    }
-
-    m_activated = true;
-    return true;
-}
-
-/**
- * Set the widget of the given role.
- * Add this AssociationWidget at the widget.
- * If this AssociationWidget has an underlying UMLAssociation then set
- * the widget's underlying UMLObject at the UMLAssociation's role object.
- *
- * @param widget    Pointer to the UMLWidget.
- * @param role      Role for which to set the widget.
- */
-void AssociationWidget::setWidgetForRole(UMLWidget* widget, Uml::RoleType::Enum role)
-{
-    m_role[role].umlWidget = widget;
-    if (widget) {
-        m_role[role].umlWidget->addAssoc(this);
-        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
-            association()->setObject(widget->umlObject(), role);
-    }
-}
-
-/**
- * Return the multiplicity FloatingTextWidget widget of the given role.
- *
- * @return  Pointer to the multiplicity FloatingTextWidget object.
- */
-FloatingTextWidget* AssociationWidget::multiplicityWidget(Uml::RoleType::Enum role) const
-{
-    return m_role[role].multiplicityWidget;
-}
-
-/**
- * Read property of FloatingTextWidget* m_nameWidget.
- *
- * @return  Pointer to the FloatingTextWidget name widget.
- */
-FloatingTextWidget* AssociationWidget::nameWidget() const
-{
-    return m_nameWidget;
-}
-
-/**
- * Return the given role's FloatingTextWidget object.
- *
- * @return  Pointer to the role's FloatingTextWidget widget.
- */
-FloatingTextWidget* AssociationWidget::roleWidget(Uml::RoleType::Enum role) const
-{
-    return m_role[role].roleWidget;
-}
-
-/**
- * Return the given role's changeability FloatingTextWidget widget.
- */
-FloatingTextWidget* AssociationWidget::changeabilityWidget(Uml::RoleType::Enum role) const
-{
-    return m_role[role].changeabilityWidget;
-}
-
-/**
- * Return the FloatingTextWidget object indicated by the given TextRole::Enum.
- *
- * @return  Pointer to the text role's FloatingTextWidget widget.
- */
-FloatingTextWidget* AssociationWidget::textWidgetByRole(Uml::TextRole::Enum tr) const
-{
-    switch (tr) {
-        case Uml::TextRole::MultiA:
-            return m_role[RoleType::A].multiplicityWidget;
-        case Uml::TextRole::MultiB:
-            return m_role[RoleType::B].multiplicityWidget;
-        case Uml::TextRole::Name:
-        case Uml::TextRole::Coll_Message:
-            return m_nameWidget;
-        case Uml::TextRole::RoleAName:
-            return m_role[RoleType::A].roleWidget;
-        case Uml::TextRole::RoleBName:
-            return m_role[RoleType::B].roleWidget;
-        case Uml::TextRole::ChangeA:
-            return m_role[RoleType::A].changeabilityWidget;
-        case Uml::TextRole::ChangeB:
-            return m_role[RoleType::B].changeabilityWidget;
-        default:
-            break;
-    }
-    return NULL;
-}
-
-/**
- * Returns the m_nameWidget's text.
- *
- * @return  Text of the FloatingTextWidget name widget.
- */
-QString AssociationWidget::name() const
-{
-    if (m_nameWidget == NULL)
-        return QString();
-    return m_nameWidget->text();
-}
-
-/**
- * Sets the text in the FloatingTextWidget widget representing the Name
- * of this association.
- */
-void AssociationWidget::setName(const QString &strName)
-{
-    // set attribute of UMLAssociation associated with this associationwidget
-    UMLAssociation *umla = association();
-    if (umla)
-        umla->setName(strName);
-
-    bool newLabel = false;
-    if (!m_nameWidget) {
-        // Don't construct the FloatingTextWidget if the string is empty.
-        if (! FloatingTextWidget::isTextValid(strName))
-            return;
-
-        newLabel = true;
-        m_nameWidget = new FloatingTextWidget(m_scene, calculateNameType(Uml::TextRole::Name), strName);
-        m_nameWidget->setParentItem(this);
-        m_nameWidget->setLink(this);
-    } else {
-        m_nameWidget->setText(strName);
-        if (! FloatingTextWidget::isTextValid(strName)) {
-            //m_nameWidget->hide();
-            m_scene->removeWidget(m_nameWidget);
-            m_nameWidget = NULL;
-            return;
-        }
-    }
-
-    setTextPosition(Uml::TextRole::Name);
-    if (newLabel) {
-        m_nameWidget->setActivated();
-        m_scene->addFloatingTextWidget(m_nameWidget);
-    }
-
-    m_nameWidget->show();
-}
-
-void AssociationWidget::setStereotype(const QString &stereo) {
-    UMLAssociation *umlassoc = association();
-    if (umlassoc) {
-        umlassoc->setStereotype(stereo);
-        if (m_nameWidget) {
-            m_nameWidget->setText(umlassoc->stereotype(true));
-        } else {
-            uDebug() << "not setting " << stereo << " because m_nameWidget is NULL";
-        }
-    } else {
-        uDebug() << "not setting " << stereo << " because association is NULL";
-    }
-}
-
-/**
- * Return the given role's FloatingTextWidget widget text.
- *
- * @return  The name set at the FloatingTextWidget.
- */
-QString AssociationWidget::roleName(Uml::RoleType::Enum role) const
-{
-    if (m_role[role].roleWidget == NULL)
-        return QString();
-    return m_role[role].roleWidget->text();
-}
-
-/**
- * Sets the text to the FloatingTextWidget that display the Role text of this
- * association.
- * For this function to work properly, the associated widget
- *  should already be set.
- */
-void AssociationWidget::setRoleName(const QString &strRole, Uml::RoleType::Enum role)
-{
-    Uml::AssociationType::Enum type = associationType();
-    //if the association is not supposed to have a Role FloatingTextWidget
-    if (!AssocRules::allowRole(type))  {
-        return;
-    }
-
-    TextRole::Enum tr = (role == RoleType::A ? TextRole::RoleAName : TextRole::RoleBName);
-    setFloatingText(tr, strRole, m_role[role].roleWidget);
-    if (m_role[role].roleWidget) {
-        Uml::Visibility::Enum vis = visibility(role);
-        if (FloatingTextWidget::isTextValid(m_role[role].roleWidget->text())) {
-            m_role[role].roleWidget->setPreText(Uml::Visibility::toString(vis, true));
-            //m_role[role].roleWidget->show();
-        } else {
-            m_role[role].roleWidget->setPreText(QString());
-            //m_role[role].roleWidget->hide();
-        }
-    }
-
-    // set attribute of UMLAssociation associated with this associationwidget
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
-        association()->setRoleName(strRole, role);
-}
-
-/**
- * Set the documentation on the given role.
- */
-void AssociationWidget::setRoleDocumentation(const QString &doc, Uml::RoleType::Enum role)
-{
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
-        association()->setRoleDoc(doc, role);
-    else
-        m_role[role].roleDocumentation = doc;
-}
-
-/**
- * Returns the given role's documentation.
- */
-QString AssociationWidget::roleDocumentation(Uml::RoleType::Enum role) const
-{
-    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
-        return QString();
-    UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
-    return umla->getRoleDoc(role);
-}
-
-/**
- * Change, create, or delete the FloatingTextWidget indicated by the given TextRole::Enum.
- *
- * @param tr    TextRole::Enum of the FloatingTextWidget to change or create.
- * @param text  Text string that controls the action:
- *              If empty and ft is NULL then setFloatingText() is a no-op.
- *              If empty and ft is non-NULL then the existing ft is deleted.
- *              If non-empty and ft is NULL then a new FloatingTextWidget is created
- *              and returned in ft with the text set.
- *              If non-empty and ft is non-NULL then the existing ft text is modified.
- * @param ft    Reference to the pointer to FloatingTextWidget to change or create.
- *              On creation/deletion, the pointer value will be changed.
- */
-void AssociationWidget::setFloatingText(Uml::TextRole::Enum role,
-                                        const QString &text,
-                                        FloatingTextWidget* &ft)
-{
-    if (! FloatingTextWidget::isTextValid(text)) {
-        if (ft) {
-            // Remove preexisting FloatingTextWidget
-            m_scene->removeWidget(ft);  // physically deletes ft
-            ft = NULL;
-        }
-        return;
-    }
-
-    if (ft == NULL) {
-        ft = new FloatingTextWidget(m_scene, role, text);
-        ft->setParentItem(this);
-        ft->setLink(this);
-        ft->activate();
-        setTextPosition(role);
-        m_scene->addFloatingTextWidget(ft);
-    } else {
-        bool newLabel = ft->text().isEmpty();
-        ft->setText(text);
-        if (newLabel)
-            setTextPosition(role);
-    }
-
-    ft->show();
-}
-
-/**
- * Return the given role's multiplicity text.
- *
- * @return  Text of the given role's multiplicity widget.
- */
-QString AssociationWidget::multiplicity(Uml::RoleType::Enum role) const
-{
-    if (m_role[role].multiplicityWidget == NULL)
-        return QString();
-    return m_role[role].multiplicityWidget->text();
-}
-
-/**
- * Sets the text in the FloatingTextWidget representing the multiplicity
- * at the given side of the association.
- */
-void AssociationWidget::setMultiplicity(const QString& text, Uml::RoleType::Enum role)
-{
-    TextRole::Enum tr = (role == RoleType::A ? TextRole::MultiA : TextRole::MultiB);
-
-    setFloatingText(tr, text, m_role[role].multiplicityWidget);
-
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)
-        association()->setMultiplicity(text, role);
-}
-
-/**
- * Gets the visibility on the given role of the association.
- */
-Visibility::Enum AssociationWidget::visibility(Uml::RoleType::Enum role) const
-{
-    const UMLAssociation *assoc = association();
-    if (assoc)
-        return assoc->visibility(role);
-    const UMLAttribute *attr = attribute();
-    if (attr)
-        return attr->visibility();
-    return m_role[role].visibility;
-}
-
-/**
- * Sets the visibility on the given role of the association.
- */
-void AssociationWidget::setVisibility(Visibility::Enum value, Uml::RoleType::Enum role)
-{
-    if (value == visibility(role)) {
-        return;
-    }
-    if (m_umlObject) {
-        // update our model object
-        const UMLObject::ObjectType ot = m_umlObject->baseType();
-        if (ot == UMLObject::ot_Association)
-            association()->setVisibility(value, role);
-        else if (ot == UMLObject::ot_Attribute)
-            attribute()->setVisibility(value);
-    }
-    m_role[role].visibility = value;
-    // update role pre-text attribute as appropriate
-    if (m_role[role].roleWidget) {
-        QString scopeString = Visibility::toString(value, true);
-        m_role[role].roleWidget->setPreText(scopeString);
-    }
-}
-
-/**
- * Gets the changeability on the given end of the Association.
- */
-Uml::Changeability::Enum AssociationWidget::changeability(Uml::RoleType::Enum role) const
-{
-    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
-        return m_role[role].changeability;
-    UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
-    return umla->changeability(role);
-}
-
-/**
- * Sets the changeability on the given end of the Association.
- */
-void AssociationWidget::setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role)
-{
-    if (value == changeability(role))
-        return;
-    QString changeString = Uml::Changeability::toString(value);
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association)  // update our model object
-        association()->setChangeability(value, role);
-    m_role[role].changeability = value;
-    // update our string representation
-    setChangeWidget(changeString, role);
-}
-
-/**
- * For internal purposes only.
- * Other classes/users should use setChangeability() instead.
- */
-void AssociationWidget::setChangeWidget(const QString &strChangeWidget, Uml::RoleType::Enum role)
-{
-    bool newLabel = false;
-    TextRole::Enum tr = (role == RoleType::A ? TextRole::ChangeA : TextRole::ChangeB);
-
-    if (!m_role[role].changeabilityWidget) {
-        // Don't construct the FloatingTextWidget if the string is empty.
-        if (strChangeWidget.isEmpty())
-            return;
-
-        newLabel = true;
-        m_role[role].changeabilityWidget = new FloatingTextWidget(m_scene, tr, strChangeWidget);
-        m_role[role].changeabilityWidget->setParentItem(this);
-        m_role[role].changeabilityWidget->setLink(this);
-        m_scene->addFloatingTextWidget(m_role[role].changeabilityWidget);
-        m_role[role].changeabilityWidget->setPreText(QLatin1String("{")); // all types have this
-        m_role[role].changeabilityWidget->setPostText(QLatin1String("}")); // all types have this
-    } else {
-        if (m_role[role].changeabilityWidget->text().isEmpty()) {
-            newLabel = true;
-        }
-        m_role[role].changeabilityWidget->setText(strChangeWidget);
-    }
-    m_role[role].changeabilityWidget->setActivated();
-
-    if (newLabel) {
-        setTextPosition(tr);
-    }
-
-    if (FloatingTextWidget::isTextValid(m_role[role].changeabilityWidget->text()))
-        m_role[role].changeabilityWidget->show();
-    else
-        m_role[role].changeabilityWidget->hide();
-}
-
-/**
- * Returns true if the line path starts at the given widget.
- */
-bool AssociationWidget::linePathStartsAt(const UMLWidget* widget)
-{
-//:TODO:
-//    QPointF lpStart = m_associationLine->point(0);
-//    int startX = lpStart.x();
-//    int startY = lpStart.y();
-//    int wX = widget->x();
-//    int wY = widget->y();
-//    int wWidth = widget->width();
-//    int wHeight = widget->height();
-//    bool result = (startX >= wX && startX <= wX + wWidth &&
-//                   startY >= wY && startY <= wY + wHeight);
-//    return result;
-    bool result = widget->contains(m_associationLine->point(0));
-    DEBUG(DBG_SRC) << "widget=" << widget->name() << " / result=" << result;
-    return result;
-}
-
-/**
- * This function calculates which role should be set for the m_nameWidget FloatingTextWidget.
- */
-Uml::TextRole::Enum AssociationWidget::calculateNameType(Uml::TextRole::Enum defaultRole)
-{
-    TextRole::Enum result = defaultRole;
-    if (m_scene->type() == DiagramType::Collaboration) {
-        if (m_role[RoleType::A].umlWidget == m_role[RoleType::B].umlWidget) {
-            result = TextRole::Coll_Message;//for now same as other Coll_Message
-        } else {
-            result = TextRole::Coll_Message;
-        }
-    } else if (m_scene->type() == DiagramType::Sequence) {
-        if (m_role[RoleType::A].umlWidget == m_role[RoleType::B].umlWidget) {
-            result = TextRole::Seq_Message_Self;
-        } else {
-            result = TextRole::Seq_Message;
-        }
-    }
-
-    return result;
-}
-
-/**
- * Gets the given role widget.
- *
- * @return  Pointer to the role's UMLWidget.
- */
-UMLWidget* AssociationWidget::widgetForRole(Uml::RoleType::Enum role) const
-{
-    return m_role[role].umlWidget;
-}
-
-/**
- * Sets the associated widgets.
- *
- * @param widgetA   Pointer the role A widget for the association.
- * @param assocType The AssociationType::Enum for this association.
- * @param widgetB   Pointer the role B widget for the association.
- */
-bool AssociationWidget::setWidgets(UMLWidget* widgetA,
-                                   Uml::AssociationType::Enum assocType,
-                                   UMLWidget* widgetB)
-{
-    //if the association already has a WidgetB or WidgetA associated, then
-    //it cannot be changed to other widget, that would require a  deletion
-    //of the association and the creation of a new one
-    if ((m_role[RoleType::A].umlWidget && (m_role[RoleType::A].umlWidget != widgetA)) ||
-            (m_role[RoleType::B].umlWidget && (m_role[RoleType::B].umlWidget != widgetB))) {
-        return false;
-    }
-    setWidgetForRole(widgetA, RoleType::A);
-    setAssociationType(assocType);
-    setWidgetForRole(widgetB, RoleType::B);
-
-    calculateEndingPoints();
-    return true;
-}
-
-/**
- * CleansUp all the association's data in the related widgets.
- */
-void AssociationWidget::cleanup()
-{
-    //let any other associations know we are going so they can tidy their positions up
-    if (m_role[RoleType::A].m_nTotalCount > 2)
-        updateAssociations(m_role[RoleType::A].m_nTotalCount - 1, m_role[RoleType::A].m_WidgetRegion, RoleType::A);
-    if (m_role[RoleType::B].m_nTotalCount > 2)
-        updateAssociations(m_role[RoleType::B].m_nTotalCount - 1, m_role[RoleType::B].m_WidgetRegion, RoleType::B);
-
-    for (unsigned r = RoleType::A; r <= RoleType::B; ++r) {
-        WidgetRole& robj = m_role[r];
-
-        if (robj.umlWidget) {
-            robj.umlWidget->removeAssoc(this);
-            robj.umlWidget = 0;
-        }
-        if (robj.roleWidget) {
-            m_scene->removeWidget(robj.roleWidget);
-            robj.roleWidget = 0;
-        }
-        if (robj.multiplicityWidget) {
-            m_scene->removeWidget(robj.multiplicityWidget);
-            robj.multiplicityWidget = 0;
-        }
-        if (robj.changeabilityWidget) {
-            m_scene->removeWidget(robj.changeabilityWidget);
-            robj.changeabilityWidget = 0;
-        }
-    }
-
-    if (m_nameWidget) {
-        m_scene->removeWidget(m_nameWidget);
-        m_nameWidget = 0;
-    }
-
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
-        /*
-           We do not remove the UMLAssociation from the document.
-           Why? - Well, for example we might be in the middle of
-           a cut/paste. If the UMLAssociation is removed by the cut
-           then upon pasteing we have a problem.
-           This is not quite clean yet - there should be a way to
-           explicitly delete a UMLAssociation.  The Right Thing would
-           be to have a ListView representation for UMLAssociation.
-        `
-                IF we are cut n pasting, why are we handling this association as a pointer?
-                We should be using the XMI representation for a cut and paste. This
-                allows us to be clean here, AND a choice of recreating the object
-                w/ same id IF its a "cut", or a new object if its a "copy" operation
-                (in which case we wouldnt be here, in cleanup()).
-         */
-        setUMLAssociation(0);
-    }
-
-    m_associationLine->cleanup();
-    removeAssocClassLine();
-}
-
-/**
- * @brief Return state if the assocation line point in the near of the last context
- *        menu event position is addable or not.
- * A point is addable if the association is not an Exception and there is no point in the near.
- *
- * @return true if point is addable
- */
-bool AssociationWidget::isPointAddable()
-{
-    if (!isSelected() || associationType() == Uml::AssociationType::Exception)
-        return false;
-    int i = m_associationLine->closestPointIndex(m_eventScenePos);
-    return i == -1;
-}
-
-/**
- * @brief Return state if the assocation line point in the near of the last context
- *        menu event position is removable or not.
- * A point is removable if the association is not an Exception and is not the start or end point.
- *
- * @return true if point is removable
- */
-bool AssociationWidget::isPointRemovable()
-{
-    if (!isSelected() || associationType() == Uml::AssociationType::Exception || m_associationLine->count() <= 2)
-        return false;
-    int i = m_associationLine->closestPointIndex(m_eventScenePos);
-    return i > 0 && i < m_associationLine->count() - 1;
-}
-
-/**
- * Set our internal umlAssociation.
- */
-void AssociationWidget::setUMLAssociation (UMLAssociation * assoc)
-{
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
-        UMLAssociation *umla = association();
-
-        // safety check. Did some num-nuts try to set the existing
-        // association again? If so, just bail here
-        if (umla == assoc)
-            return;
-
-        //umla->disconnect(this);  //Qt does disconnect automatically upon destruction.
-        umla->nrof_parent_widgets--;
-
-        // ANSWER: This is the wrong treatment of cut and paste. Associations that
-        // are being cut/n pasted should be serialized to XMI, then reconstituted
-        // (IF a paste operation) rather than passing around object pointers. Its
-        // just too hard otherwise to prevent problems in the code. Bottom line: we need to
-        // delete orphaned associations or we well get code crashes and memory leaks.
-        if (umla->nrof_parent_widgets <= 0) {
-            //umla->deleteLater();
-        }
-
-        m_umlObject = NULL;
-    }
-
-    if (assoc) {
-        m_umlObject = assoc;
-
-        // move counter to "0" from "-1" (which means, no assocwidgets)
-        if (assoc->nrof_parent_widgets < 0)
-            assoc->nrof_parent_widgets = 0;
-
-        assoc->nrof_parent_widgets++;
-        connect(assoc, SIGNAL(modified()), this, SLOT(syncToModel()));
-    }
-
-}
-
-/**
- * Returns true if the Widget is either at the starting or ending side of the association.
- */
-bool AssociationWidget::containsAsEndpoint(UMLWidget* widget)
-{
-    return (widget == m_role[RoleType::A].umlWidget || widget == m_role[RoleType::B].umlWidget);
-}
-
-/**
- * Returns true if this AssociationWidget represents a collaboration message.
- */
-bool AssociationWidget::isCollaboration() const
-{
-    Uml::AssociationType::Enum at = associationType();
-    return (at == AssociationType::Coll_Message_Synchronous
-            || at == AssociationType::Coll_Message_Asynchronous
-            || at == AssociationType::Coll_Message_Self);
-}
-
-/**
- * Returns true if this AssociationWidget represents a self message.
- */
-bool AssociationWidget::isSelf() const
-{
-    return widgetForRole(Uml::RoleType::A) == widgetForRole(Uml::RoleType::B);
-}
-
-/**
- * Gets the association's type.
- *
- * @return  This AssociationWidget's AssociationType::Enum.
- */
-Uml::AssociationType::Enum AssociationWidget::associationType() const
-{
-    if (m_umlObject == NULL || m_umlObject->baseType() != UMLObject::ot_Association)
-        return m_associationType;
-    UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
-    return umla->getAssocType();
-}
-
-/**
- * Sets the association's type.
- *
- * @param type   The AssociationType::Enum to set.
- */
-void AssociationWidget::setAssociationType(Uml::AssociationType::Enum type)
-{
-    if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
-        association()->setAssociationType(type);
-    }
-    m_associationType = type;
-    // If the association new type is not supposed to have Multiplicity
-    // FloatingTexts and a Role FloatingTextWidget then set the texts
-    // to empty.
-    // NB We do not physically delete the floatingtext widgets here because
-    // those widgets are also stored in the UMLView::m_WidgetList.
-    if (!AssocRules::allowMultiplicity(type, widgetForRole(RoleType::A)->baseType())) {
-        if (m_role[RoleType::A].multiplicityWidget) {
-            m_role[RoleType::A].multiplicityWidget->setName(QString());
-        }
-        if (m_role[RoleType::B].multiplicityWidget) {
-            m_role[RoleType::B].multiplicityWidget->setName(QString());
-        }
-    }
-    if (!AssocRules::allowRole(type)) {
-        if (m_role[RoleType::A].roleWidget) {
-            m_role[RoleType::A].roleWidget->setName(QString());
-        }
-        if (m_role[RoleType::B].roleWidget) {
-            m_role[RoleType::B].roleWidget->setName(QString());
-        }
-        setRoleDocumentation(QString(), RoleType::A);
-        setRoleDocumentation(QString(), RoleType::B);
-    }
-    m_associationLine->reconstructSymbols();
-}
-
-/**
- * Gets the ID of the given role widget.
- */
-Uml::ID::Type AssociationWidget::widgetIDForRole(Uml::RoleType::Enum role) const
-{
-    if (m_role[role].umlWidget == NULL) {
-        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
-            UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
-            return umla->getObjectId(role);
-        }
-        uError() << "umlWidget is NULL";
-        return Uml::ID::None;
-    }
-    if (m_role[role].umlWidget->baseType() == WidgetBase::wt_Object)
-        return static_cast<ObjectWidget*>(m_role[role].umlWidget)->localID();
-    Uml::ID::Type id = m_role[role].umlWidget->id();
-    return id;
-}
-
-/**
- * Gets the local ID of the given role widget.
- */
-Uml::ID::Type AssociationWidget::widgetLocalIDForRole(Uml::RoleType::Enum role) const
-{
-    if (m_role[role].umlWidget == NULL) {
-        if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) {
-            UMLAssociation *umla = static_cast<UMLAssociation*>(m_umlObject);
-            return umla->getObjectId(role);
-        }
-        uError() << "umlWidget is NULL";
-        return Uml::ID::None;
-    }
-    if (m_role[role].umlWidget->baseType() == WidgetBase::wt_Object)
-        return static_cast<ObjectWidget*>(m_role[role].umlWidget)->localID();
-    Uml::ID::Type id = m_role[role].umlWidget->localID();
-    return id;
-}
-
-/**
- * Returns a QString Object representing this AssociationWidget.
- */
-QString AssociationWidget::toString() const
-{
-    QString string;
-    static const QChar colon(QLatin1Char(':'));
-
-    if (widgetForRole(RoleType::A)) {
-        string = widgetForRole(RoleType::A)->name();
-    }
-    string.append(colon);
-
-    if (m_role[RoleType::A].roleWidget) {
-        string += m_role[RoleType::A].roleWidget->text();
-    }
-    string.append(colon);
-    string.append(Uml::AssociationType::toStringI18n(associationType()));
-    string.append(colon);
-
-    if (widgetForRole(RoleType::B)) {
-        string += widgetForRole(RoleType::B)->name();
-    }
-
-    string.append(colon);
-    if (m_role[RoleType::B].roleWidget) {
-        string += m_role[RoleType::B].roleWidget->text();
-    }
-
-    return string;
-}
-
-/**
- * Adds a break point (if left mouse button).
- */
-void AssociationWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
-{
-    if (event->button() == Qt::LeftButton) {
-        uDebug() << "widget = " << name() << " / type = " << baseTypeStr();
-        showPropertiesDialog();
-        event->accept();
-    }
-}
-
-/**
- * Overrides moveEvent.
- */
-void AssociationWidget::moveEvent(QGraphicsSceneMouseEvent *me)
-{
-    // 2004-04-30: Achim Spangler
-    // Simple Approach to block moveEvent during load of XMI
-    /// @todo avoid trigger of this event during load
-
-    if (umlDoc()->loading()) {
-        // hmmh - change of position during load of XMI
-        // -> there is something wrong
-        // -> avoid movement during opening
-        // -> print warn and stay at old position
-        uWarning() << "called during load of XMI for ViewType: "
-            << m_scene->type() << ", and BaseType: " << baseType();
-        return;
-    }
-    /*to be here a line segment has moved.
-      we need to see if the three text widgets needs to be moved.
-      there are a few things to check first though:
-
-      1) Do they exist
-      2) does it need to move:
-      2a) for the multi widgets only move if they changed region, otherwise they are close enough
-      2b) for role name move if the segment it is on moves.
-    */
-    //first see if either the first or last segments moved, else no need to recalculate their point positions
-
-    QPointF oldNamePoint = calculateTextPosition(TextRole::Name);
-    QPointF oldMultiAPoint = calculateTextPosition(TextRole::MultiA);
-    QPointF oldMultiBPoint = calculateTextPosition(TextRole::MultiB);
-    QPointF oldChangeAPoint = calculateTextPosition(TextRole::ChangeA);
-    QPointF oldChangeBPoint = calculateTextPosition(TextRole::ChangeB);
-    QPointF oldRoleAPoint = calculateTextPosition(TextRole::RoleAName);
-    QPointF oldRoleBPoint = calculateTextPosition(TextRole::RoleBName);
-
-    int movingPoint = m_associationLine->closestPointIndex(me->scenePos());
-    if (movingPoint != -1)
-        m_associationLine->setPoint(movingPoint, me->scenePos());
-    int pos = m_associationLine->count() - 1;//set to last point for widget b
-
-    if ( movingPoint == 1 || (movingPoint == pos-1) ) {
-        calculateEndingPoints();
-    }
-    if (m_role[RoleType::A].changeabilityWidget && (movingPoint == 1)) {
-        setTextPositionRelatively(TextRole::ChangeA, oldChangeAPoint);
-    }
-    if (m_role[RoleType::B].changeabilityWidget && (movingPoint == 1)) {
-        setTextPositionRelatively(TextRole::ChangeB, oldChangeBPoint);
-    }
-    if (m_role[RoleType::A].multiplicityWidget && (movingPoint == 1)) {
-        setTextPositionRelatively(TextRole::MultiA, oldMultiAPoint);
-    }
-    if (m_role[RoleType::B].multiplicityWidget && (movingPoint == pos-1)) {
-        setTextPositionRelatively(TextRole::MultiB, oldMultiBPoint);
-    }
-
-    if (m_nameWidget) {
-        if (movingPoint == m_unNameLineSegment ||
-                movingPoint - 1 == m_unNameLineSegment) {
-            setTextPositionRelatively(TextRole::Name, oldNamePoint);
-        }
-    }
-
-    if (m_role[RoleType::A].roleWidget) {
-        setTextPositionRelatively(TextRole::RoleAName, oldRoleAPoint);
-    }
-    if (m_role[RoleType::B].roleWidget) {
-        setTextPositionRelatively(TextRole::RoleBName, oldRoleBPoint);
-    }
-
-    if (m_pAssocClassLine) {
-        computeAssocClassLine();
-    }
-}
-
-/**
- * Calculates and sets the first and last point in the Association's AssociationLine.
- * Each point is a middle point of its respecting UMLWidget's Bounding rectangle
- * or a corner of it.
- * This method picks which sides to use for the association.
- */
-void AssociationWidget::calculateEndingPoints()
-{
-    /*
-     * For each UMLWidget the diagram is divided in four regions by its diagonals
-     * as indicated below
-     *                              Region 2
-     *                         \                /
-     *                           \            /
-     *                             +--------+
-     *                             | \    / |
-     *                Region 1     |   ><   |    Region 3
-     *                             | /    \ |
-     *                             +--------+
-     *                           /            \
-     *                         /                \
-     *                              Region 4
-     *
-     * Each diagonal is defined by two corners of the bounding rectangle
-     *
-     * To calculate the first point in the AssociationLine we have to find out in which
-     * Region (defined by WidgetA's diagonals) is WidgetB's center
-     * (let's call it Region M.) After that the first point will be the middle
-     * point of the rectangle's side contained in Region M.
-     *
-     * To calculate the last point in the AssociationLine we repeat the above but
-     * in the opposite direction (from widgetB to WidgetA)
-     */
-
-    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
-    UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
-    if (!pWidgetA || !pWidgetB) {
-        uWarning() << "Returning - one of the role widgets is not set.";
-        return;
-    }
-
-    int size = m_associationLine->count();
-    if (size < 2) {
-        QPointF pA = pWidgetA->pos();
-        QPointF pB = pWidgetB->pos();
-        QPolygonF polyA = pWidgetA->shape().toFillPolygon().translated(pA);
-        QPolygonF polyB = pWidgetB->shape().toFillPolygon().translated(pB);
-        QLineF nearestPoints = Widget_Utils::closestPoints(polyA, polyB);
-        if (nearestPoints.isNull()) {
-            uError() << "Widget_Utils::closestPoints failed, falling back to simple widget positions";
-        } else {
-            pA = nearestPoints.p1();
-            pB = nearestPoints.p2();
-        }
-        m_associationLine->setEndPoints(pA, pB);
-    }
-
-    // See if an association to self.
-    // See if it needs to be set up before we continue:
-    // If self association/message and doesn't have the minimum 4 points
-    // then create it. Make sure no points are out of bounds of viewing area.
-    // This only happens on first time through that we are worried about.
-    if (isSelf() && size < 4) {
-        createPointsSelfAssociation();
-        return;
-    }
-
-    if (associationType() == AssociationType::Exception && size < 4) {
-        createPointsException();
-        updatePointsException();
-        return;
-    }
-
-    // If the line has more than one segment change the values to calculate
-    // from widget to point 1.
-    qreal xB = pWidgetB->x() + pWidgetB->width() / 2;
-    qreal yB = pWidgetB->y() + pWidgetB->height() / 2;
-    if (size > 2) {
-        QPointF p = m_associationLine->point(1);
-        xB = p.x();
-        yB = p.y();
-    }
-    doUpdates(QPointF(xB, yB), RoleType::A);
-
-    // Now do the same for widgetB.
-    // If the line has more than one segment change the values to calculate
-    // from widgetB to the last point away from it.
-    qreal xA = pWidgetA->x() + pWidgetA->width() / 2;
-    qreal yA = pWidgetA->y() + pWidgetA->height() / 2;
-    if (size > 2 ) {
-        QPointF p = m_associationLine->point(size - 2);
-        xA = p.x();
-        yA = p.y();
-    }
-    doUpdates(QPointF(xA, yA), RoleType::B);
-
-    computeAssocClassLine();
-}
-
-/**
- * Used by @ref calculateEndingPoints.
- */
-void AssociationWidget::doUpdates(const QPointF &otherP, RoleType::Enum role)
-{
-    // Find widget region.
-    Uml::Region::Enum oldRegion = m_role[role].m_WidgetRegion;
-    UMLWidget *pWidget = m_role[role].umlWidget;
-    QRectF rc(pWidget->x(), pWidget->y(),
-              pWidget->width(), pWidget->height());
-    Uml::Region::Enum region = m_role[role].m_WidgetRegion;  // alias for brevity
-    region = findPointRegion(rc, otherP);
-    // Move some regions to the standard ones.
-    switch( region ) {
-    case Uml::Region::NorthWest:
-        region = Uml::Region::North;
-        break;
-    case Uml::Region::NorthEast:
-        region = Uml::Region::East;
-        break;
-    case Uml::Region::SouthEast:
-        region = Uml::Region::South;
-        break;
-    case Uml::Region::SouthWest:
-    case Uml::Region::Center:
-        region = Uml::Region::West;
-        break;
-    default:
-        break;
-    }
-    int regionCount = getRegionCount(region, role) + 2; //+2 = (1 for this one and one to halve it)
-    int totalCount = m_role[role].m_nTotalCount;
-    if (oldRegion != region) {
-        updateRegionLineCount(regionCount - 1, regionCount, region, role);
-        updateAssociations(totalCount - 1, oldRegion, role);
-    } else if (totalCount != regionCount) {
-        updateRegionLineCount(regionCount - 1, regionCount, region, role);
-    } else {
-        updateRegionLineCount(m_role[role].m_nIndex, totalCount, region, role);
-    }
-    updateAssociations(regionCount, region, role);
-}
-
-/**
- * Read property of bool m_activated.
- */
-bool AssociationWidget::isActivated() const
-{
-    return m_activated;
-}
-
-/**
- * Set the m_activated flag of a widget but does not perform the Activate method.
- */
-void AssociationWidget::setActivated(bool active)
-{
-    m_activated = active;
-}
-
-/**
- * Synchronize this widget from the UMLAssociation.
- */
-void AssociationWidget::syncToModel()
-{
-    UMLAssociation *uml = association();
-
-    if (uml == NULL) {
-        UMLAttribute *attr = attribute();
-        if (attr == NULL)
-            return;
-        setVisibility(attr->visibility(), RoleType::B);
-        setRoleName(attr->name(), RoleType::B);
-        return;
-    }
-    // block signals until finished
-    uml->blockSignals(true);
-
-    setName(uml->name());
-    setRoleName(uml->getRoleName(RoleType::A), RoleType::A);
-    setRoleName(uml->getRoleName(RoleType::B), RoleType::B);
-    setVisibility(uml->visibility(RoleType::A), RoleType::A);
-    setVisibility(uml->visibility(RoleType::B), RoleType::B);
-    setChangeability(uml->changeability(RoleType::A), RoleType::A);
-    setChangeability(uml->changeability(RoleType::B), RoleType::B);
-    setMultiplicity(uml->getMultiplicity(RoleType::A), RoleType::A);
-    setMultiplicity(uml->getMultiplicity(RoleType::B), RoleType::B);
-
-    uml->blockSignals(false);
-}
-
-/**
- * Merges/syncs the association widget data into UML object
- * representation.
- * This will synchronize UMLAssociation w/ this new Widget
- * CHECK: Can we get rid of this.
- */
-void AssociationWidget::mergeAssociationDataIntoUMLRepresentation()
-{
-    UMLAssociation *umlassoc = association();
-    UMLAttribute *umlattr = attribute();
-    if (umlassoc == NULL && umlattr == NULL)
-        return;
-
-    // block emit modified signal, or we get a horrible loop
-    m_umlObject->blockSignals(true);
-
-    // would be desirable to do the following
-    // so that we can be sure its back to initial state
-    // in case we missed something here.
-    //uml->init();
-
-    // floating text widgets
-    FloatingTextWidget *text = nameWidget();
-    if (text)
-        m_umlObject->setName(text->text());
-
-    text = roleWidget(RoleType::A);
-    if (text && umlassoc)
-        umlassoc->setRoleName(text->text(), RoleType::A);
-
-    text = roleWidget(RoleType::B);
-    if (text) {
-        if (umlassoc)
-            umlassoc->setRoleName(text->text(), RoleType::B);
-        else if (umlattr)
-            umlattr->setName(text->text());
-    }
-
-    text = multiplicityWidget(RoleType::A);
-    if (text && umlassoc)
-        umlassoc->setMultiplicity(text->text(), RoleType::A);
-
-    text = multiplicityWidget(RoleType::B);
-    if (text && umlassoc)
-        umlassoc->setMultiplicity(text->text(), RoleType::B);
-
-    // unblock
-    m_umlObject->blockSignals(false);
-}
-
-/**
- * Auxiliary method for widgetMoved():
- * Saves all ideally computed floatingtext positions before doing any
- * kind of change.  This is necessary because a single invocation of
- * calculateEndingPoints() modifies the AssociationLine ending points on ALL
- * AssociationWidgets.  This means that if we don't save the old ideal
- * positions then they are irretrievably lost as soon as
- * calculateEndingPoints() is invoked.
- */
-void AssociationWidget::saveIdealTextPositions()
-{
-    m_oldNamePoint    = calculateTextPosition(TextRole::Name);
-    m_oldMultiAPoint  = calculateTextPosition(TextRole::MultiA);
-    m_oldMultiBPoint  = calculateTextPosition(TextRole::MultiB);
-    m_oldChangeAPoint = calculateTextPosition(TextRole::ChangeA);
-    m_oldChangeBPoint = calculateTextPosition(TextRole::ChangeB);
-    m_oldRoleAPoint   = calculateTextPosition(TextRole::RoleAName);
-    m_oldRoleBPoint   = calculateTextPosition(TextRole::RoleBName);
-}
-
-/**
- * Adjusts the ending point of the association that connects to Widget.
- */
-void AssociationWidget::widgetMoved(UMLWidget* widget, qreal dx, qreal dy)
-{
-    Q_UNUSED(dx); Q_UNUSED(dy);
-
-    // Simple Approach to block moveEvent during load of XMI
-    /// @todo avoid trigger of this event during load
-    if (umlDoc()->loading()) {
-        // change of position during load of XMI
-        // -> there is something wrong
-        // -> avoid movement during opening
-        // -> print warn and stay at old position
-        DEBUG(DBG_SRC) << "called during load of XMI for ViewType: " << m_scene->type()
-                       << ", and BaseType: " << baseTypeStr();
-        return;
-    }
-
-    DEBUG(DBG_SRC) << "association type=" << Uml::AssociationType::toString(associationType());
-    if (associationType() == AssociationType::Exception) {
-        updatePointsException();
-        setTextPosition(TextRole::Name);
-    }
-    else {
-        calculateEndingPoints();
-        computeAssocClassLine();
-    }
-
-    // Assoc to self - move all points:
-    if (isSelf()) {
-        updatePointsSelfAssociation();
-
-        if (m_nameWidget && !m_nameWidget->isSelected()) {
-            setTextPositionRelatively(TextRole::Name, m_oldNamePoint);
-        }
-
-    }//end if widgetA = widgetB
-    else if (m_role[RoleType::A].umlWidget == widget) {
-        if (m_nameWidget && m_unNameLineSegment == 0 && !m_nameWidget->isSelected() ) {
-            //only calculate position and move text if the segment it is on is moving
-            setTextPositionRelatively(TextRole::Name, m_oldNamePoint);
-        }
-    }//end if widgetA moved
-    else if (m_role[RoleType::B].umlWidget == widget) {
-        const int size = m_associationLine->count();
-        if (m_nameWidget && (m_unNameLineSegment == size-2) && !m_nameWidget->isSelected() ) {
-            //only calculate position and move text if the segment it is on is moving
-            setTextPositionRelatively(TextRole::Name, m_oldNamePoint);
-        }
-    }//end if widgetB moved
-
-    if (m_role[RoleType::A].roleWidget && !m_role[RoleType::A].roleWidget->isSelected()) {
-        setTextPositionRelatively(TextRole::RoleAName, m_oldRoleAPoint);
-    }
-    if (m_role[RoleType::B].roleWidget && !m_role[RoleType::B].roleWidget->isSelected()) {
-        setTextPositionRelatively(TextRole::RoleBName, m_oldRoleBPoint);
-    }
-    if (m_role[RoleType::A].multiplicityWidget && !m_role[RoleType::A].multiplicityWidget->isSelected()) {
-        setTextPositionRelatively(TextRole::MultiA, m_oldMultiAPoint);
-    }
-    if (m_role[RoleType::B].multiplicityWidget && !m_role[RoleType::B].multiplicityWidget->isSelected()) {
-        setTextPositionRelatively(TextRole::MultiB, m_oldMultiBPoint);
-    }
-    if (m_role[RoleType::A].changeabilityWidget && !m_role[RoleType::A].changeabilityWidget->isSelected()) {
-        setTextPositionRelatively(TextRole::ChangeA, m_oldChangeAPoint);
-    }
-    if (m_role[RoleType::B].changeabilityWidget && !m_role[RoleType::B].changeabilityWidget->isSelected()) {
-        setTextPositionRelatively(TextRole::ChangeB, m_oldChangeBPoint);
-    }
-}
-
-/**
- * Creates the points of the self association.
- * Method called when a widget end points are calculated by calculateEndingPoints().
- */
-void AssociationWidget::createPointsSelfAssociation()
-{
-    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
-
-    const int DISTANCE = 50;
-    qreal x = pWidgetA->x();
-    qreal y = pWidgetA->y();
-    qreal h = pWidgetA->height();
-    qreal w = pWidgetA->width();
-    // see if above widget ok to start
-    if (y - DISTANCE > 0) {
-        m_associationLine->setEndPoints(QPointF(x + w / 4, y) , QPointF(x + w * 3 / 4, y));
-        m_associationLine->insertPoint(1, QPointF(x + w / 4, y - DISTANCE));
-        m_associationLine->insertPoint(2, QPointF(x + w * 3 / 4, y - DISTANCE));
-        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::North;
-    } else {
-        m_associationLine->setEndPoints(QPointF(x + w / 4, y + h), QPointF(x + w * 3 / 4, y + h));
-        m_associationLine->insertPoint(1, QPointF(x + w / 4, y + h + DISTANCE));
-        m_associationLine->insertPoint(2, QPointF(x + w * 3 / 4, y + h + DISTANCE));
-        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::South;
-    }
-}
-
-/**
- * Adjusts the points of the self association.
- * Method called when a widget was moved by widgetMoved(widget, x, y).
- */
-void AssociationWidget::updatePointsSelfAssociation()
-{
-    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
-
-    const int DISTANCE = 50;
-    qreal x = pWidgetA->x();
-    qreal y = pWidgetA->y();
-    qreal h = pWidgetA->height();
-    qreal w = pWidgetA->width();
-    // see if above widget ok to start
-    if (y - DISTANCE > 0) {
-        m_associationLine->setEndPoints(QPointF(x + w / 4, y) , QPointF(x + w * 3 / 4, y));
-        m_associationLine->setPoint(1, QPointF(x + w / 4, y - DISTANCE));
-        m_associationLine->setPoint(2, QPointF(x + w * 3 / 4, y - DISTANCE));
-        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::North;
-    } else {
-        m_associationLine->setEndPoints(QPointF(x + w / 4, y + h), QPointF(x + w * 3 / 4, y + h));
-        m_associationLine->setPoint(1, QPointF(x + w / 4, y + h + DISTANCE));
-        m_associationLine->setPoint(2, QPointF(x + w * 3 / 4, y + h + DISTANCE));
-        m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::South;
-    }
-}
-
-/**
- * Creates the points of the association exception.
- * Method called when a widget end points are calculated by calculateEndingPoints().
- */
-void AssociationWidget::createPointsException()
-{
-    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
-    UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
-
-    qreal xa = pWidgetA->x();
-    qreal ya = pWidgetA->y();
-    qreal ha = pWidgetA->height();
-    qreal wa = pWidgetA->width();
-
-    qreal xb = pWidgetB->x();
-    qreal yb = pWidgetB->y();
-    qreal hb = pWidgetB->height();
-    //qreal wb = pWidgetB->width();
-
-    m_associationLine->setEndPoints(QPointF(xa + wa , ya + ha/2) , QPointF(xb , yb + hb/2));
-    m_associationLine->insertPoint(1, QPointF(xa + wa , ya + ha/2));
-    m_associationLine->insertPoint(2, QPointF(xb , yb + hb/2));
-}
-
-/**
- * Adjusts the points of the association exception.
- * Method called when a widget was moved by widgetMoved(widget, x, y).
- */
-void AssociationWidget::updatePointsException()
-{
-    UMLWidget *pWidgetA = m_role[RoleType::A].umlWidget;
-    UMLWidget *pWidgetB = m_role[RoleType::B].umlWidget;
-
-    qreal xa = pWidgetA->x();
-    qreal ya = pWidgetA->y();
-    qreal ha = pWidgetA->height();
-    qreal wa = pWidgetA->width();
-
-    qreal xb = pWidgetB->x();
-    qreal yb = pWidgetB->y();
-    qreal hb = pWidgetB->height();
-    qreal wb = pWidgetB->width();
-    qreal xmil, ymil;
-    qreal xdeb, ydeb;
-    qreal xfin, yfin;
-    qreal ESPACEX, ESPACEY;
-    QPointF p1;
-    QPointF p2;
-    //calcul des coordonnées au milieu de la flèche eclair
-    if (xb - xa - wa >= 45) {
-        ESPACEX = 0;
-        xdeb = xa + wa;
-        xfin = xb;
-    } else if (xa - xb - wb > 45) {
-        ESPACEX = 0;
-        xdeb = xa;
-        xfin = xb + wb;
-    } else {
-        ESPACEX = 15;
-        xdeb = xa + wa/2;
-        xfin = xb + wb/2;
-    }
-
-    xmil = xdeb + (xfin - xdeb)/2;
-
-    if (yb - ya - ha >= 45)  {
-        ESPACEY = 0;
-        ydeb = ya + ha;
-        yfin = yb;
-    } else if (ya - yb - hb > 45) {
-        ESPACEY = 0;
-        ydeb = ya;
-        yfin = yb + hb;
-    } else {
-        ESPACEY = 15;
-        ydeb = ya + ha/2;
-        yfin = yb + hb/2;
-    }
-
-    ymil = ydeb + (yfin - ydeb)/2;
-
-    p1.setX(xmil + (xfin - xmil)*1/2); p1.setY(ymil + (yfin - ymil)*1/3);
-    p2.setX(xmil - (xmil - xdeb)*1/2); p2.setY(ymil - (ymil - ydeb)*1/3);
-
-    if (abs(p1.x() - p2.x()) <= 10)
-        ESPACEX = 15;
-    if (abs(p1.y() - p2.y()) <= 10)
-        ESPACEY = 15;
-
-    m_associationLine->setEndPoints(QPointF(xdeb, ydeb), QPointF(xfin, yfin));
-    m_associationLine->setPoint(1, QPointF(p1.x() + ESPACEX, p1.y() + ESPACEY));
-    m_associationLine->setPoint(2, QPointF(p2.x() - ESPACEX, p2.y() - ESPACEY));
-
-    m_role[RoleType::A].m_WidgetRegion = m_role[RoleType::B].m_WidgetRegion = Uml::Region::North;
-}
-
-/**
- * Finds out which region of rectangle 'rect' contains the point 'pos' and returns the region
- * number:
- * 1 = Region 1
- * 2 = Region 2
- * 3 = Region 3
- * 4 = Region 4
- * 5 = On diagonal 2 between Region 1 and 2
- * 6 = On diagonal 1 between Region 2 and 3
- * 7 = On diagonal 2 between Region 3 and 4
- * 8 = On diagonal 1 between Region 4 and 1
- * 9 = On diagonal 1 and On diagonal 2 (the center)
- */
-Uml::Region::Enum AssociationWidget::findPointRegion(const QRectF& rect, const QPointF &pos)
-{
-    qreal w = rect.width();
-    qreal h = rect.height();
-    qreal x = rect.x();
-    qreal y = rect.y();
-    qreal slope2 = w / h;
-    qreal slope1 = slope2 *(-1.0);
-    qreal b1 = x + w - (slope1 * y);
-    qreal b2 = x - (slope2 * y);
-
-    qreal eval1 = slope1 * pos.y() + b1;
-    qreal eval2 = slope2 * pos.y() + b2;
-
-    Uml::Region::Enum result = Uml::Region::Error;
-    //if inside region 1
-    if (eval1 > pos.x() && eval2 > pos.x()) {
-        result = Uml::Region::West;
-    }
-    //if inside region 2
-    else if (eval1 > pos.x() && eval2 < pos.x()) {
-        result = Uml::Region::North;
-    }
-    //if inside region 3
-    else if (eval1 < pos.x() && eval2 < pos.x()) {
-        result = Uml::Region::East;
-    }
-    //if inside region 4
-    else if (eval1 < pos.x() && eval2 > pos.x()) {
-        result = Uml::Region::South;
-    }
-    //if inside region 5
-    else if (eval1 == pos.x() && eval2 < pos.x()) {
-        result = Uml::Region::NorthWest;
-    }
-    //if inside region 6
-    else if (eval1 < pos.x() && eval2 == pos.x()) {
-        result = Uml::Region::NorthEast;
-    }
-    //if inside region 7
-    else if (eval1 == pos.x() && eval2 > pos.x()) {
-        result = Uml::Region::SouthEast;
-    }
-    //if inside region 8
-    else if (eval1 > pos.x() && eval2 == pos.x()) {
-        result = Uml::Region::SouthWest;
-    }
-    //if inside region 9
-    else if (eval1 == pos.x() && eval2 == pos.x()) {
-        result = Uml::Region::Center;
-    }
-    return result;
-}
-
-/**
- * Returns a point with interchanged X and Y coordinates.
- */
-QPointF AssociationWidget::swapXY(const QPointF &p)
-{
-    QPointF swapped( p.y(), p.x() );
-    return swapped;
-}
-
-#if 0  // not used at the moment
-/**
- * Calculates which point of segment P1P2 has a distance equal to
- * Distance from P1.
- * Let's say such point is PX, the distance from P1 to PX must be equal
- * to Distance and if PX is not a point of the segment P1P2 then the
- * function returns (-1, -1).
- */
-QPointF AssociationWidget::calculatePointAtDistance(const QPointF &P1, const QPointF &P2, float Distance)
-{
-    /*
-      the distance D between points (x1, y1) and (x3, y3) has the following formula:
-          ---     ------------------------------
-      D =    \   /         2         2
-              \ /   (x3 - x1)  +  (y3 - y1)
-
-      D, x1 and y1 are known and the point (x3, y3) is inside line (x1, y1)(x2, y2), so if the
-      that line has the formula y = mx + b
-      then y3 = m*x3 + b
-
-       2             2             2
-      D   = (x3 - x1)  +  (y3 - y1)
-
-       2       2                 2      2                 2
-      D    = x3    - 2*x3*x1 + x1   + y3   - 2*y3*y1  + y1
-
-       2       2       2       2                  2
-      D    - x1    - y1    = x3    - 2*x3*x1  + y3   - 2*y3*y1
-
-       2       2       2       2                          2
-      D    - x1    - y1    = x3    - 2*x3*x1  + (m*x3 + b)  - 2*(m*x3 + b)*y1
-
-       2       2       2              2       2 2
-      D    - x1    - y1   + 2*b*y1 - b   =  (m  + 1)*x3   + (-2*x1 + 2*m*b -2*m*y1)*x3
-
-       2      2       2       2
-      C  = - D    + x1    + y1   - 2*b*y1 + b
-
-
-       2
-      A  = (m    + 1)
-
-      B  = (-2*x1 + 2*m*b -2*m*y1)
-
-      and we have
-       2
-      A * x3 + B * x3 - C = 0
-
-                         ---------------
-             -B +  ---  /  2
-                      \/  B   - 4*A*C
-      sol_1  = --------------------------------
-                       2*A
-
-
-                         ---------------
-             -B -  ---  /  2
-                      \/  B   - 4*A*C
-      sol_2  = --------------------------------
-                       2*A
-
-
-      then in the distance formula we have only one variable x3 and that is easy
-      to calculate
-    */
-    int x1 = P1.y();
-    int y1 = P1.x();
-    int x2 = P2.y();
-    int y2 = P2.x();
-
-    if (x2 == x1) {
-        return QPointF(x1, y1 + (int)Distance);
-    }
-    float slope = ((float)y2 - (float)y1) / ((float)x2 - (float)x1);
-    float b = (y1 - slope*x1);
-    float A = (slope * slope) + 1;
-    float B = (2*slope*b) - (2*x1)  - (2*slope*y1);
-    float C = (b*b) - (Distance*Distance) + (x1*x1) + (y1*y1) - (2*b*y1);
-    float t = B*B - 4*A*C;
-
-    if (t < 0) {
-        return QPointF(-1, -1);
-    }
-    float sol_1 = ((-1* B) + sqrt(t)) / (2*A);
-    float sol_2 = ((-1*B) - sqrt(t)) / (2*A);
-
-    if (sol_1 < 0.0 && sol_2 < 0.0) {
-        return QPointF(-1, -1);
-    }
-    QPointF sol1Point((int)(slope*sol_1 + b), (int)(sol_1));
-    QPointF sol2Point((int)(slope*sol_2 + b), (int)(sol_2));
-    if (sol_1 < 0 && sol_2 >=0) {
-        if (x2 > x1) {
-            if (x1 <= sol_2 && sol_2 <= x2)
-                return sol2Point;
-        } else {
-            if (x2 <= sol_2 && sol_2 <= x1)
-                return sol2Point;
-        }
-    } else if (sol_1 >= 0 && sol_2 < 0) {
-        if (x2 > x1) {
-            if (x1 <= sol_1 && sol_1 <= x2)
-                return sol1Point;
-        } else {
-            if (x2 <= sol_1 && sol_1 <= x1)
-                return sol1Point;
-        }
-    } else {
-        if (x2 > x1) {
-            if (x1 <= sol_1 && sol_1 <= x2)
-                return sol1Point;
-            if (x1 <= sol_2 && sol_2 <= x2)
-                return sol2Point;
-        } else {
-            if (x2 <= sol_1 && sol_1 <= x1)
-                return sol1Point;
-            if (x2 <= sol_2 && sol_2 <= x1)
-                return sol2Point;
-        }
-    }
-    return QPointF(-1, -1);
-}
-
-/**
- * Calculates which point of a perpendicular line to segment P1P2 that contains P2
- *  has a distance equal to Distance from P2,
- * Lets say such point is P3,  the distance from P2 to P3 must be equal to Distance
- */
-QPointF AssociationWidget::calculatePointAtDistanceOnPerpendicular(const QPointF &P1, const QPointF &P2, float Distance)
-{
-    /*
-      the distance D between points (x2, y2) and (x3, y3) has the following formula:
-
-          ---     ------------------------------
-      D =    \   /         2             2
-              \ / (x3 - x2)  +  (y3 - y2)
-
-      D, x2 and y2 are known and line P2P3 is perpendicular to line (x1, y1)(x2, y2), so if the
-      line P1P2 has the formula y = m*x + b,
-      then      (x1 - x2)
-          m =  -----------, because it is perpendicular to line P1P2
-                (y2 - y1)
-
-      also y2 = m*x2 + b
-      => b = y2 - m*x2
-
-      then P3 = (x3, m*x3 + b)
-
-       2            2            2
-      D  = (x3 - x2)  + (y3 - y2)
-
-       2     2               2     2               2
-      D  = x3  - 2*x3*x2 + x2  + y3  - 2*y3*y2 + y2
-
-       2     2     2     2               2
-      D  - x2  - y2  = x3  - 2*x3*x2 + y3  - 2*y3*y2
-
-
-
-       2     2     2     2                       2
-      D  - x2  - y2  = x3  - 2*x3*x2 + (m*x3 + b)  - 2*(m*x3 + b)*y2
-
-       2     2     2                   2        2       2
-      D  - x2  - y2  + 2*b*y2 - b  = (m  + 1)*x3  + (-2*x2 + 2*m*b -2*m*y2)*x3
-
-              2       2       2              2
-      C  = - D    + x2    + y2   - 2*b*y2 + b
-
-             2
-      A  = (m  + 1)
-
-      B  = (-2*x2 + 2*m*b -2*m*y2)
-
-      and we have
-       2
-      A * x3 + B * x3 - C = 0
-
-
-                           ---------------
-                     ---  /  2
-                -B +    \/  B   - 4*A*C
-      sol_1 = --------------------------------
-                        2*A
-
-
-                           ---------------
-                     ---  /  2
-                -B -    \/  B   - 4*A*C
-      sol_2 = --------------------------------
-                        2*A
-
-      then in the distance formula we have only one variable x3 and that is easy
-      to calculate
-    */
-    if (P1.x() == P2.x()) {
-        return QPointF((int)(P2.x() + Distance), P2.y());
-    }
-    const int x1 = P1.y();
-    const int y1 = P1.x();
-    const int x2 = P2.y();
-    const int y2 = P2.x();
-
-    float slope = ((float)x1 - (float)x2) / ((float)y2 - (float)y1);
-    float b = (y2 - slope*x2);
-    float A = (slope * slope) + 1;
-    float B = (2*slope*b) - (2*x2) - (2*slope*y2);
-    float C = (b*b) - (Distance*Distance) + (x2*x2) + (y2*y2) - (2*b*y2);
-    float t = B*B - 4*A*C;
-    if (t < 0) {
-        return QPointF(-1, -1);
-    }
-    float sol_1 = ((-1* B) + sqrt(t)) / (2*A);
-
-    float sol_2 = ((-1*B) - sqrt(t)) / (2*A);
-
-    if (sol_1 < 0 && sol_2 < 0) {
-        return QPointF(-1, -1);
-    }
-    QPointF sol1Point((int)(slope*sol_1 + b), (int)sol_1);
-    QPointF sol2Point((int)(slope*sol_2 + b), (int)sol_2);
-    if (sol_1 < 0 && sol_2 >=0) {
-        return sol2Point;
-    } else if (sol_1 >= 0 && sol_2 < 0) {
-        return sol1Point;
-    } else {    // Choose one solution, either will work fine
-        if (slope >= 0) {
-            if (sol_1 <= sol_2)
-                return sol2Point;
-            else
-                return sol1Point;
-        } else {
-            if (sol_1 <= sol_2)
-                return sol1Point;
-            else
-                return sol2Point;
-        }
-
-    }
-    return QPointF(-1, -1);  // never reached, just keep compilers happy
-}
-
-/**
- * Calculates the intersection (PS) between line P1P2 and a perpendicular line containing
- * P3, the result is returned in ResultingPoint. and result value represents the distance
- * between ResultingPoint and P3; if this value is negative an error ocurred.
- */
-float AssociationWidget::perpendicularProjection(const QPointF& P1, const QPointF& P2, const QPointF& P3,
-        QPointF& ResultingPoint)
-{
-    //line P1P2 is Line 1 = y=slope1*x + b1
-
-    //line P3PS is Line 1 = y=slope2*x + b2
-
-    float slope2 = 0;
-    float slope1 = 0;
-    float sx = 0, sy = 0;
-    int y2 = P2.x();
-    int y1 = P1.x();
-    int x2 = P2.y();
-    int x1 = P1.y();
-    int y3 = P3.x();
-    int x3 = P3.y();
-    float distance = 0;
-    float b1 = 0;
-
-    float b2 = 0;
-
-    if (x2 == x1) {
-        sx = x2;
-        sy = y3;
-    } else if (y2 == y1) {
-        sy = y2;
-        sx = x3;
-    } else {
-        slope1 = (y2 - y1)/ (x2 - x1);
-        slope2 = (x1 - x2)/ (y2 - y1);
-        b1 = y2 - (slope1 * x2);
-        b2 = y3 - (slope2 * x3);
-        sx = (b2 - b1) / (slope1 - slope2);
-        sy = slope1*sx + b1;
-    }
-    distance = (int)(sqrt(((x3 - sx)*(x3 - sx)) + ((y3 - sy)*(y3 - sy))));
-
-    ResultingPoint.setX((int)sy);
-    ResultingPoint.setY((int)sx);
-
-    return distance;
-}
-#endif
-
-/**
- * Calculates the position of the text widget depending on the role
- * that widget is playing.
- * Returns the point at which to put the widget.
- */
-QPointF AssociationWidget::calculateTextPosition(Uml::TextRole::Enum role)
-{
-    const int SPACE = 2;
-    QPointF p(-1, -1), q(-1, -1);
-
-    // used to find out if association end point (p)
-    // is at top or bottom edge of widget.
-
-    if (role == TextRole::MultiA || role == TextRole::ChangeA || role == TextRole::RoleAName) {
-        p = m_associationLine->point(0);
-        q = m_associationLine->point(1);
-    } else if (role == TextRole::MultiB || role == TextRole::ChangeB || role == TextRole::RoleBName) {
-        const int lastSegment = m_associationLine->count() - 1;
-        p = m_associationLine->point(lastSegment);
-        q = m_associationLine->point(lastSegment - 1);
-    } else if (role != TextRole::Name) {
-        uError() << "called with unsupported TextRole::Enum " << role;
-        return QPointF(-1, -1);
-    }
-
-    FloatingTextWidget *text = textWidgetByRole(role);
-    int textW = 0, textH = 0;
-    if (text) {
-        textW = text->width();
-        textH = text->height();
-    }
-
-    qreal x = 0.0, y = 0.0;
-
-    if (role == TextRole::MultiA || role == TextRole::MultiB) {
-        const bool isHorizontal = (p.y() == q.y());
-        const int atBottom = p.y() + SPACE;
-        const int atTop = p.y() - SPACE - textH;
-        const int atLeft = p.x() - SPACE - textW;
-        const int atRight = p.x() + SPACE;
-        y = (p.y() > q.y()) == isHorizontal ? atBottom : atTop;
-        x = (p.x() < q.x()) == isHorizontal ? atRight : atLeft;
-
-    } else if (role == TextRole::ChangeA || role == TextRole::ChangeB) {
-
-        if (p.y() > q.y())
-            y = p.y() - SPACE - (textH * 2);
-        else
-            y = p.y() + SPACE + textH;
-
-        if (p.x() < q.x())
-            x = p.x() + SPACE;
-        else
-            x = p.x() - SPACE - textW;
-
-    } else if (role == TextRole::RoleAName || role == TextRole::RoleBName) {
-
-        if (p.y() > q.y())
-            y = p.y() - SPACE - textH;
-        else
-            y = p.y() + SPACE;
-
-        if (p.x() < q.x())
-            x = p.x() + SPACE;
-        else
-            x = p.x() - SPACE - textW;
-
-    } else if (role == TextRole::Name) {
-
-        calculateNameTextSegment();
-        if (m_unNameLineSegment == -1) {
-            uWarning() << "TODO:negative line segment index";
-            m_unNameLineSegment = 0;
-        }
-        x = ( m_associationLine->point(m_unNameLineSegment).x() +
-                     m_associationLine->point(m_unNameLineSegment + 1).x() ) / 2;
-        y = ( m_associationLine->point(m_unNameLineSegment).y() +
-                     m_associationLine->point(m_unNameLineSegment + 1).y() ) / 2;
-    }
-
-    if (text) {
-        constrainTextPos(x, y, textW, textH, role);
-    }
-    p = QPointF( x, y );
-    return p;
-}
-
-/**
- * Return the mid point between p0 and p1
- */
-QPointF AssociationWidget::midPoint(const QPointF& p0, const QPointF& p1)
-{
-    QPointF midP;
-    if (p0.x() < p1.x())
-        midP.setX(p0.x() + (p1.x() - p0.x()) / 2);
-    else
-        midP.setX(p1.x() + (p0.x() - p1.x()) / 2);
-    if (p0.y() < p1.y())
-        midP.setY(p0.y() + (p1.y() - p0.y()) / 2);
-    else
-        midP.setY(p1.y() + (p0.y() - p1.y()) / 2);
-    return midP;
-}
-
-/**
- * Constrains the FloatingTextWidget X and Y values supplied.
- * Implements the abstract operation from LinkWidget.
- *
- * @param textX       Candidate X value (may be modified by the constraint.)
- * @param textY       Candidate Y value (may be modified by the constraint.)
- * @param textWidth   Width of the text.
- * @param textHeight  Height of the text.
- * @param tr          Uml::Text_Role of the text.
- */
-void AssociationWidget::constrainTextPos(qreal &textX, qreal &textY,
-                                         qreal textWidth, qreal textHeight,
-                                         Uml::TextRole::Enum tr)
-{
-    const int textCenterX = textX + textWidth / 2;
-    const int textCenterY = textY + textHeight / 2;
-    const int lastSegment = m_associationLine->count() - 1;
-    QPointF p0, p1;
-    switch (tr) {
-        case TextRole::RoleAName:
-        case TextRole::MultiA:
-        case TextRole::ChangeA:
-            p0 = m_associationLine->point(0);
-            p1 = m_associationLine->point(1);
-            // If we are dealing with a single line then tie the
-            // role label to the proper half of the line, i.e.
-            // the role label must be closer to the "other"
-            // role object.
-            if (lastSegment == 1)
-                p1 = midPoint(p0, p1);
-            break;
-        case TextRole::RoleBName:
-        case TextRole::MultiB:
-        case TextRole::ChangeB:
-            p0 = m_associationLine->point(lastSegment - 1);
-            p1 = m_associationLine->point(lastSegment);
-            if (lastSegment == 1)
-                p0 = midPoint(p0, p1);
-            break;
-        case TextRole::Name:
-        case TextRole::Coll_Message:  // CHECK: collab.msg texts seem to be TextRole::Name
-        case TextRole::State:         // CHECK: is this used?
-            // Find the linepath segment to which the (textX, textY) is closest
-            // and constrain to the corridor of that segment (see farther below)
-            {
-                int minDistSquare = 100000;  // utopian initial value
-                int lpIndex = 0;
-                for (int i = 0; i < lastSegment; ++i) {
-                    p0 = m_associationLine->point(i);
-                    p1 = m_associationLine->point(i + 1);
-                    QPointF midP = midPoint(p0, p1);
-                    const int deltaX = textCenterX - midP.x();
-                    const int deltaY = textCenterY - midP.y();
-                    const int cSquare = deltaX * deltaX + deltaY * deltaY;
-                    if (cSquare < minDistSquare) {
-                        minDistSquare = cSquare;
-                        lpIndex = i;
-                    }
-                }
-                p0 = m_associationLine->point(lpIndex);
-                p1 = m_associationLine->point(lpIndex + 1);
-            }
-            break;
-        default:
-            uError() << "unexpected TextRole::Enum " << tr;
-            return;
-            break;
-    }
-    /* Constraint:
-       The midpoint between p0 and p1 is taken to be the center of a circle
-       with radius D/2 where D is the distance between p0 and p1.
-       The text center needs to be within this circle else it is constrained
-       to the nearest point on the circle.
-     */
-    p0 = swapXY(p0);    // go to the natural coordinate system
-    p1 = swapXY(p1);    // with (0,0) in the lower left corner
-    QPointF midP = midPoint(p0, p1);
-    // If (textX,textY) is not inside the circle around midP then
-    // constrain (textX,textY) to the nearest point on that circle.
-    const int x0 = p0.x();
-    const int y0 = p0.y();
-    const int x1 = p1.x();
-    const int y1 = p1.y();
-    double r = sqrt((double)((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0))) / 2;
-    if (textWidth > r)
-        r = textWidth;
-    // swap textCenter{X,Y} to convert from Qt coord.system.
-    const QPointF origTextCenter(textCenterY, textCenterX);
-    const int relX = abs(origTextCenter.x() - midP.x());
-    const int relY = abs(origTextCenter.y() - midP.y());
-    const double negativeWhenInsideCircle = relX * relX + relY * relY - r * r;
-    if (negativeWhenInsideCircle <= 0.0) {
-        return;
-    }
-    /*
-     The original constraint was to snap the text position to the
-     midpoint but that creates unpleasant visual jitter:
-    textX = midP.y() - textWidth / 2;   // go back to Qt coord.sys.
-    textY = midP.x() - textHeight / 2;  // go back to Qt coord.sys.
-
-     Rather, we project the text position onto the closest point
-     on the circle:
-
-     Circle equation:
-       relX^2 + relY^2 - r^2 = 0, or in other words
-       relY^2 = r^2 - relX^2, or
-       relY = sqrt(r^2 - relX^2)
-     Line equation:
-       relY = a * relX + b
-         We can omit "b" because relX and relY are already relative to
-         the circle origin, therefore we can also write:
-       a = relY / relX
-     To obtain the point of intersection between the circle of radius r
-     and the line connecting the circle origin with the point (relX, relY),
-     we equate the relY:
-       a * x = sqrt(r^2 - x^2), or in other words
-       a^2 * x^2 = r^2 - x^2, or
-       x^2 * (a^2 + 1) = r^2, or
-       x^2 = r^2 / (a^2 + 1), or
-       x = sqrt(r^2 / (a^2 + 1))
-     and then
-       y = a * x
-     The resulting x and y are relative to the circle origin so we just add
-     the circle origin (X, Y) to obtain the constrained (textX, textY).
-     */
-    // Handle the special case, relX = 0.
-    if (relX == 0) {
-        if (origTextCenter.y() > midP.y())
-            textX = midP.y() + (int)r;   // go back to Qt coord.sys.
-        else
-            textX = midP.y() - (int)r;   // go back to Qt coord.sys.
-        textX -= textWidth / 2;
-        return;
-    }
-    const double a = (double)relY / (double)relX;
-    const double x = sqrt(r*r / (a*a + 1));
-    const double y = a * x;
-    if (origTextCenter.x() > midP.x())
-        textY = midP.x() + (int)x;   // go back to Qt coord.sys.
-    else
-        textY = midP.x() - (int)x;   // go back to Qt coord.sys.
-    textY -= textHeight / 2;
-    if (origTextCenter.y() > midP.y())
-        textX = midP.y() + (int)y;   // go back to Qt coord.sys.
-    else
-        textX = midP.y() - (int)y;   // go back to Qt coord.sys.
-    textX -= textWidth / 2;
-}
-
-/**
- * Puts the text widget with the given role at the given position.
- * This method calls @ref calculateTextPostion to get the needed position.
- * I.e. the line segment it is on has moved and it should move the same
- * amount as the line.
- */
-void AssociationWidget::setTextPosition(Uml::TextRole::Enum role)
-{
-    bool startMove = false;
-    if (m_role[RoleType::A].multiplicityWidget && m_role[RoleType::A].multiplicityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::B].multiplicityWidget && m_role[RoleType::B].multiplicityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::A].changeabilityWidget && m_role[RoleType::A].changeabilityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::B].changeabilityWidget && m_role[RoleType::B].changeabilityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::A].roleWidget  && m_role[RoleType::A].roleWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::B].roleWidget  && m_role[RoleType::B].roleWidget->getStartMove())
-        startMove = true;
-    else if (m_nameWidget && m_nameWidget->getStartMove())
-        startMove = true;
-    if (startMove) {
-        return;
-    }
-    FloatingTextWidget *ft = textWidgetByRole(role);
-    if (ft == NULL)
-        return;
-    QPointF pos = calculateTextPosition(role);
-    ft->setX(pos.x());
-    ft->setY(pos.y());
-}
-
-/**
- * Moves the text widget with the given role by the difference between
- * the two points.
- */
-void AssociationWidget::setTextPositionRelatively(Uml::TextRole::Enum role, const QPointF &oldPosition)
-{
-    bool startMove = false;
-    if (m_role[RoleType::A].multiplicityWidget && m_role[RoleType::A].multiplicityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::B].multiplicityWidget && m_role[RoleType::B].multiplicityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::A].changeabilityWidget && m_role[RoleType::A].changeabilityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::B].changeabilityWidget && m_role[RoleType::B].changeabilityWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::A].roleWidget  && m_role[RoleType::A].roleWidget->getStartMove())
-        startMove = true;
-    else if (m_role[RoleType::B].roleWidget  && m_role[RoleType::B].roleWidget->getStartMove())
-        startMove = true;
-    else if (m_nameWidget && m_nameWidget->getStartMove())
-        startMove = true;
-
-    if (startMove) {
-        return;
-    }
-    FloatingTextWidget *ft = textWidgetByRole(role);
-    if (ft == NULL)
-        return;
-    qreal ftX = ft->x();
-    qreal ftY = ft->y();
-
-    QPointF pos = calculateTextPosition(role);
-    int relX = pos.x() - oldPosition.x();
-    int relY = pos.y() - oldPosition.y();
-    qreal ftNewX = ftX + relX;
-    qreal ftNewY = ftY + relY;
-
-    bool oldIgnoreSnapToGrid = ft->getIgnoreSnapToGrid();
-    ft->setIgnoreSnapToGrid(true);
-    ft->setX(ftNewX);
-    ft->setY(ftNewY);
-    ft->setIgnoreSnapToGrid(oldIgnoreSnapToGrid);
-}
-
-/**
- * Remove dashed connecting line for association class.
- */
-void AssociationWidget::removeAssocClassLine()
-{
-    delete m_pAssocClassLineSel0;
-    m_pAssocClassLineSel0 = 0;
-    delete m_pAssocClassLineSel1;
-    m_pAssocClassLineSel1 = 0;
-    delete m_pAssocClassLine;
-    m_pAssocClassLine = 0;
-    if (m_associationClass) {
-        m_associationClass->setClassAssociationWidget(0);
-        m_associationClass = 0;
-    }
-}
-
-/**
- * Creates the association class connecting line.
- */
-void AssociationWidget::createAssocClassLine()
-{
-    if (m_pAssocClassLine == NULL) {
-        m_pAssocClassLine = new QGraphicsLineItem(this);
-    }
-    QPen pen(lineColor(), lineWidth(), Qt::DashLine);
-    m_pAssocClassLine->setPen(pen);
-    // decoration points
-    m_pAssocClassLineSel0 = Widget_Utils::decoratePoint(m_pAssocClassLine->line().p1(),
-                                                        m_pAssocClassLine);
-    m_pAssocClassLineSel1 = Widget_Utils::decoratePoint(m_pAssocClassLine->line().p2(),
-                                                        m_pAssocClassLine);
-    computeAssocClassLine();
-    selectAssocClassLine(false);
-}
-
-/**
- * Creates the association class connecting line using the specified
- * ClassifierWidget.
- *
- * @param classifier The ClassifierWidget to use.
- * @param linePathSegmentIndex The index of the segment where the
- *        association class is created.
- */
-void AssociationWidget::createAssocClassLine(ClassifierWidget* classifier,
-                                             int linePathSegmentIndex)
-{
-    m_nLinePathSegmentIndex = linePathSegmentIndex;
-
-    if (m_nLinePathSegmentIndex < 0) {
-        return;
-    }
-
-    m_associationClass = classifier;
-    m_associationClass->setClassAssociationWidget(this);
-    m_associationClass->addAssoc(this);  // to get widgetMoved(...) for association classes
-
-    createAssocClassLine();
-}
-
-/**
- * Compute the end points of m_pAssocClassLine in case this
- * association has an attached association class.
- * TODO: The decoration points make no sense for now, because they are not movable.
- */
-void AssociationWidget::computeAssocClassLine()
-{
-    if (m_associationClass == NULL || m_pAssocClassLine == NULL) {
-        return;
-    }
-    if (m_nLinePathSegmentIndex < 0) {
-        uError() << "m_nLinePathSegmentIndex is not set";
-        return;
-    }
-
-    QPointF segStart = m_associationLine->point(m_nLinePathSegmentIndex);
-    QPointF segEnd = m_associationLine->point(m_nLinePathSegmentIndex + 1);
-    const qreal midSegX = segStart.x() + (segEnd.x() - segStart.x()) / 2.0;
-    const qreal midSegY = segStart.y() + (segEnd.y() - segStart.y()) / 2.0;
-    QPointF segmentMidPoint(midSegX, midSegY);
-
-    QLineF possibleAssocLine = QLineF(segmentMidPoint,
-                                      m_associationClass->mapRectToScene(m_associationClass->rect()).center());
-    QPointF intersectionPoint;
-    QLineF::IntersectType type = intersect(m_associationClass->mapRectToScene(m_associationClass->boundingRect()),
-                                           possibleAssocLine,
-                                           &intersectionPoint);
-    // DEBUG(DBG_SRC) << "intersect type=" << type << " / point=" << intersectionPoint;
-
-    if (type == QLineF::BoundedIntersection) {
-        m_pAssocClassLine->setLine(midSegX, midSegY,
-                                   intersectionPoint.x(), intersectionPoint.y());
-
-        if (m_pAssocClassLineSel0 && m_pAssocClassLineSel1) {
-            m_pAssocClassLineSel0->setPos(m_pAssocClassLine->line().p1());
-            m_pAssocClassLineSel1->setPos(m_pAssocClassLine->line().p2());
-        }
-    }
-}
-
-/**
- * Renders the association class connecting line selected.
- */
-void AssociationWidget::selectAssocClassLine(bool sel)
-{
-    if (m_pAssocClassLineSel0 && m_pAssocClassLineSel1) {
-        m_pAssocClassLineSel0->setVisible(sel);
-        m_pAssocClassLineSel1->setVisible(sel);
-    }
-}
-
-/**
- * Sets the association to be selected.
- */
-void AssociationWidget::mousePressEvent(QGraphicsSceneMouseEvent * me)
-{
-    // clear other selected stuff on the screen of ShiftKey
-    if (me->modifiers() != Qt::ShiftModifier) {
-        m_scene->clearSelected();
-    }
-
-    if (me->button() == Qt::LeftButton && me->modifiers() == Qt::ControlModifier) {
-        if (checkRemovePoint(me->scenePos()))
-            return;
-    }
-
-    // make sure we should be here depending on the button
-    if (me->button() != Qt::RightButton && me->button() != Qt::LeftButton) {
-        return;
-    }
-    QPointF mep = me->scenePos();
-    // see if `mep' is on the connecting line to the association class
-    if (onAssocClassLine(mep)) {
-        setSelected(true);
-        selectAssocClassLine();
-        return;
-    }
-    setSelected(!isSelected());
-    associationLine()->mousePressEvent(me);
-}
-
-/**
- * Displays the right mouse buttom menu if right button is pressed.
- */
-void AssociationWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent * me)
-{
-    associationLine()->mouseReleaseEvent(me);
-}
-
-/**
- * Handles the selection from the popup menu.
- */
-void AssociationWidget::slotMenuSelection(QAction* action)
-{
-    QString oldText, newText;
-    QRegExpValidator v(QRegExp(QLatin1String(".*")), 0);
-    Uml::AssociationType::Enum atype = associationType();
-    Uml::RoleType::Enum r = RoleType::B;
-    ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
-    DEBUG(DBG_SRC) << "menu selection = " << ListPopupMenu::toString(sel);
-
-    // if it's a collaboration message we now just use the code in floatingtextwidget
-    // this means there's some redundant code below but that's better than duplicated code
-    if (isCollaboration() && sel != ListPopupMenu::mt_Delete) {
-        m_nameWidget->slotMenuSelection(action);
-        return;
-    }
-
-    switch(sel) {
-    case ListPopupMenu::mt_Properties:
-        if (atype == AssociationType::Seq_Message || atype == AssociationType::Seq_Message_Self) {
-            // show op dlg for seq. diagram here
-            // don't worry about here, I don't think it can get here as
-            // line is widget on seq. diagram
-            // here just in case - remove later after testing
-            DEBUG(DBG_SRC) << "mt_Properties: assoctype is " << atype;
-        } else {  //standard assoc dialog
-            UMLApp::app()->docWindow()->updateDocumentation(false);
-            showPropertiesDialog();
-        }
-        break;
-
-    case ListPopupMenu::mt_Add_Point:
-        checkAddPoint(m_eventScenePos);
-        break;
-
-    case ListPopupMenu::mt_Delete_Point:
-        checkRemovePoint(m_eventScenePos);
-        break;
-
-    case ListPopupMenu::mt_Delete:
-        if (m_pAssocClassLineSel0)
-            removeAssocClassLine();
-        else if (association())
-            m_scene->removeAssocInViewAndDoc(this);
-        else
-            m_scene->removeAssoc(this);
-        break;
-
-    case ListPopupMenu::mt_Rename_MultiA:
-        r = RoleType::A;   // fall through
-    case ListPopupMenu::mt_Rename_MultiB:
-        if (m_role[r].multiplicityWidget)
-            oldText = m_role[r].multiplicityWidget->text();
-        else
-            oldText = QString();
-#if QT_VERSION >= 0x050000
-        newText = QInputDialog::getText(m_scene->activeView(),
-                                        i18n("Multiplicity"),
-                                        i18n("Enter multiplicity:"),
-                                        QLineEdit::Normal,
-                                        oldText, NULL);
-#else
-        newText = KInputDialog::getText(i18n("Multiplicity"),
-                                        i18n("Enter multiplicity:"),
-                                        oldText, NULL, m_scene->activeView(), &v);
-#endif
-        if (newText != oldText) {
-            if (FloatingTextWidget::isTextValid(newText)) {
-                setMultiplicity(newText, r);
-            } else {
-                m_scene->removeWidget(m_role[r].multiplicityWidget);
-                m_role[r].multiplicityWidget = NULL;
-            }
-        }
-        break;
-
-    case ListPopupMenu::mt_Rename_Name:
-        if (m_nameWidget)
-            oldText = m_nameWidget->text();
-        else
-            oldText = QString();
-#if QT_VERSION >= 0x050000
-        newText = QInputDialog::getText(m_scene->activeView(),
-                                        i18n("Association Name"),
-                                        i18n("Enter association name:"),
-                                        QLineEdit::Normal,
-                                        oldText, NULL);
-#else
-        newText = KInputDialog::getText(i18n("Association Name"),
-                                        i18n("Enter association name:"),
-                                        oldText, NULL, m_scene->activeView(), &v);
-#endif
-        if (newText != oldText) {
-            if (FloatingTextWidget::isTextValid(newText)) {
-                setName(newText);
-            } else {
-                m_scene->removeWidget(m_nameWidget);
-                m_nameWidget = NULL;
-            }
-        }
-        break;
-
-    case ListPopupMenu::mt_Rename_RoleAName:
-        r = RoleType::A;   // fall through
-    case ListPopupMenu::mt_Rename_RoleBName:
-        if (m_role[r].roleWidget)
-            oldText = m_role[r].roleWidget->text();
-        else
-            oldText = QString();
-#if QT_VERSION >= 0x050000
-        newText = QInputDialog::getText(m_scene->activeView(),
-                                        i18n("Role Name"),
-                                        i18n("Enter role name:"),
-                                        QLineEdit::Normal,
-                                        oldText, NULL);
-#else
-        newText = KInputDialog::getText(i18n("Role Name"),
-                                        i18n("Enter role name:"),
-                                        oldText, NULL, m_scene->activeView(), &v);
-#endif
-        if (newText != oldText) {
-            if (FloatingTextWidget::isTextValid(newText)) {
-                setRoleName(newText, r);
-            } else {
-                m_scene->removeWidget(m_role[r].roleWidget);
-                m_role[r].roleWidget = NULL;
-            }
-        }
-        break;
-
-    case ListPopupMenu::mt_Change_Font:
-        {
-#if QT_VERSION >= 0x050000
-            bool ok = false;
-            QFont fnt = QFontDialog::getFont(&ok, font(), m_scene->activeView());
-            if (ok)
-#else
-            QFont fnt = font();
-            if (KFontDialog::getFont(fnt, KFontChooser::NoDisplayFlags, m_scene->activeView()))
-#endif
-                lwSetFont(fnt);
-        }
-        break;
-
-    case ListPopupMenu::mt_Line_Color:
-        {
-#if QT_VERSION >= 0x050000
-            QColor newColor = QColorDialog::getColor(lineColor());
-            if (newColor != lineColor()) {
-#else
-            QColor newColor;
-            if (KColorDialog::getColor(newColor)) {
-#endif
-                m_scene->selectionSetLineColor(newColor);
-                umlDoc()->setModified(true);
-            }
-        }
-        break;
-
-    case ListPopupMenu::mt_Cut:
-        m_scene->setStartedCut();
-        UMLApp::app()->slotEditCut();
-        break;
-
-    case ListPopupMenu::mt_Copy:
-        UMLApp::app()->slotEditCopy();
-        break;
-
-    case ListPopupMenu::mt_Paste:
-        UMLApp::app()->slotEditPaste();
-        break;
-
-    case ListPopupMenu::mt_Reset_Label_Positions:
-        resetTextPositions();
-        break;
-
-    case ListPopupMenu::mt_LayoutDirect:
-        m_associationLine->setLayout(AssociationLine::Direct);
-        break;
-    case ListPopupMenu::mt_LayoutSpline:
-        m_associationLine->setLayout(AssociationLine::Spline);
-        break;
-    case ListPopupMenu::mt_LayoutOrthogonal:
-        m_associationLine->setLayout(AssociationLine::Orthogonal);
-        break;
-    case ListPopupMenu::mt_LayoutPolyline:
-        m_associationLine->setLayout(AssociationLine::Polyline);
-        break;
-
-    default:
-        DEBUG(DBG_SRC) << "MenuType " << ListPopupMenu::toString(sel) << " not implemented";
-        break;
-    }//end switch
-}
-
-/**
- * Return the first font found being used by any child widget. (They
- * could be different fonts, so this is a slightly misleading method.)
- */
-QFont AssociationWidget::font() const
-{
-    //:TODO: find a general font for the association
-    QFont font;
-
-    if (m_role[RoleType::A].roleWidget)
-        font = m_role[RoleType::A].roleWidget->font();
-    else    if (m_role[RoleType::B].roleWidget)
-        font = m_role[RoleType::B].roleWidget->font();
-    else    if (m_role[RoleType::A].multiplicityWidget)
-        font = m_role[RoleType::A].multiplicityWidget->font();
-    else    if (m_role[RoleType::B].multiplicityWidget)
-        font = m_role[RoleType::B].multiplicityWidget->font();
-    else    if (m_role[RoleType::A].changeabilityWidget)
-        font = m_role[RoleType::A].changeabilityWidget->font();
-    else    if (m_role[RoleType::B].changeabilityWidget)
-        font = m_role[RoleType::B].changeabilityWidget->font();
-    else    if (m_nameWidget)
-        font = m_nameWidget->font();
-    else
-        font = m_role[RoleType::A].umlWidget->font();
-
-    return font;
-}
-
-/**
- * Set all 'owned' child widgets to this text color.
- */
-void AssociationWidget::setTextColor(const QColor &color)
-{
-    WidgetBase::setTextColor(color);
-    if (m_nameWidget) {
-        m_nameWidget->setTextColor(color);
-    }
-    if (m_role[RoleType::A].roleWidget) {
-        m_role[RoleType::A].roleWidget->setTextColor(color);
-    }
-    if (m_role[RoleType::B].roleWidget) {
-        m_role[RoleType::B].roleWidget->setTextColor(color);
-    }
-    if (m_role[RoleType::A].multiplicityWidget) {
-        m_role[RoleType::A].multiplicityWidget->setTextColor(color);
-    }
-    if (m_role[RoleType::B].multiplicityWidget) {
-        m_role[RoleType::B].multiplicityWidget->setTextColor(color);
-    }
-    if (m_role[RoleType::A].changeabilityWidget)
-        m_role[RoleType::A].changeabilityWidget->setTextColor(color);
-    if (m_role[RoleType::B].changeabilityWidget)
-        m_role[RoleType::B].changeabilityWidget->setTextColor(color);
-}
-
-bool AssociationWidget::checkAddPoint(const QPointF &scenePos)
-{
-    if (associationType() == AssociationType::Exception) {
-        return false;
-    }
-
-    // if there is no point around the mouse pointer, we insert a new one
-    if (m_associationLine->closestPointIndex(scenePos) < 0) {
-        int i = m_associationLine->closestSegmentIndex(scenePos);
-        if (i < 0) {
-            DEBUG(DBG_SRC) << "no closest segment found!";
-            return false;
-        }
-        m_associationLine->insertPoint(i + 1, scenePos);
-        if (m_nLinePathSegmentIndex == i) {
-            QPointF segStart = m_associationLine->point(i);
-            QPointF segEnd = m_associationLine->point(i + 2);
-            const int midSegX = segStart.x() + (segEnd.x() - segStart.x()) / 2;
-            const int midSegY = segStart.y() + (segEnd.y() - segStart.y()) / 2;
-            /*
-            DEBUG(DBG_SRC) << "segStart=" << segStart << ", segEnd=" << segEnd
-                           << ", midSeg=(" << midSegX << "," << midSegY
-                           << "), mp=" << mp;
-             */
-            if (midSegX > scenePos.x() || midSegY < scenePos.y()) {
-                m_nLinePathSegmentIndex++;
-                DEBUG(DBG_SRC) << "setting m_nLinePathSegmentIndex to "
-                               << m_nLinePathSegmentIndex;
-                computeAssocClassLine();
-            }
-            m_associationLine->update();
-            calculateNameTextSegment();
-            umlDoc()->setModified(true);
-            setSelected(true);
-        }
-        return true;
-    }
-    else {
-        DEBUG(DBG_SRC) << "found point already close enough!";
-        return false;
-    }
-}
-
-/**
- * Remove point close to the given point and redraw the association.
- * @param scenePos   point which should be removed
- * @return   success status of the remove action
- */
-bool AssociationWidget::checkRemovePoint(const QPointF &scenePos)
-{
-    int i = m_associationLine->closestPointIndex(scenePos);
-    if (i == -1)
-        return false;
-
-    m_associationLine->setSelected(false);
-
-    // there was a point so we remove the point
-    m_associationLine->removePoint(i);
-
-    // Maybe reattach association class connecting line
-    // to different association linepath segment.
-    const int numberOfLines = m_associationLine->count() - 1;
-    if (m_nLinePathSegmentIndex >= numberOfLines) {
-        m_nLinePathSegmentIndex = numberOfLines - 1;
-    }
-    calculateEndingPoints();
-
-    // select the line path
-    m_associationLine->setSelected(true);
-
-    m_associationLine->update();
-
-    calculateNameTextSegment();
-    umlDoc()->setModified(true);
-    return true;
-}
-
-/**
- * Moves the break point being dragged.
- */
-void AssociationWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* me)
-{
-    if (me->buttons() != Qt::LeftButton) {
-        return;
-    }
-
-    setSelected(true);
-
-    associationLine()->mouseMoveEvent(me);
-    moveEvent(me);
-    m_scene->resizeSceneToItems();
-}
-
-/**
- * Returns the Region the widget to line intersection is for the given
- * widget in this Association.  If the given widget is not in the
- * Association then Region::Error is returned.
- * Used by @ref calculateEndingPoints to work these positions out for
- * another Association - since the number of Associations on the same
- * region for the same widget will mean the lines will need to be
- * spread out across the region.
- */
-//Uml::Region::Enum AssociationWidget::getWidgetRegion(AssociationWidget * widget) const
-//{
-//    if (widget->widgetForRole(RoleType
[cell cut: 2650126 characters, first 2000000 kept]