diff --git a/Doctrine/AssociationDecorator.php b/Doctrine/AssociationDecorator.php
index ae4fb6b63b2c902220f72d1fb79a01eabfb561df..c98e5697752784aecdece1c7901a68dc215329e0 100644
--- a/Doctrine/AssociationDecorator.php
+++ b/Doctrine/AssociationDecorator.php
@@ -50,35 +50,35 @@ class AssociationDecorator extends AbstractDoctrineDecorator
             return;
         }
 
-        $link = "->";
+        $linkSource = '';
+        $linkTarget = ">";
         if ($association["isCascadeRemove"]) {
-            $link = "o".$link;
+            $linkSource = "o";
         }
 
-        $leftLabel = "";
-        $rightLabel = "";
+        $sourceCardinality = "";
+        $targetCardinality = "";
         switch($association["type"]) {
             case ClassMetadata::ONE_TO_ONE:
-                $leftLabel = '1';
-                $rightLabel = '1';
+                $sourceCardinality = '1';
+                $targetCardinality = '1';
                 break;
             case ClassMetadata::ONE_TO_MANY:
-                $leftLabel = '1';
-                $rightLabel = '*';
+                $sourceCardinality = '1';
+                $targetCardinality = '*';
                 break;
             case ClassMetadata::MANY_TO_MANY:
-                $leftLabel = '*';
-                $rightLabel = '*';
+                $sourceCardinality = '*';
+                $targetCardinality = '*';
                 break;
             case ClassMetadata::MANY_TO_ONE:
-                $leftLabel = '*';
-                $rightLabel = '1';
+                $sourceCardinality = '*';
+                $targetCardinality = '1';
                 break;
         }
-        $link = sprintf('"%s" %s "%s"', $leftLabel, $link, $rightLabel);
 
         $node->addArrow(
-            new BaseArrow($node, $target, $link, $association["fieldName"]." >")
+            new BaseArrow($node, $target, "--", $association["fieldName"]." >", $linkSource, $linkTarget, $sourceCardinality, $targetCardinality)
         );
     }
 }
diff --git a/Factory/FilterFactory.php b/Factory/FilterFactory.php
deleted file mode 100644
index 04d2cf7fbd83f2dab38ebe4a815030f58c482f48..0000000000000000000000000000000000000000
--- a/Factory/FilterFactory.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-/*
- * © 2016 IRSTEA
- * Guillaume Perréal <guillaume.perreal@irstea.fr>
- * Tous droits réservés.
- */
-
-namespace Irstea\PlantUmlBundle\Factory;
-
-use Irstea\PlantUmlBundle\Model\ClassFilterInterface;
-use Irstea\PlantUmlBundle\Model\Filter\AcceptAllFilter;
-use Irstea\PlantUmlBundle\Model\Filter\ClassFilter;
-use Irstea\PlantUmlBundle\Model\Filter\Composite\AllFilter;
-use Irstea\PlantUmlBundle\Model\Filter\DirectoryFilter;
-use Irstea\PlantUmlBundle\Model\Filter\NamespaceFilter;
-use Symfony\Component\HttpKernel\KernelInterface;
-
-/**
- * Description of FilterFactory
- *
- * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
- */
-class FilterFactory
-{
-    /**
-     * @var KernelInterface
-     */
-    private $kernel;
-
-    public function __construct(KernelInterface $kernel)
-    {
-        $this->kernel = $kernel;
-    }
-
-    /**
-     * @param array $include
-     * @param array $exclude
-     * @return ClassFilterInterface
-     */
-    public function create($include = [], $exclude = [])
-    {
-        $filters = [];
-
-        if (!empty($include)) {
-            $this->appendFilters($filters, $include, false);
-        }
-        if (!empty($exclude)) {
-            $this->appendFilters($filters, $exclude, true);
-        }
-
-        switch(count($filters)) {
-            case 0:
-                $filter = AcceptAllFilter::instance();
-                break;
-            case 1:
-                $filter = $filters[0];
-                break;
-            default:
-                $filter = new AllFilter($filters);
-        }
-
-        return $filter;
-    }
-
-    protected function appendFilters(array &$filters, array $config, $notFound)
-    {
-        if (!empty($config['directories'])) {
-            $paths = $this->expandBundlePaths($config['directories']);
-            $filters[] = new DirectoryFilter($paths, $notFound);
-        }
-
-        if (!empty($config['namespaces'])) {
-            $namespaces = $this->expandBundleNamespaces($config['namespaces']);
-            $filters[] = new NamespaceFilter($namespaces, $notFound);
-        }
-
-        if (!empty($config['classes'])) {
-            $classes = $this->expandBundleNamespaces($config['classes']);
-            $filters[] = new ClassFilter($classes, $notFound);
-        }
-    }
-
-    /**
-     * @param array $paths
-     * @return array
-     */
-    protected function expandBundlePaths(array $paths)
-    {
-        $actualPaths = [];
-        foreach($paths as $path) {
-            if (preg_match('/^@(\w+)(.*)$/', $path, $groups)) {
-                $bundle = $this->kernel->getBundle($groups[1]);
-                $path = $bundle->getPath() . $groups[2];
-            }
-            $actualPaths[] = realpath($path);
-        }
-        return $actualPaths;
-    }
-
-    /**
-     * @param array $paths
-     * @return array
-     */
-    protected function expandBundleNamespaces(array $names)
-    {
-        $actualNames = [];
-        foreach($names as $name) {
-            if (preg_match('/^@(\w+)(.*)$/', $name, $groups)) {
-                $bundle = $this->kernel->getBundle($groups[1]);
-                $name = $bundle->getNamespace() . $groups[2];
-            }
-            $actualNames[] = $name;
-        }
-        return $actualNames;
-    }
-}
diff --git a/Model/Arrow/BaseArrow.php b/Model/Arrow/BaseArrow.php
index e96270aa52a4391398a9d1e4fc9d9d5524ebf08a..3be960a65000c581b7393f51f9050f1ca51b66b4 100644
--- a/Model/Arrow/BaseArrow.php
+++ b/Model/Arrow/BaseArrow.php
@@ -34,12 +34,49 @@ class BaseArrow implements ArrowInterface
      */
     private $link;
 
-    public function __construct(NodeInterface $source, NodeInterface $target, $link = "--", $label = null)
-    {
+    /**
+     * @var string
+     */
+    private $linkSource;
+
+    /**
+     * @var string
+     */
+    private $linkTarget;
+
+    /**
+     * @var string
+     */
+    private $sourceCardinality;
+
+    /**
+     * @var string
+     */
+    private $targetCardinality;
+
+    /**
+     * @var int
+     */
+    static private $splitCount = 0;
+
+    public function __construct(
+        NodeInterface $source,
+        NodeInterface $target,
+        $link = "--",
+        $label = null,
+        $linkSource = '',
+        $linkTarget = '',
+        $sourceCardinality = '',
+        $targetCardinality = ''
+    ) {
         $this->source = $source;
         $this->target = $target;
-        $this->link   = $link;
-        $this->label  = $label;
+        $this->link = $link;
+        $this->label = $label;
+        $this->linkSource = $linkSource;
+        $this->linkTarget = $linkTarget;
+        $this->sourceCardinality = $sourceCardinality;
+        $this->targetCardinality = $targetCardinality;
     }
 
     public function writeTo(WriterInterface $writer)
@@ -60,9 +97,27 @@ class BaseArrow implements ArrowInterface
         return $this;
     }
 
-    protected function writeLinkTo(WriterInterface $writer)
+    protected function writeLinkTo(WriterInterface $writer, $linkSource = null, $linkTarget = null)
     {
-        $writer->writeFormatted(" %s ", $this->link);
+        $this->writeSourceCardinalityTo($writer);
+        $writer->writeFormatted(" %s%s%s ", $linkSource ?: $this->linkSource, $this->link, $linkTarget ?: $this->linkTarget);
+        $this->writeTargetCardinalityTo($writer);
+        return $this;
+    }
+
+    protected function writeSourceCardinalityTo(WriterInterface $writer)
+    {
+        if ($this->sourceCardinality !== '') {
+            $writer->writeFormatted(' "%s"', $this->sourceCardinality);
+        }
+        return $this;
+    }
+
+    protected function writeTargetCardinalityTo(WriterInterface $writer)
+    {
+        if ($this->targetCardinality !== '') {
+            $writer->writeFormatted('"%s" ', $this->targetCardinality);
+        }
         return $this;
     }
 }
diff --git a/Model/Arrow/ExtendsClass.php b/Model/Arrow/ExtendsClass.php
index 28aa52b39553bad8fac9bf6138a124ff78b6ee40..5e8dca1f806246f8f95ff9a295a9321311fc2e15 100644
--- a/Model/Arrow/ExtendsClass.php
+++ b/Model/Arrow/ExtendsClass.php
@@ -19,6 +19,6 @@ class ExtendsClass extends BaseArrow
 {
     public function __construct(WritableNodeInterface $source, WritableNodeInterface $target)
     {
-        parent::__construct($target, $source, "<|--");
+        parent::__construct($target, $source, "--", null, "<|");
     }
 }
diff --git a/Model/Arrow/ImplementsInterface.php b/Model/Arrow/ImplementsInterface.php
index ad515627c690fbfa0347ed56389c9f419baac571..5bf208e8c32487f5f3d7d5dc28d5c8e2c5dd4100 100644
--- a/Model/Arrow/ImplementsInterface.php
+++ b/Model/Arrow/ImplementsInterface.php
@@ -20,6 +20,6 @@ class ImplementsInterface extends BaseArrow
 {
     public function __construct(WritableNodeInterface $source, Interface_ $target)
     {
-        parent::__construct($target, $source, "<|..");
+        parent::__construct($target, $source, "..", null, "<|");
     }
 }
diff --git a/Model/Arrow/UsesTrait.php b/Model/Arrow/UsesTrait.php
index ce564c00bf06bb2bcfdac47f03ed24641575bfc6..c37d293386e573dba98b959c8ab12d0581059bcd 100644
--- a/Model/Arrow/UsesTrait.php
+++ b/Model/Arrow/UsesTrait.php
@@ -20,6 +20,6 @@ class UsesTrait extends BaseArrow
 {
     public function __construct(WritableNodeInterface $source, Trait_ $trait)
     {
-        parent::__construct($trait, $source, "<|--");
+        parent::__construct($trait, $source, "--", null, "<|");
     }
 }