diff --git a/TODO b/TODO
index 701fbd3..4600634 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 To Do:
  * Implement "DriverFor" support
- * Scanning packages for annotated components
  * General usage documentation
  * Uncouple component-provided names from the library
 
diff --git a/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java b/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java
index 7078bad..4bc6a9a 100644
--- a/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java
+++ b/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java
@@ -1,6 +1,7 @@
 package info.ebenoit.ebul.cmp;
 
 
+import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -15,7 +16,9 @@ import info.ebenoit.ebul.func.ThrowingBiConsumer;
 import info.ebenoit.ebul.func.ThrowingConsumer;
 import info.ebenoit.ebul.func.ThrowingSupplier;
 import info.ebenoit.ebul.reflection.Annotations;
+import info.ebenoit.ebul.reflection.Classes;
 import info.ebenoit.ebul.reflection.MemberFinder;
+import info.ebenoit.ebul.reflection.PackageScanner;
 
 
 
@@ -55,6 +58,39 @@ public final class NewComponentInfo< T >
 	}
 
 
+	/**
+	 * Scans a package for classes that correspond to annotated components and processes them using
+	 * {@link #fromClass(Class)}
+	 * 
+	 * @param name
+	 *            the name of the package to scan
+	 * @param recursive
+	 *            <code>true</code> if child packages are to be scanned as well
+	 * @return the list of component registration records
+	 * @throws IOException
+	 *             if an I/O error occurs while scanning the packages
+	 * @throws ClassNotFoundException
+	 *             if one of the classes cannot be loaded
+	 * @throws ComponentDefinitionException
+	 *             if one of the loaded definitions is invalid
+	 */
+	public static ArrayList< NewComponentInfo< ? > > scanPackage( final String name , final boolean recursive )
+			throws IOException , ClassNotFoundException , ComponentDefinitionException
+	{
+		final PackageScanner packageScanner = new PackageScanner( name , recursive );
+		final ArrayList< Class< ? > > classes = packageScanner.findClasses( //
+				c -> ( ( c.getModifiers( ) & ( Modifier.ABSTRACT | Modifier.INTERFACE ) ) == 0
+						&& Classes.hasAncestorMatching( c , x -> x.isAnnotationPresent( Component.class ) , true ) ) );
+
+		final ArrayList< NewComponentInfo< ? > > results = new ArrayList< >( );
+		final int n = classes.size( );
+		for ( int i = 0 ; i < n ; i++ ) {
+			results.add( NewComponentInfo.fromClass( classes.get( i ) ) );
+		}
+		return results;
+	}
+
+
 	/**
 	 * Creates a new component information record based on a component's annotated class.
 	 *
@@ -540,7 +576,7 @@ public final class NewComponentInfo< T >
 		}
 
 		@SuppressWarnings( "unchecked" )
-		ThrowingBiConsumer< Object , Object > ci = (ThrowingBiConsumer< Object , Object >) injector;
+		final ThrowingBiConsumer< Object , Object > ci = (ThrowingBiConsumer< Object , Object >) injector;
 		injectors.add( ci );
 
 		this.dependencies.add( dependency );
diff --git a/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java b/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java
index 5206ae8..f21da50 100644
--- a/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java
+++ b/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java
@@ -5,12 +5,20 @@ import org.junit.Test;
 
 import info.ebenoit.ebul.func.ThrowingBiConsumer;
 import info.ebenoit.ebul.func.ThrowingConsumer;
+import test.inherited.CBase;
+import test.inherited.CChild;
+import test.inherited.CChildOfAbstract;
+import test.interfaces.CImplementation;
+import test.simple.CSimple;
 
 import static org.junit.Assert.*;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 
 
@@ -889,4 +897,51 @@ public class TestNewComponentInfo
 		injector.accept( cmp , inject );
 		assertSame( inject , cmp.dependency );
 	}
+
+
+	/**
+	 * Test: {@link NewComponentInfo#scanPackage(String, boolean)} finds a simple {@link Component}-annotated class
+	 */
+	@Test
+	public void testScanPackageSimple( )
+			throws ComponentDefinitionException , ClassNotFoundException , IOException
+	{
+		ArrayList< NewComponentInfo< ? > > result = NewComponentInfo.scanPackage( "test.simple" , false );
+		assertEquals( 1 , result.size( ) );
+		assertSame( CSimple.class , result.get( 0 ).getSupplier( ).get( ).getClass( ) );
+	}
+
+
+	/**
+	 * Test: {@link NewComponentInfo#scanPackage(String, boolean)} finds components that inherit each other, ignoring
+	 * abstract classes
+	 */
+	@Test
+	public void testScanPackageInheritance( )
+			throws ComponentDefinitionException , ClassNotFoundException , IOException
+	{
+		ArrayList< NewComponentInfo< ? > > result = NewComponentInfo.scanPackage( "test.inherited" , false );
+		assertEquals( 3 , result.size( ) );
+
+		Set< ? > classes = result.stream( ).map( x -> x.getSupplier( ).get( ).getClass( ) )
+				.collect( Collectors.toSet( ) );
+		assertTrue( classes.contains( CBase.class ) );
+		assertTrue( classes.contains( CChild.class ) );
+		assertTrue( classes.contains( CChildOfAbstract.class ) );
+	}
+
+
+	/**
+	 * Test: {@link NewComponentInfo#scanPackage(String, boolean)} finds components defined by implementing a
+	 * {@link Component}-annotated interface
+	 */
+	@Test
+	public void testScanPackageInterfaces( )
+			throws ComponentDefinitionException , ClassNotFoundException , IOException
+	{
+		ArrayList< NewComponentInfo< ? > > result = NewComponentInfo.scanPackage( "test.interfaces" , false );
+		assertEquals( 1 , result.size( ) );
+
+		assertSame( CImplementation.class , result.get( 0 ).getSupplier( ).get( ).getClass( ) );
+	}
 }
diff --git a/src/test/java/test/inherited/CAbstractBase.java b/src/test/java/test/inherited/CAbstractBase.java
new file mode 100644
index 0000000..3e63359
--- /dev/null
+++ b/src/test/java/test/inherited/CAbstractBase.java
@@ -0,0 +1,9 @@
+package test.inherited;
+
+import info.ebenoit.ebul.cmp.Component;
+
+@Component
+public abstract class CAbstractBase
+{
+	// EMPTY
+}
diff --git a/src/test/java/test/inherited/CAbstractChild.java b/src/test/java/test/inherited/CAbstractChild.java
new file mode 100644
index 0000000..2529376
--- /dev/null
+++ b/src/test/java/test/inherited/CAbstractChild.java
@@ -0,0 +1,8 @@
+package test.inherited;
+
+
+public abstract class CAbstractChild
+		extends CBase
+{
+	// EMPTY
+}
diff --git a/src/test/java/test/inherited/CBase.java b/src/test/java/test/inherited/CBase.java
new file mode 100644
index 0000000..45ab14b
--- /dev/null
+++ b/src/test/java/test/inherited/CBase.java
@@ -0,0 +1,12 @@
+package test.inherited;
+
+
+import info.ebenoit.ebul.cmp.Component;
+
+
+
+@Component
+public class CBase
+{
+	// EMPTY
+}
diff --git a/src/test/java/test/inherited/CChild.java b/src/test/java/test/inherited/CChild.java
new file mode 100644
index 0000000..15150fd
--- /dev/null
+++ b/src/test/java/test/inherited/CChild.java
@@ -0,0 +1,8 @@
+package test.inherited;
+
+
+public class CChild
+		extends CBase
+{
+	// EMPTY
+}
diff --git a/src/test/java/test/inherited/CChildOfAbstract.java b/src/test/java/test/inherited/CChildOfAbstract.java
new file mode 100644
index 0000000..62d42c5
--- /dev/null
+++ b/src/test/java/test/inherited/CChildOfAbstract.java
@@ -0,0 +1,8 @@
+package test.inherited;
+
+
+public class CChildOfAbstract
+		extends CAbstractBase
+{
+
+}
diff --git a/src/test/java/test/interfaces/CImplementation.java b/src/test/java/test/interfaces/CImplementation.java
new file mode 100644
index 0000000..8257161
--- /dev/null
+++ b/src/test/java/test/interfaces/CImplementation.java
@@ -0,0 +1,8 @@
+package test.interfaces;
+
+
+public class CImplementation
+		implements CInterface
+{
+	// EMPTY
+}
diff --git a/src/test/java/test/interfaces/CInterface.java b/src/test/java/test/interfaces/CInterface.java
new file mode 100644
index 0000000..cd4e89a
--- /dev/null
+++ b/src/test/java/test/interfaces/CInterface.java
@@ -0,0 +1,12 @@
+package test.interfaces;
+
+
+import info.ebenoit.ebul.cmp.Component;
+
+
+
+@Component
+public interface CInterface
+{
+	// EMPTY
+}
diff --git a/src/test/java/test/simple/CSimple.java b/src/test/java/test/simple/CSimple.java
new file mode 100644
index 0000000..31abae7
--- /dev/null
+++ b/src/test/java/test/simple/CSimple.java
@@ -0,0 +1,12 @@
+package test.simple;
+
+
+import info.ebenoit.ebul.cmp.Component;
+
+
+
+@Component
+public class CSimple
+{
+	// EMPTY
+}