Index: src/sas/qtgui/Perspectives/Fitting/Constraints.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/Constraints.py	(revision eae226b35388c002e867fa4776c854350a870842)
+++ src/sas/qtgui/Perspectives/Fitting/Constraints.py	(revision eae226b35388c002e867fa4776c854350a870842)
@@ -0,0 +1,69 @@
+class Constraint(object):
+    """
+    Internal representation of a single parameter constraint
+    """
+    def __init__(self, parent=None, param=None, value=0.0, min=None, max=None, func=None):
+        self._value = value
+        self._param = param
+        self._func = func
+        self.active = False
+        self._min = min
+        self._max = max
+
+    @property
+    def value(self):
+        return self._value
+
+    @value.setter
+    def value(self, val):
+        self._value = val
+
+    @property
+    def param(self):
+        return self._param
+
+    @param.setter
+    def param(self, val):
+        self._param = val
+
+    @property
+    def func(self):
+        return self._func
+
+    @func.setter
+    def func(self, val):
+        self._func = val
+
+    @property
+    def min(self):
+        return self._min
+
+    @min.setter
+    def min(self, val):
+        self._min = val
+
+    @property
+    def max(self):
+        return self._max
+
+    @max.setter
+    def max(self, val):
+        self._max = val
+
+    def delete(self, constraint=None):
+        pass
+
+
+class ConstrainedParameters(object):
+    """
+    Representation of two constrained parameters
+    """
+    def __init__(self, parent=None):
+        pass
+
+    def add(self, constraint=None):
+        pass
+
+    def delete(self, constraint=None):
+        pass
+
Index: src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision 0595bb7954497ab0a25be7ffb88395a048df52ae)
+++ src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision eae226b35388c002e867fa4776c854350a870842)
@@ -41,4 +41,6 @@
 from sas.qtgui.Perspectives.Fitting.ViewDelegate import PolyViewDelegate
 from sas.qtgui.Perspectives.Fitting.ViewDelegate import MagnetismViewDelegate
+from sas.qtgui.Perspectives.Fitting.Constraints import Constraint
+from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint
 
 
@@ -80,5 +82,5 @@
     Main widget for selecting form and structure factor models
     """
-    constraintAddedSignal = QtCore.pyqtSignal(list)
+    #constraintAddedSignal = QtCore.pyqtSignal(list)
     def __init__(self, parent=None, data=None, tab_id=1):
 
@@ -453,5 +455,5 @@
         # Respond to change in parameters from the UI
         self._model_model.itemChanged.connect(self.onMainParamsChange)
-        self.constraintAddedSignal.connect(self.modifyViewOnConstraint)
+        #self.constraintAddedSignal.connect(self.modifyViewOnConstraint)
         self._poly_model.itemChanged.connect(self.onPolyModelChange)
         self._magnet_model.itemChanged.connect(self.onMagnetModelChange)
@@ -462,5 +464,6 @@
     def showModelContextMenu(self, position):
 
-        rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()])
+        #rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()])
+        rows = [s.row() for s in self.lstParams.selectionModel().selectedRows()]
         menu = self.showModelDescription() if not rows else self.modelContextMenu(rows)
         try:
@@ -471,18 +474,28 @@
 
     def modelContextMenu(self, rows):
+        """
+        Create context menu for the given model
+        """
         menu = QtWidgets.QMenu()
-
+        num_rows = len(rows)
         # Select for fitting
+        param_string = "parameter " if num_rows==1 else "parameters "
+        to_string = "to its current value" if num_rows==1 else "to their current values"
+
         self.actionSelect = QtWidgets.QAction(self)
         self.actionSelect.setObjectName("actionSelect")
-        self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select parameter for fitting"))
+        self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select "+param_string+" for fitting"))
         # Unselect from fitting
         self.actionDeselect = QtWidgets.QAction(self)
         self.actionDeselect.setObjectName("actionDeselect")
-        self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select parameter from fitting"))
+        self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select "+param_string+" from fitting"))
 
         self.actionConstrain = QtWidgets.QAction(self)
         self.actionConstrain.setObjectName("actionConstrain")
-        self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain parameter to current value"))
+        self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain "+param_string + to_string))
+
+        self.actionRemoveConstraint = QtWidgets.QAction(self)
+        self.actionRemoveConstraint.setObjectName("actionRemoveConstrain")
+        self.actionRemoveConstraint.setText(QtCore.QCoreApplication.translate("self", "Remove constraint"))
 
         self.actionMultiConstrain = QtWidgets.QAction(self)
@@ -494,19 +507,18 @@
         self.actionMutualMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Mutual constrain of selected parameters..."))
 
-        #action.setDefaultWidget(label)
         menu.addAction(self.actionSelect)
         menu.addAction(self.actionDeselect)
         menu.addSeparator()
 
-        if rows == 1:
+        if self.rowHasConstraint(rows[0]):
+            menu.addAction(self.actionRemoveConstraint)
+        else:
             menu.addAction(self.actionConstrain)
-        elif rows == 2:
-            menu.addAction(self.actionMultiConstrain)
+        if num_rows == 2:
             menu.addAction(self.actionMutualMultiConstrain)
-        elif rows > 2:
-            menu.addAction(self.actionMultiConstrain)
 
         # Define the callbacks
         self.actionConstrain.triggered.connect(self.addSimpleConstraint)
+        self.actionRemoveConstraint.triggered.connect(self.deleteConstraint)
         self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstraint)
         self.actionSelect.triggered.connect(self.selectParameters)
@@ -518,30 +530,58 @@
         Show the constraint widget and receive the expression
         """
-        from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint
-        from .Constraints import Constraint
         selected_rows = self.lstParams.selectionModel().selectedRows()
+        assert(len(selected_rows), 2)
 
         params_list = [s.data() for s in selected_rows]
+        # Create and display the widget for param1 and param2
         mc_widget = MultiConstraint(self, params=params_list)
-        mc_widget.exec_()
+        if mc_widget.exec_() != QtWidgets.QDialog.Accepted:
+            return
+
         constraint = Constraint()
         c_text = mc_widget.txtConstraint.text()
-        # Pass the constraint to the parser
-
-        self.communicate.statusBarUpdateSignal.emit('Constraints added')
-        # Change the colour of the row
-        pass
-
-    def modifyViewOnConstraint(self, row):
-        """
-        Add visual cues that the parameter is constrained
-        """
-        value = self._model_model.item(row, 1).text()
-        # Set min/max to the value constrained
-        self._model_model.item(row,2).setText(value)
-        self._model_model.item(row,3).setText(value)
+
+        # widget.params[0] is the parameter we're constraining
+        constraint.param = mc_widget.params[0]
+        constraint.func = c_text
+
+        # Create a new item and add the Constraint object as a child
+        item = QtGui.QStandardItem()
+        item.setData(constraint)
+        # Which row is the constrained parameter in?
+
+        row = self.rowFromName(constraint.param)
+        self._model_model.item(row, 1).setChild(0, item)
+        #self.constraintAddedSignal.emit([row])
+        # Show visual hints for the constraint
         font = QtGui.QFont()
         font.setItalic(True)
         brush = QtGui.QBrush(QtGui.QColor('blue'))
+        self.modifyViewOnRow(row, font=font, brush=brush)
+
+        # Pass the constraint to the parser
+        self.communicate.statusBarUpdateSignal.emit('Constraints added')
+
+    def rowFromName(self, name):
+        """
+        given parameter name get the row number in self._model_model
+        """
+        for row in range(self._model_model.rowCount()):
+            row_name = self._model_model.item(row).text()
+            if row_name == name:
+                return row
+        return None
+
+    def modifyViewOnRow(self, row, font=None, brush=None):
+        """
+        Chage how the given row of the main model is shown
+        """
+        fields_enabled = False
+        if font is None:
+            font = QtGui.QFont()
+            fields_enabled = True
+        if brush is None:
+            brush = QtGui.QBrush()
+            fields_enabled = True
         self._model_model.blockSignals(True)
         # Modify font and foreground of affected rows
@@ -549,5 +589,5 @@
             self._model_model.item(row, column).setForeground(brush)
             self._model_model.item(row, column).setFont(font)
-            self._model_model.item(row, column).setEditable(False)
+            self._model_model.item(row, column).setEditable(fields_enabled)
         self._model_model.blockSignals(False)
 
@@ -556,16 +596,53 @@
         Adds a constraint on a single parameter.
         """
-        from .Constraints import Constraint
         for row in self.selectedParameters():
             param = self._model_model.item(row, 0).text()
             value = self._model_model.item(row, 1).text()
-            constraint = Constraint(param=param, value=value)
+            min = self._model_model.item(row, 2).text()
+            max = self._model_model.item(row, 3).text()
+            # Create a Constraint object
+            constraint = Constraint(param=param, value=value, min=min, max=max)
+            # Create a new item and add the Constraint object as a child
             item = QtGui.QStandardItem()
             item.setData(constraint)
             self._model_model.item(row, 1).setChild(0, item)
+            # Set min/max to the value constrained
+            self._model_model.item(row,2).setText(value)
+            self._model_model.item(row,3).setText(value)
             #self.constraintAddedSignal.emit([row])
-            self.modifyViewOnConstraint(row)
+            # Show visual hints for the constraint
+            font = QtGui.QFont()
+            font.setItalic(True)
+            brush = QtGui.QBrush(QtGui.QColor('blue'))
+            self.modifyViewOnRow(row, font=font, brush=brush)
         self.communicate.statusBarUpdateSignal.emit('Constraint added')
         pass
+
+    def deleteConstraint(self):
+        """
+        Delete constraints from selected parameters.
+        """
+        for row in self.selectedParameters():
+            # Get the Constraint object from of the model item
+            item = self._model_model.item(row, 1)
+            constraint = item.child(0).data()
+            # Retrieve old values and put them on the model
+            if constraint.min is not None:
+                self._model_model.item(row, 2).setText(constraint.min)
+            if constraint.max is not None:
+                self._model_model.item(row, 3).setText(constraint.max)
+            # Remove constraint item
+            item.removeRow(0)
+            #self.constraintAddedSignal.emit([row])
+            self.modifyViewOnRow(row)
+        self.communicate.statusBarUpdateSignal.emit('Constraint removed')
+        pass
+
+    def rowHasConstraint(self, row):
+        """
+        Finds out if row of the main model has a constraint child
+        """
+        item = self._model_model.item(row,1)
+        return True if (item.hasChildren() and isinstance(item.child(0).data(), Constraint)) else False
 
     def selectParameters(self):
@@ -964,5 +1041,5 @@
             np.any(res.pvec is None) or \
             not np.all(np.isfinite(res.pvec)):
-            msg = "Fitting did not converge!!!"
+            msg = "Fitting did not converge!"
             self.communicate.statusBarUpdateSignal.emit(msg)
             logging.error(msg)
Index: src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py	(revision 0595bb7954497ab0a25be7ffb88395a048df52ae)
+++ src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py	(revision eae226b35388c002e867fa4776c854350a870842)
@@ -36,5 +36,11 @@
         switch M1 <-> M2
         """
+        # Switch parameters
         self.params[1], self.params[0] = self.params[0], self.params[1]
+        # Try to swap parameter names in the line edit
+        current_text = self.txtConstraint.text()
+        new_text = current_text.replace(self.params[0], self.params[1])
+        self.txtConstraint.setText(new_text)
+        # Update labels and tooltips
         self.setupLabels()
         self.setupTooltip()
@@ -88,10 +94,9 @@
         # 2. ensure the text contains parameter name
         parameter_string_start = constraint_text.find(param_str)
-        has_parameter_name = (parameter_string_start > -1)
-        if not has_parameter_name:
+        if parameter_string_start < 0:
             return False
         parameter_string_end = parameter_string_start + len(param_str)
 
-        # 3. parameter name should be a separate word, but can have "()[]*+-/" around
+        # 3. parameter name should be a separate word, but can have "()[]*+-/ " around
         valid_neighbours = "()[]*+-/ "
         has_only_parameter = False
Index: src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui	(revision 7fd20fcaad0240e364298e5839ff98bd609bacb4)
+++ src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui	(revision eae226b35388c002e867fa4776c854350a870842)
@@ -10,5 +10,5 @@
     <x>0</x>
     <y>0</y>
-    <width>335</width>
+    <width>369</width>
     <height>143</height>
    </rect>
@@ -158,4 +158,21 @@
  </widget>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>cmdOK</sender>
+   <signal>clicked()</signal>
+   <receiver>MultiConstraintUI</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>321</x>
+     <y>121</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>184</x>
+     <y>71</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
 </ui>
