diff --git a/Core/Instrument/IDetector2D.cpp b/Core/Instrument/IDetector2D.cpp
index 02545ff6633f183ad25d09fb461daab24b5dcc72..716efb17c1b2d37a21cf897b41d82641c1ba5105 100644
--- a/Core/Instrument/IDetector2D.cpp
+++ b/Core/Instrument/IDetector2D.cpp
@@ -19,6 +19,7 @@
 #include "InfinitePlane.h"
 #include "Logger.h"
 #include "SimulationElement.h"
+#include "SimulationArea.h"
 
 IDetector2D::IDetector2D()
     : m_axes()
@@ -197,24 +198,22 @@ std::vector<SimulationElement> IDetector2D::createSimulationElements(const Beam
     Eigen::Matrix2cd beam_polarization = beam.getPolarization();
     Eigen::Matrix2cd analyzer_operator = getAnalyzerOperator();
 
-    if (getDimension()!=2)
-        throw Exceptions::RuntimeErrorException(
-            "IDetector2D::createSimulationElements: detector is not two-dimensional");
     if (!hasMasks())
         m_detector_mask.initMaskData(*this);
     size_t spec_index = getIndexOfSpecular(beam);
-    const OutputData<bool>* mask_data = m_detector_mask.getMaskData();
-    for (size_t index=0; index<mask_data->getAllocatedSize(); ++index) {
-        if ((*mask_data)[index]) continue;
+
+    SimulationArea area(this);
+    for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) {
         SimulationElement sim_element(wavelength, alpha_i, phi_i,
-                                      std::unique_ptr<IPixelMap>(createPixelMap(index)));
+                                      std::unique_ptr<IPixelMap>(createPixelMap(it.index())));
         sim_element.setPolarization(beam_polarization);
         sim_element.setAnalyzerOperator(analyzer_operator);
-        if (index==spec_index) {
+        if (it.index()==spec_index) {
             sim_element.setSpecular(true);
         }
         result.push_back(sim_element);
     }
+
     return result;
 }
 
@@ -230,15 +229,9 @@ SimulationElement IDetector2D::getSimulationElement(size_t index, const Beam &be
 void IDetector2D::transferResultsToIntensityMap(OutputData<double> &data,
     const std::vector<SimulationElement> &elements) const
 {
-    size_t element_index(0);
-    for(size_t index=0; index<data.getAllocatedSize(); ++index) {
-        if(this->isMasked(index)) continue;
-        data[index] = elements[element_index++].getIntensity();
-        if(element_index > elements.size()) {
-            throw Exceptions::RuntimeErrorException("IDetector2D::transferResultsToIntensityMap -> "
-                                                    "Error. Number of elements doesn't match data");
-        }
-    }
+    SimulationArea area(this);
+    for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it)
+        data[it.index()] = elements[it.elementIndex()].getIntensity();
 }
 
 bool IDetector2D::dataShapeMatches(const OutputData<double> *p_data) const
diff --git a/Core/Instrument/SimulationArea.cpp b/Core/Instrument/SimulationArea.cpp
index 6af53ddd2ac94e8fa2acb7133a46d1238ec971b8..9a359c3fb671c2738b73b5005ef8e6ef0bec9624 100644
--- a/Core/Instrument/SimulationArea.cpp
+++ b/Core/Instrument/SimulationArea.cpp
@@ -16,6 +16,7 @@
 #include "SimulationArea.h"
 #include "IDetector2D.h"
 #include "Exceptions.h"
+#include <sstream>
 
 SimulationArea::SimulationArea(const IDetector2D *detector)
     : m_detector(detector)
@@ -23,6 +24,10 @@ SimulationArea::SimulationArea(const IDetector2D *detector)
     if(detector == nullptr)
         throw Exceptions::RuntimeErrorException("SimulationArea::SimulationArea -> Error. "
                                                 "Detector nullptr.");
+
+    if (m_detector->getDimension()!=2)
+        throw Exceptions::RuntimeErrorException(
+            "SimulationArea::SimulationArea: detector is not two-dimensional");
 }
 
 SimulationAreaIterator SimulationArea::begin()
@@ -35,3 +40,19 @@ SimulationAreaIterator SimulationArea::end()
     return SimulationAreaIterator(this, m_detector->getTotalSize());
 }
 
+bool SimulationArea::isMasked(size_t index) const
+{
+    if(index >= m_detector->getTotalSize()) {
+        std::ostringstream message;
+        message << "SimulationArea::isActive() -> Error. Index " << index << " is out of range, "
+             << "totalSize=" << m_detector->getTotalSize();
+        throw Exceptions::RuntimeErrorException(message.str());
+    }
+
+    return m_detector->isMasked(index);
+}
+
+size_t SimulationArea::totalSize() const
+{
+    return m_detector->getTotalSize();
+}
diff --git a/Core/Instrument/SimulationArea.h b/Core/Instrument/SimulationArea.h
index a6fc2fe1b435490147cbbefd534732f1a0be11c6..60496d8b2c21ca5682400d03ed28a715eb1ab0b9 100644
--- a/Core/Instrument/SimulationArea.h
+++ b/Core/Instrument/SimulationArea.h
@@ -34,7 +34,9 @@ public:
     SimulationAreaIterator begin();
     SimulationAreaIterator end();
 
-    const IDetector2D* detector() const { return m_detector; }
+    bool isMasked(size_t index) const;
+
+    size_t totalSize() const;
 
 private:
     const IDetector2D *m_detector;
diff --git a/Core/Instrument/SimulationAreaIterator.cpp b/Core/Instrument/SimulationAreaIterator.cpp
index eba4afc9d3fa638242dcce4c5a71b79da7adfeda..dbbded7dc08f1c343228cf52481e2470e8896175 100644
--- a/Core/Instrument/SimulationAreaIterator.cpp
+++ b/Core/Instrument/SimulationAreaIterator.cpp
@@ -22,20 +22,43 @@ SimulationAreaIterator::SimulationAreaIterator(const SimulationArea *area, size_
     , m_index(start_at_index)
     , m_element_index(0)
 {
+    if(m_index > m_area->totalSize())
+        throw Exceptions::RuntimeErrorException("SimulationAreaIterator::SimulationAreaIterator() "
+                                                "-> Error. Invalid initial index");
 
+    if(m_index != m_area->totalSize() && m_area->isMasked(m_index))
+        m_index = nextIndex(m_index);
 }
 
 SimulationAreaIterator &SimulationAreaIterator::operator++()
 {
-    while(m_area->detector()->isMasked(++m_index));
-    ++m_element_index;
+    size_t index = nextIndex(m_index);
+    if(index != m_index) {
+        ++m_element_index;
+        m_index = index;
+    }
     return *this;
 }
 
-SimulationAreaIterator &SimulationAreaIterator::operator++(int)
+SimulationAreaIterator SimulationAreaIterator::operator++(int)
 {
-    m_index++;
-    m_element_index++;
-    return *this;
+    SimulationAreaIterator result(*this);
+    this->operator++();
+    return result;
+}
+
+size_t SimulationAreaIterator::nextIndex(size_t currentIndex)
+{
+    size_t result = ++currentIndex;
+    if(result < m_area->totalSize()) {
+        while(m_area->isMasked(result)) {
+            ++result;
+            if(result == m_area->totalSize())
+                break;
+        }
+    } else {
+        return m_area->totalSize();
+    }
+    return result;
 }
 
diff --git a/Core/Instrument/SimulationAreaIterator.h b/Core/Instrument/SimulationAreaIterator.h
index 30ef3b836f9b26ede331d565af88ef5161fb9c3f..b123975f24e3a6cf6b062f06b84880663178e022 100644
--- a/Core/Instrument/SimulationAreaIterator.h
+++ b/Core/Instrument/SimulationAreaIterator.h
@@ -29,8 +29,8 @@ class BA_CORE_API_ SimulationAreaIterator
 public:
     explicit SimulationAreaIterator(const SimulationArea *area, size_t start_at_index);
 
-    int index() const { return m_index; }
-    int elementIndex() const { return m_element_index;}
+    size_t index() const { return m_index; }
+    size_t elementIndex() const { return m_element_index;}
 
     bool operator==(const SimulationAreaIterator &other) const;
     bool operator!=(const SimulationAreaIterator &other) const;
@@ -39,9 +39,10 @@ public:
     SimulationAreaIterator& operator++();
 
     //! postfix increment
-    SimulationAreaIterator& operator++(int);
+    SimulationAreaIterator operator++(int);
 
 private:
+    size_t nextIndex(size_t currentIndex);
     const SimulationArea *m_area;
     size_t m_index;  //!< global index in detector plane defined by its axes
     size_t m_element_index; //!< sequential number for SimulationElementVector
@@ -50,7 +51,6 @@ private:
 inline bool SimulationAreaIterator::operator==(const SimulationAreaIterator &other) const
 {
   return m_area == other.m_area && m_index == other.m_index;
-//          && m_element_index == other.m_element_index;
 }
 
 inline bool SimulationAreaIterator::operator!=(const SimulationAreaIterator &right) const
diff --git a/Tests/UnitTests/Core/3/SimulationAreaTest.h b/Tests/UnitTests/Core/3/SimulationAreaTest.h
index 6e2ea26205931820339926c2cc5689252cc4016b..6fc647dffa6c831a0104daf0a6c0391feae04333 100644
--- a/Tests/UnitTests/Core/3/SimulationAreaTest.h
+++ b/Tests/UnitTests/Core/3/SimulationAreaTest.h
@@ -51,6 +51,11 @@ TEST_F(SimulationAreaTest, iteratorOperations)
     ++it;
     EXPECT_EQ(it.index(), 2);
     EXPECT_EQ(it.elementIndex(), 2);
+
+    // incrementing well behind the end
+    for(size_t i=0; i<100; ++i) ++it;
+    EXPECT_EQ(it.index(), detector.getTotalSize());
+    EXPECT_EQ(it.elementIndex(), detector.getTotalSize());
 }
 
 //! Iteration over non-masked detector
@@ -71,16 +76,11 @@ TEST_F(SimulationAreaTest, detectorIteration)
     }
     EXPECT_EQ(indexes, expectedIndexes);
     EXPECT_EQ(elementIndexes, expectedElementIndexes);
-
-    // testing C++-11
-//    for(SimulationArea::iterator it : area) {
-//        std::cout << "KKK" << std::endl;
-//    }
 }
 
 //! Iteration over masked detector
 
-TEST_F(SimulationAreaTest, maskedDetectorIteration)
+TEST_F(SimulationAreaTest, maskedIteration)
 {
     SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
     detector.addMask(Geometry::Rectangle(0.1, 1.1, 2.9, 2.9), true);
@@ -97,8 +97,45 @@ TEST_F(SimulationAreaTest, maskedDetectorIteration)
     }
     EXPECT_EQ(indexes, expectedIndexes);
     EXPECT_EQ(elementIndexes, expectedElementIndexes);
+}
+
+//! Iteration over the detector with first and alst bin masked
+
+TEST_F(SimulationAreaTest, maskedCornerIteration)
+{
+    SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
+    detector.addMask(Geometry::Rectangle(-0.9, 0.1, -0.1, 0.9), true);
+    detector.addMask(Geometry::Rectangle(3.1, 3.1, 3.9, 3.9), true);
+    SimulationArea area(&detector);
+
+    std::vector<int> expectedIndexes
+            = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
+    std::vector<int> expectedElementIndexes
+            = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+    std::vector<int> indexes;
+    std::vector<int> elementIndexes;
+    for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) {
+        indexes.push_back(it.index());
+        elementIndexes.push_back(it.elementIndex());
+    }
+    EXPECT_EQ(indexes, expectedIndexes);
+    EXPECT_EQ(elementIndexes, expectedElementIndexes);
+}
 
+TEST_F(SimulationAreaTest, allMaskedIteration)
+{
+    SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0);
+    detector.addMask(Geometry::Rectangle(-0.9, 0.1, 3.9, 3.9), true);
+    SimulationArea area(&detector);
 
+    std::vector<int> indexes;
+    std::vector<int> elementIndexes;
+    for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) {
+        indexes.push_back(it.index());
+        elementIndexes.push_back(it.elementIndex());
+    }
+    EXPECT_EQ(indexes.size(), size_t(0));
+    EXPECT_EQ(elementIndexes.size(), size_t(0));
 }
 
 #endif
diff --git a/dev-tools/log/perf_history.txt b/dev-tools/log/perf_history.txt
index 84f18759e99e1676b233bb0c31c9af8437963d81..7b0db4a6e1be6e078eda625159eaf1e65f2859d6 100644
--- a/dev-tools/log/perf_history.txt
+++ b/dev-tools/log/perf_history.txt
@@ -514,5 +514,8 @@
 
 
 # after the switch to std::move in SimulationElement
-| date                | hostname | sysinfo      | python | total cpu | total wall | MultiLayer | CylindersInDWBA | RotatedPyramids | CoreShell | SquareLattice | RadialParaCrystal | HexParaCrystal | SSCA   | Mesocrystal | | 2016-10-14 08:51:54 | scgsun   | Linux x86_64 | 2.7    | 122.8880  | 19.3683    | 2.8577     | 0.7296          | 3.3728          | 0.5629    | 2.3569        | 0.7555            | 3.3065         | 1.0475 | 1.7642      | 1.7467    | 0.8680    |
+| 2016-10-14 08:51:54 | scgsun   | Linux x86_64 | 2.7    | 122.8880  | 19.3683    | 2.8577     | 0.7296          | 3.3728          | 0.5629    | 2.3569        | 0.7555            | 3.3065         | 1.0475 | 1.7642      | 1.7467    | 0.8680    |
+
+# after switch to SimulationAreaIterator
+| 2016-10-17 11:28:02 | scgsun   | Linux x86_64 | 2.7    | 122.3960  | 19.9584    | 3.0328     | 0.7849          | 3.4156          | 0.5976    | 2.3843        | 0.7670            | 3.4331         | 1.0687 | 1.7839      | 1.8056    | 0.8850    |