diff --git a/Core/Algorithms/src/MultiLayerDWBASimulation.cpp b/Core/Algorithms/src/MultiLayerDWBASimulation.cpp
index 7a903249167144176ce84d65c63a86d86827c053..43387d41ba2a206dda8025dd86182439dd52fa85 100644
--- a/Core/Algorithms/src/MultiLayerDWBASimulation.cpp
+++ b/Core/Algorithms/src/MultiLayerDWBASimulation.cpp
@@ -24,6 +24,8 @@
 #include "MessageService.h"
 #include "MagneticCoefficientsMap.h"
 
+#include <boost/scoped_ptr.hpp>
+
 
 MultiLayerDWBASimulation::MultiLayerDWBASimulation(
         const MultiLayer* p_multi_layer)
@@ -100,6 +102,8 @@ void MultiLayerDWBASimulation::run()
         doubleFresnelPair_t;
     std::vector<doubleFresnelPair_t> doubleFresnel_buffer;
     std::set<double> alpha_set = getAlphaList();
+    // also add incoming alpha
+    alpha_set.insert(-m_alpha_i);
     doubleFresnel_buffer.reserve(alpha_set.size());
 
     double angle;
@@ -165,8 +169,7 @@ void MultiLayerDWBASimulation::runMagnetic()
     double lambda = 2*M_PI/m_ki_real.mag();
 
     // collect all (alpha, phi) angles and calculate Fresnel coefficients
-
-    // TODO: reverse  B-field for k_f
+    // (also one set of coefficients for the incoming wavevector)
     typedef Utils::UnorderedMap<double, SpecularMagnetic::MultiLayerCoeff_t>
         container_phi_t;
     typedef Utils::UnorderedMap<double, container_phi_t> container_t;
@@ -179,6 +182,10 @@ void MultiLayerDWBASimulation::runMagnetic()
     kvector_t kvec;
     container_phi_t phi_coeffs;
     SpecularMagnetic::MultiLayerCoeff_t coeffs;
+    // the coefficients for the incoming wavevector are calculated on the
+    // sample with inverted magnetic field:
+    boost::scoped_ptr<MultiLayer> P_inverted_B_multi_layer(
+            mp_multi_layer->cloneInvertB());
     for (std::set<double>::const_iterator it_alpha =
              alpha_set.begin(); it_alpha != alpha_set.end(); ++it_alpha) {
         alpha = *it_alpha;
@@ -186,14 +193,17 @@ void MultiLayerDWBASimulation::runMagnetic()
         for (std::set<double>::const_iterator it_phi =
              phi_set.begin(); it_phi != phi_set.end(); ++it_phi) {
             phi = *it_phi;
-            kvec.setLambdaAlphaPhi(lambda, -alpha, -phi);
-            specularCalculator.execute(*mp_multi_layer, kvec, coeffs);
+            kvec.setLambdaAlphaPhi(lambda, alpha, phi);
+            specularCalculator.execute(*P_inverted_B_multi_layer, -kvec, coeffs);
             phi_coeffs[phi] = coeffs;
         }
         multi_layer_coeff_buffer[alpha] = phi_coeffs;
     }
+    // the coefficients for the incoming wavevector are calculated on the
+    // original sample
+    specularCalculator.execute(*mp_multi_layer, m_ki_real, coeffs);
 
-    // run through layers and add DWBA calculated from these layers
+    // run through layers and add DWBA from each layer
     MagneticCoefficientsMap::container_phi_t phi_layer_coeffs;
     for(size_t i_layer=0;
         i_layer<mp_multi_layer->getNumberOfLayers(); ++i_layer) {
@@ -201,6 +211,7 @@ void MultiLayerDWBASimulation::runMagnetic()
                 "-> Layer " << i_layer;
         MagneticCoefficientsMap coeff_map;
 
+        // construct the reflection/transmission coefficients for this layer
         for(Utils::UnorderedMap<double, container_phi_t>::const_iterator
                 it_alpha = multi_layer_coeff_buffer.begin();
                 it_alpha!=multi_layer_coeff_buffer.end(); ++it_alpha) {
@@ -217,6 +228,8 @@ void MultiLayerDWBASimulation::runMagnetic()
             }
             coeff_map[alpha] = phi_layer_coeffs;
         }
+        // add reflection/transmission coeffs from incoming beam
+        coeff_map.incomingCoeff() = coeffs[i_layer];
 
         // layer DWBA simulation
         std::map<size_t, LayerDWBASimulation*>::const_iterator pos =
@@ -241,8 +254,6 @@ std::set<double> MultiLayerDWBASimulation::getAlphaList() const
         result.insert(alpha_bin.getMidPoint());
         result.insert(alpha_bin.m_upper);
     }
-    // Also add input angle
-    result.insert(-m_alpha_i);
     return result;
 }
 
@@ -256,7 +267,5 @@ std::set<double> MultiLayerDWBASimulation::getPhiList() const
         result.insert(phi_bin.getMidPoint());
         result.insert(phi_bin.m_upper);
     }
-    // Also add input angle
-    result.insert(0.0);
     return result;
 }
diff --git a/Core/Samples/inc/Crystal.h b/Core/Samples/inc/Crystal.h
index 2c9b6e067659bdd0ed32060e0c91f74da2c85100..56d3d088c791810a34af9d2ad4f29ddd93b5fc39 100644
--- a/Core/Samples/inc/Crystal.h
+++ b/Core/Samples/inc/Crystal.h
@@ -25,12 +25,15 @@
 
 class Crystal : public IClusteredParticles
 {
- public:
+public:
     Crystal(const LatticeBasis& lattice_basis, const Lattice& lattice);
     ~Crystal();
 
     virtual Crystal *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual Crystal *cloneInvertB() const;
+
     //! Calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
 
@@ -51,7 +54,9 @@ class Crystal : public IClusteredParticles
     virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(
             const ParticleInfo& parent_info) const;
 
- private:
+private:
+    Crystal(LatticeBasis *p_lattice_basis, const Lattice& lattice);
+
     Lattice m_lattice;
     LatticeBasis *mp_lattice_basis;
     double m_dw_factor;
diff --git a/Core/Samples/inc/IClusteredParticles.h b/Core/Samples/inc/IClusteredParticles.h
index fc48f63c0e2444966c3c5ed907ec7d71ab892615..13b2783b5a677ff5fa50492a9fc26ba3c10424af 100644
--- a/Core/Samples/inc/IClusteredParticles.h
+++ b/Core/Samples/inc/IClusteredParticles.h
@@ -26,36 +26,49 @@
 
 class IClusteredParticles : public ICompositeSample
 {
- public:
+public:
     IClusteredParticles() {}
     virtual ~IClusteredParticles() {}
     //! clone method to allow for polymorphic copying
-    virtual IClusteredParticles *clone() const { throw NotImplementedException("IClusteredParticles::clone() -> Error! Not implemented exception"); }
-
-    virtual void setAmbientMaterial(const IMaterial *p_ambient_material)=0;
-
-    //! @brief create a total form factor for the mesocrystal with a specific shape and content
-    //! @param meso_crystal_form_factor  the form factor describing the shape of the mesocrystal
-    //! @param ambient_refractive_index  the refractive index of the ambient material
-    //! The bulk content of the mesocrystal is encapsulated by the IClusteredParticles object itself
-//    virtual IFormFactor *createTotalFormFactor(const IFormFactor& meso_crystal_form_factor,
-//            complex_t ambient_refractive_index) const=0;
+    virtual IClusteredParticles *clone() const {
+        throw NotImplementedException("IClusteredParticles::clone() -> Error! "
+                "Not implemented exception");
+    }
 
-//    virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(const ParticleInfo& parent_info) const=0;
+    //! Returns a clone with inverted magnetic fields
+    virtual IClusteredParticles *cloneInvertB() const {
+        throw NotImplementedException("IClusteredParticles::cloneInvertB() -> "
+                "Error! Not implemented exception");
+    }
 
+    virtual void setAmbientMaterial(const IMaterial *p_ambient_material)=0;
 
-    virtual IFormFactor *createTotalFormFactor(const IFormFactor& meso_crystal_form_factor,
-            const IMaterial *p_ambient_material) const
+    //! @brief create a total form factor for the mesocrystal with a specific
+    //! shape and content
+    //! @param meso_crystal_form_factor  the form factor describing the shape
+    //! of the mesocrystal
+    //! @param ambient_refractive_index  the refractive index of the
+    //! ambient material
+    //! The bulk content of the mesocrystal is encapsulated by the
+    //! IClusteredParticles object itself
+   virtual IFormFactor *createTotalFormFactor(
+           const IFormFactor& meso_crystal_form_factor,
+           const IMaterial *p_ambient_material) const
     {
         (void)meso_crystal_form_factor;
         (void)p_ambient_material;
-        throw NotImplementedException("IClusteredParticles::createTotalFormFactor() -> NotImplementedException");
+        throw NotImplementedException(
+                "IClusteredParticles::createTotalFormFactor() "
+                "-> NotImplementedException");
     }
 
-    virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(const ParticleInfo& parent_info) const
+    virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(
+            const ParticleInfo& parent_info) const
     {
         (void)parent_info;
-        throw NotImplementedException("IClusteredParticles::createDiffuseParticleInfo() -> NotImplementedException");
+        throw NotImplementedException(
+                "IClusteredParticles::createDiffuseParticleInfo() "
+                "-> NotImplementedException");
     }
 
 };
diff --git a/Core/Samples/inc/IDecoration.h b/Core/Samples/inc/IDecoration.h
index e077a352878be09e8f010e19d618b81c055a7e95..ba7182132b569f418263b15a7a0f2991257a0afd 100644
--- a/Core/Samples/inc/IDecoration.h
+++ b/Core/Samples/inc/IDecoration.h
@@ -34,6 +34,9 @@ class IDecoration : public ICompositeSample
 
     virtual IDecoration *clone() const=0;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual IDecoration *cloneInvertB() const=0;
+
     //! Returns number of particles
     virtual size_t getNumberOfParticles() const=0;
 
diff --git a/Core/Samples/inc/ISample.h b/Core/Samples/inc/ISample.h
index c2bdf78b8099df0c24afdbf65a05c0e501f2198c..a2fba75736a63c67cb8a1f5d16ba48fefd11d587 100644
--- a/Core/Samples/inc/ISample.h
+++ b/Core/Samples/inc/ISample.h
@@ -37,6 +37,9 @@ class BA_CORE_API_ ISample : public IParameterized, public ICloneable
 
     virtual ISample *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual ISample *cloneInvertB() const;
+
     //! Calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *p_visitor) const = 0;
 
diff --git a/Core/Samples/inc/LatticeBasis.h b/Core/Samples/inc/LatticeBasis.h
index ba8a1b1b9acf9f02c6099f085df88016830404d3..89a76be3fae5562b4e5da67f001f147486461568 100644
--- a/Core/Samples/inc/LatticeBasis.h
+++ b/Core/Samples/inc/LatticeBasis.h
@@ -22,13 +22,16 @@
 
 class LatticeBasis : public Particle
 {
- public:
+public:
     LatticeBasis();
     LatticeBasis(const Particle& particle);
     LatticeBasis(const Particle& particle, std::vector<kvector_t > positions);
     virtual ~LatticeBasis();
     virtual LatticeBasis *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual LatticeBasis *cloneInvertB() const;
+
     //! Calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
 
@@ -57,10 +60,13 @@ class LatticeBasis : public Particle
     //! Creates vector of size/shape distributed particles corresponding to the particle with index i
     std::vector<DiffuseParticleInfo *> createDiffuseParticleInfos() const;
 
- private:
+private:
     //! Checks index
     inline size_t check_index(size_t index) const { return index < m_positions_vector.size() ? index : throw OutOfBoundsException("LatticeBasis::check_index() -> Index is out of bounds"); }
 
+    //! For internal use in cloneInvertB():
+    void addParticle(Particle *p_particle, std::vector<kvector_t > positions);
+
     std::vector<Particle *> m_particles;
     std::vector<std::vector<kvector_t> > m_positions_vector;
 };
diff --git a/Core/Samples/inc/Layer.h b/Core/Samples/inc/Layer.h
index cc422d9247eef8eb12b50fbbaa94a88d191de00e..4dee98ad602bac31771d5c37e045ff9d6c456b20 100644
--- a/Core/Samples/inc/Layer.h
+++ b/Core/Samples/inc/Layer.h
@@ -40,6 +40,9 @@ class BA_CORE_API_ Layer : public ICompositeSample
 
     virtual Layer *clone() const { return new Layer(*this); }
 
+    //! Returns a clone with inverted magnetic fields
+    virtual Layer *cloneInvertB() const;
+
     //! Calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
 
diff --git a/Core/Samples/inc/MaterialManager.h b/Core/Samples/inc/MaterialManager.h
index eba95e275228ffe3eb30615f637007bbcd127c1b..97ab6c8c8267c2cb21d8b39f18852fa81e4e3b92 100644
--- a/Core/Samples/inc/MaterialManager.h
+++ b/Core/Samples/inc/MaterialManager.h
@@ -42,12 +42,12 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
     static const IMaterial *getMaterial(const std::string& name)
     { return instance().this_getMaterial(name); }
 
-    //! Adds material to database.
+    //! Adds and returns material to database.
     static const IMaterial *getHomogeneousMaterial(
         const std::string& name, const complex_t& refractive_index)
     { return instance().this_getHomogeneousMaterial(name, refractive_index); }
 
-    //! Adds material to database.
+    //! Adds and returns material to database.
     static const IMaterial *getHomogeneousMaterial(
         const std::string& name,
         double refractive_index_delta,
@@ -55,14 +55,14 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
     { return instance().this_getHomogeneousMaterial(
             name, refractive_index_delta, refractive_index_beta); }
 
-    //! Adds magnetic material to database.
+    //! Adds and returns magnetic material to database.
     static const IMaterial *getHomogeneousMagneticMaterial(
         const std::string& name, const complex_t& refractive_index,
         const kvector_t &magnetic_field)
     { return instance().this_getHomogeneousMagneticMaterial(name,
             refractive_index, magnetic_field); }
 
-    //! Adds magnetic material to database.
+    //! Adds and returns magnetic material to database.
     static const IMaterial *getHomogeneousMagneticMaterial(
         const std::string& name,
         double refractive_index_delta,
@@ -72,6 +72,12 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
             name, refractive_index_delta, refractive_index_beta,
             magnetic_field); }
 
+    //! Adds and returns material with inverted magnetic field (if present) to
+    //! database. The new material is based on the material with the given name
+    static const IMaterial *getInvertedMaterial(
+            const std::string& name)
+    { return instance().this_getInvertedMaterial(name); }
+
     //! returns number of materials
     static int getNumberOfMaterials() { return instance().
             this_getNumberOfMaterials(); }
@@ -122,6 +128,8 @@ class BA_CORE_API_ MaterialManager: public ISingleton<MaterialManager>
         const std::string& name,
         double refractive_index_delta, double refractive_index_beta,
         const kvector_t &magnetic_field);
+    const IMaterial *this_getInvertedMaterial(
+        const std::string& name);
     int this_getNumberOfMaterials() const { return (int)m_materials.size(); }
 
     void check_refractive_index(const complex_t &index);
diff --git a/Core/Samples/inc/MesoCrystal.h b/Core/Samples/inc/MesoCrystal.h
index 639703b398e12ff013f5882b94bbca6f49aa86ca..b435836fc633f0e65ca7830a5114e3c902f9a09a 100644
--- a/Core/Samples/inc/MesoCrystal.h
+++ b/Core/Samples/inc/MesoCrystal.h
@@ -31,6 +31,9 @@ class MesoCrystal : public Particle
     virtual ~MesoCrystal();
     virtual MesoCrystal *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual MesoCrystal *cloneInvertB() const;
+
     //! Calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
 
diff --git a/Core/Samples/inc/MultiLayer.h b/Core/Samples/inc/MultiLayer.h
index 5ed64919e3f95dde611caf7107700b60f94f1a6a..51aa9fe2210b555416a6244059e76f4caa0a66d9 100644
--- a/Core/Samples/inc/MultiLayer.h
+++ b/Core/Samples/inc/MultiLayer.h
@@ -83,9 +83,13 @@ class BA_CORE_API_ MultiLayer : public ICompositeSample
     //! Destructs allocated objects
     void clear();
 
-    //! Returns alone of multilayer with clones of all layers and recreated interfaces between layers
+    //! Returns alone of multilayer with clones of all layers and recreated
+    //! interfaces between layers
     virtual MultiLayer *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual MultiLayer *cloneInvertB() const;
+
     //! Sets cross correlation length of roughnesses between interfaces
     inline void setCrossCorrLength(double crossCorrLength)
     {
@@ -100,7 +104,8 @@ class BA_CORE_API_ MultiLayer : public ICompositeSample
     ///! correlation function of roughnesses between the interfaces
     //double getCrossCorrFun(const kvector_t& k, int j, int k) const;
 
-    //! Fourier transform of the correlation function of roughnesses between the interfaces
+    //! Fourier transform of the correlation function of roughnesses between
+    //! the interfaces
     double getCrossCorrSpectralFun(
         const kvector_t& kvec, size_t j, size_t k) const;
 
@@ -111,7 +116,8 @@ class BA_CORE_API_ MultiLayer : public ICompositeSample
     friend std::ostream& operator << (std::ostream& ostr, const MultiLayer& m)
     { m.print(ostr); return ostr; }
 
-    //! look for the presence of DWBA terms (e.g. included particles) and return ISimulation if needed
+    //! look for the presence of DWBA terms (e.g. included particles) and return
+    //! ISimulation if needed
     virtual MultiLayerDWBASimulation *createDWBASimulation() const;
 
  protected:
diff --git a/Core/Samples/inc/Particle.h b/Core/Samples/inc/Particle.h
index 82b5b84163dad1b8be6365d65b8bdb98cd1cd857..0db8ce6e7e8caad16c31360f6b4f22b9c447287d 100644
--- a/Core/Samples/inc/Particle.h
+++ b/Core/Samples/inc/Particle.h
@@ -35,6 +35,9 @@ class BA_CORE_API_ Particle : public ICompositeSample
     virtual ~Particle();
     virtual Particle *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual Particle *cloneInvertB() const;
+
     //! calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
 
diff --git a/Core/Samples/inc/ParticleCoreShell.h b/Core/Samples/inc/ParticleCoreShell.h
index cccf7e85f930ffdc0ece2e134f8b790466048549..e806aac9cde09cdf104d1bceaed4922b4bcee3f1 100644
--- a/Core/Samples/inc/ParticleCoreShell.h
+++ b/Core/Samples/inc/ParticleCoreShell.h
@@ -22,15 +22,22 @@
 
 class ParticleCoreShell : public Particle
 {
- public:
-    ParticleCoreShell(const Particle& shell, const Particle& core, kvector_t relative_core_position);
+public:
+    ParticleCoreShell(const Particle& shell, const Particle& core,
+            kvector_t relative_core_position);
     virtual ~ParticleCoreShell();
     virtual ParticleCoreShell *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual ParticleCoreShell *cloneInvertB() const;
+
     //! Calls the ISampleVisitor's visit method
-    virtual void accept(ISampleVisitor *p_visitor) const { p_visitor->visit(this); }
+    virtual void accept(ISampleVisitor *p_visitor) const {
+        p_visitor->visit(this);
+    }
 
-    //! Sets the refractive index of the ambient material (which influences its scattering power)
+    //! Sets the refractive index of the ambient material (which influences
+    //! its scattering power)
     virtual void setAmbientMaterial(const IMaterial *p_material)
     {
         mp_ambient_material = p_material;
@@ -40,7 +47,8 @@ class ParticleCoreShell : public Particle
 
     virtual IFormFactor* createFormFactor() const;
 
-    //! Sets the formfactor of the particle (not including scattering factor from refractive index)
+    //! Sets the formfactor of the particle (not including scattering factor
+    //! from refractive index)
     virtual void setSimpleFormFactor(IFormFactor* p_form_factor)
     {
         if (p_form_factor != mp_form_factor) {
@@ -51,16 +59,21 @@ class ParticleCoreShell : public Particle
         }
     }
 
-    //! Returns formfactor of the particle (not including scattering factor from refractive index)
-    virtual const IFormFactor *getSimpleFormFactor() const { return mp_form_factor;}
+    //! Returns formfactor of the particle (not including scattering factor
+    //! from refractive index)
+    virtual const IFormFactor *getSimpleFormFactor() const {
+        return mp_form_factor;
+    }
 
     //! Creates list of contained particles for diffuse calculations
-    virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(const ParticleInfo& parent_info) const {
+    virtual std::vector<DiffuseParticleInfo *> *createDiffuseParticleInfo(
+            const ParticleInfo& parent_info) const {
         (void)parent_info;
         return 0;
     }
 
- protected:
+protected:
+    ParticleCoreShell(kvector_t relative_core_position);
     Particle *mp_shell;
     Particle *mp_core;
     kvector_t m_relative_core_position;
diff --git a/Core/Samples/inc/ParticleDecoration.h b/Core/Samples/inc/ParticleDecoration.h
index b9c2e5d13aa4b91ef368686aaf6ba9404c9448e2..f35d5037eb46bed72bf135f3d63a8aaf7a3e003d 100644
--- a/Core/Samples/inc/ParticleDecoration.h
+++ b/Core/Samples/inc/ParticleDecoration.h
@@ -56,6 +56,9 @@ class BA_CORE_API_ ParticleDecoration : public IDecoration
 
     virtual ParticleDecoration *clone() const;
 
+    //! Returns a clone with inverted magnetic fields
+    virtual ParticleDecoration *cloneInvertB() const;
+
     //! calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
 
diff --git a/Core/Samples/inc/ParticleInfo.h b/Core/Samples/inc/ParticleInfo.h
index 938dbeaa089bb2b7fe97ed08af73d46d8b2cfba7..b290eb8cf61fd1b1051193b4c5f2f012677dc23e 100644
--- a/Core/Samples/inc/ParticleInfo.h
+++ b/Core/Samples/inc/ParticleInfo.h
@@ -44,6 +44,13 @@ class ParticleInfo : public ICompositeSample
             mp_particle->clone(), mP_transform, m_depth, m_abundance);
     }
 
+    //! Returns a clone with inverted magnetic fields
+    virtual ParticleInfo *cloneInvertB() const
+    {
+        return new ParticleInfo(
+            mp_particle->cloneInvertB(), mP_transform, m_depth, m_abundance);
+    }
+
     //! calls the ISampleVisitor's visit method
     virtual void accept(ISampleVisitor *visitor) const { visitor->visit(this); }
 
diff --git a/Core/Samples/src/Crystal.cpp b/Core/Samples/src/Crystal.cpp
index a34c9e3aea85c3230102e8105f63db5a25abf517..2df30de9d08fa5702b767c0379a8934dddaf7661 100644
--- a/Core/Samples/src/Crystal.cpp
+++ b/Core/Samples/src/Crystal.cpp
@@ -41,6 +41,14 @@ Crystal* Crystal::clone() const
     return p_new;
 }
 
+Crystal* Crystal::cloneInvertB() const
+{
+    Crystal *p_new = new Crystal(mp_lattice_basis->cloneInvertB(), m_lattice);
+    p_new->setDWFactor(m_dw_factor);
+    p_new->setName(getName() + "_inv");
+    return p_new;
+}
+
 IFormFactor* Crystal::createTotalFormFactor(
         const IFormFactor& meso_crystal_form_factor,
         const IMaterial *p_ambient_material) const
@@ -82,4 +90,11 @@ std::vector<DiffuseParticleInfo*>* Crystal::createDiffuseParticleInfo(
     return p_result;
 }
 
-
+Crystal::Crystal(LatticeBasis* p_lattice_basis, const Lattice& lattice)
+: m_lattice(lattice)
+, m_dw_factor(0.0)
+{
+    setName("Crystal");
+    mp_lattice_basis = p_lattice_basis;
+    registerChild(mp_lattice_basis);
+}
diff --git a/Core/Samples/src/ISample.cpp b/Core/Samples/src/ISample.cpp
index 7227ff150cc416f5e728e042d09a1064a48ce151..ad59306d3c2a6112379c99dadd1a3b339a99d006 100644
--- a/Core/Samples/src/ISample.cpp
+++ b/Core/Samples/src/ISample.cpp
@@ -27,6 +27,13 @@ ISample *ISample::clone() const
 
 //! Adds params from local to external pool and recurses over direct children.
 
+ISample* ISample::cloneInvertB() const
+{
+    throw NotImplementedException(
+        "ISample::cloneInvertB() -> "
+        "Error! Method is not implemented");
+}
+
 std::string ISample::addParametersToExternalPool(
     std::string path, ParameterPool *external_pool, int copy_number) const
 {
diff --git a/Core/Samples/src/LatticeBasis.cpp b/Core/Samples/src/LatticeBasis.cpp
index 0a9267eff12ef8ff4964fd9b05ca5a6ca615b76d..c2bb8c46850181be1f21904a6f0f97c6b2e7440c 100644
--- a/Core/Samples/src/LatticeBasis.cpp
+++ b/Core/Samples/src/LatticeBasis.cpp
@@ -16,6 +16,7 @@
 #include "LatticeBasis.h"
 #include "FormFactors.h"
 #include "DiffuseParticleInfo.h"
+#include "MaterialManager.h"
 
 LatticeBasis::LatticeBasis()
 {
@@ -55,6 +56,20 @@ LatticeBasis* LatticeBasis::clone() const
     return p_new;
 }
 
+LatticeBasis* LatticeBasis::cloneInvertB() const
+{
+    LatticeBasis *p_new = new LatticeBasis();
+    for (size_t index=0; index<m_particles.size(); ++index) {
+        p_new->addParticle(m_particles[index]->cloneInvertB(),
+                m_positions_vector[index]);
+    }
+    p_new->setName(getName() + "_inv");
+    const IMaterial *p_ambient_material = MaterialManager::getInvertedMaterial(
+            this->mp_ambient_material->getName());
+    p_new->mp_ambient_material = p_ambient_material;
+    return p_new;
+}
+
 void LatticeBasis::addParticle(const Particle& particle, std::vector<kvector_t > positions)
 {
     Particle *np = particle.clone();
@@ -99,4 +114,10 @@ std::vector<DiffuseParticleInfo *> LatticeBasis::createDiffuseParticleInfos() co
     return result;
 }
 
-
+void LatticeBasis::addParticle(Particle* p_particle,
+        std::vector<kvector_t> positions)
+{
+    registerChild(p_particle);
+    m_particles.push_back(p_particle);
+    m_positions_vector.push_back(positions);
+}
diff --git a/Core/Samples/src/Layer.cpp b/Core/Samples/src/Layer.cpp
index fbfd18f2af67458db0a5fe08a2329508a5f5aa57..f38d136e009f14d1c8d11943dfa289c934c212b6 100644
--- a/Core/Samples/src/Layer.cpp
+++ b/Core/Samples/src/Layer.cpp
@@ -16,6 +16,7 @@
 #include "Layer.h"
 #include "Exceptions.h"
 #include "DecoratedLayerDWBASimulation.h"
+#include "MaterialManager.h"
 
 #include <iomanip>
 
@@ -71,6 +72,21 @@ Layer::~Layer()
 }
 
 
+Layer* Layer::cloneInvertB() const
+{
+    Layer *p_clone = new Layer();
+    p_clone->mp_material = MaterialManager::getInvertedMaterial(this->mp_material->getName());
+    p_clone->mp_decoration = 0;
+    if(this->getDecoration()) {
+        p_clone->setDecoration(this->getDecoration()->cloneInvertB());
+    }
+    p_clone->m_thickness = this->m_thickness;
+    std::string clone_name = this->getName() + "_inv";
+    p_clone->setName(clone_name);
+    p_clone->init_parameters();
+    return p_clone;
+}
+
 void Layer::init_parameters()
 {
     clearParameterPool();
@@ -121,7 +137,6 @@ void Layer::setDecoration(const IDecoration &decoration)
     setDecoration(decoration.clone());
 }
 
-
 //! Prints description.
 void Layer::print(std::ostream& ostr) const
 {
diff --git a/Core/Samples/src/MaterialManager.cpp b/Core/Samples/src/MaterialManager.cpp
index 5845bbd80b83ce503b37de650ccfc6b4fe97be82..16ab2980d434ea35acf19ab9e6519a007bd17ecb 100644
--- a/Core/Samples/src/MaterialManager.cpp
+++ b/Core/Samples/src/MaterialManager.cpp
@@ -153,8 +153,21 @@ const IMaterial* MaterialManager::this_getHomogeneousMagneticMaterial(
         magnetic_field);
 }
 
-//! Dump this to stream.
+const IMaterial* MaterialManager::this_getInvertedMaterial(
+        const std::string& name)
+{
+    const IMaterial *p_orig_material = getMaterial(name);
+    if (!p_orig_material) return 0;
+    const HomogeneousMagneticMaterial *p_magn_material =
+            dynamic_cast<const HomogeneousMagneticMaterial *>(p_orig_material);
+    if (!p_magn_material) return p_orig_material;
+    std::string new_name = name + "_inv";
+    return this_getHomogeneousMagneticMaterial(new_name,
+            p_magn_material->getRefractiveIndex(),
+            -p_magn_material->getMagneticField());
+}
 
+//! Dump this to stream.
 void MaterialManager::print(std::ostream& ostr) const
 {
     ostr << typeid(*this).name() << " " << this <<
diff --git a/Core/Samples/src/MesoCrystal.cpp b/Core/Samples/src/MesoCrystal.cpp
index 5d6aca0604de8625615a297126d3ba2a166a9202..f55e0114dc163c0f81b62f04f824b4b8cfce5d0d 100644
--- a/Core/Samples/src/MesoCrystal.cpp
+++ b/Core/Samples/src/MesoCrystal.cpp
@@ -43,7 +43,14 @@ MesoCrystal::~MesoCrystal()
 
 MesoCrystal* MesoCrystal::clone() const
 {
-    return new MesoCrystal(mp_particle_structure->clone(), mp_meso_form_factor->clone());
+    return new MesoCrystal(mp_particle_structure->clone(),
+            mp_meso_form_factor->clone());
+}
+
+MesoCrystal* MesoCrystal::cloneInvertB() const
+{
+    return new MesoCrystal(mp_particle_structure->cloneInvertB(),
+            mp_meso_form_factor->clone());
 }
 
 std::vector<DiffuseParticleInfo*>* MesoCrystal::createDiffuseParticleInfo(
diff --git a/Core/Samples/src/MultiLayer.cpp b/Core/Samples/src/MultiLayer.cpp
index 03cac1bb1826d7c28008cc36c58a73b9e8ee5817..0d72e660d44bf8ad2c5004b54d3443b8d2e39299 100644
--- a/Core/Samples/src/MultiLayer.cpp
+++ b/Core/Samples/src/MultiLayer.cpp
@@ -80,9 +80,11 @@ MultiLayer *MultiLayer::clone() const
 
         LayerInterface *newInterface(0);
         if(m_interfaces[i]->getRoughness()) {
-            newInterface = LayerInterface::createRoughInterface(topLayer, bottomLayer, *m_interfaces[i]->getRoughness() );
+            newInterface = LayerInterface::createRoughInterface(topLayer,
+                    bottomLayer, *m_interfaces[i]->getRoughness() );
         } else {
-            newInterface = LayerInterface::createSmoothInterface(topLayer, bottomLayer );
+            newInterface = LayerInterface::createSmoothInterface(topLayer,
+                    bottomLayer );
         }
         newMultiLayer->addAndRegisterInterface( newInterface );
     }
@@ -94,10 +96,41 @@ MultiLayer *MultiLayer::clone() const
     return newMultiLayer;
 }
 
-//! Returns pointer to the top interface of the layer.
+MultiLayer* MultiLayer::cloneInvertB() const
+{
+    MultiLayer *newMultiLayer = new MultiLayer();
+    newMultiLayer->setName(getName());
 
+    newMultiLayer->m_layers_z = m_layers_z;
+
+    for(size_t i=0; i<m_layers.size(); i++) {
+        newMultiLayer->addAndRegisterLayer( m_layers[i]->cloneInvertB() );
+    }
+
+    for(size_t i=0; i<m_interfaces.size(); i++) {
+        const Layer *topLayer = newMultiLayer->m_layers[i];
+        const Layer *bottomLayer = newMultiLayer->m_layers[i+1];
+
+        LayerInterface *newInterface(0);
+        if(m_interfaces[i]->getRoughness()) {
+            newInterface = LayerInterface::createRoughInterface(topLayer,
+                    bottomLayer, *m_interfaces[i]->getRoughness() );
+        } else {
+            newInterface = LayerInterface::createSmoothInterface(topLayer,
+                    bottomLayer );
+        }
+        newMultiLayer->addAndRegisterInterface( newInterface );
+    }
+
+    newMultiLayer->m_crossCorrLength = m_crossCorrLength;
+
+    newMultiLayer->init_parameters();
+
+    return newMultiLayer;
+}
+
+//! Returns pointer to the top interface of the layer.
 //! nInterfaces = nLayers-1, first layer in multilayer doesn't have interface.
-//!
 const LayerInterface *MultiLayer::getLayerTopInterface(size_t i_layer) const
 {
     return i_layer>0 ? m_interfaces[ check_interface_index(i_layer-1) ] : 0;
diff --git a/Core/Samples/src/Particle.cpp b/Core/Samples/src/Particle.cpp
index 7097fceb567e47429121a00f602414fbfd07c7ff..f56e651de6446fb10e6f1697fd73e9b990b2e51c 100644
--- a/Core/Samples/src/Particle.cpp
+++ b/Core/Samples/src/Particle.cpp
@@ -16,6 +16,8 @@
 #include "Particle.h"
 #include "ParticleInfo.h"
 
+#include "MaterialManager.h"
+
 
 Particle::Particle()
 : mp_material(0)
@@ -62,6 +64,23 @@ Particle* Particle::clone() const
     return p_new;
 }
 
+Particle* Particle::cloneInvertB() const
+{
+    IFormFactor *p_form_factor(0);
+    if(mp_form_factor) p_form_factor = mp_form_factor->clone();
+
+    const IMaterial *p_material = MaterialManager::getInvertedMaterial(
+            mp_material->getName());
+    const IMaterial *p_ambient_material = MaterialManager::getInvertedMaterial(
+            mp_ambient_material->getName());
+
+    Particle *p_new = new Particle(p_material, p_form_factor);
+    p_new->setAmbientMaterial(p_ambient_material);
+
+    p_new->setName(getName() + "_inv");
+    return p_new;
+}
+
 std::vector<ParticleInfo*> Particle::createDistributedParticles(
         size_t samples_per_particle, double factor) const
 {
diff --git a/Core/Samples/src/ParticleCoreShell.cpp b/Core/Samples/src/ParticleCoreShell.cpp
index 58a0b60fcf5dfd16e48e6d1f7de5c8f8eda701e1..263963bb018ea2202f913f8eca58299df14303e4 100644
--- a/Core/Samples/src/ParticleCoreShell.cpp
+++ b/Core/Samples/src/ParticleCoreShell.cpp
@@ -15,8 +15,10 @@
 
 #include "ParticleCoreShell.h"
 #include "FormFactors.h"
+#include "MaterialManager.h"
 
-ParticleCoreShell::ParticleCoreShell(const Particle& shell, const Particle& core, kvector_t relative_core_position)
+ParticleCoreShell::ParticleCoreShell(const Particle& shell,
+        const Particle& core, kvector_t relative_core_position)
     : m_relative_core_position(relative_core_position)
 {
     mp_shell = shell.clone();
@@ -31,28 +33,49 @@ ParticleCoreShell::~ParticleCoreShell()
 
 ParticleCoreShell *ParticleCoreShell::clone() const
 {
-    ParticleCoreShell *p_new = new ParticleCoreShell(*mp_shell, *mp_core, m_relative_core_position);
+    ParticleCoreShell *p_new = new ParticleCoreShell(*mp_shell, *mp_core,
+            m_relative_core_position);
     p_new->setAmbientMaterial(mp_ambient_material);
     return p_new;
 }
 
+ParticleCoreShell* ParticleCoreShell::cloneInvertB() const
+{
+    ParticleCoreShell *p_new = new ParticleCoreShell(m_relative_core_position);
+    p_new->mp_shell = this->mp_shell->cloneInvertB();
+    p_new->mp_core = this->mp_core->cloneInvertB();
+    const IMaterial *p_ambient_material = MaterialManager::getInvertedMaterial(
+            this->mp_ambient_material->getName());
+    p_new->setAmbientMaterial(p_ambient_material);
+    return p_new;
+}
+
 IFormFactor *ParticleCoreShell::createFormFactor() const
 {
     FormFactorWeighted *p_result = new FormFactorWeighted;
-    FormFactorDecoratorRefractiveIndex ff_shell(mp_shell->getSimpleFormFactor()->clone(),
+    FormFactorDecoratorRefractiveIndex ff_shell(mp_shell->
+            getSimpleFormFactor()->clone(),
             mp_shell->getRefractiveIndex());
     ff_shell.setAmbientMaterial(mp_ambient_material);
     p_result->addFormFactor(ff_shell, 1.0);
     complex_t ambient_index = mp_ambient_material->getRefractiveIndex();
-    complex_t core_index = std::sqrt(mp_core->getRefractiveIndex()*mp_core->getRefractiveIndex()
+    complex_t core_index = std::sqrt(mp_core->getRefractiveIndex()*mp_core->
+            getRefractiveIndex()
             - mp_shell->getRefractiveIndex()*mp_shell->getRefractiveIndex()
             + ambient_index*ambient_index);
-    FormFactorDecoratorRefractiveIndex ff_core(mp_core->getSimpleFormFactor()->clone(),
+    FormFactorDecoratorRefractiveIndex ff_core(mp_core->getSimpleFormFactor()->
+            clone(),
             core_index);
     ff_core.setAmbientMaterial(mp_ambient_material);
-    FormFactorDecoratorPositionFactor ff_core_translated(ff_core, m_relative_core_position);
+    FormFactorDecoratorPositionFactor ff_core_translated(ff_core,
+            m_relative_core_position);
     p_result->addFormFactor(ff_core_translated, 1.0);
     return p_result;
 }
 
-
+ParticleCoreShell::ParticleCoreShell(kvector_t relative_core_position)
+: mp_shell(0)
+, mp_core(0)
+, m_relative_core_position(relative_core_position)
+{
+}
diff --git a/Core/Samples/src/ParticleDecoration.cpp b/Core/Samples/src/ParticleDecoration.cpp
index 20deec42668952bd7931e1f2eb43cb5381f7d130..2044561de3633c69bc191909cd9a76fc0e2717fc 100644
--- a/Core/Samples/src/ParticleDecoration.cpp
+++ b/Core/Samples/src/ParticleDecoration.cpp
@@ -42,6 +42,25 @@ ParticleDecoration* ParticleDecoration::clone() const
     return p_new;
 }
 
+ParticleDecoration* ParticleDecoration::cloneInvertB() const
+{
+    //   msglog(MSG::DEBUG) << "ParticleDecoration::clone()";
+    ParticleDecoration *p_new = new ParticleDecoration();
+    p_new->setName(getName() + "_inv");
+
+    for (size_t i=0; i<m_particles.size(); ++i)
+        p_new->addAndRegisterParticleInfo(m_particles[i]->cloneInvertB());
+
+    for (size_t i=0; i<m_interference_functions.size(); ++i)
+        p_new->addAndRegisterInterferenceFunction(
+            m_interference_functions[i]->clone());
+
+    p_new->m_total_abundance = m_total_abundance;
+    p_new->setTotalParticleSurfaceDensity(getTotalParticleSurfaceDensity());
+
+    return p_new;
+}
+
 //! Adds generic particle, *-version.
 
 void ParticleDecoration::addParticle(
diff --git a/Core/Tools/inc/MagneticCoefficientsMap.h b/Core/Tools/inc/MagneticCoefficientsMap.h
index 55ba5c209218f583ba32b8bfec3a53489f262691..56b451e585975f3747d08cbf96b54cdd61cc315b 100644
--- a/Core/Tools/inc/MagneticCoefficientsMap.h
+++ b/Core/Tools/inc/MagneticCoefficientsMap.h
@@ -26,30 +26,38 @@
 
 class MagneticCoefficientsMap
 {
- public:
+public:
     typedef Utils::UnorderedMap<double, SpecularMagnetic::LayerMatrixCoeff>
         container_phi_t;
     typedef Utils::UnorderedMap<double, container_phi_t> container_t;
 
     MagneticCoefficientsMap(){}
-    MagneticCoefficientsMap(const container_t& value_map) : m_value_map(value_map) {}
+    MagneticCoefficientsMap(const container_t& value_map,
+            SpecularMagnetic::LayerMatrixCoeff incoming_coeff)
+            : m_value_map(value_map)
+            , m_incoming_coeff(incoming_coeff) {}
+
+    MagneticCoefficientsMap *clone() const;
 
     container_phi_t&  operator[] (double key) {
         return m_value_map[key];
     }
-    MagneticCoefficientsMap *clone() const {
-        return new MagneticCoefficientsMap(m_value_map);
-    }
+
     const container_phi_t& evaluate(double value) const {
         return m_value_map.find(value);
     }
- private:
+
+    SpecularMagnetic::LayerMatrixCoeff& incomingCoeff() {
+        return m_incoming_coeff;
+    }
+private:
     container_t m_value_map;
+    SpecularMagnetic::LayerMatrixCoeff m_incoming_coeff;
 };
 
-//! Double to pair of complex unordered map.
-
-
-
+inline MagneticCoefficientsMap* MagneticCoefficientsMap::clone() const
+{
+    return new MagneticCoefficientsMap(m_value_map, m_incoming_coeff);
+}
 
 #endif /* MAGNETICCOEFFICIENTSMAP_H_ */