text:
#ifndef otbLandsatTMIndices_h
#define otbLandsatTMIndices_h

#include "otbMath.h"
#include "otbBandName.h"
#include "itkVariableLengthVector.h"
#include "otbFuzzyVariable.h"
#include <vector>
#include <algorithm>
#include <string>

namespace otb
{

namespace Functor
{

namespace LandsatTM
{

/// Landsat 5 or 7
enum SATType
{
  L5,
  L7
};
/// Thermal band in Kelvin or Celsius
enum DegreeType
{
  Kelvin,
  HundredsKelvin,
  Celsius
};
/// Reflectances in thousands or in (0-1)
enum ReflectanceType
{
  Thousands,
  Normalized
};
/**
   * \class LandsatTMIndexBase
   * \brief Base class for Landsat-TM indices
   *
   *  Implement operators for UnaryFunctorImageFilter templated with a
   *  vector pixel having 8 components. The order of the components
   *  defaults to the one of Lansat 7, but the Landsat 5 order is also
   *  available. Any other order of bands can be manually selected.
   *  Subclasses should overload operator(). This class assumes
   *  that the input image is calibrated in reflectances and in
   *  temperature. The reflectances can be given in the 0-1 range
   *  (Normalized) or in 0-1000 (Thousands). Temperatures can be given
   *  in Kelvin, in Kelvin*100 or in Celsius. Appropriate accessors
   *  are available for setting these units.
   *
   * \ingroup Radiometry
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class LandsatTMIndexBase
{
public:
  // operators !=
  bool operator!=(const LandsatTMIndexBase&) const
  {
    return false;
  }
  // operator ==
  bool operator==(const LandsatTMIndexBase& other) const
  {
    return !(*this != other);
  }

  /// Constructor
  LandsatTMIndexBase()
    : m_EpsilonToBeConsideredAsZero(0.0000001),
      m_TM1(0),
      m_TM2(1),
      m_TM3(2),
      m_TM4(3),
      m_TM5(4),
      m_TM60(5),
      m_TM61(5),
      m_TM62(6),
      m_TM7(7),
      m_SAT(L7),
      m_Degree(Celsius),
      m_Reflectance(Normalized)
  {
  }
  /// Destructor
  virtual ~LandsatTMIndexBase()
  {
  }

  /** Set index, generic method */
  void SetIndex(BandName::LandsatTMBandNames band, unsigned int channel)
  {
    switch (band)
    {
    case BandName::TM1:
      m_TM1 = channel;
      break;
    case BandName::TM2:
      m_TM2 = channel;
      break;
    case BandName::TM3:
      m_TM3 = channel;
      break;
    case BandName::TM4:
      m_TM4 = channel;
      break;
    case BandName::TM5:
      m_TM5 = channel;
      break;
    case BandName::TM60:
      m_TM60 = channel;
      break;
    case BandName::TM61:
      m_TM61 = channel;
      break;
    case BandName::TM62:
      m_TM62 = channel;
      break;
    case BandName::TM7:
      m_TM7 = channel;
      break;
    }
  }
  /** Get index, generic method */
  unsigned int GetIndex(BandName::LandsatTMBandNames band) const
  {
    switch (band)
    {
    case BandName::TM1:
      return m_TM1;
      break;
    case BandName::TM2:
      return m_TM2;
      break;
    case BandName::TM3:
      return m_TM3;
      break;
    case BandName::TM4:
      return m_TM4;
      break;
    case BandName::TM5:
      return m_TM5;
      break;
    case BandName::TM60:
      return m_TM60;
      break;
    case BandName::TM61:
      return m_TM61;
      break;
    case BandName::TM62:
      return m_TM62;
      break;
    case BandName::TM7:
      return m_TM7;
      break;
    }
    return m_TM1;
  }

  unsigned int GetTM1() const
  {
    return this->m_TM1;
  }

  unsigned int GetTM2() const
  {
    return this->m_TM2;
  }

  unsigned int GetTM3() const
  {
    return this->m_TM3;
  }

  unsigned int GetTM4() const
  {
    return this->m_TM4;
  }

  unsigned int GetTM5() const
  {
    return this->m_TM5;
  }

  unsigned int GetTM60() const
  {
    return this->m_TM60;
  }

  unsigned int GetTM61() const
  {
    return this->m_TM61;
  }

  unsigned int GetTM62() const
  {
    return this->m_TM62;
  }

  unsigned int GetTM7() const
  {
    return this->m_TM7;
  }

  void SetSAT(SATType sat)
  {

    this->m_SAT = sat;

    if (sat == L5)
    {
      m_TM1  = 0;
      m_TM2  = 1;
      m_TM3  = 2;
      m_TM4  = 3;
      m_TM5  = 4;
      m_TM60 = 5;
      m_TM7  = 6;
      m_SAT  = L5;
    }
    else
    {
      m_TM1  = 0;
      m_TM2  = 1;
      m_TM3  = 2;
      m_TM4  = 3;
      m_TM5  = 4;
      m_TM61 = 5;
      m_TM62 = 6;
      m_TM7  = 7;
      m_SAT  = L7;
    }
  }

  SATType GetSAT() const
  {
    return this->m_SAT;
  }

  void SetDegree(DegreeType deg)
  {
    this->m_Degree = deg;
  }

  DegreeType GetDegre() const
  {
    return this->m_Degree;
  }

  void SetReflectance(ReflectanceType ref)
  {
    this->m_Reflectance = ref;
  }

  ReflectanceType GetReflectance() const
  {
    return this->m_Reflectance;
  }

  double GetEpsilonToBeConsideredAsZero() const
  {
    return this->m_EpsilonToBeConsideredAsZero;
  }

protected:
  /// Prepare the values so they are normalized and in C

  TInput PrepareValues(const TInput& inputPixel)
  {

    TInput newPix(inputPixel);
    if (this->m_Degree == Kelvin)
    {
      if (this->m_SAT == L5)
      {
        newPix[this->m_TM60] = newPix[this->m_TM60] - 273.15;
      }
      else
      {
        newPix[this->m_TM61] = newPix[this->m_TM61] - 273.15;
        newPix[this->m_TM62] = newPix[this->m_TM62] - 273.15;
      }
    }
    else if (this->m_Degree == HundredsKelvin)
    {
      if (this->m_SAT == L5)
      {
        newPix[this->m_TM60] = newPix[this->m_TM60] / 100. - 273.15;
      }
      else
      {
        newPix[this->m_TM61] = newPix[this->m_TM61] / 100. - 273.15;
        newPix[this->m_TM62] = newPix[this->m_TM62] / 100. - 273.15;
      }
    }
    if (this->m_Reflectance == Thousands)
    {
      newPix[this->m_TM1] = newPix[this->m_TM1] / 1000.;
      newPix[this->m_TM2] = newPix[this->m_TM2] / 1000.;
      newPix[this->m_TM3] = newPix[this->m_TM3] / 1000.;
      newPix[this->m_TM4] = newPix[this->m_TM4] / 1000.;
      newPix[this->m_TM5] = newPix[this->m_TM5] / 1000.;
      newPix[this->m_TM7] = newPix[this->m_TM7] / 1000.;
    }

    return newPix;
  }

  double m_EpsilonToBeConsideredAsZero;

  unsigned int m_TM1;
  unsigned int m_TM2;
  unsigned int m_TM3;
  unsigned int m_TM4;
  unsigned int m_TM5;
  unsigned int m_TM60;
  unsigned int m_TM61;
  unsigned int m_TM62;
  unsigned int m_TM7;

  SATType         m_SAT;
  DegreeType      m_Degree;
  ReflectanceType m_Reflectance;
};

/** \class LandsatTMIndex
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class LandsatTMIndex : public LandsatTMIndexBase<TInput, TOutput>
{
public:
  // Operator performing the work
  inline TOutput operator()(const TInput& inputPixel) const;

  /** Return the index name */
  virtual std::string GetName() const = 0;

  LandsatTMIndex()
  {
  }
  ~LandsatTMIndex() override
  {
  }
};

/** \class Bright
 *  Brightness index for LandsatTM. Computes a weighted mean of the
 *  non thermal bands as follows :
 *  \f[
 *    \frac{1}{8}\left( TM1 + TM2 + 2\times TM3 + 2\times TM4 + TM5 + TM7\right)
 *  \f]
 *  This expression is the one used in Baraldi et al. 2006, "Automatic
 *  Spectral Rule-Based Preliminary Mapping of Calibrated Landsat TM
 *  and ETM+ Images", IEEE Trans. on Geoscience and Remote Sensing,
 *  vol 44, no 9.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class Bright : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "Bright";
  }

  Bright()
  {
  }
  ~Bright() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {

    TInput newPixel(this->PrepareValues(inputPixel));
    double result = (newPixel[this->m_TM1] + newPixel[this->m_TM2] + 2 * newPixel[this->m_TM3] + 2 * newPixel[this->m_TM4] + newPixel[this->m_TM5] +
                     newPixel[this->m_TM7]) /
                    8.0;
    return static_cast<TOutput>(result);
  }
};

/** \class Vis
 *  Visible index for LandsatTM. Computes a mean of the 3 visible
 *  bands as follows:
 *  \f[
 *    \frac{1}{3}\left( TM1 + TM2 + TM3 \right)}
 *  \f]
 *  This expression is the one used in Baraldi et al. 2006, "Automatic
 *  Spectral Rule-Based Preliminary Mapping of Calibrated Landsat TM
 *  and ETM+ Images", IEEE Trans. on Geoscience and Remote Sensing,
 *  vol 44, no 9.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class Vis : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "Vis";
  }

  Vis()
  {
  }
  ~Vis() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = (newPixel[this->m_TM1] + newPixel[this->m_TM2] + newPixel[this->m_TM3]) / 3.0;
    return static_cast<TOutput>(result);
  }
};

/** \class NIR
 *  NIR index for LandsatTM. Alias for the TM4 band.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class NIR : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "NIR";
  }

  NIR()
  {
  }
  ~NIR() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = newPixel[this->m_TM4];
    return static_cast<TOutput>(result);
  }
};

/** \class MIR1
 *  MIR1 index for LandsatTM. Alias for the TM5 band.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class MIR1 : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "MIR1";
  }

  MIR1()
  {
  }
  ~MIR1() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = newPixel[this->m_TM5];
    return static_cast<TOutput>(result);
  }
};

/** \class MIR2
 *  MIR2 index for LandsatTM. Alias for the TM7 band.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class MIR2 : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "MIR2";
  }

  MIR2()
  {
  }
  ~MIR2() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = newPixel[this->m_TM7];
    return static_cast<TOutput>(result);
  }
};

/** \class TIR
 *  TIR index for LandsatTM. This is TM60 for Landsat 5 and TM62 for Landsat 7.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class TIR : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "TIR";
  }

  TIR()
  {
  }
  ~TIR() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = newPixel[this->m_TM62];

    if (this->m_SAT == L5)
      result = newPixel[this->m_TM60];

    return static_cast<TOutput>(result);
  }
};

/** \class MIRTIR
 *
 *  MIRTIR index for LandsatTM.
 *
 *  In general, clouds tend
 *  to be colder and feature a higher reflectance at the 1700 nm
 *  wavelength (TM5) than cold and highly reflective barren land. To
 *  enhance this difference, a well known TM band 5/6 composite is
 *  specifically designed for cloud detection in :
 *
 *  R. Irish, "Landsat 7 automatic cloud cover assessment (ACCA)",
 *  Poc. of SPIE, vol 4049, pp. 348-355, 2000.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class MIRTIR : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "MIRTIR";
  }

  MIRTIR()
  {
  }
  ~MIRTIR() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double tir  = newPixel[this->m_TM62];
    double mir1 = newPixel[this->m_TM5];

    if (this->m_SAT == L5)
      tir = newPixel[this->m_TM60];

    double result = 255 * (1 - mir1) * (tir + 100) / 100.;

    return static_cast<TOutput>(result);
  }
};

/** \class NDVI
 *
 *  NDVI index for LandsatTM.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class NDVI : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "NDVI";
  }

  NDVI()
  {
  }
  ~NDVI() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = (newPixel[this->m_TM4] - newPixel[this->m_TM3]) / (newPixel[this->m_TM4] + newPixel[this->m_TM3] + this->m_EpsilonToBeConsideredAsZero);

    return static_cast<TOutput>(result);
  }
};

/** \class NDBSI
 *
 *  Normalized Difference Bare Soil index for LandsatTM.
 *
 *  \f[
 *    \frac{\left( TM5 - TM4 \right)}{\left( TM5 + TM4 + \epsilon \right)}
 *  \f]
 *
 *  This expression is the one used in Baraldi et al. 2006, "Automatic
 *  Spectral Rule-Based Preliminary Mapping of Calibrated Landsat TM
 *  and ETM+ Images", IEEE Trans. on Geoscience and Remote Sensing,
 *  vol 44, no 9.
 *
 *  NDBSI > -0.2 is a strong (necessary, but not sufficient)
 *  indication of the presence of bare soil areas.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class NDBSI : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "NDBSI";
  }

  NDBSI()
  {
  }
  ~NDBSI() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = (newPixel[this->m_TM5] - newPixel[this->m_TM4]) / (newPixel[this->m_TM5] + newPixel[this->m_TM4] + this->m_EpsilonToBeConsideredAsZero);

    return static_cast<TOutput>(result);
  }
};

/** \class BIO
 *
 *  Another Bare Soil index for LandsatTM.
 *
 *  \f[
 *    \frac{\left( (TM5 + TM3) - (TM4 + TM1)  \right)}{\left( (TM5 + TM3) + (TM4 + TM1) \right)}
 *  \f]
 *
 *  This expression is the one used in: Roy PS, Miyatake S and Rikimaru
 *  A (1997) Biophysical Spectral Response Modelling Approach for
 *  Forest Density Stratification. FCD Mapper Users Guide.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class BIO : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "BIO";
  }

  BIO()
  {
  }
  ~BIO() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = ((newPixel[this->m_TM5] + newPixel[this->m_TM3]) - (newPixel[this->m_TM4] + newPixel[this->m_TM1])) /
                    ((newPixel[this->m_TM5] + newPixel[this->m_TM3]) + (newPixel[this->m_TM4] + newPixel[this->m_TM1]));

    return static_cast<TOutput>(result);
  }
};

/** \class NDSI
 *
 *  Normalized Difference Snow index for LandsatTM.
 *
 *  \f[
 *    \frac{\left( TM2 - TM5 \right)}{\left( TM2 + TM5 + \epsilon \right)}
 *  \f]
 *
 *  This expression is the one used in R. Irish, "Landsat 7 automatic
 *  cloud cover assessment (ACCA)", Poc. of SPIE, vol 4049,
 *  pp. 348-355, 2000.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class NDSI : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "NDSI";
  }

  NDSI()
  {
  }
  ~NDSI() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = (newPixel[this->m_TM2] - newPixel[this->m_TM5]) / (newPixel[this->m_TM2] + newPixel[this->m_TM5] + this->m_EpsilonToBeConsideredAsZero);

    return static_cast<TOutput>(result);
  }
};

/** \class NDSIVis
 *
 *  Baraldi's Normalized Difference Snow index for LandsatTM.
 *
 *  \f[
 *    \frac{\left( Vis - TM5 \right)}{\left( Vis + TM5 + \epsilon \right)}
 *  \f]
 *
 *  where
 *
 *  \f[
 *    Vis = \frac{1}{3}\left( TM1 + TM2 + TM3 \right)}
 *  \f]
 *
 *  This expression is the one used in Baraldi et al. 2006, "Automatic
 *  Spectral Rule-Based Preliminary Mapping of Calibrated Landsat TM
 *  and ETM+ Images", IEEE Trans. on Geoscience and Remote Sensing,
 *  vol 44, no 9.
 *
 *  and is an adaptation of the one given in R. Irish, "Landsat 7
 *  automatic cloud cover assessment (ACCA)", Poc. of SPIE, vol 4049,
 *  pp. 348-355, 2000.
 *
 *  NDSIVis > 0.5 is a strong (necessary, but not sufficient)
 *  indication of the presence of snow areas.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class NDSIVis : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "NDSIVis";
  }

  NDSIVis()
  {
  }
  ~NDSIVis() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double vis    = (newPixel[this->m_TM1] + newPixel[this->m_TM2] + newPixel[this->m_TM3]) / 3.0;
    double result = (vis - newPixel[this->m_TM5]) / (vis + newPixel[this->m_TM5] + this->m_EpsilonToBeConsideredAsZero);

    return static_cast<TOutput>(result);
  }
};

/** \class NDBBBI
 *
 *  Normalized Difference Blue-band component in Built-up areas and
 *  Barren land index for LandsatTM.
 *
 *  \f[
 *    \frac{\left( TM1 - TM5 \right)}{\left( TM1 + TM5 + \epsilon \right)}
 *  \f]
 *
 *  This expression is the one used in Baraldi et al. 2006, "Automatic
 *  Spectral Rule-Based Preliminary Mapping of Calibrated Landsat TM
 *  and ETM+ Images", IEEE Trans. on Geoscience and Remote Sensing,
 *  vol 44, no 9.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class NDBBBI : public LandsatTMIndex<TInput, TOutput>
{
public:
  /** Return the index name */
  std::string GetName() const override
  {
    return "NDBBBI";
  }

  NDBBBI()
  {
  }
  ~NDBBBI() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    double result = (newPixel[this->m_TM1] - newPixel[this->m_TM5]) / (newPixel[this->m_TM1] + newPixel[this->m_TM5] + this->m_EpsilonToBeConsideredAsZero);
    return static_cast<TOutput>(result);
  }
};

/** \class LandsatTMLinguisticVariables
 *
 * Implementation of the linguistic labels assigned to fuzzy sets
 *  providing a complete partition of a feature space consisting of
 *  scalar variables representing specific Landsat TM indices as
 *  described in Baraldi et al. 2006, "Automatic Spectral Rule-Based
 *  Preliminary Mapping of Calibrated Landsat TM and ETM+ Images",
 *  IEEE Trans. on Geoscience and Remote Sensing, vol 44, no 9.
 *
 * The hard coded thresholds are taken from table III of the paper.
 * The implementation proposed here is not at all optimal in the sense
 * that otb::FuzzyVariables are used where simple thresholds would be
 * enough. This is done like this so this class can also provide (TODO)
 * membership values instead of crisp ones.
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput>
class LinguisticVariables : public LandsatTMIndexBase<TInput, itk::FixedArray<unsigned int, 11>>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef typename itk::FixedArray<unsigned int, 11>        OutputPixelType;
  typedef otb::FuzzyVariable<unsigned short, PrecisionType> FuzzyVarType;

  enum LinguisticValues
  {
    MINlv = 0,
    Low   = MINlv,
    Medium,
    MAXlv = 2,
    High  = MAXlv
  };
  enum Indices
  {
    MINid  = 0,
    bright = MINid,
    vis,
    nir,
    mir1,
    mir2,
    tir,
    mirtir,
    ndsivis,
    ndbbbi,
    ndvi,
    MAXid = 10,
    ndbsi = MAXid
  };

  /** Return the index name */
  virtual std::string GetName() const
  {
    return "LandsatTM Linguistic Variables";
  }

  LinguisticVariables()
  {
    m_FvBright  = FuzzyVarType::New();
    m_FvVis     = FuzzyVarType::New();
    m_FvNIR     = FuzzyVarType::New();
    m_FvMIR1    = FuzzyVarType::New();
    m_FvMIR2    = FuzzyVarType::New();
    m_FvTIR     = FuzzyVarType::New();
    m_FvMIRTIR  = FuzzyVarType::New();
    m_FvNDSIVis = FuzzyVarType::New();
    m_FvNDBBBI  = FuzzyVarType::New();
    m_FvNDVI    = FuzzyVarType::New();
    m_FvNDBSI   = FuzzyVarType::New();

    PrecisionType maximumValue = itk::NumericTraits<PrecisionType>::max();
    PrecisionType minimumValue = itk::NumericTraits<PrecisionType>::NonpositiveMin();

    // the thresholds are computed wrt Baraldi's paper (normalized 0-255 values)
    m_FvBright->SetMembership(Low, minimumValue, minimumValue, 40 / 255., 40 / 255.);
    m_FvBright->SetMembership(Medium, 40 / 255., 40 / 255., 60 / 255., 60 / 255.);
    m_FvBright->SetMembership(High, 60 / 255., 60 / 255., maximumValue, maximumValue);

    m_FvVis->SetMembership(Low, minimumValue, minimumValue, 30 / 255., 30 / 255.);
    m_FvVis->SetMembership(Medium, 30 / 255., 30 / 255., 50 / 255., 50 / 255.);
    m_FvVis->SetMembership(High, 50 / 255., 50 / 255., maximumValue, maximumValue);

    m_FvNIR->SetMembership(Low, minimumValue, minimumValue, 40 / 255., 40 / 255.);
    m_FvNIR->SetMembership(Medium, 40 / 255., 40 / 255., 60 / 255., 60 / 255.);
    m_FvNIR->SetMembership(High, 60 / 255., 60 / 255., maximumValue, maximumValue);

    m_FvMIR1->SetMembership(Low, minimumValue, minimumValue, 40 / 255., 40 / 255.);
    m_FvMIR1->SetMembership(Medium, 40 / 255., 40 / 255., 60 / 255., 60 / 255.);
    m_FvMIR1->SetMembership(High, 60 / 255., 60 / 255., maximumValue, maximumValue);

    m_FvMIR2->SetMembership(Low, minimumValue, minimumValue, 30 / 255., 30 / 255.);
    m_FvMIR2->SetMembership(Medium, 30 / 255., 30 / 255., 50 / 255., 50 / 255.);
    m_FvMIR2->SetMembership(High, 50 / 255., 50 / 255., maximumValue, maximumValue);

    m_FvTIR->SetMembership(Low, minimumValue, minimumValue, 0, 0);
    m_FvTIR->SetMembership(Medium, 0, 0, 28, 28);
    m_FvTIR->SetMembership(High, 28, 28, maximumValue, maximumValue);

    m_FvMIRTIR->SetMembership(Low, minimumValue, minimumValue, 180, 180);
    m_FvMIRTIR->SetMembership(Medium, 180, 180, 220, 220);
    m_FvMIRTIR->SetMembership(High, 220, 220, maximumValue, maximumValue);

    m_FvNDSIVis->SetMembership(Low, minimumValue, minimumValue, 0, 0);
    m_FvNDSIVis->SetMembership(Medium, 0, 0, 0.5, 0.5);
    m_FvNDSIVis->SetMembership(High, 0.5, 0.5, maximumValue, maximumValue);

    m_FvNDBBBI->SetMembership(Low, minimumValue, minimumValue, -0.20, -0.20);
    m_FvNDBBBI->SetMembership(Medium, -0.20, -0.20, 0.10, 0.10);
    m_FvNDBBBI->SetMembership(High, 0.10, 0.10, maximumValue, maximumValue);

    m_FvNDVI->SetMembership(Low, minimumValue, minimumValue, 0.35, 0.35);
    m_FvNDVI->SetMembership(Medium, 0.35, 0.35, 0.6, 0.6);
    m_FvNDVI->SetMembership(High, 0.6, 0.6, maximumValue, maximumValue);

    m_FvNDBSI->SetMembership(Low, minimumValue, minimumValue, -0.20, -0.20);
    m_FvNDBSI->SetMembership(Medium, -0.20, -0.20, 0.0, 0.0);
    m_FvNDBSI->SetMembership(High, 0.0, 0.0, maximumValue, maximumValue);
  }
  ~LinguisticVariables() override
  {
  }

  inline itk::FixedArray<unsigned int, 11> operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    itk::FixedArray<unsigned int, 11> result;

    result[bright] = m_FvBright->GetMaxVar(Bright<TInput, PrecisionType>()(newPixel));
    result[vis]    = m_FvVis->GetMaxVar(Vis<TInput, PrecisionType>()(newPixel));
    result[nir]    = m_FvNIR->GetMaxVar(NIR<TInput, PrecisionType>()(newPixel));
    result[mir1]   = m_FvMIR1->GetMaxVar(MIR1<TInput, PrecisionType>()(newPixel));

    MIR2<TInput, PrecisionType> mir2F;
    mir2F.SetSAT(this->m_SAT);
    result[mir2] = m_FvMIR2->GetMaxVar(mir2F(newPixel));

    TIR<TInput, PrecisionType> tirF;
    tirF.SetSAT(this->m_SAT);
    result[tir] = m_FvTIR->GetMaxVar(tirF(newPixel));

    MIRTIR<TInput, PrecisionType> mirtirF;
    mirtirF.SetSAT(this->m_SAT);
    result[mirtir] = m_FvMIRTIR->GetMaxVar(mirtirF(newPixel));

    result[ndsivis] = m_FvNDSIVis->GetMaxVar(NDSIVis<TInput, PrecisionType>()(newPixel));

    result[ndbbbi] = m_FvNDBBBI->GetMaxVar(NDBBBI<TInput, PrecisionType>()(newPixel));

    result[ndvi] = m_FvNDVI->GetMaxVar(NDVI<TInput, PrecisionType>()(newPixel));

    result[ndbsi] = m_FvNDBSI->GetMaxVar(NDBSI<TInput, PrecisionType>()(newPixel));

    return result;
  }

protected:
  typename FuzzyVarType::Pointer m_FvBright;
  typename FuzzyVarType::Pointer m_FvVis;
  typename FuzzyVarType::Pointer m_FvNIR;
  typename FuzzyVarType::Pointer m_FvMIR1;
  typename FuzzyVarType::Pointer m_FvMIR2;
  typename FuzzyVarType::Pointer m_FvTIR;
  typename FuzzyVarType::Pointer m_FvMIRTIR;
  typename FuzzyVarType::Pointer m_FvNDSIVis;
  typename FuzzyVarType::Pointer m_FvNDBBBI;
  typename FuzzyVarType::Pointer m_FvNDVI;
  typename FuzzyVarType::Pointer m_FvNDBSI;
};

/** \class KernelSpectralRule
 *
 * Implementation of the Kernel Spectral rules for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 * This is a virtual class defining the common accessors to the 14 spectral rules
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class KernelSpectralRule : public LandsatTMIndexBase<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  virtual std::string GetName() const
  {
    return "LandsatTM KernelSpectralRule";
  }

  KernelSpectralRule() : m_TV1(0.7), m_TV2(0.5)
  {
  }
  ~KernelSpectralRule() override
  {
  }

  void SetTV1(PrecisionType tv1)
  {
    this->m_TV1 = tv1;
  }

  void SetTV2(PrecisionType tv2)
  {
    this->m_TV2 = tv2;
  }

  PrecisionType GetTV1() const
  {
    return this->m_TV1;
  }

  PrecisionType GetTV2() const
  {
    return this->m_TV2;
  }

protected:
  /** Tolerance value 1*/
  PrecisionType m_TV1;
  /** Tolerance value 2*/
  PrecisionType m_TV2;

  void SetMinMax(const TInput& inputPixel, PrecisionType* max13, PrecisionType* min123, PrecisionType* max123, PrecisionType* min12347, PrecisionType* max12347,
                 PrecisionType* max234, PrecisionType* max45)
  {
    std::vector<PrecisionType> v13;
    v13.push_back(inputPixel[this->m_TM1]);
    v13.push_back(inputPixel[this->m_TM3]);

    *max13 = *(std::max_element(v13.begin(), v13.end()));

    std::vector<PrecisionType> v123;
    v123.push_back(inputPixel[this->m_TM1]);
    v123.push_back(inputPixel[this->m_TM2]);
    v123.push_back(inputPixel[this->m_TM3]);

    *max123 = *(std::max_element(v123.begin(), v123.end()));
    *min123 = *(std::min_element(v123.begin(), v123.end()));

    std::vector<PrecisionType> v12347;
    v12347.push_back(inputPixel[this->m_TM1]);
    v12347.push_back(inputPixel[this->m_TM2]);
    v12347.push_back(inputPixel[this->m_TM3]);
    v12347.push_back(inputPixel[this->m_TM4]);
    v12347.push_back(inputPixel[this->m_TM7]);

    *max12347 = *(std::max_element(v12347.begin(), v12347.end()));
    *min12347 = *(std::min_element(v12347.begin(), v12347.end()));

    std::vector<PrecisionType> v234;
    v234.push_back(inputPixel[this->m_TM2]);
    v234.push_back(inputPixel[this->m_TM3]);
    v234.push_back(inputPixel[this->m_TM4]);

    *max234 = *(std::max_element(v234.begin(), v234.end()));

    std::vector<PrecisionType> v45;
    v45.push_back(inputPixel[this->m_TM4]);
    v45.push_back(inputPixel[this->m_TM5]);

    *max45 = *(std::max_element(v45.begin(), v45.end()));
  }
};

/** \class ThickCloudsSpectralRule
 *
 * Implementation of the ThickCloudsSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class ThickCloudsSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM ThickCloudsSpectralRule";
  }

  ThickCloudsSpectralRule()
  {
  }
  ~ThickCloudsSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (((min123 >= (this->m_TV1 * max123) && (max123 <= this->m_TV1 * newPixel[this->m_TM4])) ||
                    ((newPixel[this->m_TM2] >= this->m_TV1 * max13) && (max123 <= newPixel[this->m_TM4]))) &&
                   (newPixel[this->m_TM5] <= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM5] >= this->m_TV1 * max123) &&
                   (newPixel[this->m_TM7] <= this->m_TV1 * newPixel[this->m_TM4]));

    return static_cast<TOutput>(result);
  }
};

/** \class ThinCloudsSpectralRule
 *
 * Implementation of the ThinCloudsSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class ThinCloudsSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM ThinCloudsSpectralRule";
  }

  ThinCloudsSpectralRule()
  {
  }
  ~ThinCloudsSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (min123 >= (this->m_TV1 * max123)) && (newPixel[this->m_TM4] >= max123) &&
                  !((newPixel[this->m_TM1] <= newPixel[this->m_TM2] && newPixel[this->m_TM2] <= newPixel[this->m_TM3] &&
                     newPixel[this->m_TM3] <= newPixel[this->m_TM4]) &&
                    (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM4])) &&
                  (newPixel[this->m_TM4] >= this->m_TV1 * newPixel[this->m_TM5]) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM5] >= this->m_TV1 * max123) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

/** \class SnowOrIceSpectralRule
 *
 * Implementation of the SnowOrIceSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class SnowOrIceSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM SnowOrIceSpectralRule";
  }

  SnowOrIceSpectralRule()
  {
  }
  ~SnowOrIceSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (min123 >= (this->m_TV1 * max123)) && (newPixel[this->m_TM4] >= (this->m_TV1 * max123)) &&
                  (newPixel[this->m_TM5] <= this->m_TV2 * newPixel[this->m_TM4]) && (newPixel[this->m_TM5] <= this->m_TV1 * min123) &&
                  (newPixel[this->m_TM5] <= this->m_TV1 * max123) && (newPixel[this->m_TM7] <= this->m_TV2 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM7] <= this->m_TV1 * min123);

    return static_cast<TOutput>(result);
  }
};

/** \class WaterOrShadowSpectralRule
 *
 * Implementation of the WaterOrShadowSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class WaterOrShadowSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM WaterOrShadowSpectralRule";
  }

  WaterOrShadowSpectralRule()
  {
  }
  ~WaterOrShadowSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    bool   result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2]) && (newPixel[this->m_TM2] >= newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM3] >= newPixel[this->m_TM4]) && (newPixel[this->m_TM4] >= newPixel[this->m_TM5]) &&
                  (newPixel[this->m_TM4] >= newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

/** \class PitbogOrGreenhouseSpectralRule
 *
 * Implementation of the PitbogOrGreenhouseSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class PitbogOrGreenhouseSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM PitbogOrGreenhouseSpectralRule";
  }

  PitbogOrGreenhouseSpectralRule()
  {
  }
  ~PitbogOrGreenhouseSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM1]) && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM3]) &&
                  (max123 <= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM5] <= this->m_TV1 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM5]) && (min123 >= this->m_TV1 * newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

/** \class DominantBlueSpectralRule
 *
 * Implementation of the DominantBlueSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class DominantBlueSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM DominantBlueSpectralRule";
  }

  DominantBlueSpectralRule()
  {
  }
  ~DominantBlueSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    bool   result = (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM2]) && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM5]) &&
                  (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

/** \class VegetationSpectralRule
 *
 * Implementation of the VegetationSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class VegetationSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM VegetationSpectralRule";
  }

  VegetationSpectralRule()
  {
  }
  ~VegetationSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (newPixel[this->m_TM2] >= this->m_TV2 * newPixel[this->m_TM1]) && (newPixel[this->m_TM2] >= this->m_TV1 * newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM3] < this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM4] > max123) &&
                  (newPixel[this->m_TM5] < this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM7] < this->m_TV1 * newPixel[this->m_TM5]);

    return static_cast<TOutput>(result);
  }
};

/** \class RangelandSpectralRule
 *
 * Implementation of the RangelandSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class RangelandSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM RangelandSpectralRule";
  }

  RangelandSpectralRule()
  {
  }
  ~RangelandSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (newPixel[this->m_TM2] >= this->m_TV2 * newPixel[this->m_TM1]) && (newPixel[this->m_TM2] >= this->m_TV1 * newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM4] > max123) && (newPixel[this->m_TM3] < this->m_TV1 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM4] >= this->m_TV1 * newPixel[this->m_TM5]) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM5] > max123) && (newPixel[this->m_TM7] < this->m_TV1 * max45) && (newPixel[this->m_TM5] >= newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

/** \class BarrenLandOrBuiltUpOrCloudsSpectralRule
 *
 * Implementation of the BarrenLandOrBuiltUpOrCloudsSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class BarrenLandOrBuiltUpOrCloudsSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM BarrenLandOrBuiltUpOrCloudsSpectralRule";
  }

  BarrenLandOrBuiltUpOrCloudsSpectralRule()
  {
  }
  ~BarrenLandOrBuiltUpOrCloudsSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM1]) && (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM2]) &&
                  (newPixel[this->m_TM4] >= this->m_TV1 * max123) && (newPixel[this->m_TM5] >= max123) &&
                  (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM7]) &&
                  (newPixel[this->m_TM7] >= this->m_TV2 * max45);

    return static_cast<TOutput>(result);
  }
};

/** \class FlatResponseBarrenLandOrBuiltUpSpectralRule
 *
 * Implementation of the FlatResponseBarrenLandOrBuiltUpSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class FlatResponseBarrenLandOrBuiltUpSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM FlatResponseBarrenLandOrBuiltUpSpectralRule";
  }

  FlatResponseBarrenLandOrBuiltUpSpectralRule()
  {
  }
  ~FlatResponseBarrenLandOrBuiltUpSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (newPixel[this->m_TM5] >= this->m_TV1 * max12347) && (min12347 >= this->m_TV2 * newPixel[this->m_TM5]);

    return static_cast<TOutput>(result);
  }
};

/** \class ShadowWithBarrenLandSpectralRule
 *
 * Implementation of the ShadowWithBarrenLandSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class ShadowWithBarrenLandSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM ShadowWithBarrenLandSpectralRule";
  }

  ShadowWithBarrenLandSpectralRule()
  {
  }
  ~ShadowWithBarrenLandSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    bool   result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2]) && (newPixel[this->m_TM2] >= newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM3] >= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM1] >= newPixel[this->m_TM5]) &&
                  (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

/** \class ShadowWithVegetationSpectralRule
 *
 * Implementation of the ShadowWithVegetationSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class ShadowWithVegetationSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM ShadowWithVegetationSpectralRule";
  }

  ShadowWithVegetationSpectralRule()
  {
  }
  ~ShadowWithVegetationSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    bool   result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2]) && (newPixel[this->m_TM2] >= newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM1] >= this->m_TV2 * newPixel[this->m_TM4]) && (newPixel[this->m_TM3] < this->m_TV1 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM5] < this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM5]) &&
                  (newPixel[this->m_TM7] < this->m_TV1 * newPixel[this->m_TM4]);

    return static_cast<TOutput>(result);
  }
};

/** \class ShadowCloudOrSnowSpectralRule
 *
 * Implementation of the ShadowCloudOrSnowSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class ShadowCloudOrSnowSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM ShadowCloudOrSnowSpectralRule";
  }

  ShadowCloudOrSnowSpectralRule()
  {
  }
  ~ShadowCloudOrSnowSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput        newPixel(this->PrepareValues(inputPixel));
    PrecisionType max13;
    PrecisionType max123;
    PrecisionType min123;
    PrecisionType max12347;
    PrecisionType min12347;
    PrecisionType max234;
    PrecisionType max45;
    this->SetMinMax(newPixel, &max13, &min123, &max123, &min12347, &max12347, &max234, &max45);

    bool result = (newPixel[this->m_TM1] >= this->m_TV1 * max234) && (max234 >= this->m_TV1 * newPixel[this->m_TM1]) &&
                  (newPixel[this->m_TM5] < newPixel[this->m_TM1]) && (newPixel[this->m_TM7] < this->m_TV1 * newPixel[this->m_TM1]);

    return static_cast<TOutput>(result);
  }
};

/** \class WetlandSpectralRule
 *
 * Implementation of the WetlandSpectralRule for Landsat TM image
 *  land cover classification as described in table IV of Baraldi et
 *  al. 2006, "Automatic Spectral Rule-Based Preliminary Mapping of
 *  Calibrated Landsat TM and ETM+ Images", IEEE Trans. on Geoscience
 *  and Remote Sensing, vol 44, no 9.
 *
 *
 * \ingroup Functor
 * \ingroup Radiometry
 * \ingroup LandsatTMIndices
 *
 * \ingroup OTBIndices
 */
template <class TInput, class TOutput>
class WetlandSpectralRule : public KernelSpectralRule<TInput, TOutput>
{
public:
  typedef typename TInput::ValueType PrecisionType;
  typedef bool                       OutputPixelType;

  /** Return the index name */
  std::string GetName() const override
  {
    return "LandsatTM WetlandSpectralRule";
  }

  WetlandSpectralRule()
  {
  }
  ~WetlandSpectralRule() override
  {
  }

  inline TOutput operator()(const TInput& inputPixel)
  {
    TInput newPixel(this->PrepareValues(inputPixel));
    bool   result = (newPixel[this->m_TM1] >= newPixel[this->m_TM2]) && (newPixel[this->m_TM2] >= newPixel[this->m_TM3]) &&
                  (newPixel[this->m_TM1] >= this->m_TV1 * newPixel[this->m_TM4]) && (newPixel[this->m_TM3] < newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM4] >= this->m_TV1 * newPixel[this->m_TM5]) && (newPixel[this->m_TM5] >= this->m_TV1 * newPixel[this->m_TM4]) &&
                  (newPixel[this->m_TM3] >= this->m_TV2 * newPixel[this->m_TM5]) && (newPixel[this->m_TM5] >= newPixel[this->m_TM7]);

    return static_cast<TOutput>(result);
  }
};

} // namespace LandsatTM
} // namespace Functor
} // namespace otb

#endif


text:
package cadastre

import "time"
import "sync"
import "log"

// Represents the fetcher, which runs continuously, sucking up data from the specified hosts
// and persisting it to the storage engine for later retrieval.
type Fetcher struct {
	Configuration *Configuration
	running       bool
	fetchGuard    sync.WaitGroup
}

func (me *Fetcher) Start() error {
	me.running = false

	processListFetcher := func(server Server) {
		// Increment the fetcher guard.
		me.fetchGuard.Add(1)

		for {
			// See if we should still be running.
			if !me.running {
				break
			}

			// Wait our fetch interval before we proceed.
			time.Sleep(me.Configuration.FetchInterval)

			// Check again to see if we should be running, as we could have just sat through
			// a moderately-long fetch interval and have the process waiting on us to stop.
			if !me.running {
				break
			}

			snapshot := &Snapshot{}
			if err := snapshot.TakeSnapshot(server); err != nil {
				log.Printf("error: failed to take snapshot for host '%s'! %s", server.InternalName, err)
			} else {
				// Persist it to our datastore.
				me.Configuration.Storage.Persist(server.InternalName, snapshot)
			}
		}

		// All done, so decrement the fetcher guard.
		me.fetchGuard.Done()
	}

	// Set ourselves as running.
	me.running = true

	var fetcherCount uint64

	// Create a fetcher routine for each server we want to monitor.
	for _, server := range me.Configuration.Servers {
		fetcherCount++

		go processListFetcher(server)
	}

	log.Printf("Launched %d fetcher(s) to poll databases...", fetcherCount)

	return nil
}

func (me *Fetcher) Stop() error {
	// Alert all goroutines that we're done running.
	me.running = false

	// Wait for all fetchers to stop.
	me.fetchGuard.Wait()

	return nil
}

redpajama_set_name: RedPajamaGithub


text:
from django.core.cache import cache
from django.http import HttpResponseRedirect, Http404
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext

from friendfeedapp.models import FFUser, Service
from friendfeedapp.utils import get_graph_data

CACHE_TIME = 60 * 60

def request_to_graph_data(request, ffuser = None, friends = None):
    key = '%s' % (request.get_full_path())
    results = cache.get(key)
    if not results:
        from datetime import timedelta
        service = None
        if 'service' in request.GET:
            service = get_object_or_404(Service, uuid = request.GET['service'])
        type = request.GET.get('type', 'weekdays')
        if type == 'months':
            duration = timedelta(days = 365)
        elif type == 'days':
            duration = timedelta(days = 14)
        else:
            duration = timedelta(days = 30)
        if 'duration' in request.GET:
            try:
                duration = timedelta(days = int(request.GET['duration']))
            except Exception, e:
                pass
        data, total = get_graph_data(type = type, duration = duration, ffuser = ffuser, service = service, friends = friends)
        results = data, total, duration
        cache.set(key, results, CACHE_TIME)
    return results

def get_services():
    key = 'services'
    services = cache.get(key)
    if not services:
        services = Service.objects.order_by('name')
        cache.set(key, list(services), CACHE_TIME)
    return services

def graph(request, nickname, friends_only = False):
    ffuser = get_object_or_404(FFUser, nickname = nickname)
    friends = None
    if friends_only:
        from friendfeedapp.utils import get_friendfeed_friends
        friends = get_friendfeed_friends(nickname)
    data, total, duration = request_to_graph_data(request, ffuser, friends)
    services = get_services()
    extra_context = {'data': data, 'total': total, 'services': services, 'ffuser': ffuser, 'duration': duration.days}
    if friends:
        template = 'friendfeedapp/friends.html'
    else:
        template = 'friendfeedapp/user.html'
    return render_to_response(template, extra_context, context_instance = RequestContext(request))

def search(request):
    if request.method == 'POST' and 'nickname' in request.POST:
        try:
            ffuser = FFUser.objects.get(nickname = request.POST['nickname'].lower())
        except FFUser.DoesNotExist:
            try:
                ffuser = FFUser.objects.get(name__iexact = request.POST['nickname'])
            except FFUser.DoesNotExist:
                raise Http404
            except FFUser.MultipleObjectsReturned:
                raise Http404
        return HttpResponseRedirect(ffuser.get_absolute_url())
    else:
        raise Http404


text:
/***
* Inferno Engine v4 2015-2017
* Written by Tomasz "Rex Dex" Jonarski
***/

#pragma once

#include "physics_runtime_glue.inl"

namespace physx
{
    class PxFoundation;
    class PxPhysics;
    class PxPvd;
}

namespace physics
{
    namespace runtime
    {
        enum class PhysicsSceneType : Uint8
        {
            Preview, // mostly for single preview windows
            Editor, // editor scene (lots of adds and removes)
            Game, // game physics
        };

        class PhysicsService;

        class PhysicsScene;
        typedef base::UniquePtr<PhysicsScene> PhysicsScenePtr;

    } // runtime
} // physics

typedef physics::runtime::PhysicsService PhysicsService;


text:
<!DOCTYPE html>

    <title>Estimation Board</title>


text:
package org.apache.camel.cdi;

import org.apache.camel.CamelContext;
import org.apache.camel.Consumer;
import org.apache.camel.Endpoint;
import org.apache.camel.FailedToCreateConsumerException;
import org.apache.camel.component.bean.BeanProcessor;
import org.apache.camel.core.xml.CamelServiceExporterDefinition;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.CreationException;
import javax.enterprise.inject.UnsatisfiedResolutionException;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import java.util.function.Function;

import static org.apache.camel.cdi.BeanManagerHelper.getReference;
import static org.apache.camel.cdi.BeanManagerHelper.getReferenceByName;
import static org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint;
import static org.apache.camel.util.ObjectHelper.isNotEmpty;
import static org.apache.camel.util.ServiceHelper.startService;

final class XmlServiceExporterBean<T> extends SyntheticBean<T> {

    private final BeanManager manager;

    private final Bean<?> context;

    private final CamelServiceExporterDefinition exporter;

    private final Class<?> type;

    XmlServiceExporterBean(BeanManager manager, SyntheticAnnotated annotated, Class<?> type, Function<Bean<T>, String> toString, Bean<?> context, CamelServiceExporterDefinition exporter) {
        super(manager, annotated, type, null, toString);
        this.manager = manager;
        this.context = context;
        this.exporter = exporter;
        this.type = type;
    }

    @Override
    public T create(CreationalContext<T> creationalContext) {
        try {
            CamelContext context = isNotEmpty(exporter.getCamelContextId())
                ? getReferenceByName(manager, exporter.getCamelContextId(), CamelContext.class).get()
                : getReference(manager, CamelContext.class, this.context);

            Bean<?> bean = manager.resolve(manager.getBeans(exporter.getServiceRef()));
            if (bean == null)
                throw new UnsatisfiedResolutionException("No bean with name [" + exporter.getServiceRef() + "] is deployed!");

            @SuppressWarnings("unchecked")
            T service = (T) manager.getReference(bean, type, manager.createCreationalContext(bean));

            Endpoint endpoint = getMandatoryEndpoint(context, exporter.getUri());
            try {
                // need to start endpoint before we create consumer
                startService(endpoint);
                Consumer consumer = endpoint.createConsumer(new BeanProcessor(service, context));
                // add and start consumer
                context.addService(consumer, true, true);
            } catch (Exception cause) {
                throw new FailedToCreateConsumerException(endpoint, cause);
            }

            return service;
        } catch (Exception cause) {
            throw new CreationException("Error while creating instance for " + this, cause);
        }
    }

    @Override
    public void destroy(T instance, CreationalContext<T> creationalContext) {
        // We let the Camel context manage the lifecycle of the consumer and
        // shut it down when Camel stops.
    }
}


text:
'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var babelPluginFlowReactPropTypes_proptype_Target = require('../types').babelPluginFlowReactPropTypes_proptype_Target || require('prop-types').any;

var babelPluginFlowReactPropTypes_proptype_Interpolation = require('../types').babelPluginFlowReactPropTypes_proptype_Interpolation || require('prop-types').any;

exports.default = function (css) {
  var constructWithOptions = function constructWithOptions(componentConstructor, tag) {
    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

    if (typeof tag !== 'string' && typeof tag !== 'function') {
      // $FlowInvalidInputTest
      throw new Error('Cannot create styled-component for component: ' + tag);
    }

    /* This is callable directly as a template function */
    var templateFunction = function templateFunction(strings) {
      for (var _len = arguments.length, interpolations = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        interpolations[_key - 1] = arguments[_key];
      }

      return componentConstructor(tag, options, css.apply(undefined, [strings].concat(interpolations)));
    };

    /* If config methods are called, wrap up a new template function and merge options */
    templateFunction.withConfig = function (config) {
      return constructWithOptions(componentConstructor, tag, _extends({}, options, config));
    };
    templateFunction.attrs = function (attrs) {
      return constructWithOptions(componentConstructor, tag, _extends({}, options, {
        attrs: _extends({}, options.attrs || {}, attrs) }));
    };

    return templateFunction;
  };

  return constructWithOptions;
};

module.exports = exports['default'];


text:
package de.lessvoid.nifty.controls;

import static org.junit.Assert.*;

import org.junit.Test;

public class ConsoleExecuteCommandEventTest {
  @Test
  public void testCommandLineNull() {
    ConsoleExecuteCommandEvent command = new ConsoleExecuteCommandEvent(null, null);
    assertEquals("", command.getCommandLine());
    assertEquals("", command.getCommand());
    assertEquals(0, command.getArgumentCount());
    assertEquals(0, command.getArguments().length);
  }

  @Test
  public void testCommandLineEmpty() {
    ConsoleExecuteCommandEvent command = new ConsoleExecuteCommandEvent(null, "");
    assertEquals("", command.getCommandLine());
    assertEquals("", command.getCommand());
    assertEquals(0, command.getArgumentCount());
    assertEquals(0, command.getArguments().length);
  }

  @Test
  public void testSimpleCommandLine() {
    ConsoleExecuteCommandEvent command = new ConsoleExecuteCommandEvent(null, "exec");
    assertEquals("exec", command.getCommandLine());
    assertEquals("exec", command.getCommand());
    assertEquals(0, command.getArgumentCount());
    assertEquals(0, command.getArguments().length);
  }

  @Test
  public void testOneParameterCommandLine() {
    ConsoleExecuteCommandEvent command = new ConsoleExecuteCommandEvent(null, "exec hello");
    assertEquals("exec hello", command.getCommandLine());
    assertEquals("exec", command.getCommand());
    assertEquals(1, command.getArgumentCount());
    assertEquals(1, command.getArguments().length);
    assertEquals("hello", command.getArguments()[0]);
  }

  @Test
  public void testMultipleParameterCommandLine() {
    ConsoleExecuteCommandEvent command = new ConsoleExecuteCommandEvent(null, "exec hello 42 43 tra");
    assertEquals("exec hello 42 43 tra", command.getCommandLine());
    assertEquals("exec", command.getCommand());
    assertEquals(4, command.getArgumentCount());
    assertEquals(4, command.getArguments().length);
    assertEquals("hello", command.getArguments()[0]);
    assertEquals("42", command.getArguments()[1]);
    assertEquals("43", command.getArguments()[2]);
    assertEquals("tra", command.getArguments()[3]);
  }

  @Test
  public void testMultipleStringParameterCommandLine() {
    ConsoleExecuteCommandEvent command = new ConsoleExecuteCommandEvent(null, "exec 'hello escaped whitespace' 42 43 \"hello quoted parameter\"");
    assertEquals("exec 'hello escaped whitespace' 42 43 \"hello quoted parameter\"", command.getCommandLine());
    assertEquals("exec", command.getCommand());
    assertEquals(4, command.getArgumentCount());
    assertEquals(4, command.getArguments().length);
    assertEquals("hello escaped whitespace", command.getArguments()[0]);
    assertEquals("42", command.getArguments()[1]);
    assertEquals("43", command.getArguments()[2]);
    assertEquals("hello quoted parameter", command.getArguments()[3]);
  }

}


text:
SET DEFINE OFF;
ALTER TABLE AFW_13_INSTA_PREFR ADD (
  CONSTRAINT AFW_13_INSTA_PREFR_FK1
  FOREIGN KEY (REF_PREFR)
  REFERENCES AFW_13_PREFR (SEQNC)
  ON DELETE CASCADE
  ENABLE VALIDATE)
/


text:
#include <stdio.h>
#include <string.h>

#define TAILLE_NOM 40

int main(int argc, char** argv)
{
  char* chaineStatique = "Universite du Quebec a Montreal";
  char buffer[TAILLE_NOM + 1];
  char* pointeur;
  char* pointeur2;

  printf("La taille de la chaine statique : %lu\n", strlen(chaineStatique));

  // Construire une chaîne, caractère par caractère
  buffer[0] = 'A';
  buffer[1] = 'l';
  buffer[2] = 'l';
  buffer[3] = 'o';
  buffer[4] = '\0';
  printf("Chaine construite par caractere : %s\n", buffer);

  // Positionner un pointeur sur une partie de la chaîne
  pointeur = chaineStatique + 23;
  printf("Fraction de chaine par pointeur : %s\n", pointeur);

  // Copie
  strcpy(buffer, pointeur);
  printf("Copie : %s\n", buffer);

  // Concaténation
  strcat(buffer, ", ");
  pointeur2 = chaineStatique + 14;
  strncat(buffer, pointeur2, 6);
  printf("Resultat de concatenations : %s\n", buffer);

  // Comparaison
  if (strcmp(buffer, "Montreal, Quebec") == 0)
    printf("Chaines egales\n");

  return 0;
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ChangeListManager">
    <list default="true" id="6d6b01ad-579a-43a8-ba83-3f5f3dc96a76" name="Default" comment="" />
    <ignored path="001.iws" />
    <ignored path=".idea/workspace.xml" />
    <ignored path=".idea/dataSources.local.xml" />
    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
    <option name="TRACKING_ENABLED" value="true" />
    <option name="SHOW_DIALOG" value="false" />
    <option name="HIGHLIGHT_CONFLICTS" value="true" />
    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
    <option name="LAST_RESOLUTION" value="IGNORE" />
  </component>
  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
  <component name="CoverageDataManager">
    <SUITE FILE_PATH="coverage/001@Solitaire_works__001.coverage" NAME="Solitaire works: 001 Coverage Results" MODIFIED="1447800872540" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="rcov" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" MODULE_NAME="001" />
    <SUITE FILE_PATH="coverage/001@Run_spec__solitaire_spec___001.coverage" NAME="Run spec 'solitaire_spec': 001 Coverage Results" MODIFIED="1447807623056" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="rcov" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" MODULE_NAME="001" />
  </component>
  <component name="CreatePatchCommitExecutor">
    <option name="PATCH_PATH" value="" />
  </component>
  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
  <component name="FavoritesManager">
    <favorites_list name="001" />
  </component>
  <component name="FileEditorManager">
    <splitter split-orientation="horizontal" split-proportion="0.34375">
      <split-first>
        <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
          <file leaf-file-name="solitaire_spec.rb" pinned="false" current-in-tab="true">
            <entry file="file://$PROJECT_DIR$/spec/solitaire_spec.rb">
              <provider selected="true" editor-type-id="text-editor">
                <state vertical-scroll-proportion="0.4375">
                  <caret line="16" column="0" selection-start-line="16" selection-start-column="0" selection-end-line="16" selection-end-column="0" />
                  <folding />
                </state>
              </provider>
            </entry>
          </file>
        </leaf>
      </split-first>
      <split-second>
        <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
          <file leaf-file-name="solitaire.rb" pinned="false" current-in-tab="true">
            <entry file="file://$PROJECT_DIR$/solitaire.rb">
              <provider selected="true" editor-type-id="text-editor">
                <state vertical-scroll-proportion="0.140625">
                  <caret line="35" column="0" selection-start-line="35" selection-start-column="0" selection-end-line="35" selection-end-column="0" />
                  <folding />
                </state>
              </provider>
            </entry>
          </file>
        </leaf>
      </split-second>
    </splitter>
  </component>
  <component name="Git.Settings">
    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../../../.." />
  </component>
  <component name="IdeDocumentHistory">
    <option name="CHANGED_PATHS">
      <list>
        <option value="$PROJECT_DIR$/spec/solitaire_spec.rb" />
        <option value="$PROJECT_DIR$/solitaire.rb" />
      </list>
    </option>
  </component>
  <component name="JsBuildToolGruntFileManager" detection-done="true" />
  <component name="JsBuildToolPackageJson" detection-done="true" />
  <component name="JsGulpfileManager">
    <detection-done>true</detection-done>
  </component>
  <component name="ProjectFrameBounds">
    <option name="y" value="23" />
    <option name="width" value="1440" />
    <option name="height" value="839" />
  </component>
  <component name="ProjectLevelVcsManager" settingsEditedManually="true">
    <OptionsSetting value="true" id="Add" />
    <OptionsSetting value="true" id="Remove" />
    <OptionsSetting value="true" id="Checkout" />
    <OptionsSetting value="true" id="Update" />
    <OptionsSetting value="true" id="Status" />
    <OptionsSetting value="true" id="Edit" />
    <ConfirmationsSetting value="0" id="Add" />
    <ConfirmationsSetting value="0" id="Remove" />
  </component>
  <component name="ProjectView">
    <navigator proportions="" version="1">
      <flattenPackages />
      <showMembers />
      <showModules />
      <showLibraryContents />
      <hideEmptyPackages />
      <abbreviatePackageNames />
      <autoscrollToSource />
      <autoscrollFromSource />
      <sortByType />
      <manualOrder />
      <foldersAlwaysOnTop value="true" />
    </navigator>
    <panes />
  </component>
  <component name="PropertiesComponent">
    <property name="WebServerToolWindowFactoryState" value="false" />
    <property name="settings.editor.selected.configurable" value="reference.settingsdialog.IDE.editor.colors.File Status" />
    <property name="settings.editor.splitter.proportion" value="0.2" />
  </component>
  <component name="RunManager" selected="RSpec.Run spec 'solitaire_spec': 001">
    <configuration default="false" name="Solitaire works: 001" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
      <predefined_log_file id="RUBY_RSPEC" enabled="true" />
      <module name="001" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
      <envs>
        <env name="JRUBY_OPTS" value="-X+O" />
      </envs>
      <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="true" />
      <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
      <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov">
        <COVERAGE_PATTERN ENABLED="true">
          <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
        </COVERAGE_PATTERN>
      </EXTENSION>
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/solitaire_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_RUNNER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_EXAMPLE_NAME" VALUE="Solitaire works" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_TEST_TYPE" VALUE="TEST_SCRIPT" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_ARGS" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUNNER_VERSION" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="USE_CUSTOM_SPEC_RUNNER" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="DRB" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ZEUS" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPRING" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
      <method />
    </configuration>
    <configuration default="false" name="Solitaire: 001" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
      <predefined_log_file id="RUBY_RSPEC" enabled="true" />
      <module name="001" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
      <envs>
        <env name="JRUBY_OPTS" value="-X+O" />
      </envs>
      <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="true" />
      <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
      <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov">
        <COVERAGE_PATTERN ENABLED="true">
          <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
        </COVERAGE_PATTERN>
      </EXTENSION>
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/solitaire_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_RUNNER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_EXAMPLE_NAME" VALUE="Solitaire" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_TEST_TYPE" VALUE="TEST_SCRIPT" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_ARGS" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUNNER_VERSION" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="USE_CUSTOM_SPEC_RUNNER" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="DRB" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ZEUS" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPRING" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
      <method />
    </configuration>
    <configuration default="false" name="Run spec 'solitaire_spec': 001" type="RSpecRunConfigurationType" factoryName="RSpec" temporary="true">
      <predefined_log_file id="RUBY_RSPEC" enabled="true" />
      <module name="001" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="$MODULE_DIR$" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
      <envs>
        <env name="JRUBY_OPTS" value="-X+O" />
      </envs>
      <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="true" />
      <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
      <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov">
        <COVERAGE_PATTERN ENABLED="true">
          <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
        </COVERAGE_PATTERN>
      </EXTENSION>
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="$MODULE_DIR$/spec/solitaire_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_RUNNER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_EXAMPLE_NAME" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_TEST_TYPE" VALUE="TEST_SCRIPT" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_ARGS" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUNNER_VERSION" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="USE_CUSTOM_SPEC_RUNNER" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="DRB" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ZEUS" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPRING" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
      <method />
    </configuration>
    <configuration default="true" type="CucumberRunConfigurationType" factoryName="Cucumber">
      <predefined_log_file id="RUBY_CUCUMBER" enabled="true" />
      <module name="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
      <envs />
      <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" />
      <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
      <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov">
        <COVERAGE_PATTERN ENABLED="true">
          <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
        </COVERAGE_PATTERN>
      </EXTENSION>
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*.feature" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_TEST_TYPE" VALUE="TEST_SCRIPT" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_TAGS_FILTER" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_NAME_FILTER" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="CUCUMBER_ARGS" VALUE="--color -r features" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="RUNNER_VERSION" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="VERBOSE_OPTION" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="DRB" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="ZEUS" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="SPRING" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="CUCUMBER_RUNNER_PATH" VALUE="" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="USE_CUSTOM_RUNNER" VALUE="false" />
      <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="SETTINGS_VERSION" VALUE="2" />
      <method />
    </configuration>
    <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
      <method />
    </configuration>
    <configuration default="true" type="RSpecRunConfigurationType" factoryName="RSpec">
      <predefined_log_file id="RUBY_RSPEC" enabled="true" />
      <module name="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
      <envs />
      <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" />
      <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
      <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov">
        <COVERAGE_PATTERN ENABLED="true">
          <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
        </COVERAGE_PATTERN>
      </EXTENSION>
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_RUNNER_PATH" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*_spec.rb" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_EXAMPLE_NAME" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="TEST_TEST_TYPE" VALUE="TEST_SCRIPT" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPEC_ARGS" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="RUNNER_VERSION" VALUE="" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="USE_CUSTOM_SPEC_RUNNER" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="DRB" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="ZEUS" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="SPRING" VALUE="false" />
      <RSPEC_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
      <method />
    </configuration>
    <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
      <node-options />
      <gulpfile />
      <tasks />
      <arguments />
      <envs />
      <method />
    </configuration>
    <configuration default="true" type="js.build_tools.npm" factoryName="npm">
      <command value="run-script" />
      <scripts />
      <envs />
      <method />
    </configuration>
    <list size="3">
      <item index="0" class="java.lang.String" itemvalue="RSpec.Solitaire works: 001" />
      <item index="1" class="java.lang.String" itemvalue="RSpec.Solitaire: 001" />
      <item index="2" class="java.lang.String" itemvalue="RSpec.Run spec 'solitaire_spec': 001" />
    </list>
    <recent_temporary>
      <list size="3">
        <item index="0" class="java.lang.String" itemvalue="RSpec.Run spec 'solitaire_spec': 001" />
        <item index="1" class="java.lang.String" itemvalue="RSpec.Solitaire: 001" />
        <item index="2" class="java.lang.String" itemvalue="RSpec.Solitaire works: 001" />
      </list>
    </recent_temporary>
  </component>
  <component name="ShelveChangesManager" show_recycled="false" />
  <component name="SvnConfiguration">
    <configuration />
  </component>
  <component name="TaskManager">
    <task active="true" id="Default" summary="Default task">
      <changelist id="6d6b01ad-579a-43a8-ba83-3f5f3dc96a76" name="Default" comment="" />
      <created>1447721222275</created>
      <option name="number" value="Default" />
      <updated>1447721222275</updated>
    </task>
    <servers />
  </component>
  <component name="TestHistory">
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 43m 49s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 44m 50s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 45m 07s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 45m 12s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 45m 29s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 45m 34s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 45m 54s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 46m 01s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 46m 58s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
    <history-entry file="Run_spec__solitaire_spec___001 - 2015.11.17 at 22h 47m 03s.xml">
      <configuration name="Run spec 'solitaire_spec': 001" configurationId="RSpecRunConfigurationType" />
    </history-entry>
  </component>
  <component name="ToolWindowManager">
    <frame x="0" y="23" width="1440" height="839" extended-state="0" />
    <editor active="true" />
    <layout>
      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3606371" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3993174" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
    </layout>
  </component>
  <component name="Vcs.Log.UiProperties">
    <option name="RECENTLY_FILTERED_USER_GROUPS">
      <collection />
    </option>
    <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
      <collection />
    </option>
  </component>
  <component name="VcsContentAnnotationSettings">
    <option name="myLimit" value="2678400000" />
  </component>
  <component name="XDebuggerManager">
    <breakpoint-manager>
      <breakpoints>
        <line-breakpoint enabled="true" type="ruby-line">
          <url>file://$PROJECT_DIR$/solitaire.rb</url>
          <line>34</line>
          <option name="timeStamp" value="2" />
        </line-breakpoint>
      </breakpoints>
      <option name="time" value="3" />
    </breakpoint-manager>
    <watches-manager />
  </component>
  <component name="editorHistoryManager">
    <entry file="file://$PROJECT_DIR$/spec/solitaire_spec.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0">
          <caret line="16" column="0" selection-start-line="16" selection-start-column="0" selection-end-line="16" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/solitaire.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0">
          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/spec/solitaire_spec.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0">
          <caret line="13" column="0" selection-start-line="13" selection-start-column="0" selection-end-line="13" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/solitaire.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0">
          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/spec/solitaire_spec.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0">
          <caret line="7" column="0" selection-start-line="7" selection-start-column="0" selection-end-line="7" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/solitaire.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.0">
          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$USER_HOME$/.rvm/gems/ruby-2.2.2@kata/gems/rspec-support-3.4.0/lib/rspec/support.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.35095137">
          <caret line="127" column="0" selection-start-line="127" selection-start-column="0" selection-end-line="127" selection-end-column="0" />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/solitaire.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.140625">
          <caret line="35" column="0" selection-start-line="35" selection-start-column="0" selection-end-line="35" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
    <entry file="file://$PROJECT_DIR$/spec/solitaire_spec.rb">
      <provider selected="true" editor-type-id="text-editor">
        <state vertical-scroll-proportion="0.4375">
          <caret line="16" column="0" selection-start-line="16" selection-start-column="0" selection-end-line="16" selection-end-column="0" />
          <folding />
        </state>
      </provider>
    </entry>
  </component>
</project>


text:
package com.github.dockerjava.jaxrs;

import java.io.InputStream;

import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.dockerjava.api.command.SaveImageCmd;
import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream;

public class SaveImageCmdExec extends AbstrDockerCmdExec<SaveImageCmd, InputStream> implements SaveImageCmd.Exec {
    private static final Logger LOGGER = LoggerFactory
            .getLogger(SaveImageCmdExec.class);

    public SaveImageCmdExec(WebTarget baseResource) {
        super(baseResource);
    }

    @Override
    protected InputStream execute(SaveImageCmd command) {
        WebTarget webResource = getBaseResource().path("/images/" + command.getName() + "/get")
                .queryParam("tag", command.getTag());

        LOGGER.trace("GET: {}", webResource);
        Response response =  webResource
                .request()
                .accept(MediaType.APPLICATION_JSON)
                .get();

        return new WrappedResponseInputStream(response);
    }
}


text:
export MFVERSION="2.5.0"
export MFPRJNAME="hstr-${MFVERSION}"
export AMD64NAME="hstr_${MFVERSION}-1_amd64"
export I386NAME="hstr_${MFVERSION}-1_i386"
export NOARCHNAME="hstr_${MFVERSION}-1_noarch"

echo "IMPORTANT: this script must be run as root!"

function decompose() {
    # cleanup
    rm -rvf ${MFPRJNAME} *.rpm

    # a) everything works just fine
    #alien -r hstr_0.7.1-1_amd64.deb

    # b) alien generates RPM that conflicts w/ other RPMs
    #    https://www.electricmonk.nl/log/2017/02/23/how-to-solve-rpms-created-by-alien-having-file-conflicts/
    alien -r -g -v "${AMD64NAME}.deb"

    # remove the following lines:
    #%dir "/"
    #%dir "/usr/bin/"
    sed -i 's#%dir "/"##' ${MFPRJNAME}/${MFPRJNAME}-2.spec
    sed -i 's#%dir "/usr/bin/"##' ${MFPRJNAME}/${MFPRJNAME}-2.spec
    sed -i 's#%dir "/usr/lib/"##' ${MFPRJNAME}/${MFPRJNAME}-2.spec
}

function compose() {
    # recreate RPM
    cd ${MFPRJNAME}
    export MFRPMROOT=`pwd`

    # bin build
    # --target=x86_64
    # --target=i386
    rpmbuild --target=x86_64 --buildroot ${MFRPMROOT}/ -bb ${MFPRJNAME}-2.spec
    # noarch would be for SOURCE deb
    #rpmbuild --target=noarch --buildroot ${MFRPMROOT}/ -bb ${MFPRJNAME}-2.spec
}

######################################################################################

# Steps:
# 1. run decompose
# 2. build HSTR manually (dependencies like libncursesw5 will be replaced w/ libncursesw6, etc.)
#    build/tarball/tarball-automake.sh > cd .. > ./configure > make
# 3. replace `hstr` binary in decomposed package ... so that compose can infer lib dependencies
#    supported on fedure
# 4. run compose
# 5. install rpm to verify package
#    sudo dnf install hstr-...rpm

#decompose
# build HSTR
# compose

# end