static void Paint(mitk::Image::Pointer image, itk::Index<3> index, unsigned int timeStep)
{
  // As soon as the ImagePixelWriteAccessor object goes out of scope at the
  // end of this function, the image will be unlocked again (RAII).
  mitk::ImagePixelWriteAccessor<T> writeAccessor(image, image->GetVolumeData(timeStep));
  writeAccessor.SetPixelByIndex(index, std::numeric_limits<T>::min());

  // Don't forget to update the modified time stamp of the image. Otherwise,
  // everything downstream wouldn't recognize that the image changed,
  // including the rendering system.
  image->Modified();
}
    // The tests all do the same, only in different directions
    void testRoutine(mitk::SliceNavigationController::ViewDirection viewDirection)
    {
        int dim;
        switch(viewDirection)
        {
        case(mitk::SliceNavigationController::Axial): dim = 2; break;
        case(mitk::SliceNavigationController::Frontal): dim = 1; break;
        case(mitk::SliceNavigationController::Sagittal): dim = 0; break;
        case(mitk::SliceNavigationController::Original): dim = -1; break; // This is just to get rid of a warning
        }

        /* Fill segmentation
         *
         * 1st slice: 3x3 square segmentation
         * 2nd slice: empty
         * 3rd slice: 1x1 square segmentation in corner
         * -> 2nd slice should become 2x2 square in corner
         *
         * put accessor in scope
         */

        itk::Index<3> currentPoint;
        {
            mitk::ImagePixelWriteAccessor<mitk::Tool::DefaultSegmentationDataType, 3> writeAccessor(m_SegmentationImage);

            // Fill 3x3 slice
            currentPoint[dim] = m_CenterPoint[dim] - 1;
            for (int i=-1; i<=1; ++i)
            {
                for (int j=-1; j<=1; ++j)
                {
                    currentPoint[(dim+1)%3] = m_CenterPoint[(dim+1)%3] + i;
                    currentPoint[(dim+2)%3] = m_CenterPoint[(dim+2)%3] + j;
                    writeAccessor.SetPixelByIndexSafe(currentPoint, 1);
                }
            }
            // Now i=j=1, set point two slices up
            currentPoint[dim] = m_CenterPoint[dim] + 1;
            writeAccessor.SetPixelByIndexSafe(currentPoint, 1);
        }

    //        mitk::IOUtil::Save(m_SegmentationImage, "SOME PATH");

        m_InterpolationController->SetSegmentationVolume(m_SegmentationImage);
        m_InterpolationController->SetReferenceVolume(m_ReferenceImage);

        // This could be easier...
        mitk::SliceNavigationController::Pointer navigationController = mitk::SliceNavigationController::New();
        navigationController->SetInputWorldTimeGeometry(m_SegmentationImage->GetTimeGeometry());
        navigationController->Update(viewDirection);
        mitk::Point3D pointMM;
        m_SegmentationImage->GetTimeGeometry()->GetGeometryForTimeStep(0)->IndexToWorld(m_CenterPoint, pointMM);
        navigationController->SelectSliceByPoint(pointMM);
        auto plane = navigationController->GetCurrentPlaneGeometry();
        mitk::Image::Pointer interpolationResult = m_InterpolationController->Interpolate(dim, m_CenterPoint[dim], plane, 0);

    //        mitk::IOUtil::Save(interpolationResult, "SOME PATH");

        // Write result into segmentation image
        vtkSmartPointer<mitkVtkImageOverwrite> reslicer = vtkSmartPointer<mitkVtkImageOverwrite>::New();
        reslicer->SetInputSlice(interpolationResult->GetSliceData()->GetVtkImageAccessor(interpolationResult)->GetVtkImageData());
        reslicer->SetOverwriteMode(true);
        reslicer->Modified();
        mitk::ExtractSliceFilter::Pointer extractor =  mitk::ExtractSliceFilter::New(reslicer);
        extractor->SetInput(m_SegmentationImage);
        extractor->SetTimeStep(0);
        extractor->SetWorldGeometry(plane);
        extractor->SetVtkOutputRequest(true);
        extractor->SetResliceTransformByGeometry(m_SegmentationImage->GetTimeGeometry()->GetGeometryForTimeStep(0));
        extractor->Modified();
        extractor->Update();

    //        mitk::IOUtil::Save(m_SegmentationImage, "SOME PATH");

        // Check a 4x4 square, the center of which needs to be filled
        mitk::ImagePixelReadAccessor<mitk::Tool::DefaultSegmentationDataType, 3> readAccess(m_SegmentationImage);
        currentPoint = m_CenterPoint;

        for (int i=-1; i<=2; ++i)
        {
            for (int j=-1; j<=2; ++j)
            {
                currentPoint[(dim+1)%3] = m_CenterPoint[(dim+1)%3] + i;
                currentPoint[(dim+2)%3] = m_CenterPoint[(dim+2)%3] + j;

                if (i == -1 || i == 2 || j == -1 || j == 2)
                {
                    CPPUNIT_ASSERT_MESSAGE("Have false positive segmentation.", readAccess.GetPixelByIndexSafe(currentPoint) == 0);
                }
                else
                {
                    CPPUNIT_ASSERT_MESSAGE("Have false negative segmentation.", readAccess.GetPixelByIndexSafe(currentPoint) == 1);
                }
            }
        }
    }
ITK_THREAD_RETURN_TYPE ThreadMethod(void *data)
{
  /* extract data pointer from Thread Info structure */
  struct itk::MultiThreader::ThreadInfoStruct *pInfo = (struct itk::MultiThreader::ThreadInfoStruct *)data;

  // some data validity checking
  if (pInfo == NULL)
  {
    return ITK_THREAD_RETURN_VALUE;
  }
  if (pInfo->UserData == NULL)
  {
    return ITK_THREAD_RETURN_VALUE;
  }

  // obtain user data for processing
  ThreadData *threadData = (ThreadData *)pInfo->UserData;

  srand(pInfo->ThreadID);

  mitk::Image::Pointer im = threadData->data;

  int nrSlices = im->GetDimension(2);

  // Create randomly a PixelRead- or PixelWriteAccessor for a slice and access all pixels in it.
  try
  {
    if (rand() % 2)
    {
      testMutex.Lock();
      mitk::ImageDataItem *iDi = im->GetSliceData(rand() % nrSlices);
      testMutex.Unlock();
      while (!iDi->IsComplete())
      {
      }

      // MITK_INFO << "pixeltype: " << im->GetPixelType().GetComponentTypeAsString();

      if ((im->GetPixelType().GetComponentTypeAsString() == "short") && (im->GetDimension() == 3))
      {
        // Use pixeltype&dimension specific read accessor

        int xlength = im->GetDimension(0);
        int ylength = im->GetDimension(1);

        mitk::ImagePixelReadAccessor<short, 2> readAccessor(im, iDi);

        itk::Index<2> idx;
        for (int i = 0; i < xlength; ++i)
        {
          for (int j = 0; j < ylength; ++j)
          {
            idx[0] = i;
            idx[1] = j;
            readAccessor.GetPixelByIndexSafe(idx);
          }
        }
      }
      else
      {
        // use general accessor
        mitk::ImageReadAccessor *iRA = new mitk::ImageReadAccessor(im, iDi);
        delete iRA;
      }
    }
    else
    {
      testMutex.Lock();
      mitk::ImageDataItem *iDi = im->GetSliceData(rand() % nrSlices);
      testMutex.Unlock();
      while (!iDi->IsComplete())
      {
      }

      if ((im->GetPixelType().GetComponentTypeAsString() == "short") && (im->GetDimension() == 3))
      {
        // Use pixeltype&dimension specific read accessor

        int xlength = im->GetDimension(0);
        int ylength = im->GetDimension(1);

        mitk::ImagePixelWriteAccessor<short, 2> writeAccessor(im, iDi);

        itk::Index<2> idx;
        for (int i = 0; i < xlength; ++i)
        {
          for (int j = 0; j < ylength; ++j)
          {
            idx[0] = i;
            idx[1] = j;
            short newVal = rand() % 16000;
            writeAccessor.SetPixelByIndexSafe(idx, newVal);
            short val = writeAccessor.GetPixelByIndexSafe(idx);
            if (val != newVal)
            {
              threadData->m_Successful = false;
            }
          }
        }
      }
      else
      {
        // use general accessor
        mitk::ImageWriteAccessor iB(im, iDi);
        void *pointer = iB.GetData();
        *((char *)pointer) = 0;
      }
    }
  }
  catch (mitk::MemoryIsLockedException &e)
  {
    threadData->m_Successful = false;
    e.Print(std::cout);
  }
  catch (mitk::Exception &e)
  {
    threadData->m_Successful = false;
    e.Print(std::cout);
  }

  // data processing end!
  threadData->m_Barrier->Wait();
  return ITK_THREAD_RETURN_VALUE;
}