Index: src/Box.cpp
===================================================================
--- src/Box.cpp	(revision f3be871105a51d83420a3be4cb717bc407fcadcb)
+++ src/Box.cpp	(revision 16648f2a24b05c56b2e93ec5618bf5332f5ce6c8)
@@ -11,4 +11,5 @@
 
 #include <cmath>
+#include <iostream>
 
 #include "Matrix.hpp"
@@ -17,4 +18,6 @@
 
 #include "Helpers/Assert.hpp"
+
+using namespace std;
 
 Box::Box()
@@ -105,47 +108,81 @@
 
 VECTORSET(std::list) Box::explode(const Vector &point,int n) const{
+  ASSERT(isInside(point),"Exploded point not inside Box");
   VECTORSET(std::list) res;
 
-  // translate the Vector into each of the 27 neighbourhoods
-
-  // first create all translation Vectors
-  // there are (n*2+1)^3 such vectors
-  int max_dim = (n*2+1);
-  int max_dim2 = max_dim*max_dim;
-  int max = max_dim2*max_dim;
-  // only one loop to avoid unneccessary jumps
-  for(int i = 0;i<max;++i){
-    // get all coordinates for this iteration
-    int n1 = (i%max_dim)-n;
-    int n2 = ((i/max_dim)%max_dim)-n;
-    int n3 = ((i/max_dim2))-n;
-    Vector translation = translateIn(Vector(n1,n2,n3));
-    res.push_back(translation);
-  }
-  // translate all the translation vector by the offset defined by point
-  res.translate(point);
+  Vector translater = translateOut(point);
+  Vector mask; // contains the ignored coordinates
+
+  // count the number of coordinates we need to do
+  int dims = 0; // number of dimensions that are not ignored
+  vector<int> coords;
+  vector<int> index;
+  for(int i=0;i<NDIM;++i){
+    if(conditions[i]==Ignore){
+      mask[i]=translater[i];
+      continue;
+    }
+    coords.push_back(i);
+    index.push_back(-n);
+    dims++;
+  } // there are max vectors in total we need to create
+
+  if(!dims){
+    // all boundaries are ignored
+    res.push_back(point);
+    return res;
+  }
+
+  int pos = 0;
+  while(pos<dims){
+    // create this vector
+    Vector helper;
+    for(int i=0;i<dims;++i){
+      switch(conditions[coords[i]]){
+        case Wrap:
+          helper[coords[i]] = index[i]+translater[coords[i]];
+          break;
+        case Bounce:
+          {
+            // Bouncing the coordinate x produces the series:
+            // 0 -> x
+            // 1 -> 2-x
+            // 2 -> 2+x
+            // 3 -> 4-x
+            // 4 -> 4+x
+            // the first number is the next bigger even number (n+n%2)
+            // the next number is the value with alternating sign (x-2*(n%2)*x)
+            // the negative numbers produce the same sequence reversed and shifted
+            int n = abs(index[i]) + (index[i]<0)?-1:0;
+            int sign = (index[i]<0)?-1:+1;
+            int even = n%2;
+            helper[coords[i]]=n+even+translater[coords[i]]-2*even*translater[coords[i]];
+            helper[coords[i]]*=sign;
+          }
+          break;
+        case Ignore:
+          ASSERT(0,"Ignored coordinate handled in generation loop");
+        default:
+          ASSERT(0,"No default case for this switch-case");
+      }
+
+    }
+    // add back all ignored coordinates (not handled in above loop)
+    helper+=mask;
+    res.push_back(translateIn(helper));
+    // set the new indexes
+    pos=0;
+    ++index[pos];
+    while(index[pos]>n && pos < dims){
+      index[pos++]=-n;
+      ++index[pos];
+    }
+  }
   return res;
 }
 
 VECTORSET(std::list) Box::explode(const Vector &point) const{
-  VECTORSET(std::list) res;
-
-  // translate the Vector into each of the 27 neighbourhoods
-
-  // first create all 27 translation Vectors
-  // these loops depend on fixed parameters and can easily be expanded
-  // by the compiler to allow code without jumps
-  for(int n1 = -1;n1<=1;++n1){
-    for(int n2 = -1;n2<=1;++n2){
-      for(int n3 = -1;n3<=1;++n3){
-        // get all coordinates for this iteration
-        Vector translation = translateIn(Vector(n1,n2,n3));
-        res.push_back(translation);
-      }
-    }
-  }
-  // translate all the translation vector by the offset defined by point
-  res.translate(point);
-  return res;
+  ASSERT(isInside(point),"Exploded point not inside Box");
+  return explode(point,1);
 }
 
