diff --git a/TODO b/TODO
index bf0ef94..701fbd3 100644
--- a/TODO
+++ b/TODO
@@ -2,7 +2,6 @@ To Do:
  * Implement "DriverFor" support
  * Scanning packages for annotated components
  * General usage documentation
- * Easier anonymous components
  * Uncouple component-provided names from the library
 
 Other ideas (maybe later if needed):
diff --git a/src/main/java/info/ebenoit/ebul/cmp/Anonymous.java b/src/main/java/info/ebenoit/ebul/cmp/Anonymous.java
new file mode 100644
index 0000000..a13e421
--- /dev/null
+++ b/src/main/java/info/ebenoit/ebul/cmp/Anonymous.java
@@ -0,0 +1,21 @@
+package info.ebenoit.ebul.cmp;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+
+/**
+ * Annotation indicating that a component will not have a name.
+ *
+ * @author <a href="mailto:ebenoit@ebenoit.info">E. BenoƮt</a>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( ElementType.TYPE )
+public @interface Anonymous
+{
+	// EMPTY
+}
diff --git a/src/main/java/info/ebenoit/ebul/cmp/ComponentState.java b/src/main/java/info/ebenoit/ebul/cmp/ComponentState.java
index a78e17a..0f94658 100644
--- a/src/main/java/info/ebenoit/ebul/cmp/ComponentState.java
+++ b/src/main/java/info/ebenoit/ebul/cmp/ComponentState.java
@@ -84,7 +84,7 @@ public final class ComponentState
 			name = ( (ParametricComponent) component ).getComponentName( );
 		} else {
 			name = ci.getName( );
-			if ( name == null ) {
+			if ( "".equals( name ) ) {
 				name = component.getClass( ).getSimpleName( );
 			}
 		}
diff --git a/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java b/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java
index 5f59bfb..7078bad 100644
--- a/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java
+++ b/src/main/java/info/ebenoit/ebul/cmp/NewComponentInfo.java
@@ -75,15 +75,22 @@ public final class NewComponentInfo< T >
 
 		// Sets the new component's name
 		final Component aComp = klass.getAnnotation( Component.class );
-		if ( aComp != null && !"".equals( aComp.value( ) ) ) {
+		final boolean isAnon = klass.isAnnotationPresent( Anonymous.class );
+		if ( isAnon ) {
 			if ( ParametricComponent.class.isAssignableFrom( klass ) ) {
+				throw new ComponentDefinitionException( "parametric component can't be anonymous" );
+			}
+			if ( aComp != null && !"".equals( aComp.value( ) ) ) {
+				throw new ComponentDefinitionException( "named component can't be anonymous" );
+			}
+			info.setName( null );
+		} else if ( aComp != null ) {
+			if ( !"".equals( aComp.value( ) ) && ParametricComponent.class.isAssignableFrom( klass ) ) {
 				throw new ComponentDefinitionException( "parametric component can't be named" );
 			}
 			info.setName( aComp.value( ) );
-		} else if ( !ParametricComponent.class.isAssignableFrom( klass ) ) {
-			info.setName( klass.getSimpleName( ) );
 		} else {
-			info.setName( null );
+			info.setName( "" );
 		}
 
 		// Autostart flag
@@ -365,7 +372,8 @@ public final class NewComponentInfo< T >
 	 * Sets the new component's name
 	 *
 	 * @param name
-	 *            the new component's name
+	 *            the new component's name. May be <code>null</code> for an anonymous component or {@code ""} for a
+	 *            component whose class name will serve as its name.
 	 * @return the current object
 	 */
 	public NewComponentInfo< T > setName( final String name )
@@ -376,7 +384,8 @@ public final class NewComponentInfo< T >
 
 
 	/**
-	 * @return the name of the new component
+	 * @return the name of the new component. May be <code>null</code> for an anonymous component or {@code ""} for a
+	 *         component whose class name will serve as its name.
 	 */
 	public String getName( )
 	{
diff --git a/src/test/java/info/ebenoit/ebul/cmp/TestComponentState.java b/src/test/java/info/ebenoit/ebul/cmp/TestComponentState.java
index c1ecda3..610b230 100644
--- a/src/test/java/info/ebenoit/ebul/cmp/TestComponentState.java
+++ b/src/test/java/info/ebenoit/ebul/cmp/TestComponentState.java
@@ -71,6 +71,7 @@ public class TestComponentState
 	{
 		private ComponentRegistry registry;
 
+
 		@Override
 		public void setComponentRegistry( ComponentRegistry registry )
 		{
@@ -138,7 +139,6 @@ public class TestComponentState
 		final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object );
 		final ComponentState cs = new ComponentState( this.reg , ci );
 		Assert.assertSame( object , cs.getComponent( ) );
-		Assert.assertEquals( "Object" , cs.getName( ) );
 	}
 
 
@@ -150,7 +150,6 @@ public class TestComponentState
 		final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( ( ) -> object );
 		final ComponentState cs = new ComponentState( this.reg , ci );
 		Assert.assertSame( object , cs.getComponent( ) );
-		Assert.assertEquals( "Object" , cs.getName( ) );
 	}
 
 
@@ -168,6 +167,29 @@ public class TestComponentState
 	}
 
 
+	/** Test: initialising a {@link ComponentState} with a <code>null</code> name */
+	@Test
+	public void testInitialiseNullName( )
+	{
+		final Object object = new Object( );
+		final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object );
+		final ComponentState cs = new ComponentState( this.reg , ci );
+		Assert.assertNull( cs.getName( ) );
+	}
+
+
+	/** Test: initialising a {@link ComponentState} with an automatic name */
+	@Test
+	public void testInitialiseAutoName( )
+	{
+		final Object object = new Object( );
+		final NewComponentInfo< Object > ci = new NewComponentInfo< Object >( object ) //
+				.setName( "" );
+		final ComponentState cs = new ComponentState( this.reg , ci );
+		Assert.assertEquals( "Object" , cs.getName( ) );
+	}
+
+
 	/** Test: initialising a {@link ComponentState} with a supplied name */
 	@Test
 	public void testInitialiseWithName( )
diff --git a/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java b/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java
index e534b22..5206ae8 100644
--- a/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java
+++ b/src/test/java/info/ebenoit/ebul/cmp/TestNewComponentInfo.java
@@ -62,6 +62,50 @@ public class TestNewComponentInfo
 		// EMPTY
 	}
 
+	/** Test anonymous component */
+	@Anonymous
+	private static class TestCmpAnon
+	{
+		// EMPTY
+	}
+
+	/** Test anonymous component with empty {@link Component} annotation */
+	@Anonymous
+	@Component
+	private static class TestCmpAnonComponent
+	{
+		// EMPTY
+	}
+
+	/** Test anonymous component that implements {@link ParametricComponent} (invalid!) */
+	@Anonymous
+	private static class TestCmpAnonPN
+			implements ParametricComponent
+	{
+
+		@Override
+		public String getComponentName( )
+		{
+			return null;
+		}
+
+	}
+
+	/** Test anonymous component that has a specified name (invalid!) */
+	@Component( "Fail!" )
+	@Anonymous
+	private static class TestCmpAnonNamed
+			implements ParametricComponent
+	{
+
+		@Override
+		public String getComponentName( )
+		{
+			return null;
+		}
+
+	}
+
 	/** Test component with a parametric name */
 	private static class TestCmpPN
 			implements ParametricComponent
@@ -372,7 +416,7 @@ public class TestNewComponentInfo
 	public void testFromClass1( )
 	{
 		NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmp1.class );
-		assertEquals( "TestCmp1" , nci.getName( ) );
+		assertEquals( "" , nci.getName( ) );
 		assertFalse( nci.getAutostart( ) );
 		assertTrue( nci.getDependencies( ).isEmpty( ) );
 		assertNull( nci.getDriverFor( ) );
@@ -412,7 +456,7 @@ public class TestNewComponentInfo
 	public void testFromClass4( )
 	{
 		NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmp4.class );
-		assertEquals( "component name was inherited!" , "TestCmp4" , nci.getName( ) );
+		assertNotEquals( "component name was inherited!" , "Test component" , nci.getName( ) );
 		assertFalse( "autostart state was inherited!" , nci.getAutostart( ) );
 		HashSet< DependencyInfo > deps = nci.getDependencies( );
 		assertEquals( 3 , deps.size( ) );
@@ -422,6 +466,49 @@ public class TestNewComponentInfo
 	}
 
 
+	/** Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation */
+	@Test
+	public void testFromClassAnon( )
+	{
+		NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmpAnon.class );
+		assertNull( nci.getName( ) );
+	}
+
+
+	/**
+	 * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation and an
+	 * empty {@link Component} annotation
+	 */
+	@Test
+	public void testFromClassAnonComponent( )
+	{
+		NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmpAnonComponent.class );
+		assertNull( nci.getName( ) );
+	}
+
+
+	/**
+	 * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation that
+	 * implements {@link ParametricComponent}
+	 */
+	@Test( expected = ComponentDefinitionException.class )
+	public void testFromClassAnonPN( )
+	{
+		NewComponentInfo.fromClass( TestCmpAnonPN.class );
+	}
+
+
+	/**
+	 * Test: {@link NewComponentInfo#fromClass(Class)} on a component class with the {@link Anonymous} annotation and a
+	 * {@link Component} annotation carrying a value
+	 */
+	@Test( expected = ComponentDefinitionException.class )
+	public void testFromClassAnonNamed( )
+	{
+		NewComponentInfo.fromClass( TestCmpAnonNamed.class );
+	}
+
+
 	/**
 	 * Test: {@link NewComponentInfo#fromClass(Class)} on a component class that implements {@link ParametricComponent}
 	 */
@@ -429,7 +516,7 @@ public class TestNewComponentInfo
 	public void testFromClassPN1( )
 	{
 		NewComponentInfo< ? > nci = NewComponentInfo.fromClass( TestCmpPN.class );
-		assertNull( nci.getName( ) );
+		assertEquals( "" , nci.getName( ) );
 	}
 
 
@@ -527,8 +614,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );
@@ -556,8 +642,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );
@@ -626,8 +711,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );
@@ -655,8 +739,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );
@@ -739,8 +822,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );
@@ -767,8 +849,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );
@@ -796,8 +877,7 @@ public class TestNewComponentInfo
 		assertEquals( 1 , deps.size( ) );
 		assertTrue( deps.contains( expectedDep ) );
 
-		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci
-				.getInjectors( );
+		HashMap< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > injectors = nci.getInjectors( );
 		assertEquals( 1 , injectors.size( ) );
 		ArrayList< ThrowingBiConsumer< Object , Object > > diList = injectors.get( expectedDep );
 		assertEquals( 1 , diList.size( ) );