text:
#include <fstream>
#include <algorithm>

#include "mitkImage.h"
#include "mitkSurface.h"
#include "mitkStringProperty.h"
#include "mitkColorProperty.h"
#include "mitkGroupTagProperty.h"
#include "mitkDataNode.h"
#include "mitkReferenceCountWatcher.h"

#include "mitkDataStorage.h"
#include "mitkStandaloneDataStorage.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateSource.h"
#include "mitkMessage.h"
//#include "mitkPicFileReader.h"
#include "mitkTestingMacros.h"

#include "mitkItkImageFileReader.h"

void TestDataStorage(mitk::DataStorage* ds, std::string filename);

namespace mitk
{
  class TestStandaloneDataStorage: public StandaloneDataStorage
  {
  public:
    mitkClassMacro(TestStandaloneDataStorage, mitk::DataStorage);
    itkFactorylessNewMacro(Self)
    itkCloneMacro(Self)
    std::map<const mitk::DataNode*, unsigned long>
        GetModifiedObserverTags() const {return m_NodeModifiedObserverTags;}
    std::map<const mitk::DataNode*, unsigned long>
        GetDeletedObserverTags() const { return m_NodeDeleteObserverTags; }
  protected:
    TestStandaloneDataStorage() {}
  };
}

class DSEventReceiver // Helper class for event testing
{
public:
  const mitk::DataNode* m_NodeAdded;
  const mitk::DataNode* m_NodeRemoved;

  DSEventReceiver()
    : m_NodeAdded(NULL), m_NodeRemoved(NULL)
  {
  }

  void OnAdd(const mitk::DataNode* node)
  {
    m_NodeAdded = node;
  }

  void OnRemove(const mitk::DataNode* node)
  {
    m_NodeRemoved = node;
  }
};

///
/// \brief a class for checking if the datastorage is really thread safe
///
/// Therefore it listens to a node contained in the datastorage. when this node
/// gets removed and deleted, this class gets informed by calling OnObjectDelete().
/// in OnObjectDelete() an empty node gets added. this must not cause a deadlock
///
struct ItkDeleteEventListener
{
  ItkDeleteEventListener( mitk::DataStorage* ds )
  :   m_Node(0), m_DataStorage(ds),
  m_DeleteObserverTag(0)
  {
  }

  void SetNode( mitk::DataNode* _Node )
  {
    if(m_Node)
      return;

    m_Node = _Node;
    itk::MemberCommand<ItkDeleteEventListener>::Pointer onObjectDelete =
      itk::MemberCommand<ItkDeleteEventListener>::New();

    onObjectDelete->SetCallbackFunction(this, &ItkDeleteEventListener::OnObjectDelete);
    m_DeleteObserverTag = m_Node->AddObserver(itk::DeleteEvent(), onObjectDelete);
  }

  void OnObjectDelete( const itk::Object* /*caller*/, const itk::EventObject & )
  {
    mitk::DataNode::Pointer node = mitk::DataNode::New();
    m_DataStorage->Add( node ); // SHOULD NOT CAUSE A DEADLOCK!
    m_DataStorage->Remove( node ); // tidy up: remove the empty node again

    m_Node = 0;
  }

  protected:
    mitk::DataNode* m_Node;
    mitk::DataStorage::Pointer m_DataStorage;
    unsigned int m_DeleteObserverTag;
};

//## Documentation
//## main testing method
//## NOTE: the current Singleton implementation of DataTreeStorage will lead to crashes if a testcase fails
//##       and therefore mitk::DataStorage::ShutdownSingleton() is not called.
int mitkDataStorageTest(int argc, char* argv[])
{
  MITK_TEST_BEGIN("DataStorageTest");

  // muellerm: test observer tag remove
  mitk::TestStandaloneDataStorage::Pointer testDS
      = mitk::TestStandaloneDataStorage::New();
  mitk::DataNode::Pointer n1 = mitk::DataNode::New();
  testDS->Add(n1);
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetModifiedObserverTags().size()==1, "Testing if modified"
      " observer was added.");
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetDeletedObserverTags().size()==1, "Testing if delete"
      " observer was added.");
  testDS->Remove(n1);
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetModifiedObserverTags().size()==0, "Testing if modified"
      " observer was removed.");
  MITK_TEST_CONDITION_REQUIRED(
      testDS->GetDeletedObserverTags().size()==0, "Testing if delete"
      " observer was removed.");

  /* Create StandaloneDataStorage */
  MITK_TEST_OUTPUT( << "Create StandaloneDataStorage : ");
  mitk::StandaloneDataStorage::Pointer sds;
  try
  {
    sds = mitk::StandaloneDataStorage::New();
    MITK_TEST_CONDITION_REQUIRED(sds.IsNotNull(), "Testing Instatiation");
  }
  catch (...)
  {
    MITK_TEST_FAILED_MSG( << "Exception during creation of StandaloneDataStorage");
  }

  MITK_TEST_OUTPUT( << "Testing StandaloneDataStorage: ");
  MITK_TEST_CONDITION_REQUIRED(argc>1, "Testing correct test invocation");
  TestDataStorage(sds,argv[1]);
  // TODO: Add specific StandaloneDataStorage Tests here
  sds = NULL;

  MITK_TEST_END();
}

//##Documentation
//## @brief Test for the DataStorage class and its associated classes (e.g. the predicate classes)
//## This method will be called once for each subclass of DataStorage
void TestDataStorage( mitk::DataStorage* ds, std::string filename )
{
  /* DataStorage valid? */
  MITK_TEST_CONDITION_REQUIRED(ds != NULL, "DataStorage valid?");

  // Take the ItkImageFile Reader for the .nrrd data format.
  // (was previously pic which is now deprecated format)
  mitk::ItkImageFileReader::Pointer reader = mitk::ItkImageFileReader::New();
  reader -> SetFileName(filename.c_str());
  reader -> Update();
  mitk::Image::Pointer image = reader->GetOutput();

  // create some DataNodes to fill the ds
  mitk::DataNode::Pointer n1 = mitk::DataNode::New();   // node with image and name property
//  mitk::Image::Pointer image = mitk::Image::New();
//  unsigned int imageDimensions[] = { 10, 10, 10, 10 };
//  mitk::PixelType pt(typeid(int));
//  image->Initialize( pt, 4, imageDimensions );
  n1->SetData(image);
  n1->SetProperty("name", mitk::StringProperty::New("Node 1 - Image Node"));
  mitk::DataStorage::SetOfObjects::Pointer parents1 = mitk::DataStorage::SetOfObjects::New();

  mitk::DataNode::Pointer n2 = mitk::DataNode::New();   // node with surface and name and color properties
  mitk::Surface::Pointer surface = mitk::Surface::New();
  n2->SetData(surface);
  n2->SetProperty("name", mitk::StringProperty::New("Node 2 - Surface Node"));
  mitk::Color color;  color.Set(1.0f, 1.0f, 0.0f);
  n2->SetColor(color);
  n2->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
  mitk::DataStorage::SetOfObjects::Pointer parents2 = mitk::DataStorage::SetOfObjects::New();
  parents2->InsertElement(0, n1);  // n1 (image node) is source of n2 (surface node)

  mitk::DataNode::Pointer n3 = mitk::DataNode::New();   // node without data but with name property
  n3->SetProperty("name", mitk::StringProperty::New("Node 3 - Empty Node"));
  n3->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
  n3->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
  mitk::DataStorage::SetOfObjects::Pointer parents3 = mitk::DataStorage::SetOfObjects::New();
  parents3->InsertElement(0, n2);  // n2 is source of n3

  mitk::DataNode::Pointer n4 = mitk::DataNode::New();   // node without data but with color property
  n4->SetColor(color);
  n4->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
  mitk::DataStorage::SetOfObjects::Pointer parents4 = mitk::DataStorage::SetOfObjects::New();
  parents4->InsertElement(0, n2);
  parents4->InsertElement(1, n3);  // n2 and n3 are sources of n4

  mitk::DataNode::Pointer n5 = mitk::DataNode::New();   // extra node
  n5->SetProperty("name", mitk::StringProperty::New("Node 5"));

  try /* adding objects */
  {
    /* Add an object */
    ds->Add(n1, parents1);
    MITK_TEST_CONDITION_REQUIRED((ds->GetAll()->Size() == 1) && (ds->GetAll()->GetElement(0) == n1), "Testing Adding a new object");

    /* Check exception on adding the same object again */
    MITK_TEST_OUTPUT( << "Check exception on adding the same object again: ");
    MITK_TEST_FOR_EXCEPTION(..., ds->Add(n1, parents1));
    MITK_TEST_CONDITION(ds->GetAll()->Size() == 1, "Test if object count is correct after exception");

    /* Add an object that has a source object */
    ds->Add(n2, parents2);
    MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 2, "Testing Adding an object that has a source object");

    /* Add some more objects needed for further tests */
    ds->Add(n3, parents3);   // n3 object that has name property and one parent
    ds->Add(n4, parents4);   // n4 object that has color property
    ds->Add(n5);             // n5 has no parents
    MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 5, "Adding some more objects needed for further tests");
  }
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exeption during object creation");
  }

  try  /* object retrieval methods */
  {
    /* Requesting all Objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();

      MITK_TEST_CONDITION(
        (stlAll.size() == 5)  // check if all tree nodes are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()),
        "Testing GetAll()"
        );
    }
    /* Requesting a named object */
    {
      mitk::NodePredicateProperty::Pointer predicate(mitk::NodePredicateProperty::New("name", mitk::StringProperty::New("Node 2 - Surface Node")));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting a named object");
    }

    /* Requesting objects of specific data type */
    {
      mitk::NodePredicateDataType::Pointer predicate(mitk::NodePredicateDataType::New("Image"));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific data type")
    }
    /* Requesting objects of specific dimension */
    {
      mitk::NodePredicateDimension::Pointer predicate(mitk::NodePredicateDimension::New( 4 ));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific dimension")
    }
    /* Requesting objects with specific data object */
    {
      mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(image));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects with specific data object")
    }
    /* Requesting objects with NULL data */
    {
      mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(NULL));
      mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(all->begin(), all->end(), n3) != all->end())
        && (std::find(all->begin(), all->end(), n4) != all->end())
        && (std::find(all->begin(), all->end(), n5) != all->end())
        , "Requesting objects with NULL data");
    }
    /* Requesting objects that meet a conjunction criteria */
    {
      mitk::NodePredicateDataType::Pointer p1 = mitk::NodePredicateDataType::New("Surface");
      mitk::NodePredicateProperty::Pointer p2 = mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color));
      mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New();
      predicate->AddPredicate(p1);
      predicate->AddPredicate(p2);  // objects must be of datatype "Surface" and have red color (= n2)
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting objects that meet a conjunction criteria");
    }
    /* Requesting objects that meet a disjunction criteria */
    {
      mitk::NodePredicateDataType::Pointer p1(mitk::NodePredicateDataType::New("Image"));
      mitk::NodePredicateProperty::Pointer p2(mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color)));
      mitk::NodePredicateOr::Pointer predicate = mitk::NodePredicateOr::New();
      predicate->AddPredicate(p1);
      predicate->AddPredicate(p2);  // objects must be of datatype "Surface" or have red color (= n1, n2, n4)
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(all->begin(), all->end(), n1) != all->end())
        && (std::find(all->begin(), all->end(), n2) != all->end())
        && (std::find(all->begin(), all->end(), n4) != all->end()),
        "Requesting objects that meet a disjunction criteria");
    }
    /* Requesting objects that do not meet a criteria */
    {
      mitk::ColorProperty::Pointer cp = mitk::ColorProperty::New(color);
      mitk::NodePredicateProperty::Pointer proppred(mitk::NodePredicateProperty::New("color", cp));
      mitk::NodePredicateNot::Pointer predicate(mitk::NodePredicateNot::New(proppred));

      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3) // check if correct objects are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()), "Requesting objects that do not meet a criteria");
    }

    /* Requesting *direct* source objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, NULL, true); // Get direct parents of n3 (=n2)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
        "Requesting *direct* source objects");
    }

    /* Requesting *all* source objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n3, NULL, false); // Get all parents of n3 (= n1 + n2)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2)
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
        "Requesting *all* source objects"); // check if n1 and n2 are the resultset
    }

    /* Requesting *all* sources of object with multiple parents */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, NULL, false); // Get all parents of n4 (= n1 + n2 + n3)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
        , "Requesting *all* sources of object with multiple parents");
    }

    /* Requesting *direct* derived objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, NULL, true); // Get direct childs of n1 (=n2)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1)
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())// check if n1 is the resultset
        , "Requesting *direct* derived objects");
    }

    ///* Requesting *direct* derived objects with multiple parents/derivations */

    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n2, NULL, true); // Get direct childs of n2 (=n3 + n4)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2)
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n3 is the resultset
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) // check if n4 is the resultset
        , "Requesting *direct* derived objects with multiple parents/derivations");
    }

    //* Requesting *all* derived objects */
    {
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, NULL, false); // Get all childs of n1 (=n2, n3, n4)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        , "Requesting *all* derived objects");
    }

    /* Checking for circular source relationships */
    {
      parents1->InsertElement(0, n4);   // make n1 derived from n4 (which is derived from n2, which is derived from n1)
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, NULL, false); // Get all parents of n4 (= n1 + n2 + n3, not n4 itself and not multiple versions of the nodes!)
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 3)
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
        , "Checking for circular source relationships");
    }

    ///* Checking for circular derivation relationships can not be performed, because the internal derivations datastructure
    //   can not be accessed from the outside. (Therefore it should not be possible to create these circular relations */

    //* Checking GroupTagProperty */
    {
      mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
      mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 1", tp));
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2) // check if n2 and n3 are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        , "Checking GroupTagProperty");
    }

    /* Checking GroupTagProperty 2 */
    {
      mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
      mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 2", tp));
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2) // check if n3 and n4 are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        , "Checking GroupTagProperty 2");
    }

    /* Checking direct sources with condition */
    {
      mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Surface");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, true);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) // check if n2 is in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        , "checking direct sources with condition");
    }

    /* Checking all sources with condition */
    {
      mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Image");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) // check if n1 is in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end())
        , "Checking all sources with condition");
    }

    /* Checking all sources with condition with empty resultset */
    {
      mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("VesselTree");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
      MITK_TEST_CONDITION(all->Size() == 0 , "Checking all sources with condition with empty resultset"); // check if resultset is empty
    }

    /* Checking direct derivations with condition */
    {
      mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");
      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, true);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 1) // check if n2 is in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        , "Checking direct derivations with condition");
    }

    /* Checking all derivations with condition */
    {
      mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");

      const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, false);
      std::vector<mitk::DataNode::Pointer> stlAll = all->CastToSTLConstContainer();
      MITK_TEST_CONDITION(
        (all->Size() == 2) // check if n2 and n4 are in resultset
        && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end())
        && (std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end())
        , "Checking direct derivations with condition");
    }

    /* Checking named node method */
    MITK_TEST_CONDITION(ds->GetNamedNode("Node 2 - Surface Node") == n2, "Checking named node method");
    MITK_TEST_CONDITION(ds->GetNamedNode(std::string("Node 2 - Surface Node")) == n2, "Checking named node(std::string) method");

    /* Checking named node method with wrong name */
    MITK_TEST_CONDITION(ds->GetNamedNode("This name does not exist") == NULL, "Checking named node method with wrong name");

    /* Checking named object method */
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>("Node 1 - Image Node") == image, "Checking named object method");
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>(std::string("Node 1 - Image Node")) == image, "Checking named object(std::string) method");

    /* Checking named object method with wrong DataType */
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Surface>("Node 1 - Image Node") == NULL, "Checking named object method with wrong DataType");

    /* Checking named object method with wrong name */
    MITK_TEST_CONDITION(ds->GetNamedObject<mitk::Image>("This name does not exist") == NULL, "Checking named object method with wrong name");

    /* Checking GetNamedDerivedNode with valid name and direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 2 - Surface Node", n1, true) == n2, "Checking GetNamedDerivedNode with valid name & direct derivation only");

    /* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("wrong name", n1, true) == NULL, "Checking GetNamedDerivedNode with invalid name & direct derivation only");

    /* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, false) == n3, "Checking GetNamedDerivedNode with invalid name & direct derivation only");

    /* Checking GetNamedDerivedNode with valid Name but direct derivation only */
    MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, true) == NULL, "Checking GetNamedDerivedNode with valid Name but direct derivation only");

    /* Checking GetNode with valid predicate */
    {
      mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("Image"));
      MITK_TEST_CONDITION(ds->GetNode(p) == n1, "Checking GetNode with valid predicate");
    }
    /* Checking GetNode with invalid predicate */
    {
      mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("PointSet"));
      MITK_TEST_CONDITION(ds->GetNode(p) == NULL, "Checking GetNode with invalid predicate");
    }
  } // object retrieval methods
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exeption during object retrieval (GetXXX() Methods)");
  }

  try  /* object removal methods */
  {
    /* Checking removal of a node without relations */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));
      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      ds->Add(extra);
      MITK_TEST_CONDITION(ds->GetNamedNode("extra") == extra, "Adding extra node");
      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        , "Checking removal of a node without relations");
      extra = NULL;
    }

    /* Checking removal of a node with a parent */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));

      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      ds->Add(extra, n1);   // n1 is parent of extra

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetDerivations(n1)->Size() == 2)   // n2 and extra should be derived from n1
        , "Adding extra node");
      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetDerivations(n1)->Size() == 1)
        , "Checking removal of a node with a parent");
      extra = NULL;
    }

    /* Checking removal of a node with two parents */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));

      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
      p->push_back(n1);
      p->push_back(n2);
      ds->Add(extra, p);   // n1 and n2 are parents of extra

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetDerivations(n1)->Size() == 2)    // n2 and extra should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 3)
        , "add extra node");

      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetDerivations(n1)->Size() == 1)   // after remove, only n2 should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 2)   // after remove, only n3 and n4 should be derived from n2
        , "Checking removal of a node with two parents");
      extra = NULL;
    }

    /* Checking removal of a node with two derived nodes */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));
      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      int refCountbeforeDS = watcher->GetReferenceCount();
      ds->Add(extra);
      mitk::DataNode::Pointer d1 = mitk::DataNode::New();
      d1->SetProperty("name", mitk::StringProperty::New("d1"));
      ds->Add(d1, extra);
      mitk::DataNode::Pointer d2 = mitk::DataNode::New();
      d2->SetProperty("name", mitk::StringProperty::New("d2"));
      ds->Add(d2, extra);

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetNamedNode("d1") == d1)
        && (ds->GetNamedNode("d2") == d2)
        && (ds->GetSources(d1)->Size() == 1)    // extra should be source of d1
        && (ds->GetSources(d2)->Size() == 1)    // extra should be source of d2
        && (ds->GetDerivations(extra)->Size() == 2)    // d1 and d2 should be derived from extra
        , "add extra node");

      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (ds->GetNamedNode("d1") == d1)
        && (ds->GetNamedNode("d2") == d2)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetSources(d1)->Size() == 0)   // after remove, d1 should not have a source anymore
        && (ds->GetSources(d2)->Size() == 0)   // after remove, d2 should not have a source anymore
        , "Checking removal of a node with two derived nodes");
      extra = NULL;
    }

    /* Checking removal of a node with two parents and two derived nodes */
    {
      mitk::DataNode::Pointer extra = mitk::DataNode::New();
      extra->SetProperty("name", mitk::StringProperty::New("extra"));
      mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
      mitk::ReferenceCountWatcher::Pointer n1watcher = new mitk::ReferenceCountWatcher(n1);
      int refCountbeforeDS = watcher->GetReferenceCount();

      mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
      p->push_back(n1);
      p->push_back(n2);
      ds->Add(extra, p);   // n1 and n2 are parents of extra

      mitk::DataNode::Pointer d1 = mitk::DataNode::New();
      d1->SetProperty("name", mitk::StringProperty::New("d1x"));
      ds->Add(d1, extra);
      mitk::DataNode::Pointer d2 = mitk::DataNode::New();
      d2->SetProperty("name", mitk::StringProperty::New("d2x"));
      ds->Add(d2, extra);

      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == extra)
        && (ds->GetNamedNode("d1x") == d1)
        && (ds->GetNamedNode("d2x") == d2)
        && (ds->GetSources(d1)->Size() == 1)    // extra should be source of d1
        && (ds->GetSources(d2)->Size() == 1)    // extra should be source of d2
        && (ds->GetDerivations(n1)->Size() == 2)    // n2 and extra should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 3)   // n3, n4 and extra should be derived from n2
        && (ds->GetDerivations(extra)->Size() == 2)    // d1 and d2 should be derived from extra
        , "add extra node");

      ds->Remove(extra);
      MITK_TEST_CONDITION(
        (ds->GetNamedNode("extra") == NULL)
        && (ds->GetNamedNode("d1x") == d1)
        && (ds->GetNamedNode("d2x") == d2)
        && (refCountbeforeDS == watcher->GetReferenceCount())
        && (ds->GetDerivations(n1)->Size() == 1)    // after remove, only n2 should be derived from n1
        && (ds->GetDerivations(n2)->Size() == 2)    // after remove, only n3 and n4 should be derived from n2
        && (ds->GetSources(d1)->Size() == 0)        // after remove, d1 should not have a source anymore
        && (ds->GetSources(d2)->Size() == 0)       // after remove, d2 should not have a source anymore
        , "Checking removal of a node with two parents and two derived nodes");
      extra = NULL;
    }
  }
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exeption during object removal methods");
  }

  /* Checking for node is it's own parent exception */
  {
    MITK_TEST_FOR_EXCEPTION_BEGIN(...);
    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    extra->SetProperty("name", mitk::StringProperty::New("extra"));
    mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
    p->push_back(n1);
    p->push_back(extra); // extra is parent of extra!!!
    ds->Add(extra, p);
    MITK_TEST_FOR_EXCEPTION_END(...);
  }

  /* Checking reference count of node after add and remove */
  {
    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
    extra->SetProperty("name", mitk::StringProperty::New("extra"));
    mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
    p->push_back(n1);
    p->push_back(n3);
    ds->Add(extra, p);
    extra = NULL;
    ds->Remove(ds->GetNamedNode("extra"));
    MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Checking reference count of node after add and remove");
  }

  /* Checking removal of a node with two derived nodes [ dataStorage->GetDerivations( rootNode )] see bug #3426 */
  {
    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    extra->SetProperty("name", mitk::StringProperty::New("extra"));

    ds->Add(extra);
    mitk::DataNode::Pointer d1y = mitk::DataNode::New();
    d1y->SetProperty("name", mitk::StringProperty::New("d1y"));
    mitk::ReferenceCountWatcher::Pointer watcherD1y = new mitk::ReferenceCountWatcher(d1y);
    int refCountbeforeDS = watcherD1y->GetReferenceCount();
    ds->Add(d1y, extra);
    mitk::DataNode::Pointer d2y = mitk::DataNode::New();
    d2y->SetProperty("name", mitk::StringProperty::New("d2y"));
    ds->Add(d2y, extra);

    MITK_TEST_CONDITION(
      (ds->GetNamedNode("extra") == extra)
      && (ds->GetNamedNode("d1y") == d1y)
      && (ds->GetNamedNode("d2y") == d2y)
      && (ds->GetSources(d1y)->Size() == 1)    // extra should be source of d1y
      && (ds->GetSources(d2y)->Size() == 1)    // extra should be source of d2y
      && (ds->GetDerivations(extra)->Size() == 2)    // d1y and d2y should be derived from extra
      , "add extra node");

    ds->Remove(ds->GetDerivations( extra));
    MITK_TEST_CONDITION(
      (ds->GetNamedNode("extra") == extra)
      && (ds->GetNamedNode("d1y") == NULL) // d1y should be NULL now
      && (ds->GetNamedNode("d2y") == NULL) // d2y should be NULL now
      && (refCountbeforeDS == watcherD1y->GetReferenceCount())
      , "Checking removal of subset of two derived nodes from one parent node");

    ds->Remove(extra);
    MITK_TEST_CONDITION(
      (ds->GetNamedNode("extra") == NULL)
      , "Checking removal of a parent node");
    extra = NULL;
  }

  /* Checking GetGrouptags() */
  {
    const std::set<std::string> groupTags = ds->GetGroupTags();
    MITK_TEST_CONDITION(
      (groupTags.size() == 2)
      && (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 1") != groupTags.end())
      && (std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 2") != groupTags.end())
      , "Checking GetGrouptags()");
  }

  /* Checking Event handling */
  DSEventReceiver listener;
  try
  {
    ds->AddNodeEvent += mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
    ds->RemoveNodeEvent += mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);

    mitk::DataNode::Pointer extra = mitk::DataNode::New();
    mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
    ds->Add(extra);

    MITK_TEST_CONDITION(listener.m_NodeAdded == extra.GetPointer(), "Checking AddEvent");

    ds->Remove(extra);
    MITK_TEST_CONDITION(listener.m_NodeRemoved == extra.GetPointer(), "Checking RemoveEvent");

    /* RemoveListener */
    ds->AddNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
    ds->RemoveNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
    listener.m_NodeAdded = NULL;
    listener.m_NodeRemoved = NULL;
    ds->Add(extra);
    ds->Remove(extra);
    MITK_TEST_CONDITION((listener.m_NodeRemoved == NULL) && (listener.m_NodeAdded == NULL), "Checking RemoveListener");

    std::cout << "Pointer handling after event handling: " << std::flush;
    extra = NULL; // delete reference to the node. its memory should be freed now
    MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Pointer handling after event handling");
  }
  catch(...)
  {
    /* cleanup */
    ds->AddNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnAdd);
    ds->RemoveNodeEvent -= mitk::MessageDelegate1<DSEventReceiver, const mitk::DataNode*>(&listener, &DSEventReceiver::OnRemove);
    MITK_TEST_FAILED_MSG( << "Exception during object removal methods");
  }

  //Checking ComputeBoundingGeometry3D method*/
  const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
  mitk::TimeGeometry::Pointer geometry = ds->ComputeBoundingGeometry3D();
  MITK_TEST_CONDITION(geometry->CountTimeSteps()==4, "Test for number or time steps with ComputeBoundingGeometry()");
  mitk::TimeBounds timebounds = geometry->GetTimeBounds();
  MITK_TEST_CONDITION((timebounds[0]==0)&&(timebounds[1]==4),"Test for timebounds with ComputeBoundingGeometry()");
  for (unsigned int i=0; i<geometry->CountTimeSteps(); i++)
  {
    mitk::BaseGeometry::Pointer subGeometry = geometry->GetGeometryForTimeStep(i);
    mitk::TimeBounds bounds = geometry->GetTimeBounds(i);
    MITK_TEST_CONDITION((bounds[0]==i)&&(bounds[1]==i+1),"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
  }
  geometry = ds->ComputeBoundingGeometry3D(all);
  MITK_TEST_CONDITION(geometry->CountTimeSteps()==4, "Test for number or time steps with ComputeBoundingGeometry(allNodes)");
  timebounds = geometry->GetTimeBounds();
  MITK_TEST_CONDITION((timebounds[0]==0)&&(timebounds[1]==4),"Test for timebounds with ComputeBoundingGeometry(allNodes)");
  for (unsigned int i=0; i<geometry->CountTimeSteps(); i++)
  {
    mitk::BaseGeometry::Pointer subGeometry = geometry->GetGeometryForTimeStep(i);
    mitk::TimeBounds bounds = geometry->GetTimeBounds(i);
    MITK_TEST_CONDITION((bounds[0]==i)&&(bounds[1]==i+1),"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
  }

  // test for thread safety of DataStorage
  try
  {
    mitk::StandaloneDataStorage::Pointer standaloneDataStorage
        = mitk::StandaloneDataStorage::New();
    ItkDeleteEventListener listener( standaloneDataStorage );
    {
      mitk::DataNode::Pointer emptyNode = mitk::DataNode::New();
      mitk::DataNode* pEmptyNode = emptyNode;
      listener.SetNode( emptyNode );
      standaloneDataStorage->Add( emptyNode );
      emptyNode = 0; // emptyNode is still alive because standaloneDataStorage
                     // owns it
      standaloneDataStorage->Remove( pEmptyNode ); // this should not freeze the whole thing
    }
  }
  catch(...)
  {
    MITK_TEST_FAILED_MSG( << "Exception during testing DataStorage thread safe");
  }

  /* Clear DataStorage */
  ds->Remove(ds->GetAll());
  MITK_TEST_CONDITION(ds->GetAll()->Size() == 0, "Checking Clear DataStorage");
}


text:
package ztls

import (
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"strings"

	"github.com/zmap/zgrab/ztools/keys"
	"github.com/zmap/zgrab/ztools/x509"
)

var ErrUnimplementedCipher error = errors.New("unimplemented cipher suite")
var ErrNoMutualCipher error = errors.New("no mutual cipher suite")

type TLSVersion uint16

type CipherSuite uint16

type ClientHello struct {
	Random         []byte `json:"random"`
	ExtendedRandom []byte `json:"extended_random,omitempty"`
	SessionID      []byte `json:"session_id,omitempty"`
}

type ServerHello struct {
	Version              TLSVersion  `json:"version"`
	Random               []byte      `json:"random"`
	SessionID            []byte      `json:"session_id"`
	CipherSuite          CipherSuite `json:"cipher_suite"`
	CompressionMethod    uint8       `json:"compression_method"`
	OcspStapling         bool        `json:"ocsp_stapling"`
	TicketSupported      bool        `json:"ticket"`
	SecureRenegotiation  bool        `json:"secure_renegotiation"`
	HeartbeatSupported   bool        `json:"heartbeat"`
	ExtendedRandom       []byte      `json:"extended_random,omitempty"`
	ExtendedMasterSecret bool        `json:"extended_master_secret"`
}

// SimpleCertificate holds a *x509.Certificate and a []byte for the certificate
type SimpleCertificate struct {
	Raw    []byte            `json:"raw,omitempty"`
	Parsed *x509.Certificate `json:"parsed,omitempty"`
}

// Certificates represents a TLS certificates message in a format friendly to the golang JSON library.
// ValidationError should be non-nil whenever Valid is false.
type Certificates struct {
	Certificate SimpleCertificate   `json:"certificate,omitempty"`
	Chain       []SimpleCertificate `json:"chain,omitempty"`
	Validation  *x509.Validation    `json:"validation,omitempty"`
}

// ServerKeyExchange represents the raw key data sent by the server in TLS key exchange message
type ServerKeyExchange struct {
	Raw            []byte             `json:"-"`
	RSAParams      *keys.RSAPublicKey `json:"rsa_params,omitempty"`
	DHParams       *keys.DHParams     `json:"dh_params,omitempty"`
	ECDHParams     *keys.ECDHParams   `json:"ecdh_params,omitempty"`
	Signature      *DigitalSignature  `json:"signature,omitempty"`
	SignatureError string             `json:"signature_error,omitempty"`
}

// ClientKeyExchange represents the raw key data sent by the client in TLS key exchange message
type ClientKeyExchange struct {
	Raw        []byte                `json:"-"`
	RSAParams  *keys.RSAClientParams `json:"rsa_params,omitempty"`
	DHParams   *keys.DHParams        `json:"dh_params,omitempty"`
	ECDHParams *keys.ECDHParams      `json:"ecdh_params,omitempty"`
}

// Finished represents a TLS Finished message
type Finished struct {
	VerifyData []byte `json:"verify_data"`
}

// SessionTicket represents the new session ticket sent by the server to the
// client
type SessionTicket struct {
	Value        []uint8 `json:"value,omitempty"`
	Length       int     `json:"length,omitempty"`
	LifetimeHint uint32  `json:"lifetime_hint,omitempty"`
}

type MasterSecret struct {
	Value  []byte `json:"value,omitempty"`
	Length int    `json:"length,omitempty"`
}

type PreMasterSecret struct {
	Value  []byte `json:"value,omitempty"`
	Length int    `json:"length,omitempty"`
}

// KeyMaterial explicitly represent the cryptographic values negotiated by
// the client and server
type KeyMaterial struct {
	MasterSecret    *MasterSecret    `json:"master_secret,omitempty"`
	PreMasterSecret *PreMasterSecret `json:"pre_master_secret,omitempty"`
}

// ServerHandshake stores all of the messages sent by the server during a standard TLS Handshake.
// It implements zgrab.EventData interface
type ServerHandshake struct {
	ClientHello        *ClientHello       `json:"client_hello,omitempty"`
	ServerHello        *ServerHello       `json:"server_hello,omitempty"`
	ServerCertificates *Certificates      `json:"server_certificates,omitempty"`
	ServerKeyExchange  *ServerKeyExchange `json:"server_key_exchange,omitempty"`
	ClientKeyExchange  *ClientKeyExchange `json:"client_key_exchange,omitempty"`
	ClientFinished     *Finished          `json:"client_finished,omitempty"`
	SessionTicket      *SessionTicket     `json:"session_ticket,omitempty"`
	ServerFinished     *Finished          `json:"server_finished,omitempty"`
	KeyMaterial        *KeyMaterial       `json:"key_material,omitempty"`
}

// MarshalJSON implements the json.Marshler interface
func (v *TLSVersion) MarshalJSON() ([]byte, error) {
	aux := struct {
		Name  string `json:"name"`
		Value int    `json:"value"`
	}{
		Name:  v.String(),
		Value: int(*v),
	}
	return json.Marshal(&aux)
}

// UnmarshalJSON implements the json.Unmarshaler interface
func (v *TLSVersion) UnmarshalJSON(b []byte) error {
	aux := struct {
		Name  string `json:"name"`
		Value int    `json:"value"`
	}{}
	if err := json.Unmarshal(b, &aux); err != nil {
		return err
	}
	*v = TLSVersion(aux.Value)
	if expectedName := v.String(); expectedName != aux.Name {
		return fmt.Errorf("mismatched tls version and name: version: %d, name: %s, expected name: %s", aux.Value, aux.Name, expectedName)
	}
	return nil
}

// MarshalJSON implements the json.Marshler interface
func (cs *CipherSuite) MarshalJSON() ([]byte, error) {
	buf := make([]byte, 2)
	buf[0] = byte(*cs >> 8)
	buf[1] = byte(*cs)
	enc := strings.ToUpper(hex.EncodeToString(buf))
	aux := struct {
		Hex   string `json:"hex"`
		Name  string `json:"name"`
		Value int    `json:"value"`
	}{
		Hex:   fmt.Sprintf("0x%s", enc),
		Name:  cs.String(),
		Value: int(*cs),
	}
	return json.Marshal(&aux)
}

// UnmarshalJSON implements the json.Unmarshaler interface
func (cs *CipherSuite) UnmarshalJSON(b []byte) error {
	aux := struct {
		Hex   string `json:"hex"`
		Name  string `json:"name"`
		Value uint16 `json:"value"`
	}{}
	if err := json.Unmarshal(b, &aux); err != nil {
		return err
	}
	if expectedName := nameForSuite(aux.Value); expectedName != aux.Name {
		return fmt.Errorf("mismatched cipher suite and name, suite: %d, name: %s, expected name: %s", aux.Value, aux.Name, expectedName)
	}
	*cs = CipherSuite(aux.Value)
	return nil
}

func (c *Conn) GetHandshakeLog() *ServerHandshake {
	return c.handshakeLog
}

func (c *Conn) InCipher() (cipher interface{}) {
	return c.in.cipher
}

func (c *Conn) InSeq() []byte {
	return c.in.seq[:]
}

func (c *Conn) OutCipher() (cipher interface{}) {
	return c.out.cipher
}

func (c *Conn) OutSeq() []byte {
	return c.out.seq[:]
}

func (m *clientHelloMsg) MakeLog() *ClientHello {
	ch := new(ClientHello)
	ch.Random = make([]byte, len(m.random))
	copy(ch.Random, m.random)
	ch.SessionID = make([]byte, len(m.sessionId))
	copy(ch.SessionID, m.sessionId)
	if len(m.extendedRandom) > 0 {
		ch.ExtendedRandom = make([]byte, len(m.extendedRandom))
		copy(ch.ExtendedRandom, m.extendedRandom)
	}
	return ch
}

func (m *serverHelloMsg) MakeLog() *ServerHello {
	sh := new(ServerHello)
	sh.Version = TLSVersion(m.vers)
	sh.Random = make([]byte, len(m.random))
	copy(sh.Random, m.random)
	sh.SessionID = make([]byte, len(m.sessionId))
	copy(sh.SessionID, m.sessionId)
	sh.CipherSuite = CipherSuite(m.cipherSuite)
	sh.CompressionMethod = m.compressionMethod
	sh.OcspStapling = m.ocspStapling
	sh.TicketSupported = m.ticketSupported
	sh.SecureRenegotiation = m.secureRenegotiation
	sh.HeartbeatSupported = m.heartbeatEnabled
	if len(m.extendedRandom) > 0 {
		sh.ExtendedRandom = make([]byte, len(m.extendedRandom))
		copy(sh.ExtendedRandom, m.extendedRandom)
	}
	sh.ExtendedMasterSecret = m.extendedMasterSecret
	return sh
}

func (m *certificateMsg) MakeLog() *Certificates {
	sc := new(Certificates)
	if len(m.certificates) >= 1 {
		cert := m.certificates[0]
		sc.Certificate.Raw = make([]byte, len(cert))
		copy(sc.Certificate.Raw, cert)
	}
	if len(m.certificates) >= 2 {
		chain := m.certificates[1:]
		sc.Chain = make([]SimpleCertificate, len(chain))
		for idx, cert := range chain {
			sc.Chain[idx].Raw = make([]byte, len(cert))
			copy(sc.Chain[idx].Raw, cert)
		}
	}
	return sc
}

// addParsed sets the parsed certificates and the validation. It assumes the
// chain slice has already been allocated.
func (c *Certificates) addParsed(certs []*x509.Certificate, validation *x509.Validation) {
	if len(certs) >= 1 {
		c.Certificate.Parsed = certs[0]
	}
	if len(certs) >= 2 {
		chain := certs[1:]
		for idx, cert := range chain {
			c.Chain[idx].Parsed = cert
		}
	}
	c.Validation = validation
}

func (m *serverKeyExchangeMsg) MakeLog(ka keyAgreement) *ServerKeyExchange {
	skx := new(ServerKeyExchange)
	skx.Raw = make([]byte, len(m.key))
	var auth keyAgreementAuthentication
	var errAuth error
	copy(skx.Raw, m.key)

	// Write out parameters
	switch ka := ka.(type) {
	case *rsaKeyAgreement:
		skx.RSAParams = ka.RSAParams()
		auth = ka.auth
		errAuth = ka.verifyError
	case *dheKeyAgreement:
		skx.DHParams = ka.DHParams()
		auth = ka.auth
		errAuth = ka.verifyError
	case *ecdheKeyAgreement:
		skx.ECDHParams = ka.ECDHParams()
		auth = ka.auth
		errAuth = ka.verifyError
	default:
		break
	}

	// Write out signature
	switch auth := auth.(type) {
	case *signedKeyAgreement:
		skx.Signature = auth.Signature()
	default:
		break
	}

	// Write the signature validation error
	if errAuth != nil {
		skx.SignatureError = errAuth.Error()
	}

	return skx
}

func (m *finishedMsg) MakeLog() *Finished {
	sf := new(Finished)
	sf.VerifyData = make([]byte, len(m.verifyData))
	copy(sf.VerifyData, m.verifyData)
	return sf
}

func (m *ClientSessionState) MakeLog() *SessionTicket {
	st := new(SessionTicket)
	st.Length = len(m.sessionTicket)
	st.Value = make([]uint8, st.Length)
	copy(st.Value, m.sessionTicket)
	st.LifetimeHint = m.lifetimeHint
	return st
}

func (m *clientHandshakeState) MakeLog() *KeyMaterial {
	keymat := new(KeyMaterial)

	keymat.MasterSecret = new(MasterSecret)
	keymat.MasterSecret.Length = len(m.masterSecret)
	keymat.MasterSecret.Value = make([]byte, len(m.masterSecret))
	copy(keymat.MasterSecret.Value, m.masterSecret)

	keymat.PreMasterSecret = new(PreMasterSecret)
	keymat.PreMasterSecret.Length = len(m.preMasterSecret)
	keymat.PreMasterSecret.Value = make([]byte, len(m.preMasterSecret))
	copy(keymat.PreMasterSecret.Value, m.preMasterSecret)

	return keymat
}

func (m *clientKeyExchangeMsg) MakeLog(ka keyAgreement) *ClientKeyExchange {
	ckx := new(ClientKeyExchange)
	ckx.Raw = make([]byte, len(m.raw))
	copy(ckx.Raw, m.raw)

	switch ka := ka.(type) {
	case *rsaKeyAgreement:
		ckx.RSAParams = new(keys.RSAClientParams)
		ckx.RSAParams.Length = uint16(len(m.ciphertext) - 2) // First 2 bytes are length
		ckx.RSAParams.EncryptedPMS = make([]byte, len(m.ciphertext)-2)
		copy(ckx.RSAParams.EncryptedPMS, m.ciphertext[2:])
		// Premaster-Secret is available in KeyMaterial record
	case *dheKeyAgreement:
		ckx.DHParams = ka.ClientDHParams()
	case *ecdheKeyAgreement:
		ckx.ECDHParams = ka.ClientECDHParams()
	default:
		break
	}

	return ckx
}

redpajama_set_name: RedPajamaGithub


text:
Template['lobbyProfesorNav'].helpers({
  isGruposBloqueados: function() {
    return this.isGroupsLocked;
  }
});

Template['lobbyProfesorNav'].events({
  'click #btnBloquearGrupos': function() {
    Meteor.call('setGroupLock', {
      idPartida: this._id,
      isGroupsLocked: true
    });
  },
  'click #btnDesbloquearGrupos': function() {
    Meteor.call('setGroupLock', {
      idPartida: this._id,
      isGroupsLocked: false
    });
  },
  'click #btnForzarGrupos': function(){
    console.log({idPartida: this._id});
    Meteor.call('forzarGrupos', {idPartida: this._id});
  }
});


text:
<?php

class Google_Service_Firestore_GoogleFirestoreAdminV1Index extends Google_Collection
{
  protected $collection_key = 'fields';
  protected $fieldsType = 'Google_Service_Firestore_GoogleFirestoreAdminV1IndexField';
  protected $fieldsDataType = 'array';
  public $name;
  public $queryScope;
  public $state;

  /**
   * @param Google_Service_Firestore_GoogleFirestoreAdminV1IndexField
   */
  public function setFields($fields)
  {
    $this->fields = $fields;
  }
  /**
   * @return Google_Service_Firestore_GoogleFirestoreAdminV1IndexField
   */
  public function getFields()
  {
    return $this->fields;
  }
  public function setName($name)
  {
    $this->name = $name;
  }
  public function getName()
  {
    return $this->name;
  }
  public function setQueryScope($queryScope)
  {
    $this->queryScope = $queryScope;
  }
  public function getQueryScope()
  {
    return $this->queryScope;
  }
  public function setState($state)
  {
    $this->state = $state;
  }
  public function getState()
  {
    return $this->state;
  }
}


text:
package ru.job4j.shapes;

/**
 * Created on 08.09.2017.
 *
 * Starting class.
 *
 * @author Aleks Sidorenko (alek.sidorenko1979@gmail.com).
 * @version $Id$.
 * @since 0.1.
 */
public class StartShape {

    /**
     * Main method.
     * @param args - array.
     */
    public static void main(String[] args) {
        Paint paint = new Paint();
        paint.draw(new Triangle());
        paint.draw(new Square());
    }
}


text:
import mixin from '../utils/mixin';

/**
* Represents a node in a LinkedList.
* Initializes a new instance of the LinkedListNode class, containing the specified value.
* @param {Object} value The value to contain in the LinkedListNode
*/
export default function LinkedListNode(value) {
    this._value = value;
    this._list = null;
    this._next = null;
    this._prev = null;
}

mixin(LinkedListNode, {
    /**
    * Gets the value contained in the node.
    * @returns {Object}
    */
    value: function () {
        return this._value;
    },

    /**
    * Gets the LinkedList that the LinkedListNode belongs to.
    * @returns {LinkedList}
    */
    list: function () {
        return this._list;
    },

    /**
    * Gets the next node in the LinkedList.
    * @returns {LinkedListNode}
    */
    next: function () {
        return this._next === null || this._next === this._list.head ? null : this._next;
    },

    /**
    * Gets the previous node in the LinkedList.
    * @returns {LinkedListNode}
    */
    previous: function () {
        return this._prev === null || this === this._list.head ? null : this._prev;
    },

    toString: function () {
        return '[LinkedList Node]';
    }
});


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>STOR: std::hash< esft::stor::document > Struct Template Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

STOR

Server-less, Embeddable NoSQL Document Store

std

hash< esft::stor::document >

Public Member Functions |
List of all members

std::hash< esft::stor::document > Struct Template Reference

Public Member Functions

std::size_t 	operator() (const esft::stor::document &d) const

The documentation for this struct was generated from the following file:

include/stor/document/document.h

<address class="footer">
Generated by

 1.8.13
</address>


text:
Rooms Module
============

.. automodule:: Rooms
    :members:
    :undoc-members:
    :show-inheritance:


text:
<?php

namespace Nhiepphong\Backend\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Sentinel;
use Nhiepphong\Backend\Commands;

class BackendServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        if (! $this->app->routesAreCached()) {
            require __DIR__.'/../routes.php';
        }

        //View
        $this->loadViewsFrom(dirname(__DIR__).'/resources/views', 'backend');

        //Assets
        //Run cmd: php artisan vendor:publish --tag=public --force
        $this->publishes([
            __DIR__.'/../resources/assets' => public_path('packages/nhiepphong/assets'),
            dirname(__DIR__).'/resources/views' => base_path('resources/views/vendor/backend'),
        ], 'public');
        View::share('assetURL', asset('packages/nhiepphong/assets') . "/");
        define("ROOT_ASSET", asset('packages/nhiepphong/assets') . "/");
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        require_once __DIR__ . '/../Helpers/MainHelper.php';
        require_once __DIR__ . '/../Helpers/InputHelper.php';

        /*
         * Register the service provider for the dependency.
         */
        $imageProvider = new \Intervention\Image\ImageServiceProvider($this->app);
        $imageProvider->register();
        /*
         * Create aliases for the dependency.
         */
        $loader = \Illuminate\Foundation\AliasLoader::getInstance();
        $loader->alias('Image', 'Intervention\Image\Facades\Image');

        $this->app['backend::install'] = $this->app->share(function()
        {
            return new \Nhiepphong\Backend\Commands\BackendCommand();
        });

        $this->commands('backend::install');

    }
}


text:
package org.docksidestage.postgresql.dbflute.bsentity;

import java.util.List;
import java.util.ArrayList;

import org.dbflute.Entity;
import org.dbflute.dbmeta.DBMeta;
import org.dbflute.dbmeta.AbstractEntity;
import org.dbflute.dbmeta.accessory.DomainEntity;
import org.dbflute.optional.OptionalEntity;
import org.docksidestage.postgresql.dbflute.allcommon.DBMetaInstanceHandler;
import org.docksidestage.postgresql.dbflute.exentity.*;

/**
 * The entity of white_same_name_ref as TABLE.

 *

 * [primary-key]
 *     same_name_ref_id
 *
 * [column]
 *     same_name_ref_id, same_name_id, next_same_name_id
 *
 * [sequence]
 *
 *
 * [identity]
 *
 *
 * [version-no]
 *
 *
 * [foreign table]
 *     white_same_name
 *
 * [referrer table]
 *
 *
 * [foreign property]
 *     whiteSameName
 *
 * [referrer property]
 *
 *
 * [get/set template]
 * /= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 * Integer sameNameRefId = entity.getSameNameRefId();
 * Long sameNameId = entity.getSameNameId();
 * Long nextSameNameId = entity.getNextSameNameId();
 * entity.setSameNameRefId(sameNameRefId);
 * entity.setSameNameId(sameNameId);
 * entity.setNextSameNameId(nextSameNameId);
 * = = = = = = = = = =/
 *

 * @author DBFlute(AutoGenerator)
 */
public abstract class BsWhiteSameNameRef extends AbstractEntity implements DomainEntity {

    // ===================================================================================
    //                                                                          Definition
    //                                                                          ==========
    /** The serial version UID for object serialization. (Default) */
    private static final long serialVersionUID = 1L;

    // ===================================================================================
    //                                                                           Attribute
    //                                                                           =========
    /** same_name_ref_id: {PK, NotNull, int4(10)} */
    protected Integer _sameNameRefId;

    /** same_name_id: {NotNull, int8(19), FK to white_same_name} */
    protected Long _sameNameId;

    /** next_same_name_id: {NotNull, int8(19)} */
    protected Long _nextSameNameId;

    // ===================================================================================
    //                                                                             DB Meta
    //                                                                             =======
    /** {@inheritDoc} */
    public DBMeta asDBMeta() {
        return DBMetaInstanceHandler.findDBMeta(asTableDbName());
    }

    /** {@inheritDoc} */
    public String asTableDbName() {
        return "white_same_name_ref";
    }

    // ===================================================================================
    //                                                                        Key Handling
    //                                                                        ============
    /** {@inheritDoc} */
    public boolean hasPrimaryKeyValue() {
        if (_sameNameRefId == null) { return false; }
        return true;
    }

    // ===================================================================================
    //                                                                    Foreign Property
    //                                                                    ================
    /** white_same_name by my same_name_id, named 'whiteSameName'. */
    protected OptionalEntity<WhiteSameName> _whiteSameName;

    /**
     * [get] white_same_name by my same_name_id, named 'whiteSameName'.

     * Optional: alwaysPresent(), ifPresent().orElse(), get(), ...
     * @return The entity of foreign property 'whiteSameName'. (NotNull, EmptyAllowed: when e.g. null FK column, no setupSelect)
     */
    public OptionalEntity<WhiteSameName> getWhiteSameName() {
        if (_whiteSameName == null) { _whiteSameName = OptionalEntity.relationEmpty(this, "whiteSameName"); }
        return _whiteSameName;
    }

    /**
     * [set] white_same_name by my same_name_id, named 'whiteSameName'.
     * @param whiteSameName The entity of foreign property 'whiteSameName'. (NullAllowed)
     */
    public void setWhiteSameName(OptionalEntity<WhiteSameName> whiteSameName) {
        _whiteSameName = whiteSameName;
    }

    // ===================================================================================
    //                                                                   Referrer Property
    //                                                                   =================
    protected <ELEMENT> List<ELEMENT> newReferrerList() { // overriding to import
        return new ArrayList<ELEMENT>();
    }

    // ===================================================================================
    //                                                                      Basic Override
    //                                                                      ==============
    @Override
    protected boolean doEquals(Object obj) {
        if (obj instanceof BsWhiteSameNameRef) {
            BsWhiteSameNameRef other = (BsWhiteSameNameRef)obj;
            if (!xSV(_sameNameRefId, other._sameNameRefId)) { return false; }
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected int doHashCode(int initial) {
        int hs = initial;
        hs = xCH(hs, asTableDbName());
        hs = xCH(hs, _sameNameRefId);
        return hs;
    }

    @Override
    protected String doBuildStringWithRelation(String li) {
        StringBuilder sb = new StringBuilder();
        if (_whiteSameName != null && _whiteSameName.isPresent())
        { sb.append(li).append(xbRDS(_whiteSameName, "whiteSameName")); }
        return sb.toString();
    }
    protected <ET extends Entity> String xbRDS(org.dbflute.optional.OptionalEntity<ET> et, String name) { // buildRelationDisplayString()
        return et.get().buildDisplayString(name, true, true);
    }

    @Override
    protected String doBuildColumnString(String dm) {
        StringBuilder sb = new StringBuilder();
        sb.append(dm).append(xfND(_sameNameRefId));
        sb.append(dm).append(xfND(_sameNameId));
        sb.append(dm).append(xfND(_nextSameNameId));
        if (sb.length() > dm.length()) {
            sb.delete(0, dm.length());
        }
        sb.insert(0, "{").append("}");
        return sb.toString();
    }

    @Override
    protected String doBuildRelationString(String dm) {
        StringBuilder sb = new StringBuilder();
        if (_whiteSameName != null && _whiteSameName.isPresent())
        { sb.append(dm).append("whiteSameName"); }
        if (sb.length() > dm.length()) {
            sb.delete(0, dm.length()).insert(0, "(").append(")");
        }
        return sb.toString();
    }

    @Override
    public WhiteSameNameRef clone() {
        return (WhiteSameNameRef)super.clone();
    }

    // ===================================================================================
    //                                                                            Accessor
    //                                                                            ========
    /**
     * [get] same_name_ref_id: {PK, NotNull, int4(10)}

     * @return The value of the column 'same_name_ref_id'. (basically NotNull if selected: for the constraint)
     */
    public Integer getSameNameRefId() {
        checkSpecifiedProperty("sameNameRefId");
        return _sameNameRefId;
    }

    /**
     * [set] same_name_ref_id: {PK, NotNull, int4(10)}

     * @param sameNameRefId The value of the column 'same_name_ref_id'. (basically NotNull if update: for the constraint)
     */
    public void setSameNameRefId(Integer sameNameRefId) {
        registerModifiedProperty("sameNameRefId");
        _sameNameRefId = sameNameRefId;
    }

    /**
     * [get] same_name_id: {NotNull, int8(19), FK to white_same_name}

     * @return The value of the column 'same_name_id'. (basically NotNull if selected: for the constraint)
     */
    public Long getSameNameId() {
        checkSpecifiedProperty("sameNameId");
        return _sameNameId;
    }

    /**
     * [set] same_name_id: {NotNull, int8(19), FK to white_same_name}

     * @param sameNameId The value of the column 'same_name_id'. (basically NotNull if update: for the constraint)
     */
    public void setSameNameId(Long sameNameId) {
        registerModifiedProperty("sameNameId");
        _sameNameId = sameNameId;
    }

    /**
     * [get] next_same_name_id: {NotNull, int8(19)}

     * @return The value of the column 'next_same_name_id'. (basically NotNull if selected: for the constraint)
     */
    public Long getNextSameNameId() {
        checkSpecifiedProperty("nextSameNameId");
        return _nextSameNameId;
    }

    /**
     * [set] next_same_name_id: {NotNull, int8(19)}

     * @param nextSameNameId The value of the column 'next_same_name_id'. (basically NotNull if update: for the constraint)
     */
    public void setNextSameNameId(Long nextSameNameId) {
        registerModifiedProperty("nextSameNameId");
        _nextSameNameId = nextSameNameId;
    }
}


text:
class CreatePeople < ActiveRecord::Migration
  def change
    create_table :people do |t|
      t.string :account
      t.string :full_name
      t.string :chinese_name
      t.string :preferred_name
      t.string :email
      t.string :pinyin_name

      t.timestamps
    end
  end
end


text:
package ro.fortsoft.pf4j;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.fortsoft.pf4j.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

/**
 * Read the plugin descriptor from the manifest file.
 *
 * @author Decebal Suiu
 */
public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {

	private static final Logger log = LoggerFactory.getLogger(ManifestPluginDescriptorFinder.class);

	private PluginClasspath pluginClasspath;
        private PluginManager pluginManager;

	public ManifestPluginDescriptorFinder(PluginClasspath pluginClasspath, PluginManager pluginManager) {
		this.pluginClasspath = pluginClasspath;
            this.pluginManager = pluginManager;
	}

	@Override
	public PluginDescriptor find(File pluginRepository) throws PluginException {
    	// TODO it's ok with first classes directory? Another idea is to specify in PluginClasspath the folder.
		String classes = pluginClasspath.getClassesDirectories().get(0);
        File manifestFile = new File(pluginRepository, classes + "/META-INF/MANIFEST.MF");
        log.debug("Lookup plugin descriptor in '{}'", manifestFile);
        if (!manifestFile.exists()) {
            throw new PluginException("Cannot find '" + manifestFile + "' file");
        }

    	FileInputStream input = null;
		try {
			input = new FileInputStream(manifestFile);
		} catch (FileNotFoundException e) {
			// not happening
		}

    	Manifest manifest = null;
        try {
            manifest = new Manifest(input);
        } catch (IOException e) {
            throw new PluginException(e.getMessage(), e);
        } finally {
            try {
				input.close();
			} catch (IOException e) {
				throw new PluginException(e.getMessage(), e);
			}
        }

        PluginDescriptor pluginDescriptor = new PluginDescriptor(pluginManager);

        // TODO validate !!!
        Attributes attrs = manifest.getMainAttributes();
        String id = attrs.getValue("Plugin-Id");
        if (StringUtils.isEmpty(id)) {
        	throw new PluginException("Plugin-Id cannot be empty");
        }
        pluginDescriptor.setPluginId(id);

        String description = attrs.getValue("Plugin-Description");
        if (StringUtils.isEmpty(description)) {
        	pluginDescriptor.setPluginDescription("");
        } else {
            pluginDescriptor.setPluginDescription(description);
        }

        String clazz = attrs.getValue("Plugin-Class");
        if (StringUtils.isEmpty(clazz)) {
        	throw new PluginException("Plugin-Class cannot be empty");
        }
        pluginDescriptor.setPluginClass(clazz);

        String version = attrs.getValue("Plugin-Version");
        if (StringUtils.isEmpty(version)) {
        	throw new PluginException("Plugin-Version cannot be empty");
        }
        pluginDescriptor.setPluginVersion(Version.createVersion(version), version);

        pluginDescriptor.setProvider(attrs.getValue("Plugin-Provider"));
        pluginDescriptor.setTitle(attrs.getValue("Implementation-Title"));
        pluginDescriptor.setArtifactID(attrs.getValue("Artifact-ID"));
        pluginDescriptor.setServerID(attrs.getValue("Server-ID"));
        pluginDescriptor.setSDKVersion(attrs.getValue("SDK-Version"));
        pluginDescriptor.setDependencies(attrs.getValue("Plugin-Dependencies")); // Make sure this is below SDKVersion

        String requires = attrs.getValue("Plugin-Requires");
        if (StringUtils.isNotEmpty(requires)) {
        	pluginDescriptor.setRequires(Version.createVersion(requires));
        }

        pluginDescriptor.setAddOnProperties();
		return pluginDescriptor;
	}

}


text:
FROM node:latest
MAINTAINER Rob Loach <robloach@gmail.com>

# Install DocPad globally.

RUN npm install -g docpad

# DocPad authentication.

RUN echo "{\n  subscribed: false\n  subscribeTryAgain: false\n  tos: true\n  identified: true\n}" > ~/.docpad.cson

# Set up the application directory.

VOLUME ["/app"]
WORKDIR /app

# Expose the default DocPad port.

EXPOSE 9778

# Launch DocPad when the container stars, passing through any arguments.

CMD ["-"]
ENTRYPOINT ["docpad"]


text:
[![Build Status](https://circleci.com/gh/citypay/citypay-pan-search.svg?&style=shield)](https://circleci.com/gh/citypay/citypay-pan-search)

CityPay's PAN search is a Scala/Java tool for searching locations for the existence of sensitive primary cardholder data.

The scanner is able to scan multiple sources such as
  - Multiple Operating Systems including Microsoft ® Windows 32/64, Mac OSX 32/64, Linux 32/64, Arm
  - Local Filesystems
  - Databases (via JDBC drivers such as MySql, SQLServer, Oracle etc)
  - WebSites (Future Planned)
  - Archives, catering for compression streams such as `7-Zip`, `Zip`, `Rar`, `Tar`, `
      Split`, `Lzma`, `Iso`, `HFS`, `GZip`, `Cpio`, `BZip2`, `Z`, `Arj`, `Chm`, `Lhz`, `Cab`, `Nsis`, `Deb`, `Rpm`

*Compliance Information*

  Note that all card holder data including PANs within unit tests supplied with this source code
  are *test data* and generated with a valid luhn checksum.

## Pre-requisites

To run the search tool you will need to ensure a valid Java 8 runtime is installed on the system.

## Installation and Getting Started

The scanner can create a deployment package by using [sbt-native-packager](http://www.scala-sbt.org/sbt-native-packager/index.html)
and running one of the following

- Generate a deployment zip `sbt universal:packageBin`
- Generate a deployment tarball `sbt universal:packageZipTarball`
- Generate a deployment Xz tarball `sbt universal:packageXzTarball`

To run the scanner, extract the deployment archive to a directory (`CP_SEARCH_ROOT`). The directories should appear
  1. `bin` contains binary files `bin/citypay-pan-search` and `bin/citypay-pan-search.bat` for executing the bin search
  2. `conf` contains configuration files as listed below
  3. `lib` contains library files used by the pan search process

Once running, execute the binary file `bin/citypay-pan-search` and you will be presented with a console progress bar
   ``` scanner-svc-0|========================> | A: 61400 | C: 61400 | M: 1520 | 0100%```

## Configuration Options

Configuration is found in 3 core logging files `search.conf`, `chd.conf` and `scanner.conf`

### Search Configuration

| Parameter | Data Type | Description |
|-----------|-----------|-------------|
| search    | `object`    | holder for search configuration |
| search.source    | `object`    | holder for source configurations |
| type | `string` | The type of search based on `ScanSourceConfigFactory` such as `file`, `db` |

#### File Searching

| Parameter | Data Type | Description |
|-----------|-----------|-------------|
| type | `string` | "file" |
| root | `string[]` | array of root directories to search  |
| includeHiddenFiles | `boolean` | whether hidden files are scanned. Hidden files are either marked as _hidden_ by the file system or start with "." |
| recursive | `boolean` | whether to recursively scan a root directory. Default value is `true` |
| maxDepth | `int` | the maximum number of directories to scan into |

#### Database Searching

Database searching requires a valid driver which must be provided in the classpath

| Parameter | Data Type | Description |
|-----------|-----------|-------------|
| type | `string` | "db" |
| driver | `string` | The class name of the jdbc driver to use i.e. "com.mysql.jdbc.Driver" |
| url | `string` | The connection url string to use to provide a connection to the database, Consult the driver documentation for details of examples and configuration of connection strings |
| schema | `string` | The database schema to connect to |
| tableNameRegex | `string` | A regular expression of the table names to scan. This will be dependant on your database setup |
| colNameRegex | `string` | A regular expression of column names to scan |
| credentials | `string` | A class implementation of a `com.citypay.pan.search.util.CredentialsCallback` preconfigured examples are `com.citypay.pan.search.util.NoOpCredentials` which does not provide credentials that may be previously supplied in the connection url. `com.citypay.pan.search.util.CommandLineCredentials` provide a callback function to the command line to enter the username and password at the time of the scan. |

### Scanner Configuration

| Parameter | Data Type | Description |
|-----------|-----------|-------------|
| analaysisBufferSz | `int` | The size of the buffer to use when reading from a file, defaults to 16384 |
| concurrentScans | `int` | The number of concurrent scan processes to run. A scan process is a search configuration such as file system search, database search etc |
| scanArchives | `boolean` | Whether to scan archive files by expanding them for analysis in RAM or temp files.  |
| scanWorkers | `int` | The number of concurrent file scans to perform within a concurrent scan.  |
| stopOnFirstMatch | `boolean` | If a value is found the search will exit the file, reporting that an item was found.  Any further items will not be listed. If the value is false, the entire file will be searched and all items reported |
| renderer | `string` | A renderer to produce a report by, defaults to "json" |
| prettify | `boolean` | A boolean value whether the renderer should pretty print which is easier for human reading |

### Card Holder Data Configuration

| Parameter | Data Type | Description |
|-----------|-----------|-------------|
| chd.level1 | `chd object` | Contains an array of chd specs for analysis at a level 1 stage. Should be short digits for fast searching. Recommended as 1 or 2 digits |
| chd.level2 | `chd object` | Contains an array of chd specs for analysis at a level 2 stage. Should be longer than level1 by 1 or more positions. The more accurate these values, the less false positives are found |
| chd.falsePositives | `string array` | Contains an array of false positive strings which are checked at the point that a match is found. Examples are `2222222222222222` |

CHD Specs

| Parameter | Data Type | Description |
|-----------|-----------|-------------|
| name | `string `| The name of the card scheme spec |
| id | `string `| An id of the spec to identify by, will group via the id when testing for schemes |
| logo | `string `| The name of a logo file associated with the scheme |
| len | `string `| The length of the scheme provided as a single value of a range of values specified with a dash such as 16 or 16-19 |
| bins | `int[]` | An array of ints that form the leading values for analysis |

## Scanning Algorithm

The scanner uses an algorithm to assess whether the file contains sensitive data with the purpose
to scan against multiple character sets and encrypted files.

 ### Character Definition
- Scan characters are defined as numeric groups (*N*) `[\u0030-\u0039]` with delimiters of `[\u0020\u002D\u0009]`
  being space, comma and tab. In _PAN_ storage, this would find examples such as `4000000000000002`,
  `4000-0000-0000-0002`, `4000 0000 0000 0002`. A combination of both characters are labelled as _D_

### Input Stream analysis

  Data is collated and analysed from an input stream buffer of `analysisBufferSz` bytes. If a `N` digit is found it is
  appended to the inspection buffer and its index position marked. If the next character is "out of bounds" being a non
  _D_ character, the stream is reset. Should the next character match it is appended and the overall length of the
   inspection buffer vs the minimum pan length is checked. If we are in an inspection range, we move to an inspection
   process.  This manner of providing multiple buffers aids in preventing over analysis of data.

### PAN Inspection

Pan inspection analyses the incoming bytes and collates bytes based on matching characters in _D_ until a non _D_
character occurs or a buffer limit is obtained. In a data file it is expected that delimiters such as ',\n' etc will
divide items accordingly, to prevent overflows a buffer limit is included.

Once enough data is buffered for analysis, we use a modified version of the Knuth Morris Pratt algorithm
([KMP](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm)).

An example is to run the algorithm as `W` = "45NNNNNNNNNNNNNN" where N and `S` = "4514500000000000000000012325",
_N_ is a numeric value with a length of 16.
- `m`, denoting the position within `S` where the prospective match for `W` begins,
- `i`, denoting the index of the currently considered character in `W`

In each step the algorithm compares `S[m+i]` with `W[i]` and increments `i` if they are equal. This is illustrated at
the start, such as:

```
             1         2            3         4
m: 0123456789012345678901201234567890123456789012
S: 4514500000000000000000012325
W: 45NNNNNNNNNNNNNN
i: 0123456789012345
                  L
```

At the point that the required number of digits are found, a luhn check is performed to confirm that it is indeed
a card number. Should the luhn check fail, the algorithm either continues (if there is a range in length i.e. 16-19)

```
             1         2            3         4
m: 0123456789012345678901201234567890123456789012
S: 4514500000000000000000012325
W: 45NNNNNNNNNNNNNNNNN
i: 0123456789012345678
                   LLL
```

If no match is found, it searches from the next instance, where `m = 3`.

```
             1         2            3         4
m: 0123456789012345678901201234567890123456789012
S: 4514500000000000000000012325
W:    45NNNNNNNNNNNNNN
i:    0123456789012345
                     L
```

For further information see

1. https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
2. http://algs4.cs.princeton.edu/53substring/KMP.java.html

## Troubleshooting

  The scanner provides full trace logs for analysis of its processes and can be enabled by providing a java
  system property of `pan.search.trace` when running the scan. It can be run in multiple combinations set
  out in the table below, delimited with a comma or by setting the value to `all` e.g.
  `java com.citypay.pan.sesarch.Scanner -Dpan.search.trace=all` Any trace logging will be sent to
  System.out by default.

  | Key | Description |
  |-----|-------------|
  | `analysisBuffer` | trace logging for the analysis buffer which is run when searching the buffer for card data. The analysis buffer is run on level 1 pans only |
  | `analysisBufferL2` | trace logging for the abalysis buffer which is run on a level 2 search, after level 1 has found results. |
  | `db` | trace logging for database column searches |
  | `inspectionScanner` | used on the inspection buffer to analysis the inspection routines |

## Reporting

The scanner outputs a JSON file containing the results of the scan which can be loaded via HTML to construct
working reports to meet compliance.


text:
/*
Copyright (c) 2007-2008, Magnus Deininger
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
	  this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
	  this list of conditions and the following disclaimer in the documentation
	  and/or other materials provided with the distribution.
    * Neither the name of the project nor the names of its contributors may be
	  used to endorse or promote products derived from this software without
	  specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef EINIT_TREE_H
#define EINIT_TREE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <inttypes.h>
#include <einit/event.h>
#include <sys/types.h>
#include <einit/itree.h>

struct stree {
 struct itree *treenode;
 char *key;
 void *value;
 void *luggage;
 struct stree *next;
};

struct stree *streeadd (const struct stree *stree, const char *key, const void *value, int32_t vlen, const void *luggage);
struct stree *streefind (const struct stree *stree, const char *key, enum tree_search_base options);
struct stree *streedel (struct stree *subject);
void streefree (struct stree *stree);

struct stree *streelinear_prepare (struct stree *st);
#define streenext(h) h->next

#ifdef __cplusplus
}
#endif

#endif


text:
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace CookieMVC.Web
{
    public class LogProviderInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component.For<ILogger>()
                .ImplementedBy<ElmahLogger>()
                .LifestyleTransient());
        }
    }
}


text:
.. _dojo/back:

=========
dojo.back
=========

:since: V1.0

.. contents ::
    :depth: 2

dojo.back allows you to update the browser history, so that it's possible to use the Back- and Forward-buttons of a Browser without leaving the web application.

**NOTE**: There are problems with using dojo.back with semantically-named fragment identifiers ("hash values" on an URL). In most browsers it will be hard for dojo.back to know distinguish a back from a forward event in those cases. For back/forward support to work best, the fragment ID should always be a unique value (something using new Date().getTime() for example). If you want to detect hash changes using semantic fragment IDs, then consider using :ref:`dojo.hash <dojo/hash>` instead (in Dojo 1.4+).

Usage
=====

Initialization
--------------

To use dojo.back:

1. Add the appropriate require statement:

   .. js ::

      require(["dojo/back"], function(back){

      });

2. Register the initial state of the page by calling:

   .. js ::

      require(["dojo/back"], function(back){
          back.setInitialState(state);
      });

   This state object will be called when the user clicks Back all the way back to the start of the web application. If the user clicks Back once more, they will go back in the browser to wherever they were before loading the web application.

   The state object should have the following functions defined:

   * For receiving Back notifications: back(), backButton() or handle(type), where type will either be the string "back" or "forward".
   * For receiving Forward notifications: forward(), forwardButton() or handle(type), where type will either be the string "back" or "forward".

   Example of a very simple state object:

   .. js ::

       var state = {
           back: function(){ alert("Back was clicked!"); },
           forward: function(){ alert("Forward was clicked!"); }
       };
   ..

3. Call dojo.back.init(); inside a script tag that is inside the  tag:

   .. html ::

         (rest of the body here)

   ..

**WARNING:** back.init() must be called before the page's DOM is finished loading. Otherwise it will not work. Be careful with xdomain loading or dojoConfig.debugAtAllCosts scenarios, in order for this method to work, dojo.back will need to be part of a build layer.

Register a state object
-----------------------

To register a state object that represents the result of a user action, use the following call:

.. js ::

  require(["dojo/back"], function(back){
     back.addToHistory(state);
  });

Change the URL in the location bar
----------------------------------

To change the URL in the browser's location bar, include a **changeUrl** property on the state object.

* If this property is set to true, dojo.back will generate a unique value for the fragment identifier.
* If it is set to any other value (except undefined, null, 0 or empty string), then that value will be used as the fragment identifier.

This will allow users to bookmark the page.

Examples
========

TODO

bookmarkable
------------

A simple demo of dojo.back - it's bookmarkable and based on the tests/back.html

**BROKEN**
**this isn't working in the sandbox - needs to be a fullblown page ... leaving it here till i figure out if it can be done**

dojo.back needs either a local dojo.js or a local iframe_history.html

.. code-example::

  .. js ::

            dojo.require("dojo.back");

            ApplicationState = function(stateData, outputDivId, backForwardOutputDivId, bookmarkValue){
                this.stateData = stateData;
                this.outputDivId = outputDivId;
                this.backForwardOutputDivId = backForwardOutputDivId;
                this.changeUrl = bookmarkValue || false;
            }

            dojo.extend(ApplicationState, {
                back: function(){ this.showStateData( "we got here going back" ); },
                forward: function(){ this.showStateData( "we got here going forward" ); },
                showStateData: function(msg){
                    dojo.byId(this.outputDivId).innerHTML = "msg: " + msg + '
';
                    dojo.byId(this.outputDivId).innerHTML += this.stateData + '
';
                }
            });

            var data = {
                link0: "This is the initial state (page first loaded)",
                "link with spaces": "This is data for a state with spaces",
                "link%20with%20encoded": "This is data for a state with encoded bits",
                "link+with+pluses": "This is data for a state with pluses",
                link1: "This is data for link 1",
                link2: "This is data for link 2",
                link3: "This is data for link 3",
                link4: "This is data for link 4",
                link5: "This is data for link 5",
                link6: "This is data for link 6",
                link7: "This is data for link 7"
            };

            function goNav(id){
                var appState = new ApplicationState(data[id], "output", "dataOutput", id);
                appState.showStateData( "we got here by clicking" );
                dojo.back.addToHistory(appState);
            }

            djConfig.dojoIframeHistoryUrl = "{{dataUrl}}/dojo/back?action=AttachFile&do=get&target=iframe_history.html";
            dojo.back.init();

            dojo.ready(function(){
                var link = unescape( new dojo._Url( document.URL ).fragment || "link0" );
                var appState = new ApplicationState(data[ link ], "output", "dataOutput");
                appState.showStateData( "initial state" );
                dojo.back.setInitialState(appState);
            });

  .. html ::

dojo.back test

            <button onclick="goNav('link1')">Link 1</button>

            <button onclick="goNav('link with spaces')">Link with Spaces</button>

            <button onclick="goNav('link%20with%20encoded')">Link with Encoded</button>

            <button onclick="goNav('link+with+pluses')">Link with Pluses</button>

            <button onclick="goNav('link3')">Link 3</button>

            <button onclick="goNav('link4')">Link 4</button>

            <button onclick="goNav('link5')">Link 5</button>

            <button onclick="goNav('link6')">Link 6</button>

            <button onclick="goNav('link7')">Link 7</button>

            Data Output:

            Back/Forward Info:


text:
SYNONYM

#### According to
GRIN Taxonomy for Plants

#### Published in
J. D. Hooker, Fl. Brit. India 4:150. 1883

#### Original name
null

### Remarks
null


text:
const PlotCard = require('../../plotcard.js');

class BreakingTies extends PlotCard {
    setupCardAbilities(ability) {
        this.action({
            title: 'Return character/location to hand',
            limit: ability.limit.perRound(2),
            cost: ability.costs.sacrifice(card => card.isLoyal() && card.getType() === 'character'),
            target: {
                activePromptTitle: 'Select character or location',
                cardCondition: card => card.location === 'play area' && !card.isLoyal() &&
                                       ['character', 'location'].includes(card.getType()),
                gameAction: 'returnToHand'
            },
            handler: context => {
                context.target.owner.returnCardToHand(context.target);
                this.game.addMessage('{0} uses {1} and sacrifices {2} to return {3} to {4}\'s hand',
                    context.player, this, context.costs.sacrifice, context.target, context.target.owner);
            }
        });
    }
}

BreakingTies.code = '10050';

module.exports = BreakingTies;


text:
var range = require('ipv4-range');
var session = require ("net-ping").createSession({timeout: 500});
var ping = session.pingHost.bind(session);
var arp = require('arp-a');

var events = require('events'),
    util = require("util");

function setIntervalAndExecute(fn, t) {
    fn();
    return(setInterval(fn, t));
}

var DEFAULT_FREQUENCY = 60;

var populateARP = function(address, total, callback) {
    var count = total, ips = {};

    // Get a range of surrounding IP addresses
    range(address, total).forEach(function( address, index) {
        ping(address, function(err, target) {
            if (err) ips[address] = false;
            ips[address] = true;
            // Populate ARP table by pinging the IPs
            if (--count === 0) {
                callback(ips) ;
            }
        });
    });
}

var getConnectedClients = function(startIP, total, callback) {
    var activeClients = {};
    // Populate ARP tale
    populateARP(startIP, total, function(ips) {
        arp.table(function(err, entry) {
            if (err) return callback(err, activeClients);

            if (entry && ips[entry.ip]) {
                // alive client
                activeClients[entry.mac] = entry.ip;
            }
            if (!entry) {
                // arp-p also callback after the last entry with both null arguments.
                callback(null, activeClients);
            }
        });
    });
}

var Monitor = function (options) {
    this.timer = null;
    this.previous = {};
    events.EventEmitter.call(this);
    this.ping(options);
}
util.inherits(Monitor, events.EventEmitter);

Monitor.prototype.ping = function(options) {
    var stream = this;

    if (typeof options !== 'object') return; // No specs, bail out
    var startIP = options.startIP || this.startIP; // Either new ping, or resume
    if (!startIP) return; // No known startIP, bail out
    var total = options.total || 1;

    this.startIP = startIP;
    this.frequency = (options.frequency || this.frequency || DEFAULT_FREQUENCY) * 1000;

    this.timer = setIntervalAndExecute(function() {
        getConnectedClients(startIP, total, function(err, activeClients) {
            if (err) {
                stream.emit("error", err);
            } else {
                var previous = stream.previous, updates = {};
                for(var mac in activeClients){
                    var ip = activeClients[mac];
                    updates[mac] = ip; // Clone the new data.
                    if (previous.hasOwnProperty(mac)){
                        // Remove all duplicate clients from previous list
                        // so that it only contains old clients.
                        delete previous[mac];
                    } else {
                        stream.emit("in", {mac: mac, ip: ip});
                    }
                }
                for (var mac in previous) {
                    var ip = previous[mac];
                    // After the first loop, previous now only contains old clients
                    stream.emit("out", {mac: mac, ip: ip});
                }
                stream.emit("update", activeClients);
                stream.previous = updates;
            }
        });
    }, stream.frequency);
}

Monitor.prototype.stop = function() {
    if (this.timer) clearInterval(this.timer);
}

Monitor.prototype.pause = function() {
    if (this.timer) clearInterval(this.timer);
}

Monitor.prototype.resume = function(options) {
    this.stop();
    this.poll(options);
}

module.exports.ping = ping;
module.exports.populateARP = populateARP;
module.exports.getConnectedClients = getConnectedClients;
module.exports.Monitor = Monitor;


text:
CMD="/usr/local/bin/aws ecs register-task-definition --region $AWS_REGION --cli-input-json file://$PWD/task-definitions/asgard-hid-generator.json"
echo $CMD
$CMD


text:
**Status**: Tested
**Description**: IBM BigInsights Hadoop Big Data offering.
**Maintainer**:       Cloudify
**Maintainer email**: cloudifysource@gigaspaces.com
**Contributors**:    [yoramw](https://github.com/yoramw)
**Homepage**:   [http://www.cloudifysource.org](http://www.cloudifysource.org)
**License**:      Apache 2.0
**Build**: [Cloudify 2.2.0 ](http://repository.cloudifysource.org/org/cloudifysource/2.2.0/gigaspaces-cloudify-2.2.0-ga-b2499-48.zip)
**Linux* sudoer permissions**:	Required
**Windows***:  Not Supported
**Release Date**: Sep 26th 2012

Tested on:
--------

 * EC2:
 * RHEL 6.2 imageId "us-east-1/ami-852190ec", hardwareId "m1.medium", locationId "us-east-1"
 * OpenStack:
 * CentOs 6.2: imageId "414" CentOS 6.2 Server 64-bit, hardwareId "103" standard.large - 4 vCPU /8 GB RAM /240 GB , az-1.region-a.geo-1

Synopsis
--------

This folder contains a service recipe for the Hadoop-BigInsights application.
For more information, see http://blog.gigaspaces.com/cloudify-and-ibm-infosphere-biginsights/
*Make sure to replace the private key with your own generate key for both the master and data services


text:
namespace MassTransit.DependencyInjection
{
    using System;
    using System.Threading.Tasks;

    public class RequestHandlerMethod<TMessage, TResponse>
        where TMessage : class
        where TResponse : class
    {
        public RequestHandlerMethod(Func<ConsumeContext<TMessage>, Task<TResponse>> handler)
        {
            Handler = handler;
        }

        public RequestHandlerMethod(Func<TMessage, Task<TResponse>> handler)
        {
            Handler = context => handler(context.Message);
        }

        public Func<ConsumeContext<TMessage>, Task<TResponse>> Handler { get; }
    }

    public class RequestHandlerMethod<TMessage, T1, TResponse>
        where TMessage : class
        where T1 : class
        where TResponse : class
    {
        public RequestHandlerMethod(Func<ConsumeContext<TMessage>, T1, Task<TResponse>> handler)
        {
            Handler = handler;
        }

        public RequestHandlerMethod(Func<TMessage, T1, Task<TResponse>> handler)
        {
            Handler = (context, arg1) => handler(context.Message, arg1);
        }

        public Func<ConsumeContext<TMessage>, T1, Task<TResponse>> Handler { get; }
    }

    public class RequestHandlerMethod<TMessage, T1, T2, TResponse>
        where TMessage : class
        where T1 : class
        where T2 : class
        where TResponse : class
    {
        public RequestHandlerMethod(Func<ConsumeContext<TMessage>, T1, T2, Task<TResponse>> handler)
        {
            Handler = handler;
        }

        public RequestHandlerMethod(Func<TMessage, T1, T2, Task<TResponse>> handler)
        {
            Handler = (context, arg1, arg2) => handler(context.Message, arg1, arg2);
        }

        public Func<ConsumeContext<TMessage>, T1, T2, Task<TResponse>> Handler { get; }
    }

    public class RequestHandlerMethod<TMessage, T1, T2, T3, TResponse>
        where TMessage : class
        where T1 : class
        where T2 : class
        where T3 : class
        where TResponse : class
    {
        public RequestHandlerMethod(Func<ConsumeContext<TMessage>, T1, T2, T3, Task<TResponse>> handler)
        {
            Handler = handler;
        }

        public RequestHandlerMethod(Func<TMessage, T1, T2, T3, Task<TResponse>> handler)
        {
            Handler = (context, arg1, arg2, arg3) => handler(context.Message, arg1, arg2, arg3);
        }

        public Func<ConsumeContext<TMessage>, T1, T2, T3, Task<TResponse>> Handler { get; }
    }
}