diff --git a/bindings/C/CMakeLists.txt b/bindings/C/CMakeLists.txt
index a7d3bddfdd0f1a6f04b738d53bbaa4b941a50905..75f35a43a93c6ff2a1e013e4ff5328b2bdf3e4d4 100644
--- a/bindings/C/CMakeLists.txt
+++ b/bindings/C/CMakeLists.txt
@@ -9,6 +9,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/adios2/adios2_c_adios.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/adios2/adios2_c_glue.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/adios2/adios2_c_io.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/adios2/adios2_c_engine.cpp
+${CMAKE_CURRENT_SOURCE_DIR}/adios2/adios2_c_variable.cpp
 )
 
 target_include_directories(adios2
@@ -26,6 +27,7 @@ install(
         adios2/adios2_c_adios.h
         adios2/adios2_c_glue.h 
         adios2/adios2_c_io.h
+        adios2/adios2_c_variable.h
         adios2/adios2_c_engine.h
   DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/adios2
 )
diff --git a/bindings/C/adios2/adios2_c_glue.h b/bindings/C/adios2/adios2_c_glue.h
index 3b1ffd65cdd4b6d33bf9f10d78e67410a7be140e..07058f294de04a4956eed554896dc251080caadf 100644
--- a/bindings/C/adios2/adios2_c_glue.h
+++ b/bindings/C/adios2/adios2_c_glue.h
@@ -3,7 +3,7 @@
  * accompanying file Copyright.txt for details.
  *
  * adios2_c_glue.h : used by languages other than C, using the C-bindings API
- * (e.g. Fortran), not meant to be for applications
+ * (e.g. Fortran), not meant to be used by applications
  *
  *  Created on: Nov 3, 2017
  *      Author: William F Godoy godoywf@ornl.gov
diff --git a/bindings/C/adios2/adios2_c_variable.cpp b/bindings/C/adios2/adios2_c_variable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee1661920bcb9ca14862adc94f33ffb801ebb581
--- /dev/null
+++ b/bindings/C/adios2/adios2_c_variable.cpp
@@ -0,0 +1,172 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * adios2_c_variable.cpp
+ *
+ *  Created on: Nov 10, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include "adios2_c_variable.h"
+
+#include "adios2/core/Variable.h"
+#include "adios2/helper/adiosFunctions.h"
+
+const char *adios2_variable_name(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_Name.c_str();
+}
+
+const char *adios2_variable_type(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_Type.c_str();
+}
+
+int adios2_variable_is_constant_dims(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    const int isConstantDims = (variableBase->m_ConstantDims) ? 1 : 0;
+    return isConstantDims;
+}
+
+const size_t adios2_variable_ndims(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_Shape.size();
+}
+
+const size_t *adios2_variable_shape(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_Shape.data();
+}
+
+const size_t *adios2_variable_start(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_Start.data();
+}
+
+const size_t *adios2_variable_count(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_Count.data();
+}
+
+const size_t
+adios2_variable_available_steps_start(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_AvailableStepsStart;
+}
+
+const size_t
+adios2_variable_available_steps_count(const adios2_Variable *variable)
+{
+    const adios2::VariableBase *variableBase =
+        reinterpret_cast<const adios2::VariableBase *>(variable);
+    return variableBase->m_AvailableStepsCount;
+}
+
+void adios2_set_dimensions(adios2_Variable *variable, const size_t ndims,
+                           const size_t *shape, const size_t *start,
+                           const size_t *count)
+{
+    auto lf_Assign = [](const size_t ndims, const size_t *input,
+                        adios2::Dims &dims) {
+
+        if (input != nullptr)
+        {
+            dims.clear();
+            dims.assign(input, input + ndims);
+        }
+    };
+
+    adios2::VariableBase *variableBase =
+        reinterpret_cast<adios2::VariableBase *>(variable);
+
+    lf_Assign(ndims, shape, variableBase->m_Shape);
+    lf_Assign(ndims, start, variableBase->m_Start);
+    lf_Assign(ndims, count, variableBase->m_Count);
+    variableBase->CheckDimensions("in call to adios2_set_selection");
+}
+
+void adios2_set_selection(adios2_Variable *variable, const size_t ndims,
+                          const size_t *start, const size_t *count)
+{
+    adios2::VariableBase *variableBase =
+        reinterpret_cast<adios2::VariableBase *>(variable);
+
+    const adios2::Dims startV(start, start + ndims);
+    const adios2::Dims countV(start, start + ndims);
+    variableBase->SetSelection({startV, countV});
+    variableBase->CheckDimensions("in call to adios2_set_selection");
+}
+
+void adios2_set_step_selection(adios2_Variable *variable,
+                               const size_t step_start, const size_t step_count)
+{
+    adios2::VariableBase *variableBase =
+        reinterpret_cast<adios2::VariableBase *>(variable);
+    variableBase->SetStepSelection(adios2::Box<size_t>{step_start, step_count});
+}
+
+void *adios2_get_data(const adios2_Variable *variable)
+{
+    const std::string type(adios2_variable_type(variable));
+
+    void *data = nullptr;
+    if (type == "compound")
+    {
+        // not supported
+    }
+#define declare_template_instantiation(T)                                      \
+    else if (type == adios2::GetType<T>())                                     \
+    {                                                                          \
+        const adios2::Variable<T> *variableCpp =                               \
+            reinterpret_cast<const adios2::Variable<T> *>(variable);           \
+        data = variableCpp->GetData();                                         \
+    }
+    ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation)
+#undef declare_template_instantiation
+
+    return data;
+}
+
+void adios2_set_data(adios2_Variable *variable, const void *data)
+{
+    if (data == nullptr)
+    {
+        const std::string name(adios2_variable_name(variable));
+        throw std::invalid_argument(
+            "ERROR: trying to pass a null pointer to variable " + name +
+            ", in call to adios2_set_data");
+    }
+
+    const std::string type(adios2_variable_type(variable));
+
+    if (type == "compound")
+    {
+        // not supported
+    }
+#define declare_template_instantiation(T)                                      \
+    else if (type == adios2::GetType<T>())                                     \
+    {                                                                          \
+        adios2::Variable<T> *variableCpp =                                     \
+            reinterpret_cast<adios2::Variable<T> *>(variable);                 \
+        variableCpp->SetData(reinterpret_cast<const T *>(data));               \
+    }
+    ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation)
+#undef declare_template_instantiation
+}
diff --git a/bindings/C/adios2/adios2_c_variable.h b/bindings/C/adios2/adios2_c_variable.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce144cc6e3be30b5c2b10844573851f62b1aea12
--- /dev/null
+++ b/bindings/C/adios2/adios2_c_variable.h
@@ -0,0 +1,127 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * adios2_c_variable.h : exposes some members of the Variable handler
+ *
+ *  Created on: Nov 10, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#ifndef BINDINGS_C_ADIOS2_ADIOS2_C_VARIABLE_H_
+#define BINDINGS_C_ADIOS2_ADIOS2_C_VARIABLE_H_
+
+#include "adios2_c_types.h"
+
+#include <stddef.h> //size_t
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Retrieve variable name (read-only)
+ * @param variable handler
+ * @return name
+ */
+const char *adios2_variable_name(const adios2_Variable *variable);
+
+/**
+ * Retrieve variable type (read-only)
+ * @param variable handler
+ * @return type
+ */
+const char *adios2_variable_type(const adios2_Variable *variable);
+
+/**
+ * Check if dimensions are constant
+ * @param variable
+ * @return 0: false (dimensions are not constant), 1: true dimensions are
+ * declared constant
+ */
+int adios2_variable_is_constant_dims(const adios2_Variable *variable);
+
+const size_t adios2_variable_ndims(const adios2_Variable *variable);
+
+/**
+ * Retrieve current variable shape (read-only)
+ * @param variable handler
+ * @return shape
+ */
+const size_t *adios2_variable_shape(const adios2_Variable *variable);
+
+/**
+ * Retrieve current variable start (read-only)
+ * @param variable handler
+ * @return
+ */
+const size_t *adios2_variable_start(const adios2_Variable *variable);
+/**
+ * Retrieve current variable shape (read-only)
+ * @param variable
+ * @return type
+ */
+const size_t *adios2_variable_count(const adios2_Variable *variable);
+
+const size_t
+adios2_variable_available_steps_start(const adios2_Variable *variable);
+const size_t
+adios2_variable_available_steps_count(const adios2_Variable *variable);
+
+/**
+ * Set new dimensions
+ * @param variable
+ * @param shape
+ * @param start
+ * @param count
+ */
+void adios2_set_dimensions(adios2_Variable *variable, const size_t ndims,
+                           const size_t *shape, const size_t *start,
+                           const size_t *count);
+
+/**
+ * Set new selection using start and count
+ * @param variable
+ * @param start
+ * @param count
+ */
+void adios2_set_selection(adios2_Variable *variable, const size_t ndims,
+                          const size_t *start, const size_t *count);
+
+/**
+ * Set new step selection using step_start and step_count
+ * @param variable
+ * @param step_start
+ * @param step_count
+ */
+void adios2_set_step_selection(adios2_Variable *variable,
+                               const size_t step_start,
+                               const size_t step_count);
+
+/**
+ * Returns the minimum required allocation (in number of elements of a certain
+ * type, not bytes)
+ * for the current selection
+ * @param variable
+ * @return memory size to be allocated by a pointer/vector to read this
+ */
+size_t adios2_selection_size(const adios2_Variable *variable);
+
+/**
+ * Get current data pointer, types must match
+ * @param variable
+ */
+void *adios2_get_data(const adios2_Variable *variable);
+
+/**
+ * Sets current data pointer, types must match
+ * @param variable
+ * @param data
+ */
+void adios2_set_data(adios2_Variable *variable, const void *data);
+
+#ifdef __cplusplus
+} // end extern C
+#endif
+
+#endif /* BINDINGS_C_ADIOS2_ADIOS2_C_VARIABLE_H_ */
diff --git a/bindings/C/adios2_c.h b/bindings/C/adios2_c.h
index 64cc07d32995449ecfb294ed3743c08b10dbec6e..2813ff6d0ec275278e51b88c234fa2a8ff9ada62 100644
--- a/bindings/C/adios2_c.h
+++ b/bindings/C/adios2_c.h
@@ -16,5 +16,6 @@
 #include "adios2/adios2_c_engine.h"
 #include "adios2/adios2_c_glue.h"
 #include "adios2/adios2_c_io.h"
+#include "adios2/adios2_c_variable.h"
 
 #endif /* ADIOS2_BINDINGS_C_ADIOS2_C_H_ */
diff --git a/examples/hello/bpReader/helloBPReaderHeatMap2D.cpp b/examples/hello/bpReader/helloBPReaderHeatMap2D.cpp
index 86fc95ed6fb180be1752efe27b27191ec4d87aa9..3305d29f4e1486b42651699b03d7881f09269ad6 100644
--- a/examples/hello/bpReader/helloBPReaderHeatMap2D.cpp
+++ b/examples/hello/bpReader/helloBPReaderHeatMap2D.cpp
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
             if (inTemperature != nullptr)
             {
                 inTemperature->SetSelection({{2, 2}, {6, 1}});
-                size_t elementsSize = inTemperature->GetElementsSize();
+                size_t elementsSize = inTemperature->SelectionSize();
                 std::vector<unsigned int> inTemperatures(elementsSize);
                 std::cout << "Pre-allocated " << elementsSize << " elements, "
                           << elementsSize * sizeof(unsigned int) << " bytes\n";
diff --git a/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp b/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp
index 71cb73f486ade9a744127fdbec5d56ebe0f837de..815a02826a43e4066418a652e60eb1d931db9c11 100644
--- a/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp
+++ b/examples/hello/bpReader/helloBPReaderHeatMap3D.cpp
@@ -100,7 +100,7 @@ int main(int argc, char *argv[])
             if (inTemperature != nullptr)
             {
                 inTemperature->SetSelection({{2, 2, 2}, {4, 4, 4}});
-                const size_t elementsSize = inTemperature->GetElementsSize();
+                const size_t elementsSize = inTemperature->SelectionSize();
                 std::vector<unsigned int> inTemperatures(elementsSize);
                 std::cout << "Pre-allocated " << elementsSize << " elements, "
                           << elementsSize * sizeof(unsigned int) << " bytes\n";
diff --git a/source/adios2/core/VariableBase.cpp b/source/adios2/core/VariableBase.cpp
index 591e5ca5bde74066d61c163bf93d36638abdc887..aa3c8fa5fea15b8c1df66a54e306358892efed7c 100644
--- a/source/adios2/core/VariableBase.cpp
+++ b/source/adios2/core/VariableBase.cpp
@@ -134,7 +134,7 @@ size_t VariableBase::GetAvailableStepsCount() const
     return m_AvailableStepsCount;
 }
 
-void VariableBase::SetStepSelection(const std::pair<size_t, size_t> &boxSteps)
+void VariableBase::SetStepSelection(const Box<size_t> &boxSteps)
 {
     if (boxSteps.second == 0)
     {
@@ -176,7 +176,7 @@ void VariableBase::ClearOperators() noexcept { m_OperatorsInfo.clear(); }
 
 void VariableBase::CheckDimensions(const std::string hint) const
 {
-    if (m_ShapeID == ShapeID::GlobalArray)
+    if (m_DebugMode && m_ShapeID == ShapeID::GlobalArray)
     {
         if (m_Start.empty() || m_Count.empty())
         {
@@ -192,7 +192,7 @@ void VariableBase::CheckDimensions(const std::string hint) const
     // TODO need to think more exceptions here
 }
 
-size_t VariableBase::GetElementsSize() const
+size_t VariableBase::SelectionSize() const
 {
     return GetTotalSize(m_Count) * m_StepsCount;
 }
@@ -204,7 +204,7 @@ void VariableBase::InitShapeType()
     {
         if (std::count(m_Shape.begin(), m_Shape.end(), JoinedDim) == 1)
         {
-            if (!m_Start.empty() &&
+            if (m_DebugMode && !m_Start.empty() &&
                 std::count(m_Start.begin(), m_Start.end(), 0) != m_Start.size())
             {
                 throw std::invalid_argument("ERROR: The Start array must be "
@@ -224,17 +224,15 @@ void VariableBase::InitShapeType()
             }
             else
             {
-                if (m_DebugMode)
+
+                if (m_DebugMode && m_ConstantDims)
                 {
-                    if (m_ConstantDims)
-                    {
-                        throw std::invalid_argument(
-                            "ERROR: isConstantShape (true) argument is invalid "
-                            "with empty start and count "
-                            "arguments in call to "
-                            "DefineVariable " +
-                            m_Name + "\n");
-                    }
+                    throw std::invalid_argument(
+                        "ERROR: isConstantShape (true) argument is invalid "
+                        "with empty start and count "
+                        "arguments in call to "
+                        "DefineVariable " +
+                        m_Name + "\n");
                 }
 
                 m_ShapeID = ShapeID::GlobalArray;
@@ -299,11 +297,14 @@ void VariableBase::InitShapeType()
         }
         else
         {
-            throw std::invalid_argument(
-                "ERROR: if the "
-                "shape is empty, start must be empty as well, in call to "
-                "DefineVariable " +
-                m_Name + "\n");
+            if (m_DebugMode)
+            {
+                throw std::invalid_argument(
+                    "ERROR: if the "
+                    "shape is empty, start must be empty as well, in call to "
+                    "DefineVariable " +
+                    m_Name + "\n");
+            }
         }
     }
 
@@ -317,6 +318,11 @@ void VariableBase::InitShapeType()
 
 void VariableBase::CheckDimensionsCommon(const std::string hint) const
 {
+    if (!m_DebugMode)
+    {
+        return;
+    }
+
     if (m_Type == "string")
     {
         if (!(m_Shape.empty() && m_Start.empty() && m_Count.empty()))
diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h
index 39d6410578db70a1d820725262e8be7e78a18edf..c57b716908a142a48e709eeb88dd41ba5304c124 100644
--- a/source/adios2/core/VariableBase.h
+++ b/source/adios2/core/VariableBase.h
@@ -148,7 +148,7 @@ public:
      * @return memory size to be allocated by a pointer/vector to read this
      * variable
      */
-    size_t GetElementsSize() const;
+    size_t SelectionSize() const;
 
 protected:
     const bool m_DebugMode = false;
diff --git a/source/adios2/helper/adiosMath.h b/source/adios2/helper/adiosMath.h
index 4ca4140170db2a5211d98abe80eb8d019bada1f1..d8dd481fc6498e0bfe55db8f411273caf4d71395 100644
--- a/source/adios2/helper/adiosMath.h
+++ b/source/adios2/helper/adiosMath.h
@@ -120,7 +120,7 @@ Box<Dims> IntersectionBox(const Box<Dims> &box1,
                           const Box<Dims> &box2) noexcept;
 
 /**
- * Get a linear index for a point inside a localBox
+ * Get a linear index for a point inside a localBox depending on data layout
  * @param localBox start and count
  * @param point inside box
  * @param isRowMajor
diff --git a/source/adios2/helper/adiosSystem.cpp b/source/adios2/helper/adiosSystem.cpp
index 233f2d096cffde6bb1b482c75bcdcbbc5a36ee72..cac0a33421628d3bbe0963968da800fe021eb6be 100644
--- a/source/adios2/helper/adiosSystem.cpp
+++ b/source/adios2/helper/adiosSystem.cpp
@@ -21,7 +21,7 @@
 
 // remove ctime warning on Windows
 #ifdef _WIN32
-#pragma warning(disable : 4996)
+#pragma warning(disable : 4996) // ctime warning
 #endif
 
 namespace adios2
@@ -46,4 +46,26 @@ std::string LocalTimeDate() noexcept
     return std::string(ctime(&now));
 }
 
-} // end namespace adios
+bool IsRowMajor(const std::string hostLanguage) noexcept
+{
+    bool isRowMajor = true;
+
+    if (hostLanguage == "Fortran" || hostLanguage == "R")
+    {
+        isRowMajor = false;
+    }
+    return isRowMajor;
+}
+
+bool IsZeroIndexed(const std::string hostLanguage) noexcept
+{
+    bool isZeroIndexed = true;
+
+    if (hostLanguage == "Fortran" || hostLanguage == "R")
+    {
+        isZeroIndexed = false;
+    }
+    return isZeroIndexed;
+}
+
+} // end namespace adios2
diff --git a/source/adios2/helper/adiosSystem.h b/source/adios2/helper/adiosSystem.h
index e241e65164a1ccf89cf805f9721dc5863ce0a5c7..0a8c2cfb78ff5903777fe1fc0ad3431af2c1fc25 100644
--- a/source/adios2/helper/adiosSystem.h
+++ b/source/adios2/helper/adiosSystem.h
@@ -40,6 +40,22 @@ bool IsLittleEndian() noexcept;
  */
 std::string LocalTimeDate() noexcept;
 
-} // end namespace adios
+/**
+ * Support for language bindings, identify if data is row-major (C, C++) or not
+ * (Fortran, R)
+ * @param hostLanguage input host language
+ * @return true: row-major, false: column-major
+ */
+bool IsRowMajor(const std::string hostLanguage) noexcept;
+
+/**
+ * Support for language bindings, identify if data is zero-indexed (C, C++) or
+ * not (Fortran, R)
+ * @param hostLanguage input host language
+ * @return true: zero-indexed, false: one-indexed
+ */
+bool IsZeroIndexed(const std::string hostLanguage) noexcept;
+
+} // end namespace adios2
 
 #endif /* ADIOS2_HELPER_ADIOSSYSTEM_H_ */
diff --git a/source/adios2/toolkit/format/bp3/BP3Base.h b/source/adios2/toolkit/format/bp3/BP3Base.h
index 6f10ebdc7124afc67f17e6a48dfe4e6b13e47507..a5d5d0c72d91f81df53237432972b87cffc798b0 100644
--- a/source/adios2/toolkit/format/bp3/BP3Base.h
+++ b/source/adios2/toolkit/format/bp3/BP3Base.h
@@ -207,9 +207,9 @@ protected:
     unsigned int m_Threads = 1;
     const bool m_DebugMode = false;
 
-    /** from host language */
+    /** from host language in data information */
     bool m_IsRowMajor = true; // C, C++ defaults
-    /** from host language */
+    /** from host language in data information */
     bool m_IsZeroIndex = true; // C, C++
 
     /** method type for file I/O */
diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp b/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp
index 1bfa4de39606f8cdcdfea9aa6df98ab9e19364dc..701e425ed68e3248b30ae1bcafb554acd69a9c05 100644
--- a/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp
+++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.cpp
@@ -119,6 +119,7 @@ void BP3Deserializer::ParsePGIndex()
     m_MetadataSet.DataPGCount = ReadValue<uint64_t>(buffer, position);
     const uint64_t pgLength =
         ReadValue<uint64_t>(buffer, position); // not required
+    // TODO: here check for host language in first pg index
 }
 
 void BP3Deserializer::ParseVariablesIndex(IO &io)
diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.h b/source/adios2/toolkit/format/bp3/BP3Deserializer.h
index 4bf14e3f5b692ffc6ab99cf869059d9858b2ed9b..01f829dcbd53d30a875d831b988f9ecff5a8c50f 100644
--- a/source/adios2/toolkit/format/bp3/BP3Deserializer.h
+++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.h
@@ -70,8 +70,8 @@ private:
     void ParseAttributesIndex(IO &io);
 
     /**
-     * This function reads a variable index element (serialized) and calls IO
-     * DefineVariable to deserialize the data
+     * Reads a variable index element (serialized) and calls IO.DefineVariable
+     * to deserialize the Variable metadata
      * @param header serialize
      * @param io
      * @param buffer
@@ -91,10 +91,29 @@ private:
                                     const Box<Dims> &blockBox,
                                     const Box<Dims> &intersectionBox) const;
 
+    /**
+     * Row-major, zero-indexed data e.g. : C, C++
+     * @param variable
+     * @param contiguousMemory
+     * @param blockBox
+     * @param intersectionBox
+     */
     template <class T>
     void ClipContiguousMemoryCommonRowZero(
         Variable<T> &variable, const std::vector<char> &contiguousMemory,
         const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const;
+
+    /**
+     * Column-major, one indexed data e.g. : Fortran, R
+     * @param variable
+     * @param contiguousMemory
+     * @param blockBox
+     * @param intersectionBox
+     */
+    template <class T>
+    void ClipContiguousMemoryCommonColumnOne(
+        Variable<T> &variable, const std::vector<char> &contiguousMemory,
+        const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const;
 };
 
 #define declare_template_instantiation(T)                                      \
diff --git a/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc b/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc
index c0c0933815e9ee7d1875916eaccbba11064b601a..8e90253eef67ff1ceaae5495ca08caf74dd0aa9b 100644
--- a/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc
+++ b/source/adios2/toolkit/format/bp3/BP3Deserializer.tcc
@@ -217,11 +217,16 @@ void BP3Deserializer::ClipContiguousMemoryCommon(
         return;
     }
 
-    if (m_IsRowMajor && m_IsZeroIndex)
+    if (m_IsRowMajor && m_IsZeroIndex) // C, C++, Python
     {
         ClipContiguousMemoryCommonRowZero(variable, contiguousMemory, blockBox,
                                           intersectionBox);
     }
+    else if (!m_IsRowMajor && !m_IsZeroIndex) // Fortran, R
+    {
+        ClipContiguousMemoryCommonColumnOne(variable, contiguousMemory,
+                                            blockBox, intersectionBox);
+    }
 }
 
 template <class T>
@@ -288,6 +293,70 @@ void BP3Deserializer::ClipContiguousMemoryCommonRowZero(
     }     // run
 }
 
+template <class T>
+void BP3Deserializer::ClipContiguousMemoryCommonColumnOne(
+    Variable<T> &variable, const std::vector<char> &contiguousMemory,
+    const Box<Dims> &blockBox, const Box<Dims> &intersectionBox) const
+{
+    const Dims &start = intersectionBox.first;
+    const Dims &end = intersectionBox.second;
+    const size_t stride = (end.front() - start.front() + 1) * sizeof(T);
+
+    Dims currentPoint(start); // current point for memory copy
+
+    const Box<Dims> selectionBox =
+        StartEndBox(variable.m_Start, variable.m_Count);
+
+    const size_t dimensions = start.size();
+    bool run = true;
+
+    const size_t intersectionStart =
+        LinearIndex(blockBox, intersectionBox.first, false, false) * sizeof(T);
+
+    while (run)
+    {
+        // here copy current linear memory between currentPoint and end
+        const size_t contiguousStart =
+            LinearIndex(blockBox, currentPoint, false, false) * sizeof(T) -
+            intersectionStart;
+
+        const size_t variableStart =
+            LinearIndex(selectionBox, currentPoint, false, false) * sizeof(T);
+
+        char *rawVariableData = reinterpret_cast<char *>(variable.GetData());
+
+        std::copy(&contiguousMemory[contiguousStart],
+                  &contiguousMemory[contiguousStart + stride],
+                  &rawVariableData[variableStart]);
+
+        // here update each index recursively, always starting from the 2nd
+        // fastest changing index, since fastest changing index is the
+        // continuous part in the previous std::copy
+        size_t p = 1;
+        while (true)
+        {
+            ++currentPoint[p];
+            if (currentPoint[p] > end[p]) // TODO: check end condition
+            {
+                if (p == dimensions - 1)
+                {
+                    run = false; // we are done
+                    break;
+                }
+                else
+                {
+                    currentPoint[p] = start[p];
+                    ++p;
+                }
+            }
+            else
+            {
+                break; // break inner p loop
+            }
+        } // dimension index update
+    }
+}
+
 } // end namespace format
 } // end namespace adios2