private void createPatternsImpl(final AngleUnitFlapPattern seed, final int indexToAdd,
			final Collection<Piece> pieces) {

		trace(seed);

		if (indexToAdd == tailIndex) {
			if (acceptablePatternCondition.holds(seed)) {
				trace("accepted");
				patterns.add(seed.cloneInstance());
			}
			return;
		}

		if (indexToAdd > tailIndex) {
			trace("recursion stopped: overlength");
			return;
		}

		if (pieces.isEmpty()) {
			trace("recurtion stopped: empty candidates");
			return;
		}

		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("seed: " + seed);
			LOGGER.debug("indexToAdd: " + indexToAdd);
			LOGGER.debug("pieces: " + pieces);
		}

		for (Piece piece : pieces) {

			trace(piece);

			if (!isAppendable(seed, indexToAdd, piece)) {
				continue;
			}

			int nextIndex = appendTo(seed, indexToAdd, piece);
			if (!pruningCondition.holds(seed)) {
				// call with connectable pieces
				createPatternsImpl(seed, nextIndex, pieceMap.get(piece.getLast()));
			}

			undo(seed, indexToAdd, piece);
		}

	}