void mitk::ExampleDataStructureWriterService::Write()
{
  MITK_INFO << "Writing ExampleDataStructure";
  InputType::ConstPointer input = dynamic_cast<const InputType *>(this->GetInput());
  if (input.IsNull())
  {
    MITK_ERROR << "Sorry, input to ExampleDataStructureWriterService is nullptr!";
    return;
  }
  if (this->GetOutputLocation().empty())
  {
    MITK_ERROR << "Sorry, filename has not been set!";
    return;
  }

  std::string ext = itksys::SystemTools::GetFilenameLastExtension(this->GetOutputLocation());
  ext = itksys::SystemTools::LowerCase(ext);

  // default extension is .txt
  if (ext == "")
  {
    ext = ".txt";
    this->SetOutputLocation(this->GetOutputLocation() + ext);
  }

  try
  {
    std::ofstream file(this->GetOutputLocation());

    if (file.is_open())
    {
      file << input->GetData();
    }
    else
    {
      mitkThrow() << "Could not open file " << this->GetOutputLocation() << " for writing.";
    }

    MITK_INFO << "Example Data Structure has been written";
  }

  catch (mitk::Exception e)
  {
    MITK_ERROR << e.GetDescription();
  }
  catch (...)
  {
    MITK_ERROR << "Unknown error occurred while trying to write file.";
  }
}
void mitk::ConnectomicsNetworkCSVWriter::Write()
{
  MITK_INFO << "Writing connectomics network";
  InputType::ConstPointer input = dynamic_cast<const InputType*>(this->GetInput());
  if (input.IsNull() )
  {
    MITK_ERROR <<"Sorry, input to ConnectomicsNetworkMatrixWriter is nullptr!";
    return;
  }

  this->ValidateOutputLocation();

  std::ostream* out;
  std::ofstream outStream;

  if( this->GetOutputStream() )
  {
    out = this->GetOutputStream();
  }
  else
  {
    outStream.open( this->GetOutputLocation().c_str() );
    out = &outStream;
  }

  if ( !out->good() )
  {
    mitkThrow() << "Could not open stream.";
  }

  try
  {
    const std::string& locale = "C";
    const std::string& currLocale = setlocale( LC_ALL, nullptr );
    setlocale(LC_ALL, locale.c_str());

    std::locale previousLocale(out->getloc());
    std::locale I("C");
    out->imbue(I);

    // construct header
    std::stringstream header;

    mitk::StringProperty::Pointer addHeaderInfoProperty = dynamic_cast<mitk::StringProperty*>(input->GetProperty(connectomicsDataAdditionalHeaderInformation.c_str()).GetPointer());
    if(addHeaderInfoProperty.IsNotNull())
    {
      std::string additionalHeaderInfo = addHeaderInfoProperty->GetValue();
      // if the additional header info contains newlines we need to add #
      // in front of the new lines
      std::vector<std::string> strings;
      boost::split(strings, additionalHeaderInfo, boost::is_any_of("\n"));
      for( unsigned int index(0); index < strings.size(); ++index)
      {
        header << "#" << strings[index] << "\n";
      }
    }

    // construct body
    std::stringstream body;

    std::vector< InputType::VertexDescriptorType > nodes = input->GetVectorOfAllVertexDescriptors();
    for(unsigned int i(0); i < nodes.size(); ++i)
    {
      for(unsigned int j(0); j < i; ++j)
      {
        double weight(0);
        if( input->EdgeExists(nodes[i], nodes[j]) )
        {
          weight = (input->GetEdge(nodes[i], nodes[j])).edge_weight;
        }
        body << (input->GetNode(nodes[i])).label << " "
             << (input->GetNode(nodes[j])).label << " "
             << weight << "\n";
      }
    }

    (*out)<< header.str() << body.str();

    setlocale(LC_ALL, currLocale.c_str());
    MITK_INFO << "Connectomics network connection list written";
  }
  catch(...)
  {
    mitkThrow() << "Error while writing to stream.";
  }
}
void mitk::ConnectomicsNetworkWriter::Write()
{
    MITK_INFO << "Writing connectomics network";
    InputType::ConstPointer input = dynamic_cast<const InputType*>(this->GetInput());
    if (input.IsNull() )
    {
        MITK_ERROR <<"Sorry, input to ConnectomicsNetworkWriter is NULL!";
        return;
    }
    if ( this->GetOutputLocation().empty() )
    {
        MITK_ERROR << "Sorry, filename has not been set!" ;
        return ;
    }

    std::string ext = itksys::SystemTools::GetFilenameLastExtension(this->GetOutputLocation());
    ext = itksys::SystemTools::LowerCase(ext);

    // default extension is .cnf
    if(ext == "")
    {
        ext = ".cnf";
        this->SetOutputLocation(this->GetOutputLocation() + ext);
    }

    if (ext == ".cnf")
    {
        // Get geometry of the network
        mitk::BaseGeometry* geometry = input->GetGeometry();

        // Create XML document
        TiXmlDocument documentXML;
        {   // begin document
            TiXmlDeclaration* declXML = new TiXmlDeclaration( "1.0", "", "" ); // TODO what to write here? encoding? etc....
            documentXML.LinkEndChild( declXML );

            TiXmlElement* mainXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_CONNECTOMICS_FILE);
            mainXML->SetAttribute(mitk::ConnectomicsNetworkDefinitions::XML_FILE_VERSION, mitk::ConnectomicsNetworkDefinitions::VERSION_STRING);
            documentXML.LinkEndChild(mainXML);

            TiXmlElement* geometryXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_GEOMETRY);
            {   // begin geometry
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XX, geometry->GetMatrixColumn(0)[0]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XY, geometry->GetMatrixColumn(0)[1]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_XZ, geometry->GetMatrixColumn(0)[2]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YX, geometry->GetMatrixColumn(1)[0]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YY, geometry->GetMatrixColumn(1)[1]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_YZ, geometry->GetMatrixColumn(1)[2]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZX, geometry->GetMatrixColumn(2)[0]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZY, geometry->GetMatrixColumn(2)[1]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_MATRIX_ZZ, geometry->GetMatrixColumn(2)[2]);

                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_X, geometry->GetOrigin()[0]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Y, geometry->GetOrigin()[1]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_ORIGIN_Z, geometry->GetOrigin()[2]);

                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_X, geometry->GetSpacing()[0]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Y, geometry->GetSpacing()[1]);
                geometryXML->SetDoubleAttribute(mitk::ConnectomicsNetworkDefinitions::XML_SPACING_Z, geometry->GetSpacing()[2]);

            } // end geometry
            mainXML->LinkEndChild(geometryXML);

            TiXmlElement* verticesXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_VERTICES);
            {   // begin vertices section
                VertexVectorType vertexVector = dynamic_cast<const InputType*>(this->GetInput())->GetVectorOfAllNodes();
                for( unsigned int index = 0; index < vertexVector.size(); index++ )
                {
                    // not localized as of yet TODO
                    TiXmlElement* vertexXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_VERTEX );
                    vertexXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_ID , vertexVector[ index ].id );
                    vertexXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_LABEL , vertexVector[ index ].label );
                    vertexXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_X , vertexVector[ index ].coordinates[0] );
                    vertexXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Y , vertexVector[ index ].coordinates[1] );
                    vertexXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_VERTEX_Z , vertexVector[ index ].coordinates[2] );
                    verticesXML->LinkEndChild(vertexXML);
                }
            } // end vertices section
            mainXML->LinkEndChild(verticesXML);

            TiXmlElement* edgesXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_EDGES);
            {   // begin edges section
                EdgeVectorType edgeVector = dynamic_cast<const InputType*>(this->GetInput())->GetVectorOfAllEdges();
                for(unsigned  int index = 0; index < edgeVector.size(); index++ )
                {
                    TiXmlElement* edgeXML = new TiXmlElement(mitk::ConnectomicsNetworkDefinitions::XML_EDGE );
                    edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_ID , index );
                    edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_SOURCE_ID , edgeVector[ index ].second.sourceId );
                    edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_TARGET_ID , edgeVector[ index ].second.targetId );
                    edgeXML->SetAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_WEIGHT_ID , edgeVector[ index ].second.weight );
                    edgeXML->SetDoubleAttribute( mitk::ConnectomicsNetworkDefinitions::XML_EDGE_DOUBLE_WEIGHT_ID , edgeVector[ index ].second.edge_weight );
                    edgesXML->LinkEndChild(edgeXML);
                }
            } // end edges section
            mainXML->LinkEndChild(edgesXML);

        } // end document
        documentXML.SaveFile( this->GetOutputLocation().c_str() );
        MITK_INFO << "Connectomics network written";

    }
}