std::unique_ptr<typename ElementaryLocalOperator<BasisFunctionType,
                                                 ResultType>::LocalAssembler>
ElementaryLocalOperator<BasisFunctionType, ResultType>::makeAssembler(
    const QuadratureStrategy &quadStrategy,
    const AssemblyOptions &options) const {
  typedef Fiber::RawGridGeometry<CoordinateType> RawGridGeometry;
  typedef std::vector<const Fiber::Shapeset<BasisFunctionType> *>
      ShapesetPtrVector;

  shared_ptr<RawGridGeometry> testRawGeometry, trialRawGeometry;
  shared_ptr<GeometryFactory> testGeometryFactory, trialGeometryFactory;
  shared_ptr<Fiber::OpenClHandler> openClHandler;
  shared_ptr<ShapesetPtrVector> testShapesets, trialShapesets;
  bool cacheSingularIntegrals;

  this->collectDataForAssemblerConstruction(
      options, testRawGeometry, trialRawGeometry, testGeometryFactory,
      trialGeometryFactory, testShapesets, trialShapesets, openClHandler,
      cacheSingularIntegrals);
  assert(testRawGeometry == trialRawGeometry);
  assert(testGeometryFactory == trialGeometryFactory);

  return quadStrategy.makeAssemblerForLocalOperators(
      testGeometryFactory, testRawGeometry, testShapesets, trialShapesets,
      make_shared_from_ref(testTransformations()),
      make_shared_from_ref(trialTransformations()),
      make_shared_from_ref(integral()), openClHandler);
}
std::pair<
shared_ptr<typename HypersingularIntegralOperator<
BasisFunctionType, KernelType, ResultType>::LocalAssembler>,
shared_ptr<typename HypersingularIntegralOperator<
BasisFunctionType, KernelType, ResultType>::LocalAssembler>
>
HypersingularIntegralOperator<BasisFunctionType, KernelType, ResultType>::
reallyMakeAssemblers(
        const QuadratureStrategy& quadStrategy,
        const shared_ptr<const GeometryFactory>& testGeometryFactory,
        const shared_ptr<const GeometryFactory>& trialGeometryFactory,
        const shared_ptr<const Fiber::RawGridGeometry<CoordinateType> >& testRawGeometry,
        const shared_ptr<const Fiber::RawGridGeometry<CoordinateType> >& trialRawGeometry,
        const shared_ptr<const std::vector<const Fiber::Shapeset<BasisFunctionType>*> >& testShapesets,
        const shared_ptr<const std::vector<const Fiber::Shapeset<BasisFunctionType>*> >& trialShapesets,
        const shared_ptr<const Fiber::OpenClHandler>& openClHandler,
        const ParallelizationOptions& parallelizationOptions,
        VerbosityLevel::Level verbosityLevel,
        bool cacheSingularIntegrals,
        bool makeSeparateOffDiagonalAssembler) const
{
    std::pair<shared_ptr<LocalAssembler>, shared_ptr<LocalAssembler> > result;
    // first element: "standard" assembler
    // second element: assembler used for admissible (off-diagonal)
    // H-matrix blocks in "disassembled mode"
    result.first.reset(quadStrategy.makeAssemblerForIntegralOperators(
                           testGeometryFactory, trialGeometryFactory,
                           testRawGeometry, trialRawGeometry,
                           testShapesets, trialShapesets,
                           make_shared_from_ref(testTransformations()),
                           make_shared_from_ref(kernels()),
                           make_shared_from_ref(trialTransformations()),
                           make_shared_from_ref(integral()),
                           openClHandler, parallelizationOptions, verbosityLevel,
                           cacheSingularIntegrals).release());
    if (makeSeparateOffDiagonalAssembler)
        result.second.reset(quadStrategy.makeAssemblerForIntegralOperators(
                                testGeometryFactory, trialGeometryFactory,
                                testRawGeometry, trialRawGeometry,
                                testShapesets, trialShapesets,
                                make_shared_from_ref(offDiagonalTestTransformations()),
                                make_shared_from_ref(offDiagonalKernels()),
                                make_shared_from_ref(offDiagonalTrialTransformations()),
                                make_shared_from_ref(offDiagonalIntegral()),
                                openClHandler, parallelizationOptions, verbosityLevel,
                                false /*cacheSingularIntegrals*/).release());
    else
        result.second = result.first;
    return result;
}