diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt
index 5d4d9ea06427e35ef69c270c5678ede94820e9c9..1716ea2bf1011cda47fd21b273d9173309cc7319 100644
--- a/Code/Mantid/MantidPlot/CMakeLists.txt
+++ b/Code/Mantid/MantidPlot/CMakeLists.txt
@@ -204,6 +204,8 @@ set ( MANTID_SRCS  src/Mantid/AbstractMantidLog.cpp
                    src/Mantid/InstrumentWidget/UnwrappedSurface.cpp
                    src/Mantid/InstrumentWidget/ProjectionSurface.cpp
                    src/Mantid/InstrumentWidget/Projection3D.cpp
+                   src/Mantid/InstrumentWidget/PeakMarker2D.cpp
+                   src/Mantid/InstrumentWidget/PeakOverlay.cpp
                    src/Mantid/InstrumentWidget/OneCurvePlot.cpp
                    src/Mantid/InstrumentWidget/CollapsiblePanel.cpp
                    src/Mantid/InstrumentWidget/DetSelector.cpp
@@ -411,6 +413,8 @@ set ( MANTID_HDRS  src/Mantid/AbstractMantidLog.h
                    src/Mantid/InstrumentWidget/UnwrappedCylinder.h
                    src/Mantid/InstrumentWidget/UnwrappedSphere.h
                    src/Mantid/InstrumentWidget/UnwrappedSurface.h
+                   src/Mantid/InstrumentWidget/PeakMarker2D.h
+                   src/Mantid/InstrumentWidget/PeakOverlay.h
                    src/Mantid/InstrumentWidget/ProjectionSurface.h
                    src/Mantid/InstrumentWidget/Projection3D.h
                    src/Mantid/InstrumentWidget/OneCurvePlot.h
@@ -653,6 +657,7 @@ set ( MANTID_MOC_FILES src/Mantid/AlgMonitor.h
                        src/Mantid/InstrumentWidget/OneCurvePlot.h
                        src/Mantid/InstrumentWidget/CollapsiblePanel.h
                        src/Mantid/InstrumentWidget/InstrumentActor.h
+                       src/Mantid/InstrumentWidget/PeakOverlay.h
                        src/Mantid/InstrumentWidget/ProjectionSurface.h
                        src/Mantid/InstrumentWidget/Shape2DCollection.h
 )
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
index 2884c7ba39d83e303b39f171daa74d33ba6be5b1..c3fd3742df61d9988d4ba7b2b17c5eac7ef7b2e2 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/InstrumentWindowPickTab.cpp
@@ -4,6 +4,7 @@
 #include "CollapsiblePanel.h"
 #include "InstrumentActor.h"
 #include "ProjectionSurface.h"
+#include "PeakMarker2D.h"
 
 #include "MantidKernel/ConfigService.h"
 #include "MantidAPI/AnalysisDataService.h"
@@ -344,8 +345,13 @@ void InstrumentWindowPickTab::getBinMinMaxIndex(size_t wi,size_t& imin, size_t&
   }
 }
 
+/**
+ * Plot data for a detector.
+ * @param detid :: ID of the detector to be plotted.
+ */
 void InstrumentWindowPickTab::plotSingle(int detid)
 {
+  m_plot->clearLabels();
   InstrumentActor* instrActor = m_instrWindow->getInstrumentActor();
   Mantid::API::MatrixWorkspace_const_sptr ws = instrActor->getWorkspace();
   size_t wi;
@@ -354,8 +360,11 @@ void InstrumentWindowPickTab::plotSingle(int detid)
   } catch (Mantid::Kernel::Exception::NotFoundError) {
     return; // Detector doesn't have a workspace index relating to it
   }
+  // get the data
   const Mantid::MantidVec& x = ws->readX(wi);
   const Mantid::MantidVec& y = ws->readY(wi);
+
+  // find min and max for x
   size_t imin,imax;
   getBinMinMaxIndex(wi,imin,imax);
 
@@ -364,16 +373,26 @@ void InstrumentWindowPickTab::plotSingle(int detid)
 
   m_plot->setXScale(x[imin],x[imax]);
 
+  // fins min and max for y
   Mantid::MantidVec::const_iterator min_it = std::min_element(y_begin,y_end);
   Mantid::MantidVec::const_iterator max_it = std::max_element(y_begin,y_end);
+  // set the data 
   m_plot->setData(&x[0],&y[0],static_cast<int>(y.size()));
   m_plot->setYScale(*min_it,*max_it);
+
+  // find any markers
+  ProjectionSurface* surface = mInstrumentDisplay->getSurface();
+  if (surface)
+  {
+    QList<PeakMarker2D*> markers = surface->getPeakOverlay().getMarkersWithID(detid);
+    foreach(PeakMarker2D* marker,markers)
+    {
+      m_plot->addLabel(new PeakLabel(marker));
+      //std::cerr << marker->getLabel().toStdString() << std::endl;
+    }
+  }
 }
 
-//void InstrumentWindowPickTab::plotBox(const Instrument3DWidget::DetInfo & /*cursorPos*/)
-//{
-//}
-//
 void InstrumentWindowPickTab::plotTube(int detid)
 {
   InstrumentActor* instrActor = m_instrWindow->getInstrumentActor();
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.cpp
index cfbd35ecdf77aa639d5a7bfe7c4063c4a45a08d1..95d417314bea015177a526cdf4fb9741652c0fca 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.cpp
@@ -1,4 +1,5 @@
 #include "OneCurvePlot.h"
+#include "PeakMarker2D.h"
 
 #include <qwt_plot_curve.h>
 #include <qwt_scale_div.h>
@@ -11,6 +12,7 @@
 #include <QFontMetrics>
 #include <QMouseEvent>
 #include <QContextMenuEvent>
+#include <QPainter>
 
 #include <iostream>
 
@@ -182,3 +184,39 @@ void OneCurvePlot::setYLinearScale()
   update();
 }
 
+/**
+ * Add new peak label
+ * @param label :: A pointer to a PeakLabel, becomes owned by OneCurvePlot
+ */
+void OneCurvePlot::addLabel(PeakLabel* label)
+{
+  label->attach(this);
+  m_peakLabels.append(label);
+}
+
+/**
+ * Removes all peak labels.
+ */
+void OneCurvePlot::clearLabels()
+{
+  foreach(PeakLabel* label, m_peakLabels)
+  {
+    label->detach();
+    delete label;
+  }
+  m_peakLabels.clear();
+}
+
+
+/**
+ * Draw PeakLabel on a plot
+ */
+void PeakLabel::draw(QPainter *painter, 
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRect &canvasRect) const
+{
+  int x = xMap.transform(m_marker->getTOF());
+  int y = canvasRect.top() + m_marker->getLabelRect().height();
+  painter->drawText(x,y,m_marker->getLabel());
+  //std::cerr << x << ' ' << y << ' ' << m_marker->getLabel().toStdString() << std::endl;
+}
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.h
index 5032245b17de3ca6c3674cf334a75069c288e959..6ef75eaa03992cbd6ae00ef30e530ad1958c701e 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/OneCurvePlot.h
@@ -2,11 +2,13 @@
 #define ONECURVEPLOT_H_
 
 #include <qwt_plot.h>
+#include <qwt_plot_item.h>
 #include <QList>
 
 class QwtPlotCurve;
 class QwtPlotZoomer;
-
+class PeakLabel;
+class PeakMarker2D;
 /**
   * Implements a simple widget for plotting a single curve.
   */
@@ -17,6 +19,8 @@ public:
   OneCurvePlot(QWidget* parent);
   void setData(const double* x,const double* y,int dataSize);
   void setYAxisLabelRotation(double degrees);
+  void addLabel(PeakLabel*);
+  void clearLabels();
 public slots:
   void setXScale(double from, double to);
   void setYScale(double from, double to);
@@ -37,7 +41,18 @@ private:
   QwtPlotZoomer* m_zoomer; ///< does zooming
   int m_x0; ///< save x coord of last left mouse click
   int m_y0; ///< save y coord of last left mouse click
+  QList<PeakLabel*> m_peakLabels;
 };
 
+class PeakLabel: public QwtPlotItem
+{
+public:
+  PeakLabel(const PeakMarker2D* m):m_marker(m){}
+  void draw(QPainter *painter, 
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRect &canvasRect) const;
+private:
+  const PeakMarker2D* m_marker;
+};
 
 #endif /*ONECURVEPLOT_H_*/
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakMarker2D.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakMarker2D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9d76b8ef88de83727d8ffa8da62b55ab8cbc69d2
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakMarker2D.cpp
@@ -0,0 +1,119 @@
+#include "PeakMarker2D.h"
+
+#include <QPainter>
+#include <QPainterPath>
+#include <QFontMetrics>
+#include <QMouseEvent>
+#include <QWheelEvent>
+
+#include <iostream>
+#include <algorithm>
+#include <stdexcept>
+#include <cmath>
+
+/// Default size in screen pixels of the marker's symbol
+const int PeakMarker2D::g_defaultMarkerSize = 5;
+
+/**
+ * Constructor.
+ * @param centre :: Centre of the marker. Represents the peak position.
+ * @param symbol :: Symbol to draw. One of: Circle, Diamond, or Square
+ * @param markerSize :: Optional size of marker's symbol.
+ */
+PeakMarker2D::PeakMarker2D(const QPointF& centre,Symbol symbol,int markerSize):
+m_symbol(symbol)
+{
+  if (markerSize > 0)
+  {
+    m_markerSize = markerSize;
+  }
+  else
+  {
+    m_markerSize = g_defaultMarkerSize;
+  }
+  m_boundingRect = QRectF(centre - QPointF((qreal)m_markerSize/2,(qreal)m_markerSize/2), 
+                          QSizeF((qreal)m_markerSize,(qreal)m_markerSize));
+  setScalable(false);
+}
+
+bool PeakMarker2D::selectAt(const QPointF& p)const
+{
+    return contains(p);
+}
+
+void PeakMarker2D::drawShape(QPainter& painter) const
+{
+  // draw the symbol
+  switch(m_symbol)
+  {
+  case Circle: drawCircle(painter); break;
+  case Diamond: drawDiamond(painter); break;
+  case Square: drawSquare(painter); break;
+  default:
+    drawCircle(painter);
+  }
+  // calculate label's area on the screen
+  QFontMetrics fm(painter.font());
+  QRect r = fm.boundingRect(m_label);
+  m_labelRect = QRectF(r);
+  m_labelRect.moveTo(m_boundingRect.right() + m_markerSize,m_boundingRect.top() - m_markerSize);
+}
+
+void PeakMarker2D::addToPath(QPainterPath& path) const
+{
+  path.addRect(m_boundingRect);
+}
+
+/// Set new marker size to s
+void PeakMarker2D::setMarkerSize(const int& s)
+{
+  if (s > 0)
+  {
+    m_markerSize = s;
+  }
+}
+
+/// Draw marker as a circle
+void PeakMarker2D::drawCircle(QPainter& painter)const
+{
+  QPainterPath path;
+  path.addEllipse(m_boundingRect);
+  painter.fillPath(path,m_color);
+}
+
+/// Draw marker as a diamond
+void PeakMarker2D::drawDiamond(QPainter& painter)const
+{
+  QPointF dp = origin();
+  QPointF mdp(-dp.x(),-dp.y());
+  // draw a diamond as a square rotated by 45 degrees
+  painter.save();
+  painter.translate(dp);
+  painter.rotate(45);
+  painter.translate(mdp);
+  QPainterPath path;
+  path.addRect(m_boundingRect);
+  painter.fillPath(path,m_color);
+  painter.restore();
+}
+
+/// Draw marker as a square
+void PeakMarker2D::drawSquare(QPainter& painter)const
+{
+  QPainterPath path;
+  path.addRect(m_boundingRect);
+  painter.fillPath(path,m_color);
+}
+
+/**
+ * Save some peak information.
+ */
+void PeakMarker2D::setPeak(const Mantid::API::IPeak& peak)
+{
+  m_h = peak.getH();
+  m_k = peak.getK();
+  m_l = peak.getL();
+  m_label = QString("%1 %2 %3").arg(QString::number(m_h),QString::number(m_k),QString::number(m_l));
+  m_detID = peak.getDetectorID();
+  m_tof = peak.getTOF();
+}
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakMarker2D.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakMarker2D.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fff883697d5c684be0e0607e0e28ef707a6068a
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakMarker2D.h
@@ -0,0 +1,62 @@
+#ifndef MANTIDPLOT_PEAKMARKER2D_H_
+#define MANTIDPLOT_PEAKMARKER2D_H_
+
+#include "Shape2D.h"
+#include "MantidAPI/IPeak.h"
+
+/**
+ * Shape representing a peak marker on un unwrapped surface.
+ * A marker consists of a symbol marking location of a peak
+ * and a text label.
+ */
+class PeakMarker2D: public Shape2D
+{
+public:
+  enum Symbol {Circle = 0,Diamond,Square};
+  PeakMarker2D(const QPointF& centre,Symbol symbol = Circle,int markerSize = 0);
+  /* --- Implemented Shape2D virtual methods --- */
+  virtual Shape2D* clone()const{return new PeakMarker2D(*this);}
+  virtual bool selectAt(const QPointF& p)const;
+  virtual bool contains(const QPointF& p)const{return m_boundingRect.contains(p);}
+  virtual void addToPath(QPainterPath& path) const;
+  /* --- Own public methods --- */
+  /// Set new marker size to s
+  void setMarkerSize(const int& s);
+  /// Get marker size
+  int getMarkerSize()const{return m_markerSize;}
+  /// Get default marker size
+  static const int getDefaultMarkerSize(){return g_defaultMarkerSize;}
+  Symbol getSymbol()const{return m_symbol;}
+  void setSymbol(Symbol s){m_symbol=s;}
+  void setPeak(const Mantid::API::IPeak& peak);
+  double getH()const{return m_h;}
+  double getK()const{return m_k;}
+  double getL()const{return m_l;}
+  int getDetectorID()const{return m_detID;}
+  double getTOF()const{return m_tof;}
+  /// Get label's area on the screen
+  const QRectF& getLabelRect()const{return m_labelRect;}
+  /// Allows PeakOverlay to move the label to avoid overlapping
+  void moveLabelRectTo(const QPointF& p)const{m_labelRect.moveTo(p);}
+  QString getLabel()const{return m_label;}
+protected:
+  /* --- Implemented Shape2D protected virtual methods --- */
+  virtual void drawShape(QPainter& painter) const;
+  virtual void refit(){}
+  /* --- Own protected methods --- */
+  void drawCircle(QPainter& painter)const;
+  void drawDiamond(QPainter& painter)const;
+  void drawSquare(QPainter& painter)const;
+private:
+
+  int m_markerSize;
+  static const int g_defaultMarkerSize;
+  Symbol m_symbol; ///< Shape of the marker
+  double m_h, m_k, m_l; ///< Peak's h,k,l
+  int m_detID;
+  double m_tof;
+  QString m_label;
+  mutable QRectF m_labelRect; ///< label's area on the screen
+};
+
+#endif /*MANTIDPLOT_PEAKMARKER2D_H_*/
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakOverlay.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakOverlay.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aab862cbd4e7cc04f63f61643bef78975b73c26b
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakOverlay.cpp
@@ -0,0 +1,141 @@
+#include "PeakOverlay.h"
+#include "PeakMarker2D.h"
+
+#include <QPainter>
+#include <QList>
+
+/**
+* Constructor.
+*/
+PeakHKL::PeakHKL(PeakMarker2D* m,const QRectF& trect):
+p(m->origin()),
+  rect(trect),
+  //rectTopLeft(m->getLabelRect().topLeft()),
+  h(m->getH()),
+  k(m->getK()),
+  l(m->getL()),
+  nh(true),
+  nk(true),
+  nl(true)
+{}
+
+/**
+* Check if this rect intersects with marker's and if it does combine the labels
+* @param marker :: A marker to check for intersection
+* @param trect :: Transformed marker's label rect
+* @return True if labels were combined, false otherwise.
+*/
+bool PeakHKL::add(PeakMarker2D* marker,const QRectF& trect)
+{
+  if ( !rect.intersects(trect) )
+  {
+    return false;
+  }
+  if (nh && marker->getH() != h) 
+  {
+    nh = false;
+  }
+  if (nk && marker->getK() != k) 
+  {
+    nk = false;
+  }
+  if (nl && marker->getL() != l) 
+  {
+    nl = false;
+  }
+  return true;
+}
+/**
+* Draw the label
+* @param painter :: QPainter to draw with
+* @param transform :: Current transform
+*/
+void PeakHKL::draw(QPainter& painter,const QTransform& transform)
+{
+  QString label;
+  if (nh) label = QString::number(h) + " ";
+  else
+    label = "h ";
+  if (nk) label += QString::number(k) + " ";
+  else
+    label += "k ";
+  if (nl) label += QString::number(l);
+  else
+    label += "l";
+  painter.drawText(rect.bottomLeft(),label);
+
+}
+
+void PeakHKL::print()const
+{
+  std::cerr << "     " << p.x() << ' ' << p.y() << '('<<h<<','<<k<<','<<l<<")("<<nh<<','<<nk<<','<<nl<<')' << std::endl;
+}
+
+/**
+ * Add new marker to the overlay.
+ * @param m :: Pointer to the new marker
+ */
+void PeakOverlay::addMarker(PeakMarker2D* m)
+{
+  addShape(m,false);
+  m_det2marker.insert(m->getDetectorID(),m);
+}
+
+void PeakOverlay::draw(QPainter& painter) const
+{
+  // Draw symbols
+  Shape2DCollection::draw(painter);
+  // Sort the labels to avoid overlapping
+  QColor color;
+  QRectF clipRect(painter.viewport());
+  m_labels.clear();
+  foreach(Shape2D* shape,m_shapes)
+  {
+    if (!clipRect.contains(m_transform.map(shape->origin()))) continue;
+    PeakMarker2D* marker = dynamic_cast<PeakMarker2D*>(shape);
+    if (!marker) continue;
+    color = marker->getColor();
+    QPointF p0 = marker->origin();
+    QPointF p1 = m_transform.map(p0);
+    QRectF rect = marker->getLabelRect();
+    QPointF dp = rect.topLeft() - p0;
+    p1 += dp;
+    rect.moveTo(p1);
+
+    //painter.setPen(color);
+    //painter.drawRect(rect);
+
+    bool overlap = false;
+    // if current label overlaps with another
+    // combine them substituting differing numbers with letter 'h','k', or 'l'
+    for(int i = 0; i < m_labels.size(); ++i)
+    {
+      PeakHKL& hkl = m_labels[i];
+      overlap = hkl.add(marker,rect);
+    }
+    
+    if (!overlap)
+    {
+      PeakHKL hkl(marker,rect);
+      m_labels.append(hkl);
+    }
+  }
+  //std::cerr << m_labels.size() << " labels\n";
+  painter.setPen(color);
+  for(int i = 0; i < m_labels.size(); ++i)
+  {
+    PeakHKL& hkl = m_labels[i];
+    hkl.draw(painter,m_transform);
+    //hkl.print();
+  }
+}
+
+/**
+ * Return a list of markers put onto a detector
+ * @param detID :: A detector ID for which markers are to be returned.
+ * @return :: A list of zero ot more markers.
+ */
+QList<PeakMarker2D*> PeakOverlay::getMarkersWithID(int detID)const
+{
+  return m_det2marker.values(detID);
+}
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakOverlay.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakOverlay.h
new file mode 100644
index 0000000000000000000000000000000000000000..a508ac8d6085224402d9f81b952b27e783068aa9
--- /dev/null
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/PeakOverlay.h
@@ -0,0 +1,50 @@
+#ifndef MANTIDPLOT_PEAKOVERLAY_H_
+#define MANTIDPLOT_PEAKOVERLAY_H_
+
+#include "Shape2DCollection.h"
+#include <QHash>
+
+class PeakMarker2D;
+
+/**
+ * Class for managing overlapping peak labels and drawing them on screen.
+ * If labels of two or more peaks overlap they are combined into a single label.
+ * A label shows three numbers h,k, and l. A combined label replaces non-equal
+ * numbers of included markers with its letter.
+ */
+class PeakHKL
+{
+public:
+  PeakHKL(PeakMarker2D* m,const QRectF& trect);
+  bool add(PeakMarker2D* marker,const QRectF& trect);
+  void draw(QPainter& painter,const QTransform& transform);
+  void print()const;
+
+private:
+  QPointF p; ///< untransformed marker origin
+  QRectF rect; ///< label's screen area in transformed coords
+  double h,k,l; ///< h,k, and l
+  bool nh,nk,nl; ///< true if h, k, or l is numeric
+
+};
+
+/**
+ * Class for managing peak markers.
+ */
+class PeakOverlay: public Shape2DCollection
+{
+public:
+  PeakOverlay():Shape2DCollection(){}
+  ~PeakOverlay(){}
+  /// Override the drawing method
+  void draw(QPainter& painter) const;
+
+  void addMarker(PeakMarker2D* m);
+  QList<PeakMarker2D*> getMarkersWithID(int detID)const;
+
+private:
+  QMultiHash<int,PeakMarker2D*> m_det2marker; ///< detector ID to PeakMarker2D map
+  mutable QList<PeakHKL> m_labels;
+};
+
+#endif /*MANTIDPLOT_PEAKOVERLAY_H_*/
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
index 5fd086ec6649df17bd5678b115769cd023c265f4..40a554d4471b55e44d5bc617e00e411be6938acd 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/ProjectionSurface.h
@@ -7,6 +7,7 @@
 
 #include "InstrumentActor.h"
 #include "Shape2DCollection.h"
+#include "PeakOverlay.h"
 
 #include <QImage>
 #include <QList>
@@ -109,6 +110,8 @@ public:
   bool isMasked(double x,double y)const{return m_maskShapes.isMasked(x,y);}
   void clearMask(){m_maskShapes.clear();}
 
+  PeakOverlay& getPeakOverlay(){return m_peakShapes;}
+
 signals:
 
   void singleDetectorTouched(int);
@@ -173,7 +176,7 @@ protected:
   bool m_leftButtonDown;
 
   Shape2DCollection m_maskShapes;  ///< to draw mask shapes
-  mutable Shape2DCollection m_peakShapes; ///< to draw peak labels
+  mutable PeakOverlay m_peakShapes; ///< to draw peak labels
 
 };
 
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp
index e2bf72ccd24e3cfc3250d36fbf5d75e67ac1c074..4b39ba2649a4bcc7613b96d719d15a1ebbabb0b0 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.cpp
@@ -16,6 +16,7 @@ const qreal Shape2D::sizeCP = 2;
 
 Shape2D::Shape2D():
 m_color(Qt::red),
+m_scalable(true),
 m_editing(false)
 {
 
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h
index 16c1d7d97ecc6f7ef51e3d43287815142034f622..a7aaa98c798b2b286e00189b9db14852b7e3781e 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2D.h
@@ -24,10 +24,13 @@ public:
   virtual Shape2D* clone()const = 0;
   // modify path so painter.drawPath(path) could be used to draw the shape. needed for filling in complex shapes
   virtual void addToPath(QPainterPath& path) const = 0;
-  // make sure the shape is withing the bounding box
+  // make sure the shape is within the bounding box
   virtual void refit() = 0;
 
+  // --- Public virtual methods --- //
+
   virtual void draw(QPainter& painter) const;
+  virtual QPointF origin() const {return m_boundingRect.center();}
   virtual void moveBy(const QPointF& pos);
   virtual size_t getNControlPoints() const;
   virtual QPointF getControlPoint(size_t i) const;
@@ -37,11 +40,6 @@ public:
   // by dx1, dy1, dx2, and dy2 correspondingly
   virtual void adjustBoundingRect(qreal dx1,qreal dy1,qreal dx2,qreal dy2);
   virtual void setBoundingRect(const QRectF& rect);
-
-  void setColor(const QColor& color){m_color = color;}
-  void setFillColor(const QColor& color){m_fill_color = color;}
-  void edit(bool on){m_editing = on;}
-  bool isEditing()const{return m_editing;}
   // will the shape be selected if clicked at a point
   virtual bool selectAt(const QPointF& )const{return false;}
   // is a point inside the shape (closed line)
@@ -49,6 +47,16 @@ public:
   // is a point "masked" by the shape. Only filled regians of a shape mask a point
   virtual bool isMasked(const QPointF& )const;
 
+  // --- Public methods --- //
+
+  void setColor(const QColor& color){m_color = color;}
+  QColor getColor()const{return m_color;}
+  void setFillColor(const QColor& color){m_fill_color = color;}
+  void setScalable(bool on){m_scalable = on;}
+  bool isScalable() const {return m_scalable;}
+  void edit(bool on){m_editing = on;}
+  bool isEditing()const{return m_editing;}
+
   // --- Properties. for gui interaction --- //
 
   // double properties
@@ -66,6 +74,8 @@ protected:
 
   virtual void drawShape(QPainter& painter) const = 0;
 
+  // --- Protected virtual methods --- //
+
   // return number of control points specific to this shape
   virtual size_t getShapeNControlPoints() const{return 0;}
   // returns position of a shape specific control point, 0 < i < getShapeNControlPoints()
@@ -75,14 +85,19 @@ protected:
   // make sure the bounding box is correct
   virtual void resetBoundingRect() {}
 
+  // --- Protected methods --- //
+
   // make sure that width and heigth are positive
   void correctBoundingRect();
 
+  // --- Protected data --- //
+
   static const size_t NCommonCP;
   static const qreal sizeCP;
   QRectF m_boundingRect;
   QColor m_color;
   QColor m_fill_color;
+  bool m_scalable; ///< shape cann be scaled when zoomed
   bool m_editing;
 };
 
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
index debedc4f95254b377d0840669a9bb6d2681855a5..0400a36df31347e2773d83a31216f4990c569b81 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.cpp
@@ -32,18 +32,56 @@ Shape2DCollection::~Shape2DCollection()
   }
 }
 
+/**
+ * Draw the collection on screen.
+ */
 void Shape2DCollection::draw(QPainter& painter) const
 {
   if (m_shapes.isEmpty()) return;
+
+  // separate scalable and nonscalable shapes
+  QList<Shape2D*> scalable;
+  QList<Shape2D*> nonscalable;
+  foreach(Shape2D* shape,m_shapes)
+  {
+    if (shape->isScalable())
+    {
+      scalable << shape;
+    }
+    else
+    {
+      nonscalable << shape;
+    }
+  }
+
+  // first draw the scalable ones
   painter.save();
   painter.setTransform(m_transform);
-  foreach(const Shape2D* shape,m_shapes)
+  foreach(const Shape2D* shape,scalable)
   {
     shape->draw(painter);
   }
   painter.restore();
+
+  // now the nonscalable
+  foreach(const Shape2D* shape,nonscalable)
+  {
+    QPointF p0 = shape->origin();
+    QPointF p1 = m_transform.map(p0);
+    QPointF dp = p1 - p0;
+    painter.save();
+    painter.translate(dp);
+    shape->draw(painter);
+    painter.restore();
+  }
+  //std::cerr << m_transform.m11() << ' ' << m_transform.m22() << ' ' << m_transform.m33() << std::endl;
 }
 
+/**
+ * Add a new shape to collection.
+ * @param shape :: A pointer to the new shape.
+ * @param slct :: A bool flag to select the shape after it's added.
+ */
 void Shape2DCollection::addShape(Shape2D* shape,bool slct)
 {
   m_shapes.push_back(shape);
@@ -55,23 +93,37 @@ void Shape2DCollection::addShape(Shape2D* shape,bool slct)
   emit shapeCreated();
 }
 
-void Shape2DCollection::setWindow(const QRectF& rect,const QRect& viewport) const
+/**
+ * Remove a shape from collection
+ * @param shape :: Pointer to the shape to remove.
+ */
+void Shape2DCollection::removeShape(Shape2D* shape)
+{
+  if (shape && m_shapes.contains(shape))
+  {
+    m_shapes.removeOne(shape);
+  }
+}
+
+/**
+ */
+void Shape2DCollection::setWindow(const QRectF& window,const QRect& viewport) const
 {
   m_transform.reset();
   m_viewport = viewport;
   if ( m_windowRect.isNull() )
   {
-    m_windowRect = rect;
+    m_windowRect = window;
     m_h = viewport.height();
-    m_wx = viewport.width() / rect.width();
-    m_wy = m_h / rect.height();
+    m_wx = viewport.width() / window.width();
+    m_wy = m_h / window.height();
   }
   else
   {
-    double wx = viewport.width() / rect.width();
-    double wy = viewport.height() / rect.height();
-    double rx = m_windowRect.left() - rect.left();
-    double ry = m_windowRect.top() - rect.top();
+    double wx = viewport.width() / window.width();
+    double wy = viewport.height() / window.height();
+    double rx = m_windowRect.left() - window.left();
+    double ry = m_windowRect.top() - window.top();
     qreal sx = wx / m_wx;
     qreal sy = wy / m_wy;
     qreal dx = rx * wx;
@@ -320,7 +372,7 @@ void Shape2DCollection::removeCurrentShape()
 {
   if (m_currentShape)
   {
-    m_shapes.removeOne(m_currentShape);
+    this->removeShape(m_currentShape);
     m_currentShape = NULL;
     emit shapesDeselected();
   }
@@ -448,11 +500,21 @@ void Shape2DCollection::getMaskedPixels(QList<QPoint>& pixels)const
 void Shape2DCollection::setCurrentBoundingRectReal(const QRectF& rect)
 {
   if (!m_currentShape) return;
-  // convert rect from real to original screen coordinates
+  // convert rect from real to original screen coordinates (unaffected by m_transform)
   double x = (rect.x() - m_windowRect.left()) * m_wx;
   double y = m_h - (rect.bottom() - m_windowRect.y()) * m_wy;
   double width = rect.width() * m_wx;
   double height = rect.height() * m_wy;
   
+  //QPointF c = QRectF(x,y,width,height).center();
+  //std::cerr << "setCurrentBoundingRectReal: " << c.x() << ' ' << c.y() << std::endl << std::endl;
   m_currentShape->setBoundingRect(QRectF(x,y,width,height));
 }
+
+QPointF Shape2DCollection::realToUntransformed(const QPointF& point)const
+{
+  qreal x = (point.x() - m_windowRect.left()) * m_wx;
+  qreal y = m_h - (point.y() - m_windowRect.y()) * m_wy;
+  //std::cerr << "realToUntransformed: " << x << ' ' << y << std::endl;
+  return QPointF(x,y);
+}
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
index fb80e38b37709b1340aebbd078dbc278fe7a05ca..fa637b728cb969a49ad8a4aa80c54a406b435fc5 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/Shape2DCollection.h
@@ -13,6 +13,21 @@ class QKeyEvent;
 
 /**
  * Class Shape2DCollection is a collection of 2D shapes. 
+ * It supports operations on teh shapes such as adding, removing, and aditting either
+ * with the mouse via control points (CPs) or via properties.
+ *
+ * The shapes operate in three coordinate systems:
+ * 1. Some 'real' or logical coordinates
+ * 2. Current or transformed screen coordinates
+ * 3. Untransformed screen coordinates
+ *
+ * Shape2DCollection must know the boundaries of the drawing area in logical and transformed screen coords.
+ * They are set by calling setWindow(...) method. The first argument is the logical drawing rectangle and 
+ * the second one is the corresponding screen viewport in pixels. The first screen viewport set with setWindow
+ * defines the Untransformed screen coordinates. The individual shapes draw themselves in the untransformed
+ * screen coords and unaware of the logical ones at all. If the size of the screen/widget changes setWindow
+ * must be called again. Changing the logical drawing bounds translates and zooms the picture.
+ * The transformation is done by Qt's QTransform object.
  */
 class Shape2DCollection: public QObject, public Shape2D
 {
@@ -21,9 +36,10 @@ public:
   Shape2DCollection();
   ~Shape2DCollection();
   Shape2D* clone()const{return NULL;}
-  void setWindow(const QRectF& rect,const QRect& viewport) const;
+  void setWindow(const QRectF& window,const QRect& viewport) const;
   virtual void draw(QPainter& painter) const;
   virtual void addShape(Shape2D*,bool slct = false);
+  virtual void removeShape(Shape2D*);
   
   void mousePressEvent(QMouseEvent*);
   void mouseMoveEvent(QMouseEvent*);
@@ -58,7 +74,12 @@ public:
   // collect all screen pixels that are masked by the shapes
   void getMaskedPixels(QList<QPoint>& pixels)const;
 
+  // --- coordinate transformations --- //
+
+  // set the bounding rect of the current shape such that its real rect is given by the argument
   void setCurrentBoundingRectReal(const QRectF& rect);
+  // convert a real point to the untransformed screen coordinates
+  QPointF realToUntransformed(const QPointF& point)const;
 
 signals:
 
@@ -79,15 +100,15 @@ protected:
   void select(Shape2D* shape);
 
   QList<Shape2D*> m_shapes;
-  mutable QRectF m_windowRect; // original surface window in "real" cooerdinates
+  mutable QRectF m_windowRect; // original surface window in "real" coordinates
   mutable double m_wx,m_wy;
   mutable int m_h; // original screen viewport height
   mutable QRect m_viewport;  // current screen viewport
   mutable QTransform m_transform; // current transform
 
-  bool m_creating;
-  bool m_editing;
-  bool m_moving;
+  bool m_creating; ///< a shape is being created with a mouse
+  bool m_editing;  ///< current shape is being edited with a mouse. CPs are visible
+  bool m_moving;   ///< current shape is being moved with a mouse. 
   int m_x,m_y;
   QString m_shapeType;
   QColor m_borderColor, m_fillColor;
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp
index 3fc09e6163c327fdb13bb014237351962c405f1e..0d82b43bc177c480855293456a1fadee121fbefa 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.cpp
@@ -2,6 +2,7 @@
 #include "GLColor.h"
 #include "MantidGLWidget.h"
 #include "OpenGLError.h"
+#include "PeakMarker2D.h"
 
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Objects/Object.h"
@@ -12,6 +13,7 @@
 #include <QSet>
 #include <QMenu>
 #include <QMouseEvent>
+#include <QApplication>
 
 #include <cfloat>
 #include <limits>
@@ -170,7 +172,7 @@ void UnwrappedSurface::drawSurface(MantidGLWidget *widget,bool picking)const
 
   if (m_startPeakShapes)
   {
-    ceatePeakShapes(widget->rect());
+    createPeakShapes(widget->rect());
   }
 
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -632,9 +634,10 @@ void UnwrappedSurface::setPeaksWorkspace(boost::shared_ptr<Mantid::API::IPeaksWo
  * Create the peak labels from the peaks set by setPeaksWorkspace. The method is called from the draw(...) method
  * @param window :: The screen window rectangle in pixels.
  */
-void UnwrappedSurface::ceatePeakShapes(const QRect& viewport)const
+void UnwrappedSurface::createPeakShapes(const QRect& window)const
 {
-  m_peakShapes.setWindow(getSurfaceBounds(),viewport);
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+  m_peakShapes.setWindow(getSurfaceBounds(),window);
   int nPeaks = m_peaksWorkspace->getNumberPeaks();
   for(int i = 0; i < nPeaks; ++i)
   {
@@ -645,12 +648,12 @@ void UnwrappedSurface::ceatePeakShapes(const QRect& viewport)const
       Mantid::Geometry::IDetector_const_sptr det = udet.detector;
       if (! det ) continue;
       if (det->getID() != detID) continue;
-      Shape2DRectangle* r = new Shape2DRectangle();
-      r->setFillColor(QColor(255,255,255,100));
-      m_peakShapes.addShape(r,true);
-      m_peakShapes.setCurrentBoundingRectReal(QRectF(udet.u-udet.width/2,udet.v-udet.height/2,udet.width,udet.height));
+      PeakMarker2D* r = new PeakMarker2D(m_peakShapes.realToUntransformed(QPointF(udet.u,udet.v)));
+      r->setPeak(peak);
+      m_peakShapes.addMarker(r);
     }
   }
   m_peakShapes.deselectAll();
   m_startPeakShapes = false;
+  QApplication::restoreOverrideCursor();
 }
diff --git a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.h b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.h
index 0b01986b9170913afa5f61deae9936f58bbd0a10..21109020f7fdb6cdb323a7b58944d7dde6b4c513 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.h
+++ b/Code/Mantid/MantidPlot/src/Mantid/InstrumentWidget/UnwrappedSurface.h
@@ -97,7 +97,7 @@ protected:
   void showPickedDetector();
   void calcAssemblies(boost::shared_ptr<const Mantid::Geometry::IComponent> comp,const QRectF& compRect);
   void findAndCorrectUGap();
-  void ceatePeakShapes(const QRect& viewport)const;
+  void createPeakShapes(const QRect& viewport)const;
 
   const InstrumentActor* m_instrActor;
   double m_u_min;                      ///< Minimum u