diff --git a/includes/t-data/dao_tasks.inc.php b/includes/t-data/dao_tasks.inc.php
index 7cbb3a4..1695738 100644
--- a/includes/t-data/dao_tasks.inc.php
+++ b/includes/t-data/dao_tasks.inc.php
@@ -171,8 +171,10 @@ class DAO_Tasks
 			.	'ORDER BY i.item_name , t.task_priority DESC , t.task_title' )->execute( $id );
 		$task->possibleDependencies = $this->query(
 			'SELECT t.task_id AS id , t.task_title AS title , t.item_id AS item , '
-			.		'i.item_name AS item_name '
+			.		'i.item_name AS item_name , l.badness <> 0 AS blocked , '
+			.		'l.completed_at IS NOT NULL AS completed '
 			.	'FROM tasks_possible_dependencies( $1 ) t '
+			.		'INNER JOIN tasks_list l ON t.task_id = l.id '
 			.		'LEFT OUTER JOIN items i USING ( item_id ) '
 			.	'ORDER BY i.item_name , t.task_priority , t.task_title' )->execute( $id );
 		$task->lineage = null;
diff --git a/includes/t-tasks/controllers.inc.php b/includes/t-tasks/controllers.inc.php
index 9322389..de5862d 100644
--- a/includes/t-tasks/controllers.inc.php
+++ b/includes/t-tasks/controllers.inc.php
@@ -527,6 +527,188 @@ class Ctrl_DependencyAdd
 }
 
 
+class Ctrl_DependencyAddFiltering
+	extends Controller
+	implements FormAware
+{
+	private $filtering;
+	private $selector;
+	private $task;
+
+	private $dependencies;
+
+	public function __construct( Form $selector , $task )
+	{
+		$this->selector = $selector;
+		$this->task = $task;
+	}
+
+	public function setForm( Form $form )
+	{
+		$this->filtering = $form;
+	}
+
+	public function handle( Page $page )
+	{
+		$this->filterTaskDependencies( );
+		$this->addDependencySelector( );
+		$this->copyFiltersToSelector( );
+		return null;
+	}
+
+	private function filterTaskDependencies( )
+	{
+		$this->dependencies = array( );
+		$text = trim( $this->getField( 'text' ) );
+		if ( $text == '' ) {
+			$text = array( );
+		} else {
+			$text = array_unique( preg_split( '/\s+/' , $text ) );
+		}
+
+		$state = $this->getField( 'state' );
+		$sActive = ( $state == '' || strstr( $state , 'a' ) !== false );
+		$sBlocked = ( $state == '' || strstr( $state , 'b' ) !== false );
+		$sCompleted = ( $state == '' || strstr( $state , 'c' ) !== false );
+
+		foreach ( $this->task->possibleDependencies as $dep ) {
+			// Check for text
+			$ok = true;
+			foreach ( $text as $tCheck ) {
+				$ok = stristr( $dep->title , $tCheck );
+				if ( !$ok ) {
+					break;
+				}
+			}
+			if ( !$ok ) {
+				continue;
+			}
+
+			// Check state
+			$isBlocked = ( $dep->blocked === 't' );
+			$isCompleted = ( $dep->completed === 't' );
+			if ( $isBlocked && !$sBlocked || $isCompleted && !$sCompleted
+					|| !( $isBlocked || $isCompleted ) && !$sActive ) {
+				continue;
+			}
+
+			$this->dependencies[] = $dep;
+		}
+	}
+
+	private function addDependencySelector( )
+	{
+		$this->selector->addField( $select = Loader::Create( 'Field' , 'dependency' , 'select' )
+			->setDescription( 'Dependency to add:' )
+			->addOption( '' , '(please select a task)' ) );
+
+		if ( $this->task->parent_task === null ) {
+			$depsByItem = $this->getDependenciesByItem( );
+			$items = $this->getItemsToDisplay( $depsByItem );
+			foreach ( $items as $item ) {
+				$prefix = '-' . str_repeat( '--' , $item->depth );
+				$name = $prefix . ' ' . $item->name;
+				$select->addOption( 'I' . $item->id , $name , true );
+				if ( ! array_key_exists( $item->id , $depsByItem ) ) {
+					continue;
+				}
+
+				foreach ( $depsByItem[ $item->id ] as $task ) {
+					$select->addOption( $task->id , $prefix . '-> ' . $task->title );
+				}
+			}
+		} else {
+			foreach ( $this->dependencies as $task ) {
+				$select->addOption( $task->id , $task->title );
+			}
+		}
+		return true;
+
+	}
+
+	private function getItemsToDisplay( $depsByItem )
+	{
+		$dao = Loader::DAO( 'items' );
+		$found = array( );
+		foreach ( array_keys( $depsByItem ) as $id ) {
+			if ( array_key_exists( $id , $found ) ) {
+				continue;
+			}
+			$item = $dao->get( $id );
+			foreach ( $dao->getLineage( $item ) as $parent ) {
+				$found[ $parent ] = 1;
+			}
+			$found[ $id ] = 1;
+		}
+
+		$fByItem = $this->getField( 'items' );
+		$fByItem = ( $fByItem == '' ) ? null : ( (int) $fByItem );
+		$fChildren = ( $this->getField( 'item-children' ) === '1' );
+		$fOKChildren = false;
+		$fDepth = -1;
+
+		$result = array( );
+		foreach ( $dao->getTreeList( ) as $item ) {
+			if ( $fByItem !== null && $fChildren ){
+				if ( $item->id == $fByItem ) {
+					$fOKChildren = true;
+					$fDepth = $item->depth;
+				} else if ( $fOKChildren && $item->depth <= $fDepth ) {
+					$fOKChildren = false;
+				}
+			}
+
+			if ( $fByItem !== null && $item->id != $fByItem && !$fOKChildren ) {
+				continue;
+			}
+			if ( array_key_exists( $item->id , $found ) ) {
+				array_push( $result , $item );
+			}
+		}
+		return $result;
+	}
+
+	private function getDependenciesByItem( )
+	{
+		$dbi = array( );
+		foreach ( $this->dependencies as $pDep ) {
+			$dbi[ $pDep->item ][] = $pDep;
+		}
+		return $dbi;
+	}
+
+	private function copyFiltersToSelector( )
+	{
+		$fields = array( 'text' , 'state' , 'items' , 'item-children' );
+		foreach ( $fields as $f ) {
+			$v = $this->getField( $f );
+			$this->selector->addField(
+				Loader::Create( 'Field' , 'filters-' . $f , 'hidden' )
+					->setMandatory( false )
+					->setDefaultValue( $v ) );
+		}
+	}
+
+	public function getFiltersFromSelector( )
+	{
+		$fields = array( 'text' , 'state' , 'items' , 'item-children' );
+		foreach ( $fields as $f ) {
+			$field = $this->filtering->field( $f );
+			if ( $field !== null ) {
+				$fv = $this->getParameter( 'filters-' . $f , 'POST' );
+				$field->setFormValue( $fv );
+			}
+		}
+	}
+
+	private function getField( $name )
+	{
+		$fld = $this->filtering->field( $name );
+		return $fld ? $fld->value( ) : '';
+	}
+}
+
+
 class Ctrl_DependencyDelete
 	extends Controller
 	implements FormAware
diff --git a/includes/t-tasks/package.inc.php b/includes/t-tasks/package.inc.php
index 3c13298..992cca5 100644
--- a/includes/t-tasks/package.inc.php
+++ b/includes/t-tasks/package.inc.php
@@ -20,6 +20,7 @@ $package[ 'ctrls' ][] = 'delete_task_form';
 $package[ 'ctrls' ][] = 'delete_task';
 $package[ 'ctrls' ][] = 'dependency_add';
 $package[ 'ctrls' ][] = 'dependency_add_form';
+$package[ 'ctrls' ][] = 'dependency_add_filtering';
 $package[ 'ctrls' ][] = 'dependency_delete';
 $package[ 'ctrls' ][] = 'dependency_delete_form';
 $package[ 'ctrls' ][] = 'edit_note_form';
diff --git a/includes/t-tasks/page_controllers.inc.php b/includes/t-tasks/page_controllers.inc.php
index a15c628..5d469b5 100644
--- a/includes/t-tasks/page_controllers.inc.php
+++ b/includes/t-tasks/page_controllers.inc.php
@@ -454,78 +454,90 @@ class Ctrl_DependencyAddForm
 		$page->setTitle( $task->title . ' (task)' );
 
 		// Generate form
-		$form = Loader::Create( 'Form' , 'Add dependency' , 'add-dep' )
+		$form = Loader::Create( 'Form' , 'Add dependency' , 'add-dep' , 'Select dependency' )
 			->addField( Loader::Create( 'Field' , 'to' , 'hidden' )
-			->setDefaultValue( $id ) );
-		$this->addDependencySelector( $form , $task->possibleDependencies , $task->parent_task === null );
-		return $form->setURL( 'tasks/view?id=' . $id )
-			->addController( Loader::Ctrl( 'dependency_add' ) )
-			->controller( );
+				->setDefaultValue( $id ) )
+			->setURL( 'tasks/view?id=' . $id )
+			->addController( Loader::Ctrl( 'dependency_add' ) );
 
+		$filters = $this->handleFiltering( $page , $form , $task );
+
+		return array( $form->controller( ) , $filters );
 	}
 
-	private function addDependencySelector( $form , $possibleDependencies , $topLevel )
+	private function handleFiltering( Page $page , Form $form , $task )
 	{
-		$form->addField( $select = Loader::Create( 'Field' , 'dependency' , 'select' )
-			->setDescription( 'Dependency to add:' )
-			->addOption( '' , '(please select a task)' ) );
+		$fCtrl = Loader::Ctrl( 'dependency_add_filtering' , $form , $task );
+		$filters = $this->makeFilteringForm( $form , $fCtrl , $task );
 
-		if ( $topLevel ) {
-			$depsByItem = $this->getDependenciesByItem( $possibleDependencies );
-			$items = $this->getItemsToDisplay( $depsByItem );
-			foreach ( $items as $item ) {
-				$prefix = '-' . str_repeat( '--' , $item->depth );
-				$name = $prefix . ' ' . $item->name;
-				$select->addOption( 'I' . $item->id , $name , true );
-				if ( ! array_key_exists( $item->id , $depsByItem ) ) {
-					continue;
-				}
-
-				foreach ( $depsByItem[ $item->id ] as $task ) {
-					$select->addOption( $task->id , $prefix . '-> ' . $task->title );
-				}
-			}
-		} else {
-			foreach ( $possibleDependencies as $task ) {
-				$select->addOption( $task->id , $task->title );
-			}
+		// Was the filters form submitted?
+		try {
+			$submitted = $this->getParameter( 'filter-deps-submit' , 'POST' );
+		} catch ( ParameterException $e ) {
+			$submitted = null;
+		}
+		if ( $submitted !== null ) {
+			return $filters->controller( )->handle( $page );
 		}
-		return true;
 
+		// Was the main form submitted?
+		try {
+			$submitted = $this->getParameter( 'to' , 'POST' );
+		} catch ( ParameterException $e ) {
+			$submitted = null;
+		}
+		if ( $submitted !== null ) {
+			$fCtrl->getFiltersFromSelector( );
+		}
+
+		// Fake handling the form
+		$fCtrl->handle( $page );
+		return $filters->view( );
 	}
 
-	private function getDependenciesByItem( $possibleDependencies )
+	private function makeFilteringForm( Form $form , Controller $ctrl , $task )
 	{
-		$dbi = array( );
-		foreach ( $possibleDependencies as $pDep ) {
-			$dbi[ $pDep->item ][] = $pDep;
+		// Generate filtering form, and handle it immediately
+		$filters = Loader::Create( 'Form' , 'Apply' , 'filter-deps' , 'Filter dependencies' )
+			->addController( $ctrl )
+			->setAction( '?' )
+			->addField( Loader::Create( 'Field' , 'to' , 'hidden' )
+				->setDefaultValue( $task->id ) )
+			->addField( Loader::Create( 'Field' , 'text' , 'text' )
+				->setDescription( 'Name must contain:' )
+				->setMandatory( false ) )
+			->addField( Loader::Create( 'Field' , 'state' , 'select' )
+				->setDescription( 'Task state:' )
+				->setMandatory( false )
+				->addOption( 'abc' , 'Indifferent' )
+				->addOption( 'ab' , 'Active or blocked' )
+				->addOption( 'a' , 'Active' )
+				->addOption( 'b' , 'Blocked' )
+				->addOption( 'c' , 'Completed' ) );
+		if ( $task->parent_task === null ) {
+			$itemSelect = Loader::Create( 'Field' , 'items' , 'select' )
+				->setDescription( 'Limit to items:' )
+				->setMandatory( false )
+				->addOption( '' , '(Any item)' );
+			$this->addItemSelector( $itemSelect );
+			$filters->addField( $itemSelect )
+				->addField( Loader::Create( 'Field' , 'item-children' , 'select' )
+					->setDescription( 'Include child items:' )
+					->setMandatory( false )
+					->addOption( '1' , 'Yes' )
+					->addOption( '0' , 'No' ) );
 		}
-		return $dbi;
+		return $filters;
 	}
 
-	private function getItemsToDisplay( $depsByItem )
+	// FIXME: duplicate code
+	private function addItemSelector( $select )
 	{
-		$dao = Loader::DAO( 'items' );
-		$allItems = $dao->getTreeList( );
-		$found = array( );
-		foreach ( array_keys( $depsByItem ) as $id ) {
-			if ( array_key_exists( $id , $found ) ) {
-				continue;
-			}
-			$item = $dao->get( $id );
-			foreach ( $dao->getLineage( $item ) as $parent ) {
-				$found[ $parent ] = 1;
-			}
-			$found[ $id ] = 1;
+		$items =  Loader::DAO( 'items' )->getTreeList( );
+		foreach ( $items as $item ) {
+			$name = '-' . str_repeat( '--' , $item->depth ) . ' ' . $item->name;
+			$select->addOption( $item->id , $name );
 		}
-
-		$result = array( );
-		foreach ( $allItems as $item ) {
-			if ( array_key_exists( $item->id , $found ) ) {
-				array_push( $result , $item );
-			}
-		}
-		return $result;
 	}
 }