diff --git a/Command/GenerateCommand.php b/Command/GenerateCommand.php
index 0a2a7374c6dcac3873b3688ec1dfccc7d8123ecf..b17b5f0c6ea5cda817aed75237e4f4734e5bfc96 100644
--- a/Command/GenerateCommand.php
+++ b/Command/GenerateCommand.php
@@ -7,24 +7,36 @@
 namespace Irstea\PlantUmlBundle\Command;
 
 use Doctrine\ORM\EntityManagerInterface;
-use Doctrine\ORM\Mapping\ClassMetadata;
 use Irstea\PlantUmlBundle\Doctrine\AssociationDecorator;
 use Irstea\PlantUmlBundle\Doctrine\DoctrineNamespace;
 use Irstea\PlantUmlBundle\Doctrine\EntityDecorator;
+use Irstea\PlantUmlBundle\Model\ClassFilterInterface;
 use Irstea\PlantUmlBundle\Model\ClassVisitor;
 use Irstea\PlantUmlBundle\Model\Decorator\CompositeDecorator;
 use Irstea\PlantUmlBundle\Model\Decorator\FilteringDecorator;
 use Irstea\PlantUmlBundle\Model\Decorator\InheritanceDecorator;
+use Irstea\PlantUmlBundle\Model\Decorator\NullDecorator;
+use Irstea\PlantUmlBundle\Model\DecoratorInterface;
+use Irstea\PlantUmlBundle\Model\Filter\AcceptAllFilter;
+use Irstea\PlantUmlBundle\Model\Filter\Composite\AllFilter;
 use Irstea\PlantUmlBundle\Model\Filter\DirectoryFilter;
 use Irstea\PlantUmlBundle\Model\Filter\NamespaceFilter;
-use Irstea\PlantUmlBundle\Model\Filter\Whitelist;
 use Irstea\PlantUmlBundle\Model\Namespace_\BundleNamespace;
 use Irstea\PlantUmlBundle\Model\Namespace_\FlatNamespace;
-use Irstea\PlantUmlBundle\Model\Namespace_\MappedNamespace;
+use Irstea\PlantUmlBundle\Model\Namespace_\Php\RootNamespace;
+use Irstea\PlantUmlBundle\Model\NamespaceInterface;
 use Irstea\PlantUmlBundle\Writer\OutputWriter;
+use ReflectionClass;
 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Config\Definition\Exception\Exception;
+use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Finder\SplFileInfo;
+use Symfony\Component\HttpKernel\KernelInterface;
+use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
+use Symfony\Component\Security\Core\Exception\RuntimeException;
 
 
 /**
@@ -32,13 +44,39 @@ use Symfony\Component\Console\Output\OutputInterface;
  *
  * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
  */
-class EntitySchemaCommand extends ContainerAwareCommand
+class GenerateCommand extends ContainerAwareCommand
 {
+    /**
+     * @var string[]
+     */
+    private $bundles;
+
+    /**
+     * @var KernelInterface
+     */
+    private $kernel;
+
+    /**
+     * @var EntityManagerInterface
+     */
+    private $entityManager;
+
     protected function configure()
     {
         $this
-            ->setName('irstea:plantuml:entities')
-            ->setDescription("Génère un schéma PlantUML à partir des métadonnées de Doctrine.");
+            ->setName('irstea:plantuml:generate')
+            ->setDescription("Génère un graphe en PlantUML.")
+            ->addArgument('graph', InputArgument::REQUIRED, 'Nom du graphe à générer');
+    }
+
+    protected function initialize(InputInterface $input, OutputInterface $output)
+    {
+        parent::initialize($input, $output);
+
+        // @todo: DI
+        $this->bundles = $this->getContainer()->getParameter('kernel.bundles');
+        $this->kernel =  $this->getContainer()->get('kernel');
+        $this->entityManager =  $this->getContainer()->get('doctrine.orm.entity_manager');
     }
 
     /**
@@ -50,41 +88,29 @@ class EntitySchemaCommand extends ContainerAwareCommand
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        /* @var $manager EntityManagerInterface */
-        $manager = $this->getContainer()->get('doctrine.orm.entity_manager');
-
-        $factory = $manager->getMetadataFactory();
-        $allMetadata = $factory->getAllMetadata();
+        $name = $input->getArgument('graph');
+        $graphs = $this->getContainer()->getParameter('irstea_plant_uml.graphs');
+        if (!isset($graphs[$name])) {
+            throw new InvalidArgumentException("Le graphe '$name' n'est pas défini.");
+        }
 
-        $decorationFilter = new DirectoryFilter(
-            [
-                realpath($this->getContainer()->getParameter('kernel.root_dir').'/../src')
-            ]
-        );
+        $config = $graphs[$name];
 
-        $bundleNamespace = 'Irstea\\SygadeBundle\\Entity\\';
+        $classes = $this->findClasses($config['sources']);
+        if (empty($classes)) {
+            $output->writeln("Nothing to analyze.");
+            return 0;
+        }
 
-        $entityFilter = new NamespaceFilter([$bundleNamespace]);
+        $namespace = $this->buildNamespace($config['layout']['namespaces']);
+        $displayFilter = $this->buildFilter($config['layout']);
 
-        //$namespace = new BundleNamespace($this->getContainer()->getParameter('kernel.bundles'));
-        $namespace = new MappedNamespace([$bundleNamespace => '']);
+        $decorator = $this->buildDecorator($config['decoration']);
 
-        $decorator = new FilteringDecorator(
-            new CompositeDecorator([
-                new InheritanceDecorator(),
-                new EntityDecorator($factory),
-                new AssociationDecorator($factory),
-            ]),
-            $decorationFilter
-        );
+        $visitor = new ClassVisitor($decorator, $displayFilter, $namespace);
 
-        $visitor = new ClassVisitor($decorator, null, $namespace);
-
-        foreach($allMetadata as $metadata) {
-            /* @var $metadata ClassMetadata */
-            if ($entityFilter->accept($metadata->getReflectionClass())) {
-                $visitor->visitClass($metadata->getName());
-            }
+        foreach($classes as $class) {
+            $visitor->visitClass($class);
         }
 
         $writer = new OutputWriter($output);
@@ -92,4 +118,223 @@ class EntitySchemaCommand extends ContainerAwareCommand
         $visitor->outputTo($writer);
         $writer->write("@enduml\n");
     }
+
+    /**
+     * @param ReflectionClass[]
+     */
+    protected function findClasses(array $config)
+    {
+        switch($config['type']) {
+            case 'entities':
+                $classes = $this->findEntities($config['entity_manager']);
+                break;
+            case 'classes':
+                $classes = $this->findClassesInDirectories($config['directories']);
+                break;
+        }
+
+        $filter = $this->buildFilter($config);
+        if ($filter) {
+            return array_filter($classes, [$filter, 'accept']);
+        }
+
+        return $classes;
+    }
+
+    /**
+     * @return ReflectionClass[]
+     */
+    protected function findEntities($managerName)
+    {
+        $doctrine = $this->getContainer()->get('doctrine');
+        $this->entityManager = $doctrine->getManager($managerName);
+
+        $classes = [];
+        foreach($this->entityManager->getMetadataFactory()->getAllMetadata() as $metadata) {
+            $classes[$metadata->getName()] = $metadata->getReflectionClass();
+        }
+
+        return $classes;
+    }
+
+    /**
+     *
+     * @return ReflectionClass[]
+     */
+    protected function findClassesInDirectories($directories)
+    {
+        $paths = $this->parseDirectories($directories);
+
+        $files = Finder::create()
+            ->in($paths)
+            ->files()
+            ->name('*.php')
+            ->getIterator();
+
+        foreach($files as $file)
+        {
+            /* @var $file SplFileInfo */
+            $path = $file->getPathname();
+            try {
+                irstea_plantmul_include($path);
+            } catch(Exception $ex) {
+                printf("%s: %s (%s)\n", $path, get_class($ex), $ex->getMessage());
+            }
+        }
+
+        $filter = new DirectoryFilter($paths);
+        $classes = [];
+        foreach(get_declared_classes() as $className) {
+            $class = new ReflectionClass($className);
+            if ($filter->accept($class)) {
+                $classes[$className] = $class;
+            }
+        }
+
+        return $classes;
+    }
+
+    /**
+     * @param array $config
+     * @return DecoratorInterface
+     * @throws RuntimeException
+     */
+    protected function buildDecorator(array $config)
+    {
+        $decorators = [];
+
+        foreach($config['decorators'] as $decorator) {
+            switch($decorator) {
+                case 'inheritance':
+                    $decorators[] = new InheritanceDecorator();
+                    break;
+                case 'entity':
+                    $decorators[] = new EntityDecorator($this->entityManager->getMetadataFactory());
+                    break;
+                case 'associations':
+                    $decorators[] = new AssociationDecorator($this->entityManager->getMetadataFactory());
+                    break;
+                /*default:
+                    throw new RuntimeException("Decorator '$decorator' not yet implemented");*/
+            }
+        }
+
+        if (empty($decorators)) {
+            return NullDecorator::instance();
+        }
+
+        if (count($decorators) === 1) {
+            $decorator = $decorators[0];
+        } else {
+            $decorator = new CompositeDecorator($decorators);
+        }
+
+        $filter = $this->buildFilter($config);
+        if ($filter) {
+            $decorator = new FilteringDecorator($decorator, $filter);
+        }
+
+        return $decorator;
+    }
+
+    /**
+     * @param string $config
+     * @return NamespaceInterface
+     */
+    protected function buildNamespace($config)
+    {
+        switch($config) {
+            case 'php':
+                return new RootNamespace();
+            case 'flat':
+                return new FlatNamespace();
+            case 'entities':
+                return new DoctrineNamespace($this->entityManager->getConfiguration()->getEntityNamespaces());
+            case 'bundles':
+                return new BundleNamespace($this->bundles);
+        }
+    }
+
+    /**
+     * @param array $config
+     * @return ClassFilterInterface|null
+     */
+    protected function buildFilter(array $config)
+    {
+        $filters = array_merge(
+            isset($config['include']) ? $this->buildSubFilters($config['include'], false) : [],
+            isset($config['exclude']) ? $this->buildSubFilters($config['exclude'], true) : []
+        );
+
+        switch(count($filters)) {
+            case 0:
+                return null;
+            case 1:
+                return $filters[0];
+            default:
+                return new AllFilter($filters);
+        }
+    }
+
+    /**
+     * @param array $config
+     * @param boolean $notFound
+     * @return ClassFilterInterface|null
+     */
+    protected function buildSubFilters(array $config, $notFound)
+    {
+        $filters = [];
+
+        if (!empty($config['directories'])) {
+            $paths = $this->parseDirectories($config['directories']);
+            $filters[] = new DirectoryFilter($paths, $notFound);
+        }
+
+        if (!empty($config['namespaces'])) {
+            $namespaces = $this->parseNamespaces($config['namespaces']);
+            $filters[] = new NamespaceFilter($namespaces, $notFound);
+        }
+
+        return $filters;
+    }
+
+    /**
+     * @param array $paths
+     * @return array
+     */
+    protected function parseDirectories(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 parseNamespaces(array $namespaces)
+    {
+        $actualNamespaces = [];
+        foreach($namespaces as $namespace) {
+            if (preg_match('/^@(\w+)(.*)$/', $namespace, $groups)) {
+                $bundle = $this->kernel->getBundle($groups[1]);
+                $namespace = $bundle->getNamespace() . $groups[2];
+            }
+            $actualNamespaces[] = $namespace;
+        }
+        return $actualNamespaces;
+    }
+
 }
+
+function irstea_plantmul_include($filepath)
+{
+    @include_once($filepath);
+}
\ No newline at end of file
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
new file mode 100644
index 0000000000000000000000000000000000000000..e112708c847a7dc6161ff129832764fcbe9d9537
--- /dev/null
+++ b/DependencyInjection/Configuration.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\DependencyInjection;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+/**
+ * Description of Configuration
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class Configuration implements ConfigurationInterface
+{
+    public function getConfigTreeBuilder()
+    {
+        $treeBuilder = new TreeBuilder();
+
+        $treeBuilder->root('irstea_plant_uml')
+            ->children()
+                ->arrayNode('binaries')
+                    ->addDefaultsIfNotSet()
+                    ->children()
+                        ->scalarNode('java')
+                            ->defaultValue("java")
+                        ->end()
+                        ->scalarNode('plamtuml_jar')
+                            ->defaultValue("plantuml.jar")
+                        ->end()
+                        ->scalarNode('dot')
+                            ->defaultValue("dot")
+                        ->end()
+                    ->end()
+                ->end()
+                ->append($this->buildGraphNode())
+            ->end();
+
+        return $treeBuilder;
+    }
+
+    protected function buildGraphNode()
+    {
+        $node = (new TreeBuilder())->root('graphs');
+
+        $node
+            ->useAttributeAsKey('name')
+            ->prototype('array')
+                ->children()
+                    ->arrayNode('sources')
+                        ->addDefaultsIfNotSet()
+                        ->children()
+                            ->enumNode('type')
+                                ->defaultValue('classes')
+                                ->values(['classes', 'entities'])
+                            ->end()
+                            ->scalarNode('entity_manager')
+                                ->defaultValue('default')
+                            ->end()
+                            ->arrayNode('directories')
+                                ->defaultValue(['%kernel.root_dir%/../src'])
+                                ->prototype('scalar')->end()
+                            ->end()
+                            ->append($this->buildFilterNode('include'))
+                            ->append($this->buildFilterNode('exclude'))
+                        ->end()
+                    ->end()
+                    ->arrayNode('layout')
+                        ->addDefaultsIfNotSet()
+                        ->children()
+                            ->enumNode('namespaces')
+                                ->defaultValue('php')
+                                ->values(['bundles', 'php', 'flat', 'entities'])
+                            ->end()
+                            ->append($this->buildFilterNode('include'))
+                            ->append($this->buildFilterNode('exclude'))
+                         ->end()
+                    ->end()
+                    ->arrayNode('decoration')
+                        ->addDefaultsIfNotSet()
+                        ->children()
+                            ->arrayNode('decorators')
+                                ->defaultValue(['inheritance', 'entity', 'associations', 'properties', 'methods'])
+                                ->prototype('enum')
+                                    ->values(['inheritance', 'entity', 'associations', 'properties', 'methods'])
+                                ->end()
+                            ->end()
+                            ->append($this->buildFilterNode('include'))
+                            ->append($this->buildFilterNode('exclude'))
+                        ->end()
+                    ->end()
+                ->end()
+            ->end();
+
+        return $node;
+    }
+
+    protected function buildFilterNode($nodeName)
+    {
+        $node = (new TreeBuilder())->root($nodeName);
+
+        $node
+            ->children()
+                ->arrayNode('directories')
+                    ->prototype('scalar')->end()
+                ->end()
+                ->arrayNode('namespaces')
+                    ->prototype('scalar')->end()
+                ->end()
+            ->end();
+
+        return $node;
+    }
+
+}
+
diff --git a/DependencyInjection/IrsteaPlantUmlExtension.php b/DependencyInjection/IrsteaPlantUmlExtension.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae45c05e1258cb4dbe8928230f980aa6437bdb25
--- /dev/null
+++ b/DependencyInjection/IrsteaPlantUmlExtension.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+/**
+ * Description of IrsteaPlantUmlExtension
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class IrsteaPlantUmlExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+        $configuration = new Configuration();
+        $config = $this->processConfiguration($configuration, $configs);
+
+        $container->setParameter('irstea_plant_uml.binaries', $config['binaries']);
+        $container->setParameter('irstea_plant_uml.graphs', $config['graphs']);
+    }
+}
diff --git a/Model/ClassVisitor.php b/Model/ClassVisitor.php
index 75730ae8dcb501e520e6601466af9dd00541e8e9..1f557bc08da5c95421faa459e3cd8be9f0b48216 100644
--- a/Model/ClassVisitor.php
+++ b/Model/ClassVisitor.php
@@ -70,15 +70,21 @@ class ClassVisitor implements ClassVisitorInterface, WritableInterface
         return $this;
     }
 
-    public function visitClass($className)
+    public function visitClass($classOrName)
     {
-        assert('is_string($className)', $className);
+        if ($classOrName instanceof \ReflectionClass) {
+            $class = $classOrName;
+        } elseif (is_string($classOrName)) {
+            $class = new \ReflectionClass($classOrName);
+        } else {
+            throw new \InvalidArgumentException("Invalid argument, expected ReflectionClass or string");
+        }
+        $className = $class->getName();
+
         if (isset($this->nodes[$className])) {
             return $this->nodes[$className];
         }
 
-        $class = new ReflectionClass($className);
-
         if (!$this->filter->accept($class)) {
             return $this->nodes[$className] = false;
         }
diff --git a/Model/ClassVisitorInterface.php b/Model/ClassVisitorInterface.php
index 91071200e816a922dbab8f2c86aaa80741ec01ca..dbc6608022934facf36f3e89e092f958d59746ac 100644
--- a/Model/ClassVisitorInterface.php
+++ b/Model/ClassVisitorInterface.php
@@ -8,6 +8,8 @@
 
 namespace Irstea\PlantUmlBundle\Model;
 
+use ReflectionClass;
+
 /**
  *
  * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
@@ -15,7 +17,8 @@ namespace Irstea\PlantUmlBundle\Model;
 interface ClassVisitorInterface
 {
     /**
+     * @param ReflectionClass|string
      * @return NodeInterface
      */
-    public function visitClass($className);
+    public function visitClass($classOrName);
 }
diff --git a/Model/Filter/Composite/AbstractCompositeFilter.php b/Model/Filter/Composite/AbstractCompositeFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d2971574ab8fb708ab3b90fbaafa41ad2d6bb49
--- /dev/null
+++ b/Model/Filter/Composite/AbstractCompositeFilter.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\Model\Filter\Composite;
+
+use Irstea\PlantUmlBundle\Model\ClassFilterInterface;
+use ReflectionClass;
+
+/**
+ * Description of CompositeFilter
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+abstract class AbstractCompositeFilter implements ClassFilterInterface
+{
+    /**
+     * @var ClassFilterInterface
+     */
+    protected $filters;
+
+    public function __construct(array $filters)
+    {
+        $this->filters = $filters;
+    }
+}
diff --git a/Model/Filter/Composite/AllFilter.php b/Model/Filter/Composite/AllFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3033280ae52671ef8c5a3d87b49073d5f8f75b3
--- /dev/null
+++ b/Model/Filter/Composite/AllFilter.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\Model\Filter\Composite;
+
+/**
+ * Description of AnyFilter
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class AllFilter extends AbstractCompositeFilter
+{
+    public function accept(\ReflectionClass $class)
+    {
+        foreach($this->filters as $filter) {
+            if (!$filter->accept($class)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/Model/Filter/Composite/AnyFilter.php b/Model/Filter/Composite/AnyFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..e671b857e4af9fffd49cedc61f57ba4e35aa126d
--- /dev/null
+++ b/Model/Filter/Composite/AnyFilter.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\Model\Filter\Composite;
+
+/**
+ * Description of AnyFilter
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class AnyFilter extends AbstractCompositeFilter
+{
+    public function accept(\ReflectionClass $class)
+    {
+        foreach($this->filters as $filter) {
+            if ($filter->accept($class)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/Model/Filter/DirectoryFilter.php b/Model/Filter/DirectoryFilter.php
index 02a8f81dd78da225c8644ae8d8c31d403af418ad..85fa8cf56db664875228e7a33472897fcb5e6263 100644
--- a/Model/Filter/DirectoryFilter.php
+++ b/Model/Filter/DirectoryFilter.php
@@ -21,20 +21,32 @@ class DirectoryFilter implements ClassFilterInterface
     /**
      * @var string[]
      */
-    private $accepted = [];
+    private $paths = [];
 
-    public function __construct(array $accepted)
+    /**
+     * @var boolean
+     */
+    private $notFound;
+
+    public function __construct(array $paths, $notFound = false)
     {
-        $this->accepted = $accepted;
+        $this->paths = array_map(
+            function ($path) {
+                return rtrim(strtr($path, '/\\', DIRECTORY_SEPARATOR), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+            },
+            $paths
+        );
+        $this->notFound = $notFound;
     }
 
     public function accept(ReflectionClass $class)
     {
-        foreach($this->accepted as $path) {
-            if (strpos($class->getFileName(), $path) === 0) {
-                return true;
+        $filepath = dirname($class->getFileName());
+        foreach($this->paths as $path) {
+            if (strpos($filepath, $path) === 0) {
+                return !$this->notFound;
             }
         }
-        return false;
+        return $this->notFound;
     }
 }
diff --git a/Model/Filter/NamespaceFilter.php b/Model/Filter/NamespaceFilter.php
index dcafefc871fb3095526a91eef3cd80e9e9023e16..4b01aa2f1eced69ea3717851e52ef3a4db4faa19 100644
--- a/Model/Filter/NamespaceFilter.php
+++ b/Model/Filter/NamespaceFilter.php
@@ -21,20 +21,32 @@ class NamespaceFilter implements ClassFilterInterface
     /**
      * @var string[]
      */
-    private $accepted = [];
+    private $namespaces = [];
 
-    public function __construct(array $accepted)
+    /**
+     * @var boolena
+     */
+    private $notFound;
+
+    public function __construct(array $namespaces, $notFound = false)
     {
-        $this->accepted = $accepted;
+        $this->namespaces = array_map(
+            function ($namespace) {
+                return trim($namespace, '\\').'\\';
+            },
+            $namespaces
+        );
+        $this->notFound = $notFound;
     }
 
     public function accept(ReflectionClass $class)
     {
-        foreach($this->accepted as $namespace) {
-            if (strpos($class->getName(), $namespace) === 0) {
-                return true;
+        $className = $class->getNamespaceName().'\\';
+        foreach($this->namespaces as $namespace) {
+            if (strpos($className, $namespace) === 0) {
+                return !$this->notFound;
             }
         }
-        return false;
+        return $this->notFound;
     }
 }