diff --git a/CMake/CTestCustom.cmake.in b/CMake/CTestCustom.cmake.in
index a9d61cb9ff222df34bf5a2db728cd0e6402b42a7..1d3f118028b108d8669887eb8f51bba4297dd016 100644
--- a/CMake/CTestCustom.cmake.in
+++ b/CMake/CTestCustom.cmake.in
@@ -63,5 +63,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
   # Ignore clang's summary warning, assuming prior text has matched some
   # other warning expression:
   "[0-9,]+ warnings? generated."
-
+  ".*include.opencv2.*warning.*"
+  ".*warning:.*deprecated.*"
+  ".*vcl_deprecated_header.*"
   )
diff --git a/CMake/FindNumpy.cmake b/CMake/FindNumpy.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..764f57497c1dfbf43dda09118bc8e538fb513047
--- /dev/null
+++ b/CMake/FindNumpy.cmake
@@ -0,0 +1,28 @@
+# - Find Numpy
+# Find the native numpy includes
+#
+#   NUMPY_FOUND        - True if Numpy headers are found.
+#   NUMPY_INCLUDE_DIR   - where to find numpy/arrayobject.h, etc.
+
+EXEC_PROGRAM ("${PYTHON_EXECUTABLE}"
+  ARGS "-c 'import numpy; print numpy.get_include()'"
+  OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
+  RETURN_VALUE NUMPY_NOT_FOUND)
+
+if( NUMPY_INCLUDE_DIR MATCHES "Traceback" )
+# Did not successfully include numpy
+set( NUMPY_INCLUDE_DIR )
+else()
+  set( NUMPY_INCLUDE_DIR ${NUMPY_INCLUDE_DIR} CACHE STRING "Numpy include path." )
+endif()
+
+include( FindPackageHandleStandardArgs )
+FIND_PACKAGE_HANDLE_STANDARD_ARGS( Numpy DEFAULT_MSG NUMPY_INCLUDE_DIR )
+
+mark_as_advanced( NUMPY_INCLUDE_DIR )
+
+if(NUMPY_FOUND)
+  set(NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIR})
+else()
+  set(NUMPY_INCLUDE_DIRS)
+endif()
diff --git a/Examples/Projections/test/CMakeLists.txt b/Examples/Projections/test/CMakeLists.txt
index fad74a593fa3d4bde04cde96b541e4be13827c86..7964d8655050eabe8f3b030ed237203666fa915a 100644
--- a/Examples/Projections/test/CMakeLists.txt
+++ b/Examples/Projections/test/CMakeLists.txt
@@ -68,7 +68,7 @@ otb_add_test(NAME prTeEstimateRPCSensorModelExampleTest COMMAND ${OTB_TEST_DRIVE
   --compare-ascii ${EPSILON_4}
     ${BASELINE}/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt
     ${TEMP}/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt
-  --ignore-lines-with 5 PipelineMTime ImportImageContaine Source: Image Time:
+  --ignore-lines-with 6 PipelineMTime ImportImageContaine Source: Image Time: Pointer:
   Execute $<TARGET_FILE:EstimateRPCSensorModelExample>
     LARGEINPUT{SPOT4/RIO_DE_JANEIRO/IMAG_01.DAT}
     ${TEMP}/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt
diff --git a/Modules/Applications/AppSARDecompositions/CMakeLists.txt b/Modules/Applications/AppSARDecompositions/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..aa7832f8f44840a95e5ac6bfdbcddee53ade5a7c
--- /dev/null
+++ b/Modules/Applications/AppSARDecompositions/CMakeLists.txt
@@ -0,0 +1,2 @@
+project(OTBAppSARDecompositions)
+otb_module_impl()
diff --git a/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt b/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d311a3c7e5755cf7de35c79e054dd6c0164c5316
--- /dev/null
+++ b/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(OTBAppFiltering_LINK_LIBS
+  ${OTBPolarimetry_LIBRARIES}
+  ${OTBImageManipulation_LIBRARIES}
+  ${OTBApplicationEngine_LIBRARIES}
+  ${OTBImageBase_LIBRARIES}
+)
+
+otb_create_application(
+  NAME           SARDecompositions
+  SOURCES        otbSARDecompositions.cxx
+  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a159356f4a076b53fb2923877b050aab9ff11276
--- /dev/null
+++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
@@ -0,0 +1,189 @@
+/*=========================================================================
+
+ Program:   ORFEO Toolbox
+ Language:  C++
+ Date:      $Date$
+ Version:   $Revision$
+
+
+ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+ See OTBCopyright.txt for details.
+
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notices for more information.
+
+ =========================================================================*/
+#include "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+
+#include "otbReciprocalHAlphaImageFilter.h"
+#include "otbSinclairReciprocalImageFilter.h"
+#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
+#include "otbPerBandVectorImageFilter.h"
+#include "itkMeanImageFilter.h"
+
+
+namespace otb
+{
+namespace Wrapper
+{
+
+class SARDecompositions : public Application
+{
+public:
+  /** Standard class typedefs. */
+  typedef SARDecompositions                   Self;
+  typedef Application                         Superclass;
+  typedef itk::SmartPointer<Self>             Pointer;
+  typedef itk::SmartPointer<const Self>       ConstPointer;
+
+  
+  
+  typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								FunctorType;
+                                    
+                                    								
+  typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 FunctorType > 												SRFilterType;
+  
+  
+  typedef otb::ReciprocalHAlphaImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType> 			HAFilterType;
+  
+  
+  typedef itk::MeanImageFilter<ComplexDoubleImageType, ComplexDoubleImageType>         MeanFilterType;
+  typedef otb::PerBandVectorImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType, MeanFilterType> PerBandMeanFilterType;
+  //FloatImageType
+
+  /** Standard macro */
+  itkNewMacro(Self);
+
+  itkTypeMacro(SARDecompositions, otb::Application);
+
+private:
+  void DoInit()
+  {
+    SetName("SARDecompositions");
+    SetDescription("From one-band complex images (each one related to an element of the Sinclair matrix), returns the selected decomposition.");
+
+    // Documentation
+    SetDocName("SARDecompositions");
+    SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
+						  "The H-alpha-A decomposition is currently the only one available; it is implemented for the monostatic case (transmitter and receiver are co-located).\n"
+						  "User must provide three one-band complex images HH, HV or VH, and VV (monostatic case <=> HV = VH).\n"
+						  "The H-alpha-A decomposition consists in averaging 3x3 complex coherency matrices (incoherent analysis); the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize.\n "
+						  "The applications returns a float vector image, made up of three channels : H (entropy), Alpha, A (Anisotropy)." );
+						  
+						  
+						  
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso("SARPolarMatrixConvert, SARPolarSynth");
+
+    AddDocTag(Tags::SAR);
+
+    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input Image");
+    SetParameterDescription("inhh", "Input image (HH)");
+    
+    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input Image");
+    SetParameterDescription("inhv", "Input image (HV)");
+    MandatoryOff("inhv");
+    
+    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input Image");
+    SetParameterDescription("invh", "Input image (VH)");
+    MandatoryOff("invh");
+    
+    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input Image");
+    SetParameterDescription("invv", "Input image (VV)");
+    
+    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
+    SetParameterDescription("out", "Output image");
+    
+    AddParameter(ParameterType_Choice, "decomp", "Decompositions");
+    AddChoice("decomp.haa","H-alpha-A decomposition");
+    SetParameterDescription("decomp.haa","H-alpha-A decomposition");
+    
+    AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
+    SetParameterDescription("inco","This group allows to set parameters related to the incoherent decompositions.");
+    
+    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging.");
+    SetParameterDescription("inco.kernelsize", "Minute (0-59)");
+    SetMinimumParameterIntValue("inco.kernelsize", 1);
+    SetDefaultParameterInt("inco.kernelsize", 3);
+    MandatoryOff("inco.kernelsize");
+
+    AddRAMParameter();
+
+    // Default values
+    SetDefaultParameterInt("decomp", 0); // H-alpha-A
+
+    // Doc example parameter settings
+    SetDocExampleParameterValue("inhh", "HH.tif");
+	SetDocExampleParameterValue("invh", "VH.tif");
+	SetDocExampleParameterValue("invv", "VV.tif");
+	SetDocExampleParameterValue("decomp", "haa");
+    SetDocExampleParameterValue("out", "HaA.tif");
+  }
+
+  void DoUpdateParameters()
+  {
+    // Nothing to do here : all parameters are independent
+  }
+
+  void DoExecute()
+  {
+	  
+	bool inhv = HasUserValue("inhv");
+	bool invh = HasUserValue("invh");
+		
+	if ( (!inhv) && (!invh) )
+	  otbAppLogFATAL( << "Parameter inhv or invh not set. Please provide a HV or a VH complex image.");
+    
+    switch (GetParameterInt("decomp"))
+      {
+		case 0: // H-alpha-A
+		
+		m_SRFilter = SRFilterType::New();
+		m_HAFilter = HAFilterType::New();
+		m_MeanFilter = PerBandMeanFilterType::New();
+		
+		if (inhv)
+		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+	    else if (invh)
+		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+
+		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		MeanFilterType::InputSizeType radius;
+        radius.Fill( GetParameterInt("inco.kernelsize") );
+        m_MeanFilter->GetFilter()->SetRadius(radius);
+		
+		
+		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
+		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
+		SetParameterOutputImage("out", m_HAFilter->GetOutput() );
+    
+		break;
+	  }
+   	 
+  }
+
+  //MCPSFilterType::Pointer m_MCPSFilter;
+  SRFilterType::Pointer m_SRFilter;
+  HAFilterType::Pointer m_HAFilter;
+  PerBandMeanFilterType::Pointer m_MeanFilter;
+  
+}; 
+
+} //end namespace Wrapper
+} //end namespace otb
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::SARDecompositions)
diff --git a/Modules/Applications/AppSARDecompositions/otb-module.cmake b/Modules/Applications/AppSARDecompositions/otb-module.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..71303c803d5d707c9918ec8b578e89a204cc53b6
--- /dev/null
+++ b/Modules/Applications/AppSARDecompositions/otb-module.cmake
@@ -0,0 +1,17 @@
+set(DOCUMENTATION "Basic filters application.")
+
+otb_module(OTBAppSARDecompositions
+  DEPENDS
+    OTBPolarimetry
+    OTBImageManipulation
+    OTBITK
+    OTBApplicationEngine
+    OTBImageBase
+
+  TEST_DEPENDS
+    OTBTestKernel
+    OTBCommandLine
+
+  DESCRIPTION
+    "${DOCUMENTATION}"
+)
diff --git a/Modules/Applications/AppSARDecompositions/test/CMakeLists.txt b/Modules/Applications/AppSARDecompositions/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b99fa48fe8d6b2fea3afa6ab5a63b21228496094
--- /dev/null
+++ b/Modules/Applications/AppSARDecompositions/test/CMakeLists.txt
@@ -0,0 +1,14 @@
+otb_module_test()
+#----------- SARDecompositions TESTS ----------------
+
+otb_test_application(NAME  apTvSARDecompositions
+                     APP  SARDecompositions
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -decomp haa
+							 -out ${TEMP}/apTvReciprocalHAlpha.tif
+							 
+                     )
+                             
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/CMakeLists.txt b/Modules/Applications/AppSARPolarMatrixConvert/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b20d3ebc6c81733b0ce1f5738dca23a6ff522139
--- /dev/null
+++ b/Modules/Applications/AppSARPolarMatrixConvert/CMakeLists.txt
@@ -0,0 +1,2 @@
+project(OTBAppSARPolarMatrixConvert)
+otb_module_impl()
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt b/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..81426caca5d49ecef97df614ebc0214cd79bd008
--- /dev/null
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(OTBAppFiltering_LINK_LIBS
+  ${OTBPolarimetry_LIBRARIES}
+  ${OTBImageManipulation_LIBRARIES}
+  ${OTBApplicationEngine_LIBRARIES}
+  ${OTBImageBase_LIBRARIES}
+)
+
+otb_create_application(
+  NAME           SARPolarMatrixConvert
+  SOURCES        otbSARPolarMatrixConvert.cxx
+  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c670aabb0e2c2273daf5749368cd419142079b81
--- /dev/null
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -0,0 +1,709 @@
+/*=========================================================================
+
+ Program:   ORFEO Toolbox
+ Language:  C++
+ Date:      $Date$
+ Version:   $Revision$
+
+
+ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+ See OTBCopyright.txt for details.
+
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notices for more information.
+
+ =========================================================================*/
+#include "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+
+
+
+
+//monostatic case
+#include "otbSinclairReciprocalImageFilter.h"
+#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
+#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
+#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
+
+#include "otbReciprocalCoherencyToReciprocalMuellerImageFilter.h"
+#include "otbReciprocalCovarianceToCoherencyDegreeImageFilter.h"
+#include "otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h"
+#include "otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h"
+
+
+//bistatic case
+#include "otbSinclairImageFilter.h"
+#include "otbSinclairToCoherencyMatrixFunctor.h"
+#include "otbSinclairToCovarianceMatrixFunctor.h"
+#include "otbSinclairToCircularCovarianceMatrixFunctor.h"
+#include "otbSinclairToMuellerMatrixFunctor.h"
+
+#include "otbMuellerToReciprocalCovarianceImageFilter.h"
+#include "otbMuellerToPolarisationDegreeAndPowerImageFilter.h"
+
+
+
+
+
+
+namespace otb
+{
+namespace Wrapper
+{
+
+class SARPolarMatrixConvert : public Application
+{
+public:
+  /** Standard class typedefs. */
+  typedef SARPolarMatrixConvert                   Self;
+  typedef Application                         Superclass;
+  typedef itk::SmartPointer<Self>             Pointer;
+  typedef itk::SmartPointer<const Self>       ConstPointer;
+
+  
+  //Monostatic case
+    typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								RCoherencyFunctorType;
+                                    
+    typedef otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								RCovarianceFunctorType;
+                                    
+    typedef otb::Functor::SinclairToReciprocalCircularCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								RCircularCovarianceFunctorType;
+                                                                  
+                                    								
+    typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 RCoherencyFunctorType > 									RCohSRFilterType;
+											 
+											 
+    typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 RCovarianceFunctorType > 									RCovSRFilterType;
+											 
+	typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 RCircularCovarianceFunctorType > 							RCCSRFilterType;
+											 
+											 
+    typedef otb::ReciprocalCoherencyToReciprocalMuellerImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType> RCRMFilterType;
+	
+	typedef otb::ReciprocalCovarianceToCoherencyDegreeImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RCCDFilterType;
+	
+	typedef otb::ReciprocalCovarianceToReciprocalCoherencyImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RCRCFilterType;
+	
+	typedef otb::ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RLCRCCFilterType;
+											 
+  
+	//Bistatic case
+	typedef otb::Functor::SinclairToCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								CoherencyFunctorType;
+                                    
+                                    
+	typedef otb::Functor::SinclairToCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								CovarianceFunctorType;
+                                    
+                                   
+	typedef otb::Functor::SinclairToCircularCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleVectorImageType::PixelType>								CircularCovarianceFunctorType;
+                                    
+                                    	
+    typedef otb::Functor::SinclairToMuellerMatrixFunctor<ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    ComplexDoubleImageType::PixelType,
+                                    DoubleVectorImageType::PixelType>									MuellerFunctorType;
+                                    
+    
+    typedef SinclairImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType,
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 CoherencyFunctorType > 									CohSRFilterType;
+											 
+											 
+    typedef SinclairImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType,
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 CovarianceFunctorType > 									CovSRFilterType;
+											 
+	typedef SinclairImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType,
+											 ComplexDoubleImageType, 
+											 ComplexDoubleVectorImageType, 
+											 CircularCovarianceFunctorType > 							CCSRFilterType;
+                                    
+	typedef SinclairImageFilter<ComplexDoubleImageType, 
+											 ComplexDoubleImageType, 
+											 ComplexDoubleImageType,
+											 ComplexDoubleImageType, 
+											 DoubleVectorImageType, 
+											 MuellerFunctorType > 										MSRFilterType;
+											 
+											 
+	typedef otb::MuellerToReciprocalCovarianceImageFilter<DoubleVectorImageType, ComplexDoubleVectorImageType>  MRCFilterType;									 
+	
+	typedef otb::MuellerToPolarisationDegreeAndPowerImageFilter<DoubleVectorImageType, DoubleVectorImageType>   MPDPFilterType;
+  
+  
+
+  /** Standard macro */
+  itkNewMacro(Self);
+
+  itkTypeMacro(SARPolarMatrixConvert, otb::Application);
+
+private:
+  void DoInit()
+  {
+    SetName("SARPolarMatrixConvert");
+    SetDescription("This applications allows converting classical polarimetric matrices to each other.");
+
+    // Documentation
+    SetDocName("SARPolarMatrixConvert");
+    SetDocLongDescription(
+    
+    "This application allows converting classical polarimetric matrices to each other.\n"
+    "For instance, it is possible to get the coherency matrix from the Sinclar one, or the Mueller matrix from the coherency one.\n"
+    "The filters used in this application never handle matrices, but images where each band is related to their elements.\n"
+    "As most of the time SAR polarimetry handles symetric/hermitian matrices, only the relevant elements are stored, so that the images representing them have a minimal number of bands.\n"
+    "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case : it will thus be stored in a 6-band or a 10-band complex image (the diagonal and the upper elements of the matrix).\n"
+    "\n"
+    "The Sinclair matrix is a special case : it is always represented as 3 or 4 one-band complex images (for mono- or bistatic case).\n"
+    "The available conversions are listed below:\n"
+    
+	"\n--- Monostatic case ---\n" 
+    
+    "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
+    "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
+    "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
+    "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input : 6 complex channels | 16 real channels)\n"
+    "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input : 6 complex channels | 3 complex channels)\n"
+    "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input : 6 complex channels | 6 complex channels)\n"
+    "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input : 6 complex channels | output : 6 complex channels)\n"
+    
+    "\n--- Bistatic case ---\n"
+    
+    "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
+    "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 10 complex channels)\n"
+    "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 10 complex channels)\n"
+    
+    "\n--- Both cases ---\n"
+    
+    "11 sinclairtomueller --> Sinclair matrix to Mueller matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 16 real channels)\n"
+    "12 muellertomcovariance --> Mueller matrix to covariance matrix (input : 16 real channels | output : 6 complex channels)\n"
+    "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input : 16 real channels | output : 4 real channels)\n"
+
+ );
+						  
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso("SARPolarSynth, SARDecompositions");
+
+    AddDocTag(Tags::SAR);
+
+    AddParameter(ParameterType_ComplexInputImage,  "inc",   "Input : multi-band complex image");
+    SetParameterDescription("inc", "Input : multi-band complex image");
+    MandatoryOff("inc");
+    
+    AddParameter(ParameterType_InputImage,  "inf",   "Input : multi-band real image");
+    SetParameterDescription("inf", "Input : multi-band real image");
+    MandatoryOff("inf");
+
+
+    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input : one-band complex image (HH)");
+    SetParameterDescription("inhh", "Input : one-band complex image (HH)");
+    MandatoryOff("inhh");
+    
+    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input : one-band complex image (HV)");
+    SetParameterDescription("inhv", "Input : one-band complex image (HV)");
+    MandatoryOff("inhv");
+    
+    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input : one-band complex image (VH)");
+    SetParameterDescription("invh", "Input : one-band complex image (VH)");
+    MandatoryOff("invh");
+    
+    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input : one-band complex image (VV)");
+    SetParameterDescription("invv", "Input : one-band complex image (VV)");
+    MandatoryOff("invv");
+    
+    AddParameter(ParameterType_ComplexOutputImage, "outc",  "Output Complex Image");
+    SetParameterDescription("outc", "Output Complex image.");
+    MandatoryOff("outc");
+    
+    AddParameter(ParameterType_OutputImage, "outf",  "Output Real Image");
+    SetParameterDescription("outf", "Output Real image.");
+    MandatoryOff("outf");
+    
+    
+    
+    AddParameter(ParameterType_Choice, "conv", "Convertion");
+
+    //Monostatic case 
+    
+    // #1
+    // SinclairToReciprocalCoherency
+    AddChoice("conv.msinclairtocoherency","1 Monostatic : Sinclair matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocoherency","1 Monostatic :Sinclair matrix to coherency matrix (complex output)");
+    
+    // #2
+    // SinclairToReciprocalCovariance
+    AddChoice("conv.msinclairtocovariance","2 Monostatic : Sinclair matrix to covariance matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocovariance","2 Monostatic : Sinclair matrix to covariance matrix (complex output)");
+    
+    // #3 
+    // SinclairToReciprocalCircularCovariance
+    AddChoice("conv.msinclairtocircovariance","3 Monostatic : Sinclair matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocircovariance","3 Monostatic : Sinclair matrix to circular covariance matrix (complex output)");
+    
+    // #4 
+    // ReciprocalCoherencyToReciprocalMuellerImageFilter
+    AddChoice("conv.mcoherencytomueller","4 Monostatic : Coherency matrix to Mueller matrix"); 
+    SetParameterDescription("conv.mcoherencytomueller","4 Monostatic : Coherency matrix to Mueller matrix"); 
+    
+    // #5
+    // ReciprocalCovarianceToCoherencyDegreeImageFilter 
+    AddChoice("conv.mcovariancetocoherencydegree","5 Monostatic : Covariance matrix to coherency degree "); 
+    SetParameterDescription("conv.mcovariancetocoherencydegree","5 Monostatic : Covariance matrix to coherency degree "); 
+    
+    // #6
+    // ReciprocalCovarianceToReciprocalCoherencyImageFilter
+    AddChoice("conv.mcovariancetocoherency","6 Monostatic : Covariance matrix to coherency matrix (complex output)"); 
+    SetParameterDescription("conv.mcovariancetocoherency","6 Monostatic : Covariance matrix to coherency matrix (complex output)");  
+    
+    // #7
+    // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
+    AddChoice("conv.mlinearcovariancetocircularcovariance","7 Monostatic : Covariance matrix to circular covariance matrix (complex output)"); 
+    SetParameterDescription("conv.mlinearcovariancetocircularcovariance","7 Monostatic : Covariance matrix to circular covariance matrix (complex output)");  
+    
+    // #8
+    // MuellerToReciprocalCovarianceImageFilter 
+    AddChoice("conv.muellertomcovariance","8 Bi/mono : Mueller matrix to monostatic covariance matrix");
+    SetParameterDescription("conv.muellertomcovariance","8 Bi/mono : Mueller matrix to monostatic covariance matrix");
+    
+    //Bistatic case
+    
+    // #9
+    // SinclairToCoherency
+    AddChoice("conv.bsinclairtocoherency","9 Bistatic : Sinclair matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocoherency","9 Bistatic : Sinclair matrix to coherency matrix (complex output)");
+    
+    // #10
+    // SinclairToCovariance  
+    AddChoice("conv.bsinclairtocovariance","10 Bistatic : Sinclair matrix to covariance matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocovariance","10 Bistatic : Sinclair matrix to covariance matrix (complex output)");
+    
+    // #11
+    // SinclairToCircularCovariance 
+    AddChoice("conv.bsinclairtocircovariance","11 Bistatic : Sinclair matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocircovariance","11 Bistatic : Sinclair matrix to circular covariance matrix (complex output)");
+    
+    //Both case
+    
+    // #12
+    // SinclairToMueller
+    AddChoice("conv.sinclairtomueller","12 Bi/mono : Sinclair matrix to Mueller matrix");
+    SetParameterDescription("conv.sinclairtomueller","12 Bi/mono : Sinclair matrix to Mueller matrix");
+    
+    
+    // #13
+    // MuellerToPolarisationDegreeAndPowerImageFilter
+    AddChoice("conv.muellertopoldegandpower","13 Bi/mono : Mueller matrix to polarisation degree and power");
+    SetParameterDescription("conv.muellertopoldegandpower","13 Bi/mono : Mueller matrix to polarisation degree and power");
+
+    AddRAMParameter();
+
+    // Default values
+    SetDefaultParameterInt("conv", 0); // SinclairToReciprocalCoherency
+
+    // Doc example parameter settings
+    SetDocExampleParameterValue("inhh", "HH.tif");
+	SetDocExampleParameterValue("invh", "VH.tif");
+	SetDocExampleParameterValue("invv", "VV.tif");
+	SetDocExampleParameterValue("conv", "msinclairtocoherency"); 
+    SetDocExampleParameterValue("outc", "mcoherency.tif");
+  }
+
+  void DoUpdateParameters()
+  {
+    
+    int convType = GetParameterInt("conv");
+    
+    if ( (convType>=0) && (convType<=2)) //msinclairtocoherency msinclairtocovariance msinclairtocircovariance
+	{
+	    GetParameterByKey("inc")->SetActive(false);
+	    GetParameterByKey("inf")->SetActive(false); 
+	    GetParameterByKey("inhh")->SetActive(true);
+	    GetParameterByKey("inhv")->SetActive(true); 
+	    GetParameterByKey("invh")->SetActive(true);
+	    GetParameterByKey("invv")->SetActive(true); 
+	    GetParameterByKey("outc")->SetActive(true);
+	    GetParameterByKey("outf")->SetActive(false);
+	}
+	else if ( (convType>=3) && (convType<=6)) // mcoherencytomueller mcovariancetocoherencydegree mcovariancetocoherency mlinearcovariancetocircularcovariance
+	{  
+	    GetParameterByKey("inc")->SetActive(true);
+	    GetParameterByKey("inf")->SetActive(false); 
+	    GetParameterByKey("inhh")->SetActive(false);
+	    GetParameterByKey("inhv")->SetActive(false); 
+	    GetParameterByKey("invh")->SetActive(false);
+	    GetParameterByKey("invv")->SetActive(false); 
+	    
+	    if (convType == 3)
+	    {
+			GetParameterByKey("outc")->SetActive(false);
+			GetParameterByKey("outf")->SetActive(true);
+		}
+		else
+		{
+			GetParameterByKey("outc")->SetActive(true);
+			GetParameterByKey("outf")->SetActive(false);
+		}
+	}
+	else if ( convType==7) // muellertomcovariance
+	{
+		GetParameterByKey("inc")->SetActive(false);
+	    GetParameterByKey("inf")->SetActive(true); 
+	    GetParameterByKey("inhh")->SetActive(false);
+	    GetParameterByKey("inhv")->SetActive(false); 
+	    GetParameterByKey("invh")->SetActive(false);
+	    GetParameterByKey("invv")->SetActive(false); 
+	    GetParameterByKey("outc")->SetActive(true);
+		GetParameterByKey("outf")->SetActive(false);	
+	}
+	else if ( (convType>=8) && (convType<=11)) // bsinclairtocoherency bsinclairtocovariance bsinclairtocircovariance sinclairtomueller
+	{
+	    GetParameterByKey("inc")->SetActive(false);
+	    GetParameterByKey("inf")->SetActive(false); 
+	    GetParameterByKey("inhh")->SetActive(true);
+	    GetParameterByKey("inhv")->SetActive(true); 
+	    GetParameterByKey("invh")->SetActive(true);
+	    GetParameterByKey("invv")->SetActive(true); 
+	    	    
+	    if (convType == 11)
+	    {
+			GetParameterByKey("outc")->SetActive(false);
+			GetParameterByKey("outf")->SetActive(true);
+		}
+		else
+		{
+			GetParameterByKey("outc")->SetActive(true);
+			GetParameterByKey("outf")->SetActive(false);
+		}
+	    
+	}
+	else if ( convType==12 )  // muellertopoldegandpower
+	{
+	    GetParameterByKey("inc")->SetActive(false);
+	    GetParameterByKey("inf")->SetActive(true); 
+	    GetParameterByKey("inhh")->SetActive(false);
+	    GetParameterByKey("inhv")->SetActive(false); 
+	    GetParameterByKey("invh")->SetActive(false);
+	    GetParameterByKey("invv")->SetActive(false); 
+	    GetParameterByKey("outc")->SetActive(false);
+		GetParameterByKey("outf")->SetActive(true);	    
+	}
+	
+    
+    
+  }
+
+  void DoExecute()
+  {
+
+    //****************************************
+	//* Check inputs and outputs consistency *
+	//****************************************
+	
+    bool inc = HasUserValue("inc");
+    bool inf = HasUserValue("inf");
+	bool inhh = HasUserValue("inhh");
+	bool inhv = HasUserValue("inhv");
+	bool invh = HasUserValue("invh");
+	bool invv = HasUserValue("invv");
+	bool outc = HasUserValue("outc"); 
+	bool outf = HasUserValue("outf"); 
+	
+	int convType = GetParameterInt("conv");
+	
+	
+	if ( (!outc) && (!outf) )
+	        otbAppLogFATAL( << "No output image provided; please, set the parameter 'outc' or 'outf'.");
+
+	
+	if ( (convType>=0) && (convType<=2)) //msinclairtocoherency msinclairtocovariance msinclairtocircovariance
+	{
+		if ( (!inhv) && (!invh) )
+	        otbAppLogFATAL( << "Parameter 'inhv' or 'invh' not set.");
+	    if ( !inhh )
+	        otbAppLogFATAL( << "Parameter 'inhh' not set.");
+	    if ( !invv )
+	        otbAppLogFATAL( << "Parameter 'invv' not set.");
+	        
+	}
+	
+	else if ( (convType>=3) && (convType<=6)) // mcoherencytomueller mcovariancetocoherencydegree mcovariancetocoherency mlinearcovariancetocircularcovariance
+	{
+		if ( !inc )
+	        otbAppLogFATAL( << "Parameter 'inc' not set.");
+	}
+	else if ( (convType>=8) && (convType<=11)) // bsinclairtocoherency bsinclairtocovariance bsinclairtocircovariance sinclairtomueller
+	{
+	    if ( (!inhh) || (!inhv) || (!invh) || (!invv) )
+	        otbAppLogFATAL( << "Please, ensure that HH, HV, VH and VV complex images have been provided (paramaters inhh, inhv, invh, invv).");
+	}
+	else if ( (convType==7) || (convType==12) ) // muellertomcovariance muellertopoldegandpower
+	{
+		if ( !inf )
+	        otbAppLogFATAL( << "Parameter 'inf' not set.");
+	}
+
+		
+	switch (GetParameterInt("conv"))
+      {
+		  
+		//***************************************
+		//*             MONOSTATIC              *
+		//***************************************
+		
+		case 0: // SinclairToReciprocalCoherency
+	  	m_RCohSRFilter = RCohSRFilterType::New();
+	  	
+	    if (inhv)
+		  m_RCohSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+	    else if (invh)
+		  m_RCohSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+	  	
+		m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterComplexOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		
+		break;
+
+		
+		case 1: // SinclairToReciprocalCovariance	
+	
+		m_RCovSRFilter = RCovSRFilterType::New();
+		
+		if (inhv)
+		  m_RCovSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+	    else if (invh)
+		  m_RCovSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+		
+		m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterComplexOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		
+		break;
+		
+		
+		
+		case 2: // SinclairToReciprocalCircularCovariance
+		
+		m_RCCSRFilter = RCCSRFilterType::New();
+		
+		if (inhv)
+		  m_RCCSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+	    else if (invh)
+		  m_RCCSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+		
+		m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterComplexOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		
+		break;
+		
+		
+	    case 3: // ReciprocalCoherencyToReciprocalMuellerImageFilter
+		
+		m_RCRMFilter = RCRMFilterType::New();
+		m_RCRMFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
+		
+		SetParameterOutputImage("outf", m_RCRMFilter->GetOutput() ); // input : 6 complex channels | 16 real channels
+		
+		break;
+		
+	
+		
+		case 4: // ReciprocalCovarianceToCoherencyDegreeImageFilter
+		
+		m_RCCDFilter = RCCDFilterType::New();
+		m_RCCDFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
+		
+		SetParameterComplexOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels
+		
+		break;
+
+
+	    case 5: // ReciprocalCovarianceToReciprocalCoherencyImageFilter
+		
+		m_RCRCFilter = RCRCFilterType::New();
+		m_RCRCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
+		
+		SetParameterComplexOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels
+		
+		break;
+		
+	    
+
+	    case 6: // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
+		
+		m_RLCRCCFilter = RLCRCCFilterType::New();
+		m_RLCRCCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
+		
+		SetParameterComplexOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels
+		
+		break;
+		
+		
+		case 7: // MuellerToReciprocalCovarianceImageFilter
+		
+		m_MRCFilter = MRCFilterType::New();
+		
+		m_MRCFilter->SetInput(GetParameterDoubleVectorImage("inf"));
+		
+		SetParameterComplexOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels
+		
+		break;
+		
+		
+	    //***************************************
+		//*               BISTATIC              * 
+		//***************************************
+		
+	    case 8: // SinclairToCoherency
+			
+	  	m_CohSRFilter = CohSRFilterType::New();
+	  	
+		m_CohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_CohSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
+		m_CohSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
+		m_CohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterComplexOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels
+		
+		break;
+		
+			
+    
+		case 9: // SinclairToCovariance	
+		
+		m_CovSRFilter = CovSRFilterType::New();
+		
+		m_CovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_CovSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
+		m_CovSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
+		m_CovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterComplexOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		
+		break;
+		
+		
+		case 10: // SinclairToCircularCovariance
+		
+		m_CCSRFilter = CCSRFilterType::New();
+		
+		m_CCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_CCSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
+		m_CCSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
+		m_CCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterComplexOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		
+		break;
+		
+		
+		//***************************************
+		//*             BOTH CASES              * 
+		//***************************************
+		
+				
+		case 11: // SinclairToMueller
+		std::cout << "taloula 1" << std::endl;
+		m_MSRFilter = MSRFilterType::New();
+		
+		m_MSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
+		m_MSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
+		m_MSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
+		m_MSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		
+		SetParameterOutputImage("outf", m_MSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 16 real channels
+		
+		break;
+		
+		
+		case 12: // MuellerToPolarisationDegreeAndPowerImageFilter
+		m_MPDPFilter = MPDPFilterType::New();
+		
+		m_MPDPFilter->SetInput(GetParameterDoubleVectorImage("inf"));
+		
+		SetParameterOutputImage("outf", m_MPDPFilter->GetOutput() ); //  input : 16 real channels | output : 4 real channels
+		
+		break;
+		
+	  }
+	  
+
+    
+  }
+
+  //Monostatic
+  RCohSRFilterType::Pointer m_RCohSRFilter;
+  RCovSRFilterType::Pointer m_RCovSRFilter;
+  RCCSRFilterType::Pointer  m_RCCSRFilter;
+  RCRMFilterType::Pointer   m_RCRMFilter;
+  RCCDFilterType::Pointer   m_RCCDFilter;
+  RCRCFilterType::Pointer   m_RCRCFilter;
+  RLCRCCFilterType::Pointer m_RLCRCCFilter;
+  
+  //Bistatic
+  CohSRFilterType::Pointer m_CohSRFilter;
+  CovSRFilterType::Pointer m_CovSRFilter;
+  CCSRFilterType::Pointer  m_CCSRFilter;
+  MSRFilterType::Pointer   m_MSRFilter;
+  
+  //Both cases
+  MRCFilterType::Pointer   m_MRCFilter;
+  MPDPFilterType::Pointer  m_MPDPFilter;
+  
+
+
+
+  
+}; 
+
+} //end namespace Wrapper
+} //end namespace otb
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::SARPolarMatrixConvert)
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/otb-module.cmake b/Modules/Applications/AppSARPolarMatrixConvert/otb-module.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..759161f8b45b6a0e22916b9838c78f29c36b75ba
--- /dev/null
+++ b/Modules/Applications/AppSARPolarMatrixConvert/otb-module.cmake
@@ -0,0 +1,17 @@
+set(DOCUMENTATION "Basic filters application.")
+
+otb_module(OTBAppSARPolarMatrixConvert
+  DEPENDS
+    OTBPolarimetry
+    OTBImageManipulation
+    OTBITK
+    OTBApplicationEngine
+    OTBImageBase
+
+  TEST_DEPENDS
+    OTBTestKernel
+    OTBCommandLine
+
+  DESCRIPTION
+    "${DOCUMENTATION}"
+)
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/test/CMakeLists.txt b/Modules/Applications/AppSARPolarMatrixConvert/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a7c518f53999ce2c19ca2c74db8ce4eea95d486b
--- /dev/null
+++ b/Modules/Applications/AppSARPolarMatrixConvert/test/CMakeLists.txt
@@ -0,0 +1,157 @@
+otb_module_test()
+#----------- SARPolarMatrixConvert TESTS ----------------
+
+#1
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecCoherency
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv msinclairtocoherency 
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertRecCoherency.tif
+							 
+                     )
+            
+#2                            
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecCovariance
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv msinclairtocovariance 
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertRecCovariance.tif
+							 
+                     )
+
+#3
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecCirCovariance
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv msinclairtocircovariance 
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertRecCirCovariance.tif
+							 
+                     )
+
+#4
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecCohToMueller
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inc ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
+							 -conv mcoherencytomueller
+							 -outf ${TEMP}/apTvSARPolarMatrixConvertRecCohToMueller.tif
+							 
+                     )
+                             
+                             
+#5
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecCovToCohDeg
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inc ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
+							 -conv mcovariancetocoherencydegree
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertRecCovToCohDeg.tif
+							 
+                     )
+                             
+
+#6 
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecCovToRecCoh
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inc ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
+							 -conv mcovariancetocoherency
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertRecCovToRecCoh.tif
+							 
+                     )
+
+#7 
+otb_test_application(NAME  apTvSARPolarMatrixConvertRecLinCovToRecCirCov
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inc ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
+							 -conv mlinearcovariancetocircularcovariance
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertRecCovToRecCoh.tif
+							 
+                     )
+                             
+                             
+#8 
+otb_test_application(NAME  apTvSARPolarMatrixConvertMuellerToRecCov
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inf ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif
+							 -conv muellertomcovariance
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertMuellerToRecCov.tif
+							 
+                     )
+
+
+#9
+otb_test_application(NAME  apTvSARPolarMatrixConvertBiSincToCoherency
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invh ${INPUTDATA}/RSAT_imageryC_VH.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv bsinclairtocoherency
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertBiSincToCoherency.tif
+							 
+                     )
+                             
+                             
+#10
+otb_test_application(NAME  apTvSARPolarMatrixConvertBiSincToCovariance
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invh ${INPUTDATA}/RSAT_imageryC_VH.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv bsinclairtocovariance
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertBiSincToCovariance.tif
+							 
+                     )
+                             
+#11
+otb_test_application(NAME  apTvSARPolarMatrixConvertBiSincToCirCovariance
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invh ${INPUTDATA}/RSAT_imageryC_VH.tif
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv bsinclairtocircovariance
+							 -outc ${TEMP}/apTvSARPolarMatrixConvertBiSincToCirCovariance.tif
+							 
+                     )
+   
+                             
+#12 
+otb_test_application(NAME  apTvSARPolarMatrixConvertSincToMueller
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inhh ${INPUTDATA}/RSAT_imageryC_HH.tif
+							 -inhv ${INPUTDATA}/RSAT_imageryC_HV.tif
+							 -invh ${INPUTDATA}/RSAT_imageryC_HV.tif #monostatic
+							 -invv ${INPUTDATA}/RSAT_imageryC_VV.tif
+							 -conv sinclairtomueller
+							 -outf ${TEMP}/apTvSARPolarMatrixConvertSincToMueller.tif
+							 
+                     )
+                             
+                             
+#13 
+otb_test_application(NAME  apTvSARPolarMatrixConvertMuellerToPolDeGPow
+                     APP  SARPolarMatrixConvert
+                     OPTIONS 
+							 -inf ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif
+							 -conv muellertopoldegandpower
+							 -outf ${TEMP}/apTvSARPolarMatrixConvertMuellerToPolDeGPow.tif
+							 
+                     )
diff --git a/Modules/Applications/AppSARPolarSynth/CMakeLists.txt b/Modules/Applications/AppSARPolarSynth/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f6c2324b5b9053c0a5f0f3818560e586c30ba62c
--- /dev/null
+++ b/Modules/Applications/AppSARPolarSynth/CMakeLists.txt
@@ -0,0 +1,2 @@
+project(OTBAppSARPolarSynth)
+otb_module_impl()
diff --git a/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt b/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ea87ee870ad0182cd2338fc42e915c81279f6495
--- /dev/null
+++ b/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(OTBAppFiltering_LINK_LIBS
+  ${OTBPolarimetry_LIBRARIES}
+  ${OTBImageManipulation_LIBRARIES}
+  ${OTBApplicationEngine_LIBRARIES}
+  ${OTBImageBase_LIBRARIES}
+)
+
+otb_create_application(
+  NAME           SARPolarSynth
+  SOURCES        otbSARPolarSynth.cxx
+  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
diff --git a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4963306b34a459f87283d7bf17cc98b0ad4060d9
--- /dev/null
+++ b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
@@ -0,0 +1,185 @@
+/*=========================================================================
+
+ Program:   ORFEO Toolbox
+ Language:  C++
+ Date:      $Date$
+ Version:   $Revision$
+
+
+ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+ See OTBCopyright.txt for details.
+
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notices for more information.
+
+ =========================================================================*/
+#include "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+#include "otbMultiChannelsPolarimetricSynthesisFilter.h"
+
+namespace otb
+{
+namespace Wrapper
+{
+
+class SARPolarSynth : public Application
+{
+public:
+  /** Standard class typedefs. */
+  typedef SARPolarSynth                       Self;
+  typedef Application                         Superclass;
+  typedef itk::SmartPointer<Self>             Pointer;
+  typedef itk::SmartPointer<const Self>       ConstPointer;
+
+  typedef MultiChannelsPolarimetricSynthesisFilter<ComplexDoubleVectorImageType, FloatImageType>        MCPSFilterType;
+  /** Standard macro */
+  itkNewMacro(Self);
+
+  itkTypeMacro(SARPolarSynth, otb::Application);
+
+private:
+  void DoInit()
+  {
+    SetName("SARPolarSynth");
+    SetDescription("Gives, for each pixel, the power that would have been received by a SAR system with a basis different from the classical (H,V) one (polarimetric synthetis).");
+
+    // Documentation
+    SetDocName("SARPolarSynth");
+    SetDocLongDescription("This application gives, for each pixel, the power that would have been received by a SAR system with a basis different from the classical (H,V) one (polarimetric synthetis).\n" 
+						  "The new basis A and B are indicated through two Jones vectors, defined by the user thanks to orientation (psi) and ellipticity (khi) parameters.\n"
+						  "These parameters are namely psii, khii, psir and khir. The suffixes (i) and (r) refer to the transmiting antenna and the receiving antenna respectively.\n"
+						  "Orientations and ellipticities are given in degrees, and are between -90°/90° and -45°/45° respectively.\n " 
+						  "\n"
+						  "Four polarization architectures can be processed : \n"
+						  "1) HH_HV_VH_VV : full polarization, general bistatic case.\n"
+						  "2) HH_HV_VV or HH_VH_VV : full polarization, monostatic case (transmitter and receiver are co-located).\n"
+						  "3) HH_HV : dual polarization.\n"
+						  "4) VH_VV : dual polarization.\n"
+						  "The application takes a complex vector image as input, where each band correspond to a particular emission/reception polarization scheme.\n"
+						  "User must comply with the band order given above, since the bands are used to build the Sinclair matrix.\n"
+						  "\n"
+						  "In order to determine the architecture, the application first relies on the number of bands of the input image.\n" 
+						  "1) Architecture HH_HV_VH_VV is the only one with four bands, there is no possible confusion.\n"
+						  "2) Concerning HH_HV_VV and HH_VH_VV architectures, both correspond to a three channels image. But they are processed in the same way, as the Sinclair matrix is symetric in the monostatic case.\n"
+						  "3) Finally, the two last architectures (dual polarizations), can't be distinguished only by the number of bands of the input image.\n"
+						  "   User must then use the parameters emissionh and emissionv to indicate the architecture of the system : emissionh=1 and emissionv=0 --> HH_HV,  emissionh=0 and emissionv=1 --> VH_VV.\n"
+						  "Note : if the architecture is HH_HV, khii and psii are automatically set to 0°/0°; if the architecture is VH_VV, khii and psii are automatically set to 0°/90°.\n"
+						  "\n"
+						  "It is also possible to force the calculation to co-polar or cross-polar modes.\n"
+						  "In the co-polar case, values for psir and khir will be ignored and forced to psii and khii; same as the cross-polar mode, where khir and psir will be forced to psii+90° and -khii.\n"
+						  "\n"
+						  "Finally, the result of the polarimetric synthetis is expressed in the power domain, through a one-band scalar image.\n"
+						  "Note: this application doesn't take into account the terms which do not depend on the polarization of the antennas. \n"
+						  "The parameter gain can be used for this purpose.\n"
+						  "\n"
+						  "The final formula is thus : P = | B^T . [S] . A |², where A ans B are two Jones vectors and S is a Sinclair matrix.");
+						  
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso("SARDecompositions, SARPolarMatrixConvert");
+
+    AddDocTag(Tags::SAR);
+
+    AddParameter(ParameterType_ComplexInputImage,  "in",   "Input Image");
+    SetParameterDescription("in", "Input image.");
+    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
+    SetParameterDescription("out", "Output image.");
+    
+    AddParameter(ParameterType_Float,"psii","psii");
+    SetParameterDescription("psii","Orientation (transmitting antenna)");
+    SetMinimumParameterFloatValue("psii",-90.0);
+    SetMaximumParameterFloatValue("psii",90.0);
+    
+    AddParameter(ParameterType_Float,"khii","khii");
+    SetParameterDescription("khii","Ellipticity (transmitting antenna)");
+    SetMinimumParameterFloatValue("khii",-45.0);
+    SetMaximumParameterFloatValue("khii",45.0);
+    
+    AddParameter(ParameterType_Float,"psir","psir");
+    SetParameterDescription("psir","Orientation (receiving antenna)");
+    SetMinimumParameterFloatValue("psir",-90.0);
+    SetMaximumParameterFloatValue("psir",90.0);
+    
+    AddParameter(ParameterType_Float,"khir","khir");
+    SetParameterDescription("khir","Ellipticity (receiving antenna)");
+    SetMinimumParameterFloatValue("khir",-45.0);
+    SetMaximumParameterFloatValue("khir",45.0);
+    
+    AddParameter(ParameterType_Int,"emissionh","Emission H");
+    SetParameterDescription("emissionh","This parameter is useful in determining the polarization architecture (dual polarization case).");
+    SetMinimumParameterIntValue("emissionh",0);
+    SetMaximumParameterIntValue("emissionh",1);
+    MandatoryOff("emissionh");
+    
+    AddParameter(ParameterType_Int,"emissionv","Emission V");
+    SetParameterDescription("emissionv","This parameter is useful in determining the polarization architecture (dual polarization case).");
+    SetMinimumParameterIntValue("emissionv",0);
+    SetMaximumParameterIntValue("emissionv",1);
+    MandatoryOff("emissionv");
+    
+    AddParameter(ParameterType_Choice, "mode", "Forced mode");
+    AddChoice("mode.none","None");
+    SetParameterDescription("mode.none","None");
+    AddChoice("mode.co","Copolarization");
+    SetParameterDescription("mode.none","Copolarization");
+    AddChoice("mode.cross","Crosspolarization");
+    SetParameterDescription("mode.cross","Crosspolarization");
+    
+
+    AddRAMParameter();
+
+    // Default values
+    SetDefaultParameterFloat("psii", 0.);
+    SetDefaultParameterFloat("khii", 0.);
+    SetDefaultParameterFloat("psir",  0.);
+    SetDefaultParameterFloat("khir",  0.);
+    SetDefaultParameterInt("emissionh", 0);
+    SetDefaultParameterInt("emissionv", 0);
+	SetDefaultParameterFloat("mode",  0);
+
+    // Doc example parameter settings
+    SetDocExampleParameterValue("in", "sar.tif");
+    SetDocExampleParameterValue("psii","15.");
+    SetDocExampleParameterValue("khii", "5.");
+    SetDocExampleParameterValue("psir","-25.");
+    SetDocExampleParameterValue("khir", "10.");
+    SetDocExampleParameterValue("out", "newbasis.tif");
+  }
+
+  void DoUpdateParameters()
+  {
+    // Nothing to do here : all parameters are independent
+  }
+
+  void DoExecute()
+  {
+	
+	m_MCPSFilter = MCPSFilterType::New();
+	m_MCPSFilter->SetPsiI(GetParameterFloat("psii"));
+    m_MCPSFilter->SetKhiI(GetParameterFloat("khii"));
+    m_MCPSFilter->SetPsiR(GetParameterFloat("psir"));
+    m_MCPSFilter->SetKhiR(GetParameterFloat("khir"));
+    m_MCPSFilter->SetEmissionH(GetParameterInt("emissionh"));
+    m_MCPSFilter->SetEmissionV(GetParameterInt("emissionv"));
+	m_MCPSFilter->SetMode(GetParameterInt("mode"));  
+	  
+    ComplexDoubleVectorImageType* inVImage = GetParameterComplexDoubleVectorImage("in");
+    inVImage->UpdateOutputInformation();
+    int nbBands = inVImage->GetNumberOfComponentsPerPixel();
+    otbAppLogINFO( << "nbBands = " << nbBands);
+
+	m_MCPSFilter->SetInput(inVImage);
+   
+    SetParameterOutputImage("out", m_MCPSFilter->GetOutput());
+  }
+  //std::vector<itk::ProcessObject::Pointer> m_Ref;
+  MCPSFilterType::Pointer m_MCPSFilter;
+}; 
+
+} //end namespace Wrapper
+} //end namespace otb
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::SARPolarSynth)
diff --git a/Modules/Applications/AppSARPolarSynth/otb-module.cmake b/Modules/Applications/AppSARPolarSynth/otb-module.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..16d19e0a98d9dde0b29258a43063e6d2696e563e
--- /dev/null
+++ b/Modules/Applications/AppSARPolarSynth/otb-module.cmake
@@ -0,0 +1,17 @@
+set(DOCUMENTATION "Basic filters application.")
+
+otb_module(OTBAppSARPolarSynth
+  DEPENDS
+    OTBPolarimetry
+    OTBImageManipulation
+    OTBITK
+    OTBApplicationEngine
+    OTBImageBase
+
+  TEST_DEPENDS
+    OTBTestKernel
+    OTBCommandLine
+
+  DESCRIPTION
+    "${DOCUMENTATION}"
+)
diff --git a/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt b/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1adeb2028634a4d0cb63774dd91a7d07cfb44110
--- /dev/null
+++ b/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt
@@ -0,0 +1,13 @@
+otb_module_test()
+#----------- PolarSynth TESTS ----------------
+
+otb_test_application(NAME  apTvSARPolarSynth
+                     APP  SARPolarSynth
+                     OPTIONS -in ${INPUTDATA}/RSAT2_AltonaExtract_1000_1000_100_100.hdr
+               	             -out ${TEMP}/resApMultiPolarimetricSynthesis1.tif
+                             -psii 10.0 
+                             -khii 0.0
+                             -psir 0.0
+                             -khir 0.0
+                     )
+                             
diff --git a/Modules/Core/Metadata/include/otbSarImageMetadataInterface.h b/Modules/Core/Metadata/include/otbSarImageMetadataInterface.h
index 3ed787e142b5696bce239adf57a5b3b339e77090..7ce844f4207ca378e11c7e8d49722bcd6e953bfd 100644
--- a/Modules/Core/Metadata/include/otbSarImageMetadataInterface.h
+++ b/Modules/Core/Metadata/include/otbSarImageMetadataInterface.h
@@ -59,7 +59,7 @@ public:
   typedef double                                     RealType;
   typedef PointSetType::PointType                    PointType;
   typedef SarCalibrationLookupData                   LookupDataType;
-  typedef typename LookupDataType::Pointer          LookupDataPointerType;
+  typedef LookupDataType::Pointer                    LookupDataPointerType;
 
   virtual void CreateCalibrationLookupData(const short t);
 
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h
index 06a7a949d5ae59d1090521a4a914c50627362a5c..0967d1747196fa2632a926d3eedfe26692a92927 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h
@@ -137,6 +137,7 @@ public:
 			plog[k]=0.0;
 		else
 			plog[k]=-p[k]*log(p[k])/log(3.0);
+
       }
 
 	entropy = 0.0;
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
index e1d6743c6f9a4f5e960f1897c457f371f50a305e..7fb9ddc327a721737781b24eb065de7bc07dcf63 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
@@ -18,8 +18,10 @@
 #ifndef __otbSinclairToReciprocalCoherencyMatrixFunctor_h
 #define __otbSinclairToReciprocalCoherencyMatrixFunctor_h
 
-#include "vcl_complex.h"
 #include "itkMacro.h"
+#include "vcl_complex.h"
+#include "otbMath.h"
+#include "vnl/vnl_matrix.h"
 
 namespace otb
 {
@@ -62,6 +64,7 @@ class SinclairToReciprocalCoherencyMatrixFunctor
 public:
   /** Some typedefs. */
   typedef typename std::complex <double>           ComplexType;
+  typedef vnl_matrix<ComplexType>       		   VNLMatrixType;
   typedef typename TOutput::ValueType              OutputValueType;
   
   itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 6);
@@ -75,19 +78,23 @@ public:
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
-
-    const ComplexType HHPlusVV  = S_hh + S_vv;
-    const ComplexType HHMinusVV = S_hh - S_vv;
-    const ComplexType twoHV     = ComplexType( 2.0 ) * S_hv;
-
-    result[0] = static_cast<OutputValueType>( std::norm(HHPlusVV) );
-    result[1] = static_cast<OutputValueType>( HHPlusVV * vcl_conj(HHMinusVV) );
-    result[2] = static_cast<OutputValueType>( HHPlusVV * vcl_conj(twoHV) );
-    result[3] = static_cast<OutputValueType>( std::norm(HHMinusVV) );
-    result[4] = static_cast<OutputValueType>( HHMinusVV *vcl_conj(twoHV) );
-    result[5] = static_cast<OutputValueType>( std::norm(twoHV) );
-
-    result /= 2.0;
+   
+    
+    VNLMatrixType f3p(3, 1, 0.);
+    f3p[0][0]= (S_hh + S_vv) / ComplexType( std::sqrt(2.0) , 0.0);
+    f3p[1][0]= (S_hh - S_vv) / ComplexType( std::sqrt(2.0) , 0.0);
+    f3p[2][0]= ComplexType( std::sqrt(2.0) , 0.0) * S_hv;
+
+
+    VNLMatrixType res = f3p*f3p.conjugate_transpose();
+    
+    result[0] = static_cast<OutputValueType>( res[0][0] );
+    result[1] = static_cast<OutputValueType>( res[0][1] );
+    result[2] = static_cast<OutputValueType>( res[0][2] );
+    result[3] = static_cast<OutputValueType>( res[1][1] );
+    result[4] = static_cast<OutputValueType>( res[1][2] );
+    result[5] = static_cast<OutputValueType>( res[2][2] );
+    
 
     return (result);
   }
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
index 8ad714abef0d6c103c84e882489cf7d3fa634226..632033676ae0d5b2895f723074d9459a736969ba 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
@@ -19,6 +19,8 @@
 #define __otbSinclairToReciprocalCovarianceMatrixFunctor_h
 
 #include "vcl_complex.h"
+#include "otbMath.h"
+#include "vnl/vnl_matrix.h"
 
 namespace otb
 {
@@ -61,6 +63,7 @@ class SinclairToReciprocalCovarianceMatrixFunctor
 public:
   /** Some typedefs. */
   typedef typename std::complex <double>           ComplexType;
+  typedef vnl_matrix<ComplexType>       		   VNLMatrixType;
   typedef typename TOutput::ValueType              OutputValueType;
   inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv, const TInput3& Svv)
   {
@@ -72,12 +75,19 @@ public:
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
     
-    result[0] = static_cast<OutputValueType>( std::norm( S_hh ) );
-    result[1] = static_cast<OutputValueType>( vcl_sqrt(2.0)*S_hh*vcl_conj(S_hv) );
-    result[2] = static_cast<OutputValueType>( S_hh*vcl_conj(S_vv) );
-    result[3] = static_cast<OutputValueType>( 2.0*std::norm( S_hv ) );
-    result[4] = static_cast<OutputValueType>( vcl_sqrt(2.0)*S_hv*vcl_conj(S_vv) );
-    result[5] = static_cast<OutputValueType>( std::norm( S_vv ) );
+    VNLMatrixType f3l(3, 1, 0.);
+    f3l[0][0]=S_hh;
+    f3l[1][0]=ComplexType(std::sqrt(2.0),0.0)*S_hv;
+    f3l[2][0]=S_vv;
+    
+    VNLMatrixType res = f3l*f3l.conjugate_transpose();
+    
+    result[0] = static_cast<OutputValueType>( res[0][0] );
+    result[1] = static_cast<OutputValueType>( res[0][1] );
+    result[2] = static_cast<OutputValueType>( res[0][2] );
+    result[3] = static_cast<OutputValueType>( res[1][1] );
+    result[4] = static_cast<OutputValueType>( res[1][2] );
+    result[5] = static_cast<OutputValueType>( res[2][2] );
 
     return (result);
   }
diff --git a/Modules/Filtering/Polarimetry/test/CMakeLists.txt b/Modules/Filtering/Polarimetry/test/CMakeLists.txt
index 4d7a2a42b78f04c19a89665141b71f17dd4c4cf7..f69bd683b63d17200a0d8d0a0b79b09b7f46de9c 100644
--- a/Modules/Filtering/Polarimetry/test/CMakeLists.txt
+++ b/Modules/Filtering/Polarimetry/test/CMakeLists.txt
@@ -109,12 +109,12 @@ otb_add_test(NAME saTvMultiChannelsPolarimetricSynthesisFilter COMMAND otbPolari
 
 otb_add_test(NAME saTvMultiChannelsPolarimetricSynthesisFilter_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvMultiPolarimetricSynthesis2.tif
-  ${TEMP}/resMultiPolarimetricSynthesis2.tif
+  ${TEMP}/resMultiPolarimetricSynthesis2_C.tif
   otbMultiChannelsPolarimetricSynthesisFilter
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/resMultiPolarimetricSynthesis2.tif
+  ${TEMP}/resMultiPolarimetricSynthesis2_C.tif
   32.0     # PsiI
   22.0     # KhiI
   58.0     # PsiR
@@ -134,13 +134,13 @@ otb_add_test(NAME saTvSinclairImageFilter_SinclairToMueller COMMAND otbPolarimet
   
 otb_add_test(NAME saTvSinclairImageFilter_SinclairToMueller_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToMueller.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToMueller_C.tif
   otbSinclairImageFilter
   SinclairToMuellerMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToMueller.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToMueller_C.tif
   )
 
 otb_add_test(NAME saTvSinclairImageFilter_SinclairToCovariance COMMAND otbPolarimetryTestDriver
@@ -156,13 +156,13 @@ otb_add_test(NAME saTvSinclairImageFilter_SinclairToCovariance COMMAND otbPolari
   
 otb_add_test(NAME saTvSinclairImageFilter_SinclairToCovariance_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToCovariance.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToCovariance.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToCovariance_C.tif
   otbSinclairImageFilter
   SinclairToCovarianceMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToCovariance.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToCovariance_C.tif
   )
 
 otb_add_test(NAME saTuSinclairImageFilterNew COMMAND otbPolarimetryTestDriver
@@ -182,13 +182,13 @@ otb_add_test(NAME saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix COM
   
 otb_add_test(NAME saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix_C.tif
   otbSinclairImageFilter
   SinclairToCircularCovarianceMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToCircularCovarianceMatrix_C.tif
   )
 
 otb_add_test(NAME saTvSinclairImageFilter_SinclairToCoherency COMMAND otbPolarimetryTestDriver
@@ -204,13 +204,13 @@ otb_add_test(NAME saTvSinclairImageFilter_SinclairToCoherency COMMAND otbPolarim
   
 otb_add_test(NAME saTvSinclairImageFilter_SinclairToCoherency_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToCoherency.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToCoherency.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToCoherency_C.tif
   otbSinclairImageFilter
   SinclairToCoherencyMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToCoherency.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToCoherency_C.tif
   )
 
 otb_add_test(NAME saTuReciprocalCovarianceToReciprocalCoherencyImageFilterNew COMMAND otbPolarimetryTestDriver
@@ -238,13 +238,13 @@ otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCovarian
   
 otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCovariance_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCovariance_C.tif
   otbSinclairReciprocalImageFilter
   SinclairToReciprocalCovarianceMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCovariance_C.tif
   )
 
 otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCircularCovarianceMatrix COMMAND otbPolarimetryTestDriver
@@ -261,13 +261,13 @@ otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCircular
   
 otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCircularCovarianceMatrix_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix_C.tif
   otbSinclairReciprocalImageFilter
   SinclairToReciprocalCircularCovarianceMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix_C.tif
   )
 
 otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCoherency COMMAND otbPolarimetryTestDriver
@@ -283,13 +283,13 @@ otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCoherenc
   
 otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCoherency_C COMMAND otbPolarimetryTestDriver
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCoherency_C.tif
   otbSinclairReciprocalImageFilter
   SinclairToReciprocalCoherencyMatrix
   ${INPUTDATA}/RSAT_imageryC_HH.tif
   ${INPUTDATA}/RSAT_imageryC_HV.tif
   ${INPUTDATA}/RSAT_imageryC_VV.tif
-  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif
+  ${TEMP}/saTvSinclairImageFilter_SinclairToReciprocalCoherency_C.tif
   )
  
 
diff --git a/Modules/IO/ExtendedFilename/src/otbExtendedFilenameHelper.cxx b/Modules/IO/ExtendedFilename/src/otbExtendedFilenameHelper.cxx
index eb08b5e874318b3825359a16350774c72a7635a6..e7d77129417b8d6ea4015f210a6eeb314e463cae 100644
--- a/Modules/IO/ExtendedFilename/src/otbExtendedFilenameHelper.cxx
+++ b/Modules/IO/ExtendedFilename/src/otbExtendedFilenameHelper.cxx
@@ -30,6 +30,7 @@ ExtendedFilenameHelper
     itkGenericExceptionMacro( << "Filename is NULL" );
   }
   this->m_ExtendedFileName = extFname;
+  this->m_OptionMap.clear();
   std::vector<std::string> tmp1;
   std::vector<std::string> tmp2;
   if (!m_ExtendedFileName.empty())
diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
index 1085a23c6f8b86a0b6b7b4e76925f064e45332d1..37c14462dcafe9c7e086da4a10a00f8b4c3019c4 100644
--- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
@@ -1679,6 +1679,28 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
     {
     dataset->SetProjection(projectionRef.c_str());
     }
+  else
+    {
+    /* -------------------------------------------------------------------- */
+    /* Set the RPC coeffs if no projection available (since GDAL 1.10.0)    */
+    /* -------------------------------------------------------------------- */
+#if GDAL_VERSION_NUM >= 1100000
+    ImageKeywordlist otb_kwl;
+    itk::ExposeMetaData<ImageKeywordlist>(dict,
+                                          MetaDataKey::OSSIMKeywordlistKey,
+                                          otb_kwl);
+    if( otb_kwl.GetSize() != 0 )
+      {
+      GDALRPCInfo gdalRpcStruct;
+      if ( otb_kwl.convertToGDALRPC(gdalRpcStruct) )
+        {
+        char **rpcMetadata = RPCInfoToMD(&gdalRpcStruct);
+        dataset->SetMetadata(rpcMetadata, "RPC");
+        CSLDestroy( rpcMetadata );
+        }
+      }
+#endif
+    }
 
   /* -------------------------------------------------------------------- */
   /*  Set the six coefficients of affine geoTransform                     */
@@ -1719,23 +1741,6 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
       }
     }
 
-#if GDAL_VERSION_NUM >= 1100000
-  // Report any RPC coefficients (feature available since GDAL 1.10.0)
-  ImageKeywordlist otb_kwl;
-  itk::ExposeMetaData<ImageKeywordlist>(dict,
-                                        MetaDataKey::OSSIMKeywordlistKey,
-                                        otb_kwl);
-  if( otb_kwl.GetSize() != 0 )
-    {
-    GDALRPCInfo gdalRpcStruct;
-    if ( otb_kwl.convertToGDALRPC(gdalRpcStruct) )
-      {
-      char **rpcMetadata = RPCInfoToMD(&gdalRpcStruct);
-      dataset->SetMetadata(rpcMetadata, "RPC");
-      CSLDestroy( rpcMetadata );
-      }
-    }
-#endif
 
   // END
 
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1ProductDoc.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1ProductDoc.cpp
index 6f1ca586fba59f2339923b2383b7d81a6bd64242..64840e227889d5246096f139694086c94bfc5573 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1ProductDoc.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1ProductDoc.cpp
@@ -128,14 +128,15 @@ namespace ossimplugins
    {
       bool commonMetadataRetrieved = false;
       double heightSum = 0.0;
-      int numBands = 1;
+      int numBands = 0;
 
       ossimDirectory annotationDir( theManifestDirectory.dirCat( "annotation") );
       std::vector<ossimFilename> files;
       annotationDir.findAllFilesThatMatch(files, ".xml");
       std::vector<ossimFilename>::const_iterator it = files.begin();
 
-
+      /* avoid zero value for numBands. This will result in division by zero below */
+      if( files.size() < 1 ) numBands = 1;
 
       for (int count=0; it != files.end(); ++it,  ++count)
       {
diff --git a/Modules/Wrappers/SWIG/otb-module-init.cmake b/Modules/Wrappers/SWIG/otb-module-init.cmake
index c5ae8a9992535524c193725380679c16888a5b25..819a60d7718fd005fe537b1fede1ad2e1ea6eff8 100644
--- a/Modules/Wrappers/SWIG/otb-module-init.cmake
+++ b/Modules/Wrappers/SWIG/otb-module-init.cmake
@@ -25,6 +25,7 @@ if ( OTB_WRAP_PYTHON )
   check_PIC_flag ( Python )
   find_package ( PythonLibs REQUIRED )
   find_package ( PythonInterp REQUIRED )
+  find_package ( Numpy )
 endif()
 
 #
diff --git a/Modules/Wrappers/SWIG/src/CMakeLists.txt b/Modules/Wrappers/SWIG/src/CMakeLists.txt
index 786f3a68657cfb5987b13dd2ea1f93bb0521584e..79150ccc03c2ce3fd8cd6362159e6d215312d8d3 100644
--- a/Modules/Wrappers/SWIG/src/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/src/CMakeLists.txt
@@ -24,6 +24,10 @@ if ( OTB_WRAP_PYTHON )
 
   # Run swig
   set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS})
+  if(NUMPY_FOUND)
+    include_directories(${NUMPY_INCLUDE_DIRS})
+    list(APPEND CMAKE_SWIG_FLAGS  "-DOTB_SWIGNUMPY=1")
+  endif()
   set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR})
   set(SWIG_MODULE_otbApplication_EXTRA_DEPS
        ${CMAKE_CURRENT_SOURCE_DIR}/Python.i
@@ -42,7 +46,7 @@ if ( OTB_WRAP_PYTHON )
       COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/CMake/PythonCompile.py otbApplication.py
       DEPENDS _otbApplication
     )
-    
+
   otb_module_target_label( _otbApplication )
 
   install( TARGETS _otbApplication
@@ -80,7 +84,7 @@ if ( OTB_WRAP_JAVA )
 
   # Add target for org.otb.Application.jar
   add_custom_target(org_otb_Application_jar ALL DEPENDS org.otb.application.jar)
-  
+
   otb_module_target_label( org_otb_Application_jar )
 
   # Add custom command and target to compile the generated files and put them in a jar file
@@ -106,4 +110,3 @@ if ( OTB_WRAP_JAVA )
           COMPONENT RuntimeLibraries )
 
 endif()
-
diff --git a/Modules/Wrappers/SWIG/src/numpy.i b/Modules/Wrappers/SWIG/src/numpy.i
new file mode 100644
index 0000000000000000000000000000000000000000..b9a7ce7f40b3f83bf3e2b82d43d6a477f347a372
--- /dev/null
+++ b/Modules/Wrappers/SWIG/src/numpy.i
@@ -0,0 +1,3117 @@
+/* -*- C -*-  (not really, but good for syntax highlighting) */
+
+/*
+ * Copyright (c) 2005-2015, NumPy Developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials provided
+ *        with the distribution.
+ *
+ *     * Neither the name of the NumPy Developers nor the names of any
+ *        contributors may be used to endorse or promote products derived
+ *        from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef SWIGPYTHON
+
+%{
+#ifndef SWIG_FILE_WITH_INIT
+#define NO_IMPORT_ARRAY
+#endif
+#include "stdio.h"
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/arrayobject.h>
+%}
+
+/**********************************************************************/
+
+%fragment("NumPy_Backward_Compatibility", "header")
+{
+%#if NPY_API_VERSION < 0x00000007
+%#define NPY_ARRAY_DEFAULT NPY_DEFAULT
+%#define NPY_ARRAY_FARRAY  NPY_FARRAY
+%#define NPY_FORTRANORDER  NPY_FORTRAN
+%#endif
+}
+
+/**********************************************************************/
+
+/* The following code originally appeared in
+ * enthought/kiva/agg/src/numeric.i written by Eric Jones.  It was
+ * translated from C++ to C by John Hunter.  Bill Spotz has modified
+ * it to fix some minor bugs, upgrade from Numeric to numpy (all
+ * versions), add some comments and functionality, and convert from
+ * direct code insertion to SWIG fragments.
+ */
+
+%fragment("NumPy_Macros", "header")
+{
+/* Macros to extract array attributes.
+ */
+%#if NPY_API_VERSION < 0x00000007
+%#define is_array(a)            ((a) && PyArray_Check((PyArrayObject*)a))
+%#define array_type(a)          (int)(PyArray_TYPE((PyArrayObject*)a))
+%#define array_numdims(a)       (((PyArrayObject*)a)->nd)
+%#define array_dimensions(a)    (((PyArrayObject*)a)->dimensions)
+%#define array_size(a,i)        (((PyArrayObject*)a)->dimensions[i])
+%#define array_strides(a)       (((PyArrayObject*)a)->strides)
+%#define array_stride(a,i)      (((PyArrayObject*)a)->strides[i])
+%#define array_data(a)          (((PyArrayObject*)a)->data)
+%#define array_descr(a)         (((PyArrayObject*)a)->descr)
+%#define array_flags(a)         (((PyArrayObject*)a)->flags)
+%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f
+%#else
+%#define is_array(a)            ((a) && PyArray_Check(a))
+%#define array_type(a)          PyArray_TYPE((PyArrayObject*)a)
+%#define array_numdims(a)       PyArray_NDIM((PyArrayObject*)a)
+%#define array_dimensions(a)    PyArray_DIMS((PyArrayObject*)a)
+%#define array_strides(a)       PyArray_STRIDES((PyArrayObject*)a)
+%#define array_stride(a,i)      PyArray_STRIDE((PyArrayObject*)a,i)
+%#define array_size(a,i)        PyArray_DIM((PyArrayObject*)a,i)
+%#define array_data(a)          PyArray_DATA((PyArrayObject*)a)
+%#define array_descr(a)         PyArray_DESCR((PyArrayObject*)a)
+%#define array_flags(a)         PyArray_FLAGS((PyArrayObject*)a)
+%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f)
+%#endif
+%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a))
+%#define array_is_native(a)     (PyArray_ISNOTSWAPPED((PyArrayObject*)a))
+%#define array_is_fortran(a)    (PyArray_ISFORTRAN((PyArrayObject*)a))
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Utilities",
+          "header")
+{
+  /* Given a PyObject, return a string describing its type.
+   */
+  const char* pytype_string(PyObject* py_obj)
+  {
+    if (py_obj == NULL          ) return "C NULL value";
+    if (py_obj == Py_None       ) return "Python None" ;
+    if (PyCallable_Check(py_obj)) return "callable"    ;
+    if (PyString_Check(  py_obj)) return "string"      ;
+    if (PyInt_Check(     py_obj)) return "int"         ;
+    if (PyFloat_Check(   py_obj)) return "float"       ;
+    if (PyDict_Check(    py_obj)) return "dict"        ;
+    if (PyList_Check(    py_obj)) return "list"        ;
+    if (PyTuple_Check(   py_obj)) return "tuple"       ;
+%#if PY_MAJOR_VERSION < 3
+    if (PyFile_Check(    py_obj)) return "file"        ;
+    if (PyModule_Check(  py_obj)) return "module"      ;
+    if (PyInstance_Check(py_obj)) return "instance"    ;
+%#endif
+
+    return "unkown type";
+  }
+
+  /* Given a NumPy typecode, return a string describing the type.
+   */
+  const char* typecode_string(int typecode)
+  {
+    static const char* type_names[25] = {"bool",
+                                         "byte",
+                                         "unsigned byte",
+                                         "short",
+                                         "unsigned short",
+                                         "int",
+                                         "unsigned int",
+                                         "long",
+                                         "unsigned long",
+                                         "long long",
+                                         "unsigned long long",
+                                         "float",
+                                         "double",
+                                         "long double",
+                                         "complex float",
+                                         "complex double",
+                                         "complex long double",
+                                         "object",
+                                         "string",
+                                         "unicode",
+                                         "void",
+                                         "ntypes",
+                                         "notype",
+                                         "char",
+                                         "unknown"};
+    return typecode < 24 ? type_names[typecode] : type_names[24];
+  }
+
+  /* Make sure input has correct numpy type.  This now just calls
+     PyArray_EquivTypenums().
+   */
+  int type_match(int actual_type,
+                 int desired_type)
+  {
+    return PyArray_EquivTypenums(actual_type, desired_type);
+  }
+
+%#ifdef SWIGPY_USE_CAPSULE
+  void free_cap(PyObject * cap)
+  {
+    void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME);
+    if (array != NULL) free(array);
+  }
+%#endif
+
+
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Object_to_Array",
+          "header",
+          fragment="NumPy_Backward_Compatibility",
+          fragment="NumPy_Macros",
+          fragment="NumPy_Utilities")
+{
+  /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
+   * legal.  If not, set the python error string appropriately and
+   * return NULL.
+   */
+  PyArrayObject* obj_to_array_no_conversion(PyObject* input,
+                                            int        typecode)
+  {
+    PyArrayObject* ary = NULL;
+    if (is_array(input) && (typecode == NPY_NOTYPE ||
+                            PyArray_EquivTypenums(array_type(input), typecode)))
+    {
+      ary = (PyArrayObject*) input;
+    }
+    else if is_array(input)
+    {
+      const char* desired_type = typecode_string(typecode);
+      const char* actual_type  = typecode_string(array_type(input));
+      PyErr_Format(PyExc_TypeError,
+                   "Array of type '%s' required.  Array of type '%s' given",
+                   desired_type, actual_type);
+      ary = NULL;
+    }
+    else
+    {
+      const char* desired_type = typecode_string(typecode);
+      const char* actual_type  = pytype_string(input);
+      PyErr_Format(PyExc_TypeError,
+                   "Array of type '%s' required.  A '%s' was given",
+                   desired_type,
+                   actual_type);
+      ary = NULL;
+    }
+    return ary;
+  }
+
+  /* Convert the given PyObject to a NumPy array with the given
+   * typecode.  On success, return a valid PyArrayObject* with the
+   * correct type.  On failure, the python error string will be set and
+   * the routine returns NULL.
+   */
+  PyArrayObject* obj_to_array_allow_conversion(PyObject* input,
+                                               int       typecode,
+                                               int*      is_new_object)
+  {
+    PyArrayObject* ary = NULL;
+    PyObject*      py_obj;
+    if (is_array(input) && (typecode == NPY_NOTYPE ||
+                            PyArray_EquivTypenums(array_type(input),typecode)))
+    {
+      ary = (PyArrayObject*) input;
+      *is_new_object = 0;
+    }
+    else
+    {
+      py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT);
+      /* If NULL, PyArray_FromObject will have set python error value.*/
+      ary = (PyArrayObject*) py_obj;
+      *is_new_object = 1;
+    }
+    return ary;
+  }
+
+  /* Given a PyArrayObject, check to see if it is contiguous.  If so,
+   * return the input pointer and flag it as not a new object.  If it is
+   * not contiguous, create a new PyArrayObject using the original data,
+   * flag it as a new object and return the pointer.
+   */
+  PyArrayObject* make_contiguous(PyArrayObject* ary,
+                                 int*           is_new_object,
+                                 int            min_dims,
+                                 int            max_dims)
+  {
+    PyArrayObject* result;
+    if (array_is_contiguous(ary))
+    {
+      result = ary;
+      *is_new_object = 0;
+    }
+    else
+    {
+      result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
+                                                              array_type(ary),
+                                                              min_dims,
+                                                              max_dims);
+      *is_new_object = 1;
+    }
+    return result;
+  }
+
+  /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
+   * If so, return the input pointer, but do not flag it as not a new
+   * object.  If it is not Fortran-contiguous, create a new
+   * PyArrayObject using the original data, flag it as a new object
+   * and return the pointer.
+   */
+  PyArrayObject* make_fortran(PyArrayObject* ary,
+                              int*           is_new_object)
+  {
+    PyArrayObject* result;
+    if (array_is_fortran(ary))
+    {
+      result = ary;
+      *is_new_object = 0;
+    }
+    else
+    {
+      Py_INCREF(array_descr(ary));
+      result = (PyArrayObject*) PyArray_FromArray(ary,
+                                                  array_descr(ary),
+                                                  NPY_FORTRANORDER);
+      *is_new_object = 1;
+    }
+    return result;
+  }
+
+  /* Convert a given PyObject to a contiguous PyArrayObject of the
+   * specified type.  If the input object is not a contiguous
+   * PyArrayObject, a new one will be created and the new object flag
+   * will be set.
+   */
+  PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
+                                                          int       typecode,
+                                                          int*      is_new_object)
+  {
+    int is_new1 = 0;
+    int is_new2 = 0;
+    PyArrayObject* ary2;
+    PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+                                                        typecode,
+                                                        &is_new1);
+    if (ary1)
+    {
+      ary2 = make_contiguous(ary1, &is_new2, 0, 0);
+      if ( is_new1 && is_new2)
+      {
+        Py_DECREF(ary1);
+      }
+      ary1 = ary2;
+    }
+    *is_new_object = is_new1 || is_new2;
+    return ary1;
+  }
+
+  /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
+   * specified type.  If the input object is not a Fortran-ordered
+   * PyArrayObject, a new one will be created and the new object flag
+   * will be set.
+   */
+  PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
+                                                       int       typecode,
+                                                       int*      is_new_object)
+  {
+    int is_new1 = 0;
+    int is_new2 = 0;
+    PyArrayObject* ary2;
+    PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+                                                        typecode,
+                                                        &is_new1);
+    if (ary1)
+    {
+      ary2 = make_fortran(ary1, &is_new2);
+      if (is_new1 && is_new2)
+      {
+        Py_DECREF(ary1);
+      }
+      ary1 = ary2;
+    }
+    *is_new_object = is_new1 || is_new2;
+    return ary1;
+  }
+} /* end fragment */
+
+/**********************************************************************/
+
+%fragment("NumPy_Array_Requirements",
+          "header",
+          fragment="NumPy_Backward_Compatibility",
+          fragment="NumPy_Macros")
+{
+  /* Test whether a python object is contiguous.  If array is
+   * contiguous, return 1.  Otherwise, set the python error string and
+   * return 0.
+   */
+  int require_contiguous(PyArrayObject* ary)
+  {
+    int contiguous = 1;
+    if (!array_is_contiguous(ary))
+    {
+      PyErr_SetString(PyExc_TypeError,
+                      "Array must be contiguous.  A non-contiguous array was given");
+      contiguous = 0;
+    }
+    return contiguous;
+  }
+
+  /* Require that a numpy array is not byte-swapped.  If the array is
+   * not byte-swapped, return 1.  Otherwise, set the python error string
+   * and return 0.
+   */
+  int require_native(PyArrayObject* ary)
+  {
+    int native = 1;
+    if (!array_is_native(ary))
+    {
+      PyErr_SetString(PyExc_TypeError,
+                      "Array must have native byteorder.  "
+                      "A byte-swapped array was given");
+      native = 0;
+    }
+    return native;
+  }
+
+  /* Require the given PyArrayObject to have a specified number of
+   * dimensions.  If the array has the specified number of dimensions,
+   * return 1.  Otherwise, set the python error string and return 0.
+   */
+  int require_dimensions(PyArrayObject* ary,
+                         int            exact_dimensions)
+  {
+    int success = 1;
+    if (array_numdims(ary) != exact_dimensions)
+    {
+      PyErr_Format(PyExc_TypeError,
+                   "Array must have %d dimensions.  Given array has %d dimensions",
+                   exact_dimensions,
+                   array_numdims(ary));
+      success = 0;
+    }
+    return success;
+  }
+
+  /* Require the given PyArrayObject to have one of a list of specified
+   * number of dimensions.  If the array has one of the specified number
+   * of dimensions, return 1.  Otherwise, set the python error string
+   * and return 0.
+   */
+  int require_dimensions_n(PyArrayObject* ary,
+                           int*           exact_dimensions,
+                           int            n)
+  {
+    int success = 0;
+    int i;
+    char dims_str[255] = "";
+    char s[255];
+    for (i = 0; i < n && !success; i++)
+    {
+      if (array_numdims(ary) == exact_dimensions[i])
+      {
+        success = 1;
+      }
+    }
+    if (!success)
+    {
+      for (i = 0; i < n-1; i++)
+      {
+        sprintf(s, "%d, ", exact_dimensions[i]);
+        strcat(dims_str,s);
+      }
+      sprintf(s, " or %d", exact_dimensions[n-1]);
+      strcat(dims_str,s);
+      PyErr_Format(PyExc_TypeError,
+                   "Array must have %s dimensions.  Given array has %d dimensions",
+                   dims_str,
+                   array_numdims(ary));
+    }
+    return success;
+  }
+
+  /* Require the given PyArrayObject to have a specified shape.  If the
+   * array has the specified shape, return 1.  Otherwise, set the python
+   * error string and return 0.
+   */
+  int require_size(PyArrayObject* ary,
+                   npy_intp*      size,
+                   int            n)
+  {
+    int i;
+    int success = 1;
+    int len;
+    char desired_dims[255] = "[";
+    char s[255];
+    char actual_dims[255] = "[";
+    for(i=0; i < n;i++)
+    {
+      if (size[i] != -1 &&  size[i] != array_size(ary,i))
+      {
+        success = 0;
+      }
+    }
+    if (!success)
+    {
+      for (i = 0; i < n; i++)
+      {
+        if (size[i] == -1)
+        {
+          sprintf(s, "*,");
+        }
+        else
+        {
+          sprintf(s, "%ld,", (long int)size[i]);
+        }
+        strcat(desired_dims,s);
+      }
+      len = strlen(desired_dims);
+      desired_dims[len-1] = ']';
+      for (i = 0; i < n; i++)
+      {
+        sprintf(s, "%ld,", (long int)array_size(ary,i));
+        strcat(actual_dims,s);
+      }
+      len = strlen(actual_dims);
+      actual_dims[len-1] = ']';
+      PyErr_Format(PyExc_TypeError,
+                   "Array must have shape of %s.  Given array has shape of %s",
+                   desired_dims,
+                   actual_dims);
+    }
+    return success;
+  }
+
+  /* Require the given PyArrayObject to to be Fortran ordered.  If the
+   * the PyArrayObject is already Fortran ordered, do nothing.  Else,
+   * set the Fortran ordering flag and recompute the strides.
+   */
+  int require_fortran(PyArrayObject* ary)
+  {
+    int success = 1;
+    int nd = array_numdims(ary);
+    int i;
+    npy_intp * strides = array_strides(ary);
+    if (array_is_fortran(ary)) return success;
+    /* Set the Fortran ordered flag */
+    array_enableflags(ary,NPY_ARRAY_FARRAY);
+    /* Recompute the strides */
+    strides[0] = strides[nd-1];
+    for (i=1; i < nd; ++i)
+      strides[i] = strides[i-1] * array_size(ary,i-1);
+    return success;
+  }
+}
+
+/* Combine all NumPy fragments into one for convenience */
+%fragment("NumPy_Fragments",
+          "header",
+          fragment="NumPy_Backward_Compatibility",
+          fragment="NumPy_Macros",
+          fragment="NumPy_Utilities",
+          fragment="NumPy_Object_to_Array",
+          fragment="NumPy_Array_Requirements")
+{
+}
+
+/* End John Hunter translation (with modifications by Bill Spotz)
+ */
+
+/* %numpy_typemaps() macro
+ *
+ * This macro defines a family of 74 typemaps that allow C arguments
+ * of the form
+ *
+ *    1. (DATA_TYPE IN_ARRAY1[ANY])
+ *    2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ *    3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *
+ *    4. (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ *    5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *    6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ *    7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *    8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *
+ *    9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ *   10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ *   13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ *
+ *   15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ *   16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+ *   19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+ *
+ *   21. (DATA_TYPE INPLACE_ARRAY1[ANY])
+ *   22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ *   23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ *
+ *   24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ *   25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *   26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ *   27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *   28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ *
+ *   29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ *   30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ *   33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ *
+ *   35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ *   36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+ *   39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+ *
+ *   41. (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ *   42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ *   43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ *
+ *   44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ *
+ *   45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *
+ *   46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ *
+ *   47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ *   48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ *
+ *   49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ *   51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *
+ *   53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ *   55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *
+ *   57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ *   59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ *
+ *   61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ *   62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ *
+ *   63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ *   65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ *
+ *   67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ *   69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ *
+ *   71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ *   73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ *
+ * where "DATA_TYPE" is any type supported by the NumPy module, and
+ * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
+ * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
+ * that the "FARRAY" typemaps expect Fortran ordering of
+ * multidimensional arrays.  In python, the dimensions will not need
+ * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
+ * typemaps).  The IN_ARRAYs can be a numpy array or any sequence that
+ * can be converted to a numpy array of the specified type.  The
+ * INPLACE_ARRAYs must be numpy arrays of the appropriate type.  The
+ * ARGOUT_ARRAYs will be returned as new numpy arrays of the
+ * appropriate type.
+ *
+ * These typemaps can be applied to existing functions using the
+ * %apply directive.  For example:
+ *
+ *     %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
+ *     double prod(double* series, int length);
+ *
+ *     %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
+ *           {(int rows, int cols, double* matrix        )};
+ *     void floor(int rows, int cols, double* matrix, double f);
+ *
+ *     %apply (double IN_ARRAY3[ANY][ANY][ANY])
+ *           {(double tensor[2][2][2]         )};
+ *     %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *           {(double low[2][2][2]                )};
+ *     %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *           {(double upp[2][2][2]                )};
+ *     void luSplit(double tensor[2][2][2],
+ *                  double low[2][2][2],
+ *                  double upp[2][2][2]    );
+ *
+ * or directly with
+ *
+ *     double prod(double* IN_ARRAY1, int DIM1);
+ *
+ *     void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
+ *
+ *     void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
+ *                  double ARGOUT_ARRAY3[ANY][ANY][ANY],
+ *                  double ARGOUT_ARRAY3[ANY][ANY][ANY]);
+ */
+
+%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
+
+/************************/
+/* Input Array Typemaps */
+/************************/
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY1[ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY1[ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[1] = { $1_dim0 };
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 1) ||
+      !require_size(array, size, 1)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY1[ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[1] = { -1 };
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 1) ||
+      !require_size(array, size, 1)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[1] = {-1};
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 1) ||
+      !require_size(array, size, 1)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY2[ANY][ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { $1_dim0, $1_dim1 };
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input,
+                                                DATA_TYPECODE,
+                                                &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  /* for now, only concerned with lists */
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+  npy_intp size[2] = { -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+  int is_new_object;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+  is_new_object_array = (int *)calloc($2,sizeof(int));
+
+  if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+    is_new_object_array[i] = is_new_object;
+
+    if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+    }
+
+    if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+  (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  Py_ssize_t i;
+
+  if (array$argnum!=NULL) free(array$argnum);
+
+  /*freeing the individual arrays if needed */
+  if (object_array$argnum!=NULL)
+  {
+    if (is_new_object_array$argnum!=NULL)
+    {
+      for (i=0; i<$2; i++)
+      {
+        if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+        { Py_DECREF(object_array$argnum[i]); }
+      }
+      free(is_new_object_array$argnum);
+    }
+    free(object_array$argnum);
+  }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* IN_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* IN_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input,
+                                                   DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3};
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  /* for now, only concerned with lists */
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+  int is_new_object;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+  is_new_object_array = (int *)calloc($2,sizeof(int));
+
+  if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+    is_new_object_array[i] = is_new_object;
+
+    if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+      size[2] = array_size(temp_array,2);
+    }
+
+    if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+  $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+  (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  Py_ssize_t i;
+
+  if (array$argnum!=NULL) free(array$argnum);
+
+  /*freeing the individual arrays if needed */
+  if (object_array$argnum!=NULL)
+  {
+    if (is_new_object_array$argnum!=NULL)
+    {
+      for (i=0; i<$2; i++)
+      {
+        if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+        { Py_DECREF(object_array$argnum[i]); }
+      }
+      free(is_new_object_array$argnum);
+    }
+    free(object_array$argnum);
+  }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ *                    DATA_TYPE* IN_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1 , -1};
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ *                    DATA_TYPE* IN_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1 , -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/***************************/
+/* In-Place Array Typemaps */
+/***************************/
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY1[ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY1[ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[1] = { $1_dim0 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+  (PyArrayObject* array=NULL, int i=1)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = 1;
+  for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+  (PyArrayObject* array=NULL, int i=0)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = 1;
+  for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
+  $2 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[2] = { $1_dim0, $1_dim1 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+      !require_native(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+      || !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+      !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+      !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+  npy_intp size[2] = { -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+  if (array == NULL || object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+
+    if ( !temp_array || !require_dimensions(temp_array, 2) ||
+      !require_contiguous(temp_array) ||
+      !require_native(temp_array) ||
+      !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+    ) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+    }
+
+    if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+  (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  if (array$argnum!=NULL) free(array$argnum);
+  if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+      !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+      || !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+      !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+  if (array == NULL || object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+
+    if ( !temp_array || !require_dimensions(temp_array, 3) ||
+      !require_contiguous(temp_array) ||
+      !require_native(temp_array) ||
+      !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+    ) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+      size[2] = array_size(temp_array,2);
+    }
+
+    if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+  $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+  (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  if (array$argnum!=NULL) free(array$argnum);
+  if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ *                    DATA_TYPE* INPLACE_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+      !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+      || !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+
+/*************************/
+/* Argout Array Typemaps */
+/*************************/
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY1[ANY])
+  (PyObject* array = NULL)
+{
+  npy_intp dims[1] = { $1_dim0 };
+  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY1[ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ */
+%typemap(in,numinputs=1,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+  (PyObject* array = NULL)
+{
+  npy_intp dims[1];
+  if (!PyInt_Check($input))
+  {
+    const char* typestring = pytype_string($input);
+    PyErr_Format(PyExc_TypeError,
+                 "Int dimension expected.  '%s' given.",
+                 typestring);
+    SWIG_fail;
+  }
+  $2 = (DIM_TYPE) PyInt_AsLong($input);
+  dims[0] = (npy_intp) $2;
+  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ */
+%typemap(in,numinputs=1,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+  (PyObject* array = NULL)
+{
+  npy_intp dims[1];
+  if (!PyInt_Check($input))
+  {
+    const char* typestring = pytype_string($input);
+    PyErr_Format(PyExc_TypeError,
+                 "Int dimension expected.  '%s' given.",
+                 typestring);
+    SWIG_fail;
+  }
+  $1 = (DIM_TYPE) PyInt_AsLong($input);
+  dims[0] = (npy_intp) $1;
+  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+  (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+  (PyObject* array = NULL)
+{
+  npy_intp dims[2] = { $1_dim0, $1_dim1 };
+  array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+  (PyObject* array = NULL)
+{
+  npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
+  array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+  (PyObject* array = NULL)
+{
+  npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 };
+  array = PyArray_SimpleNew(4, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/*****************************/
+/* Argoutview Array Typemaps */
+/*****************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1    )
+  (DATA_TYPE*  data_temp = NULL , DIM_TYPE  dim_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+{
+  npy_intp dims[1] = { *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DATA_TYPE** ARGOUTVIEW_ARRAY1)
+  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp = NULL )
+{
+  $1 = &dim_temp;
+  $2 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+{
+  npy_intp dims[1] = { *$1 };
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp = NULL , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_ARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp = NULL  , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_FARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL  )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL  , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL)
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DATA_TYPE** ARGOUTVIEW_FARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL  , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEW_ARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL  )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEW_FARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/*************************************/
+/* Managed Argoutview Array Typemaps */
+/*************************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1    )
+  (DATA_TYPE*  data_temp = NULL  , DIM_TYPE  dim_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+{
+  npy_intp dims[1] = { *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp = NULL  )
+{
+  $1 = &dim_temp;
+  $2 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+{
+  npy_intp dims[1] = { *$1 };
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp = NULL  , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL  )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp = NULL   , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL    , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL    )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL    , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL    )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL    , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL    )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+%enddef    /* %numpy_typemaps() macro */
+/* *************************************************************** */
+
+/* Concrete instances of the %numpy_typemaps() macro: Each invocation
+ * below applies all of the typemaps above to the specified data type.
+ */
+%numpy_typemaps(signed char       , NPY_BYTE     , int)
+%numpy_typemaps(unsigned char     , NPY_UBYTE    , int)
+%numpy_typemaps(short             , NPY_SHORT    , int)
+%numpy_typemaps(unsigned short    , NPY_USHORT   , int)
+%numpy_typemaps(int               , NPY_INT      , int)
+%numpy_typemaps(unsigned int      , NPY_UINT     , int)
+%numpy_typemaps(long              , NPY_LONG     , int)
+%numpy_typemaps(unsigned long     , NPY_ULONG    , int)
+%numpy_typemaps(long long         , NPY_LONGLONG , int)
+%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
+%numpy_typemaps(float             , NPY_FLOAT    , int)
+%numpy_typemaps(double            , NPY_DOUBLE   , int)
+
+/* ***************************************************************
+ * The follow macro expansion does not work, because C++ bool is 4
+ * bytes and NPY_BOOL is 1 byte
+ *
+ *    %numpy_typemaps(bool, NPY_BOOL, int)
+ */
+
+/* ***************************************************************
+ * On my Mac, I get the following warning for this macro expansion:
+ * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
+ *
+ *    %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
+ */
+
+#ifdef __cplusplus
+
+%include <std_complex.i>
+
+%numpy_typemaps(std::complex<float>,  NPY_CFLOAT , int)
+%numpy_typemaps(std::complex<double>, NPY_CDOUBLE, int)
+
+#endif
+
+#endif /* SWIGPYTHON */
diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index 39768eddbad6047e0251be34e6e97245af411f0d..3a8247b761fc0dadf99bc6aa1e372ec5f005e93b 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -6,38 +6,74 @@
   Version:   $Revision$
 
 
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
+  Copyright:
+    Centre National d'Etudes Spatiales,
+    CS Systemes d'information.
 
+ See OTBCopyright.txt, CSCopyright.txt for details.
+ All rights reserved.
 
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
 
 %module otbApplication
 
-
  %{
 #include "itkBase.includes"
 #include "otbWrapperSWIGIncludes.h"
- %}
+#include <string>         // std::string
+#include <locale>
+#define SWIG_FILE_WITH_INIT
+%}
 
 // Langage specific extension
 %include "Python.i"
 %include "Java.i"
 %include "Ruby.i"
 %include "Lua.i"
-
 %include "itkMacro.i"
 %include "itkBase.i"
 
+#if OTB_SWIGNUMPY
+%include "numpy.i"
+
+%init
+%{
+import_array();
+%}
+
+/*leave the mess to SWIG and let us not worry.*/
+%apply (signed char* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(signed char* buffer, int dim1, int dim2, int dim3)};
+%apply (signed short* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(signed short* buffer, int dim1, int dim2, int dim3)};
+%apply (signed int* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(signed int* buffer, int dim1, int dim2, int dim3)};
+%apply (signed long* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(signed long* buffer, int dim1, int dim2, int dim3)};
+%apply (float* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(float* buffer, int dim1, int dim2, int dim3)};
+%apply (unsigned char* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(unsigned char* buffer, int dim1, int dim2, int dim3)};
+%apply (unsigned short* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(unsigned short* buffer, int dim1, int dim2, int dim3)};
+%apply (unsigned int* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(unsigned int* buffer, int dim1, int dim2, int dim3)};
+%apply (unsigned long* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(unsigned long* buffer, int dim1, int dim2, int dim3)};
+%apply (double* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3) {(double* buffer, int dim1, int dim2, int dim3)};
+
+%apply (signed char** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(signed char** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (signed short** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(signed short** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (signed int** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(signed int** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (signed long** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(signed long** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (float** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(float** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (unsigned char** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(unsigned char** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (unsigned short** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(unsigned short** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (unsigned int** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(unsigned int** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (unsigned long** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(unsigned long** buffer, int *dim1, int *dim2, int *dim3)};
+%apply (double** ARGOUTVIEW_ARRAY3, int *DIM1, int *DIM2, int *DIM3) {(double** buffer, int *dim1, int *dim2, int *dim3)};
+
+#endif /* OTB_SWIGNUMPY */
+
 namespace otb
 {
 namespace Wrapper
 {
-
   enum DefaultValueMode
   {
     DefaultValueMode_UNKNOWN,
@@ -90,19 +126,20 @@ namespace Wrapper
     ImagePixelType_double,
   } ImagePixelType;
 
- typedef enum
- {
-   Role_Input,
-   Role_Output
- } Role;
+  typedef enum
+  {
+    Role_Input,
+    Role_Output
+  } Role;
 
- typedef enum
- {
-   ComplexImagePixelType_float,
-   ComplexImagePixelType_double,
- } ComplexImagePixelType;
+  typedef enum
+  {
+    ComplexImagePixelType_float,
+    ComplexImagePixelType_double,
+  } ComplexImagePixelType;
 
 }
+
 }
 
 class Application: public itkObject
@@ -120,11 +157,13 @@ public:
   int ExecuteAndWriteOutput();
 
   std::vector<std::string> GetParametersKeys(bool recursive = true);
+  Parameter* Application::GetParameterByKey(std::string name);
   std::string GetParameterName(std::string);
   std::string GetParameterDescription(std::string);
   void SetParameterDescription(std::string paramKey, std::string dec);
   void SetParameterUserValue(std::string paramKey, bool value);
 
+
   void EnableParameter(std::string paramKey);
   void DisableParameter(std::string paramKey);
   bool IsParameterEnabled(std::string paramKey) const;
@@ -153,7 +192,6 @@ public:
   void SetParameterStringList(std::string parameter, std::vector<std::string> values, bool hasUserValueFlag);
   void SetParameterEmpty(std::string parameter, bool value, bool hasUserValueFlag);
 
-
   void SetParameterOutputImagePixelType(std::string parameter, otb::Wrapper::ImagePixelType pixelType);
   void SetParameterComplexOutputImagePixelType(std::string parameter, otb::Wrapper::ComplexImagePixelType cpixelType);
 
@@ -184,6 +222,7 @@ public:
   void AddDocTag( const std::string & tag );
   std::vector<std::string> GetDocTags();
 
+  otb::Wrapper::ParameterGroup* GetParameterList();
 
   unsigned int GetNumberOfExamples();
   std::string GetExampleComment(unsigned int id);
@@ -199,6 +238,161 @@ public:
   std::string GetHtmlExample();
   std::vector< std::pair<std::string, std::string> > GetOutputParametersSumUp();
 
+#if OTB_SWIGNUMPY
+  %extend {
+
+#define SetFromNumpyArrayMacro(prefix, PixelDataType, ImageClass)       \
+      void Set##ImageClass##From##prefix##NumpyArray_(std::string pkey, ##PixelDataType##* buffer, int dim1, int dim2, int dim3) \
+      {                                                                 \
+        otb::Wrapper::Parameter *parameter = $self->GetParameterList()->GetParameterByKey(pkey); \
+        InputImageParameter* inputImageParam = dynamic_cast<InputImageParameter*>(parameter); \
+        typedef otb::##ImageClass##<##PixelDataType##>   ImageType;     \
+        typename ImageType::Pointer output = ImageType::New();          \
+        typedef typename ImageType::SizeType        SizeType;           \
+        typedef typename ImageType::IndexType       IndexType;          \
+        typedef typename ImageType::RegionType      RegionType;         \
+        typedef typename ImageType::PointType       PointType;          \
+        typedef typename ImageType::SpacingType     SpacingType;        \
+        typedef typename ImageType::DirectionType   DirectionType;      \
+        IndexType start;                                                \
+        DirectionType direction;                                        \
+        start.Fill( 0 );                                                \
+        SizeType size;                                                  \
+        size[0] = dim2; size[1] = dim1;                                 \
+        SetVectorLengthMacro                                            \
+        output->Allocate();                                             \
+        unsigned int numberOfPixels = dim1 * dim2 * dim3;               \
+        RegionType region;                                              \
+        region.SetIndex( start );                                       \
+        region.SetSize( size );                                         \
+        PointType origin;                                               \
+        origin.Fill( 0.0 );                                             \
+        SpacingType spacing;                                            \
+        spacing.Fill( 1.0 );                                            \
+        direction.SetIdentity();                                        \
+        output->SetOrigin( origin );                                    \
+        output->SetSpacing( spacing );                                  \
+        output->SetDirection(direction);                                \
+        output->SetLargestPossibleRegion(region);                       \
+        output->SetRequestedRegion(output->GetLargestPossibleRegion()); \
+        output->SetBufferedRegion(output->GetLargestPossibleRegion());  \
+        output->GetPixelContainer()->SetImportPointer(buffer, numberOfPixels, false); \
+        inputImageParam->SetImage<ImageType>(output);                   \
+  }
+
+#define SetVectorLengthMacro output->SetVectorLength(dim3);
+       SetFromNumpyArrayMacro(Float, float, VectorImage)
+       SetFromNumpyArrayMacro(Int8, signed char, VectorImage)
+       SetFromNumpyArrayMacro(Int16, signed short, VectorImage)
+       SetFromNumpyArrayMacro(Int32, signed int, VectorImage)
+       SetFromNumpyArrayMacro(Int64, signed long, VectorImage)
+       SetFromNumpyArrayMacro(UInt8, unsigned char, VectorImage)
+       SetFromNumpyArrayMacro(UInt16, unsigned short, VectorImage)
+       SetFromNumpyArrayMacro(UInt32, unsigned int, VectorImage)
+       SetFromNumpyArrayMacro(UInt64, unsigned long, VectorImage)
+       SetFromNumpyArrayMacro(Double, double, VectorImage)
+#undef SetVectorLengthMacro
+
+#define SetVectorLengthMacro dim3=1;
+       SetFromNumpyArrayMacro(Float, float, Image)
+       SetFromNumpyArrayMacro(Int8, signed char, Image)
+       SetFromNumpyArrayMacro(Int16, signed short, Image)
+       SetFromNumpyArrayMacro(Int32, signed int, Image)
+       SetFromNumpyArrayMacro(Int64, signed long, Image)
+       SetFromNumpyArrayMacro(UInt8, unsigned char, Image)
+       SetFromNumpyArrayMacro(UInt16, unsigned short, Image)
+       SetFromNumpyArrayMacro(UInt32, unsigned int, Image)
+       SetFromNumpyArrayMacro(UInt64, unsigned long, Image)
+       SetFromNumpyArrayMacro(Double, double, Image)
+#undef SetVectorLengthMacro
+#undef SetFromNumpyArrayMacro
+
+#define GetVectorImageAsNumpyArrayMacro(prefix, PixelType)                    \
+      void GetVectorImageAs##prefix##NumpyArray_(std::string pkey, ##PixelType##** buffer, int *dim1, int *dim2, int *dim3) \
+        {                                                               \
+        otb::Wrapper::Parameter *parameter = $self->GetParameterList()->GetParameterByKey(pkey); \
+        OutputImageParameter* outputImageParam = dynamic_cast<OutputImageParameter*>(parameter); \
+        typedef itk::ImageBase<2> ImageBaseType;                        \
+        typedef typename ImageBaseType::RegionType RegionType;          \
+        ImageBaseType::Pointer imageBase;                               \
+        imageBase = outputImageParam->GetValue();                       \
+        imageBase->Update();                                            \
+        typedef typename ImageBaseType::SizeType        SizeType;       \
+        typedef typename ImageBaseType::IndexType       IndexType;      \
+        typedef typename ImageBaseType::PointType       PointType;      \
+        typedef typename ImageBaseType::SpacingType     SpacingType;    \
+        RegionType region = imageBase->GetBufferedRegion();             \
+        SizeType size =  region.GetSize();                              \
+        *dim1 = size[1];                                                \
+        *dim2 = size[0];                                                \
+        typedef otb::VectorImage<signed char> Int8ImageType;            \
+        typedef otb::VectorImage<signed short> Int16ImageType;          \
+        typedef otb::VectorImage<signed int> Int32ImageType;            \
+        typedef otb::VectorImage<unsigned char> UInt8ImageType;         \
+        typedef otb::VectorImage<unsigned short> UInt16ImageType;       \
+        typedef otb::VectorImage<unsigned int> UInt32ImageType;         \
+        typedef otb::VectorImage<float> FloatImageType;                 \
+        typedef otb::VectorImage<double> DoubleImageType;               \
+        if (dynamic_cast<UInt8ImageType*>(imageBase.GetPointer()))      \
+          {                                                             \
+            UInt8ImageType* output = dynamic_cast<UInt8ImageType*>(imageBase.GetPointer()); \
+            *buffer  =  reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else if (dynamic_cast<Int16ImageType*>(imageBase.GetPointer())) \
+          {                                                             \
+            Int16ImageType* output = dynamic_cast<Int16ImageType*>(imageBase.GetPointer()); \
+            *buffer  =  reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else if (dynamic_cast<UInt16ImageType*>(imageBase.GetPointer())) \
+          {                                                             \
+            UInt16ImageType* output = dynamic_cast<UInt16ImageType*>(imageBase.GetPointer()); \
+            *buffer  =  reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else if (dynamic_cast<Int32ImageType*>(imageBase.GetPointer())) \
+          {                                                             \
+            Int32ImageType* output = dynamic_cast<Int32ImageType*>(imageBase.GetPointer()); \
+            *buffer  =  reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else if (dynamic_cast<UInt32ImageType*>(imageBase.GetPointer())) \
+          {                                                             \
+            UInt32ImageType* output = dynamic_cast<UInt32ImageType*>(imageBase.GetPointer()); \
+            *buffer = reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else if (dynamic_cast<FloatImageType*>(imageBase.GetPointer())) \
+          {                                                             \
+            FloatImageType* output = dynamic_cast<FloatImageType*>(imageBase.GetPointer()); \
+            *buffer  =  reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else if (dynamic_cast<DoubleImageType*>(imageBase.GetPointer())) \
+          {                                                             \
+            DoubleImageType* output = dynamic_cast<DoubleImageType*>(imageBase.GetPointer()); \
+            *buffer  =  reinterpret_cast<##PixelType##*>(output->GetBufferPointer()); \
+              *dim3 = output->GetNumberOfComponentsPerPixel();          \
+          }                                                             \
+        else                                                            \
+          {                                                             \
+            std::cerr << "unknown image type. cannot make a numpy array" << std::endl; \
+          }                                                             \
+      }
+
+       GetVectorImageAsNumpyArrayMacro(Float, float)
+       GetVectorImageAsNumpyArrayMacro(Int16, signed short)
+       GetVectorImageAsNumpyArrayMacro(Int32, signed int)
+       GetVectorImageAsNumpyArrayMacro(UInt8, unsigned char)
+       GetVectorImageAsNumpyArrayMacro(UInt16, unsigned short)
+       GetVectorImageAsNumpyArrayMacro(UInt32, unsigned int)
+       GetVectorImageAsNumpyArrayMacro(Double, double)
+#undef GetVectorImageAsNumpyArrayMacro
+
+} /* end of %extend */
+#endif /* OTB_SWIGNUMPY */
+
 protected:
   Application();
 #if SWIGJAVA
@@ -208,57 +402,351 @@ private:
   Application(const Application &);
   void operator =(const Application&);
 };
+
 DECLARE_REF_COUNT_CLASS( Application )
 
+
+    /* Int8 Int16 Int32 Int64 */
+    /* UInt8 UInt16 UInt32 UInt64 */
+    /* Float32 Double64 */
+    /* Complex32 Complex64 */
+
+    /* typedef signed char       Int8; */
+    /* typedef signed short      Int16; */
+    /* typedef signed int        Int32; */
+    /* typedef signed long      Int64; */
+    /* typedef unsigned char     UInt8; */
+    /* typedef unsigned short    UInt16; */
+    /* typedef unsigned int      UInt32; */
+    /* typedef unsigned long     UInt64; */
+    /* typedef float Float32; */
+    /* typedef double Float64; */
+
 #if SWIGPYTHON
+%pythoncode {
+import sys
+
+class ApplicationProxy(object):
+  def __init__(self, application, groupkey, value = None):
+    self.__dict__["application"] = application
+    self.__dict__["groupkey"] = groupkey
+    if value is not None:
+      self.__dict__["application"].SetParameterString(groupkey, value)
+
+  def __str__(self):
+      return self.__dict__["application"].GetParameterAsString(self.groupkey)
+
+  def __eq__(self, other):
+    if not type(other) == type(self):
+			return (self.__str__() == other)
+    else:
+			return (isinstance(other, self.__class__) and self.__dict__ == other.__dict__)
+
+  def __ne__(self, other):
+    return not self.__eq__(other)
+
+  def __getattr__(self,attr):
+    return self.__dict__["application"].GetParameterValue( self.groupkey + "." + attr.lower() )
+
+  def __setattr__(self,attr,value):
+    if attr not in self.__dict__:
+        return self.__dict__["application"].SetParameterValue( self.groupkey + "." + attr.lower(), value )
+    else:
+        return dict.__setattr__(self, attr, value)
+
+
+}
+#endif
+
+#if SWIGPYTHON
+/*Maybe TODO: change use a dict to  GetParameterTypeAsString */
+
 %extend Application {
   %pythoncode {
-    def GetParameterValue(self, paramKey):
-       paramType = self.GetParameterType(paramKey)
-       if paramType in [ParameterType_InputProcessXML, ParameterType_Choice,
-                        ParameterType_String, ParameterType_InputFilename,
-                        ParameterType_OutputImage, ParameterType_OutputVectorData,
-                        ParameterType_OutputProcessXML, ParameterType_OutputFilename,
-                        ParameterType_Directory, ParameterType_InputImage,
-                        ParameterType_ComplexInputImage, ParameterType_InputVectorData]:
-          return self.GetParameterString(paramKey)
-
-       elif paramType in [ ParameterType_InputImageList, ParameterType_InputVectorDataList,
-                        ParameterType_InputFilenameList, ParameterType_StringList,
-                        ParameterType_ListView]:
-          return self.GetParameterStringList(paramKey)
-
-       elif paramType in [ParameterType_Int, ParameterType_Radius, ParameterType_RAM]:
-          return self.GetParameterInt(paramKey)
-
-       elif paramType in [ParameterType_Float]:
-          return self.GetParameterFloat(paramKey)
-
-       elif paramType in [ParameterType_Empty]:
-          return self.IsParameterEnabled(paramKey)
-
-       else:
-          print "Unsupported parameter type for '" + paramKey  + "'"
-          return None
+
+		def __str__(self):
+			s  = self.GetDocName()
+
+		def GetParameterTypeAsString(self, parameter_type):
+			return {
+			ParameterType_InputProcessXML : 'ParameterType_InputProcessXML',
+      ParameterType_String : 'ParameterType_String',
+      ParameterType_InputFilename : 'ParameterType_InputFilename',
+      ParameterType_OutputImage : 'ParameterType_OutputImage',
+      ParameterType_OutputVectorData : 'ParameterType_OutputVectorData',
+      ParameterType_OutputProcessXML : 'ParameterType_OutputProcessXML',
+      ParameterType_OutputFilename : 'ParameterType_OutputFilename',
+      ParameterType_Directory : 'ParameterType_Directory',
+      ParameterType_InputImage : 'ParameterType_InputImage',
+      ParameterType_ComplexInputImage : 'ParameterType_ComplexInputImage',
+      ParameterType_InputVectorData : 'ParameterType_InputVectorData',
+      ParameterType_InputImageList : 'ParameterType_InputImageList',
+      ParameterType_InputVectorDataList : 'ParameterType_InputImageList',
+      ParameterType_InputFilenameList : 'ParameterType_InputFilenameList',
+      ParameterType_StringList : 'ParameterType_StringList',
+      ParameterType_ListView : 'ParameterType_ListView',
+      ParameterType_Int : 'ParameterType_Int',
+      ParameterType_Radius : 'ParameterType_Radius',
+      ParameterType_RAM : 'ParameterType_RAM',
+      ParameterType_Float : 'ParameterType_Float',
+      ParameterType_Empty : 'ParameterType_Empty',
+      ParameterType_Choice : 'ParameterType_Choice',
+      ParameterType_Group : 'ParameterType_Group',
+      }.get(parameter_type, 'ParameterType_UNKNOWN')
+
+
+		def __str__(self):
+			s  = self.GetDocName()
+			s += '\n'
+			s += self.GetDocLongDescription()
+			return s
+
+		def SetParameterValue(self, paramKey, value):
+		  paramType = self.GetParameterType(paramKey)
+		  if paramType in [ParameterType_InputProcessXML, ParameterType_RAM,
+    									 ParameterType_String, ParameterType_InputFilename,
+    									 ParameterType_OutputImage, ParameterType_OutputVectorData,
+    									 ParameterType_OutputProcessXML, ParameterType_OutputFilename,
+    									 ParameterType_Directory, ParameterType_InputImage,
+    									 ParameterType_ComplexInputImage, ParameterType_InputVectorData]:
+		    return self.SetParameterString(paramKey, value)
+		  elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
+    										 ParameterType_InputFilenameList, ParameterType_StringList,
+    										 ParameterType_ListView]:
+		    return self.setParameterStringList(paramKey, value)
+		  elif paramType in [ParameterType_Int, ParameterType_Radius]:
+		    return self.SetParameterInt(paramKey, value)
+		  elif paramType in [ParameterType_Float]:
+		    return self.SetParameterFloat(paramKey, value)
+		  elif paramType in [ParameterType_Empty]:
+		    return self.EnableParameter(paramKey)
+		  elif paramType in [ParameterType_Group]:
+		    return ApplicationProxy(self, paramKey)
+		  elif paramType in [ParameterType_Choice]:
+		    return ApplicationProxy(self, paramKey, value)
+		  else:
+		    print "Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey)
+		  return
+
+		def GetParameterValue(self, paramKey):
+		  paramType = self.GetParameterType(paramKey)
+		  if paramType in [ParameterType_InputProcessXML,
+    									 ParameterType_String, ParameterType_InputFilename,
+    									 ParameterType_OutputImage, ParameterType_OutputVectorData,
+    									 ParameterType_OutputProcessXML, ParameterType_OutputFilename,
+    									 ParameterType_Directory, ParameterType_InputImage,
+    									 ParameterType_ComplexInputImage, ParameterType_InputVectorData]:
+		    return self.GetParameterString(paramKey)
+		  elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
+    										 ParameterType_InputFilenameList, ParameterType_StringList,
+    										 ParameterType_ListView]:
+		    return self.GetParameterStringList(paramKey)
+		  elif paramType in [ParameterType_Int, ParameterType_Radius, ParameterType_RAM]:
+		    return self.GetParameterInt(paramKey)
+		  elif paramType in [ParameterType_Float]:
+		    return self.GetParameterFloat(paramKey)
+		  elif paramType in [ParameterType_Empty]:
+		    return self.IsParameterEnabled(paramKey)
+		  elif paramType in [ParameterType_Group, ParameterType_Choice]:
+		    return ApplicationProxy(self, paramKey)
+		  else:
+		    print "Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey)
+		  return None
+
+		def __getattr__(self,attr):
+		  """
+		  __get_attribute__ is called whenever an instance request an attribute.
+		  eg: App.SetParameterString(), App.GetName() ..
+		  __getattr__ is only called if the attribute is not found by __get_attribute__ call
+		  So we keep hide the GetParameter** calls within this method so that it seems like
+		  an obivous call for users. App.IN , App.OUT , where 'in' and 'out' are
+		  parameters in the 'otb application' with instance App
+		  """
+		  if attr is not None:
+		    key_list = [k.upper() for k in self.GetParametersKeys(True)]
+		    if attr in key_list:
+		      return self.GetParameterValue(attr.lower())
+		    else:
+		      raise AttributeError
+
+		def __setattr__(self, attr, value):
+		  """
+		  __setattr__ is called if the attribute requested is not found in the attribute list.
+		  So these attributes are supposed to be 'key' of parameters used. Here we
+		  keep hide the SetParameter** calls within this method so that it seems like
+		  an obivous call for users. App.IN='my-input-file-name' , App.OUT='my-output-file-name'w
+		  here 'in' and 'out' are    parameters in the 'otb application' with instance App
+		  Ofcourse, we dont blindly accept any attributes as python, we check them against
+		  list of existing parameters for application with 'self.GetParametersKeys(True)'
+		  """
+		  if attr is not None:
+		    key_list = [k.upper() for k in self.GetParametersKeys(True)]
+		    if attr in key_list:
+		      self.SetParameterValue(attr.lower(), value)
+		    else:
+		      raise AttributeError
       }
 }
 #endif
 
+#if OTB_SWIGNUMPY
+%extend Application {
+  %pythoncode {
+
+    def SetImageFromNumpyArray(self, paramKey, npArray):
+      """
+      This method takes a numpy array and set ImageIOBase of
+      InputImageParameter by creating an otbImage with
+      same pixel type as numpyarray.dtype
+      """
+      if len(npArray.shape) == 3:
+         raise ValueError( "(len(npArray.shape) == 3)\n"
+													"Input array given is of 3 dimension.\n"
+													"SetImageFromNumpyArray create ImageIO from otbImage and thus demands a 2d array.\n"
+													"you can either provide an 2d numpy array or use SetVectorImageFromNumpyArray depending on your application.\n")
+
+      dt = npArray.dtype.name
+      if dt == 'int8':
+        self.SetImageFromInt8NumpyArray_(paramKey, npArray)
+      elif dt == 'int16':
+        self.SetImageFromInt16NumpyArray_(paramKey, npArray)
+      elif dt == 'int32':
+        self.SetImageFromInt32NumpyArray_(paramKey, npArray)
+      elif dt == 'uint8':
+        self.SetImageFromUInt8NumpyArray_(paramKey, npArray)
+      elif dt == 'uint16':
+        self.SetImageFromUInt16NumpyArray_(paramKey, npArray)
+      elif dt == 'uint32':
+        self.SetImageFromUInt32NumpyArray_(paramKey, npArray)
+      elif dt == 'float':
+        self.SetImageFromFloatNumpyArray_(paramKey, npArray)
+      elif dt == 'double':
+        self.SetImageFromDoubleNumpyArray_(paramKey, npArray)
+      else:
+        self.SetImageFromFloatNumpyArray_(paramKey, npArray)
+      return
+
+    def SetVectorImageFromNumpyArray(self, paramKey, npArray):
+      """
+      This method takes a numpy array and set ImageIOBase of
+      InputImageParameter by creating an otbVectorImage with
+      same pixel type as numpyarray.dtype.
+      NOTE: Input (npArray) must be an ndarray with 3 dimension,
+      len(npArray.shape) must be > 2
+      """
+      if len(npArray.shape) < 3:
+        raise ValueError( "(len(npArray.shape) < 3)\n"
+													"Input array given is not of 3 dimension.\n"
+													"SetVectorImageFromNumpyArray create ImageIO from otbVectorImage and thus demands an array of shape 3.\n"
+													"you can either provide an 3d numpy array or use SetImageFromNumpyArray depending on your application.\n")
+
+      dt = npArray.dtype.name
+      if dt == 'int8':
+        self.SetVectorImageFromInt8NumpyArray_(paramKey, npArray)
+      elif dt == 'int16':
+        self.SetVectorImageFromInt16NumpyArray_(paramKey, npArray)
+      elif dt == 'int32':
+        self.SetVectorImageFromInt32NumpyArray_(paramKey, npArray)
+      elif dt == 'uint8':
+        self.SetVectorImageFromUInt8NumpyArray_(paramKey, npArray)
+      elif dt == 'uint16':
+        self.SetVectorImageFromUInt16NumpyArray_(paramKey, npArray)
+      elif dt == 'uint32':
+        self.SetVectorImageFromUInt32NumpyArray_(paramKey, npArray)
+      elif dt == 'float':
+        self.SetVectorImageFromFloatNumpyArray_(paramKey, npArray)
+      elif dt == 'double':
+        self.SetVectorImageFromDoubleNumpyArray_(paramKey, npArray)
+      else:
+        self.SetVectorImageFromFloatNumpyArray_(paramKey, npArray)
+      return
+
+    def GetVectorImageAsNumpyArray(self, paramKey, dt='float'):
+      """
+      If datatype is unknown this method assumes to numpy.float32
+      Valid datatypes are:
+      int8, int16, int32, uint8, uint16, uint32, float, double.
+      NOTE: This method always return an numpy array with dimension 3
+      """
+      if dt == 'int8':
+        return self.GetVectorImageAsInt8NumpyArray_(paramKey)
+      elif dt == 'int16':
+        return self.GetVectorImageAsInt16NumpyArray_(paramKey)
+      elif dt == 'int32':
+        return self.GetVectorImageAsInt32NumpyArray_(paramKey)
+      elif dt == 'uint8':
+        return self.GetVectorImageAsUInt8NumpyArray_(paramKey)
+      elif dt == 'uint16':
+        return self.GetVectorImageAsUInt16NumpyArray_(paramKey)
+      elif dt == 'uint32':
+        return self.GetVectorImageAsUInt32NumpyArray_(paramKey)
+      elif dt == 'float':
+        return self.GetVectorImageAsFloatNumpyArray_(paramKey)
+      elif dt == 'double':
+        return self.GetVectorImageAsDoubleNumpyArray_(paramKey)
+      else:
+        print "Unknown datatype '" + dt + "'. Using float instead. Available types are:"
+        print "int8, int16, int32, uint8, uint16, uint32, float, double"
+        return self.GetVectorImageAsFloatNumpyArray_(paramKey)
+
+    def GetImageAsNumpyArray(self, paramKey, dt='float'):
+      """
+      If datatype is unknown this method assumes to numpy.float32
+      Valid datatypes are:
+      int8, int16, int32, uint8, uint16, uint32, float, double.
+      NOTE: This method always return an numpy array with dimension 3
+      """
+      if dt == 'int8':
+        numpy_vector_image = self.GetVectorImageAsInt8NumpyArray_(paramKey)
+      elif dt == 'int16':
+        numpy_vector_image = self.GetVectorImageAsInt16NumpyArray_(paramKey)
+      elif dt == 'int32':
+        numpy_vector_image = self.GetVectorImageAsInt32NumpyArray_(paramKey)
+      elif dt == 'uint8':
+        numpy_vector_image = self.GetVectorImageAsUInt8NumpyArray_(paramKey)
+      elif dt == 'uint16':
+        numpy_vector_image = self.GetVectorImageAsUInt16NumpyArray_(paramKey)
+      elif dt == 'uint32':
+        numpy_vector_image = self.GetVectorImageAsUInt32NumpyArray_(paramKey)
+      elif dt == 'float':
+        numpy_vector_image = self.GetVectorImageAsFloatNumpyArray_(paramKey)
+      elif dt == 'double':
+        numpy_vector_image = self.GetVectorImageAsDoubleNumpyArray_(paramKey)
+
+      else:
+        print "Unknown datatype '" + dt + "'. Using float instead. Available types are:"
+        print "int8, int16, int32, uint8, uint16, uint32, float, double"
+        numpy_vector_image = self.GetVectorImageAsFloatNumpyArray_(paramKey)
+
+      if len(numpy_vector_image.shape) > 2:
+        raise ValueError("len(numpy_vector_image.shape) > 2\n"
+                         "Output image from application is of 3 dimension (len(nparray.shape) > 2). \n"
+                         "GetImageFromNumpyArray returns an numpy array of dimension 2 that will result is loss of data.\n"
+                         "In this case you must use GetVectorImageFromNumpyArray which is capable of return a 3 dimension image.\n")
+
+      numpy_vector_image = numpy_vector_image[:,:,1]
+      return numpy_vector_image
+
+    }
+}
+
+#endif /* OTB_SWIGNUMPY */
+
+
 class Registry : public itkObject
 {
 public:
+
   static std::vector<std::string> GetAvailableApplications();
   static Application_Pointer CreateApplication(const std::string& name);
   static void AddApplicationPath(std::string newpath);
   static void SetApplicationPath(std::string newpath);
 
-
 protected:
   Registry();
   virtual ~Registry();
 };
 
-
 class AddProcessToWatchEvent : public itkEventObject
 {
 public:
diff --git a/Modules/Wrappers/SWIG/src/otbWrapperSWIGIncludes.h b/Modules/Wrappers/SWIG/src/otbWrapperSWIGIncludes.h
index 3bf30746dcf81c1f9b8633c7152a4f0fdccd6f6c..80459d30c634d15b49e5f5fe345e9f2e27991c94 100644
--- a/Modules/Wrappers/SWIG/src/otbWrapperSWIGIncludes.h
+++ b/Modules/Wrappers/SWIG/src/otbWrapperSWIGIncludes.h
@@ -6,13 +6,16 @@
   Version:   $Revision$
 
 
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
+  Copyright:
+    Centre National d'Etudes Spatiales,
+    CS Systemes d'information.
 
+ See OTBCopyright.txt, CSCopyright.txt for details.
+ All rights reserved.
 
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notices for more information.
 
 =========================================================================*/
 #ifndef __otbWrapperSWIGIncludes_h
@@ -27,5 +30,7 @@ typedef otb::Wrapper::Application::Pointer               Application_Pointer;
 typedef otb::Wrapper::ApplicationRegistry                Registry;
 typedef otb::Wrapper::AddProcessToWatchEvent             AddProcessToWatchEvent;
 typedef otb::Wrapper::DocExampleStructure                DocExampleStructure;
-
+typedef otb::Wrapper::Parameter                          Parameter;
+typedef otb::Wrapper::OutputImageParameter               OutputImageParameter;
+typedef otb::Wrapper::InputImageParameter                InputImageParameter;
 #endif
diff --git a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
index e51c82f85da0a7b73c9dc8c0ad552ca388706733..2eb46785fb95436f872bfec5c724d7070f1ce62b 100644
--- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
@@ -72,3 +72,14 @@ add_test( NAME pyTvBandMathInXML
                   ${TEMP}/pyTvBandMathInXML.tif
                   )
 
+add_test( NAME pyTvNumpyIO
+          COMMAND ${TEST_DRIVER} Execute
+                  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonNumpyTest.py
+                  ${OTB_DATA_ROOT}/Examples/ROI_QB_MUL_1_SVN_CLASS_MULTI.png
+                  ${TEMP}/pyTvNumpyIO_SmoothingOut.png )
+
+add_test( NAME pyTvNewStyleParameters
+          COMMAND ${TEST_DRIVER} Execute
+          ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonNewStyleParametersTest.py
+          ${OTB_DATA_ROOT}/Input/poupees.tif
+          ${TEMP}/pyTvNewStyleParametersTest.tif )
diff --git a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f15b51ec972a06578b4ac2b91f3f52955bcb972
--- /dev/null
+++ b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+# Authors: Rashad Kanavath <rashad.kanavath@c-s.fr>
+#          Julien Malik <julien.malik@c-s.fr>
+#
+# Copyright: (c) CS Systemes d'information. All rights reserved
+#
+#  Example on the use of otb "pythonization"
+#
+from sys import argv
+import otbApplication as otb
+
+def cm_assert(a,b):
+	print "debug print before assert check: '%s'== '%s'" %(a, b)
+	assert a == b
+
+app = otb.Registry.CreateApplication('OrthoRectification')
+
+#test GetParameterTypeAsString() method in python.
+print app.GetParameterTypeAsString(otb.ParameterType_InputImage)
+print app.GetParameterTypeAsString(otb.ParameterType_String)
+print app.GetParameterTypeAsString(otb.ParameterType_Empty)
+
+# one test for each parameter type (string, float, int, ...)
+
+# # parameter group io.in
+# 1 - input image parameter set
+app.IO.IN = argv[1]
+cm_assert(app.GetParameterString('io.in'), argv[1])
+
+# 2 - input image parameter get
+cm_assert(app.IO.IN, argv[1])
+
+# # parameter group io.in
+# 3 - output image parameter set
+app.IO.OUT = argv[2]
+cm_assert(app.GetParameterString('io.out'), argv[2])
+
+# 4 - output image parameter get
+cm_assert(app.IO.OUT, argv[2])
+
+# 5 - choice with sub parameters set
+app.MAP = 'lambert2'
+cm_assert(app.GetParameterString('map'), 'lambert2')
+
+# 5.1 - choice with sub parameters get
+app.SetParameterString('map', 'wgs')
+cm_assert('wgs', app.MAP)
+
+# 5.2 - choice with sub parameters set
+app.MAP = 'lambert93'
+cm_assert('lambert93', app.GetParameterString('map'))
+
+# 5.3 - choice with sub parameters set
+app.SetParameterString('map', 'epsg')
+cm_assert(app.MAP, 'epsg')
+
+# 6 - int type 2nd level sub parameters of choice parameter set
+app.MAP.EPSG.CODE = 32768
+cm_assert(32768, app.GetParameterInt('map.epsg.code'))
+
+# 7 - another choice with sub parameters set
+app.MAP = 'utm'
+cm_assert('utm', app.GetParameterString('map'))
+
+# 8 - int type sub parameters of choice parameter set
+app.MAP.UTM.ZONE = 47
+cm_assert(47,app.GetParameterInt('map.utm.zone'))
+
+# 9 - int type sub parameters of choice parameter get
+app.SetParameterInt('map.utm.zone', 31)
+cm_assert(app.MAP.UTM.ZONE, 31)
+
+# 10 - bool type sub parameters of choice parameter get
+app.DisableParameter('map.utm.northhem')
+cm_assert(app.MAP.UTM.NORTHHEM, False)
+
+# 11 - bool type sub parameters of choice parameter set
+app.MAP.UTM.NORTHHEM = True
+cm_assert(True, app.IsParameterEnabled('map.utm.northhem') )
+
+#12 - simple choice parameter set
+app.OUTPUTS.MODE = 'auto'
+cm_assert('auto', app.GetParameterString('outputs.mode'))
+
+#13 - simple choice parameter get
+app.SetParameterString('outputs.mode', 'orthofit')
+cm_assert(app.OUTPUTS.MODE, 'orthofit')
+
+#14 - inputxml parameter set
+app.INXML = 'input.xml'
+cm_assert(app.GetParameterString('inxml'), 'input.xml')
+
+#15 - outputxml parameter get
+app.SetParameterString('outxml', 'output.xml')
+cm_assert("output.xml", app.OUTXML)
+
+#16 - parameter float get
+app.SetParameterFloat('elev.default', 5.0)
+cm_assert(5.0, app.ELEV.DEFAULT)
+
+#17 -parameter float set
+app.ELEV.DEFAULT = -2.5
+cm_assert(app.GetParameterFloat('elev.default'), -2.5)
+
+#18 - parameter ram get
+app.SetParameterString('opt.ram', '256')
+cm_assert(256, app.OPT.RAM)
+
+#19 - parameter ram set
+app.OPT.RAM = '512'
+cm_assert(app.GetParameterInt('opt.ram'), 512)
+
+#20 - parameter bool set
+app.OUTPUTS.ISOTROPIC = True
+cm_assert(app.IsParameterEnabled('outputs.isotropic'), True)
+
+#21 - parameter bool get
+app.DisableParameter('outputs.isotropic')
+cm_assert(False, app.OUTPUTS.ISOTROPIC)
+
+#Do not execute. we need LARGEINPUT. so we tried a small application
+#app.Execute()
+
+app = None
+
+app = otb.Registry.CreateApplication('Smoothing')
+app.IN = argv[1]
+app.TYPE='anidif'
+app.OUT = argv[2]
+app.ExecuteAndWriteOutput()
diff --git a/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py b/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..7aee4e2a5d11fd8bfb2d2c2c0d99d30190a6d0cb
--- /dev/null
+++ b/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Author: Rashad Kanavath <rashad.kanavath@c-s.fr>
+#
+# Copyright: (c) CS Systemes d'information. All rights reserved
+#
+#  Example on testing numpy
+#
+
+import sys
+import os
+#from scipy import misc
+
+import numpy as np
+import otbApplication
+
+#from PIL import Image as PILImage
+
+inFile  = sys.argv[1]
+outFile = sys.argv[2]
+# pilimage = PILImage.open(inFile)
+# npimage = np.asarray(pilimage)
+# print npimage.dtype
+
+ExtractROI = otbApplication.Registry.CreateApplication("ExtractROI")
+ExtractROI.SetParameterString("in", inFile)
+ExtractROI.SetParameterInt("startx", 10)
+ExtractROI.SetParameterInt("starty", 10)
+ExtractROI.SetParameterInt("sizex", 250)
+ExtractROI.SetParameterInt("sizey", 250)
+
+#Bug or Design ?.
+#Anyway below two is needed only for ExtractROI application
+ExtractROI.SetParameterUserValue("sizex", True)
+ExtractROI.SetParameterUserValue("sizey", True)
+ExtractROI.Execute()
+
+ExtractROIOut = ExtractROI.GetVectorImageAsNumpyArray("out", 'float')
+
+#write RGB image to file via python
+#misc.imsave('ExtractROIOut.jpg', ExtractROIOut)
+
+Rescale = otbApplication.Registry.CreateApplication("Rescale")
+#take numpy array from ExtractROI and feed into Rescale
+Rescale.SetVectorImageFromNumpyArray("in", ExtractROIOut)
+Rescale.SetParameterFloat("outmin", 50, True)
+Rescale.SetParameterFloat("outmax", 100, True)
+Rescale.Execute()
+
+RescaleOut = Rescale.GetVectorImageAsNumpyArray("out", 'float')
+#misc.imsave('RescaleOut.jpg', RescaleOut)
+
+Convert = otbApplication.Registry.CreateApplication("Convert")
+#take numpy output from Rescale application and feed into Convert
+Convert.SetVectorImageFromNumpyArray("in", RescaleOut)
+Convert.SetParameterString("out", "ConvertOut.png")
+Convert.ExecuteAndWriteOutput()
+ConvertOut = Convert.GetVectorImageAsNumpyArray("out", 'float')
+
+Smoothing = otbApplication.Registry.CreateApplication("Smoothing")
+#take numpy output from Convert application and feed into Smoothing
+Smoothing.SetVectorImageFromNumpyArray("in", ConvertOut)
+Smoothing.SetParameterString("type", 'anidif')
+Smoothing.SetParameterString("out", outFile)
+Smoothing.ExecuteAndWriteOutput()
diff --git a/SuperBuild/CMake/External_ossim.cmake b/SuperBuild/CMake/External_ossim.cmake
index 2222495018c21c4bd0dbadea243996f101d5d867..7303c9f9c0659c00f784c05526cb4530d180fd99 100644
--- a/SuperBuild/CMake/External_ossim.cmake
+++ b/SuperBuild/CMake/External_ossim.cmake
@@ -17,14 +17,14 @@ if(USE_SYSTEM_OSSIM)
 else()
   SETUP_SUPERBUILD(PROJECT ${proj})
   message(STATUS "  Using OSSIM SuperBuild version")
-  
+
   # declare dependencies
   ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(${proj} TIFF GEOTIFF GEOS JPEG OPENTHREADS FREETYPE)
 
   INCLUDE_SUPERBUILD_DEPENDENCIES(${${proj}_DEPENDENCIES})
   # set proj back to its original value
   set(proj OSSIM)
-  
+
   ADD_SUPERBUILD_CMAKE_VAR(TIFF_INCLUDE_DIR)
   ADD_SUPERBUILD_CMAKE_VAR(TIFF_LIBRARY)
   ADD_SUPERBUILD_CMAKE_VAR(GEOTIFF_INCLUDE_DIR)
@@ -39,16 +39,16 @@ else()
   ADD_SUPERBUILD_CMAKE_VAR(FREETYPE_LIBRARY)
 
   set(OSSIM_CXX_FLAGS  -D__STDC_CONSTANT_MACROS)
-  
+
   if(MSVC)
     set(OSSIM_CXX_FLAGS /EHsc)
   endif()
-  
+
   # archive version
   ExternalProject_Add(${proj}
     PREFIX ${proj}
     URL "https://www.orfeo-toolbox.org/packages/ossim-minimal-r23537.tar.gz"
-    URL_MD5 1a37403053711447a8f174bb875cca6b
+    URL_MD5 f77d574ab2817bcc36633f77824facb5
     BINARY_DIR ${OSSIM_SB_BUILD_DIR}
     INSTALL_DIR ${SB_INSTALL_PREFIX}
     DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
@@ -70,14 +70,14 @@ else()
     DEPENDS ${${proj}_DEPENDENCIES}
     CMAKE_COMMAND ${SB_CMAKE_COMMAND}
     )
-  
+
   set(_SB_${proj}_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
   if(WIN32)
     set(_SB_${proj}_LIBRARY ${SB_INSTALL_PREFIX}/lib/ossim.lib)
   elseif(UNIX)
     set(_SB_${proj}_LIBRARY ${SB_INSTALL_PREFIX}/lib/libossim${CMAKE_SHARED_LIBRARY_SUFFIX})
   endif()
-  
+
 endif()
 
 endif()