Openembedded Devel Discussions
 help / color / mirror / Atom feed
From: auh@moto-timo.dev
To: openembedded-devel@lists.openembedded.org
Subject: [AUH] python3-behave: upgrading to 6 FAILED
Date: Wed, 12 Jul 2023 05:30:10 +0000 (UTC)	[thread overview]
Message-ID: <20230712053010.DA7C6C001DC@smtp.lore.kernel.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 1247077 bytes --]

Hello,

this email is a notification from the Auto Upgrade Helper
that the automatic attempt to upgrade the recipe *python3-behave* to *6* has Failed(do_compile).

Detailed error information:

do_compile failed



Next steps:
    - apply the patch: git am 0001-python3-behave-upgrade-1.2.6-git9520119376046aeff738.patch
    - check the changes to upstream patches and summarize them in the commit message,
    - compile an image that contains the package
    - perform some basic sanity tests
    - amend the patch and sign it off: git commit -s --reset-author --amend
    - send it to the appropriate mailing list

Alternatively, if you believe the recipe should not be upgraded at this time,
you can fill RECIPE_NO_UPDATE_REASON in respective recipe file so that
automatic upgrades would no longer be attempted.

Please review the attached files for further information and build/update failures.
Any problem please file a bug at https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Automated%20Update%20Handler

Regards,
The Upgrade Helper

-- >8 --
From 815d53cd9a095b0b67dc6f98ad9a7fa251edefbf Mon Sep 17 00:00:00 2001
From: Upgrade Helper <auh@moto-timo.dev>
Date: Tue, 11 Jul 2023 17:12:25 -0500
Subject: [PATCH] python3-behave: upgrade
 1.2.6+git9520119376046aeff73804b5f1ea05d87a63f370 -> 6

---
 ...ioOutlineBuilder-was-not-copying-des.patch |   22 +
 .../0002-UPDATE-FIXED-725.patch               |   21 +
 ...ST-to-verify-that-issue-725-is-fixed.patch |   60 +
 ...ter-counts-computation-when-Rules-ar.patch |  342 +
 ...print_summary-Simplify-if-Rules-are-.patch |   60 +
 ...r-Add-basic-support-output-for-Rules.patch |  395 +
 ...MP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch |   67 +
 .../0008-Correct-examples-and-docstring.patch |   41 +
 ...ure.run_items-processing-with-Rule-s.patch |   58 +
 ...-sphinx-intl-support-for-READTHEDOCS.patch |   58 +
 ...ent-package-versions-in-requirements.patch |   81 +
 .../0012-docs-conf.py-tweaks.patch            |   30 +
 ...lled-after_rule-hook-was-after_after.patch |   30 +
 ...d-hints-on-Gherkin-v6-grammar-issues.patch |   45 +
 .../0015-README-ReST-tweaks.patch             |   18 +
 ...016-Example-using-Gherkin-v6-grammar.patch |  228 +
 .../0017-PREPARE-Python-3.8-support.patch     |   39 +
 ...x-logging.Formatter-validate-problem.patch |   22 +
 ...arily-move-py38-dev-to-front-build-f.patch |   28 +
 ...Tweaks-for-faster-builds-temporarily.patch |   35 +
 ...8-logging.Formatter.validate-problem.patch |   47 +
 ...on-3.8-asyncio.coroutine-is-deprecat.patch |   42 +
 .../0023-UPDATE-Add-755-info.patch            |   24 +
 ...ted-to-docstring-example-and-weird-b.patch |   25 +
 ...pe-sequence-warnings-w-regex-pattern.patch |   29 +
 ...NUP-Move-deprecated-tag-matcher-clas.patch | 1020 +++
 .../python3-behave/0027-Comment-tweaks.patch  |   30 +
 ...-related-to-invalid-escapes-in-regex.patch |   79 +
 ...ould-not-break-configured-rerun-sett.patch |   73 +
 ...les-and-failing-scenarios-enable-via.patch |   36 +
 ..._v6-Tweak-ScenarioOutline-Examples-t.patch |   27 +
 .../0032-Add-info-on-merged-pull-588.patch    |   21 +
 ...3-Tweak-tests-required-by-pytest-5.0.patch |   97 +
 ...st-instead-of-nose-to-remove-nose.im.patch |  180 +
 ...Y-nose-to-avoid-nose.importer-warnin.patch | 1815 ++++
 ...0036-FIX-Remove-test-from-pytest-run.patch |   22 +
 ...on-Add-support-for-Scenario-containe.patch |  652 ++
 ...tion-for-Select-by-location-for-Scen.patch |   58 +
 .../0039-tests-Fix-warnings-for-python3.patch |   50 +
 ...ag-expressions-1.1.2-to-fix-warnings.patch |   55 +
 ...ENT-Support-emojis-in-feature-files-.patch |   91 +
 ...valid-escape-char-in-regex-w-python3.patch |  250 +
 ...3-Example-related-to-question-in-756.patch |  335 +
 ...X-python3.8-regressions-on-CI-server.patch |  489 +
 .../0045-UPDATE-Mark-issue-755-as-fixed.patch |   46 +
 ...DATE-Cucumber-gherkin-languages.json.patch |   57 +
 ...ule-keyword-translation-in-portugues.patch |  202 +
 ...-generate-from-gherkin-languages.jso.patch |  141 +
 ...ming-to-fixture.behave.no_background.patch |  322 +
 ...50-EXAMPLE-Cleanup-Gherkin-v6-README.patch |   64 +
 ...for-feature.background-inheritance-f.patch | 1510 +++
 ...-Add-support-for-runtime-constraints.patch |  269 +
 .../0053-Use-runtime-constraints.patch        |  196 +
 ...0054-CLEANUP-Remove-deprecated-parts.patch | 3937 ++++++++
 ...0055-CLEANUP-Remove-deprecated-parts.patch |  736 ++
 ...rform-more-Gherkin-v6-checks-and-run.patch |  155 +
 ...-and-python-module-old-was-broken-no.patch |   72 +
 .../0058-UTIL-Formatting-tweaks.patch         |   22 +
 ...e-use_fixture_by_tag-didn-t-return-t.patch |   23 +
 .../0060-Added-issue-unit-test.patch          |   62 +
 ...e-pull-request-767-with-minor-tweaks.patch |   60 +
 ...sue-766-PrettyFormatter-UnicodeError.patch |   83 +
 ...enarioOutline.Examples-without-table.patch |   74 +
 ...enarioOutline.Examples-without-table.patch |   21 +
 .../0065-Nibble-TravisCI-to-wake-up.patch     |   21 +
 .../0066-Tweak-pytest-version-selection.patch |   37 +
 ...figuration-to-silence-JUnit-XML-dial.patch |   37 +
 ...e-test-for-wildcard-pattern-matching.patch |   56 +
 ...ATE-dependencies-path.py-path-pytest.patch |  141 +
 ...eprecatedWarning-from-distutils-pack.patch |   25 +
 ...-Add-ContextMode-enum-related-to-797.patch |  216 +
 .../0072-Cleanup-comments.patch               |   22 +
 ...phinx-build-problem-async_steps3x.py.patch |   29 +
 ...-parse_expressions-was-parse_builtin.patch |  185 +
 ...ssion-add-links-to-parse_type-module.patch |   40 +
 ...MP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch |   65 +
 ...leanups-related-to-question-in-800-P.patch |  223 +
 ...y-name-uses-regex-pattern-related-to.patch |   82 +
 ...nce-problem-copy-paste-in-Rule-class.patch |   34 +
 ...API-description-for-Runner-Operation.patch |  195 +
 ...0081-FIX-DOCS-Runner-operations-typo.patch |   22 +
 ...ement-Context.add_cleanup-with-layer.patch |  295 +
 ...8.0-parse-versions-1.16.0-.-1.17.x-h.patch |   37 +
 ...Duplicated-steps-AmbiguousStepErrors.patch |   34 +
 .../0085-Add-renovate.json.patch              |   21 +
 ...086-PRPEPARE-RENOVATE-With-adaptions.patch |  175 +
 .../0087-Pin-dependencies.patch               |   36 +
 ...te-Extend-pip-requirements-file-list.patch |   31 +
 ...IN-REQUIREMENTS-Extend-to-all-places.patch |   92 +
 ..._cleanup-replaces-_tasklet_cleanup-r.patch | 8116 +++++++++++++++++
 ...nge-code-blocks-from-bash-to-console.patch |   36 +
 .../0092-Fix-typo-in-tutorial.patch           |   24 +
 ...nts-Use-PyHamcrest-2.0-for-python2.7.patch |   80 +
 .../0094-UPDATE-PR-877-was-merged.patch       |   21 +
 .../0095-capitalizing-steps.patch             |   28 +
 ...develop.update-gherkin-that-aborted-.patch |   56 +
 ...ainst-PowerPC-CPU-support-Travis-867.patch |   22 +
 ...098-Add-Context.attach-docs-and-test.patch |  132 +
 .../0099-Add-Contributing-chapter.patch       |  125 +
 ...apt-Tox-target-for-building-the-docs.patch |   34 +
 ...tion-HTML-formatter-in-documentation.patch |   83 +
 ...le-highlighting-for-pip-install-docs.patch |   22 +
 ...ocs-fix-simple-typo-tuorial-tutorial.patch |   52 +
 ...t-for-python3.9-by-using-active-tags.patch |  227 +
 .../0105-PREFER-python3-from-now-on.patch     |   19 +
 .../0106-REMOVE-invoke-scripts.patch          |   41 +
 ...X-Deprecated-warnings-for-Python-3.x.patch |  124 +
 ...lems-in-virtualenvs-w-behave4cmd0-st.patch |   18 +
 .../0109-FIX-Active-tag-logic.patch           |  875 ++
 .../0110-FIX-Tests-w-more.features.patch      |   56 +
 ...FIX-Some-regressions-with-Python-3.9.patch |  741 ++
 .../0112-docs-Update-new-and-noteworthy.patch |   84 +
 ...elper-function-to-print-the-current-.patch |  278 +
 ...kin-languages.json-from-cucumber-rep.patch |  541 ++
 ...TE-CHANGES-Related-to-PR-895-and-827.patch |   22 +
 ...r-python-2.7-builds-mock-4.0-only-fo.patch |   39 +
 ...-to-use-a-custom-runner-in-the-behav.patch |  126 +
 ...llow-forcing-color-with-color-always.patch |   59 +
 ...lor-with-no-value-followed-by-posarg.patch |   43 +
 .../0120-Add-BEHAVE_COLOR-env-var.patch       |   31 +
 ...121-fix-malformed-table-rows-warning.patch |   33 +
 ...-955-setup-Remove-attribute-use_2to3.patch |   42 +
 .../0123-Add-info-for-fixed-issue-955.patch   |   21 +
 .../python/python3-behave_1.2.6.bb            |  129 +-
 124 files changed, 29808 insertions(+), 2 deletions(-)
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch

diff --git a/meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch b/meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
new file mode 100644
index 000000000..5c49cc00c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
@@ -0,0 +1,22 @@
+From b941f353c129f73934853082f3f3a01cebe6f944 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 11 Mar 2019 22:37:04 +0100
+Subject: [PATCH] FIXES #725: ScenarioOutlineBuilder was not copying
+ description to created Scenario.
+
+---
+ behave/model.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/behave/model.py b/behave/model.py
+index 4ad4b9d..9dd68fd 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -1196,6 +1196,7 @@ class ScenarioOutlineBuilder(object):
+                 scenario.feature = scenario_outline.feature
+                 scenario.parent = scenario_outline
+                 scenario.background = scenario_outline.background
++                scenario.description = scenario_outline.description
+                 scenario._row = row     # pylint: disable=protected-access
+                 scenarios.append(scenario)
+         return scenarios
diff --git a/meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch b/meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch
new file mode 100644
index 000000000..2be6811fb
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch
@@ -0,0 +1,21 @@
+From 0e26bbae1f9f8d60c3ab9470b3685af1dde5b6d8 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 11 Mar 2019 22:40:13 +0100
+Subject: [PATCH] UPDATE: FIXED #725
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index c11840f..d6e96af 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -32,6 +32,7 @@ ENHANCEMENTS:
+ 
+ FIXED:
+ 
++* issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
+ * pull  #657: Allow async steps with timeouts to fail when they raise exceptions (provided by: ALSchwalm)
+ * issue #631: ScenarioOutline variables not possible in table headings (provided by: mschnelle, pull #642)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch b/meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch
new file mode 100644
index 000000000..3e4f6fdf2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch
@@ -0,0 +1,60 @@
+From 66324f8dc74715a5018d1eced225557c40bd7acd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 11 Mar 2019 23:08:00 +0100
+Subject: [PATCH] ADD TEST to verify that issue #725 is fixed.
+
+---
+ tests/issues/test_issue0725.py | 44 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+ create mode 100644 tests/issues/test_issue0725.py
+
+diff --git a/tests/issues/test_issue0725.py b/tests/issues/test_issue0725.py
+new file mode 100644
+index 0000000..7479f59
+--- /dev/null
++++ b/tests/issues/test_issue0725.py
+@@ -0,0 +1,44 @@
++# -*- coding: UTF-8 -*-
++"""
++https://github.com/behave/behave/issues/725
++
++ANALYSIS:
++----------
++
++ScenarioOutlineBuilder did not copy ScenarioOutline.description
++to the Scenarios that were created from the ScenarioOutline.
++"""
++
++from __future__ import absolute_import, print_function
++from behave.parser import parse_feature
++
++
++def test_issue():
++    """Verifies that issue #725 is fixed."""
++    text = u'''
++Feature: ScenarioOutline with description
++
++  Scenario Outline: SO_1
++    Description line 1 for ScenarioOutline.
++    Description line 2 for ScenarioOutline.
++
++    Given a step with "<name>"
++    
++    Examples:
++      | name  |
++      | Alice |
++      | Bob   |
++'''.lstrip()
++    feature = parse_feature(text)
++    assert len(feature.scenarios) == 1
++    scenario_outline_1 = feature.scenarios[0]
++    assert len(scenario_outline_1.scenarios) == 2
++    # -- HINT: Last line triggers building of the Scenarios from ScenarioOutline.
++
++    expected_description = [
++        "Description line 1 for ScenarioOutline.",
++        "Description line 2 for ScenarioOutline.",
++    ]
++    assert scenario_outline_1.description == expected_description
++    assert scenario_outline_1.scenarios[0].description == expected_description
++    assert scenario_outline_1.scenarios[1].description == expected_description
diff --git a/meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch b/meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch
new file mode 100644
index 000000000..ec55efb50
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch
@@ -0,0 +1,342 @@
+From 74d539b86ca52e83255183d96b93ff7492751b6f Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 08:29:02 +0100
+Subject: [PATCH] FIX: SummaryReporter counts computation when Rules are used.
+
+---
+ behave/model.py                               |  39 +++---
+ behave/reporter/summary.py                    | 114 ++++++++++++++----
+ .../unit/{reporters => reporter}/__init__.py  |   0
+ .../{reporters => reporter}/test_summary.py   |   4 +
+ 4 files changed, 116 insertions(+), 41 deletions(-)
+ rename tests/unit/{reporters => reporter}/__init__.py (100%)
+ rename tests/unit/{reporters => reporter}/test_summary.py (99%)
+
+diff --git a/behave/model.py b/behave/model.py
+index 9dd68fd..6238313 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -144,18 +144,18 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         self.hook_failed = False
+         self.run_starttime = 0
+         self.run_endtime = 0
+-        for scenario in self.scenarios:
+-            scenario.reset()
++        for run_item in self.run_items:
++            run_item.reset()
+ 
+     def __iter__(self):
+-        return iter(self.scenarios)
++        return iter(self.run_items)
+ 
+     def add_scenario(self, scenario):
+         feature = getattr(self, "feature", None)
+         if isinstance(self, Feature):
+             feature = self
+ 
+-        scenario.parent = self      # XXX-NEW
++        scenario.parent = self
+         scenario.feature = feature
+         scenario.background = self.background
+         self.scenarios.append(scenario)
+@@ -174,17 +174,17 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+         skipped = True
+         passed_count = 0
+-        for scenario in self.scenarios:
+-            scenario_status = scenario.status
+-            if scenario_status == Status.failed:
++        for run_item in self.run_items:
++            run_item_status = run_item.status
++            if run_item_status == Status.failed:
+                 return Status.failed
+-            elif scenario_status == Status.untested:
++            elif run_item_status == Status.untested:
+                 if passed_count > 0:
+                     return Status.failed  # ABORTED: Some passed, now untested.
+                 return Status.untested
+-            if scenario_status != Status.skipped:
++            if run_item_status != Status.skipped:
+                 skipped = False
+-            if scenario_status == Status.passed:
++            if run_item_status == Status.passed:
+                 passed_count += 1
+ 
+         if skipped:
+@@ -217,14 +217,19 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         """
+         # TODO: Better use self.run_items
+         all_scenarios = []
+-        for scenario in self.scenarios:
+-            if isinstance(scenario, ScenarioOutline):
+-                scenario_outline = scenario
++        # for scenario in self.scenarios:
++        for run_item in self.run_items:
++            if isinstance(run_item, Rule):
++                rule = run_item
++                all_scenarios.extend(rule.walk_scenarios(with_outlines=with_outlines))
++            if isinstance(run_item, ScenarioOutline):
++                scenario_outline = run_item
+                 if with_outlines:
+                     all_scenarios.append(scenario_outline)
+                 all_scenarios.extend(scenario_outline.scenarios)
+             else:
+-                all_scenarios.append(scenario)
++                assert isinstance(run_item, Scenario)
++                all_scenarios.append(run_item)
+         return all_scenarios
+ 
+     def should_run(self, config=None):
+@@ -285,9 +290,9 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         self.clear_status()
+         self.should_skip = True
+         self.skip_reason = reason
+-        for scenario in self.scenarios:
+-            scenario.skip(reason, require_not_executed)
+-        if not self.scenarios:
++        for run_item in self.run_items:
++            run_item.skip(reason, require_not_executed)
++        if not self.run_items:
+             # -- SPECIAL CASE: Feature without scenarios
+             self.set_status(Status.skipped)
+         assert self.status in self.final_status #< skipped, failed or passed.
+diff --git a/behave/reporter/summary.py b/behave/reporter/summary.py
+index c82daa1..2ccdc8f 100644
+--- a/behave/reporter/summary.py
++++ b/behave/reporter/summary.py
+@@ -6,25 +6,52 @@ Provides a summary after each test run.
+ from __future__ import absolute_import, division, print_function
+ import sys
+ from time import time as time_now
+-from behave.model import ScenarioOutline
++from behave.model import Rule, ScenarioOutline  # MAYBE: Scenario
+ from behave.model_core import Status
+ from behave.reporter.base import Reporter
+ from behave.formatter.base import StreamOpener
+ 
+ 
+-# -- DISABLED: optional_steps = ('untested', 'undefined')
+-optional_steps = (Status.untested,) # MAYBE: Status.undefined
+-status_order = (Status.passed, Status.failed, Status.skipped,
++# ---------------------------------------------------------------------------
++# CONSTANTS:
++# ---------------------------------------------------------------------------
++# -- DISABLED: OPTIONAL_STEPS = ('untested', 'undefined')
++OPTIONAL_STEPS = (Status.untested,) # MAYBE: Status.undefined
++STATUS_ORDER = (Status.passed, Status.failed, Status.skipped,
+                 Status.undefined, Status.untested)
+ 
+ 
+-def format_summary(statement_type, summary):
++# ---------------------------------------------------------------------------
++# UTILITY FUNCTIONS:
++# ---------------------------------------------------------------------------
++def pluralize(word, count=1, suffix="s"):
++    if count == 1:
++        return word
++    # -- OTHERWISE:
++    return "{0}{1}".format(word, suffix)
++
++
++def compute_summary_sum(summary):
++    """Compute sum of all summary counts (except: all)
++
++    :param summary: Summary counts (as dict).
++    :return: Sum of all counts (as integer).
++    """
++    counts_sum = 0
++    for name, count in summary.items():
++        if name == "all":
++            continue    # IGNORE IT.
++        counts_sum += count
++    return counts_sum
++
++
++def format_summary0(statement_type, summary):
+     parts = []
+-    for status in status_order:
++    for status in STATUS_ORDER:
+         if status.name not in summary:
+             continue
+         counts = summary[status.name]
+-        if status in optional_steps and counts == 0:
++        if status in OPTIONAL_STEPS and counts == 0:
+             # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
+             continue
+ 
+@@ -40,11 +67,23 @@ def format_summary(statement_type, summary):
+     return ", ".join(parts) + "\n"
+ 
+ 
+-def pluralize(word, count=1, suffix="s"):
+-    if count == 1:
+-        return word
+-    # -- OTHERWISE:
+-    return "{0}{1}".format(word, suffix)
++def format_summary(statement_type, summary):
++    parts = []
++    for status in STATUS_ORDER:
++        if status.name not in summary:
++            continue
++        counts = summary[status.name]
++        if status in OPTIONAL_STEPS and counts == 0:
++            # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
++            continue
++
++        name = status.name
++        if status.name == "passed":
++            statement = pluralize(statement_type, counts)
++            name = u"%s passed" % statement
++        part = u"%d %s" % (counts, name)
++        parts.append(part)
++    return ", ".join(parts) + "\n"
+ 
+ 
+ # -- PREPARED:
+@@ -60,18 +99,16 @@ def format_summary2(statement_type, summary, end="\n"):
+     :return:
+     """
+     parts = []
+-    counts_sum = 0
+-    for status in status_order:
++    for status in STATUS_ORDER:
+         if status.name not in summary:
+             continue
+         counts = summary[status.name]
+-        if status in optional_steps and counts == 0:
++        if status in OPTIONAL_STEPS and counts == 0:
+             # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
+             continue
+-
+-        counts_sum += counts
+         parts.append((status.name, counts))
+ 
++    counts_sum = summary["all"]
+     statement = pluralize(statement_type, sum)
+     parts_text = ", ".join(["{0}: {1}".format(name, value)
+                             for name, value in parts])
+@@ -79,6 +116,9 @@ def format_summary2(statement_type, summary, end="\n"):
+         count=counts_sum, statement=statement, parts=parts_text, end=end)
+ 
+ 
++# ---------------------------------------------------------------------------
++# REPORTERS:
++# ---------------------------------------------------------------------------
+ class SummaryReporter(Reporter):
+     show_failed_scenarios = True
+     output_stream_name = "stdout"
+@@ -88,6 +128,7 @@ class SummaryReporter(Reporter):
+         stream = getattr(sys, self.output_stream_name, sys.stderr)
+         self.stream = StreamOpener.ensure_stream_with_encoder(stream)
+         summary_zero_data = {
++            "all": 0,
+             Status.passed.name: 0,
+             Status.failed.name: 0,
+             Status.skipped.name: 0,
+@@ -122,10 +163,22 @@ class SummaryReporter(Reporter):
+         for scenario in self.failed_scenarios:
+             stream.write(u"  %s  %s\n" % (scenario.location, scenario.name))
+ 
++    def compute_summary_sums(self):
++        """(Re)Compute summary sum of all counts (except: all)."""
++        summaries = [
++            self.feature_summary,
++            self.rule_summary,
++            self.scenario_summary,
++            self.step_summary
++        ]
++        for summary in summaries:
++            summary["all"] = compute_summary_sum(summary)
++
+     def print_summary(self, stream=None, with_duration=True):
+         if stream is None:
+             stream = self.stream
+ 
++        self.compute_summary_sums()
+         stream.write(format_summary("feature", self.feature_summary))
+         rules_summary = format_summary("rule", self.rule_summary)
+         if self.show_rules and not rules_summary.strip().startswith("0"):
+@@ -145,13 +198,7 @@ class SummaryReporter(Reporter):
+             # -- DISCOVER: TEST-RUN started.
+             self.testrun_started()
+ 
+-        self.feature_summary[feature.status.name] += 1
+-        self.duration += feature.duration
+-        for scenario in feature:
+-            if isinstance(scenario, ScenarioOutline):
+-                self.process_scenario_outline(scenario)
+-            else:
+-                self.process_scenario(scenario)
++        self.process_feature(feature)
+ 
+     def end(self):
+         self.testrun_finished()
+@@ -164,6 +211,25 @@ class SummaryReporter(Reporter):
+         # -- SHOW SUMMARY COUNTS:
+         self.print_summary()
+ 
++    def process_run_items_for(self, parent):
++        for run_item in parent:
++            if isinstance(run_item, Rule):
++                self.process_rule(run_item)
++            elif isinstance(run_item, ScenarioOutline):
++                self.process_scenario_outline(run_item)
++            else:
++                # assert isinstance(run_item, Scenario)
++                self.process_scenario(run_item)
++
++    def process_feature(self, feature):
++        self.duration += feature.duration
++        self.feature_summary[feature.status.name] += 1
++        self.process_run_items_for(feature)
++
++    def process_rule(self, rule):
++        self.rule_summary[rule.status.name] += 1
++        self.process_run_items_for(rule)
++
+     def process_scenario(self, scenario):
+         if scenario.status == Status.failed:
+             self.failed_scenarios.append(scenario)
+diff --git a/tests/unit/reporters/__init__.py b/tests/unit/reporter/__init__.py
+similarity index 100%
+rename from tests/unit/reporters/__init__.py
+rename to tests/unit/reporter/__init__.py
+diff --git a/tests/unit/reporters/test_summary.py b/tests/unit/reporter/test_summary.py
+similarity index 99%
+rename from tests/unit/reporters/test_summary.py
+rename to tests/unit/reporter/test_summary.py
+index 02154db..97adbb5 100644
+--- a/tests/unit/reporters/test_summary.py
++++ b/tests/unit/reporter/test_summary.py
+@@ -120,6 +120,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 5,
+             Status.passed.name: 2,
+             Status.failed.name: 1,
+             Status.skipped.name: 1,
+@@ -156,6 +157,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 5,
+             Status.passed.name: 1,
+             Status.failed.name: 2,
+             Status.skipped.name: 1,
+@@ -201,6 +203,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 7,
+             Status.passed.name: 2,
+             Status.failed.name: 3,
+             Status.skipped.name: 2,
+@@ -241,6 +244,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 5,
+             Status.passed.name: 2,
+             Status.failed.name: 1,
+             Status.skipped.name: 1,
diff --git a/meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch b/meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch
new file mode 100644
index 000000000..2cbf02925
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch
@@ -0,0 +1,60 @@
+From db1ead991924fb71d87e02aa43ffa73eae60594e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 08:41:37 +0100
+Subject: [PATCH] SummaryReporter.print_summary: Simplify if Rules are used.
+
+---
+ behave/reporter/summary.py          | 7 ++++---
+ tests/unit/reporter/test_summary.py | 6 +++---
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/behave/reporter/summary.py b/behave/reporter/summary.py
+index 2ccdc8f..09285ea 100644
+--- a/behave/reporter/summary.py
++++ b/behave/reporter/summary.py
+@@ -179,11 +179,12 @@ class SummaryReporter(Reporter):
+             stream = self.stream
+ 
+         self.compute_summary_sums()
++        has_rules = (self.rule_summary["all"] > 0)
++
+         stream.write(format_summary("feature", self.feature_summary))
+-        rules_summary = format_summary("rule", self.rule_summary)
+-        if self.show_rules and not rules_summary.strip().startswith("0"):
++        if self.show_rules and has_rules:
+             # -- HINT: Show only rules, if any exists.
+-            self.stream.write(rules_summary)
++            self.stream.write(format_summary("rule", self.rule_summary))
+         stream.write(format_summary("scenario", self.scenario_summary))
+         stream.write(format_summary("step", self.step_summary))
+ 
+diff --git a/tests/unit/reporter/test_summary.py b/tests/unit/reporter/test_summary.py
+index 97adbb5..d4e85b5 100644
+--- a/tests/unit/reporter/test_summary.py
++++ b/tests/unit/reporter/test_summary.py
+@@ -164,7 +164,7 @@ class TestSummaryReporter(object):
+             Status.untested.name: 1,
+         }
+ 
+-        scenario_index = 2
++        scenario_index = 1  # -- HINT: Index for scenarios if no Rules are used.
+         expected_parts = ("scenario", expected)
+         assert format_summary.call_args_list[scenario_index][0] == expected_parts
+ 
+@@ -209,7 +209,7 @@ class TestSummaryReporter(object):
+             Status.skipped.name: 2,
+             Status.untested.name: 0,
+         }
+-        scenario_index = 2
++        scenario_index = 1  # -- HINT: Index for scenarios if no Rules are used.
+         expected_parts = ("scenario", expected)
+         assert format_summary.call_args_list[scenario_index][0] == expected_parts
+ 
+@@ -252,6 +252,6 @@ class TestSummaryReporter(object):
+             Status.undefined.name: 1,
+         }
+ 
+-        step_index = 3
++        step_index = 2  # HINT: Index for steps if not rules are used.
+         expected_parts = ("step", expected)
+         assert format_summary.call_args_list[step_index][0] == expected_parts
diff --git a/meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch b/meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch
new file mode 100644
index 000000000..bcfe315bf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch
@@ -0,0 +1,395 @@
+From 24811b631e0eed92347880f1dac3f932f4b46f9d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 23:08:19 +0100
+Subject: [PATCH] Formatter: Add basic support/output for Rules.
+
+---
+ behave/formatter/base.py     | 18 +++++------
+ behave/formatter/plain.py    | 63 +++++++++++++++++++++++++++++-------
+ behave/formatter/pretty.py   | 33 +++++++++++++++----
+ behave/formatter/progress.py | 18 ++++++++++-
+ behave/model.py              | 14 ++++----
+ 5 files changed, 110 insertions(+), 36 deletions(-)
+
+diff --git a/behave/formatter/base.py b/behave/formatter/base.py
+index f7268fa..a8b9f7c 100644
+--- a/behave/formatter/base.py
++++ b/behave/formatter/base.py
+@@ -129,15 +129,6 @@ class Formatter(object):
+         """
+         pass
+ 
+-    def background(self, background):
+-        """Called when a (Feature) Background is provided.
+-        Called after :method:`feature()` is called.
+-        Called before processing any scenarios or scenario outlines.
+-
+-        :param background:  Background object (as :class:`behave.model.Background`)
+-        """
+-        pass
+-
+     def rule(self, rule):
+         """Called before a rule is executed.
+ 
+@@ -153,6 +144,15 @@ class Formatter(object):
+     #     """
+     #     pass
+ 
++    def background(self, background):
++        """Called when a (Feature) Background is provided.
++        Called after :method:`feature()` is called.
++        Called before processing any scenarios or scenario outlines.
++
++        :param background:  Background object (as :class:`behave.model.Background`)
++        """
++        pass
++
+     def scenario(self, scenario):
+         """Called before a scenario is executed (or ScenarioOutline scenarios).
+ 
+diff --git a/behave/formatter/plain.py b/behave/formatter/plain.py
+index 9f1f833..e720829 100644
+--- a/behave/formatter/plain.py
++++ b/behave/formatter/plain.py
+@@ -23,6 +23,8 @@ class PlainFormatter(Formatter):
+ 
+     SHOW_MULTI_LINE = True
+     SHOW_TAGS = False
++    SHOW_RULES = True
++    SHOW_BACKGROUNDS = True
+     SHOW_ALIGNED_KEYWORDS = False
+     DEFAULT_INDENT_SIZE = 2
+     RAISE_OUTPUT_ERRORS = True
+@@ -35,6 +37,7 @@ class PlainFormatter(Formatter):
+         self.show_aligned_keywords = self.SHOW_ALIGNED_KEYWORDS
+         self.show_tags = self.SHOW_TAGS
+         self.indent_size = self.DEFAULT_INDENT_SIZE
++        self.current_rule = None
+         # -- ENSURE: Output stream is open.
+         self.stream = self.open()
+         self.printer = ModelPrinter(self.stream)
+@@ -49,6 +52,10 @@ class PlainFormatter(Formatter):
+                 offset = 2
+             indentation = make_indentation(3 * self.indent_size + offset)
+             self._multiline_indentation = indentation
++
++        if self.current_rule:
++            indent_extra = make_indentation(self.indent_size)
++            return self._multiline_indentation + indent_extra
+         return self._multiline_indentation
+ 
+     def reset_steps(self):
+@@ -60,37 +67,69 @@ class PlainFormatter(Formatter):
+             text = " @".join(tags)
+             self.stream.write(u"%s@%s\n" % (indent, text))
+ 
++    def write_entity(self, entity, indent="", has_tags=True):
++        if has_tags:
++            self.write_tags(entity.tags, indent)
++        text = u"%s%s: %s\n" % (indent, entity.keyword, entity.name)
++        self.stream.write(text)
++
+     # -- IMPLEMENT-INTERFACE FOR: Formatter
+     def feature(self, feature):
++        self.current_rule = None
+         self.reset_steps()
+-        self.write_tags(feature.tags)
+-        self.stream.write(u"%s: %s\n" % (feature.keyword, feature.name))
++        self.write_entity(feature)
++        # self.write_tags(feature.tags)
++        # self.stream.write(u"%s: %s\n" % (feature.keyword, feature.name))
+ 
+-    def background(self, background):
++    def rule(self, rule):
++        self.current_rule = rule
+         self.reset_steps()
+         indent = make_indentation(self.indent_size)
+-        text = u"%s%s: %s\n" % (indent, background.keyword, background.name)
+-        self.stream.write(text)
++        self.stream.write(u"\n")
++        self.write_entity(rule, indent)
++        # self.stream.write(u"%s%s: %s\n" % (indent, rule.keyword, rule.name))
++
++    def background(self, background):
++        self.reset_steps()
++        if not self.SHOW_BACKGROUNDS:
++            return
++
++        indent_extra = 0
++        if self.current_rule:
++            indent_extra = self.indent_size
++
++        indent = make_indentation(self.indent_size + indent_extra)
++        self.write_entity(background, indent, has_tags=False)
++        # text = u"%s%s: %s\n" % (indent, background.keyword, background.name)
++        # self.stream.write(text)
+ 
+     def scenario(self, scenario):
++        indent_extra = 0
++        if self.current_rule:
++            indent_extra = self.indent_size
++
+         self.reset_steps()
+         self.stream.write(u"\n")
+-        indent = make_indentation(self.indent_size)
+-        text = u"%s%s: %s\n" % (indent, scenario.keyword, scenario.name)
+-        self.write_tags(scenario.tags, indent)
+-        self.stream.write(text)
++        indent = make_indentation(self.indent_size + indent_extra)
++        self.write_entity(scenario, indent)
++        # text = u"%s%s: %s\n" % (indent, scenario.keyword, scenario.name)
++        # self.write_tags(scenario.tags, indent)
++        # self.stream.write(text)
+ 
+     def step(self, step):
+         self.steps.append(step)
+ 
+     def result(self, step):
+-        """
+-        Process the result of a step (after step execution).
++        """Process the result of a step (after step execution).
+ 
+         :param step:   Step object with result to process.
+         """
++        indent_extra = 0
++        if self.current_rule:
++            indent_extra = self.indent_size
++
+         step = self.steps.pop(0)
+-        indent = make_indentation(2 * self.indent_size)
++        indent = make_indentation(2 * self.indent_size + indent_extra)
+         if self.show_aligned_keywords:
+             # -- RIGHT-ALIGN KEYWORDS (max. keyword width: 6):
+             text = u"%s%6s %s ... " % (indent, step.keyword, step.name)
+diff --git a/behave/formatter/pretty.py b/behave/formatter/pretty.py
+index b6f0eac..794e1d7 100644
+--- a/behave/formatter/pretty.py
++++ b/behave/formatter/pretty.py
+@@ -6,7 +6,7 @@ from behave.formatter.ansi_escapes import escapes, up
+ from behave.formatter.base import Formatter
+ from behave.model_core import Status
+ from behave.model_describe import escape_cell, escape_triple_quotes
+-from behave.textutil import indent, text as _text
++from behave.textutil import indent, make_indentation, text as _text
+ import six
+ from six.moves import range, zip
+ 
+@@ -86,6 +86,7 @@ class PrettyFormatter(Formatter):
+ 
+     def reset(self):
+         # -- UNUSED: self.tag_statement = None
++        self.current_rule = None
+         self.steps = []
+         self._uri = None
+         self._match = None
+@@ -99,7 +100,9 @@ class PrettyFormatter(Formatter):
+ 
+     def feature(self, feature):
+         #self.print_comments(feature.comments, '')
+-        self.print_tags(feature.tags, '')
++        self.current_rule = None
++        prefix = ""
++        self.print_tags(feature.tags, prefix)
+         self.stream.write(u"%s: %s" % (feature.keyword, feature.name))
+         if self.show_source:
+             # pylint: disable=redefined-builtin
+@@ -109,6 +112,11 @@ class PrettyFormatter(Formatter):
+         self.print_description(feature.description, "  ", False)
+         self.stream.flush()
+ 
++    def rule(self, rule):
++        self.replay()
++        self.current_rule = rule
++        self.statement = rule
++
+     def background(self, background):
+         self.replay()
+         self.statement = background
+@@ -176,6 +184,10 @@ class PrettyFormatter(Formatter):
+         self.stream.flush()
+ 
+     def table(self, table):
++        prefix = u"      "
++        if self.current_rule:
++            prefix += u"  "
++
+         cell_lengths = []
+         all_rows = [table.headings] + table.rows
+         for row in all_rows:
+@@ -189,7 +201,7 @@ class PrettyFormatter(Formatter):
+         for i, row in enumerate(all_rows):
+             #for comment in row.comments:
+             #    self.stream.write("      %s\n" % comment.value)
+-            self.stream.write("      |")
++            self.stream.write(u"%s|" % prefix)
+             for j, (cell, max_length) in enumerate(zip(row, max_lengths)):
+                 self.stream.write(" ")
+                 self.stream.write(self.color(cell, None, j))
+@@ -202,6 +214,8 @@ class PrettyFormatter(Formatter):
+         #self.stream.write('      """' + doc_string.content_type + '\n')
+         doc_string = _text(doc_string)
+         prefix = u"      "
++        if self.current_rule:
++            prefix += u"  "
+         self.stream.write(u'%s"""\n' % prefix)
+         doc_string = escape_triple_quotes(indent(doc_string, prefix))
+         self.stream.write(doc_string)
+@@ -251,12 +265,16 @@ class PrettyFormatter(Formatter):
+         if self.statement is None:
+             return
+ 
++        prefix = u"  "
++        if self.current_rule and self.statement.type != "rule":
++            prefix += prefix
++
+         self.calculate_location_indentations()
+         self.stream.write(u"\n")
+         #self.print_comments(self.statement.comments, "  ")
+         if hasattr(self.statement, "tags"):
+-            self.print_tags(self.statement.tags, u"  ")
+-        self.stream.write(u"  %s: %s " % (self.statement.keyword,
++            self.print_tags(self.statement.tags, prefix)
++        self.stream.write(u"%s%s: %s " % (prefix, self.statement.keyword,
+                                           self.statement.name))
+ 
+         location = self.indented_text(six.text_type(self.statement.location), True)
+@@ -279,8 +297,11 @@ class PrettyFormatter(Formatter):
+         text_format = self.format(status.name)
+         arg_format = self.arg_format(status.name)
+ 
++        prefix = u"    "
++        if self.current_rule:
++            prefix += u"  "
+         #self.print_comments(step.comments, "    ")
+-        self.stream.write("    ")
++        self.stream.write(prefix)
+         self.stream.write(text_format.text(step.keyword + " "))
+         line_length = 5 + len(step.keyword)
+ 
+diff --git a/behave/formatter/progress.py b/behave/formatter/progress.py
+index 6d8adf6..3b471ed 100644
+--- a/behave/formatter/progress.py
++++ b/behave/formatter/progress.py
+@@ -43,6 +43,7 @@ class ProgressFormatterBase(Formatter):
+         self.steps = []
+         self.failures = []
+         self.current_feature = None
++        self.current_rule = None
+         self.current_scenario = None
+         self.show_timings = config.show_timings and self.show_timings
+ 
+@@ -50,14 +51,19 @@ class ProgressFormatterBase(Formatter):
+         self.steps = []
+         self.failures = []
+         self.current_feature = None
++        self.current_rule = None
+         self.current_scenario = None
+ 
+     # -- FORMATTER API:
+     def feature(self, feature):
++        self.current_rule = None
+         self.current_feature = feature
+         self.stream.write("%s  " % six.text_type(feature.filename))
+         self.stream.flush()
+ 
++    def rule(self, rule):
++        self.current_rule = rule
++
+     def background(self, background):
+         pass
+ 
+@@ -219,9 +225,16 @@ class ScenarioStepProgressFormatter(StepProgressFormatter):
+ 
+     # -- FORMATTER API:
+     def feature(self, feature):
++        self.current_rule = None
+         self.current_feature = feature
+         self.stream.write(u"%s    # %s" % (feature.name, feature.filename))
+ 
++    def rule(self, rule):
++        self.current_rule = rule
++        self.stream.write(u"\n\n  %s: %s    # %s" %
++                          (rule.keyword, rule.name, rule.location))
++        self.stream.flush()
++
+     def scenario(self, scenario):
+         """Process the next scenario."""
+         # -- LAST SCENARIO: Report failures (if any).
+@@ -231,9 +244,12 @@ class ScenarioStepProgressFormatter(StepProgressFormatter):
+         assert not self.failures
+         self.current_scenario = scenario
+         scenario_name = scenario.name
++        prefix = self.scenario_prefix
++        if self.current_rule:
++            prefix += u"  "
+         if scenario_name:
+             scenario_name += " "
+-        self.stream.write(u"%s%s " % (self.scenario_prefix, scenario_name))
++        self.stream.write(u"%s%s " % (prefix, scenario_name))
+         self.stream.flush()
+ 
+     # -- DISABLED:
+diff --git a/behave/model.py b/behave/model.py
+index 6238313..3084850 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -318,10 +318,10 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         runner.context.tags = set(self.tags)
+ 
+         skip_entity_untested = runner.aborted
+-        run_entity = self.should_run(runner.config)
++        should_run_entity = self.should_run(runner.config)
+         failed_count = 0
+         hooks_called = False
+-        if not runner.config.dry_run and run_entity:
++        if not runner.config.dry_run and should_run_entity:
+             hooks_called = True
+             for tag in self.tags:
+                 runner.run_hook("before_tag", runner.context, tag)
+@@ -332,10 +332,10 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+             # -- RE-EVALUATE SHOULD-RUN STATE:
+             # Hook may call entity.mark_skipped() to exclude it.
+             skip_entity_untested = self.hook_failed or runner.aborted
+-            run_entity = self.should_run()
++            should_run_entity = self.should_run()
+ 
+         # run this entity if the tags say so or any one of its scenarios
+-        if run_entity or runner.config.show_skipped:
++        if should_run_entity or runner.config.show_skipped:
+             for formatter in runner.formatters:
+                 formatter_callback = getattr(formatter, entity_name, None)
+                 if formatter_callback:
+@@ -363,7 +363,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+                         break
+ 
+         self.clear_status()  # -- ENFORCE: compute_status() after run.
+-        if not self.run_items and not run_entity:
++        if not self.run_items and not should_run_entity:
+             # -- SPECIAL CASE: Feature without scenarios
+             self.set_status(Status.skipped)
+ 
+@@ -382,7 +382,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+             # -- CLEANUP-ERROR:
+             self.set_status(Status.failed)
+ 
+-        if run_entity or runner.config.show_skipped:
++        if should_run_entity or runner.config.show_skipped:
+             callback_name = "{0}_finished".format(entity_name)
+             if entity_name == "feature":
+                 callback_name = "eof"
+@@ -608,7 +608,6 @@ class Rule(ScenarioContainer):
+     .. versionadded:: 1.2.7
+     .. _`feature`: gherkin.html#rule
+     """
+-
+     type = "rule"
+ 
+     def __init__(self, filename, line, keyword, name, tags=None,
+@@ -625,7 +624,6 @@ class Rule(ScenarioContainer):
+             (self.name, len(self.scenarios))
+ 
+ 
+-
+ class Background(BasicStatement, Replayable):
+     """A `background`_ parsed from a *feature file*.
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch b/meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch
new file mode 100644
index 000000000..b8e804269
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch
@@ -0,0 +1,67 @@
+From 19a4134596217540832ed394d790d7b509ec865a Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 23:11:50 +0100
+Subject: [PATCH] BUMP-VERSION: 1.2.7.dev1 (was: 1.2.7.dev0)
+
+---
+ .bumpversion.cfg   | 2 +-
+ VERSION.txt        | 2 +-
+ behave/__init__.py | 2 +-
+ pytest.ini         | 2 +-
+ setup.py           | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/.bumpversion.cfg b/.bumpversion.cfg
+index f387d43..ac913c2 100644
+--- a/.bumpversion.cfg
++++ b/.bumpversion.cfg
+@@ -1,5 +1,5 @@
+ [bumpversion]
+-current_version = 1.2.7.dev0
++current_version = 1.2.7.dev1
+ files = behave/__init__.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
+ parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<drop>\w*)
+ serialize = {major}.{minor}.{patch}{drop}
+diff --git a/VERSION.txt b/VERSION.txt
+index 4e63eef..c0ef36b 100644
+--- a/VERSION.txt
++++ b/VERSION.txt
+@@ -1 +1 @@
+-1.2.7.dev0
++1.2.7.dev1
+diff --git a/behave/__init__.py b/behave/__init__.py
+index 8888355..31e4e55 100644
+--- a/behave/__init__.py
++++ b/behave/__init__.py
+@@ -29,4 +29,4 @@ __all__ = [
+     # -- DEPRECATING:
+     "step_matcher"
+ ]
+-__version__ = "1.2.7.dev0"
++__version__ = "1.2.7.dev1"
+diff --git a/pytest.ini b/pytest.ini
+index 70e10cd..17ad388 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -20,7 +20,7 @@ minversion    = 2.8
+ testpaths     = test tests
+ python_files  = test_*.py
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+-    --metadata PACKAGE_VERSION 1.2.7.dev0
++    --metadata PACKAGE_VERSION 1.2.7.dev1
+     --html=build/testing/report.html --self-contained-html
+     --junit-xml=build/testing/report.xml
+ markers =
+diff --git a/setup.py b/setup.py
+index cb3b338..c5af262 100644
+--- a/setup.py
++++ b/setup.py
+@@ -55,7 +55,7 @@ def find_packages_by_root_package(where):
+ # -----------------------------------------------------------------------------
+ setup(
+     name="behave",
+-    version="1.2.7.dev0",
++    version="1.2.7.dev1",
+     description="behave is behaviour-driven development, Python style",
+     long_description=description,
+     author="Jens Engel, Benno Rice and Richard Jones",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch b/meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch
new file mode 100644
index 000000000..9ab6cee15
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch
@@ -0,0 +1,41 @@
+From 29d3ef4d3ff8c836bc592b92687a28bf873d0e0c Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 14 Mar 2019 22:14:54 +0100
+Subject: [PATCH] Correct examples and docstring
+
+---
+ behave/contrib/scenario_autoretry.py | 2 +-
+ behave/formatter/base.py             | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/behave/contrib/scenario_autoretry.py b/behave/contrib/scenario_autoretry.py
+index 2b7f94f..2592d10 100644
+--- a/behave/contrib/scenario_autoretry.py
++++ b/behave/contrib/scenario_autoretry.py
+@@ -24,7 +24,7 @@ EXAMPLE:
+     from behave.contrib.scenario_autoretry import patch_scenario_with_autoretry
+ 
+     def before_feature(context, feature):
+-        for scenario in feature.scenarios:
++        for scenario in feature.walk_scenarios():
+             if "autoretry" in scenario.effective_tags:
+                 patch_scenario_with_autoretry(scenario, max_attempts=2)
+ 
+diff --git a/behave/formatter/base.py b/behave/formatter/base.py
+index a8b9f7c..7f59ad4 100644
+--- a/behave/formatter/base.py
++++ b/behave/formatter/base.py
+@@ -74,11 +74,12 @@ class Formatter(object):
+ 
+     Processing Logic (simplified, without ScenarioOutline and skip logic)::
+ 
++        # -- HINT: Rule processing is missing.
+         for feature in runner.features:
+             formatter = make_formatters(...)
+             formatter.uri(feature.filename)
+             formatter.feature(feature)
+-            for scenario in feature.scenarios:
++            for scenario in feature.walk_scenarios():
+                 formatter.scenario(scenario)
+                 for step in scenario.all_steps:
+                     formatter.step(step)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch b/meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch
new file mode 100644
index 000000000..0c70cc566
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch
@@ -0,0 +1,58 @@
+From dee5266820aabcfe09d103cf007bb26b9db54849 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 14 Mar 2019 22:15:34 +0100
+Subject: [PATCH] FIX: feature.run_items processing with Rule(s).
+
+---
+ behave/reporter/junit.py | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/behave/reporter/junit.py b/behave/reporter/junit.py
+index 48e1411..9018399 100644
+--- a/behave/reporter/junit.py
++++ b/behave/reporter/junit.py
+@@ -75,7 +75,7 @@ import codecs
+ from xml.etree import ElementTree
+ from datetime import datetime
+ from behave.reporter.base import Reporter
+-from behave.model import Scenario, ScenarioOutline, Step
++from behave.model import Rule, Scenario, ScenarioOutline, Step
+ from behave.model_core import Status
+ from behave.formatter import ansi_escapes
+ from behave.model_describe import ModelDescriptor
+@@ -236,13 +236,8 @@ class JUnitReporter(Reporter):
+         feature_name = feature.name or feature_filename
+         suite.set(u'name', u'%s.%s' % (classname, feature_name))
+ 
+-        # -- BUILD-TESTCASES: From scenarios
+-        for scenario in feature:
+-            if isinstance(scenario, ScenarioOutline):
+-                scenario_outline = scenario
+-                self._process_scenario_outline(scenario_outline, report)
+-            else:
+-                self._process_scenario(scenario, report)
++        # -- BUILD-TESTCASES: From run_items (and scenarios)
++        self._process_run_items_for(feature, report)
+ 
+         # -- ADD TESTCASES to testsuite:
+         for testcase in report.testcases:
+@@ -457,6 +452,19 @@ class JUnitReporter(Reporter):
+         if scenario.status != Status.skipped or self.show_skipped:
+             report.testcases.append(case)
+ 
++    def _process_run_items_for(self, parent, report):
++        for run_item in parent.run_items:
++            if isinstance(run_item, Rule):
++                self._process_rule(run_item, report)
++            elif isinstance(run_item, ScenarioOutline):
++                self._process_scenario_outline(run_item, report)
++            else:
++                assert isinstance(run_item, Scenario)
++                self._process_scenario(run_item, report)
++
++    def _process_rule(self, rule, report):
++        self._process_run_items_for(rule, report)
++
+     def _process_scenario_outline(self, scenario_outline, report):
+         assert isinstance(scenario_outline, ScenarioOutline)
+         for scenario in scenario_outline:
diff --git a/meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch b/meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch
new file mode 100644
index 000000000..122b7e9f2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch
@@ -0,0 +1,58 @@
+From b4a40c4df5872b0c9c7293b3a9fa057e208361d6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 26 May 2019 14:40:38 +0200
+Subject: [PATCH] docs: Disable sphinx-intl support for READTHEDOCS.
+
+---
+ docs/conf.py | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index d38db7a..f9dfb6a 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -3,6 +3,7 @@
+ # SPHINX CONFIGURATION: behave documentation build configuration file
+ # =============================================================================
+ 
++from __future__ import print_function
+ import os.path
+ import sys
+ import importlib
+@@ -13,6 +14,13 @@ import importlib
+ # documentation root, use os.path.abspath to make it absolute, like shown here.
+ sys.path.insert(0, os.path.abspath(".."))
+ 
++# ------------------------------------------------------------------------------
++# DETECT BUILD CONTEXT
++# ------------------------------------------------------------------------------
++ON_READTHEDOCS = os.environ.get("READTHEDOCS", None) == "True"
++USE_SPHINX_INTERNATIONAL = not ON_READTHEDOCS
++
++
+ # ------------------------------------------------------------------------------
+ # EXTENSIONS CONFIGURATION
+ # ------------------------------------------------------------------------------
+@@ -82,8 +90,10 @@ master_doc = "index"
+ # -- MULTI-LANGUAGE SUPPORT: en, ...
+ # SEE: https://pypi.org/project/sphinx-intl/
+ # SEE: https://github.com/sphinx-doc/sphinx-intl/
+-locale_dirs = ["locale/"]   # path is example but recommended.
+-gettext_compact = False     # optional.
++if USE_SPHINX_INTERNATIONAL:
++    locale_dirs = ["locale/"]   # path is example but recommended.
++    gettext_compact = False     # optional.
++    print("USE SPHINX-INTL: locale_dirs=%s" % ",".join(locale_dirs))
+ 
+ # STEPS:
+ #   make gettext
+@@ -155,8 +165,7 @@ todo_include_todos = False
+ html_theme = "kr"
+ html_theme = "bootstrap"
+ 
+-on_rtd = os.environ.get("READTHEDOCS", None) == "True"
+-if on_rtd:
++if ON_READTHEDOCS:
+     html_theme = "default"
+ 
+ if html_theme == "bootstrap":
diff --git a/meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch b/meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch
new file mode 100644
index 000000000..726402a8e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch
@@ -0,0 +1,81 @@
+From ffbd9840d2c2e273a0ce2ea8fe20afad034bdeb2 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 18 Apr 2019 19:02:43 +0200
+Subject: [PATCH] Cleanup: Dependent package versions in requirements.
+
+---
+ py.requirements/basic.txt   | 2 +-
+ py.requirements/develop.txt | 4 ++--
+ py.requirements/testing.txt | 2 +-
+ setup.py                    | 6 +++---
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index 9eebcad..3b71bfb 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -11,7 +11,7 @@
+ cucumber-tag-expressions >= 1.1.1
+ parse >= 1.8.2
+ parse_type >= 0.4.2
+-six >= 1.11.0
++six >= 1.12.0
+ 
+ traceback2;  python_version < '3.0'
+ contextlib2     # MAYBE: python_version < '3.5'
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index c55d3cd..3deedc7 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -5,8 +5,8 @@
+ # -- BUILD-TOOL:
+ # PREPARE USAGE: invoke
+ # ALREADY: six >= 1.11.0
+-invoke >= 0.21.0
+-path.py >= 10.1
++invoke >= 1.2.0
++path.py >= 11.5.0
+ pathlib;    python_version <= '3.4'
+ pycmd
+ 
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 5876e29..3806d39 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -12,4 +12,4 @@ PyHamcrest >= 1.9
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+-path.py >= 10.1
++path.py >= 11.5.0
+diff --git a/setup.py b/setup.py
+index c5af262..ac7bddf 100644
+--- a/setup.py
++++ b/setup.py
+@@ -79,7 +79,7 @@ setup(
+         "cucumber-tag-expressions >= 1.1.1",
+         "parse >= 1.8.2",
+         "parse_type >= 0.4.2",
+-        "six >= 1.11.0",
++        "six >= 1.12.0",
+         "traceback2; python_version < '3.0'",
+         "enum34; python_version < '3.4'",
+         # -- PREPARED:
+@@ -93,7 +93,7 @@ setup(
+         "nose >= 1.3",
+         "mock >= 1.1",
+         "PyHamcrest >= 1.8",
+-        "path.py >= 10.1"
++        "path.py >= 11.5.0"
+     ],
+     cmdclass = {
+         "behave_test": behave_test,
+@@ -110,7 +110,7 @@ setup(
+             "pytest-cov",
+             "tox",
+             "invoke >= 1.2.0",
+-            "path.py >= 10.1",
++            "path.py >= 11.5.0",
+             "pycmd",
+             "pathlib; python_version <= '3.4'",
+             "modernize >= 0.5",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch
new file mode 100644
index 000000000..22c6c6bb6
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch
@@ -0,0 +1,30 @@
+From 430d19123b3a7adc21075b1befda8b550b7eb641 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 26 May 2019 14:55:20 +0200
+Subject: [PATCH] docs: conf.py tweaks.
+
+---
+ docs/conf.py | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index f9dfb6a..f7c2c24 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -18,7 +18,7 @@ sys.path.insert(0, os.path.abspath(".."))
+ # DETECT BUILD CONTEXT
+ # ------------------------------------------------------------------------------
+ ON_READTHEDOCS = os.environ.get("READTHEDOCS", None) == "True"
+-USE_SPHINX_INTERNATIONAL = not ON_READTHEDOCS
++USE_SPHINX_INTERNATIONAL = True
+ 
+ 
+ # ------------------------------------------------------------------------------
+@@ -164,7 +164,6 @@ todo_include_todos = False
+ # a list of builtin themes.
+ html_theme = "kr"
+ html_theme = "bootstrap"
+-
+ if ON_READTHEDOCS:
+     html_theme = "default"
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch b/meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch
new file mode 100644
index 000000000..aa67bd2f4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch
@@ -0,0 +1,30 @@
+From 5ea1f1b47c14cf9aeabe7d8e22511d54b15e5f1e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:11:23 +0200
+Subject: [PATCH] FIX: Misspelled after_rule hook (was: after_after)
+
+---
+ docs/context_attributes.rst | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/docs/context_attributes.rst b/docs/context_attributes.rst
+index a4817d1..163664b 100644
+--- a/docs/context_attributes.rst
++++ b/docs/context_attributes.rst
+@@ -23,6 +23,7 @@ config          test run  :class:`~behave.configuration.Configuration`  Configur
+ aborted         test run  bool                                          Set to true if test run is aborted by the user.
+ failed          test run  bool                                          Set to true if a step fails.
+ feature         feature   :class:`~behave.model.Feature`                Current feature.
++rule            rule      :class:`~behave.model.Feature`                Current rule.
+ tags            feature,  list<:class:`~behave.model.Tag`>              Effective tags of current feature, rule, scenario, scenario outline.
+                 rule,
+                 scenario
+@@ -62,7 +63,7 @@ Hook    :func:`after_tags`          feature, rule or scenario
+ Hook    :func:`before_feature`      feature
+ Hook    :func:`after_feature`       feature
+ Hook    :func:`before_rule`         rule
+-Hook    :func:`after_after`         rule
++Hook    :func:`after_rule`          rule
+ Hook    :func:`before_scenario`     scenario
+ Hook    :func:`after_scenario`      scenario
+ Hook    :func:`before_step`         scenario
diff --git a/meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch b/meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch
new file mode 100644
index 000000000..7322216cc
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch
@@ -0,0 +1,45 @@
+From 14e4c88e9bd1a12a2f081dfb2709df9f78106ca6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:12:23 +0200
+Subject: [PATCH] Add hints on Gherkin v6 grammar issues.
+
+---
+ docs/conf.py                       | 4 +++-
+ docs/new_and_noteworthy_v1.2.7.rst | 8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index f7c2c24..e55fb21 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -54,9 +54,11 @@ for optional_module_name in optional_extensions:
+ extlinks = {
+     "pypi": ("https://pypi.org/project/%s", ""),
+     "github": ("https://github.com/%s", "github:/"),
+-    "issue":  ("https://github.com/behave/behave/issue/%s", "issue #"),
++    "issue":  ("https://github.com/behave/behave/issues/%s", "issue #"),
+     "youtube": ("https://www.youtube.com/watch?v=%s", "youtube:video="),
+     "behave": ("https://github.com/behave/behave", None),
++    "cucumber": ("https://github.com/cucumber/cucumber/", None),
++    "cucumber.issue": ("https://github.com/cucumber/cucumber/issues/%s", "issue #"),
+ }
+ 
+ intersphinx_mapping = {
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index 451ed8c..80d9576 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -92,5 +92,13 @@ Overview of the `Example Mapping`_ concepts:
+     * https://lisacrispin.com/2016/06/02/experiment-example-mapping/
+     * https://tobythetesterblog.wordpress.com/2016/05/25/how-to-do-example-mapping/
+ 
++.. hint:: **Gherkin v6 Grammar Issues**
++
++    * :cucumber.issue:`632`: Rule tags are currently only supported in `behave`.
++      The Cucumber Gherkin v6 grammar currently lacks this functionality.
++
++    * :cucumber.issue:`590`: Rule Background:
++      A proposal is pending to remove Rule Backgrounds again
++
+ 
+ .. include:: _content.tag_expressions_v2.rst
diff --git a/meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch
new file mode 100644
index 000000000..04e45f3f3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch
@@ -0,0 +1,18 @@
+From 12d37ec6af46d3edb806679183ab2138e4f1f5bf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:13:08 +0200
+Subject: [PATCH] README: ReST tweaks
+
+---
+ etc/gherkin/README.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/etc/gherkin/README.rst b/etc/gherkin/README.rst
+index ad3cedb..7ec2108 100644
+--- a/etc/gherkin/README.rst
++++ b/etc/gherkin/README.rst
+@@ -1,3 +1,4 @@
+ SOURCE:
++
+ * https://github.com/cucumber/cucumber/blob/master/gherkin/gherkin-languages.json
+ * https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/gherkin-languages.json
diff --git a/meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch b/meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch
new file mode 100644
index 000000000..cbbcfd541
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch
@@ -0,0 +1,228 @@
+From eabcf73f0e7f26ef021cef30950c7bb3d2442226 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:16:01 +0200
+Subject: [PATCH] Example using Gherkin v6 grammar.
+
+---
+ examples/gherkin_v6/README.rst                | 18 ++++++++
+ examples/gherkin_v6/behave.ini                | 42 +++++++++++++++++++
+ examples/gherkin_v6/features/rule_1.feature   | 42 +++++++++++++++++++
+ examples/gherkin_v6/features/rule_2.feature   | 42 +++++++++++++++++++
+ .../features/steps/example_steps.py           | 21 ++++++++++
+ .../gherkin_v6/features/steps/person_steps.py |  7 ++++
+ 6 files changed, 172 insertions(+)
+ create mode 100644 examples/gherkin_v6/README.rst
+ create mode 100644 examples/gherkin_v6/behave.ini
+ create mode 100644 examples/gherkin_v6/features/rule_1.feature
+ create mode 100644 examples/gherkin_v6/features/rule_2.feature
+ create mode 100644 examples/gherkin_v6/features/steps/example_steps.py
+ create mode 100644 examples/gherkin_v6/features/steps/person_steps.py
+
+diff --git a/examples/gherkin_v6/README.rst b/examples/gherkin_v6/README.rst
+new file mode 100644
+index 0000000..58199dd
+--- /dev/null
++++ b/examples/gherkin_v6/README.rst
+@@ -0,0 +1,18 @@
++Gherkin v6 Examples
++=============================================================================
++
++
++SCRATCHPAD: Problems
++-----------------------------------------------------------------------------
++
++- SummaryReporter: Shows wrong counts when Rules are present::
++
++    ...
++    0 features passed, 0 failed, 1 skipped XXX
++    3 rules passed, 0 failed, 0 skipped
++    5 scenarios passed, 0 failed, 0 skipped
++    13 steps passed, 0 failed, 0 skipped, 0 undefined
++
++
++- Formatters: PrettyFormatter, PlainFormatter (at least) need Rule support
++
+diff --git a/examples/gherkin_v6/behave.ini b/examples/gherkin_v6/behave.ini
+new file mode 100644
+index 0000000..45c0f0d
+--- /dev/null
++++ b/examples/gherkin_v6/behave.ini
+@@ -0,0 +1,42 @@
++# =============================================================================
++# BEHAVE CONFIGURATION
++# =============================================================================
++# FILE: .behaverc, behave.ini, setup.cfg, tox.ini
++#
++# SEE ALSO:
++#  * http://packages.python.org/behave/behave.html#configuration-files
++#  * https://github.com/behave/behave
++#  * http://pypi.python.org/pypi/behave/
++# =============================================================================
++
++[behave]
++default_tags = not (@xfail or @not_implemented)
++show_skipped = false
++format   = rerun
++    progress3
++outfiles = rerun.txt
++    reports/report_progress3.txt
++junit = true
++logging_level = INFO
++# logging_format = LOG.%(levelname)-8s  %(name)-10s: %(message)s
++# logging_format = LOG.%(levelname)-8s  %(asctime)s  %(name)-10s: %(message)s
++
++# -- ALLURE-FORMATTER REQUIRES:
++# brew install allure
++# pip install allure-behave
++# ALLURE_REPORTS_DIR=allure.reports
++# behave -f allure -o $ALLURE_REPORTS_DIR ...
++# allure serve $ALLURE_REPORTS_DIR
++#
++# SEE ALSO:
++# * https://github.com/allure-framework/allure2
++# * https://github.com/allure-framework/allure-python
++[behave.formatters]
++allure = allure_behave.formatter:AllureFormatter
++
++# PREPARED:
++#  [behave]
++#  format = ... missing_steps ...
++#  output = ... features/steps/missing_steps.py ...
++#  [behave.formatters]
++#  missing_steps = behave.contrib.formatter_missing_steps:MissingStepsFormatter
+diff --git a/examples/gherkin_v6/features/rule_1.feature b/examples/gherkin_v6/features/rule_1.feature
+new file mode 100644
+index 0000000..a802e19
+--- /dev/null
++++ b/examples/gherkin_v6/features/rule_1.feature
+@@ -0,0 +1,42 @@
++Feature: Gherkin v6 Example -- with Rules
++  Feature description line 1.
++
++  Background: Feature.Background
++    Given feature background step_1
++
++  Rule: R1 (with Rule.Background)
++    Rule R1 description line 1.
++
++    Background: R1.Background
++      Given rule R1 background step_1
++      When  rule R1 background step_2
++
++    Example: R1.Scenario_1
++      When rule R1 scenario_1 step_1
++      Then rule R1 scenario_1 step_2
++
++    Example: R1.Scenario_2
++      Given rule R1 scenario_2 step_1
++      Then  rule R1 scenario_2 step_2
++
++  Rule: R2 (without Rule.Background)
++    Rule R2 description line 1.
++
++    Example: R2.Scenario_1
++      When rule R2 scenario_1 step_1
++      Then rule R2 scenario_1 step_2
++
++
++  Rule: R3 (with empty Rule.Background)
++    Rule R3 description line 1.
++    Rule R3 description line 2.
++
++    Background: R3.EmptyBackground
++
++    Scenario Template: R3.Scenario
++      Given a person named "<name>"
++
++      Examples:
++        | name  |
++        | Alice |
++        | Bob   |
+diff --git a/examples/gherkin_v6/features/rule_2.feature b/examples/gherkin_v6/features/rule_2.feature
+new file mode 100644
+index 0000000..a802e19
+--- /dev/null
++++ b/examples/gherkin_v6/features/rule_2.feature
+@@ -0,0 +1,42 @@
++Feature: Gherkin v6 Example -- with Rules
++  Feature description line 1.
++
++  Background: Feature.Background
++    Given feature background step_1
++
++  Rule: R1 (with Rule.Background)
++    Rule R1 description line 1.
++
++    Background: R1.Background
++      Given rule R1 background step_1
++      When  rule R1 background step_2
++
++    Example: R1.Scenario_1
++      When rule R1 scenario_1 step_1
++      Then rule R1 scenario_1 step_2
++
++    Example: R1.Scenario_2
++      Given rule R1 scenario_2 step_1
++      Then  rule R1 scenario_2 step_2
++
++  Rule: R2 (without Rule.Background)
++    Rule R2 description line 1.
++
++    Example: R2.Scenario_1
++      When rule R2 scenario_1 step_1
++      Then rule R2 scenario_1 step_2
++
++
++  Rule: R3 (with empty Rule.Background)
++    Rule R3 description line 1.
++    Rule R3 description line 2.
++
++    Background: R3.EmptyBackground
++
++    Scenario Template: R3.Scenario
++      Given a person named "<name>"
++
++      Examples:
++        | name  |
++        | Alice |
++        | Bob   |
+diff --git a/examples/gherkin_v6/features/steps/example_steps.py b/examples/gherkin_v6/features/steps/example_steps.py
+new file mode 100644
+index 0000000..f4822f3
+--- /dev/null
++++ b/examples/gherkin_v6/features/steps/example_steps.py
+@@ -0,0 +1,21 @@
++# -*- coding: UTF-8 -*-
++from __future__ import absolute_import, print_function
++from behave import step
++
++
++@step(u'feature background step_{step_id:d}')
++def step_rule_background(ctx, step_id):
++    print("feature background step_{0}".format(step_id))
++
++
++@step(u'rule {rule_id:w} background step_{step_id:d}')
++def step_rule_background(ctx, rule_id, step_id):
++    print("rule {0} background step_{1}".format(rule_id, step_id))
++
++
++@step(u'rule {rule_id:w} scenario_{scenario_id:d} step_{step_id:d}')
++def step_rule_scenario(ctx, rule_id, scenario_id, step_id):
++    print("rule {0} scenario_{1} step_{2}".format(
++        rule_id, scenario_id, step_id))
++
++
+diff --git a/examples/gherkin_v6/features/steps/person_steps.py b/examples/gherkin_v6/features/steps/person_steps.py
+new file mode 100644
+index 0000000..714ac01
+--- /dev/null
++++ b/examples/gherkin_v6/features/steps/person_steps.py
+@@ -0,0 +1,7 @@
++# -*- coding: UTF-8 -*-
++from behave import given
++
++
++@given(u'a person named "{name}"')
++def step_given_person_with_name(ctx, name):
++    pass
diff --git a/meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch b/meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch
new file mode 100644
index 000000000..7c6e9b521
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch
@@ -0,0 +1,39 @@
+From 5e529b9ae17c15231f989c17fe1a09897edf6477 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:39:42 +0200
+Subject: [PATCH] PREPARE: Python-3.8 support
+
+---
+ .travis.yml | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index 7015b88..d8f2443 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -1,12 +1,14 @@
+ language: python
+ sudo: false
++dist: xenial   # required for Python >= 3.7
+ python:
+-  - "3.6"
++  - "3.7"
+   - "2.7"
++  - "3.6"
+   - "3.5"
+   - "pypy"
+   - "pypy3"
+-  - "3.7-dev"
++  - "3.8-dev"
+ 
+ # -- DISABLED:
+ #  - "nightly"
+@@ -19,7 +21,7 @@ python:
+ # -- TEST-BALLON: Check if Python 3.6 is actually Python 3.5.1 or newer
+ matrix:
+   allow_failures:
+-    - python: "3.7-dev"
++    - python: "3.8-dev"
+     - python: "nightly"
+ 
+ cache:
diff --git a/meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch b/meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch
new file mode 100644
index 000000000..4fe596a2f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch
@@ -0,0 +1,22 @@
+From c046c3a31322c7c29ff6d7f6172df41da3530683 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:17:10 +0200
+Subject: [PATCH] py3.8: Try to fix logging.Formatter validate problem
+
+---
+ tests/unit/test_capture.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tests/unit/test_capture.py b/tests/unit/test_capture.py
+index ac2655e..d9a3f3a 100644
+--- a/tests/unit/test_capture.py
++++ b/tests/unit/test_capture.py
+@@ -20,6 +20,8 @@ def create_capture_controller(config=None):
+         config.log_capture = True
+         config.logging_filter = None
+         config.logging_level = "INFO"
++        config.logging_format = "%(levelname)s:%(name)s:%(message)s"
++        config.logging_datefmt = None
+     return CaptureController(config)
+ 
+ def setup_capture_controller(capture_controller, context=None):
diff --git a/meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch b/meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch
new file mode 100644
index 000000000..121da7094
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch
@@ -0,0 +1,28 @@
+From fbe6b2937087db11f96e21b36a540270d7c2b165 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:19:58 +0200
+Subject: [PATCH] travis.ci: Temporarily move py38-dev to front (build first).
+
+---
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index d8f2443..35bce8c 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -2,13 +2,13 @@ language: python
+ sudo: false
+ dist: xenial   # required for Python >= 3.7
+ python:
++  - "3.8-dev"
+   - "3.7"
+   - "2.7"
+   - "3.6"
+   - "3.5"
+   - "pypy"
+   - "pypy3"
+-  - "3.8-dev"
+ 
+ # -- DISABLED:
+ #  - "nightly"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch b/meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch
new file mode 100644
index 000000000..cf9aff701
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch
@@ -0,0 +1,35 @@
+From 41525c748413405d0faf6c8fc9a345047e31a1a7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:26:19 +0200
+Subject: [PATCH] travis.ci: Tweaks for faster builds (temporarily).
+
+---
+ .travis.yml | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index 35bce8c..fbc3520 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -5,15 +5,15 @@ python:
+   - "3.8-dev"
+   - "3.7"
+   - "2.7"
+-  - "3.6"
+-  - "3.5"
+-  - "pypy"
+-  - "pypy3"
++
++# -- DISABLE-TEMPORARILY: Ensure faster builds
++#  - "3.6"
++#  - "3.5"
++#  - "pypy"
++#  - "pypy3"
+ 
+ # -- DISABLED:
+ #  - "nightly"
+-#  - "3.4"
+-#  - "3.3"
+ #
+ # NOW SUPPORTED: "3.5" => python 3.5.2 (>= 3.5.1)
+ # NOTE: nightly = 3.7-dev
diff --git a/meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch b/meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch
new file mode 100644
index 000000000..5fb1176ac
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch
@@ -0,0 +1,47 @@
+From fed4bb3273633e5f81fc8ba21c8b62255c7eefcd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:42:20 +0200
+Subject: [PATCH] FIX py3.8: logging.Formatter.validate() problem.
+
+---
+ test/test_runner.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/test/test_runner.py b/test/test_runner.py
+index 57c9445..6647283 100644
+--- a/test/test_runner.py
++++ b/test/test_runner.py
+@@ -286,6 +286,7 @@ class TestContext(unittest.TestCase):
+         eq_("thing" in self.context, True)
+         del self.context.thing
+ 
++
+ class ExampleSteps(object):
+     text = None
+     table = None
+@@ -320,6 +321,7 @@ class ExampleSteps(object):
+         for keyword, pattern, func in step_definitions:
+             step_registry.add_step_definition(keyword, pattern, func)
+ 
++
+ class TestContext_ExecuteSteps(unittest.TestCase):
+     """
+     Test the behave.runner.Context.execute_steps() functionality.
+@@ -341,6 +343,8 @@ class TestContext_ExecuteSteps(unittest.TestCase):
+         runner_.config.stdout_capture = False
+         runner_.config.stderr_capture = False
+         runner_.config.log_capture = False
++        runner_.config.logging_format = None
++        runner_.config.logging_datefmt = None
+         runner_.step_registry = self.step_registry
+ 
+         self.context = runner.Context(runner_)
+@@ -658,6 +662,8 @@ class TestRunWithPaths(unittest.TestCase):
+         self.config.logging_filter = None
+         self.config.outputs = [Mock(), StreamOpener(stream=sys.stdout)]
+         self.config.format = ["plain", "progress"]
++        self.config.logging_format = None
++        self.config.logging_datefmt = None
+         self.runner = runner.Runner(self.config)
+         self.load_hooks = self.runner.load_hooks = Mock()
+         self.load_step_definitions = self.runner.load_step_definitions = Mock()
diff --git a/meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch b/meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch
new file mode 100644
index 000000000..b46846478
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch
@@ -0,0 +1,42 @@
+From d54d8c038a7e5f9d2168daa6e13362d1df7d17a5 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:58:22 +0200
+Subject: [PATCH] PREPARE FOR: Python 3.8, @asyncio.coroutine is deprecated
+ since py38.
+
+---
+ tests/api/_test_async_step34.py | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tests/api/_test_async_step34.py b/tests/api/_test_async_step34.py
+index 8242be7..1c0c31f 100644
+--- a/tests/api/_test_async_step34.py
++++ b/tests/api/_test_async_step34.py
+@@ -37,13 +37,16 @@ from .testing_support_async import AsyncStepTheory
+ # -----------------------------------------------------------------------------
+ # TEST MARKERS:
+ # -----------------------------------------------------------------------------
++# DEPRECATED: @asyncio.coroutine decorator (since: Python >= 3.8)
+ _python_version = float("%s.%s" % sys.version_info[:2])
+-py34_or_newer = pytest.mark.skipif(_python_version < 3.4, reason="Needs Python >= 3.4")
++requires_py34_to_py37 = pytest.mark.skipif(not (3.4 <= _python_version < 3.8),
++    reason="Supported only for python.versions: 3.4 .. 3.7 (inclusive)")
++
+ 
+ # -----------------------------------------------------------------------------
+ # TESTSUITE:
+ # -----------------------------------------------------------------------------
+-@py34_or_newer
++@requires_py34_to_py37
+ class TestAsyncStepDecoratorPy34(object):
+ 
+     def test_step_decorator_async_run_until_complete2(self):
+@@ -128,7 +131,7 @@ class TestAsyncContext(object):
+         assert async_context.loop is loop0
+ 
+ 
+-@py34_or_newer
++@requires_py34_to_py37
+ class TestAsyncStepRunPy34(object):
+     """Ensure that execution of async-steps works as expected."""
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch b/meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch
new file mode 100644
index 000000000..56b8bd6c7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch
@@ -0,0 +1,24 @@
+From db66eecf4c5301ca45db9f71c7b2c3c26d5927a1 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 14:06:14 +0200
+Subject: [PATCH] UPDATE: Add #755 info
+
+---
+ CHANGES.rst | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d6e96af..a91e22a 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -30,6 +30,10 @@ ENHANCEMENTS:
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ 
+ 
++PARTIALLY FIXED:
++
++* issue #755: Failures with Python 3.8 (submitted by: hroncok)
++
+ FIXED:
+ 
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch b/meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch
new file mode 100644
index 000000000..8f9464a2d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch
@@ -0,0 +1,25 @@
+From 467b223dc84f52933b2782ce9d116e89d48a26f1 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 14:27:23 +0200
+Subject: [PATCH] FIX-WARNING: Related to docstring-example and weird backslash
+ usage.
+
+---
+ behave/matchers.py | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/behave/matchers.py b/behave/matchers.py
+index c896f52..0fee0c7 100644
+--- a/behave/matchers.py
++++ b/behave/matchers.py
+@@ -261,9 +261,7 @@ class CFParseMatcher(ParseMatcher):
+ 
+ 
+ def register_type(**kw):
+-    # pylint: disable=anomalous-backslash-in-string
+-    # REQUIRED-BY: code example
+-    """Registers a custom type that will be available to "parse"
++    r"""Registers a custom type that will be available to "parse"
+     for type conversion during step matching.
+ 
+     Converters should be supplied as ``name=callable`` arguments (or as dict).
diff --git a/meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch b/meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch
new file mode 100644
index 000000000..9213ccd2e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch
@@ -0,0 +1,29 @@
+From 11ea2c45d5b88c92b25ab8e8027a931df81c2abc Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 14:37:41 +0200
+Subject: [PATCH] FIX: invalid escape sequence warnings (w/ regex patterns).
+
+---
+ tests/unit/test_behave4cmd_command_shell_proc.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/unit/test_behave4cmd_command_shell_proc.py b/tests/unit/test_behave4cmd_command_shell_proc.py
+index aae5e9f..c45ab3b 100644
+--- a/tests/unit/test_behave4cmd_command_shell_proc.py
++++ b/tests/unit/test_behave4cmd_command_shell_proc.py
+@@ -1,5 +1,5 @@
+ # -*- coding: UTF-8 -*-
+-"""
++r"""
+ 
+ Regular expressions for winpath:
+ http://regexlib.com/Search.aspx?k=file+name
+@@ -61,7 +61,7 @@ line_processor_ioerrors = [
+ 
+ line_processor_traceback = [
+     ExceptionWithPathNormalizer(
+-        '^\s*File "(?P<path>.*)", line \d+, in ',
++        r'^\s*File "(?P<path>.*)", line \d+, in ',
+         '  File "'),
+     BehaveWinCommandOutputProcessor.line_processors[4],
+ ]
diff --git a/meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch b/meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch
new file mode 100644
index 000000000..67ea8860e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch
@@ -0,0 +1,1020 @@
+From 72279d87372cf21d980c40d01fce2f59bb734884 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 16:04:43 +0200
+Subject: [PATCH] DEPRECATING-CLEANUP: Move deprecated tag matcher classes
+
+- behave.tag_matcher.OnlyWithCategoryTagMatcher
+- behave.tag_matcher.OnlyWithAnyCategoryTagMatcher
+
+to "behave.attic.tag_matcher".
+Move related unit tests to "tests.attic/unit/test_tag_matcher.py".
+---
+ behave/attic/__init__.py             |   0
+ behave/attic/tag_matcher.py          | 181 +++++++++++++++++
+ behave/tag_matcher.py                | 189 +-----------------
+ tests.attic/__init__.py              |   0
+ tests.attic/unit/__init__.py         |   0
+ tests.attic/unit/test_tag_matcher.py | 280 +++++++++++++++++++++++++++
+ tests/unit/test_tag_matcher.py       | 279 +-------------------------
+ 7 files changed, 470 insertions(+), 459 deletions(-)
+ create mode 100644 behave/attic/__init__.py
+ create mode 100644 behave/attic/tag_matcher.py
+ create mode 100644 tests.attic/__init__.py
+ create mode 100644 tests.attic/unit/__init__.py
+ create mode 100644 tests.attic/unit/test_tag_matcher.py
+
+diff --git a/behave/attic/__init__.py b/behave/attic/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/behave/attic/tag_matcher.py b/behave/attic/tag_matcher.py
+new file mode 100644
+index 0000000..f07dcbf
+--- /dev/null
++++ b/behave/attic/tag_matcher.py
+@@ -0,0 +1,181 @@
++# -----------------------------------------------------------------------------
++# PROTOTYPING CLASSES: Should no longer be used
++# -----------------------------------------------------------------------------
++
++import warnings
++from behave.tag_matcher import TagMatcher
++
++
++class OnlyWithCategoryTagMatcher(TagMatcher):
++    """
++    Provides a tag matcher that allows to determine if feature/scenario
++    should run or should be excluded from the run-set (at runtime).
++
++    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
++
++    EXAMPLE:
++    --------
++
++    Run some scenarios only when runtime conditions are met:
++
++      * Run scenario Alice only on Windows OS
++      * Run scenario Bob only on MACOSX
++
++    .. code-block:: gherkin
++
++        # -- FILE: features/alice.feature
++        # TAG SCHEMA: @only.with_{category}={current_value}
++        Feature:
++
++          @only.with_os=win32
++          Scenario: Alice (Run only on Windows)
++            Given I do something
++            ...
++
++          @only.with_os=darwin
++          Scenario: Bob (Run only on MACOSX)
++            Given I do something else
++            ...
++
++
++    .. code-block:: python
++
++        # -- FILE: features/environment.py
++        from behave.tag_matcher import OnlyWithCategoryTagMatcher
++        import sys
++
++        # -- MATCHES TAGS: @only.with_{category}=* = @only.with_os=*
++        active_tag_matcher = OnlyWithCategoryTagMatcher("os", sys.platform)
++
++        def before_scenario(context, scenario):
++            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
++                scenario.skip()   #< LATE-EXCLUDE from run-set.
++    """
++    tag_prefix = "only.with_"
++    value_separator = "="
++
++    def __init__(self, category, value, tag_prefix=None, value_sep=None):
++        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
++        super(OnlyWithCategoryTagMatcher, self).__init__()
++        self.active_tag = self.make_category_tag(category, value,
++                                                 tag_prefix, value_sep)
++        self.category_tag_prefix = self.make_category_tag(category, None,
++                                                          tag_prefix, value_sep)
++
++    def should_exclude_with(self, tags):
++        category_tags = self.select_category_tags(tags)
++        if category_tags and self.active_tag not in category_tags:
++            return True
++        # -- OTHERWISE: feature/scenario with theses tags should run.
++        return False
++
++    def select_category_tags(self, tags):
++        return [tag  for tag in tags
++                if tag.startswith(self.category_tag_prefix)]
++
++    @classmethod
++    def make_category_tag(cls, category, value=None, tag_prefix=None,
++                          value_sep=None):
++        if tag_prefix is None:
++            tag_prefix = cls.tag_prefix
++        if value_sep is None:
++            value_sep = cls.value_separator
++        value = value or ""
++        return "%s%s%s%s" % (tag_prefix, category, value_sep, value)
++
++
++class OnlyWithAnyCategoryTagMatcher(TagMatcher):
++    """
++    Provides a tag matcher that matches any category that follows the
++    "@only.with_" tag schema and determines if it should run or
++    should be excluded from the run-set (at runtime).
++
++    TAG SCHEMA: @only.with_{category}={value}
++
++    .. seealso:: OnlyWithCategoryTagMatcher
++    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
++
++    EXAMPLE:
++    --------
++
++    Run some scenarios only when runtime conditions are met:
++
++      * Run scenario Alice only on Windows OS
++      * Run scenario Bob only with browser Chrome
++
++    .. code-block:: gherkin
++
++        # -- FILE: features/alice.feature
++        # TAG SCHEMA: @only.with_{category}={current_value}
++        Feature:
++
++          @only.with_os=win32
++          Scenario: Alice (Run only on Windows)
++            Given I do something
++            ...
++
++          @only.with_browser=chrome
++          Scenario: Bob (Run only with Web-Browser Chrome)
++            Given I do something else
++            ...
++
++
++    .. code-block:: python
++
++        # -- FILE: features/environment.py
++        from behave.tag_matcher import OnlyWithAnyCategoryTagMatcher
++        import sys
++
++        # -- MATCHES ANY TAGS: @only.with_{category}={value}
++        # NOTE: active_tag_value_provider provides current category values.
++        active_tag_value_provider = {
++            "browser": os.environ.get("BEHAVE_BROWSER", "chrome"),
++            "os":      sys.platform,
++        }
++        active_tag_matcher = OnlyWithAnyCategoryTagMatcher(active_tag_value_provider)
++
++        def before_scenario(context, scenario):
++            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
++                scenario.skip()   #< LATE-EXCLUDE from run-set.
++    """
++
++    def __init__(self, value_provider, tag_prefix=None, value_sep=None):
++        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
++        super(OnlyWithAnyCategoryTagMatcher, self).__init__()
++        if value_sep is None:
++            value_sep = OnlyWithCategoryTagMatcher.value_separator
++        self.value_provider = value_provider
++        self.tag_prefix = tag_prefix or OnlyWithCategoryTagMatcher.tag_prefix
++        self.value_separator = value_sep
++
++    def should_exclude_with(self, tags):
++        exclude_decision_map = {}
++        for category_tag in self.select_category_tags(tags):
++            category, value = self.parse_category_tag(category_tag)
++            active_value = self.value_provider.get(category, None)
++            if active_value is None:
++                # -- CASE: Unknown category, ignore it.
++                continue
++            elif active_value == value:
++                # -- CASE: Active category value selected, decision should run.
++                exclude_decision_map[category] = False
++            else:
++                # -- CASE: Inactive category value selected, may exclude it.
++                if category not in exclude_decision_map:
++                    exclude_decision_map[category] = True
++        return any(exclude_decision_map.values())
++
++    def select_category_tags(self, tags):
++        return [tag  for tag in tags
++                if tag.startswith(self.tag_prefix)]
++
++    def parse_category_tag(self, tag):
++        assert tag and tag.startswith(self.tag_prefix)
++        category_value = tag[len(self.tag_prefix):]
++        if self.value_separator in category_value:
++            category, value = category_value.split(self.value_separator, 1)
++        else:
++            # -- OOPS: TAG SCHEMA FORMAT MISMATCH
++            category = category_value
++            value = None
++        return category, value
+diff --git a/behave/tag_matcher.py b/behave/tag_matcher.py
+index f1f955b..5f9dce0 100644
+--- a/behave/tag_matcher.py
++++ b/behave/tag_matcher.py
+@@ -1,9 +1,12 @@
+-# -*- coding: utf-8 -*-
++# -*- coding: UTF-8 -*-
++"""
++Contains classes and functionality to provide a skip-if logic based on tags
++in feature files.
++"""
+ 
+ from __future__ import absolute_import
+ import re
+ import operator
+-import warnings
+ import six
+ 
+ 
+@@ -34,10 +37,10 @@ class ActiveTagMatcher(TagMatcher):
+     """Provides an active tag matcher for many categories.
+ 
+     TAG SCHEMA:
+-      * active.with_{category}={value}
+-      * not_active.with_{category}={value}
+       * use.with_{category}={value}
+       * not.with_{category}={value}
++      * active.with_{category}={value}
++      * not_active.with_{category}={value}
+       * only.with_{category}={value}        (NOTE: For backward compatibility)
+ 
+     TAG LOGIC
+@@ -285,181 +288,3 @@ def setup_active_tag_values(active_tag_values, data):
+     for category in list(active_tag_values.keys()):
+         if category in data:
+             active_tag_values[category] = data[category]
+-
+-
+-# -----------------------------------------------------------------------------
+-# PROTOTYPING CLASSES:
+-# -----------------------------------------------------------------------------
+-class OnlyWithCategoryTagMatcher(TagMatcher):
+-    """
+-    Provides a tag matcher that allows to determine if feature/scenario
+-    should run or should be excluded from the run-set (at runtime).
+-
+-    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
+-
+-    EXAMPLE:
+-    --------
+-
+-    Run some scenarios only when runtime conditions are met:
+-
+-      * Run scenario Alice only on Windows OS
+-      * Run scenario Bob only on MACOSX
+-
+-    .. code-block:: gherkin
+-
+-        # -- FILE: features/alice.feature
+-        # TAG SCHEMA: @only.with_{category}={current_value}
+-        Feature:
+-
+-          @only.with_os=win32
+-          Scenario: Alice (Run only on Windows)
+-            Given I do something
+-            ...
+-
+-          @only.with_os=darwin
+-          Scenario: Bob (Run only on MACOSX)
+-            Given I do something else
+-            ...
+-
+-
+-    .. code-block:: python
+-
+-        # -- FILE: features/environment.py
+-        from behave.tag_matcher import OnlyWithCategoryTagMatcher
+-        import sys
+-
+-        # -- MATCHES TAGS: @only.with_{category}=* = @only.with_os=*
+-        active_tag_matcher = OnlyWithCategoryTagMatcher("os", sys.platform)
+-
+-        def before_scenario(context, scenario):
+-            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+-                scenario.skip()   #< LATE-EXCLUDE from run-set.
+-    """
+-    tag_prefix = "only.with_"
+-    value_separator = "="
+-
+-    def __init__(self, category, value, tag_prefix=None, value_sep=None):
+-        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
+-        super(OnlyWithCategoryTagMatcher, self).__init__()
+-        self.active_tag = self.make_category_tag(category, value,
+-                                                 tag_prefix, value_sep)
+-        self.category_tag_prefix = self.make_category_tag(category, None,
+-                                                          tag_prefix, value_sep)
+-
+-    def should_exclude_with(self, tags):
+-        category_tags = self.select_category_tags(tags)
+-        if category_tags and self.active_tag not in category_tags:
+-            return True
+-        # -- OTHERWISE: feature/scenario with theses tags should run.
+-        return False
+-
+-    def select_category_tags(self, tags):
+-        return [tag  for tag in tags
+-                if tag.startswith(self.category_tag_prefix)]
+-
+-    @classmethod
+-    def make_category_tag(cls, category, value=None, tag_prefix=None,
+-                          value_sep=None):
+-        if tag_prefix is None:
+-            tag_prefix = cls.tag_prefix
+-        if value_sep is None:
+-            value_sep = cls.value_separator
+-        value = value or ""
+-        return "%s%s%s%s" % (tag_prefix, category, value_sep, value)
+-
+-
+-class OnlyWithAnyCategoryTagMatcher(TagMatcher):
+-    """
+-    Provides a tag matcher that matches any category that follows the
+-    "@only.with_" tag schema and determines if it should run or
+-    should be excluded from the run-set (at runtime).
+-
+-    TAG SCHEMA: @only.with_{category}={value}
+-
+-    .. seealso:: OnlyWithCategoryTagMatcher
+-    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
+-
+-    EXAMPLE:
+-    --------
+-
+-    Run some scenarios only when runtime conditions are met:
+-
+-      * Run scenario Alice only on Windows OS
+-      * Run scenario Bob only with browser Chrome
+-
+-    .. code-block:: gherkin
+-
+-        # -- FILE: features/alice.feature
+-        # TAG SCHEMA: @only.with_{category}={current_value}
+-        Feature:
+-
+-          @only.with_os=win32
+-          Scenario: Alice (Run only on Windows)
+-            Given I do something
+-            ...
+-
+-          @only.with_browser=chrome
+-          Scenario: Bob (Run only with Web-Browser Chrome)
+-            Given I do something else
+-            ...
+-
+-
+-    .. code-block:: python
+-
+-        # -- FILE: features/environment.py
+-        from behave.tag_matcher import OnlyWithAnyCategoryTagMatcher
+-        import sys
+-
+-        # -- MATCHES ANY TAGS: @only.with_{category}={value}
+-        # NOTE: active_tag_value_provider provides current category values.
+-        active_tag_value_provider = {
+-            "browser": os.environ.get("BEHAVE_BROWSER", "chrome"),
+-            "os":      sys.platform,
+-        }
+-        active_tag_matcher = OnlyWithAnyCategoryTagMatcher(active_tag_value_provider)
+-
+-        def before_scenario(context, scenario):
+-            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+-                scenario.skip()   #< LATE-EXCLUDE from run-set.
+-    """
+-
+-    def __init__(self, value_provider, tag_prefix=None, value_sep=None):
+-        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
+-        super(OnlyWithAnyCategoryTagMatcher, self).__init__()
+-        if value_sep is None:
+-            value_sep = OnlyWithCategoryTagMatcher.value_separator
+-        self.value_provider = value_provider
+-        self.tag_prefix = tag_prefix or OnlyWithCategoryTagMatcher.tag_prefix
+-        self.value_separator = value_sep
+-
+-    def should_exclude_with(self, tags):
+-        exclude_decision_map = {}
+-        for category_tag in self.select_category_tags(tags):
+-            category, value = self.parse_category_tag(category_tag)
+-            active_value = self.value_provider.get(category, None)
+-            if active_value is None:
+-                # -- CASE: Unknown category, ignore it.
+-                continue
+-            elif active_value == value:
+-                # -- CASE: Active category value selected, decision should run.
+-                exclude_decision_map[category] = False
+-            else:
+-                # -- CASE: Inactive category value selected, may exclude it.
+-                if category not in exclude_decision_map:
+-                    exclude_decision_map[category] = True
+-        return any(exclude_decision_map.values())
+-
+-    def select_category_tags(self, tags):
+-        return [tag  for tag in tags
+-                if tag.startswith(self.tag_prefix)]
+-
+-    def parse_category_tag(self, tag):
+-        assert tag and tag.startswith(self.tag_prefix)
+-        category_value = tag[len(self.tag_prefix):]
+-        if self.value_separator in category_value:
+-            category, value = category_value.split(self.value_separator, 1)
+-        else:
+-            # -- OOPS: TAG SCHEMA FORMAT MISMATCH
+-            category = category_value
+-            value = None
+-        return category, value
+diff --git a/tests.attic/__init__.py b/tests.attic/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests.attic/unit/__init__.py b/tests.attic/unit/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests.attic/unit/test_tag_matcher.py b/tests.attic/unit/test_tag_matcher.py
+new file mode 100644
+index 0000000..d767fa7
+--- /dev/null
++++ b/tests.attic/unit/test_tag_matcher.py
+@@ -0,0 +1,280 @@
++# -----------------------------------------------------------------------------
++# PROTOTYPING CLASSES (deprecating) -- Should no longer be used.
++# -----------------------------------------------------------------------------
++
++import warnings
++from unittest import TestCase
++from behave.attic.tag_matcher import \
++    OnlyWithCategoryTagMatcher,  OnlyWithAnyCategoryTagMatcher
++
++
++class TestOnlyWithCategoryTagMatcher(TestCase):
++    TagMatcher = OnlyWithCategoryTagMatcher
++
++    def setUp(self):
++        category = "xxx"
++        with warnings.catch_warnings():
++            warnings.simplefilter("ignore", DeprecationWarning)
++            self.tag_matcher = OnlyWithCategoryTagMatcher(category, "alice")
++        self.enabled_tag = self.TagMatcher.make_category_tag(category, "alice")
++        self.similar_tag = self.TagMatcher.make_category_tag(category, "alice2")
++        self.other_tag = self.TagMatcher.make_category_tag(category, "other")
++        self.category = category
++
++    def test_should_exclude_with__returns_false_with_enabled_tag(self):
++        tags = [ self.enabled_tag ]
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
++        test_patterns = [
++            ([ self.enabled_tag, self.other_tag ], "case: first"),
++            ([ self.other_tag, self.enabled_tag ], "case: last"),
++            ([ "foo", self.enabled_tag, self.other_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag(self):
++        tags = [ self.other_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
++        test_patterns = [
++            ([ self.other_tag, "foo" ], "case: first"),
++            ([ "foo", self.other_tag ], "case: last"),
++            ([ "foo", self.other_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_similar_tag(self):
++        tags = [ self.similar_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_similar_and_more(self):
++        test_patterns = [
++            ([ self.similar_tag, "foo" ], "case: first"),
++            ([ "foo", self.similar_tag ], "case: last"),
++            ([ "foo", self.similar_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_without_category_tag(self):
++        test_patterns = [
++            ([ ],           "case: No tags"),
++            ([ "foo" ],     "case: One tag"),
++            ([ "foo", "bar" ], "case: Two tags"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_run_with__negates_result_of_should_exclude_with(self):
++        test_patterns = [
++            ([ ],                   "case: No tags"),
++            ([ "foo" ],             "case: One non-category tag"),
++            ([ "foo", "bar" ],      "case: Two non-category tags"),
++            ([ self.enabled_tag ],   "case: enabled tag"),
++            ([ self.enabled_tag, self.other_tag ],  "case: enabled and other tag"),
++            ([ self.enabled_tag, "foo" ],    "case: enabled and foo tag"),
++            ([ self.other_tag ],            "case: other tag"),
++            ([ self.other_tag, "foo" ],     "case: other and foo tag"),
++            ([ self.similar_tag ],          "case: similar tag"),
++            ([ "foo", self.similar_tag ],   "case: foo and similar tag"),
++        ]
++        for tags, case in test_patterns:
++            result1 = self.tag_matcher.should_run_with(tags)
++            result2 = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
++            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
++
++    def test_make_category_tag__returns_category_tag_prefix_without_value(self):
++        category = "xxx"
++        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category)
++        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, None)
++        tag3 = OnlyWithCategoryTagMatcher.make_category_tag(category, value=None)
++        self.assertEqual("only.with_xxx=", tag1)
++        self.assertEqual("only.with_xxx=", tag2)
++        self.assertEqual("only.with_xxx=", tag3)
++        self.assertTrue(tag1.startswith(OnlyWithCategoryTagMatcher.tag_prefix))
++
++    def test_make_category_tag__returns_category_tag_with_value(self):
++        category = "xxx"
++        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category, "alice")
++        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, "bob")
++        self.assertEqual("only.with_xxx=alice", tag1)
++        self.assertEqual("only.with_xxx=bob", tag2)
++
++    def test_make_category_tag__returns_category_tag_with_tag_prefix(self):
++        my_tag_prefix = "ONLY_WITH."
++        category = "xxx"
++        TagMatcher = OnlyWithCategoryTagMatcher
++        tag0 = TagMatcher.make_category_tag(category, tag_prefix=my_tag_prefix)
++        tag1 = TagMatcher.make_category_tag(category, "alice", my_tag_prefix)
++        tag2 = TagMatcher.make_category_tag(category, "bob", tag_prefix=my_tag_prefix)
++        self.assertEqual("ONLY_WITH.xxx=", tag0)
++        self.assertEqual("ONLY_WITH.xxx=alice", tag1)
++        self.assertEqual("ONLY_WITH.xxx=bob", tag2)
++        self.assertTrue(tag1.startswith(my_tag_prefix))
++
++    def test_ctor__with_tag_prefix(self):
++        tag_prefix = "ONLY_WITH."
++        tag_matcher = OnlyWithCategoryTagMatcher("xxx", "alice", tag_prefix)
++
++        tags = ["foo", "ONLY_WITH.xxx=foo", "only.with_xxx=bar", "bar"]
++        actual_tags = tag_matcher.select_category_tags(tags)
++        self.assertEqual(["ONLY_WITH.xxx=foo"], actual_tags)
++
++
++class Traits4OnlyWithAnyCategoryTagMatcher(object):
++    """Test data for OnlyWithAnyCategoryTagMatcher."""
++
++    TagMatcher0 = OnlyWithCategoryTagMatcher
++    TagMatcher = OnlyWithAnyCategoryTagMatcher
++    category1_enabled_tag = TagMatcher0.make_category_tag("foo", "alice")
++    category1_similar_tag = TagMatcher0.make_category_tag("foo", "alice2")
++    category1_disabled_tag = TagMatcher0.make_category_tag("foo", "bob")
++    category2_enabled_tag = TagMatcher0.make_category_tag("bar", "BOB")
++    category2_similar_tag = TagMatcher0.make_category_tag("bar", "BOB2")
++    category2_disabled_tag = TagMatcher0.make_category_tag("bar", "CHARLY")
++    unknown_category_tag = TagMatcher0.make_category_tag("UNKNOWN", "one")
++
++
++class TestOnlyWithAnyCategoryTagMatcher(TestCase):
++    TagMatcher = OnlyWithAnyCategoryTagMatcher
++    traits = Traits4OnlyWithAnyCategoryTagMatcher
++
++    def setUp(self):
++        value_provider = {
++            "foo": "alice",
++            "bar": "BOB",
++        }
++        with warnings.catch_warnings():
++            warnings.simplefilter("ignore", DeprecationWarning)
++            self.tag_matcher = self.TagMatcher(value_provider)
++
++    # def test_deprecating_warning_is_issued(self):
++    #     value_provider = {"foo": "alice"}
++    #     with warnings.catch_warnings(record=True) as recorder:
++    #         warnings.simplefilter("always", DeprecationWarning)
++    #         tag_matcher = OnlyWithAnyCategoryTagMatcher(value_provider)
++    #         self.assertEqual(len(recorder), 1)
++    #         last_warning = recorder[-1]
++    #         assert issubclass(last_warning.category, DeprecationWarning)
++    #         assert "deprecated" in str(last_warning.message)
++
++    def test_should_exclude_with__returns_false_with_enabled_tag(self):
++        traits = self.traits
++        tags1 = [ traits.category1_enabled_tag ]
++        tags2 = [ traits.category2_enabled_tag ]
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags1))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags2))
++
++    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
++            ([ traits.category1_disabled_tag, traits.category1_enabled_tag ], "case: last"),
++            ([ "foo", traits.category1_enabled_tag, traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_disabled_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_disabled_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_disabled_tag ], "case: last"),
++            ([ "foo", traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_similar_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_similar_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_similar_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_similar_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_similar_tag ], "case: last"),
++            ([ "foo", traits.category1_similar_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_without_category_tag(self):
++        test_patterns = [
++            ([ ],           "case: No tags"),
++            ([ "foo" ],     "case: One tag"),
++            ([ "foo", "bar" ], "case: Two tags"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_with_unknown_category_tag(self):
++        """Tags from unknown categories, not supported by value_provider,
++        should not be excluded.
++        """
++        traits = self.traits
++        tags = [ traits.unknown_category_tag ]
++        self.assertEqual("only.with_UNKNOWN=one", traits.unknown_category_tag)
++        self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__combinations_of_2_categories(self):
++        traits = self.traits
++        test_patterns = [
++            ("case 00: 2 disabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
++            ("case 01: disabled and enabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
++            ("case 10: enabled and disabled category tags", True,
++             [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
++            ("case 11: 2 enabled category tags", False,  # -- SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
++            # -- SPECIAL CASE: With unknown category
++            ("case 0x: disabled and unknown category tags", True,
++             [ traits.category1_disabled_tag, traits.unknown_category_tag]),
++            ("case 1x: enabled and unknown category tags", False,  # SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.unknown_category_tag]),
++        ]
++        for case, expected, tags in test_patterns:
++            actual_result = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(expected, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_run_with__negates_result_of_should_exclude_with(self):
++        traits = self.traits
++        test_patterns = [
++            ([ ],                   "case: No tags"),
++            ([ "foo" ],             "case: One non-category tag"),
++            ([ "foo", "bar" ],      "case: Two non-category tags"),
++            ([ traits.category1_enabled_tag ],   "case: enabled tag"),
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ],  "case: enabled and other tag"),
++            ([ traits.category1_enabled_tag, "foo" ],    "case: enabled and foo tag"),
++            ([ traits.category1_disabled_tag ],            "case: other tag"),
++            ([ traits.category1_disabled_tag, "foo" ],     "case: other and foo tag"),
++            ([ traits.category1_similar_tag ],          "case: similar tag"),
++            ([ "foo", traits.category1_similar_tag ],   "case: foo and similar tag"),
++        ]
++        for tags, case in test_patterns:
++            result1 = self.tag_matcher.should_run_with(tags)
++            result2 = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
++            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
+diff --git a/tests/unit/test_tag_matcher.py b/tests/unit/test_tag_matcher.py
+index c5d2266..a04c1d4 100644
+--- a/tests/unit/test_tag_matcher.py
++++ b/tests/unit/test_tag_matcher.py
+@@ -8,12 +8,13 @@ Unit tests for active tag-matcher (mod:`behave.tag_matcher`).
+ """
+ 
+ from __future__ import absolute_import
+-from behave.tag_matcher import *
+ from mock import Mock
+ from unittest import TestCase
+ import warnings
+ import pytest
+ 
++from behave.tag_matcher import *
++
+ 
+ class Traits4ActiveTagMatcher(object):
+     TagMatcher = ActiveTagMatcher
+@@ -460,279 +461,3 @@ class TestCompositeTagMatcher(TestCase):
+             actual_true_count = self.count_tag_matcher_with_result(
+                                     self.ctag_matcher.tag_matchers, tags, True)
+             self.assertEqual(0, actual_true_count)
+-
+-
+-# -----------------------------------------------------------------------------
+-# PROTOTYPING CLASSES (deprecating)
+-# -----------------------------------------------------------------------------
+-class TestOnlyWithCategoryTagMatcher(TestCase):
+-    TagMatcher = OnlyWithCategoryTagMatcher
+-
+-    def setUp(self):
+-        category = "xxx"
+-        with warnings.catch_warnings():
+-            warnings.simplefilter("ignore", DeprecationWarning)
+-            self.tag_matcher = OnlyWithCategoryTagMatcher(category, "alice")
+-        self.enabled_tag = self.TagMatcher.make_category_tag(category, "alice")
+-        self.similar_tag = self.TagMatcher.make_category_tag(category, "alice2")
+-        self.other_tag = self.TagMatcher.make_category_tag(category, "other")
+-        self.category = category
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag(self):
+-        tags = [ self.enabled_tag ]
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
+-        test_patterns = [
+-            ([ self.enabled_tag, self.other_tag ], "case: first"),
+-            ([ self.other_tag, self.enabled_tag ], "case: last"),
+-            ([ "foo", self.enabled_tag, self.other_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag(self):
+-        tags = [ self.other_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
+-        test_patterns = [
+-            ([ self.other_tag, "foo" ], "case: first"),
+-            ([ "foo", self.other_tag ], "case: last"),
+-            ([ "foo", self.other_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_tag(self):
+-        tags = [ self.similar_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_and_more(self):
+-        test_patterns = [
+-            ([ self.similar_tag, "foo" ], "case: first"),
+-            ([ "foo", self.similar_tag ], "case: last"),
+-            ([ "foo", self.similar_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_false_without_category_tag(self):
+-        test_patterns = [
+-            ([ ],           "case: No tags"),
+-            ([ "foo" ],     "case: One tag"),
+-            ([ "foo", "bar" ], "case: Two tags"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_run_with__negates_result_of_should_exclude_with(self):
+-        test_patterns = [
+-            ([ ],                   "case: No tags"),
+-            ([ "foo" ],             "case: One non-category tag"),
+-            ([ "foo", "bar" ],      "case: Two non-category tags"),
+-            ([ self.enabled_tag ],   "case: enabled tag"),
+-            ([ self.enabled_tag, self.other_tag ],  "case: enabled and other tag"),
+-            ([ self.enabled_tag, "foo" ],    "case: enabled and foo tag"),
+-            ([ self.other_tag ],            "case: other tag"),
+-            ([ self.other_tag, "foo" ],     "case: other and foo tag"),
+-            ([ self.similar_tag ],          "case: similar tag"),
+-            ([ "foo", self.similar_tag ],   "case: foo and similar tag"),
+-        ]
+-        for tags, case in test_patterns:
+-            result1 = self.tag_matcher.should_run_with(tags)
+-            result2 = self.tag_matcher.should_exclude_with(tags)
+-            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
+-            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
+-
+-    def test_make_category_tag__returns_category_tag_prefix_without_value(self):
+-        category = "xxx"
+-        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category)
+-        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, None)
+-        tag3 = OnlyWithCategoryTagMatcher.make_category_tag(category, value=None)
+-        self.assertEqual("only.with_xxx=", tag1)
+-        self.assertEqual("only.with_xxx=", tag2)
+-        self.assertEqual("only.with_xxx=", tag3)
+-        self.assertTrue(tag1.startswith(OnlyWithCategoryTagMatcher.tag_prefix))
+-
+-    def test_make_category_tag__returns_category_tag_with_value(self):
+-        category = "xxx"
+-        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category, "alice")
+-        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, "bob")
+-        self.assertEqual("only.with_xxx=alice", tag1)
+-        self.assertEqual("only.with_xxx=bob", tag2)
+-
+-    def test_make_category_tag__returns_category_tag_with_tag_prefix(self):
+-        my_tag_prefix = "ONLY_WITH."
+-        category = "xxx"
+-        TagMatcher = OnlyWithCategoryTagMatcher
+-        tag0 = TagMatcher.make_category_tag(category, tag_prefix=my_tag_prefix)
+-        tag1 = TagMatcher.make_category_tag(category, "alice", my_tag_prefix)
+-        tag2 = TagMatcher.make_category_tag(category, "bob", tag_prefix=my_tag_prefix)
+-        self.assertEqual("ONLY_WITH.xxx=", tag0)
+-        self.assertEqual("ONLY_WITH.xxx=alice", tag1)
+-        self.assertEqual("ONLY_WITH.xxx=bob", tag2)
+-        self.assertTrue(tag1.startswith(my_tag_prefix))
+-
+-    def test_ctor__with_tag_prefix(self):
+-        tag_prefix = "ONLY_WITH."
+-        tag_matcher = OnlyWithCategoryTagMatcher("xxx", "alice", tag_prefix)
+-
+-        tags = ["foo", "ONLY_WITH.xxx=foo", "only.with_xxx=bar", "bar"]
+-        actual_tags = tag_matcher.select_category_tags(tags)
+-        self.assertEqual(["ONLY_WITH.xxx=foo"], actual_tags)
+-
+-
+-class Traits4OnlyWithAnyCategoryTagMatcher(object):
+-    """Test data for OnlyWithAnyCategoryTagMatcher."""
+-
+-    TagMatcher0 = OnlyWithCategoryTagMatcher
+-    TagMatcher = OnlyWithAnyCategoryTagMatcher
+-    category1_enabled_tag = TagMatcher0.make_category_tag("foo", "alice")
+-    category1_similar_tag = TagMatcher0.make_category_tag("foo", "alice2")
+-    category1_disabled_tag = TagMatcher0.make_category_tag("foo", "bob")
+-    category2_enabled_tag = TagMatcher0.make_category_tag("bar", "BOB")
+-    category2_similar_tag = TagMatcher0.make_category_tag("bar", "BOB2")
+-    category2_disabled_tag = TagMatcher0.make_category_tag("bar", "CHARLY")
+-    unknown_category_tag = TagMatcher0.make_category_tag("UNKNOWN", "one")
+-
+-
+-class TestOnlyWithAnyCategoryTagMatcher(TestCase):
+-    TagMatcher = OnlyWithAnyCategoryTagMatcher
+-    traits = Traits4OnlyWithAnyCategoryTagMatcher
+-
+-    def setUp(self):
+-        value_provider = {
+-            "foo": "alice",
+-            "bar": "BOB",
+-        }
+-        with warnings.catch_warnings():
+-            warnings.simplefilter("ignore", DeprecationWarning)
+-            self.tag_matcher = self.TagMatcher(value_provider)
+-
+-    # def test_deprecating_warning_is_issued(self):
+-    #     value_provider = {"foo": "alice"}
+-    #     with warnings.catch_warnings(record=True) as recorder:
+-    #         warnings.simplefilter("always", DeprecationWarning)
+-    #         tag_matcher = OnlyWithAnyCategoryTagMatcher(value_provider)
+-    #         self.assertEqual(len(recorder), 1)
+-    #         last_warning = recorder[-1]
+-    #         assert issubclass(last_warning.category, DeprecationWarning)
+-    #         assert "deprecated" in str(last_warning.message)
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag(self):
+-        traits = self.traits
+-        tags1 = [ traits.category1_enabled_tag ]
+-        tags2 = [ traits.category2_enabled_tag ]
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags1))
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags2))
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
+-            ([ traits.category1_disabled_tag, traits.category1_enabled_tag ], "case: last"),
+-            ([ "foo", traits.category1_enabled_tag, traits.category1_disabled_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag(self):
+-        traits = self.traits
+-        tags = [ traits.category1_disabled_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ traits.category1_disabled_tag, "foo" ], "case: first"),
+-            ([ "foo", traits.category1_disabled_tag ], "case: last"),
+-            ([ "foo", traits.category1_disabled_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_tag(self):
+-        traits = self.traits
+-        tags = [ traits.category1_similar_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_and_more(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ traits.category1_similar_tag, "foo" ], "case: first"),
+-            ([ "foo", traits.category1_similar_tag ], "case: last"),
+-            ([ "foo", traits.category1_similar_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_false_without_category_tag(self):
+-        test_patterns = [
+-            ([ ],           "case: No tags"),
+-            ([ "foo" ],     "case: One tag"),
+-            ([ "foo", "bar" ], "case: Two tags"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_false_with_unknown_category_tag(self):
+-        """Tags from unknown categories, not supported by value_provider,
+-        should not be excluded.
+-        """
+-        traits = self.traits
+-        tags = [ traits.unknown_category_tag ]
+-        self.assertEqual("only.with_UNKNOWN=one", traits.unknown_category_tag)
+-        self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__combinations_of_2_categories(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ("case 00: 2 disabled category tags", True,
+-             [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
+-            ("case 01: disabled and enabled category tags", True,
+-             [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
+-            ("case 10: enabled and disabled category tags", True,
+-             [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
+-            ("case 11: 2 enabled category tags", False,  # -- SHOULD-RUN
+-             [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
+-            # -- SPECIAL CASE: With unknown category
+-            ("case 0x: disabled and unknown category tags", True,
+-             [ traits.category1_disabled_tag, traits.unknown_category_tag]),
+-            ("case 1x: enabled and unknown category tags", False,  # SHOULD-RUN
+-             [ traits.category1_enabled_tag, traits.unknown_category_tag]),
+-        ]
+-        for case, expected, tags in test_patterns:
+-            actual_result = self.tag_matcher.should_exclude_with(tags)
+-            self.assertEqual(expected, actual_result,
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_run_with__negates_result_of_should_exclude_with(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ ],                   "case: No tags"),
+-            ([ "foo" ],             "case: One non-category tag"),
+-            ([ "foo", "bar" ],      "case: Two non-category tags"),
+-            ([ traits.category1_enabled_tag ],   "case: enabled tag"),
+-            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ],  "case: enabled and other tag"),
+-            ([ traits.category1_enabled_tag, "foo" ],    "case: enabled and foo tag"),
+-            ([ traits.category1_disabled_tag ],            "case: other tag"),
+-            ([ traits.category1_disabled_tag, "foo" ],     "case: other and foo tag"),
+-            ([ traits.category1_similar_tag ],          "case: similar tag"),
+-            ([ "foo", traits.category1_similar_tag ],   "case: foo and similar tag"),
+-        ]
+-        for tags, case in test_patterns:
+-            result1 = self.tag_matcher.should_run_with(tags)
+-            result2 = self.tag_matcher.should_exclude_with(tags)
+-            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
+-            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
+-
diff --git a/meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch
new file mode 100644
index 000000000..c41068c96
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch
@@ -0,0 +1,30 @@
+From 362e778e5e57054b45099f1432abea181987d3c9 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 19:24:14 +0200
+Subject: [PATCH] Comment tweaks
+
+---
+ behave/runner.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/behave/runner.py b/behave/runner.py
+index f0f077a..f209cb0 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -167,10 +167,15 @@ class Context(object):
+         self._record = {}
+         self._origin = {}
+         self._mode = self.BEHAVE
++
++        # -- MODEL ENTITY REFERENCES/SUPPORT:
+         self.feature = None
+-        # -- RECHECK: If needed
++        # DISABLED: self.rule = None
++        # DISABLED: self.scenario = None
+         self.text = None
+         self.table = None
++
++        # -- RUNTIME SUPPORT:
+         self.stdout_capture = None
+         self.stderr_capture = None
+         self.log_capture = None
diff --git a/meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch b/meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch
new file mode 100644
index 000000000..8f0ad3a82
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch
@@ -0,0 +1,79 @@
+From d892f81e3bd3e979d3677c39c3a9efc40131b452 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 19:32:10 +0200
+Subject: [PATCH] FIX warnings related to invalid escapes in regex.
+
+---
+ behave4cmd0/command_shell_proc.py           |  3 ++-
+ features/steps/behave_select_files_steps.py | 24 +++++++++++++--------
+ 2 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/behave4cmd0/command_shell_proc.py b/behave4cmd0/command_shell_proc.py
+index 07f1c84..03ca55a 100755
+--- a/behave4cmd0/command_shell_proc.py
++++ b/behave4cmd0/command_shell_proc.py
+@@ -251,6 +251,7 @@ class BehaveWinCommandOutputProcessor(LineCommandOutputProcessor):
+             "No such file or directory: '(?P<path>.*)'",
+             "[Errno 2] No such file or directory:"),  # IOError
+         ExceptionWithPathNormalizer(
+-            '^\s*File "(?P<path>.*)", line \d+, in ',
++            # WAS: '^\s*File "(?P<path>.*)", line \d+, in ',
++            r'^\s*File "(?P<path>.*)", line \d+, in ',
+             'File "'),
+     ]
+diff --git a/features/steps/behave_select_files_steps.py b/features/steps/behave_select_files_steps.py
+index 431674e..0d2cd2e 100644
+--- a/features/steps/behave_select_files_steps.py
++++ b/features/steps/behave_select_files_steps.py
+@@ -1,29 +1,34 @@
+ # -*- coding: utf-8 -*-
+-"""
++# DOCSTRING-NEEDS-REGEX-STRING-PREFIX: Due to example w/ wildcard pattern.
++r'''
+ Provides step definitions that test how the behave runner selects feature files.
+ 
+ EXAMPLE:
++
++.. code-block:: gherkin
++
+     Given behave has the following feature fileset:
+-      '''
++      """
+       features/alice.feature
+       features/bob.feature
+       features/barbi.feature
+-      '''
++      """
+     When behave includes feature files with "features/a.*\.feature"
+     And  behave excludes feature files with "features/b.*\.feature"
+     Then the following feature files are selected:
+-      '''
++      """
+       features/alice.feature
+-      '''
+-"""
++      """
++'''
+ 
+ from __future__ import absolute_import
+-from behave import given, when, then
+-from behave.runner_util import FeatureListParser
+-from hamcrest import assert_that, equal_to
+ from copy import copy
+ import re
+ import six
++from hamcrest import assert_that, equal_to
++from behave import given, when, then
++from behave.runner_util import FeatureListParser
++
+ 
+ # -----------------------------------------------------------------------------
+ # STEP UTILS:
+@@ -47,6 +52,7 @@ class BasicBehaveRunner(object):
+ # -----------------------------------------------------------------------------
+ # STEP DEFINITIONS:
+ # -----------------------------------------------------------------------------
++# pylint: disable=invalid-name
+ @given('behave has the following feature fileset')
+ def step_given_behave_has_feature_fileset(context):
+     assert context.text is not None, "REQUIRE: text"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch b/meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch
new file mode 100644
index 000000000..e2d86ca99
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch
@@ -0,0 +1,73 @@
+From 11c4ac862bdce901ef19864532ef6d17a85799cd Mon Sep 17 00:00:00 2001
+From: Edvin Linge <edvin.linge@gmail.com>
+Date: Mon, 31 Jul 2017 17:05:18 +0200
+Subject: [PATCH] Steps-catalog should not break configured rerun settings
+
+---
+ behave/configuration.py                  |  5 ++++-
+ features/formatter.rerun.feature         | 17 +++++++++++++++++
+ features/formatter.steps_catalog.feature | 13 +++++++++++++
+ 3 files changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 49b1dff..861f89f 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -601,7 +601,10 @@ class Configuration(object):
+         if self.steps_catalog:
+             # -- SHOW STEP-CATALOG: As step summary.
+             self.default_format = "steps.catalog"
+-            self.format = ["steps.catalog"]
++            if self.format:
++                self.format.append("steps.catalog")
++            else:
++                self.format = ["steps.catalog"]
+             self.dry_run = True
+             self.summary = False
+             self.show_skipped = False
+diff --git a/features/formatter.rerun.feature b/features/formatter.rerun.feature
+index 1e645f1..b9d7e1b 100644
+--- a/features/formatter.rerun.feature
++++ b/features/formatter.rerun.feature
+@@ -294,3 +294,20 @@ Feature: Rerun Formatter
+             features/bob.feature:13
+             """
+         And note that "the second RerunFormatter overwrites the output of the first one"
++
++    @with.behave_configfile
++    Scenario: RerunFormatter with steps-catalog
++        Given a file named "behave.ini" with:
++            """
++            [behave]
++            format   = rerun
++            outfiles = rerun.txt
++            """
++        When I run "behave --steps-catalog features/"
++
++        Then it should pass with:
++            """
++            Given a step passes
++            """
++        And a file named "rerun.txt" does not exist
++
+diff --git a/features/formatter.steps_catalog.feature b/features/formatter.steps_catalog.feature
+index 09591bf..936d7f4 100644
+--- a/features/formatter.steps_catalog.feature
++++ b/features/formatter.steps_catalog.feature
+@@ -98,3 +98,16 @@ Feature: Steps Catalog Formatter
+           """
+         But note that "the step definitions are ordered by step type"
+         And note that "'When I visit {person}' has no doc-string"
++
++
++    Scenario: Steps catalog formatter is used for output even when other formatter is specified
++        When I run "behave --steps-catalog -f plain features/"
++        Then it should pass with:
++          """
++          Given {person} lives in {city}
++              Setup the data where a person lives and store in the database.
++
++              :param person:  Person's name (as string).
++              :param city:    City where the person lives (as string).
++          """
++
diff --git a/meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch b/meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch
new file mode 100644
index 000000000..f050c9c85
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch
@@ -0,0 +1,36 @@
+From 502382430f1bee8d0a9031fc70541488224a1029 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 1 Jul 2019 22:07:19 +0200
+Subject: [PATCH] Add feature w/ rules and failing scenarios (enable via
+ tags=fail or tags=xfail).
+
+---
+ .../gherkin_v6/features/rule_fails.feature    | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+ create mode 100644 examples/gherkin_v6/features/rule_fails.feature
+
+diff --git a/examples/gherkin_v6/features/rule_fails.feature b/examples/gherkin_v6/features/rule_fails.feature
+new file mode 100644
+index 0000000..7e3872e
+--- /dev/null
++++ b/examples/gherkin_v6/features/rule_fails.feature
+@@ -0,0 +1,19 @@
++@fail
++Feature: With Rule(s) and Failing Scenario(s)
++
++  HINT: Contains failing scenarios (by intention).
++
++  @xfail
++  Scenario: F0 -- Fails
++    When some step fails
++
++  Rule: Fails in Scenario F2
++
++    Scenario: F1
++      Given a step passes
++
++    @xfail
++    Scenario: F2 -- Fails
++      Given another step passes
++      When a step fails
++      Then another step passes
diff --git a/meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch b/meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch
new file mode 100644
index 000000000..6f71729f5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch
@@ -0,0 +1,27 @@
+From dcbba864209e8784ecaa5a1cf80b346b39b2a5d6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 1 Jul 2019 22:11:13 +0200
+Subject: [PATCH] examples/gherkin_v6: Tweak ScenarioOutline Examples titles.
+
+---
+ examples/gherkin_v6/features/rule_2.feature | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/examples/gherkin_v6/features/rule_2.feature b/examples/gherkin_v6/features/rule_2.feature
+index a802e19..8b8bb04 100644
+--- a/examples/gherkin_v6/features/rule_2.feature
++++ b/examples/gherkin_v6/features/rule_2.feature
+@@ -36,7 +36,12 @@ Feature: Gherkin v6 Example -- with Rules
+     Scenario Template: R3.Scenario
+       Given a person named "<name>"
+ 
+-      Examples:
++      Examples: R3.E1
+         | name  |
+         | Alice |
+         | Bob   |
++
++      Examples: R3.E2
++        | name  |
++        | Charly |
++        | Doro   |
diff --git a/meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch b/meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch
new file mode 100644
index 000000000..4d44fea08
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch
@@ -0,0 +1,21 @@
+From 9c9bb1e6320a6ffbac0b171d9cf98cbb311104eb Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 1 Jul 2019 08:06:43 +0200
+Subject: [PATCH] Add info on merged pull #588
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index a91e22a..3d805b3 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -36,6 +36,7 @@ PARTIALLY FIXED:
+ 
+ FIXED:
+ 
++* pull  #588: Steps-catalog argument should not break configured rerun settings (provided by: Lego3)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
+ * pull  #657: Allow async steps with timeouts to fail when they raise exceptions (provided by: ALSchwalm)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch b/meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch
new file mode 100644
index 000000000..1fdda3a7d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch
@@ -0,0 +1,97 @@
+From 8fe1bc305aeea5d86de1b3c5dfcd2e7984fc5145 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 5 Jul 2019 08:27:44 +0200
+Subject: [PATCH] Tweak tests, required by pytest >= 5.0. With pytest.raises
+ use str(e.value) instead of str(e) in some cases.
+
+---
+ tests/issues/test_issue0458.py      |  2 +-
+ tests/unit/test_context_cleanups.py |  2 +-
+ tests/unit/test_textutil.py         | 24 +++++++++++++++---------
+ 3 files changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/tests/issues/test_issue0458.py b/tests/issues/test_issue0458.py
+index 1853ad6..f66f6d3 100644
+--- a/tests/issues/test_issue0458.py
++++ b/tests/issues/test_issue0458.py
+@@ -48,7 +48,7 @@ def test_issue(exception_class, message):
+         raise_exception(exception_class, message)
+ 
+     # -- SHOULD NOT RAISE EXCEPTION HERE:
+-    text = _text(e)
++    text = _text(e.value)
+     # -- DIAGNOSTICS:
+     print(u"text"+ text)
+     print(u"exception: %s" % e)
+diff --git a/tests/unit/test_context_cleanups.py b/tests/unit/test_context_cleanups.py
+index b0e8ae6..bf0ab50 100644
+--- a/tests/unit/test_context_cleanups.py
++++ b/tests/unit/test_context_cleanups.py
+@@ -153,7 +153,7 @@ class TestContextCleanup(object):
+         with pytest.raises(AssertionError) as e:
+             with scoped_context_layer(context):
+                 context.add_cleanup(non_callable)
+-        assert "REQUIRES: callable(cleanup_func)" in str(e)
++        assert "REQUIRES: callable(cleanup_func)" in str(e.value)
+ 
+     def test_on_cleanup_error__prints_error_by_default(self, capsys):
+         def bad_cleanup_func():
+diff --git a/tests/unit/test_textutil.py b/tests/unit/test_textutil.py
+index f7f642c..e05e9ad 100644
+--- a/tests/unit/test_textutil.py
++++ b/tests/unit/test_textutil.py
+@@ -214,9 +214,11 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(AssertionError) as e:
+             assert False, message
+ 
+-        text2 = text(e)
+-        expected = u"AssertionError: %s" % message
+-        assert text2.endswith(expected)
++        # -- FOR: pytest < 5.0
++        # expected = u"AssertionError: %s" % message
++        text2 = text(e.value)
++        assert u"AssertionError" in text(e)
++        assert message in text2, "OOPS: text=%r" % text2
+ 
+     @requires_python2
+     @pytest.mark.parametrize("message", [
+@@ -236,10 +238,11 @@ class TestObjectToTextConversion(object):
+                 assert expected_decode_error in str(uni_error)
+                 assert False, bytes_message.decode(self.ENCODING)
+ 
++        # -- FOR: pytest < 5.0
++        # expected = u"AssertionError: %s" % message
+         print("decode_error_occured(ascii)=%s" % decode_error_occured)
+-        text2 = text(e)
+-        expected = u"AssertionError: %s" % message
+-        assert text2.endswith(expected)
++        text2 = text(e.value)
++        assert message in text2, "OOPS: text=%r" % text2
+ 
+     @pytest.mark.parametrize("exception_class, message", [
+         (AssertionError, u"Ärgernis"),
+@@ -251,10 +254,13 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(exception_class) as e:
+             raise exception_class(message)
+ 
+-        text2 = text(e)
++        # -- FOR: pytest < 5.0
++        # expected = u"AssertionError: %s" % message
++        text2 = text(e.value)
+         expected = u"%s: %s" % (exception_class.__name__, message)
+         assert isinstance(text2, six.text_type)
+-        assert text2.endswith(expected)
++        assert exception_class.__name__ in str(e)
++        assert message in text2, "OOPS: text=%r" % text2
+ 
+     @requires_python2
+     @pytest.mark.parametrize("exception_class, message", [
+@@ -268,7 +274,7 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(exception_class) as e:
+             raise exception_class(bytes_message)
+ 
+-        text2 = text(e)
++        text2 = text(e.value)
+         unicode_message = bytes_message.decode(self.ENCODING)
+         expected = u"%s: %s" % (exception_class.__name__, unicode_message)
+         assert isinstance(text2, six.text_type)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch b/meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch
new file mode 100644
index 000000000..7a47c7fe7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch
@@ -0,0 +1,180 @@
+From dce0e40c9689a8d4fe71c9b2e8e4decd72dcf574 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 5 Jul 2019 08:45:51 +0200
+Subject: [PATCH] CLEANUP: Use pytest instead of nose to remove nose.importer
+ DeprecationWarning.
+
+---
+ tests/unit/test_importer.py | 163 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 163 insertions(+)
+ create mode 100644 tests/unit/test_importer.py
+
+diff --git a/tests/unit/test_importer.py b/tests/unit/test_importer.py
+new file mode 100644
+index 0000000..f3f4e2c
+--- /dev/null
++++ b/tests/unit/test_importer.py
+@@ -0,0 +1,163 @@
++# -*- coding: utf-8 -*-
++"""
++Tests for behave.importing.
++The module provides a lazy-loading/importing mechanism.
++"""
++
++from __future__ import absolute_import
++import pytest
++from behave.importer import LazyObject, LazyDict, load_module, parse_scoped_name
++from behave.formatter.base import Formatter
++import sys
++import types
++# import unittest
++
++
++class TestTheory(object):
++    """Marker for test-theory classes as syntactic sugar."""
++    pass
++
++
++class ImportModuleTheory(TestTheory):
++    """
++    Provides a test theory for importing modules.
++    """
++
++    @classmethod
++    def ensure_module_is_not_imported(cls, module_name):
++        if module_name in sys.modules:
++            del sys.modules[module_name]
++        cls.assert_module_is_not_imported(module_name)
++
++    @staticmethod
++    def assert_module_is_imported(module_name):
++        module = sys.modules.get(module_name, None)
++        assert module_name in sys.modules
++        assert module is not None
++
++    @staticmethod
++    def assert_module_is_not_imported(module_name):
++        assert module_name not in sys.modules
++
++    @staticmethod
++    def assert_module_with_name(module, name):
++        assert isinstance(module, types.ModuleType)
++        assert module.__name__ == name
++
++
++class TestLoadModule(object):
++    theory = ImportModuleTheory
++
++    def test_load_module__should_fail_for_unknown_module(self):
++        with pytest.raises(ImportError) as e:
++            load_module("__unknown_module__")
++        # OLD: assert_raises(ImportError, load_module, "__unknown_module__")
++
++    def test_load_module__should_succeed_for_already_imported_module(self):
++        module_name = "behave.importer"
++        self.theory.assert_module_is_imported(module_name)
++
++        module = load_module(module_name)
++        self.theory.assert_module_with_name(module, module_name)
++        self.theory.assert_module_is_imported(module_name)
++
++    def test_load_module__should_succeed_for_existing_module(self):
++        module_name = "test._importer_candidate"
++        self.theory.ensure_module_is_not_imported(module_name)
++
++        module = load_module(module_name)
++        self.theory.assert_module_with_name(module, module_name)
++        self.theory.assert_module_is_imported(module_name)
++
++
++class TestLazyObject(object):
++
++    def test_get__should_succeed_for_known_object(self):
++        lazy = LazyObject("behave.importer", "LazyObject")
++        value = lazy.get()
++        assert value is LazyObject
++
++        lazy2 = LazyObject("behave.importer:LazyObject")
++        value2 = lazy2.get()
++        assert value2 is LazyObject
++
++        lazy3 = LazyObject("behave.formatter.steps", "StepsFormatter")
++        value3 = lazy3.get()
++        assert issubclass(value3, Formatter)
++
++    def test_get__should_fail_for_unknown_module(self):
++        lazy = LazyObject("__unknown_module__", "xxx")
++        with pytest.raises(ImportError):
++            lazy.get()
++
++    def test_get__should_fail_for_unknown_object_in_module(self):
++        lazy = LazyObject("test._importer_candidate", "xxx")
++        with pytest.raises(ImportError):
++            lazy.get()
++
++
++class LazyDictTheory(TestTheory):
++
++    @staticmethod
++    def safe_getitem(data, key):
++        return dict.__getitem__(data, key)
++
++    @classmethod
++    def assert_item_is_lazy(cls, data, key):
++        value = cls.safe_getitem(data, key)
++        cls.assert_is_lazy_object(value)
++
++    @classmethod
++    def assert_item_is_not_lazy(cls, data, key):
++        value = cls.safe_getitem(data, key)
++        cls.assert_is_not_lazy_object(value)
++
++    @staticmethod
++    def assert_is_lazy_object(obj):
++        assert isinstance(obj, LazyObject)
++
++    @staticmethod
++    def assert_is_not_lazy_object(obj):
++        assert not isinstance(obj, LazyObject)
++
++
++class TestLazyDict(object):
++    theory = LazyDictTheory
++
++    def test_unknown_item_access__should_raise_keyerror(self):
++        lazy_dict = LazyDict({"alice": 42})
++        item_access = lambda key: lazy_dict[key]
++        with pytest.raises(KeyError):
++            item_access("unknown")
++
++    def test_plain_item_access__should_succeed(self):
++        theory = LazyDictTheory
++        lazy_dict = LazyDict({"alice": 42})
++        theory.assert_item_is_not_lazy(lazy_dict, "alice")
++
++        value = lazy_dict["alice"]
++        assert value == 42
++
++    def test_lazy_item_access__should_load_object(self):
++        ImportModuleTheory.ensure_module_is_not_imported("inspect")
++        lazy_dict = LazyDict({"alice": LazyObject("inspect:ismodule")})
++        self.theory.assert_item_is_lazy(lazy_dict, "alice")
++        self.theory.assert_item_is_lazy(lazy_dict, "alice")
++
++        value = lazy_dict["alice"]
++        self.theory.assert_is_not_lazy_object(value)
++        self.theory.assert_item_is_not_lazy(lazy_dict, "alice")
++
++    def test_lazy_item_access__should_fail_with_unknown_module(self):
++        lazy_dict = LazyDict({"bob": LazyObject("__unknown_module__", "xxx")})
++        item_access = lambda key: lazy_dict[key]
++        with pytest.raises(ImportError):
++            item_access("bob")
++
++    def test_lazy_item_access__should_fail_with_unknown_object(self):
++        lazy_dict = LazyDict({
++            "bob": LazyObject("behave.importer", "XUnknown")
++        })
++        item_access = lambda key: lazy_dict[key]
++        with pytest.raises(ImportError):
++            item_access("bob")
diff --git a/meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch b/meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch
new file mode 100644
index 000000000..33738459d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch
@@ -0,0 +1,1815 @@
+From 65b17ccbea1a17b26e6191a1d7336088d0dd4181 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 09:10:52 +0200
+Subject: [PATCH] REMOVE-DEPENDENCY: nose (to avoid nose.importer warnings)
+
+Replace nose test-framework functionality w/ pytest.
+Move test/*.py => tests/unit/*.py
+---
+ MANIFEST.in                                   |   2 -
+ conftest.py                                   |  13 ++
+ invoke.yaml                                   |   1 +
+ py.requirements/ci.tox.txt                    |   9 +
+ py.requirements/ci.travis.txt                 |   1 -
+ py.requirements/develop.txt                   |   1 -
+ py.requirements/testing.txt                   |   3 +-
+ pytest.ini                                    |   7 +-
+ setup.py                                      |   8 +-
+ tasks/test.py                                 |   2 +-
+ test/__init__.py                              |   0
+ test/test_importer.py                         | 151 -------------
+ {test => tests/unit}/_importer_candidate.py   |   0
+ tests/unit/reporter/test_summary.py           |   2 -
+ .../test_tag_expression_v1_part1.py           |  17 +-
+ .../test_tag_expression_v1_part2.py           |  18 +-
+ {test => tests/unit}/test_ansi_escapes.py     |  14 +-
+ {test => tests/unit}/test_configuration.py    |  75 +++---
+ {test => tests/unit}/test_formatter.py        |  15 +-
+ .../unit}/test_formatter_progress.py          |   7 +
+ {test => tests/unit}/test_formatter_rerun.py  |  12 +-
+ {test => tests/unit}/test_formatter_tags.py   |   9 +
+ tests/unit/test_importer.py                   |   2 +-
+ {test => tests/unit}/test_log_capture.py      |   9 +-
+ {test => tests/unit}/test_matchers.py         |  24 +-
+ tests/unit/test_parser.py                     |   1 -
+ {test => tests/unit}/test_runner.py           | 213 ++++++++++--------
+ {test => tests/unit}/test_step_registry.py    |   5 +-
+ tests/unit/test_textutil.py                   |  12 +-
+ tox.ini                                       |  19 +-
+ 30 files changed, 283 insertions(+), 369 deletions(-)
+ create mode 100644 py.requirements/ci.tox.txt
+ delete mode 100644 test/__init__.py
+ delete mode 100644 test/test_importer.py
+ rename {test => tests/unit}/_importer_candidate.py (100%)
+ rename {test => tests/unit}/test_ansi_escapes.py (84%)
+ rename {test => tests/unit}/test_configuration.py (72%)
+ rename {test => tests/unit}/test_formatter.py (94%)
+ rename {test => tests/unit}/test_formatter_progress.py (99%)
+ rename {test => tests/unit}/test_formatter_rerun.py (94%)
+ rename {test => tests/unit}/test_formatter_tags.py (99%)
+ rename {test => tests/unit}/test_log_capture.py (87%)
+ rename {test => tests/unit}/test_matchers.py (93%)
+ rename {test => tests/unit}/test_runner.py (82%)
+ rename {test => tests/unit}/test_step_registry.py (95%)
+
+diff --git a/MANIFEST.in b/MANIFEST.in
+index 49cb7c6..60c2601 100644
+--- a/MANIFEST.in
++++ b/MANIFEST.in
+@@ -33,5 +33,3 @@ recursive-include py.requirements  *.txt
+ 
+ prune .tox
+ prune .venv*
+-prune paver_ext
+-exclude pavement.py
+diff --git a/conftest.py b/conftest.py
+index 7b3a883..71a3bd0 100644
+--- a/conftest.py
++++ b/conftest.py
+@@ -10,6 +10,10 @@ Add project-specific information.
+ import behave
+ import pytest
+ 
++
++# ---------------------------------------------------------------------------
++# PYTEST FIXTURES:
++# ---------------------------------------------------------------------------
+ @pytest.fixture(autouse=True)
+ def _annotate_environment(request):
+     """Add project-specific information to test-run environment:
+@@ -25,3 +29,12 @@ def _annotate_environment(request):
+         behave_version = behave.__version__
+         environment.append(("behave", behave_version))
+ 
++_pytest_version = pytest.__version__
++if _pytest_version >= "5.0":
++    # -- SUPPORTED SINCE: pytest 5.0
++    @pytest.fixture(scope="session", autouse=True)
++    def log_global_env_facts(record_testsuite_property):
++        # SEE: https://docs.pytest.org/en/latest/usage.html
++        behave_version = behave.__version__
++        record_testsuite_property("BEHAVE_VERSION", behave_version)
++
+diff --git a/invoke.yaml b/invoke.yaml
+index 4f21328..3e93cfc 100644
+--- a/invoke.yaml
++++ b/invoke.yaml
+@@ -23,6 +23,7 @@ sphinx:
+     languages:
+       - de
+       # PREPARED: - zh-CN
++
+ cleanup:
+     extra_directories:
+       - "build"
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+new file mode 100644
+index 0000000..6b3b3ae
+--- /dev/null
++++ b/py.requirements/ci.tox.txt
+@@ -0,0 +1,9 @@
++# ============================================================================
++# BEHAVE: PYTHON PACKAGE REQUIREMENTS: ci.tox.txt
++# ============================================================================
++
++pytest >= 4.2
++pytest-html >= 1.19.0
++mock >= 2.0
++PyHamcrest >= 1.9
++path.py >= 10.1
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 1cc0239..73d65f6 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,5 +1,4 @@
+ mock
+-nose
+ PyHamcrest >= 1.9
+ pytest >= 3.0
+ pytest-html >= 1.19.0
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index 3deedc7..d823389 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -14,7 +14,6 @@ pycmd
+ bumpversion >= 0.4.0
+ 
+ # -- DEVELOPMENT SUPPORT:
+-# PREPARED: nose-cov >= 1.4
+ tox   >= 1.8.1
+ coverage >= 4.2
+ pytest-cov
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 3806d39..a418739 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -4,9 +4,8 @@
+ 
+ # -- TESTING: Unit tests and behave self-tests.
+ # PREPARED-FUTURE: behave4cmd0, behave4cmd
+-pytest >= 3.0
++pytest >= 4.2
+ pytest-html >= 1.19.0
+-nose  >= 1.3
+ mock  >= 2.0
+ PyHamcrest >= 1.9
+ 
+diff --git a/pytest.ini b/pytest.ini
+index 17ad388..a686596 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -16,8 +16,8 @@
+ # ============================================================================
+ 
+ [pytest]
+-minversion    = 2.8
+-testpaths     = test tests
++minversion    = 4.2
++testpaths     = tests
+ python_files  = test_*.py
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+     --metadata PACKAGE_VERSION 1.2.7.dev1
+@@ -26,6 +26,7 @@ addopts = --metadata PACKAGE_UNDER_TEST behave
+ markers =
+     smoke
+     slow
++
+ # -- BACKWARD COMPATIBILITY: pytest < 2.8
+-norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
++# norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
+ 
+diff --git a/setup.py b/setup.py
+index ac7bddf..9c7560d 100644
+--- a/setup.py
++++ b/setup.py
+@@ -86,13 +86,11 @@ setup(
+         "win_unicode_console; python_version < '3.6'",
+         "colorama",
+     ],
+-    test_suite="nose.collector",
+     tests_require=[
+-        "pytest >= 3.0",
++        "pytest >= 4.2",
+         "pytest-html >= 1.19.0",
+-        "nose >= 1.3",
+         "mock >= 1.1",
+-        "PyHamcrest >= 1.8",
++        "PyHamcrest >= 1.9",
+         "path.py >= 11.5.0"
+     ],
+     cmdclass = {
+@@ -105,7 +103,7 @@ setup(
+         ],
+         "develop": [
+             "coverage",
+-            "pytest >= 3.0",
++            "pytest >= 4.2",
+             "pytest-html >= 1.19.0",
+             "pytest-cov",
+             "tox",
+diff --git a/tasks/test.py b/tasks/test.py
+index 06eb175..bfa2d80 100644
+--- a/tasks/test.py
++++ b/tasks/test.py
+@@ -172,7 +172,7 @@ namespace.configure({
+         },
+     },
+     "pytest": {
+-        "scopes":   ["test", "tests"],
++        "scopes":   ["tests"],
+         "args":   "",
+         "options": "",  # -- NOTE:  Overide in configfile "invoke.yaml"
+     },
+diff --git a/test/__init__.py b/test/__init__.py
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/test/test_importer.py b/test/test_importer.py
+deleted file mode 100644
+index baca21a..0000000
+--- a/test/test_importer.py
++++ /dev/null
+@@ -1,151 +0,0 @@
+-# -*- coding: utf-8 -*-
+-"""
+-Tests for behave.importing.
+-The module provides a lazy-loading/importing mechanism.
+-"""
+-
+-from __future__ import absolute_import
+-from behave.importer import LazyObject, LazyDict, load_module, parse_scoped_name
+-from behave.formatter.base import Formatter
+-from nose.tools import eq_, assert_raises
+-import sys
+-import types
+-# import unittest
+-
+-
+-class TestTheory(object): pass
+-class ImportModuleTheory(TestTheory):
+-    """
+-    Provides a test theory for importing modules.
+-    """
+-
+-    @classmethod
+-    def ensure_module_is_not_imported(cls, module_name):
+-        if module_name in sys.modules:
+-            del sys.modules[module_name]
+-        cls.assert_module_is_not_imported(module_name)
+-
+-    @staticmethod
+-    def assert_module_is_imported(module_name):
+-        module = sys.modules.get(module_name, None)
+-        assert module_name in sys.modules
+-        assert module is not None
+-
+-    @staticmethod
+-    def assert_module_is_not_imported(module_name):
+-        assert module_name not in sys.modules
+-
+-    @staticmethod
+-    def assert_module_with_name(module, name):
+-        assert isinstance(module, types.ModuleType)
+-        eq_(module.__name__, name)
+-
+-
+-class TestLoadModule(object):
+-    theory = ImportModuleTheory
+-
+-    def test_load_module__should_fail_for_unknown_module(self):
+-        assert_raises(ImportError, load_module, "__unknown_module__")
+-
+-    def test_load_module__should_succeed_for_already_imported_module(self):
+-        module_name = "behave.importer"
+-        self.theory.assert_module_is_imported(module_name)
+-
+-        module = load_module(module_name)
+-        self.theory.assert_module_with_name(module, module_name)
+-        self.theory.assert_module_is_imported(module_name)
+-
+-    def test_load_module__should_succeed_for_existing_module(self):
+-        module_name = "test._importer_candidate"
+-        self.theory.ensure_module_is_not_imported(module_name)
+-
+-        module = load_module(module_name)
+-        self.theory.assert_module_with_name(module, module_name)
+-        self.theory.assert_module_is_imported(module_name)
+-
+-class TestLazyObject(object):
+-
+-    def test_get__should_succeed_for_known_object(self):
+-        lazy = LazyObject("behave.importer", "LazyObject")
+-        value = lazy.get()
+-        assert value is LazyObject
+-
+-        lazy2 = LazyObject("behave.importer:LazyObject")
+-        value2 = lazy2.get()
+-        assert value2 is LazyObject
+-
+-        lazy3 = LazyObject("behave.formatter.steps", "StepsFormatter")
+-        value3 = lazy3.get()
+-        assert issubclass(value3, Formatter)
+-
+-    def test_get__should_fail_for_unknown_module(self):
+-        lazy = LazyObject("__unknown_module__", "xxx")
+-        assert_raises(ImportError, lazy.get)
+-
+-    def test_get__should_fail_for_unknown_object_in_module(self):
+-        lazy = LazyObject("test._importer_candidate", "xxx")
+-        assert_raises(ImportError, lazy.get)
+-
+-
+-class LazyDictTheory(TestTheory):
+-
+-    @staticmethod
+-    def safe_getitem(data, key):
+-        return dict.__getitem__(data, key)
+-
+-    @classmethod
+-    def assert_item_is_lazy(cls, data, key):
+-        value = cls.safe_getitem(data, key)
+-        cls.assert_is_lazy_object(value)
+-
+-    @classmethod
+-    def assert_item_is_not_lazy(cls, data, key):
+-        value = cls.safe_getitem(data, key)
+-        cls.assert_is_not_lazy_object(value)
+-
+-    @staticmethod
+-    def assert_is_lazy_object(obj):
+-        assert isinstance(obj, LazyObject)
+-
+-    @staticmethod
+-    def assert_is_not_lazy_object(obj):
+-        assert not isinstance(obj, LazyObject)
+-
+-
+-class TestLazyDict(object):
+-    theory = LazyDictTheory
+-
+-    def test_unknown_item_access__should_raise_keyerror(self):
+-        lazy_dict = LazyDict({"alice": 42})
+-        item_access = lambda key: lazy_dict[key]
+-        assert_raises(KeyError, item_access, "unknown")
+-
+-    def test_plain_item_access__should_succeed(self):
+-        theory = LazyDictTheory
+-        lazy_dict = LazyDict({"alice": 42})
+-        theory.assert_item_is_not_lazy(lazy_dict, "alice")
+-
+-        value = lazy_dict["alice"]
+-        eq_(value, 42)
+-
+-    def test_lazy_item_access__should_load_object(self):
+-        ImportModuleTheory.ensure_module_is_not_imported("inspect")
+-        lazy_dict = LazyDict({"alice": LazyObject("inspect:ismodule")})
+-        self.theory.assert_item_is_lazy(lazy_dict, "alice")
+-        self.theory.assert_item_is_lazy(lazy_dict, "alice")
+-
+-        value = lazy_dict["alice"]
+-        self.theory.assert_is_not_lazy_object(value)
+-        self.theory.assert_item_is_not_lazy(lazy_dict, "alice")
+-
+-    def test_lazy_item_access__should_fail_with_unknown_module(self):
+-        lazy_dict = LazyDict({"bob": LazyObject("__unknown_module__", "xxx")})
+-        item_access = lambda key: lazy_dict[key]
+-        assert_raises(ImportError, item_access, "bob")
+-
+-    def test_lazy_item_access__should_fail_with_unknown_object(self):
+-        lazy_dict = LazyDict({
+-            "bob": LazyObject("behave.importer", "XUnknown")
+-        })
+-        item_access = lambda key: lazy_dict[key]
+-        assert_raises(ImportError, item_access, "bob")
+diff --git a/test/_importer_candidate.py b/tests/unit/_importer_candidate.py
+similarity index 100%
+rename from test/_importer_candidate.py
+rename to tests/unit/_importer_candidate.py
+diff --git a/tests/unit/reporter/test_summary.py b/tests/unit/reporter/test_summary.py
+index d4e85b5..6b947bd 100644
+--- a/tests/unit/reporter/test_summary.py
++++ b/tests/unit/reporter/test_summary.py
+@@ -4,8 +4,6 @@ from __future__ import absolute_import, division
+ import sys
+ import pytest
+ from mock import Mock, patch
+-# NOT-NEEDED: from nose.tools import *
+-
+ from behave.model import ScenarioOutline, Scenario
+ from behave.model_core import Status
+ from behave.reporter.summary import SummaryReporter, format_summary
+diff --git a/tests/unit/tag_expression/test_tag_expression_v1_part1.py b/tests/unit/tag_expression/test_tag_expression_v1_part1.py
+index 619c710..56fb85d 100644
+--- a/tests/unit/tag_expression/test_tag_expression_v1_part1.py
++++ b/tests/unit/tag_expression/test_tag_expression_v1_part1.py
+@@ -2,7 +2,7 @@
+ 
+ from __future__ import absolute_import
+ from behave.tag_expression import TagExpression
+-from nose import tools
++import pytest
+ import unittest
+ 
+ 
+@@ -476,31 +476,34 @@ class TestTagExpressionFoo3OrNotBar4AndZap5(unittest.TestCase):
+         self.e = TagExpression(['foo:3,-bar', 'zap:5'])
+ 
+     def test_should_count_tags_for_positive_tags(self):
+-        tools.eq_(self.e.limits, {'foo': 3, 'zap': 5})
++        assert self.e.limits == {'foo': 3, 'zap': 5}
+ 
+     def test_should_match_foo_zap(self):
+         assert self.e.check(['foo', 'zap'])
+ 
++
+ class TestTagExpressionParsing(unittest.TestCase):
+     def setUp(self):
+         self.e = TagExpression([' foo:3 , -bar ', ' zap:5 '])
+ 
+     def test_should_have_limits(self):
+-        tools.eq_(self.e.limits, {'zap': 5, 'foo': 3})
++        assert self.e.limits == {'zap': 5, 'foo': 3}
++
+ 
+ class TestTagExpressionTagLimits(unittest.TestCase):
+     def test_should_be_counted_for_negative_tags(self):
+         e = TagExpression(['-todo:3'])
+-        tools.eq_(e.limits, {'todo': 3})
++        assert e.limits == {'todo': 3}
+ 
+     def test_should_be_counted_for_positive_tags(self):
+         e = TagExpression(['todo:3'])
+-        tools.eq_(e.limits, {'todo': 3})
++        assert e.limits == {'todo': 3}
+ 
+     def test_should_raise_an_error_for_inconsistent_limits(self):
+-        tools.assert_raises(Exception, TagExpression, ['todo:3', '-todo:4'])
++        with pytest.raises(Exception):
++            _ = TagExpression(['todo:3', '-todo:4'])
+ 
+     def test_should_allow_duplicate_consistent_limits(self):
+         e = TagExpression(['todo:3', '-todo:3'])
+-        tools.eq_(e.limits, {'todo': 3})
++        assert e.limits == {'todo': 3}
+ 
+diff --git a/tests/unit/tag_expression/test_tag_expression_v1_part2.py b/tests/unit/tag_expression/test_tag_expression_v1_part2.py
+index 690235b..cf619da 100644
+--- a/tests/unit/tag_expression/test_tag_expression_v1_part2.py
++++ b/tests/unit/tag_expression/test_tag_expression_v1_part2.py
+@@ -6,10 +6,11 @@ REQUIRES: Python >= 2.6, because itertools.combinations() is used.
+ """
+ 
+ from __future__ import absolute_import
+-from behave.tag_expression import TagExpression
+-from nose import tools
+ import itertools
+ from six.moves import range
++import pytest
++from behave.tag_expression import TagExpression
++
+ 
+ has_combinations = hasattr(itertools, "combinations")
+ if has_combinations:
+@@ -31,6 +32,7 @@ if has_combinations:
+             return "@" + " @".join(tags)
+         return NO_TAGS
+ 
++
+     TestCase = object
+     # ----------------------------------------------------------------------------
+     # TEST: all_combinations() test helper
+@@ -45,8 +47,8 @@ if has_combinations:
+                 ('@one', '@two'),
+             ]
+             actual = all_combinations(items)
+-            tools.eq_(actual, expected)
+-            tools.eq_(len(actual), 4)
++            assert actual == expected
++            assert len(actual) == 4
+ 
+         def test_all_combinations_with_3values(self):
+             items = "@one @two @three".split()
+@@ -61,8 +63,8 @@ if has_combinations:
+                 ('@one', '@two', '@three'),
+             ]
+             actual = all_combinations(items)
+-            tools.eq_(actual, expected)
+-            tools.eq_(len(actual), 8)
++            assert actual == expected
++            assert len(actual) == 8
+ 
+ 
+     # ----------------------------------------------------------------------------
+@@ -74,13 +76,13 @@ if has_combinations:
+                                           tag_combinations, expected):
+             matched = [ make_tags_line(c) for c in tag_combinations
+                                 if tag_expression.check(c) ]
+-            tools.eq_(matched, expected)
++            assert matched == expected
+ 
+         def assert_tag_expression_mismatches(self, tag_expression,
+                                             tag_combinations, expected):
+             mismatched = [ make_tags_line(c) for c in tag_combinations
+                                 if not tag_expression.check(c) ]
+-            tools.eq_(mismatched, expected)
++            assert mismatched == expected
+ 
+ 
+     class TestTagExpressionWith1Term(TagExpressionTestCase):
+diff --git a/test/test_ansi_escapes.py b/tests/unit/test_ansi_escapes.py
+similarity index 84%
+rename from test/test_ansi_escapes.py
+rename to tests/unit/test_ansi_escapes.py
+index 77564fd..969f3a9 100644
+--- a/test/test_ansi_escapes.py
++++ b/tests/unit/test_ansi_escapes.py
+@@ -7,7 +7,7 @@
+ #   W0621   Redefining name ... from outer scope
+ 
+ from __future__ import absolute_import
+-from nose import tools
++import pytest
+ from behave.formatter import ansi_escapes
+ import unittest
+ from six.moves import range
+@@ -44,30 +44,30 @@ class StripEscapesTest(unittest.TestCase):
+ 
+     def test_should_return_same_text_without_escapes(self):
+         for text in self.TEXTS:
+-            tools.eq_(text, ansi_escapes.strip_escapes(text))
++            assert text == ansi_escapes.strip_escapes(text)
+ 
+     def test_should_return_empty_string_for_any_ansi_escape(self):
+         # XXX-JE-CHECK-PY23: If list() is really needed.
+         for text in list(ansi_escapes.colors.values()):
+-            tools.eq_("", ansi_escapes.strip_escapes(text))
++            assert "" == ansi_escapes.strip_escapes(text)
+         for text in list(ansi_escapes.escapes.values()):
+-            tools.eq_("", ansi_escapes.strip_escapes(text))
++            assert "" == ansi_escapes.strip_escapes(text)
+ 
+ 
+     def test_should_strip_color_escapes_from_text(self):
+         for text in self.TEXTS:
+             colored_text = self.colorize_text(text, self.ALL_COLORS)
+-            tools.eq_(text, ansi_escapes.strip_escapes(colored_text))
++            assert text == ansi_escapes.strip_escapes(colored_text)
+             self.assertNotEqual(text, colored_text)
+ 
+             for color in self.ALL_COLORS:
+                 colored_text = self.colorize(text, color)
+-                tools.eq_(text, ansi_escapes.strip_escapes(colored_text))
++                assert text == ansi_escapes.strip_escapes(colored_text)
+                 self.assertNotEqual(text, colored_text)
+ 
+     def test_should_strip_cursor_up_escapes_from_text(self):
+         for text in self.TEXTS:
+             for cursor_up in self.CURSOR_UPS:
+                 colored_text = cursor_up + text + ansi_escapes.escapes["reset"]
+-                tools.eq_(text, ansi_escapes.strip_escapes(colored_text))
++                assert text == ansi_escapes.strip_escapes(colored_text)
+                 self.assertNotEqual(text, colored_text)
+diff --git a/test/test_configuration.py b/tests/unit/test_configuration.py
+similarity index 72%
+rename from test/test_configuration.py
+rename to tests/unit/test_configuration.py
+index e6828e3..c96cf63 100644
+--- a/test/test_configuration.py
++++ b/tests/unit/test_configuration.py
+@@ -2,7 +2,7 @@ import os.path
+ import sys
+ import tempfile
+ import six
+-from nose.tools import *
++import pytest
+ from behave import configuration
+ from behave.configuration import Configuration, UserData
+ from unittest import TestCase
+@@ -36,6 +36,7 @@ if sys.platform.startswith("win"):
+         ROOTDIR_PREFIX_DEFAULT = ROOTDIR_PREFIX_DEFAULT.lower()
+     ROOTDIR_PREFIX = os.environ.get("BEHAVE_ROOTDIR_PREFIX", ROOTDIR_PREFIX_DEFAULT)
+ 
++
+ class TestConfiguration(object):
+ 
+     def test_read_file(self):
+@@ -46,19 +47,19 @@ class TestConfiguration(object):
+ 
+         # -- WINDOWS-REQUIRES: normpath
+         d = configuration.read_configuration(tn)
+-        eq_(d["outfiles"], [
++        assert d["outfiles"] ==[
+             os.path.normpath(ROOTDIR_PREFIX + "/absolute/path1"),
+             os.path.normpath(os.path.join(tndir, "relative/path2")),
+-        ])
+-        eq_(d["paths"], [
++        ]
++        assert d["paths"] == [
+             os.path.normpath(ROOTDIR_PREFIX + "/absolute/path3"),
+             os.path.normpath(os.path.join(tndir, "relative/path4")),
+-            ])
+-        eq_(d["format"], ["pretty", "tag-counter"])
+-        eq_(d["default_tags"], ["@foo,~@bar", "@zap"])
+-        eq_(d["stdout_capture"], False)
+-        ok_("bogus" not in d)
+-        eq_(d["userdata"], {"foo": "bar", "answer": "42"})
++            ]
++        assert d["format"] == ["pretty", "tag-counter"]
++        assert d["default_tags"] == ["@foo,~@bar", "@zap"]
++        assert d["stdout_capture"] == False
++        assert "bogus" not in d
++        assert d["userdata"] == {"foo": "bar", "answer": "42"}
+ 
+     def ensure_stage_environment_is_not_set(self):
+         if "BEHAVE_STAGE" in os.environ:
+@@ -69,26 +70,26 @@ class TestConfiguration(object):
+         self.ensure_stage_environment_is_not_set()
+         assert "BEHAVE_STAGE" not in os.environ
+         config = Configuration("")
+-        eq_("steps", config.steps_dir)
+-        eq_("environment.py", config.environment_file)
++        assert "steps" == config.steps_dir
++        assert "environment.py" == config.environment_file
+ 
+     def test_settings_with_stage(self):
+         config = Configuration(["--stage=STAGE1"])
+-        eq_("STAGE1_steps", config.steps_dir)
+-        eq_("STAGE1_environment.py", config.environment_file)
++        assert "STAGE1_steps" == config.steps_dir
++        assert "STAGE1_environment.py" == config.environment_file
+ 
+     def test_settings_with_stage_and_envvar(self):
+         os.environ["BEHAVE_STAGE"] = "STAGE2"
+         config = Configuration(["--stage=STAGE1"])
+-        eq_("STAGE1_steps", config.steps_dir)
+-        eq_("STAGE1_environment.py", config.environment_file)
++        assert "STAGE1_steps" == config.steps_dir
++        assert "STAGE1_environment.py" == config.environment_file
+         del os.environ["BEHAVE_STAGE"]
+ 
+     def test_settings_with_stage_from_envvar(self):
+         os.environ["BEHAVE_STAGE"] = "STAGE2"
+         config = Configuration("")
+-        eq_("STAGE2_steps", config.steps_dir)
+-        eq_("STAGE2_environment.py", config.environment_file)
++        assert "STAGE2_steps" == config.steps_dir
++        assert "STAGE2_environment.py" == config.environment_file
+         del os.environ["BEHAVE_STAGE"]
+ 
+ 
+@@ -101,33 +102,33 @@ class TestConfigurationUserData(TestCase):
+             "--define=bar=bar_value",
+             "--define", "baz=BAZ_VALUE",
+         ])
+-        eq_("foo_value", config.userdata["foo"])
+-        eq_("bar_value", config.userdata["bar"])
+-        eq_("BAZ_VALUE", config.userdata["baz"])
++        assert "foo_value" == config.userdata["foo"]
++        assert "bar_value" == config.userdata["bar"]
++        assert "BAZ_VALUE" == config.userdata["baz"]
+ 
+     def test_cmdline_defines_override_configfile(self):
+         userdata_init = {"foo": "XXX", "bar": "ZZZ", "baz": 42}
+         config = Configuration(
+                     "-D foo=foo_value --define bar=123",
+                     load_config=False, userdata=userdata_init)
+-        eq_("foo_value", config.userdata["foo"])
+-        eq_("123", config.userdata["bar"])
+-        eq_(42, config.userdata["baz"])
++        assert "foo_value" == config.userdata["foo"]
++        assert "123" == config.userdata["bar"]
++        assert 42 == config.userdata["baz"]
+ 
+     def test_cmdline_defines_without_value_are_true(self):
+         config = Configuration("-D foo --define bar -Dbaz")
+-        eq_("true", config.userdata["foo"])
+-        eq_("true", config.userdata["bar"])
+-        eq_("true", config.userdata["baz"])
+-        eq_(True, config.userdata.getbool("foo"))
++        assert "true" == config.userdata["foo"]
++        assert "true" == config.userdata["bar"]
++        assert "true" == config.userdata["baz"]
++        assert True == config.userdata.getbool("foo")
+ 
+     def test_cmdline_defines_with_empty_value(self):
+         config = Configuration("-D foo=")
+-        eq_("", config.userdata["foo"])
++        assert "" == config.userdata["foo"]
+ 
+     def test_cmdline_defines_with_assign_character_as_value(self):
+         config = Configuration("-D foo=bar=baz")
+-        eq_("bar=baz", config.userdata["foo"])
++        assert "bar=baz" == config.userdata["foo"]
+ 
+     def test_cmdline_defines__with_quoted_name_value_pair(self):
+         cmdlines = [
+@@ -136,7 +137,7 @@ class TestConfigurationUserData(TestCase):
+         ]
+         for cmdline in cmdlines:
+             config = Configuration(cmdline, load_config=False)
+-            eq_(config.userdata, dict(person="Alice and Bob"))
++            assert config.userdata == dict(person="Alice and Bob")
+ 
+     def test_cmdline_defines__with_quoted_value(self):
+         cmdlines = [
+@@ -145,7 +146,7 @@ class TestConfigurationUserData(TestCase):
+         ]
+         for cmdline in cmdlines:
+             config = Configuration(cmdline, load_config=False)
+-            eq_(config.userdata, dict(person="Alice and Bob"))
++            assert config.userdata == dict(person="Alice and Bob")
+ 
+     def test_setup_userdata(self):
+         config = Configuration("", load_config=False)
+@@ -154,7 +155,7 @@ class TestConfigurationUserData(TestCase):
+         config.setup_userdata()
+ 
+         expected_data = dict(person1="Alice", person2="Charly")
+-        eq_(config.userdata, expected_data)
++        assert config.userdata == expected_data
+ 
+     def test_update_userdata__with_cmdline_defines(self):
+         # -- NOTE: cmdline defines are reapplied.
+@@ -163,8 +164,8 @@ class TestConfigurationUserData(TestCase):
+         config.update_userdata(dict(person1="Alice", person2="Bob"))
+ 
+         expected_data = dict(person1="Alice", person2="Bea", person3="Charly")
+-        eq_(config.userdata, expected_data)
+-        eq_(config.userdata_defines, [("person2", "Bea")])
++        assert config.userdata == expected_data
++        assert config.userdata_defines == [("person2", "Bea")]
+ 
+     def test_update_userdata__without_cmdline_defines(self):
+         config = Configuration("", load_config=False)
+@@ -172,5 +173,5 @@ class TestConfigurationUserData(TestCase):
+         config.update_userdata(dict(person1="Alice", person2="Bob"))
+ 
+         expected_data = dict(person1="Alice", person2="Bob", person3="Charly")
+-        eq_(config.userdata, expected_data)
+-        self.assertFalse(config.userdata_defines)
++        assert config.userdata == expected_data
++        assert config.userdata_defines is None
+diff --git a/test/test_formatter.py b/tests/unit/test_formatter.py
+similarity index 94%
+rename from test/test_formatter.py
+rename to tests/unit/test_formatter.py
+index 42e5f0d..c1a0945 100644
+--- a/test/test_formatter.py
++++ b/tests/unit/test_formatter.py
+@@ -6,9 +6,8 @@ import sys
+ import tempfile
+ import unittest
+ import six
++import pytest
+ from mock import Mock, patch
+-from nose.tools import *    # pylint: disable=wildcard-import, unused-wildcard-import
+-
+ from behave.formatter._registry import make_formatters
+ from behave.formatter import pretty
+ from behave.formatter.base import StreamOpener
+@@ -35,7 +34,7 @@ class TestGetTerminalSize(unittest.TestCase):
+         platform = sys.platform
+         sys.platform = "windows"
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+ 
+         sys.platform = platform
+ 
+@@ -46,7 +45,7 @@ class TestGetTerminalSize(unittest.TestCase):
+         except ImportError:
+             pass
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+ 
+     def test_exception_in_ioctl(self):
+         try:
+@@ -59,7 +58,7 @@ class TestGetTerminalSize(unittest.TestCase):
+ 
+         self.ioctl.side_effect = raiser
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+         self.ioctl.assert_called_with(0, termios.TIOCGWINSZ, self.zero_struct)
+ 
+     def test_happy_path(self):
+@@ -70,7 +69,7 @@ class TestGetTerminalSize(unittest.TestCase):
+ 
+         self.ioctl.return_value = struct.pack("HHHH", 17, 23, 5, 5)
+ 
+-        eq_(pretty.get_terminal_size(), (23, 17))
++        assert pretty.get_terminal_size() == (23, 17)
+         self.ioctl.assert_called_with(0, termios.TIOCGWINSZ, self.zero_struct)
+ 
+     def test_zero_size_fallback(self):
+@@ -81,7 +80,7 @@ class TestGetTerminalSize(unittest.TestCase):
+ 
+         self.ioctl.return_value = self.zero_struct
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+         self.ioctl.assert_called_with(0, termios.TIOCGWINSZ, self.zero_struct)
+ 
+ 
+@@ -204,7 +203,7 @@ class TestTagsCount(FormatterTests):
+         p.feature(f)
+         p.scenario(s)
+ 
+-        eq_(p.tag_counts, {"ham": [f, s], "spam": [f], "foo": [s]})
++        assert p.tag_counts == {"ham": [f, s], "spam": [f], "foo": [s]}
+ 
+ 
+ class MultipleFormattersTests(FormatterTests):
+diff --git a/test/test_formatter_progress.py b/tests/unit/test_formatter_progress.py
+similarity index 99%
+rename from test/test_formatter_progress.py
+rename to tests/unit/test_formatter_progress.py
+index 29c8e68..19cdf64 100644
+--- a/test/test_formatter_progress.py
++++ b/tests/unit/test_formatter_progress.py
+@@ -9,6 +9,7 @@ from __future__ import absolute_import
+ from .test_formatter import FormatterTests as FormatterTest
+ from .test_formatter import MultipleFormattersTests as MultipleFormattersTest
+ 
++
+ class TestScenarioProgressFormatter(FormatterTest):
+     formatter_name = "progress"
+ 
+@@ -20,20 +21,26 @@ class TestStepProgressFormatter(FormatterTest):
+ class TestPrettyAndScenarioProgress(MultipleFormattersTest):
+     formatters = ['pretty', 'progress']
+ 
++
+ class TestPlainAndScenarioProgress(MultipleFormattersTest):
+     formatters = ['plain', 'progress']
+ 
++
+ class TestJSONAndScenarioProgress(MultipleFormattersTest):
+     formatters = ['json', 'progress']
+ 
++
+ class TestPrettyAndStepProgress(MultipleFormattersTest):
+     formatters = ['pretty', 'progress2']
+ 
++
+ class TestPlainAndStepProgress(MultipleFormattersTest):
+     formatters = ['plain', 'progress2']
+ 
++
+ class TestJSONAndStepProgress(MultipleFormattersTest):
+     formatters = ['json', 'progress2']
+ 
++
+ class TestScenarioProgressAndStepProgress(MultipleFormattersTest):
+     formatters = ['progress', 'progress2']
+diff --git a/test/test_formatter_rerun.py b/tests/unit/test_formatter_rerun.py
+similarity index 94%
+rename from test/test_formatter_rerun.py
+rename to tests/unit/test_formatter_rerun.py
+index 6357f92..154588f 100644
+--- a/test/test_formatter_rerun.py
++++ b/tests/unit/test_formatter_rerun.py
+@@ -8,7 +8,7 @@ from __future__ import absolute_import
+ from behave.model_core import Status
+ from .test_formatter import FormatterTests as FormatterTest, _tf
+ from .test_formatter import MultipleFormattersTests as MultipleFormattersTest
+-from nose.tools import *
++
+ 
+ class TestRerunFormatter(FormatterTest):
+     formatter_name = "rerun"
+@@ -26,7 +26,7 @@ class TestRerunFormatter(FormatterTest):
+             p.scenario(scenario)
+             assert scenario.status == Status.passed
+         p.eof()
+-        eq_([], p.failed_scenarios)
++        assert [] == p.failed_scenarios
+         # -- EMIT REPORT:
+         p.close()
+ 
+@@ -49,7 +49,7 @@ class TestRerunFormatter(FormatterTest):
+         assert scenarios[0].status == Status.passed
+         assert scenarios[1].status == Status.failed
+         p.eof()
+-        eq_([ failing_scenario ], p.failed_scenarios)
++        assert [ failing_scenario ] == p.failed_scenarios
+         # -- EMIT REPORT:
+         p.close()
+ 
+@@ -76,7 +76,7 @@ class TestRerunFormatter(FormatterTest):
+         assert scenarios[1].status == Status.passed
+         assert scenarios[2].status == Status.failed
+         p.eof()
+-        eq_([ failing_scenario1, failing_scenario2 ], p.failed_scenarios)
++        assert [ failing_scenario1, failing_scenario2 ] == p.failed_scenarios
+         # -- EMIT REPORT:
+         p.close()
+ 
+@@ -84,14 +84,18 @@ class TestRerunFormatter(FormatterTest):
+ class TestRerunAndPrettyFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "pretty"]
+ 
++
+ class TestRerunAndPlainFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "plain"]
+ 
++
+ class TestRerunAndScenarioProgressFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "progress"]
+ 
++
+ class TestRerunAndStepProgressFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "progress2"]
+ 
++
+ class TestRerunAndJsonFormatter(MultipleFormattersTest):
+     formatters = ["rerun", "json"]
+diff --git a/test/test_formatter_tags.py b/tests/unit/test_formatter_tags.py
+similarity index 99%
+rename from test/test_formatter_tags.py
+rename to tests/unit/test_formatter_tags.py
+index 5125d51..9f95374 100644
+--- a/test/test_formatter_tags.py
++++ b/tests/unit/test_formatter_tags.py
+@@ -9,12 +9,14 @@ from __future__ import absolute_import
+ from .test_formatter import FormatterTests as FormatterTest
+ from .test_formatter import MultipleFormattersTests as MultipleFormattersTest
+ 
++
+ # -----------------------------------------------------------------------------
+ # FORMATTER TESTS: With TagCountFormatter
+ # -----------------------------------------------------------------------------
+ class TestTagsCountFormatter(FormatterTest):
+     formatter_name = "tags"
+ 
++
+ # -----------------------------------------------------------------------------
+ # FORMATTER TESTS: With TagLocationFormatter
+ # -----------------------------------------------------------------------------
+@@ -28,12 +30,15 @@ class TestTagsLocationFormatter(FormatterTest):
+ class TestPrettyAndTagsCount(MultipleFormattersTest):
+     formatters = ["pretty", "tags"]
+ 
++
+ class TestPlainAndTagsCount(MultipleFormattersTest):
+     formatters = ["plain", "tags"]
+ 
++
+ class TestJSONAndTagsCount(MultipleFormattersTest):
+     formatters = ["json", "tags"]
+ 
++
+ class TestRerunAndTagsCount(MultipleFormattersTest):
+     formatters = ["rerun", "tags"]
+ 
+@@ -44,14 +49,18 @@ class TestRerunAndTagsCount(MultipleFormattersTest):
+ class TestPrettyAndTagsLocation(MultipleFormattersTest):
+     formatters = ["pretty", "tags.location"]
+ 
++
+ class TestPlainAndTagsLocation(MultipleFormattersTest):
+     formatters = ["plain", "tags.location"]
+ 
++
+ class TestJSONAndTagsLocation(MultipleFormattersTest):
+     formatters = ["json", "tags.location"]
+ 
++
+ class TestRerunAndTagsLocation(MultipleFormattersTest):
+     formatters = ["rerun", "tags.location"]
+ 
++
+ class TestTagsCountAndTagsLocation(MultipleFormattersTest):
+     formatters = ["tags", "tags.location"]
+diff --git a/tests/unit/test_importer.py b/tests/unit/test_importer.py
+index f3f4e2c..055b9fb 100644
+--- a/tests/unit/test_importer.py
++++ b/tests/unit/test_importer.py
+@@ -62,7 +62,7 @@ class TestLoadModule(object):
+         self.theory.assert_module_is_imported(module_name)
+ 
+     def test_load_module__should_succeed_for_existing_module(self):
+-        module_name = "test._importer_candidate"
++        module_name = "tests.unit._importer_candidate"
+         self.theory.ensure_module_is_not_imported(module_name)
+ 
+         module = load_module(module_name)
+diff --git a/test/test_log_capture.py b/tests/unit/test_log_capture.py
+similarity index 87%
+rename from test/test_log_capture.py
+rename to tests/unit/test_log_capture.py
+index bfdbed7..bf1874c 100644
+--- a/test/test_log_capture.py
++++ b/tests/unit/test_log_capture.py
+@@ -1,11 +1,10 @@
+ from __future__ import absolute_import, with_statement
+-
+-from nose.tools import *
++import pytest
+ from mock import patch
+-
+ from behave.log_capture import LoggingCapture
+ from six.moves import range
+ 
++
+ class TestLogCapture(object):
+     def test_get_value_returns_all_log_records(self):
+         class FakeConfig(object):
+@@ -23,7 +22,7 @@ class TestLogCapture(object):
+             format.return_value = 'foo'
+             expected = '\n'.join(['foo'] * len(fake_records))
+ 
+-            eq_(handler.getvalue(), expected)
++            assert handler.getvalue() == expected
+ 
+             calls = [args[0][0] for args in format.call_args_list]
+-            eq_(calls, fake_records)
++            assert calls == fake_records
+diff --git a/test/test_matchers.py b/tests/unit/test_matchers.py
+similarity index 93%
+rename from test/test_matchers.py
+rename to tests/unit/test_matchers.py
+index bfe04fc..815581c 100644
+--- a/test/test_matchers.py
++++ b/tests/unit/test_matchers.py
+@@ -1,7 +1,7 @@
+ # -*- coding: UTF-8 -*-
+ from __future__ import absolute_import, with_statement
++import pytest
+ from mock import Mock, patch
+-from nose.tools import *  # pylint: disable=wildcard-import, unused-wildcard-import
+ import parse
+ from behave.matchers import Match, Matcher, ParseMatcher, RegexMatcher, \
+     SimplifiedRegexMatcher, CucumberRegexMatcher
+@@ -80,7 +80,7 @@ class TestParseMatcher(object):
+             assert m.func is func
+             args = m.arguments
+             have = [(a.start, a.end, a.original, a.value, a.name) for a in args]
+-            eq_(have, expected)
++            assert have == expected
+ 
+     def test_named_arguments(self):
+         text = "has a {string}, an {integer:d} and a {decimal:f}"
+@@ -89,11 +89,11 @@ class TestParseMatcher(object):
+ 
+         m = matcher.match("has a foo, an 11 and a 3.14159")
+         m.run(context)
+-        eq_(self.recorded_args, ((context,), {
++        assert self.recorded_args, ((context,) == {
+             'string': 'foo',
+             'integer': 11,
+             'decimal': 3.14159
+-        }))
++        })
+ 
+     def test_positional_arguments(self):
+         text = "has a {}, an {:d} and a {:f}"
+@@ -102,7 +102,7 @@ class TestParseMatcher(object):
+ 
+         m = matcher.match("has a foo, an 11 and a 3.14159")
+         m.run(context)
+-        eq_(self.recorded_args, ((context, 'foo', 11, 3.14159), {}))
++        assert self.recorded_args == ((context, 'foo', 11, 3.14159), {})
+ 
+ class TestRegexMatcher(object):
+     # pylint: disable=invalid-name, no-self-use
+@@ -151,7 +151,7 @@ class TestRegexMatcher(object):
+         assert m.func is func
+         args = m.arguments
+         have = [(a.start, a.end, a.original, a.value, a.name) for a in args]
+-        eq_(have, expected)
++        assert have == expected
+ 
+ 
+ 
+@@ -179,17 +179,17 @@ class TestSimplifiedRegexMatcher(TestRegexMatcher):
+         assert isinstance(matched1, Match)
+         assert isinstance(matched2, Match)
+ 
+-    @raises(AssertionError)
+     def test_step_should_not_use_regex_begin_marker(self):
+-        SimplifiedRegexMatcher(None, "^I do something")
++        with pytest.raises(AssertionError):
++            SimplifiedRegexMatcher(None, "^I do something")
+ 
+-    @raises(AssertionError)
+     def test_step_should_not_use_regex_end_marker(self):
+-        SimplifiedRegexMatcher(None, "I do something$")
++        with pytest.raises(AssertionError):
++            SimplifiedRegexMatcher(None, "I do something$")
+ 
+-    @raises(AssertionError)
+     def test_step_should_not_use_regex_begin_and_end_marker(self):
+-        SimplifiedRegexMatcher(None, "^I do something$")
++        with pytest.raises(AssertionError):
++            SimplifiedRegexMatcher(None, "^I do something$")
+ 
+ 
+ class TestCucumberRegexMatcher(TestRegexMatcher):
+diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py
+index 5603a4b..ecbb1bf 100644
+--- a/tests/unit/test_parser.py
++++ b/tests/unit/test_parser.py
+@@ -7,7 +7,6 @@ Unit tests for Gherkin parser: :mod:`behave.parser`.
+ from __future__ import absolute_import, print_function
+ import pytest
+ from behave import i18n, model, parser
+-# NOT-NEEDED: from nose.tools import *
+ 
+ 
+ # ---------------------------------------------------------------------------
+diff --git a/test/test_runner.py b/tests/unit/test_runner.py
+similarity index 82%
+rename from test/test_runner.py
+rename to tests/unit/test_runner.py
+index 6647283..030dffa 100644
+--- a/test/test_runner.py
++++ b/tests/unit/test_runner.py
+@@ -11,10 +11,8 @@ import tempfile
+ import unittest
+ import six
+ from six import StringIO
+-
++import pytest
+ from mock import Mock, patch
+-from nose.tools import *  # pylint: disable=wildcard-import, unused-wildcard-import
+-
+ from behave import runner_util
+ from behave.model import Table
+ from behave.step_registry import StepRegistry
+@@ -39,31 +37,31 @@ class TestContext(unittest.TestCase):
+     def test_user_mode_shall_restore_behave_mode(self):
+         # -- CASE: No exception is raised.
+         initial_mode = runner.Context.BEHAVE
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+         with self.context.use_with_user_mode():
+-            eq_(self.context._mode, runner.Context.USER)
++            assert self.context._mode == runner.Context.USER
+             self.context.thing = "stuff"
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_assert_fails(self):
+         initial_mode = runner.Context.BEHAVE
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                eq_(self.context._mode, runner.Context.USER)
++                assert self.context._mode == runner.Context.USER
+                 assert False, "XFAIL"
+         except AssertionError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_exception_is_raised(self):
+         initial_mode = runner.Context.BEHAVE
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                eq_(self.context._mode, runner.Context.USER)
++                assert self.context._mode == runner.Context.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_use_with_user_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+@@ -71,9 +69,9 @@ class TestContext(unittest.TestCase):
+         initial_mode = runner.Context.BEHAVE
+         self.context._mode = initial_mode
+         with self.context.use_with_user_mode():
+-            eq_(self.context._mode, runner.Context.USER)
++            assert self.context._mode == runner.Context.USER
+             self.context.thing = "stuff"
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+ 
+     def test_use_with_user_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+@@ -82,10 +80,10 @@ class TestContext(unittest.TestCase):
+         self.context._mode = initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                eq_(self.context._mode, runner.Context.USER)
++                assert self.context._mode == runner.Context.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_use_with_behave_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+@@ -93,9 +91,9 @@ class TestContext(unittest.TestCase):
+         initial_mode = runner.Context.USER
+         self.context._mode = initial_mode
+         with self.context._use_with_behave_mode():
+-            eq_(self.context._mode, runner.Context.BEHAVE)
++            assert self.context._mode == runner.Context.BEHAVE
+             self.context.thing = "stuff"
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+ 
+     def test_use_with_behave_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+@@ -104,22 +102,22 @@ class TestContext(unittest.TestCase):
+         self.context._mode = initial_mode
+         try:
+             with self.context._use_with_behave_mode():
+-                eq_(self.context._mode, runner.Context.BEHAVE)
++                assert self.context._mode == runner.Context.BEHAVE
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_context_contains(self):
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+         self.context.thing = "stuff"
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+         self.context._push()
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+ 
+     def test_attribute_set_at_upper_level_visible_at_lower_level(self):
+         self.context.thing = "stuff"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
++        assert self.context.thing == "stuff"
+ 
+     def test_attribute_set_at_lower_level_not_visible_at_upper_level(self):
+         self.context._push()
+@@ -130,16 +128,16 @@ class TestContext(unittest.TestCase):
+     def test_attributes_set_at_upper_level_visible_at_lower_level(self):
+         self.context.thing = "stuff"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
++        assert self.context.thing == "stuff"
+         self.context.other_thing = "more stuff"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
+         self.context.third_thing = "wombats"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
+-        eq_(self.context.third_thing, "wombats")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
++        assert self.context.third_thing == "wombats"
+ 
+     def test_attributes_set_at_lower_level_not_visible_at_upper_level(self):
+         self.context.thing = "stuff"
+@@ -149,17 +147,17 @@ class TestContext(unittest.TestCase):
+ 
+         self.context._push()
+         self.context.third_thing = "wombats"
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
+-        eq_(self.context.third_thing, "wombats")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
++        assert self.context.third_thing == "wombats"
+ 
+         self.context._pop()
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
+         assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
+ 
+         self.context._pop()
+-        eq_(self.context.thing, "stuff")
++        assert self.context.thing == "stuff"
+         assert getattr(self.context, "other_thing", None) is None, "%s is not None" % self.context.other_thing
+         assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
+ 
+@@ -270,21 +268,22 @@ class TestContext(unittest.TestCase):
+         assert filename in info, "%r not in %r" % (filename, info)
+ 
+     def test_context_deletable(self):
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+         self.context.thing = "stuff"
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+         del self.context.thing
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+ 
+-    @raises(AttributeError)
++    # OLD: @raises(AttributeError)
+     def test_context_deletable_raises(self):
+         # pylint: disable=protected-access
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+         self.context.thing = "stuff"
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+         self.context._push()
+-        eq_("thing" in self.context, True)
+-        del self.context.thing
++        assert "thing" in self.context
++        with pytest.raises(AttributeError):
++            del self.context.thing
+ 
+ 
+ class ExampleSteps(object):
+@@ -362,7 +361,7 @@ Then a step passes
+ """.lstrip()
+         with patch("behave.step_registry.registry", self.step_registry):
+             result = self.context.execute_steps(doc)
+-            eq_(result, True)
++            assert result is True
+ 
+     def test_execute_steps_with_failing_step(self):
+         doc = u"""
+@@ -374,7 +373,7 @@ Then a step passes
+             try:
+                 result = self.context.execute_steps(doc)
+             except AssertionError as e:
+-                ok_("FAILED SUB-STEP: When a step fails" in _text(e))
++                assert "FAILED SUB-STEP: When a step fails" in _text(e)
+ 
+     def test_execute_steps_with_undefined_step(self):
+         doc = u"""
+@@ -386,7 +385,7 @@ Then a step passes
+             try:
+                 result = self.context.execute_steps(doc)
+             except AssertionError as e:
+-                ok_("UNDEFINED SUB-STEP: When a step is undefined" in _text(e))
++                assert "UNDEFINED SUB-STEP: When a step is undefined" in _text(e)
+ 
+     def test_execute_steps_with_text(self):
+         doc = u'''
+@@ -401,8 +400,8 @@ Then a step passes
+         with patch("behave.step_registry.registry", self.step_registry):
+             result = self.context.execute_steps(doc)
+             expected_text = "Lorem ipsum\nIpsum lorem"
+-            eq_(result, True)
+-            eq_(expected_text, ExampleSteps.text)
++            assert result is True
++            assert expected_text == ExampleSteps.text
+ 
+     def test_execute_steps_with_table(self):
+         doc = u"""
+@@ -419,8 +418,8 @@ Then a step passes
+                     [u"Alice", u"12"],
+                     [u"Bob",   u"23"],
+             ])
+-            eq_(result, True)
+-            eq_(expected_table, ExampleSteps.table)
++            assert result is True
++            assert expected_table == ExampleSteps.table
+ 
+     def test_context_table_is_restored_after_execute_steps_without_table(self):
+         doc = u"""
+@@ -431,7 +430,7 @@ Then a step passes
+             original_table = "<ORIGINAL_TABLE>"
+             self.context.table = original_table
+             self.context.execute_steps(doc)
+-            eq_(self.context.table, original_table)
++            assert self.context.table == original_table
+ 
+     def test_context_table_is_restored_after_execute_steps_with_table(self):
+         doc = u"""
+@@ -445,7 +444,7 @@ Then a step passes
+             original_table = "<ORIGINAL_TABLE>"
+             self.context.table = original_table
+             self.context.execute_steps(doc)
+-            eq_(self.context.table, original_table)
++            assert self.context.table == original_table
+ 
+     def test_context_text_is_restored_after_execute_steps_without_text(self):
+         doc = u"""
+@@ -456,7 +455,7 @@ Then a step passes
+             original_text = "<ORIGINAL_TEXT>"
+             self.context.text = original_text
+             self.context.execute_steps(doc)
+-            eq_(self.context.text, original_text)
++            assert self.context.text == original_text
+ 
+     def test_context_text_is_restored_after_execute_steps_with_text(self):
+         doc = u'''
+@@ -471,10 +470,10 @@ When a step with text:
+             original_text = "<ORIGINAL_TEXT>"
+             self.context.text = original_text
+             self.context.execute_steps(doc)
+-            eq_(self.context.text, original_text)
++            assert self.context.text == original_text
+ 
+ 
+-    @raises(ValueError)
++    # OLD: @raises(ValueError)
+     def test_execute_steps_should_fail_when_called_without_feature(self):
+         doc = u"""
+ Given a passes
+@@ -482,7 +481,8 @@ Then a step passes
+ """.lstrip()
+         with patch("behave.step_registry.registry", self.step_registry):
+             self.context.feature = None
+-            self.context.execute_steps(doc)
++            with pytest.raises(ValueError):
++                self.context.execute_steps(doc)
+ 
+ 
+ def create_mock_config():
+@@ -588,11 +588,11 @@ class TestRunner(object):
+         r.setup_capture()
+         r.start_capture()
+ 
+-        eq_(sys.stdout, r.capture_controller.stdout_capture)
++        assert sys.stdout == r.capture_controller.stdout_capture
+ 
+         r.stop_capture()
+ 
+-        eq_(sys.stdout, new_stdout)
++        assert sys.stdout == new_stdout
+ 
+         sys.stdout = old_stdout
+ 
+@@ -605,11 +605,11 @@ class TestRunner(object):
+ 
+         r.start_capture()
+ 
+-        eq_(sys.stdout, old_stdout)
++        assert sys.stdout == old_stdout
+ 
+         r.stop_capture()
+ 
+-        eq_(sys.stdout, old_stdout)
++        assert sys.stdout == old_stdout
+ 
+     def test_teardown_capture_removes_log_tap(self):
+         r = runner.Runner(Mock())
+@@ -633,7 +633,7 @@ class TestRunner(object):
+         # pylint: disable=too-many-format-args
+         assert "spam" in l, '"spam" variable not set in locals (%r)' % (g, l)
+         # pylint: enable=too-many-format-args
+-        eq_(l["spam"], fn)
++        assert l["spam"] == fn
+ 
+     def test_run_returns_true_if_everything_passed(self):
+         r = runner.Runner(Mock())
+@@ -694,11 +694,11 @@ class TestRunWithPaths(unittest.TestCase):
+         self.runner.context = Mock()
+         self.runner.run_with_paths()
+ 
+-        eq_(self.run_hook.call_args_list, [
++        assert self.run_hook.call_args_list == [
+             ((), {}),
+             (("before_all", self.runner.context), {}),
+             (("after_all", self.runner.context), {}),
+-        ])
++        ]
+ 
+     @patch("behave.parser.parse_file")
+     @patch("os.path.abspath")
+@@ -724,8 +724,8 @@ class TestRunWithPaths(unittest.TestCase):
+ 
+         expected_parse_file_args = \
+             [((x.upper(),), {"language": "fritz"}) for x in feature_locations]
+-        eq_(parse_file.call_args_list, expected_parse_file_args)
+-        eq_(self.runner.features, [feature] * 3)
++        assert parse_file.call_args_list == expected_parse_file_args
++        assert self.runner.features == [feature] * 3
+ 
+ 
+ class FsMock(object):
+@@ -829,9 +829,12 @@ class TestFeatureDirectory(object):
+ 
+         # will look for a "features" directory and not find one
+         with patch("os.path", fs):
+-            assert_raises(ConfigError, r.setup_paths)
++            with pytest.raises(ConfigError):
++                r.setup_paths()
++            # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        # ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+ 
+     def test_default_path_no_features(self):
+         config = create_mock_config()
+@@ -842,7 +845,9 @@ class TestFeatureDirectory(object):
+         fs = FsMock("features/steps/")
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+     def test_default_path(self):
+         config = create_mock_config()
+@@ -857,7 +862,7 @@ class TestFeatureDirectory(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        eq_(r.base_dir, os.path.abspath("features"))
++        assert r.base_dir == os.path.abspath("features")
+ 
+     def test_supplied_feature_file(self):
+         config = create_mock_config()
+@@ -872,10 +877,12 @@ class TestFeatureDirectory(object):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+                     r.setup_paths()
+-        ok_(("isdir", os.path.join(fs.base, "steps")) in fs.calls)
+-        ok_(("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "steps")) in fs.calls
++        assert ("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls
++        # OLD: ok_(("isdir", os.path.join(fs.base, "steps")) in fs.calls)
++        # OLD: ok_(("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls)
+ 
+-        eq_(r.base_dir, fs.base)
++        assert r.base_dir == fs.base
+ 
+     def test_supplied_feature_file_no_steps(self):
+         config = create_mock_config()
+@@ -888,7 +895,9 @@ class TestFeatureDirectory(object):
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+-                    assert_raises(ConfigError, r.setup_paths)
++                    with pytest.raises(ConfigError):
++                        r.setup_paths()
++                    # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+     def test_supplied_feature_directory(self):
+         config = create_mock_config()
+@@ -903,9 +912,10 @@ class TestFeatureDirectory(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls
++        # OLD ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
+ 
+-        eq_(r.base_dir, os.path.join(fs.base, "spam"))
++        assert r.base_dir == os.path.join(fs.base, "spam")
+ 
+     def test_supplied_feature_directory_no_steps(self):
+         config = create_mock_config()
+@@ -917,9 +927,12 @@ class TestFeatureDirectory(object):
+ 
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls
++        # OLD: ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
+ 
+     def test_supplied_feature_directory_missing(self):
+         config = create_mock_config()
+@@ -931,7 +944,9 @@ class TestFeatureDirectory(object):
+ 
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+ 
+ class TestFeatureDirectoryLayout2(object):
+@@ -955,7 +970,7 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        eq_(r.base_dir, os.path.abspath("features"))
++        assert r.base_dir == os.path.abspath("features")
+ 
+     def test_supplied_root_directory(self):
+         config = create_mock_config()
+@@ -975,8 +990,9 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+-        eq_(r.base_dir, os.path.join(fs.base, "features"))
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        assert r.base_dir == os.path.join(fs.base, "features")
+ 
+     def test_supplied_root_directory_no_steps(self):
+         config = create_mock_config()
+@@ -993,10 +1009,13 @@ class TestFeatureDirectoryLayout2(object):
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+-                    assert_raises(ConfigError, r.setup_paths)
++                    with pytest.raises(ConfigError):
++                        r.setup_paths()
++                    # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+-        eq_(r.base_dir, None)
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        assert r.base_dir is None
+ 
+ 
+     def test_supplied_feature_file(self):
+@@ -1018,9 +1037,11 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps"))  in fs.calls)
+-        ok_(("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls)
+-        eq_(r.base_dir, fs.join(fs.base, "features"))
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps"))  in fs.calls)
++        # OLD: ok_(("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps"))  in fs.calls
++        assert ("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls
++        assert r.base_dir == fs.join(fs.base, "features")
+ 
+     def test_supplied_feature_file_no_steps(self):
+         config = create_mock_config()
+@@ -1037,7 +1058,9 @@ class TestFeatureDirectoryLayout2(object):
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+-                    assert_raises(ConfigError, r.setup_paths)
++                    with pytest.raises(ConfigError):
++                        r.setup_paths()
++                    # OLD assert_raises(ConfigError, r.setup_paths)
+ 
+     def test_supplied_feature_directory(self):
+         config = create_mock_config()
+@@ -1057,8 +1080,9 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+-        eq_(r.base_dir, os.path.join(fs.base, "features"))
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        assert r.base_dir == os.path.join(fs.base, "features")
+ 
+ 
+     def test_supplied_feature_directory_no_steps(self):
+@@ -1075,6 +1099,9 @@ class TestFeatureDirectoryLayout2(object):
+ 
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
+diff --git a/test/test_step_registry.py b/tests/unit/test_step_registry.py
+similarity index 95%
+rename from test/test_step_registry.py
+rename to tests/unit/test_step_registry.py
+index f5b5a4d..6f85729 100644
+--- a/test/test_step_registry.py
++++ b/tests/unit/test_step_registry.py
+@@ -2,7 +2,6 @@
+ # pylint: disable=unused-wildcard-import
+ from __future__ import absolute_import, with_statement
+ from mock import Mock, patch
+-from nose.tools import *        # pylint: disable=wildcard-import
+ from six.moves import range     # pylint: disable=redefined-builtin
+ from behave import step_registry
+ 
+@@ -26,7 +25,7 @@ class TestStepRegistry(object):
+ 
+                 registry.add_step_definition(step_type.upper(), pattern, func)
+                 get_matcher.assert_called_with(func, pattern)
+-                eq_(l, [magic_object])
++                assert l == [magic_object]
+ 
+     def test_find_match_with_specific_step_type_also_searches_generic(self):
+         registry = step_registry.StepRegistry()
+@@ -80,7 +79,7 @@ class TestStepRegistry(object):
+ 
+         assert registry.find_match(step) is magic_object
+         for mock in step_defs[6:]:
+-            eq_(mock.match.call_count, 0)
++            assert mock.match.call_count == 0
+ 
+     # pylint: disable=line-too-long
+     @patch.object(step_registry.registry, 'add_step_definition')
+diff --git a/tests/unit/test_textutil.py b/tests/unit/test_textutil.py
+index e05e9ad..3ffab3c 100644
+--- a/tests/unit/test_textutil.py
++++ b/tests/unit/test_textutil.py
+@@ -9,6 +9,10 @@ import pytest
+ import codecs
+ import six
+ 
++
++pytest_version = pytest.__version__
++
++
+ # -----------------------------------------------------------------------------
+ # TEST SUPPORT:
+ # -----------------------------------------------------------------------------
+@@ -263,6 +267,7 @@ class TestObjectToTextConversion(object):
+         assert message in text2, "OOPS: text=%r" % text2
+ 
+     @requires_python2
++    @pytest.mark.skipif(pytest_version >= "5.0", reason="Fails with pytest 5.0")
+     @pytest.mark.parametrize("exception_class, message", [
+         (AssertionError, u"Ärgernis"),
+         (RuntimeError, u"Übermütig"),
+@@ -274,10 +279,15 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(exception_class) as e:
+             raise exception_class(bytes_message)
+ 
+-        text2 = text(e.value)
++        # -- REQUIRES: pytest < 5.0
++        # HINT: pytest >= 5.0 needs: text(e.value)
++        # NEW:  text2 = text(e.value)   # Causes problems w/ decoding and comparison.
++        assert isinstance(e.value, Exception)
++        text2 = text(e)
+         unicode_message = bytes_message.decode(self.ENCODING)
+         expected = u"%s: %s" % (exception_class.__name__, unicode_message)
+         assert isinstance(text2, six.text_type)
++        assert unicode_message in text2
+         assert text2.endswith(expected)
+         # -- DIAGNOSTICS:
+         print(u"text2: "+ text2)
+diff --git a/tox.ini b/tox.ini
+index 392bb39..d2fbce2 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -67,17 +67,11 @@ deps=
+ install_command = pip install -U {opts} {packages}
+ changedir = {toxinidir}
+ commands=
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
+-deps=
+-    pytest>=3.0
+-    pytest-html >= 1.19.0
+-    nose>=1.3
+-    mock>=2.0
+-    PyHamcrest>=1.9
+-    path.py >= 10.1
++deps= -r {toxinidir}/py.requirements/ci.tox.txt
+ setenv =
+      PYTHONPATH = {toxinidir}
+ 
+@@ -97,13 +91,12 @@ changedir = {envdir}
+ commands=
+     behave --version
+     {toxinidir}/bin/toxcmd.py copytree ../../behave4cmd0 .
+-    {toxinidir}/bin/toxcmd.py copytree ../../test .
+     {toxinidir}/bin/toxcmd.py copytree ../../tests .
+     {toxinidir}/bin/toxcmd.py copytree ../../features .
+     {toxinidir}/bin/toxcmd.py copytree ../../tools  .
+     {toxinidir}/bin/toxcmd.py copytree ../../issue.features .
+     {toxinidir}/bin/toxcmd.py copy ../../behave.ini .
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
+@@ -119,18 +112,16 @@ changedir = {envdir}
+ commands=
+     behave --version
+     {toxinidir}/bin/toxcmd.py copytree ../../behave4cmd0 .
+-    {toxinidir}/bin/toxcmd.py copytree ../../test .
+     {toxinidir}/bin/toxcmd.py copytree ../../tests .
+     {toxinidir}/bin/toxcmd.py copytree ../../features .
+     {toxinidir}/bin/toxcmd.py copytree ../../tools  .
+     {toxinidir}/bin/toxcmd.py copytree ../../issue.features .
+     {toxinidir}/bin/toxcmd.py copy ../../behave.ini .
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs behave4cmd0
+-    {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs test
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs tools
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs features
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs issue.features
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
+@@ -148,7 +139,7 @@ setenv =
+ [testenv:jy27]
+ basepython= jython
+ commands=
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch b/meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch
new file mode 100644
index 000000000..7fe451b2f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch
@@ -0,0 +1,22 @@
+From 2c886d201c19085ab52065d47e4f86a82a77f991 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 09:17:54 +0200
+Subject: [PATCH] FIX: Remove test/ from pytest run.
+
+---
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index fbc3520..c6027e0 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -35,7 +35,7 @@ install:
+ 
+ script:
+   - python --version
+-  - pytest test tests
++  - pytest tests
+   - behave -f progress --junit features/
+   - behave -f progress --junit tools/test-features/
+   - behave -f progress --junit issue.features/
diff --git a/meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch b/meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch
new file mode 100644
index 000000000..3e9a46a0c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch
@@ -0,0 +1,652 @@
+From 57a9cc0e1c99b0ed2ec5dbfd3fcfce456cfe13c8 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 09:50:46 +0200
+Subject: [PATCH] Select-by-location: Add support for "Scenario container"
+ (Feature, Rule, ScenarioOutline) (related to: #391)
+
+---
+ CHANGES.rst                                   |   2 +-
+ behave/model.py                               |  49 +++--
+ behave/runner_util.py                         | 186 +++++++++++++++++-
+ ....select_scenarios_by_file_location.feature |  27 ++-
+ pytest.ini                                    |   2 +-
+ tests/unit/test_runner_util.py                | 175 ++++++++++++++++
+ 6 files changed, 416 insertions(+), 25 deletions(-)
+ create mode 100644 tests/unit/test_runner_util.py
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 3d805b3..01bd1bd 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -28,7 +28,7 @@ ENHANCEMENTS:
+ * Use `cucumber-tag-expressions`_ with tag-matching extension (superceeds: old-style tag-expressions)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+-
++* Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+ 
+ PARTIALLY FIXED:
+ 
+diff --git a/behave/model.py b/behave/model.py
+index 3084850..7fc534a 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -55,11 +55,11 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+     .. attribute:: keyword
+ 
+        This is the keyword as seen in the *feature file*. In English this will
+-       be "Feature".
++       be "Feature" or "Rule".
+ 
+     .. attribute:: name
+ 
+-       The name of the feature (the text after "Feature".)
++       The name (or title) of the model entity (the text after the keyword.)
+ 
+     .. attribute:: description
+ 
+@@ -93,12 +93,16 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+        Status.untested
+          The feature was has not been completely tested yet.
++
+        Status.skipped
+-         One or more steps of this feature was passed over during testing.
++         The execution of this model entity (feature or rule)
++         should be / was skipped (excluded from the test run).
++
+        Status.passed
+-         The feature was tested successfully.
++         The model entity (feature or rule) was tested successfully.
++
+        Status.failed
+-         One or more steps of this feature failed.
++         One or more run items of this model entity failed.
+ 
+        .. versionchanged:: 1.2.6
+             Use Status enum class (was: string).
+@@ -147,6 +151,11 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         for run_item in self.run_items:
+             run_item.reset()
+ 
++    def _setup_context_for_run(self, context):
++        """Setup/Init runner context for run."""
++        # -- OVERRIDDEN: By derived classes.
++        pass
++
+     def __iter__(self):
+         return iter(self.run_items)
+ 
+@@ -204,7 +213,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         # feature_duration = self.run_endtime - self.run_starttime
+         return feature_duration
+ 
+-    def walk_scenarios(self, with_outlines=False):
++    def walk_scenarios(self, with_outlines=False, with_rules=False):
+         """Provides a flat list of all scenarios of this ScenarioContainer.
+         A ScenarioOutline element adds its scenarios to this list.
+         But the ScenarioOutline element itself is only added when specified.
+@@ -215,20 +224,20 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         :param with_outlines: If ScenarioOutline items should be added, too.
+         :return: List of all scenarios of this feature.
+         """
+-        # TODO: Better use self.run_items
+         all_scenarios = []
+-        # for scenario in self.scenarios:
+         for run_item in self.run_items:
+             if isinstance(run_item, Rule):
+                 rule = run_item
++                if with_rules:
++                    all_scenarios.append(rule)
+                 all_scenarios.extend(rule.walk_scenarios(with_outlines=with_outlines))
+-            if isinstance(run_item, ScenarioOutline):
++            elif isinstance(run_item, ScenarioOutline):
+                 scenario_outline = run_item
+                 if with_outlines:
+                     all_scenarios.append(scenario_outline)
+                 all_scenarios.extend(scenario_outline.scenarios)
+             else:
+-                assert isinstance(run_item, Scenario)
++                assert isinstance(run_item, Scenario), "OOPS: %r" % run_item
+                 all_scenarios.append(run_item)
+         return all_scenarios
+ 
+@@ -274,9 +283,9 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         assert self.status == Status.skipped or self.hook_failed
+ 
+     def skip(self, reason=None, require_not_executed=False):
+-        """Skip executing this feature or the remaining parts of it.
+-        Note that this feature may be already partly executed
+-        when this function is called.
++        """Skip executing this model entity or the remaining parts of it.
++        Note that this model entity (feature or rule) may be already partly
++        executed when this function is called.
+ 
+         :param reason:  Optional reason why feature should be skipped (as string).
+         :param require_not_executed: Optional, requires that feature is not
+@@ -314,8 +323,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         hook_after_entity = "after_{0}".format(entity_name)
+ 
+         runner.context._push(layer_name=entity_name)      # pylint: disable=protected-access
+-        runner.context.feature = self
+         runner.context.tags = set(self.tags)
++        self._setup_context_for_run(runner.context)
+ 
+         skip_entity_untested = runner.aborted
+         should_run_entity = self.should_run(runner.config)
+@@ -497,6 +506,9 @@ class Feature(ScenarioContainer):
+             (self.name, len(self.run_items),
+              len(self.rules), len(self.scenarios))
+ 
++    def _setup_context_for_run(self, context):
++        context.feature = self
++
+     def add_rule(self, rule):
+         """Add a rule to this feature."""
+         feature = self
+@@ -619,6 +631,9 @@ class Rule(ScenarioContainer):
+         self.parent = parent
+         self.feature = parent
+ 
++    def _setup_context_for_run(self, context):
++        context.rule = self
++
+     def __repr__(self):
+         return '<Rule "%s": %d scenario(s)>' % \
+             (self.name, len(self.scenarios))
+@@ -664,6 +679,10 @@ class Background(BasicStatement, Replayable):
+ 
+     .. _`background`: gherkin.html#backgrounds
+     """
++    # TODO: Background inheritance
++    # Rule.background should inherit its Feature.background steps (if available)
++    # Rule.background = Feature.background iff not Rule.background exists (ALREADY-SOLVED)
++    # Rule may override background inheritance mechanism
+     type = "background"
+ 
+     def __init__(self, filename, line, keyword, name, steps=None, description=None):
+@@ -796,7 +815,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+ 
+     @property
+     def background_steps(self):
+-        """Provide background steps if feature has a background.
++        """Provide background steps if feature/rule has a background.
+         Lazy init that copies the background steps.
+ 
+         Note that a copy of the background steps is needed to ensure
+diff --git a/behave/runner_util.py b/behave/runner_util.py
+index 2210f78..7e0807f 100644
+--- a/behave/runner_util.py
++++ b/behave/runner_util.py
+@@ -58,6 +58,100 @@ class FileLocationParser(object):
+ # -----------------------------------------------------------------------------
+ # CLASSES:
+ # -----------------------------------------------------------------------------
++from collections import OrderedDict
++from .model import Feature, Rule, ScenarioOutline, Scenario
++
++
++class FeatureLineDatabase(object):
++    """Helper class that supports select-by-location mechanism (FileLocation)
++    within a feature file by storing the feature line numbers for each entity.
++
++    RESPONSIBILITY(s):
++
++    * Can use the line number to select the best matching entity(s) in a feature
++    * Implements the select-by-location mechanism for each entity in the feature
++    """
++
++    def __init__(self, entity=None, line_data=None):
++        if entity and not line_data:
++            line_data = self.make_line_data_for(entity)
++        self.entity = entity
++        self.data = OrderedDict(line_data or [])
++        self._line_numbers = None
++        self._line_entities = None
++
++    def select_run_item_by_line(self, line):
++        """Select one run-items by using the line number.
++
++        * Exact match returns run-time entity (Feature, Rule, ScenarioOutline, Scenario)
++        * Any other line in between uses the predecessor entity
++
++        :param line: Line number in Feature file (as int)
++        :return: Selected run-item object.
++        """
++        run_item = self.data.get(line, None)
++        if run_item is None:
++            # -- CASE: BEST-MATCH in ordered line database
++            if self._line_numbers is None:
++                self._line_numbers = list(self.data.keys())
++                self._line_entities = list(self.data.values())
++
++            pos = bisect(self._line_numbers, line) - 1
++            if pos < 0:
++                pos = 0
++            run_item = self._line_entities[pos]
++        return run_item
++
++    def select_scenarios_by_line(self, line):
++        """Select one or more scenarios by using the line number.
++
++        * line = 0: Selects all scenarios in the Feature file
++        * Feature / Rule / ScenarioOutline.location.line selects its scenarios
++        * Scenario.location.line selects the Scenario
++        * Any other lines use the predecessor entity (and its scenarios)
++
++        :param line: Line number in Feature file (as int)
++        :return: List of selected scenarios
++        """
++        run_item = self.select_run_item_by_line(line)
++        scenarios = []
++        if isinstance(run_item, Feature):
++            scenarios = list(run_item.walk_scenarios())
++        elif isinstance(run_item, Rule):
++            scenarios = list(run_item.walk_scenarios())
++        elif isinstance(run_item, ScenarioOutline):
++            scenarios = list(run_item.scenarios)
++        elif isinstance(run_item, Scenario):
++            scenarios = [run_item]
++        return scenarios
++
++    @classmethod
++    def make_line_data_for(cls, entity):
++        line_data = []
++        run_items = []
++        if isinstance(entity, Feature):
++            line_data.append((0, entity))
++            run_items = entity.run_items
++        elif isinstance(entity, Rule):
++            run_items = entity.run_items
++        elif isinstance(entity, ScenarioOutline):
++            run_items = entity.scenarios
++
++        line_data.append((entity.location.line, entity))
++        for run_item in run_items:
++            line_data.extend(cls.make_line_data_for(run_item))
++        # -- MAYBE:
++        # if isinstance(entity, ScenarioOutline) and run_items:
++        #     # -- SPECIAL CASE: Lines after last Examples row => Use ScenarioOutline
++        #     line_data.append((run_items[-1].location.line + 1, entity))
++        return sorted(line_data)
++
++    @classmethod
++    def make(cls, entity):
++        return cls(entity, cls.make_line_data_for(entity))
++
++
++
+ class FeatureScenarioLocationCollector(object):
+     """
+     Collects FileLocation objects for a feature.
+@@ -200,6 +294,94 @@ class FeatureScenarioLocationCollector(object):
+         return self.feature
+ 
+ 
++class FeatureScenarioLocationCollector1(FeatureScenarioLocationCollector):
++
++    @staticmethod
++    def select_scenario_line_for(line, scenario_lines):
++        """
++        Select scenario line for any given line.
++
++        ALGORITHM: scenario.line <= line < next_scenario.line
++
++        :param line:  A line number in the file (as number).
++        :param scenario_lines: Sorted list of scenario lines.
++        :return: Scenario.line (first line) for the given line.
++        """
++        if not scenario_lines:
++            return 0    # -- Select all scenarios.
++        pos = bisect(scenario_lines, line) - 1
++        if pos < 0:
++            pos = 0
++        return scenario_lines[pos]
++
++    def discover_selected_scenarios(self, strict=False):
++        """
++        Discovers selected scenarios based on the provided file locations.
++        In addition:
++          * discover all scenarios
++          * auto-correct BAD LINE-NUMBERS
++
++        :param strict:  If true, raises exception if file location is invalid.
++        :return: List of selected scenarios of this feature (as set).
++        :raises InvalidFileLocationError:
++            If file location is no exactly correct and strict is true.
++        """
++        assert self.feature
++        if not self.all_scenarios:
++            self.all_scenarios = self.feature.walk_scenarios()
++
++        # -- STEP: Check if lines are correct.
++        existing_lines = [scenario.line for scenario in self.all_scenarios]
++        selected_lines = list(self.scenario_lines)
++        for line in selected_lines:
++            new_line = self.select_scenario_line_for(line, existing_lines)
++            if new_line != line:
++                # -- AUTO-CORRECT BAD-LINE:
++                self.scenario_lines.remove(line)
++                self.scenario_lines.add(new_line)
++                if strict:
++                    msg = "Scenario location '...:%d' should be: '%s:%d'" % \
++                          (line, self.filename, new_line)
++                    raise InvalidFileLocationError(msg)
++
++        # -- STEP: Determine selected scenarios and store them.
++        scenario_lines = set(self.scenario_lines)
++        selected_scenarios = set()
++        for scenario in self.all_scenarios:
++            if scenario.line in scenario_lines:
++                selected_scenarios.add(scenario)
++                scenario_lines.remove(scenario.line)
++        # -- CHECK ALL ARE RESOLVED:
++        assert not scenario_lines
++        return selected_scenarios
++
++
++class FeatureScenarioLocationCollector2(FeatureScenarioLocationCollector):
++
++    def discover_selected_scenarios(self, strict=False):
++        """Discovers selected scenarios based on the provided file locations.
++        In addition:
++          * discover all scenarios
++          * auto-correct BAD LINE-NUMBERS
++
++        :param strict:  If true, raises exception if file location is invalid.
++        :return: List of selected scenarios of this feature (as set).
++        :raises InvalidFileLocationError:
++            If file location is no exactly correct and strict is true.
++        """
++        assert self.feature
++        if not self.all_scenarios:
++            self.all_scenarios = self.feature.walk_scenarios()
++
++        line_database = FeatureLineDatabase.make(self.feature)
++        selected_lines = list(self.scenario_lines)
++        selected_scenarios = set()
++        for line in selected_lines:
++            more_scenarios = line_database.select_scenarios_by_line(line)
++            selected_scenarios.update(more_scenarios)
++        return selected_scenarios
++
++
+ class FeatureListParser(object):
+     """
+     Read textual file, ala '@features.txt'. This file contains:
+@@ -304,7 +486,7 @@ def parse_features(feature_files, language=None):
+     :param language:      Default language to use.
+     :return: List of feature objects.
+     """
+-    scenario_collector = FeatureScenarioLocationCollector()
++    scenario_collector = FeatureScenarioLocationCollector2()
+     features = []
+     for location in feature_files:
+         if not isinstance(location, FileLocation):
+@@ -315,7 +497,7 @@ def parse_features(feature_files, language=None):
+             scenario_collector.add_location(location)
+             continue
+         elif scenario_collector.feature:
+-            # -- ADD CURRENT FEATURE: As collection of scenarios.
++            # -- NEW FEATURE DETECTED: Add current feature.
+             current_feature = scenario_collector.build_feature()
+             features.append(current_feature)
+             scenario_collector.clear()
+diff --git a/features/runner.select_scenarios_by_file_location.feature b/features/runner.select_scenarios_by_file_location.feature
+index f60c43f..69e23fe 100644
+--- a/features/runner.select_scenarios_by_file_location.feature
++++ b/features/runner.select_scenarios_by_file_location.feature
+@@ -13,15 +13,28 @@ Feature: Select Scenarios by File Location
+     .   * A file location with filename but without line number
+     .     refers to the complete file
+     .   * A file location with line number 0 (zero) refers to the complete file
++    .   * A file location within a scenario container (Feature, Rule, ScenarioOutline),
++    .     that does not refer to the file location within a scenario,
++    .     selects all scenarios of this scenario container.
+     .
+     . SPECIFICATION: Scenario selection by file locations
+     .   * scenario.line == file_location.line selects scenario (preferred method).
+     .   * Any line number in the following range is acceptable:
+-    .        scenario.line <= file_location.line < next_scenario.line
+-    .   * The first scenario is selected,
+-    .     if the file location line number is less than first scenario.line.
++    .        scenario.line <= file_location.line < next_entity.line (maybe: scenario)
++    .   * If the file location line number is less than first scenario.line,
++    .     the preceeding scenario container (Feature or Rule) is selected.
+     .   * The last scenario is selected,
+     .     if the file location line number is greater than the lines in the file.
++    .   * For ScenarioOutline.scenarios:
++    .         scenario.line == ScenarioOutline.examples[x].row.line
++    .     The line number of the Examples row that created the scenario is assigned to it.
++    .
++    . SPECIFICATION: "Scenario container" selection by file locations
++    .   * Scenario containers are: Feature, Rule, ScenarioOutline
++    .   * A file location that points into the matching range of a scenario container,
++    .     selects all scenarios / run-items within this scenario container.
++    .   * Any line number in the following range selects the scenario container:
++    .        entity.line <= file_location.line < next_entity.line (maybe: child)
+     .
+     . SPECIFICATION: Runner with scenario locations (file locations)
+     .   * Adjacent file locations are merged if they refer to the same file, like:
+@@ -162,22 +175,24 @@ Feature: Select Scenarios by File Location
+             """
+ 
+     @file_location.select_first
+-    Scenario: Select first scenario if line number is smaller than first scenario line
++    Scenario: Select all scenarios if line number is smaller than first scenario line
+ 
+       CASE: 0 < file_location.line < first_scenario.line
++      HINT: Any line number outside of a scenario may point into a "scenario container".
++            In this case, all the scenarios of the scenario container are selected.
+ 
+         When I run "behave -f plain --dry-run --no-skipped features/alice.feature:1"
+         Then it should pass with:
+             """
+             0 features passed, 0 failed, 0 skipped, 1 untested
+-            0 scenarios passed, 0 failed, 1 skipped, 1 untested
++            0 scenarios passed, 0 failed, 0 skipped, 2 untested
+             """
+         And the command output should contain:
+             """
+             Feature: Alice
+               Scenario: Alice First
+             """
+-        But the command output should not contain:
++        But the command output should contain:
+             """
+             Scenario: Alice Last
+             """
+diff --git a/pytest.ini b/pytest.ini
+index a686596..ff2a8a2 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -16,7 +16,7 @@
+ # ============================================================================
+ 
+ [pytest]
+-minversion    = 4.2
++minversion    = 2.8
+ testpaths     = tests
+ python_files  = test_*.py
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+diff --git a/tests/unit/test_runner_util.py b/tests/unit/test_runner_util.py
+new file mode 100644
+index 0000000..b5019b8
+--- /dev/null
++++ b/tests/unit/test_runner_util.py
+@@ -0,0 +1,175 @@
++# -*- coding: UTF-8 -*-
++
++from __future__ import absolute_import, print_function
++from collections import OrderedDict
++from behave.runner_util import FeatureLineDatabase
++from behave.parser import parse_feature
++from behave.model import Feature, Rule, ScenarioOutline, Scenario, Background
++import pytest
++
++
++# ---------------------------------------------------------------------------------------
++# TEST DATA: FeatureLineDatabase
++# ---------------------------------------------------------------------------------------
++feature_text1 = u"""
++    Feature: Alice
++        Background: Alice.Background
++          Given a background step passes
++          
++        Scenario: A1
++          Given a scenario step passes
++
++        Scenario: A2
++          Given a scenario step passes
++          When a scenario step passes
++    """
++
++feature_text_with_scenario_outline = u"""
++    Feature: Bob
++    
++        Scenario Outline: Bob.SO_2_<row.id>
++          Given a person with name "<Name>"
++          Then the person is born in <Birthyear>
++        
++          Examples:
++            | Name  | Birthyear |
++            | Alice |  1990     |
++            | Bob   |  1991     |
++            
++        Scenario: Bob.S3
++          Given a scenario step passes
++          When a scenario step passes
++    """
++
++feature_text_with_rule = u"""
++    Feature: Charly
++        Background: Charly.Background
++          Given a background step passes
++
++        Scenario: C1
++          Given a scenario step passes
++
++        Rule: Charly.Rule_1
++
++          Scenario: Rule_1.C2
++            Given a scenario step passes
++            When a scenario step passes
++    """
++
++feature_file_map = {
++    "basic.feature": feature_text1,
++    "scenario_outline.feature": feature_text_with_scenario_outline,
++    "rule.feature": feature_text_with_rule,
++}
++
++# ---------------------------------------------------------------------------------------
++# TEST SUITE FOR: FeatureLineDatabase
++# ---------------------------------------------------------------------------------------
++class TestFeatureLineDatabase(object):
++    def test_make(self):
++        feature = parse_feature(feature_text1.strip(),
++                                filename="features/Alice.feature")
++        scenario_0 = feature.scenarios[0]
++        scenario_1 = feature.scenarios[1]
++
++        line_database = FeatureLineDatabase.make(feature)
++        expected = OrderedDict([
++            (0, feature),
++            (feature.location.line, feature),
++            (scenario_0.line, scenario_0),
++            (scenario_1.line, scenario_1),
++        ])
++        assert line_database.data == expected
++        assert feature.location.line == 1
++
++    def test_make__with_scenario_outline(self):
++        feature = parse_feature(feature_text_with_scenario_outline.strip(),
++                                filename="features/Bob.feature")
++        scenarios = feature.walk_scenarios(with_outlines=True)
++        scenario_outline = scenarios[0]
++        assert scenario_outline is feature.run_items[0]
++        scenario_1 = scenarios[1]
++        scenario_2 = scenarios[2]
++        scenario_3 = scenarios[3]
++
++        line_database = FeatureLineDatabase.make(feature)
++        expected = OrderedDict([
++            (0, feature),
++            (feature.location.line, feature),
++            (scenario_outline.line, scenario_outline),
++            (scenario_1.line, scenario_1),
++            (scenario_2.line, scenario_2),
++            (scenario_3.line, scenario_3),
++        ])
++        assert line_database.data == expected
++        assert feature.location.line < scenario_outline.location.line
++        assert scenario_outline.location.line < scenario_1.location.line
++        assert scenario_1.location.line < scenario_2.location.line
++        assert scenario_2.location.line < scenario_3.location.line
++
++
++    def test_select_run_items_by_line__feature_line_selects_feature(self):
++        feature = parse_feature(feature_text1, filename="features/Alice.feature")
++        line_database = FeatureLineDatabase.make(feature)
++        selected = line_database.select_run_item_by_line(feature.location.line)
++        assert selected is feature
++        assert isinstance(selected, Feature)
++
++    @pytest.mark.parametrize("filename", [
++        "basic.feature", "scenario_outline.feature", "rule.feature"
++    ])
++    def test_select_run_items_by_line__entity_line_selects_entity(self, filename):
++        feature_text = feature_file_map[filename]
++        feature = parse_feature(feature_text, filename=filename)
++        line_database = FeatureLineDatabase.make(feature)
++        last_line = 0
++        all_run_items = feature.walk_scenarios(with_outlines=True, with_rules=True)
++        for run_item in all_run_items:
++            selected = line_database.select_run_item_by_line(run_item.location.line)
++            assert selected is run_item
++            assert last_line < selected.location.line
++            last_line = run_item.location.line
++
++    @pytest.mark.parametrize("filename", [
++        "basic.feature", "scenario_outline.feature", "rule.feature"
++    ])
++    def test_select_run_items_by_line__line_before_entity_selects_last_entity(self, filename):
++        feature_text = feature_file_map[filename]
++        feature = parse_feature(feature_text, filename=filename)
++        line_database = FeatureLineDatabase.make(feature)
++        all_run_items = feature.walk_scenarios(with_outlines=True, with_rules=True)
++        last_run_item = feature
++        for run_item in all_run_items:
++            predecessor_line = run_item.location.line - 1
++            selected = line_database.select_run_item_by_line(predecessor_line)
++            assert selected is last_run_item
++            assert selected is not run_item
++            last_run_item = run_item
++
++    @pytest.mark.parametrize("filename", [
++        "basic.feature", "scenario_outline.feature", "rule.feature"
++    ])
++    def test_select_run_items_by_line__line_after_entity_selects_entity(self, filename):
++        # -- HINT: In most cases
++        # EXCEPT:
++        #   * Scenarios of ScenarioOutline: scenario.line == SO.examples.row.line
++        #   * Empty entity without steps is directly followed by other entity
++        feature_text = feature_file_map[filename]
++        feature = parse_feature(feature_text, filename=filename)
++        line_database = FeatureLineDatabase.make(feature)
++        all_run_items = feature.walk_scenarios(with_outlines=True, with_rules=True)
++        file_end_line = all_run_items[-1].location.line + 1000
++        for index, run_item in enumerate(all_run_items):
++            next_line = run_item.location.line + 1
++            next_entity_line = file_end_line
++            if index+1 < len(all_run_items):
++                next_entity = all_run_items[index+1]
++                next_entity_line = next_entity.line
++            if next_line >= next_entity_line:
++                # -- EXCLUDE: Scenarios in a ScenarioOutline
++                print("EXCLUDED: %s: %s (line=%s)" %
++                      (run_item.keyword, run_item.name, run_item.line))
++                continue
++
++            selected = line_database.select_run_item_by_line(next_line)
++            assert selected is run_item
diff --git a/meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch b/meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch
new file mode 100644
index 000000000..14394603f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch
@@ -0,0 +1,58 @@
+From a6388c0e97e4378a4ef628361a46ff6d02d3159e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 10:50:54 +0200
+Subject: [PATCH] docs: Add description for "Select-by-location for Scenario
+ Containers"
+
+---
+ docs/new_and_noteworthy_v1.2.7.rst | 33 ++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index 80d9576..ff1cd1f 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -7,6 +7,7 @@ Summary:
+ * Use/Support :pypi:`cucumber-tag-expressions` (superceed: old-style tag-expressions)
+ * :pypi:`cucumber-tag-expressions` are extended by "tag-matching"
+   to match partial tag names, like: ``@foo.*``
++* `Select-by-location for Scenario Containers`_ (Feature, Rule, ScenarioOutline)
+ 
+ .. _`Example Mapping`: https://cucumber.io/blog/example-mapping-introduction/
+ .. _`Example Mapping Webinar`: https://cucumber.io/blog/example-mapping-webinar/
+@@ -102,3 +103,35 @@ Overview of the `Example Mapping`_ concepts:
+ 
+ 
+ .. include:: _content.tag_expressions_v2.rst
++
++
++Select-by-location for Scenario Containers
++-------------------------------------------------------------------------------
++
++In the past, it was already possible to scenario(s) by using its **file-location**.
++
++A **file-location** has the schema: ``<FILENAME>:<LINE_NUMBER>``.
++Example: ``features/alice.feature:12``
++(refers to ``line 12`` in ``features/alice.feature`` file).
++
++Rules to select **Scenarios** by using the file-location:
++
++* **Scenario:** Use a file-location that points to the keyword/title or its steps
++  (until next Scenario/Entity starts).
++
++* **Scenario of a ScenarioOutline:**
++  Use the file-location of its Examples row.
++
++Now you can select all entities of a **Scenario Container** (Feature, Rule, ScenarioOutline):
++
++* **Feature:**
++  Use file-location before first contained entity/Scenario starts.
++
++* **Rule:**
++  Use file-location from keyword/title line to line before its first Scenario/Background.
++
++* **ScenarioOutline:**
++  Use file-location from keyword/title line to line before its Examples rows.
++
++A file-location into a **Scenario Container** selects all its entities
++(Scenarios, ...).
diff --git a/meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch b/meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch
new file mode 100644
index 000000000..2b80d5df1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch
@@ -0,0 +1,50 @@
+From 93f578698844d7276e5b2f287ee7ff3bcfc049bf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 13:35:51 +0200
+Subject: [PATCH] tests: Fix warnings for python3.
+
+---
+ tests/issues/test_issue0336.py |  1 +
+ tests/unit/test_parser.py      | 11 +++++++----
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/tests/issues/test_issue0336.py b/tests/issues/test_issue0336.py
+index eb4c3fd..09201ae 100644
+--- a/tests/issues/test_issue0336.py
++++ b/tests/issues/test_issue0336.py
+@@ -52,6 +52,7 @@ AssertionError
+             assert file_line_text in text2
+ 
+     # @require_python2
++    @pytest.mark.filterwarnings("ignore:invalid escape sequence")
+     def test__problem_exists_with_problematic_encoding(self):
+         """Test ensures that problem exists with encoding=unicode-escape"""
+         # -- NOTE: Explicit use of problematic encoding
+diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py
+index ecbb1bf..01006f9 100644
+--- a/tests/unit/test_parser.py
++++ b/tests/unit/test_parser.py
+@@ -564,16 +564,19 @@ Feature: Stuff
+             ('then', 'Then', 'stuff is in buckets', None, None),
+         ])
+ 
++    @pytest.mark.filterwarnings("ignore:invalid escape sequence")
+     def test_parses_feature_with_table_and_escaped_pipe_in_cell_values(self):
++        # -- HINT py37: DeprecationWarning: invalid escape sequence '\|'
++        # USE: Double escaped-backslashes.
+         doc = u'''
+ Feature:
+   Scenario:
+     Given we have special cell values:
+       | name   | value    |
+-      | alice  | one\|two |
+-      | bob    |\|one     |
+-      | charly |     one\||
+-      | doro   | one\|two\|three\|four |
++      | alice  | one\\|two |
++      | bob    |\\|one     |
++      | charly |     one\\||
++      | doro   | one\\|two\\|three\\|four |
+ '''.lstrip()
+         feature = parser.parse_feature(doc)
+         assert len(feature.scenarios) == 1
diff --git a/meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch b/meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch
new file mode 100644
index 000000000..85c1bc16a
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch
@@ -0,0 +1,55 @@
+From 21a399bf6e2e2eb09c98d173f1d0975bcecbf1e5 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 13:36:59 +0200
+Subject: [PATCH] Use cucumber-tag-expressions 1.1.2 (to fix warnings).
+
+py.requirements: Add twine, bump2version
+---
+ py.requirements/basic.txt   | 2 +-
+ py.requirements/develop.txt | 6 +++++-
+ setup.py                    | 2 +-
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index 3b71bfb..ad5b9a6 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -8,7 +8,7 @@
+ #  * http://www.pip-installer.org/
+ # ============================================================================
+ 
+-cucumber-tag-expressions >= 1.1.1
++cucumber-tag-expressions >= 1.1.2
+ parse >= 1.8.2
+ parse_type >= 0.4.2
+ six >= 1.12.0
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index d823389..a16d7bf 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -11,7 +11,11 @@ pathlib;    python_version <= '3.4'
+ pycmd
+ 
+ # -- CONFIGURATION MANAGEMENT (helpers):
+-bumpversion >= 0.4.0
++# FORMER: bumpversion >= 0.4.0
++bump2version >= 0.5.6
++
++# -- RELEASE MANAGEMENT: Push package to pypi.
++twine >= 1.13.0
+ 
+ # -- DEVELOPMENT SUPPORT:
+ tox   >= 1.8.1
+diff --git a/setup.py b/setup.py
+index 9c7560d..cea4392 100644
+--- a/setup.py
++++ b/setup.py
+@@ -76,7 +76,7 @@ setup(
+     # SUPPORT: python2.7, python3.3 (or higher)
+     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*",
+     install_requires=[
+-        "cucumber-tag-expressions >= 1.1.1",
++        "cucumber-tag-expressions >= 1.1.2",
+         "parse >= 1.8.2",
+         "parse_type >= 0.4.2",
+         "six >= 1.12.0",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch b/meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch
new file mode 100644
index 000000000..6d69f4754
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch
@@ -0,0 +1,91 @@
+From 1d3c288a2eed8caef24356e2a92483425bee0378 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 14:18:16 +0200
+Subject: [PATCH] MENTION ENHANCEMENT: Support emojis in feature files and
+ steps.
+
+---
+ CHANGES.rst                        |  3 ++-
+ docs/new_and_noteworthy_v1.2.7.rst | 17 +++++++++++++++++
+ features/i18n_emoji.feature        |  7 +++++++
+ features/steps/i18n_emoji_steps.py | 10 ++++++++++
+ 4 files changed, 36 insertions(+), 1 deletion(-)
+ create mode 100644 features/i18n_emoji.feature
+ create mode 100644 features/steps/i18n_emoji_steps.py
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 01bd1bd..d165275 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -24,8 +24,9 @@ GOALS:
+ ENHANCEMENTS:
+ 
+ * Add support for Gherkin v6 grammar and syntax in ``*.feature`` files
+-* Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Use `cucumber-tag-expressions`_ with tag-matching extension (superceeds: old-style tag-expressions)
++* Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
++* Support emojis in ``*.feature`` files and steps
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ * Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index ff1cd1f..b7242f7 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -8,6 +8,7 @@ Summary:
+ * :pypi:`cucumber-tag-expressions` are extended by "tag-matching"
+   to match partial tag names, like: ``@foo.*``
+ * `Select-by-location for Scenario Containers`_ (Feature, Rule, ScenarioOutline)
++* `Support for emojis in feature files and steps`_
+ 
+ .. _`Example Mapping`: https://cucumber.io/blog/example-mapping-introduction/
+ .. _`Example Mapping Webinar`: https://cucumber.io/blog/example-mapping-webinar/
+@@ -135,3 +136,19 @@ Now you can select all entities of a **Scenario Container** (Feature, Rule, Scen
+ 
+ A file-location into a **Scenario Container** selects all its entities
+ (Scenarios, ...).
++
++
++Support for Emojis in Feature Files and Steps
++-------------------------------------------------------------------------------
++
++* Emojis can now be used in ``*.feature`` files.
++* Emojis can now be used in step definitions.
++* You can now use ``language=emoji (em)`` in ``*.feature`` files ;-)
++
++.. literalinclude:: ../features/i18n_emoji.feature
++    :prepend:  # -- FILE: features/i18n_emoji.feature
++    :language: gherkin
++
++.. literalinclude:: ../features/steps/i18n_emoji_steps.py
++    :prepend:  # -- FILE: features/steps/i18n_emoji_steps.py
++    :language: python
+diff --git a/features/i18n_emoji.feature b/features/i18n_emoji.feature
+new file mode 100644
+index 0000000..db23ac2
+--- /dev/null
++++ b/features/i18n_emoji.feature
+@@ -0,0 +1,7 @@
++# language: em
++# SOURCE: https://github.com/cucumber/cucumber/blob/master/gherkin/testdata/good/i18n_emoji.feature
++
++📚: 🙈🙉🙊
++
++  📕: 💃
++    😐🎸
+diff --git a/features/steps/i18n_emoji_steps.py b/features/steps/i18n_emoji_steps.py
+new file mode 100644
+index 0000000..381d2bb
+--- /dev/null
++++ b/features/steps/i18n_emoji_steps.py
+@@ -0,0 +1,10 @@
++# -*- coding: UTF-8 -*-
++# NEEDED-BY: features/i18n_emoji.feature
++
++from behave import given
++
++@given(u'🎸')
++def step_impl(context):
++    """Step implementation example with emoji(s)."""
++    pass
++
diff --git a/meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch b/meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch
new file mode 100644
index 000000000..00db4a627
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch
@@ -0,0 +1,250 @@
+From 281bb19a47566c01ce44e7184640728bb56d4de7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 19:06:11 +0200
+Subject: [PATCH] FIX: Invalid escape char (in regex) w/ python3.
+
+---
+ behave/formatter/ansi_escapes.py |  53 ++++++++----
+ tests/unit/test_ansi_escapes.py  | 144 ++++++++++++++++++-------------
+ 2 files changed, 122 insertions(+), 75 deletions(-)
+
+diff --git a/behave/formatter/ansi_escapes.py b/behave/formatter/ansi_escapes.py
+index 6c93e6c..3ec84db 100644
+--- a/behave/formatter/ansi_escapes.py
++++ b/behave/formatter/ansi_escapes.py
+@@ -7,6 +7,9 @@ from __future__ import absolute_import
+ import os
+ import re
+ 
++# ---------------------------------------------------------------------------
++# MODULE DATA
++# ---------------------------------------------------------------------------
+ colors = {
+     "black":        u"\x1b[30m",
+     "red":          u"\x1b[31m",
+@@ -38,27 +41,48 @@ escapes = {
+     "up":           u"\x1b[1A",
+ }
+ 
+-if "GHERKIN_COLORS" in os.environ:
+-    new_aliases = [p.split("=") for p in os.environ["GHERKIN_COLORS"].split(":")]
+-    aliases.update(dict(new_aliases))
+ 
+-for alias in aliases:
+-    escapes[alias] = "".join([colors[c] for c in aliases[alias].split(",")])
+-    arg_alias = alias + "_arg"
+-    arg_seq = aliases.get(arg_alias, aliases[alias] + ",bold")
+-    escapes[arg_alias] = "".join([colors[c] for c in arg_seq.split(",")])
++# -- NEEDED-FOR: strip_escapes(), ...
++_ANSI_ESCAPE_PATTERN = re.compile(u"\x1b\\[\\d+[mA]", re.UNICODE)
+ 
+ 
+-# pylint: disable=anomalous-backslash-in-string
++
++# ---------------------------------------------------------------------------
++# MODULE SETUP
++# ---------------------------------------------------------------------------
++def _setup_module():
++    """Setup the remaining ANSI color aliases and ANSI escape sequences.
++
++    .. note:: May modify/extend the module attributes:
++
++        * :attr:`aliases`
++        * :attr:`escapes`
++    """
++    # MAYBE: global aliases, escapes
++    if "GHERKIN_COLORS" in os.environ:
++        new_aliases = [p.split("=") for p in os.environ["GHERKIN_COLORS"].split(":")]
++        aliases.update(dict(new_aliases))
++
++    for alias in aliases:
++        escapes[alias] = "".join([colors[c] for c in aliases[alias].split(",")])
++        arg_alias = alias + "_arg"
++        arg_seq = aliases.get(arg_alias, aliases[alias] + ",bold")
++        escapes[arg_alias] = "".join([colors[c] for c in arg_seq.split(",")])
++
++
++# -- ONCE: During module-import.
++_setup_module()
++
++
++# ---------------------------------------------------------------------------
++# FUNCTIONS:
++# ---------------------------------------------------------------------------
+ def up(n):
+     return u"\x1b[%dA" % n
+ 
+ 
+-_ANSI_ESCAPE_PATTERN = re.compile(u"\x1b\[\d+[mA]", re.UNICODE)
+-# pylint: enable=anomalous-backslash-in-string
+ def strip_escapes(text):
+-    """
+-    Removes ANSI escape sequences from text (if any are contained).
++    """Removes ANSI escape sequences from text (if any are contained).
+ 
+     :param text: Text that may or may not contain ANSI escape sequences.
+     :return: Text without ANSI escape sequences.
+@@ -67,8 +91,7 @@ def strip_escapes(text):
+ 
+ 
+ def use_ansi_escape_colorbold_composites():     # pragma: no cover
+-    """
+-    Patch for "sphinxcontrib-ansi" to process the following ANSI escapes
++    """Patch for "sphinxcontrib-ansi" to process the following ANSI escapes
+     correctly (set-color set-bold sequences):
+ 
+         ESC[{color}mESC[1m  => ESC[{color};1m
+diff --git a/tests/unit/test_ansi_escapes.py b/tests/unit/test_ansi_escapes.py
+index 969f3a9..4fb78c2 100644
+--- a/tests/unit/test_ansi_escapes.py
++++ b/tests/unit/test_ansi_escapes.py
+@@ -9,65 +9,89 @@
+ from __future__ import absolute_import
+ import pytest
+ from behave.formatter import ansi_escapes
+-import unittest
+ from six.moves import range
+ 
+-class StripEscapesTest(unittest.TestCase):
+-    ALL_COLORS = list(ansi_escapes.colors.keys())
+-    CURSOR_UPS = [ ansi_escapes.up(count)  for count in range(10) ]
+-    TEXTS = [
+-        u"lorem ipsum",
+-        u"Alice\nBob\nCharly\nDennis",
+-    ]
+-
+-    @classmethod
+-    def colorize(cls, text, color):
+-        color_escape = ""
+-        if color:
+-            color_escape = ansi_escapes.colors[color]
+-        return color_escape + text + ansi_escapes.escapes["reset"]
+-
+-    @classmethod
+-    def colorize_text(cls, text, colors=None):
+-        if not colors:
+-            colors = []
+-        colors_size = len(colors)
+-        color_index = 0
+-        colored_chars = []
+-        for char in text:
+-            color = colors[color_index]
+-            colored_chars.append(cls.colorize(char, color))
+-            color_index += 1
+-            if color_index >= colors_size:
+-                color_index = 0
+-        return "".join(colored_chars)
+-
+-    def test_should_return_same_text_without_escapes(self):
+-        for text in self.TEXTS:
+-            assert text == ansi_escapes.strip_escapes(text)
+-
+-    def test_should_return_empty_string_for_any_ansi_escape(self):
+-        # XXX-JE-CHECK-PY23: If list() is really needed.
+-        for text in list(ansi_escapes.colors.values()):
+-            assert "" == ansi_escapes.strip_escapes(text)
+-        for text in list(ansi_escapes.escapes.values()):
+-            assert "" == ansi_escapes.strip_escapes(text)
+-
+-
+-    def test_should_strip_color_escapes_from_text(self):
+-        for text in self.TEXTS:
+-            colored_text = self.colorize_text(text, self.ALL_COLORS)
+-            assert text == ansi_escapes.strip_escapes(colored_text)
+-            self.assertNotEqual(text, colored_text)
+-
+-            for color in self.ALL_COLORS:
+-                colored_text = self.colorize(text, color)
+-                assert text == ansi_escapes.strip_escapes(colored_text)
+-                self.assertNotEqual(text, colored_text)
+-
+-    def test_should_strip_cursor_up_escapes_from_text(self):
+-        for text in self.TEXTS:
+-            for cursor_up in self.CURSOR_UPS:
+-                colored_text = cursor_up + text + ansi_escapes.escapes["reset"]
+-                assert text == ansi_escapes.strip_escapes(colored_text)
+-                self.assertNotEqual(text, colored_text)
++
++# --------------------------------------------------------------------------
++# TEST SUPPORT and TEST DATA
++# --------------------------------------------------------------------------
++TEXTS = [
++    u"lorem ipsum",
++    u"Alice and Bob",
++    u"Alice\nBob",
++]
++ALL_COLORS = list(ansi_escapes.colors.keys())
++CURSOR_UPS = [ansi_escapes.up(count) for count in range(10)]
++
++
++def colorize(text, color):
++    color_escape = ""
++    if color:
++        color_escape = ansi_escapes.colors[color]
++    return color_escape + text + ansi_escapes.escapes["reset"]
++
++
++def colorize_text(text, colors=None):
++    if not colors:
++        colors = []
++    colors_size = len(colors)
++    color_index = 0
++    colored_chars = []
++    for char in text:
++        color = colors[color_index]
++        colored_chars.append(colorize(char, color))
++        color_index += 1
++        if color_index >= colors_size:
++            color_index = 0
++    return "".join(colored_chars)
++
++
++# --------------------------------------------------------------------------
++# TEST SUITE
++# --------------------------------------------------------------------------
++def test_module_setup():
++    """Ensure that the module setup (aliases, escapes) occured."""
++    # colors_count = len(ansi_escapes.colors)
++    aliases_count = len(ansi_escapes.aliases)
++    escapes_count = len(ansi_escapes.escapes)
++    assert escapes_count >= (2 + aliases_count + aliases_count)
++
++
++class TestStripEscapes(object):
++
++    @pytest.mark.parametrize("text", TEXTS)
++    def test_should_return_same_text_without_escapes(self, text):
++        assert text == ansi_escapes.strip_escapes(text)
++
++    @pytest.mark.parametrize("text", ansi_escapes.colors.values())
++    def test_should_return_empty_string_for_any_ansi_escape_color(self, text):
++        assert "" == ansi_escapes.strip_escapes(text)
++
++    @pytest.mark.parametrize("text", ansi_escapes.escapes.values())
++    def test_should_return_empty_string_for_any_ansi_escape(self, text):
++        assert "" == ansi_escapes.strip_escapes(text)
++
++    @pytest.mark.parametrize("text", TEXTS)
++    def test_should_strip_color_escapes_from_all_colored_text(self, text):
++        colored_text = colorize_text(text, ALL_COLORS)
++        assert text == ansi_escapes.strip_escapes(colored_text)
++        assert text != colored_text
++
++    @pytest.mark.parametrize("text", TEXTS)
++    @pytest.mark.parametrize("color", ALL_COLORS)
++    def test_should_strip_color_escapes_from_text(self, text, color):
++        colored_text = colorize(text, color)
++        assert text == ansi_escapes.strip_escapes(colored_text)
++        assert text != colored_text
++
++        colored_text2 = colorize(text, color) + text
++        text2 = text + text
++        assert text2 == ansi_escapes.strip_escapes(colored_text2)
++        assert text2 != colored_text2
++
++    @pytest.mark.parametrize("text", TEXTS)
++    @pytest.mark.parametrize("cursor_up", CURSOR_UPS)
++    def test_should_strip_cursor_up_escapes_from_text(self, text, cursor_up):
++        colored_text = cursor_up + text + ansi_escapes.escapes["reset"]
++        assert text == ansi_escapes.strip_escapes(colored_text)
++        assert text != colored_text
diff --git a/meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch b/meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch
new file mode 100644
index 000000000..82bf8bb08
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch
@@ -0,0 +1,335 @@
+From 8ab2ff875382a92a1a72cf82a346c4acf2ec6859 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 19:15:44 +0200
+Subject: [PATCH] Example related to question in #756
+
+---
+ .../fixture.override_background/README.rst    | 116 ++++++++++++++++++
+ .../behave_fixture_lib/__init__.py            |   0
+ .../behave_fixture_lib/override_background.py |  80 ++++++++++++
+ .../features/environment.py                   |  35 ++++++
+ .../features/example.feature                  |  18 +++
+ .../features/steps/basic_steps.py             |  13 ++
+ .../features/steps/use_steplib_behave4cmd.py  |  12 ++
+ 7 files changed, 274 insertions(+)
+ create mode 100644 examples/fixture.override_background/README.rst
+ create mode 100644 examples/fixture.override_background/behave_fixture_lib/__init__.py
+ create mode 100644 examples/fixture.override_background/behave_fixture_lib/override_background.py
+ create mode 100644 examples/fixture.override_background/features/environment.py
+ create mode 100644 examples/fixture.override_background/features/example.feature
+ create mode 100644 examples/fixture.override_background/features/steps/basic_steps.py
+ create mode 100644 examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+
+diff --git a/examples/fixture.override_background/README.rst b/examples/fixture.override_background/README.rst
+new file mode 100644
+index 0000000..9c150cc
+--- /dev/null
++++ b/examples/fixture.override_background/README.rst
+@@ -0,0 +1,116 @@
++EXAMPLE: Override / Disable Background Inheritance Mechanism for Scenario
++===============================================================================
++
++:RELATED-TO: #756
++
++This example shows how the Background inheritance mechanism in Gherkin
++can be disabled in ``behave``.
++
++Parts of the recipe:
++
++* features/example.feature (Feature file as example)
++* features/environment.py (glue code and hooks for fixture-tag / fixture)
++* behave_fixture_lib/override_background.py (fixture implementation, workhorse)
++
++
++.. warning:: BEWARE: This shows you how can do it, not that you should do it
++
++    BETTER:
++
++    * Use Rules to group Scenarios, each with its own Background (in Gherkin v6)
++    * Split Feature aspects into multiple feature files (if needed)
++    * ... (see issue #756 above)
++
++
++Explanation
++------------------------------------------------------------------------
++
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism by using a fixture / fixture-tag.
++The fixture-tag "@ixture.behave.override_background" marks the
++location in Gherkin (which Scenario) where the fixture should be used
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.override_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.overide_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++When the feature is executed, you see that:
++
++* First Scenario "Alice": Background steps are inherited and executed first.
++* Second Scenario "Bob": No Background step is executed.
++
++.. code-block:: sh
++
++    $ ../../bin/behave -f plain features/example.feature
++    Feature: Override the Background Inheritance Mechanism in some Scenarios
++      Background:
++
++      Scenario: Alice
++        Given a background step passes ... passed
++        When a step passes ... passed
++        And note that "Background steps are executed here" ... passed
++    FIXTURE-HINT: DISABLE-BACKGROUND FOR: Bob
++
++      Scenario: Bob
++        Given I need another scenario setup ... passed
++        When another step passes ... passed
++        And note that "NO-BACKGROUND STEPS are executed here" ... passed
++
++    1 feature passed, 0 failed, 0 skipped
++    2 scenarios passed, 0 failed, 0 skipped
++    6 steps passed, 0 failed, 0 skipped, 0 undefined
++
++
++The environment file provides the glue code that the fixture is called:
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.override_background import behave_override_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.overide_background": behave_override_background,
++    }
++
++    # -----------------------------------------------------------------------------
++    # HOOKS:
++    # -----------------------------------------------------------------------------
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++
++.. code-block:: python
++
++    # -- FILE: behave_fixture_lib/override_background.py (fixture implementation)
++    from behave import fixture
++
++    @fixture(name="fixture.behave.override_background")
++    def behave_override_background(ctx):
++        # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++        current_scenario = ctx.scenario
++        if current_scenario:
++            behave_disable_background_inheritance_for_scenario(current_scenario)
++
++    # -----------------------------------------------------------------------------
++    # BEHAVE UTILITY:
++    # -----------------------------------------------------------------------------
++    def behave_disable_background_inheritance_for_scenario(scenario):
++        print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
++        scenario.background = None
+diff --git a/examples/fixture.override_background/behave_fixture_lib/__init__.py b/examples/fixture.override_background/behave_fixture_lib/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/examples/fixture.override_background/behave_fixture_lib/override_background.py b/examples/fixture.override_background/behave_fixture_lib/override_background.py
+new file mode 100644
+index 0000000..6c572cf
+--- /dev/null
++++ b/examples/fixture.override_background/behave_fixture_lib/override_background.py
+@@ -0,0 +1,80 @@
++# -*- coding: UTF-8 -*-
++# RELATED-TO: #756
++"""
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism.
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.override_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.overide_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.override_background import behave_override_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.overide_background": behave_override_background,
++    }
++
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++"""
++
++from __future__ import absolute_import, print_function
++from behave import fixture
++
++
++# -----------------------------------------------------------------------------
++# BEHAVE FIXTURES:
++# -----------------------------------------------------------------------------
++@fixture(name="fixture.behave.override_background")
++def behave_override_background(ctx):
++    """Override the Background inherintance mechanism.
++    If a Feature / Rule Background exists in a Feature,
++    all contained Scenarios inherit the Background's steps.
++
++    This fixture disables this mechanism.
++    The tagged Gherkin element will no longer inherit the background steps.
++
++    :param ctx: Context object to use (during a test run).
++    """
++    # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++    current_scenario = ctx.scenario
++    if current_scenario:
++        behave_disable_background_inheritance_for_scenario(current_scenario)
++
++
++# -----------------------------------------------------------------------------
++# BEHAVE UTILITY:
++# -----------------------------------------------------------------------------
++def behave_disable_background_inheritance_for_scenario(scenario):
++    print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
++    scenario.background = None
++    # scenario._background_steps = []
++
++
++# -----------------------------------------------------------------------------
++# MODULE SPECIFIC:
++# -----------------------------------------------------------------------------
++fixture_registry = {
++    "fixture.behave.overide_background": behave_override_background,
++}
+diff --git a/examples/fixture.override_background/features/environment.py b/examples/fixture.override_background/features/environment.py
+new file mode 100644
+index 0000000..7a4b735
+--- /dev/null
++++ b/examples/fixture.override_background/features/environment.py
+@@ -0,0 +1,35 @@
++# -*- coding: UTF-8 -*-
++# -- FILE: features/environment.py
++import os.path
++import sys
++
++# -----------------------------------------------------------------------------
++# PYTHON PATH SETUP:
++# -----------------------------------------------------------------------------
++HERE = os.path.dirname(__file__)
++TOPA = os.path.abspath(os.path.join(HERE, ".."))
++
++def setup_python_path():
++    sys.path.insert(0, TOPA)
++
++setup_python_path()
++
++# -----------------------------------------------------------------------------
++# NORMAL PART:
++# -----------------------------------------------------------------------------
++from behave_fixture_lib.override_background import behave_override_background
++from behave.fixture import use_fixture_by_tag
++
++# -- FIXTURE REGISTRY:
++fixture_registry = {
++    "fixture.behave.overide_background": behave_override_background,
++}
++
++
++# -----------------------------------------------------------------------------
++# HOOKS:
++# -----------------------------------------------------------------------------
++def before_tag(context, tag):
++    if tag.startswith("fixture."):
++        return use_fixture_by_tag(tag, context, fixture_registry)
++
+diff --git a/examples/fixture.override_background/features/example.feature b/examples/fixture.override_background/features/example.feature
+new file mode 100644
+index 0000000..5ddd874
+--- /dev/null
++++ b/examples/fixture.override_background/features/example.feature
+@@ -0,0 +1,18 @@
++Feature: Override the Background Inheritance Mechanism in some Scenarios
++
++  . BEWARE:
++  .   This is only an example how this can be done (PROOF-OF-CONCEPT).
++  .   This is not an example that you should do this !!!
++
++    Background:
++      Given a background step passes
++
++    Scenario: Alice
++      When a step passes
++      And note that "Background steps are executed here"
++
++    @fixture.behave.overide_background
++    Scenario: Bob
++      Given I need another scenario setup
++      When another step passes
++      And note that "NO-BACKGROUND STEPS are executed here"
+diff --git a/examples/fixture.override_background/features/steps/basic_steps.py b/examples/fixture.override_background/features/steps/basic_steps.py
+new file mode 100644
+index 0000000..34f2107
+--- /dev/null
++++ b/examples/fixture.override_background/features/steps/basic_steps.py
+@@ -0,0 +1,13 @@
++from behave import given, step
++
++# @step(u'{word} step passes')
++# def step_passes_with_word(context, word):
++#     pass
++
++@step(u'{word} background step passes')
++def step_background_step_passes(context, word):
++    pass
++
++@given(u'I need {word} scenario setup')
++def step_given_i_need_scenario_setup(context, word):
++    pass
+diff --git a/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py b/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+new file mode 100644
+index 0000000..bc32a32
+--- /dev/null
++++ b/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+@@ -0,0 +1,12 @@
++# -*- coding: utf-8 -*-
++"""
++Use behave4cmd0 step library (predecessor of behave4cmd).
++"""
++
++from __future__ import absolute_import
++
++# -- REGISTER-STEPS FROM STEP-LIBRARY:
++# import behave4cmd0.__all_steps__
++# import behave4cmd0.failing_steps
++import behave4cmd0.passing_steps
++import behave4cmd0.note_steps
diff --git a/meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch b/meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch
new file mode 100644
index 000000000..c383e39f5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch
@@ -0,0 +1,489 @@
+From 64e58e5721f4fccc9cdf49b524271265a0c776e4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 7 Jul 2019 12:43:19 +0200
+Subject: [PATCH] FIX: python3.8 regressions on CI server
+
+Issues w/ python3.8:
+* Traceback: Line numbers of step functions differ (+1)
+* JUnit XML: Attribute ordering of XML element differs (in output)
+---
+ behave.ini                            |  3 +-
+ features/environment.py               | 14 ++++++
+ features/step.duplicated_step.feature | 20 ++++----
+ issue.features/environment.py         | 38 ++++++++++++---
+ issue.features/issue0330.feature      | 64 ++++++++++++++++++++++++
+ issue.features/issue0446.feature      | 70 +++++++++++++++++++++++++++
+ issue.features/issue0457.feature      | 49 +++++++++++++++++++
+ tox.ini                               |  2 +-
+ 8 files changed, 242 insertions(+), 18 deletions(-)
+
+diff --git a/behave.ini b/behave.ini
+index 45c0f0d..952240d 100644
+--- a/behave.ini
++++ b/behave.ini
+@@ -15,8 +15,9 @@ show_skipped = false
+ format   = rerun
+     progress3
+ outfiles = rerun.txt
+-    reports/report_progress3.txt
++    build/behave.reports/report_progress3.txt
+ junit = true
++junit_directory = build/behave.reports
+ logging_level = INFO
+ # logging_format = LOG.%(levelname)-8s  %(name)-10s: %(message)s
+ # logging_format = LOG.%(levelname)-8s  %(asctime)s  %(name)-10s: %(message)s
+diff --git a/features/environment.py b/features/environment.py
+index 4744e89..3769ee4 100644
+--- a/features/environment.py
++++ b/features/environment.py
+@@ -1,5 +1,7 @@
+ # -*- coding: UTF-8 -*-
++# FILE: features/environemnt.py
+ 
++from __future__ import absolute_import, print_function
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+ import platform
+@@ -20,6 +22,15 @@ active_tag_value_provider = {
+ }
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
++def print_active_tags_summary():
++    active_tag_data = active_tag_value_provider
++    print("ACTIVE-TAG SUMMARY:")
++    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
++    # print("use.with_os=%s" % active_tag_data.get("os"))
++    print()
++
++
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+@@ -30,11 +41,14 @@ def before_all(context):
+     setup_python_path()
+     setup_context_with_global_params_test(context)
+     setup_command_shell_processors4behave()
++    print_active_tags_summary()
++
+ 
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/features/step.duplicated_step.feature b/features/step.duplicated_step.feature
+index 59888b0..396cca2 100644
+--- a/features/step.duplicated_step.feature
++++ b/features/step.duplicated_step.feature
+@@ -32,11 +32,11 @@ Feature: Duplicated Step Definitions
+         AmbiguousStep: @given('I call Alice') has already been defined in
+         existing step @given('I call Alice') at features/steps/alice_steps.py:3
+         """
+-    And the command output should contain:
+-        """
+-        File "features/steps/alice_steps.py", line 7, in <module>
+-        @given(u'I call Alice')
+-        """
++    # -- DISABLED: Python 3.8 traceback line numbers differ w/ decorators (+1).
++    # And the command output should contain:
++    #    """
++    #    File "features/steps/alice_steps.py", line 7, in <module>
++    #    """
+ 
+ 
+   Scenario: Duplicated Step Definition in another File
+@@ -70,11 +70,11 @@ Feature: Duplicated Step Definitions
+         AmbiguousStep: @given('I call Bob') has already been defined in
+         existing step @given('I call Bob') at features/steps/bob1_steps.py:3
+         """
+-    And the command output should contain:
+-        """
+-        File "features/steps/bob2_steps.py", line 3, in <module>
+-        @given('I call Bob')
+-        """
++    # -- DISABLED: Python 3.8 traceback line numbers differ w/ decorators (+1).
++    # And the command output should contain:
++    #    """
++    #    File "features/steps/bob2_steps.py", line 3, in <module>
++    #    """
+ 
+   @xfail
+   Scenario: Duplicated Same Step Definition via import from another File
+diff --git a/issue.features/environment.py b/issue.features/environment.py
+index 2dfec75..7e48ee0 100644
+--- a/issue.features/environment.py
++++ b/issue.features/environment.py
+@@ -1,5 +1,5 @@
+ # -*- coding: UTF-8 -*-
+-# FILE: features/environment.py
++# FILE: issue.features/environemnt.py
+ # pylint: disable=unused-argument
+ """
+ Functionality:
+@@ -7,17 +7,20 @@ Functionality:
+   * active tags
+ """
+ 
+-from __future__ import print_function
++
++from __future__ import absolute_import, print_function
+ import sys
+ import platform
+ import os.path
+ import six
+ from behave.tag_matcher import ActiveTagMatcher
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+-# PREPARED:
+-# from behave.tag_matcher import setup_active_tag_values
++# PREPARED: from behave.tag_matcher import setup_active_tag_values
+ 
+ 
++# ---------------------------------------------------------------------------
++# TEST SUPPORT: For Active Tags
++# ---------------------------------------------------------------------------
+ def require_tool(tool_name):
+     """Check if a tool (an executable program) is provided on this platform.
+ 
+@@ -45,12 +48,14 @@ def require_tool(tool_name):
+     # print("TOOL-NOT-FOUND: %s" % tool_name)
+     return False
+ 
++
+ def as_bool_string(value):
+     if bool(value):
+         return "yes"
+     else:
+         return "no"
+ 
++
+ def discover_ci_server():
+     # pylint: disable=invalid-name
+     ci_server = "none"
+@@ -67,12 +72,17 @@ def discover_ci_server():
+     return ci_server
+ 
+ 
++# ---------------------------------------------------------------------------
++# BEHAVE SUPPORT: Active Tags
++# ---------------------------------------------------------------------------
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
++python_version = "%s.%s" % sys.version_info[:2]
+ active_tag_value_provider = {
+     "platform": sys.platform,
+     "python2": str(six.PY2).lower(),
+     "python3": str(six.PY3).lower(),
++    "python.version": python_version,
+     # -- python.implementation: cpython, pypy, jython, ironpython
+     "python.implementation": platform.python_implementation().lower(),
+     "pypy":    str("__pypy__" in sys.modules).lower(),
+@@ -82,17 +92,33 @@ active_tag_value_provider = {
+ }
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
++def print_active_tags_summary():
++    active_tag_data = active_tag_value_provider
++    print("ACTIVE-TAG SUMMARY:")
++    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
++    # print("use.with_platform=%s" % active_tag_data.get("platform"))
++    # print("use.with_os=%s" % active_tag_data.get("os"))
++    print()
++
++
++# ---------------------------------------------------------------------------
++# BEHAVE HOOKS:
++# ---------------------------------------------------------------------------
+ def before_all(context):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+     # USE: behave -D browser=safari ...
+-    # NOT-NEEDED: setup_active_tag_values(active_tag_value_provider,
+-    #                                     context.config.userdata)
++    # NOT-NEEDED:
++    # setup_active_tag_values(active_tag_value_provider, context.config.userdata)
+     setup_command_shell_processors4behave()
++    print_active_tags_summary()
++
+ 
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/issue.features/issue0330.feature b/issue.features/issue0330.feature
+index dc1ebe7..81cb6e2 100644
+--- a/issue.features/issue0330.feature
++++ b/issue.features/issue0330.feature
+@@ -70,6 +70,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+     And note that "bob.feature is skipped"
+ 
+ 
++  @not.with_python.version=3.8
+   Scenario: Junit report for skipped feature is created with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+@@ -83,6 +84,23 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       <testsuite errors="0" failures="0" name="bob.Bob" skipped="1" tests="1" time="0.0">
+       """
+ 
++  @use.with_python.version=3.8
++  Scenario: Junit report for skipped feature is created with --show-skipped
++    When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
++    Then it should pass with:
++      """
++      1 feature passed, 0 failed, 1 skipped
++      """
++    And a file named "test_results/TESTS-alice.xml" exists
++    And a file named "test_results/TESTS-bob.xml" exists
++    And the file "test_results/TESTS-bob.xml" should contain:
++      """
++      <testsuite name="bob.Bob" tests="1" errors="0" failures="0" skipped="1" time="0.0">
++      """
++      # -- HINT FOR: Python < 3.8
++      # <testsuite errors="0" failures="0" name="bob.Bob" skipped="1" tests="1" time="0.0">
++
++  @not.with_python.version=3.8
+   Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+@@ -102,7 +120,30 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       """
+     And note that "Charly2 is the skipped scenarion in charly.feature"
+ 
++  @use.with_python.version=3.8
++  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
++    When I run "behave --junit -t @tag1 --no-skipped"
++    Then it should pass with:
++      """
++      2 features passed, 0 failed, 1 skipped
++      2 scenarios passed, 0 failed, 2 skipped
++      """
++    And a file named "test_results/TESTS-alice.xml" exists
++    And a file named "test_results/TESTS-charly.xml" exists
++    And the file "test_results/TESTS-charly.xml" should contain:
++      """
++      <testsuite name="charly.Charly" tests="1" errors="0" failures="0" skipped="0"
++      """
++      # -- HINT FOR: Python < 3.8
++      # <testsuite errors="0" failures="0" name="charly.Charly" skipped="0" tests="1"
++    And the file "test_results/TESTS-charly.xml" should not contain:
++      """
++      <testcase classname="charly.Charly" name="Charly2"
++      """
++    And note that "Charly2 is the skipped scenarion in charly.feature"
++
+ 
++  @not.with_python.version=3.8
+   Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+@@ -122,3 +163,26 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       """
+     And note that "Charly2 is the skipped scenarion in charly.feature"
+ 
++
++  @use.with_python.version=3.8
++  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
++    When I run "behave --junit -t @tag1 --show-skipped"
++    Then it should pass with:
++      """
++      2 features passed, 0 failed, 1 skipped
++      2 scenarios passed, 0 failed, 2 skipped
++      """
++    And a file named "test_results/TESTS-alice.xml" exists
++    And a file named "test_results/TESTS-charly.xml" exists
++    And the file "test_results/TESTS-charly.xml" should contain:
++      """
++      <testsuite name="charly.Charly" tests="2" errors="0" failures="0" skipped="1"
++      """
++      # HINT: Python < 3.8
++      # <testsuite errors="0" failures="0" name="charly.Charly" skipped="1" tests="2"
++    And the file "test_results/TESTS-charly.xml" should contain:
++      """
++      <testcase classname="charly.Charly" name="Charly2" status="skipped"
++      """
++    And note that "Charly2 is the skipped scenarion in charly.feature"
++
+diff --git a/issue.features/issue0446.feature b/issue.features/issue0446.feature
+index a2ed892..901bdec 100644
+--- a/issue.features/issue0446.feature
++++ b/issue.features/issue0446.feature
+@@ -58,6 +58,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+         behave.reporter.junit.show_hostname = False
+         """
+ 
++    @not.with_python.version=3.8
+     Scenario: Hook error in before_scenario()
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+@@ -86,6 +87,40 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+       And note that "the traceback is contained in the XML element <error/>"
+ 
+ 
++    @use.with_python.version=3.8
++    Scenario: Hook error in before_scenario()
++      When I run "behave -f plain --junit features/before_scenario_failure.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the command output should contain:
++        """
++        HOOK-ERROR in before_scenario: RuntimeError: OOPS
++        """
++      And the file "reports/TESTS-before_scenario_failure.xml" should contain:
++        """
++        <testsuite name="before_scenario_failure.Alice" tests="1" errors="1" failures="0" skipped="0"
++        """
++        # -- HINT FOR: Python < 3.8
++        # <testsuite errors="1" failures="0" name="before_scenario_failure.Alice" skipped="0" tests="1"
++      And the file "reports/TESTS-before_scenario_failure.xml" should contain:
++        """
++        <error type="RuntimeError" message="HOOK-ERROR in before_scenario: RuntimeError: OOPS">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <error message="HOOK-ERROR in before_scenario: RuntimeError: OOPS" type="RuntimeError">
++      And the file "reports/TESTS-before_scenario_failure.xml" should contain:
++        """
++        File "features/environment.py", line 6, in before_scenario
++          cause_hook_failure()
++        File "features/environment.py", line 2, in cause_hook_failure
++          raise RuntimeError("OOPS")
++        """
++      And note that "the traceback is contained in the XML element <error/>"
++
++
++    @not.with_python.version=3.8
+     Scenario: Hook error in after_scenario()
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+@@ -114,3 +149,38 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+           raise RuntimeError("OOPS")
+         """
+       And note that "the traceback is contained in the XML element <error/>"
++
++
++    @use.with_python.version=3.8
++    Scenario: Hook error in after_scenario()
++      When I run "behave -f plain --junit features/after_scenario_failure.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the command output should contain:
++        """
++          Scenario: B1
++            Given another step passes ... passed
++        HOOK-ERROR in after_scenario: RuntimeError: OOPS
++        """
++      And the file "reports/TESTS-after_scenario_failure.xml" should contain:
++        """
++        <testsuite name="after_scenario_failure.Bob" tests="1" errors="1" failures="0" skipped="0"
++        """
++        # -- HINT FOR: Python < 3.8
++        # <testsuite errors="1" failures="0" name="after_scenario_failure.Bob" skipped="0" tests="1"
++      And the file "reports/TESTS-after_scenario_failure.xml" should contain:
++        """
++        <error type="RuntimeError" message="HOOK-ERROR in after_scenario: RuntimeError: OOPS">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <error message="HOOK-ERROR in after_scenario: RuntimeError: OOPS" type="RuntimeError">
++      And the file "reports/TESTS-after_scenario_failure.xml" should contain:
++        """
++        File "features/environment.py", line 10, in after_scenario
++          cause_hook_failure()
++        File "features/environment.py", line 2, in cause_hook_failure
++          raise RuntimeError("OOPS")
++        """
++      And note that "the traceback is contained in the XML element <error/>"
+diff --git a/issue.features/issue0457.feature b/issue.features/issue0457.feature
+index f80640e..46f96e9 100644
+--- a/issue.features/issue0457.feature
++++ b/issue.features/issue0457.feature
+@@ -24,6 +24,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         """
+ 
+ 
++    @not.with_python.version=3.8
+     Scenario: Use failing assertation in a JUnit XML report
+       Given a file named "features/fails1.feature" with:
+         """
+@@ -44,6 +45,31 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         <failure message="FAILED: My name is &quot;Alice&quot;"
+         """
+ 
++    @use.with_python.version=3.8
++    Scenario: Use failing assertation in a JUnit XML report
++      Given a file named "features/fails1.feature" with:
++        """
++        Feature:
++          Scenario: Alice
++            Given a step fails with message:
++              '''
++              My name is "Alice"
++              '''
++        """
++      When I run "behave --junit features/fails1.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the file "reports/TESTS-fails1.xml" should contain:
++        """
++        <failure type="AssertionError" message="FAILED: My name is &quot;Alice&quot;">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <failure message="FAILED: My name is &quot;Alice&quot;"
++
++
++    @not.with_python.version=3.8
+     Scenario: Use exception in a JUnit XML report
+       Given a file named "features/fails2.feature" with:
+         """
+@@ -63,3 +89,26 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         """
+         <error message="My name is &quot;Bob&quot; and &lt;here&gt; I am"
+         """
++
++    @use.with_python.version=3.8
++    Scenario: Use exception in a JUnit XML report
++      Given a file named "features/fails2.feature" with:
++        """
++        Feature:
++          Scenario: Bob
++            Given a step fails with error and message:
++              '''
++              My name is "Bob" and <here> I am
++              '''
++        """
++      When I run "behave --junit features/fails2.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the file "reports/TESTS-fails2.xml" should contain:
++        """
++        <error type="RuntimeError" message="My name is &quot;Bob&quot; and &lt;here&gt; I am">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <error message="My name is &quot;Bob&quot; and &lt;here&gt; I am"
+diff --git a/tox.ini b/tox.ini
+index d2fbce2..b825921 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -28,7 +28,7 @@
+ 
+ [tox]
+ minversion   = 2.3
+-envlist      = py27, py37, py36, py35, py34, py33, pypy, docs
++envlist      = py27, py37, py38, py36, py35, pypy, docs
+ skip_missing_interpreters = True
+ sitepackages = False
+ indexserver =
diff --git a/meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch b/meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch
new file mode 100644
index 000000000..606c1318c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch
@@ -0,0 +1,46 @@
+From ad723ba7e7c2204bbd29115e967d249827d3c8f7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 7 Jul 2019 12:59:57 +0200
+Subject: [PATCH] UPDATE: Mark issue #755 as fixed.
+
+---
+ CHANGES.rst | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d165275..312cbba 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -27,28 +27,25 @@ ENHANCEMENTS:
+ * Use `cucumber-tag-expressions`_ with tag-matching extension (superceeds: old-style tag-expressions)
+ * Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Support emojis in ``*.feature`` files and steps
++* Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+-* Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+-
+-PARTIALLY FIXED:
+-
+-* issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ 
+ FIXED:
+ 
+-* pull  #588: Steps-catalog argument should not break configured rerun settings (provided by: Lego3)
++* issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
+ * pull  #657: Allow async steps with timeouts to fail when they raise exceptions (provided by: ALSchwalm)
+ * issue #631: ScenarioOutline variables not possible in table headings (provided by: mschnelle, pull #642)
+ * issue #619: Context __getattr__ should raise AttributeError instead of KeyError (submitted by: anxodio)
++* pull  #588: Steps-catalog argument should not break configured rerun settings (provided by: Lego3)
+ 
+ MINOR:
+ 
++* pull  #660: Fix minor typos (provided by: rrueth)
+ * pull  #655: Use pytest instead of py.test per upstream recommendation (provided by: scop)
+ * issue #654: tox.ini: pypi.python.org -> pypi.org (submitted by: pradyunsg)
+-* pull  #660: Fix minor typos (provided by: rrueth)
+ 
+ DOCUMENTATION:
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch b/meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch
new file mode 100644
index 000000000..05c33089a
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch
@@ -0,0 +1,57 @@
+From 8c02ce2abbab65cfa4d5b0f306bf9e4735a7195d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 7 Jul 2019 23:35:45 +0200
+Subject: [PATCH] UPDATE: Cucumber gherkin-languages.json
+
+---
+ behave/i18n.py                     | 5 ++++-
+ etc/gherkin/gherkin-languages.json | 6 +++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/behave/i18n.py b/behave/i18n.py
+index 9eb9aab..721c4c3 100644
+--- a/behave/i18n.py
++++ b/behave/i18n.py
+@@ -382,6 +382,9 @@ languages = \
+         'feature': ['Fonctionnalité'],
+         'given': ['* ',
+                   'Soit ',
++                  'Sachant que ',
++                  "Sachant qu'",
++                  'Sachant ',
+                   'Etant donné que ',
+                   "Etant donné qu'",
+                   'Etant donné ',
+@@ -399,7 +402,7 @@ languages = \
+         'rule': ['Règle'],
+         'scenario': ['Exemple', 'Scénario'],
+         'scenario_outline': ['Plan du scénario', 'Plan du Scénario'],
+-        'then': ['* ', 'Alors '],
++        'then': ['* ', 'Alors ', 'Donc '],
+         'when': ['* ', 'Quand ', 'Lorsque ', "Lorsqu'"]},
+  'ga': {'and': ['* ', 'Agus'],
+         'background': ['Cúlra'],
+diff --git a/etc/gherkin/gherkin-languages.json b/etc/gherkin/gherkin-languages.json
+index b08e0f5..913cfac 100644
+--- a/etc/gherkin/gherkin-languages.json
++++ b/etc/gherkin/gherkin-languages.json
+@@ -1256,6 +1256,9 @@
+     "given": [
+       "* ",
+       "Soit ",
++      "Sachant que ",
++      "Sachant qu'",
++      "Sachant ",
+       "Etant donné que ",
+       "Etant donné qu'",
+       "Etant donné ",
+@@ -1284,7 +1287,8 @@
+     ],
+     "then": [
+       "* ",
+-      "Alors "
++      "Alors ",
++      "Donc "
+     ],
+     "when": [
+       "* ",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch b/meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch
new file mode 100644
index 000000000..ebbaa72ed
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch
@@ -0,0 +1,202 @@
+From cf7b144c917f5bc067dd8fd2a4d98c859849dbf0 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 8 Jul 2019 00:38:26 +0200
+Subject: [PATCH] gherkin: Adding Rule keyword translation in portuguese and
+ spanish to gherkin-languages.json
+
+* Integrate changes based on merged cucumber pull-request #621
+* Update "gherkin-languages.json"
+* Update "behave/i18n.py" (generated from: gherkin-languages.json)
+
+RELATED-TO: pull #751 (same; using the official way)
+---
+ CHANGES.rst                        |  1 +
+ behave/fixture.py                  |  1 -
+ behave/i18n.py                     |  4 +--
+ etc/gherkin/gherkin-languages.json |  4 +--
+ invoke.yaml                        |  4 +++
+ tasks/__init__.py                  |  3 ++
+ tasks/develop.py                   | 58 ++++++++++++++++++++++++++++++
+ tasks/py.requirements.txt          |  3 ++
+ 8 files changed, 73 insertions(+), 5 deletions(-)
+ create mode 100644 tasks/develop.py
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 312cbba..15a4ef9 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -43,6 +43,7 @@ FIXED:
+ 
+ MINOR:
+ 
++* pull  #751: gherkin: Adding Rule keyword translation in portuguese and spanish to gherkin-languages.json (provided by: dunossauro)
+ * pull  #660: Fix minor typos (provided by: rrueth)
+ * pull  #655: Use pytest instead of py.test per upstream recommendation (provided by: scop)
+ * issue #654: tox.ini: pypi.python.org -> pypi.org (submitted by: pradyunsg)
+diff --git a/behave/fixture.py b/behave/fixture.py
+index 21093b0..3a9f1bc 100644
+--- a/behave/fixture.py
++++ b/behave/fixture.py
+@@ -348,7 +348,6 @@ def use_composite_fixture_with(context, fixture_funcs_with_params):
+     return composite_fixture
+ 
+ 
+-
+ # -------------------------------------------------------------------------------
+ # DECORATORS:
+ # -------------------------------------------------------------------------------
+diff --git a/behave/i18n.py b/behave/i18n.py
+index 721c4c3..2781afe 100644
+--- a/behave/i18n.py
++++ b/behave/i18n.py
+@@ -331,7 +331,7 @@ languages = \
+         'given': ['* ', 'Dado ', 'Dada ', 'Dados ', 'Dadas '],
+         'name': 'Spanish',
+         'native': 'español',
+-        'rule': ['Rule'],
++        'rule': ['Regla'],
+         'scenario': ['Ejemplo', 'Escenario'],
+         'scenario_outline': ['Esquema del escenario'],
+         'then': ['* ', 'Entonces '],
+@@ -762,7 +762,7 @@ languages = \
+         'given': ['* ', 'Dado ', 'Dada ', 'Dados ', 'Dadas '],
+         'name': 'Portuguese',
+         'native': 'português',
+-        'rule': ['Rule'],
++        'rule': ['Regra'],
+         'scenario': ['Exemplo', 'Cenário', 'Cenario'],
+         'scenario_outline': ['Esquema do Cenário',
+                              'Esquema do Cenario',
+diff --git a/etc/gherkin/gherkin-languages.json b/etc/gherkin/gherkin-languages.json
+index 913cfac..29cbca1 100644
+--- a/etc/gherkin/gherkin-languages.json
++++ b/etc/gherkin/gherkin-languages.json
+@@ -1084,7 +1084,7 @@
+     "name": "Spanish",
+     "native": "español",
+     "rule": [
+-      "Rule"
++      "Regla"
+     ],
+     "scenario": [
+       "Ejemplo",
+@@ -2553,7 +2553,7 @@
+     "name": "Portuguese",
+     "native": "português",
+     "rule": [
+-      "Rule"
++      "Regra"
+     ],
+     "scenario": [
+       "Exemplo",
+diff --git a/invoke.yaml b/invoke.yaml
+index 3e93cfc..d6f141c 100644
+--- a/invoke.yaml
++++ b/invoke.yaml
+@@ -38,6 +38,10 @@ cleanup:
+       - "__WORKDIR__"
+       - reports
+ 
++    extra_files:
++      - "etc/gherkin/gherkin*.json.SAVED"
++      - "etc/gherkin/i18n.py"
++
+ cleanup_all:
+     extra_directories:
+       - .hypothesis
+diff --git a/tasks/__init__.py b/tasks/__init__.py
+index 969a94a..a572465 100644
+--- a/tasks/__init__.py
++++ b/tasks/__init__.py
+@@ -39,6 +39,8 @@ from . import _tasklet_cleanup as cleanup
+ from . import docs
+ from . import test
+ from . import release
++from . import develop
++
+ 
+ # -----------------------------------------------------------------------------
+ # TASKS:
+@@ -56,6 +58,7 @@ namespace.add_collection(Collection.from_module(cleanup), name="cleanup")
+ namespace.add_collection(Collection.from_module(docs))
+ namespace.add_collection(Collection.from_module(test))
+ namespace.add_collection(Collection.from_module(release))
++namespace.add_collection(Collection.from_module(develop))
+ cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+ 
+ cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+diff --git a/tasks/develop.py b/tasks/develop.py
+new file mode 100644
+index 0000000..b08df0e
+--- /dev/null
++++ b/tasks/develop.py
+@@ -0,0 +1,58 @@
++# -*- coding: UTF-8 -*-
++"""
++Development tasks
++"""
++
++from __future__ import absolute_import, print_function
++from invoke import Collection, task
++from invoke.util import cd
++from path import Path
++import requests
++
++# -----------------------------------------------------------------------------
++# CONSTANTS:
++# -----------------------------------------------------------------------------
++GHERKIN_LANGUAGES_URL = "https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/gherkin-languages.json"
++
++
++# -----------------------------------------------------------------------------
++# TASKS:
++# -----------------------------------------------------------------------------
++@task(name="update_gherkin") # TOO-LONGS: aliases=["update_gherkin_languages"])
++def update_gherkin_languages(ctx):
++    """Update "gherkin-languages.json" file from cucumber-repo."""
++    with cd("etc/gherkin"):
++        # -- BACKUP-FILE:
++        gherkin_languages_file = Path("gherkin-languages.json")
++        gherkin_languages_file.copy("gherkin-languages.json.SAVED")
++
++        print('Downloading "gherkin-languages.json" from github:cucumber ...')
++        download_request = requests.get(GHERKIN_LANGUAGES_URL)
++        gherkin_languages_newfile = Path("gherkin-languages.json.NEW")
++        assert download_request.ok
++        print('Download finished: OK (size={0})'.format(len(download_request.content)))
++        with open(gherkin_languages_newfile, "wb") as f:
++            f.write(download_request.content)
++        gherkin_languages_newfile.rename("gherkin-languages.json")
++
++        print('Generating "i18n.py" ...')
++        ctx.run("./convert_gherkin-languages.py")
++
++
++# -----------------------------------------------------------------------------
++# TASK HELPERS:
++# -----------------------------------------------------------------------------
++def print_packages(packages):
++    print("PACKAGES[%d]:" % len(packages))
++    for package in packages:
++        package_size = package.stat().st_size
++        package_time = package.stat().st_mtime
++        print("  - %s  (size=%s)" % (package, package_size))
++
++
++# -----------------------------------------------------------------------------
++# TASK CONFIGURATION:
++# -----------------------------------------------------------------------------
++namespace = Collection()
++namespace.add_task(update_gherkin_languages)
++namespace.configure({})
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index e772d5e..a77d3bc 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -16,3 +16,6 @@ six >= 1.12.0
+ # -- PYTHON2 BACKPORTS:
+ pathlib;    python_version <= '3.4'
+ backports.shutil_which; python_version <= '3.3'
++
++# -- SECTION: develop
++requests
diff --git a/meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch b/meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch
new file mode 100644
index 000000000..939a0901e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch
@@ -0,0 +1,141 @@
+From 084f823fda5939442f48eb34d99c0ed48d675097 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 8 Jul 2019 01:07:11 +0200
+Subject: [PATCH] Tweaks to update/generate from gherkin-languages.json
+
+---
+ etc/gherkin/convert_gherkin-languages.py | 16 +++++++----
+ tasks/develop.py                         | 34 +++++++++++-------------
+ 2 files changed, 27 insertions(+), 23 deletions(-)
+
+diff --git a/etc/gherkin/convert_gherkin-languages.py b/etc/gherkin/convert_gherkin-languages.py
+index 1803ca6..9ef9b0c 100755
+--- a/etc/gherkin/convert_gherkin-languages.py
++++ b/etc/gherkin/convert_gherkin-languages.py
+@@ -68,7 +68,7 @@ def yaml_normalize(data):
+     return data
+ 
+ 
+-def data_normalize(data):
++def data_normalize(data, verbose=False):
+     """Normalize "gherkin-languages.json" data into internal format,
+     needed by behave."
+ 
+@@ -76,7 +76,8 @@ def data_normalize(data):
+     :return: Normalized data (as dictionary).
+     """
+     for language in data:
+-        print("Language: %s ..." % language)
++        if verbose:
++            print("Language: %s ..." % language)
+         # -- STEP: Normalize attribute "scenarioOutline" => "scenario_outline"
+         lang_keywords = data[language]
+         lang_keywords[u"scenario_outline"] = lang_keywords[u"scenarioOutline"]
+@@ -107,7 +108,7 @@ def data_normalize(data):
+ 
+ 
+ def gherkin_languages_to_python_module(gherkin_languages_path, output_file=None,
+-                                       encoding=None):
++                                       encoding=None, verbose=False):
+     """Workhorse.
+     Performs the conversion from "gherkin-languages.json" to "i18n.py".
+     Writes output to file or console (stdout).
+@@ -115,6 +116,7 @@ def gherkin_languages_to_python_module(gherkin_languages_path, output_file=None,
+     :param gherkin_languages_path: File path for JSON file.
+     :param output_file:     Output filename (or STDOUT for: None, "stdout", "-")
+     :param encoding:        Optional output encoding to use (default: UTF-8).
++    :param verbose:         Enable verbose mode (as bool; optional).
+     """
+     if encoding is None:
+         encoding = "UTF-8"
+@@ -122,7 +124,7 @@ def gherkin_languages_to_python_module(gherkin_languages_path, output_file=None,
+     # -- STEP 1: Load JSON data.
+     json_encoding = "UTF-8"
+     languages = json.load(open(gherkin_languages_path, encoding=json_encoding))
+-    languages = data_normalize(languages)
++    languages = data_normalize(languages, verbose=verbose)
+     # languages = yaml_normalize(languages)
+ 
+     # -- STEP 2: Generate python module with i18n data.
+@@ -178,6 +180,9 @@ def main(args=None):
+     parser.add_argument("-e", "--encoding", dest="encoding",
+                         default="UTF-8",
+                         help="Output encoding.")
++    parser.add_argument("--verbose", dest="verbose", default=False,
++                        action="store_true",
++                        help="Enable verbose mode.")
+     parser.add_argument("output_file", default="i18n.py", nargs="?",
+                 help="Filename of Python I18N module (as output).")
+     parser.add_argument("--version", action="version", version=__version__)
+@@ -191,7 +196,8 @@ def main(args=None):
+     try:
+         print("Writing %s .." % options.output_file)
+         gherkin_languages_to_python_module(options.json_file, options.output_file,
+-                                           encoding=options.encoding)
++                                           encoding=options.encoding,
++                                           verbose=options.verbose)
+     except Exception as e:
+         message = "%s: %s" % (e.__class__.__name__, e)
+         sys.exit(message)
+diff --git a/tasks/develop.py b/tasks/develop.py
+index b08df0e..9a21363 100644
+--- a/tasks/develop.py
++++ b/tasks/develop.py
+@@ -18,9 +18,15 @@ GHERKIN_LANGUAGES_URL = "https://raw.githubusercontent.com/cucumber/cucumber/mas
+ # -----------------------------------------------------------------------------
+ # TASKS:
+ # -----------------------------------------------------------------------------
+-@task(name="update_gherkin") # TOO-LONGS: aliases=["update_gherkin_languages"])
+-def update_gherkin_languages(ctx):
+-    """Update "gherkin-languages.json" file from cucumber-repo."""
++@task
++def update_gherkin(ctx, dry_run=False):
++    """Update "gherkin-languages.json" file from cucumber-repo.
++
++    * Download "gherkin-languages.json" from cucumber repo
++    * Update "gherkin-languages.json"
++    * Generate "i18n.py" file from "gherkin-languages.json"
++    * Update "behave/i18n.py" file (optional; not in dry-run mode)
++    """
+     with cd("etc/gherkin"):
+         # -- BACKUP-FILE:
+         gherkin_languages_file = Path("gherkin-languages.json")
+@@ -28,31 +34,23 @@ def update_gherkin_languages(ctx):
+ 
+         print('Downloading "gherkin-languages.json" from github:cucumber ...')
+         download_request = requests.get(GHERKIN_LANGUAGES_URL)
+-        gherkin_languages_newfile = Path("gherkin-languages.json.NEW")
+         assert download_request.ok
+         print('Download finished: OK (size={0})'.format(len(download_request.content)))
+-        with open(gherkin_languages_newfile, "wb") as f:
++        with open(gherkin_languages_file, "wb") as f:
+             f.write(download_request.content)
+-        gherkin_languages_newfile.rename("gherkin-languages.json")
+ 
+         print('Generating "i18n.py" ...')
+         ctx.run("./convert_gherkin-languages.py")
+-
+-
+-# -----------------------------------------------------------------------------
+-# TASK HELPERS:
+-# -----------------------------------------------------------------------------
+-def print_packages(packages):
+-    print("PACKAGES[%d]:" % len(packages))
+-    for package in packages:
+-        package_size = package.stat().st_size
+-        package_time = package.stat().st_mtime
+-        print("  - %s  (size=%s)" % (package, package_size))
++        ctx.run("diff i18n.py ../../behave/i18n.py")
++        if not dry_run:
++            print("Updating behave/i18n.py ...")
++            Path("i18n.py").move("../../behave/i18n.py")
+ 
+ 
+ # -----------------------------------------------------------------------------
+ # TASK CONFIGURATION:
+ # -----------------------------------------------------------------------------
++# TOO-LONG: aliases=["update_gherkin_languages"])
+ namespace = Collection()
+-namespace.add_task(update_gherkin_languages)
++namespace.add_task(update_gherkin)
+ namespace.configure({})
diff --git a/meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch b/meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch
new file mode 100644
index 000000000..8d956cdd5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch
@@ -0,0 +1,322 @@
+From d3ef06c2dfe44b2286b42b7ddcc66f7c9e6aa245 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 9 Jul 2019 08:10:26 +0200
+Subject: [PATCH] EXAMPLE: Tweak naming to @fixture.behave.no_background (was:
+ .override_background)
+
+---
+ examples/fixture.no_background/README.rst     | 110 ++++++++++++++++++
+ .../behave_fixture_lib/__init__.py            |   0
+ .../behave_fixture_lib/no_background.py       |  72 ++++++++++++
+ .../features/environment.py                   |  35 ++++++
+ .../features/example.feature                  |  18 +++
+ .../features/steps/basic_steps.py             |  13 +++
+ .../features/steps/use_steplib_behave4cmd.py  |  12 ++
+ 7 files changed, 260 insertions(+)
+ create mode 100644 examples/fixture.no_background/README.rst
+ create mode 100644 examples/fixture.no_background/behave_fixture_lib/__init__.py
+ create mode 100644 examples/fixture.no_background/behave_fixture_lib/no_background.py
+ create mode 100644 examples/fixture.no_background/features/environment.py
+ create mode 100644 examples/fixture.no_background/features/example.feature
+ create mode 100644 examples/fixture.no_background/features/steps/basic_steps.py
+ create mode 100644 examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py
+
+diff --git a/examples/fixture.no_background/README.rst b/examples/fixture.no_background/README.rst
+new file mode 100644
+index 0000000..4243f10
+--- /dev/null
++++ b/examples/fixture.no_background/README.rst
+@@ -0,0 +1,110 @@
++EXAMPLE: Disable Background Inheritance Mechanism for Scenario
++===============================================================================
++
++:RELATED-TO: #756
++
++This example shows how the Background inheritance mechanism in Gherkin
++can be disabled in ``behave``.
++
++Parts of the recipe:
++
++* features/example.feature (Feature file as example)
++* features/environment.py (glue code and hooks for fixture-tag / fixture)
++* behave_fixture_lib/no_background.py (fixture implementation, workhorse)
++
++
++.. warning:: BEWARE: This shows you how can do it, not that you should do it
++
++    BETTER:
++
++    * Use Rules to group Scenarios, each with its own Background (in Gherkin v6)
++    * Split Feature aspects into multiple feature files (if needed)
++    * ... (see issue #756 above)
++
++
++Explanation
++------------------------------------------------------------------------
++
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism by using a fixture / fixture-tag.
++The fixture-tag "@fixture.behave.no_background" marks the
++location in Gherkin (which Scenario) where the fixture should be used
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.no_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.no_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++When the feature is executed, you see that:
++
++* First Scenario "Alice": Background steps are inherited and executed first.
++* Second Scenario "Bob": No Background step is executed.
++
++.. code-block:: sh
++
++    $ ../../bin/behave -f plain features/example.feature
++    Feature: Override the Background Inheritance Mechanism in some Scenarios
++      Background:
++
++      Scenario: Alice
++        Given a background step passes ... passed
++        When a step passes ... passed
++        And note that "Background steps are executed here" ... passed
++    FIXTURE-HINT: DISABLE-BACKGROUND FOR: Bob
++
++      Scenario: Bob
++        Given I need another scenario setup ... passed
++        When another step passes ... passed
++        And note that "NO-BACKGROUND STEPS are executed here" ... passed
++
++    1 feature passed, 0 failed, 0 skipped
++    2 scenarios passed, 0 failed, 0 skipped
++    6 steps passed, 0 failed, 0 skipped, 0 undefined
++
++
++The environment file provides the glue code that the fixture is called:
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.no_background import behave_no_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.no_background": behave_no_background,
++    }
++
++    # -----------------------------------------------------------------------------
++    # HOOKS:
++    # -----------------------------------------------------------------------------
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++
++.. code-block:: python
++
++    # -- FILE: behave_fixture_lib/no_background.py (fixture implementation)
++    from behave import fixture
++
++    @fixture(name="fixture.behave.no_background")
++    def behave_no_background(ctx):
++        # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++        current_scenario = ctx.scenario
++        if current_scenario:
++            print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % current_scenario.name)
++            current_scenario.use_background = False
+diff --git a/examples/fixture.no_background/behave_fixture_lib/__init__.py b/examples/fixture.no_background/behave_fixture_lib/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/examples/fixture.no_background/behave_fixture_lib/no_background.py b/examples/fixture.no_background/behave_fixture_lib/no_background.py
+new file mode 100644
+index 0000000..47bd0b5
+--- /dev/null
++++ b/examples/fixture.no_background/behave_fixture_lib/no_background.py
+@@ -0,0 +1,72 @@
++# -*- coding: UTF-8 -*-
++# RELATED-TO: #756
++"""
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism.
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.override_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.no_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.override_background import behave_override_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.no_background": behave_override_background,
++    }
++
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++"""
++
++from __future__ import absolute_import, print_function
++from behave import fixture
++
++
++# -----------------------------------------------------------------------------
++# BEHAVE FIXTURES:
++# -----------------------------------------------------------------------------
++@fixture(name="fixture.behave.ono_background")
++def behave_no_background(ctx):
++    """Override the Background inherintance mechanism.
++    If a Feature / Rule Background exists in a Feature,
++    all contained Scenarios inherit the Background's steps.
++
++    This fixture disables this mechanism.
++    The tagged Gherkin element will no longer inherit the background steps.
++
++    :param ctx: Context object to use (during a test run).
++    """
++    # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++    current_scenario = ctx.scenario
++    if current_scenario:
++        print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % current_scenario.name)
++        current_scenario.use_background = False
++
++
++# -----------------------------------------------------------------------------
++# MODULE SPECIFIC:
++# -----------------------------------------------------------------------------
++fixture_registry = {
++    "fixture.behave.no_background": behave_no_background,
++}
+diff --git a/examples/fixture.no_background/features/environment.py b/examples/fixture.no_background/features/environment.py
+new file mode 100644
+index 0000000..18857b9
+--- /dev/null
++++ b/examples/fixture.no_background/features/environment.py
+@@ -0,0 +1,35 @@
++# -*- coding: UTF-8 -*-
++# -- FILE: features/environment.py
++import os.path
++import sys
++
++# -----------------------------------------------------------------------------
++# PYTHON PATH SETUP:
++# -----------------------------------------------------------------------------
++HERE = os.path.dirname(__file__)
++TOPA = os.path.abspath(os.path.join(HERE, ".."))
++
++def setup_python_path():
++    sys.path.insert(0, TOPA)
++
++setup_python_path()
++
++# -----------------------------------------------------------------------------
++# NORMAL PART:
++# -----------------------------------------------------------------------------
++from behave_fixture_lib.no_background import behave_no_background
++from behave.fixture import use_fixture_by_tag
++
++# -- FIXTURE REGISTRY:
++fixture_registry = {
++    "fixture.behave.no_background": behave_no_background,
++}
++
++
++# -----------------------------------------------------------------------------
++# HOOKS:
++# -----------------------------------------------------------------------------
++def before_tag(context, tag):
++    if tag.startswith("fixture."):
++        return use_fixture_by_tag(tag, context, fixture_registry)
++
+diff --git a/examples/fixture.no_background/features/example.feature b/examples/fixture.no_background/features/example.feature
+new file mode 100644
+index 0000000..2025716
+--- /dev/null
++++ b/examples/fixture.no_background/features/example.feature
+@@ -0,0 +1,18 @@
++Feature: Disable the Background Inheritance Mechanism in some Scenarios
++
++  . BEWARE:
++  .   This is only an example how this can be done (PROOF-OF-CONCEPT).
++  .   This is not an example that you should do this !!!
++
++    Background:
++      Given a background step passes
++
++    Scenario: Alice
++      When a step passes
++      And note that "BACKGROUND STEPS are executed here"
++
++    @fixture.behave.no_background
++    Scenario: Bob
++      Given I need another scenario setup
++      When another step passes
++      And note that "NO-BACKGROUND STEPS are executed here"
+diff --git a/examples/fixture.no_background/features/steps/basic_steps.py b/examples/fixture.no_background/features/steps/basic_steps.py
+new file mode 100644
+index 0000000..34f2107
+--- /dev/null
++++ b/examples/fixture.no_background/features/steps/basic_steps.py
+@@ -0,0 +1,13 @@
++from behave import given, step
++
++# @step(u'{word} step passes')
++# def step_passes_with_word(context, word):
++#     pass
++
++@step(u'{word} background step passes')
++def step_background_step_passes(context, word):
++    pass
++
++@given(u'I need {word} scenario setup')
++def step_given_i_need_scenario_setup(context, word):
++    pass
+diff --git a/examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py b/examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py
+new file mode 100644
+index 0000000..bc32a32
+--- /dev/null
++++ b/examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py
+@@ -0,0 +1,12 @@
++# -*- coding: utf-8 -*-
++"""
++Use behave4cmd0 step library (predecessor of behave4cmd).
++"""
++
++from __future__ import absolute_import
++
++# -- REGISTER-STEPS FROM STEP-LIBRARY:
++# import behave4cmd0.__all_steps__
++# import behave4cmd0.failing_steps
++import behave4cmd0.passing_steps
++import behave4cmd0.note_steps
diff --git a/meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch b/meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch
new file mode 100644
index 000000000..b630d48e7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch
@@ -0,0 +1,64 @@
+From b52d7c5d0141971f2e745ec806f829e2c7c897cf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 9 Jul 2019 08:20:25 +0200
+Subject: [PATCH] EXAMPLE: Cleanup Gherkin v6 README
+
+---
+ examples/gherkin_v6/README.rst                | 23 +++++++++++--------
+ .../features/steps/passing_steps.py           | 11 +++++++++
+ 2 files changed, 25 insertions(+), 9 deletions(-)
+ create mode 100644 examples/gherkin_v6/features/steps/passing_steps.py
+
+diff --git a/examples/gherkin_v6/README.rst b/examples/gherkin_v6/README.rst
+index 58199dd..99af1c5 100644
+--- a/examples/gherkin_v6/README.rst
++++ b/examples/gherkin_v6/README.rst
+@@ -2,17 +2,22 @@ Gherkin v6 Examples
+ =============================================================================
+ 
+ 
+-SCRATCHPAD: Problems
+------------------------------------------------------------------------------
++Provides example(s) of Gherkin v6 additions:
+ 
+-- SummaryReporter: Shows wrong counts when Rules are present::
++* Rule concept
++* New aliases for Gherkin keywords (Scenario, ScenarioOutline)
+ 
+-    ...
+-    0 features passed, 0 failed, 1 skipped XXX
+-    3 rules passed, 0 failed, 0 skipped
+-    5 scenarios passed, 0 failed, 0 skipped
+-    13 steps passed, 0 failed, 0 skipped, 0 undefined
++Rule functionality:
+ 
++* A Rule is a scenario container similar to a Feature
++* A Feature may contain many Rules
++* A Rule may not contain other Rules
++* A Rule may contain a Background (and inherits its Feature Background)
++* A Rule inherits its Feature Background if it has no Background
++* A Rule may contain many Scenarios and/or ScenarioOutlines
++* A Rule may have tags
+ 
+-- Formatters: PrettyFormatter, PlainFormatter (at least) need Rule support
++New keyword aliases:
+ 
++* "Scenario Template" for "Scenario Outline"
++* "Example" for "Scenario"
+diff --git a/examples/gherkin_v6/features/steps/passing_steps.py b/examples/gherkin_v6/features/steps/passing_steps.py
+new file mode 100644
+index 0000000..2714cb1
+--- /dev/null
++++ b/examples/gherkin_v6/features/steps/passing_steps.py
+@@ -0,0 +1,11 @@
++# -*- coding: UTF-8 -*-
++
++from behave import step
++
++@step(u'{word} step passes')
++def step_passes(ctx, word):
++    pass
++
++@step(u'{word} step fails')
++def step_fails(ctx, word):
++    assert False, "XFAIL-STEP: {0} step fails".format(word)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch b/meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch
new file mode 100644
index 000000000..764ff7869
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch
@@ -0,0 +1,1510 @@
+From 4f013b949f6528ec70105c1fb8e292f23e3a13c8 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 10 Jul 2019 22:38:13 +0200
+Subject: [PATCH] Improve support for feature.background inheritance for
+ rule.background.
+
+---
+ .gitignore                                    |   3 +
+ behave/model.py                               | 230 ++++++++++--
+ behave/parser.py                              |   9 +-
+ .../fixture.override_background/README.rst    | 116 ------
+ .../behave_fixture_lib/__init__.py            |   0
+ .../behave_fixture_lib/override_background.py |  80 -----
+ .../features/environment.py                   |  35 --
+ .../features/example.feature                  |  18 -
+ .../features/steps/basic_steps.py             |  13 -
+ .../features/steps/use_steplib_behave4cmd.py  |  12 -
+ setup.py                                      |   1 +
+ tests/unit/test_model.py                      | 117 +-----
+ tests/unit/test_model2.py                     |   4 -
+ tests/unit/test_model_core.py                 | 116 +++++-
+ tests/unit/test_parser_gherkin_v6.py          | 339 +++++++++++++++++-
+ 15 files changed, 645 insertions(+), 448 deletions(-)
+ delete mode 100644 examples/fixture.override_background/README.rst
+ delete mode 100644 examples/fixture.override_background/behave_fixture_lib/__init__.py
+ delete mode 100644 examples/fixture.override_background/behave_fixture_lib/override_background.py
+ delete mode 100644 examples/fixture.override_background/features/environment.py
+ delete mode 100644 examples/fixture.override_background/features/example.feature
+ delete mode 100644 examples/fixture.override_background/features/steps/basic_steps.py
+ delete mode 100644 examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+
+diff --git a/.gitignore b/.gitignore
+index 6196a6d..9c5c33d 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -7,6 +7,9 @@ build/
+ dist/
+ __pycache__/
+ __WORKDIR__/
++__*/
++__*.txt
++__*.rst
+ _build/
+ _WORKSPACE/
+ reports/
+diff --git a/behave/model.py b/behave/model.py
+index 7fc534a..69f38ab 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -29,6 +29,36 @@ else:
+     import traceback
+ 
+ 
++# ---------------------------------------------------------------------------
++# MODEL UTILITIES:
++# ---------------------------------------------------------------------------
++def reset_steps(steps):
++    for step in steps:
++        step.reset()
++    return steps
++
++
++def copy_steps(steps):
++    """Copy steps; needed if steps should be used in multiple run contexts.
++
++    :param steps:       List of steps to copy.
++    :return: List of copied steps.
++    """
++    return [copy.copy(step) for step in steps]
++
++
++def copy_and_reset_steps(steps):
++    """Copy steps and reset each step (status, duration, etc.)
++
++    :param steps:       List of steps to copy.
++    :return: List of copied steps.
++    """
++    return reset_steps(copy_steps(steps))
++
++
++# ---------------------------------------------------------------------------
++# MODEL CLASSES:
++# ---------------------------------------------------------------------------
+ class ScenarioContainer(TagAndStatusStatement, Replayable):
+     """Abstract base class for model elements
+     that contains the following structure:
+@@ -198,8 +228,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+         if skipped:
+             return Status.skipped
+-        else:
+-            return Status.passed
++        # -- OTHERWISE:
++        return Status.passed
+ 
+     @property
+     def duration(self):
+@@ -230,7 +260,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+                 rule = run_item
+                 if with_rules:
+                     all_scenarios.append(rule)
+-                all_scenarios.extend(rule.walk_scenarios(with_outlines=with_outlines))
++                scenarios = rule.walk_scenarios(with_outlines=with_outlines)
++                all_scenarios.extend(scenarios)
+             elif isinstance(run_item, ScenarioOutline):
+                 scenario_outline = run_item
+                 if with_outlines:
+@@ -241,6 +272,16 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+                 all_scenarios.append(run_item)
+         return all_scenarios
+ 
++    def iter_scenarios(self):
++        return iter(self.walk_scenarios())
++
++    def iter_scenario_outlines(self):
++        return iter([x for x in self.walk_scenarios(with_outlines=True)
++                     if isinstance(x, ScenarioOutline)])
++
++    def iter_rules(self):
++        return iter([x for x in self.run_items if isinstance(x, Rule)])
++
+     def should_run(self, config=None):
+         """
+         Determines if this Feature (and its scenarios) should run.
+@@ -312,7 +353,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         :param runner:  Runner to use.
+         :return: True, if test-run failed.
+         """
+-        # pylint: disable=too-many-branches
++        # pylint: disable=too-many-branches, too-many-locals, too-many-statements
+         # MAYBE: self.reset()
+         self.clear_status()
+         self.hook_failed = False
+@@ -387,7 +428,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         # -- PERFORM CONTEXT CLEANUP: May raise cleanup errors.
+         try:
+             runner.context._pop()       # pylint: disable=protected-access
+-        except Exception:
++        except Exception:               # pylint: disable=broad-except
+             # -- CLEANUP-ERROR:
+             self.set_status(Status.failed)
+ 
+@@ -509,16 +550,28 @@ class Feature(ScenarioContainer):
+     def _setup_context_for_run(self, context):
+         context.feature = self
+ 
++    def add_background(self, background):
++        self.background = background
++        self.background.parent = self
++
+     def add_rule(self, rule):
+-        """Add a rule to this feature."""
++        """Add a rule to this feature (supported in: Gherkin v6).
++
++        .. versionadded: 1.2.7
++        """
+         feature = self
+         rule.parent = feature
+         rule.feature = feature
+-        if not rule.background:
+-            # -- MAYBE: Inherit feature.background if the rule has no background.
+-            rule.background = self.background
+         self.rules.append(rule)
+         self.run_items.append(rule)
++        if self.background:
++            # -- ENSURE: Rule inherits feature.background.
++            if not rule.background:
++                # -- ENSURE: Rule has a default background.
++                # Necessary to inherit feature.background (or disable it).
++                rule_default_background = Background(rule.filename, rule.line)
++                rule.add_background(rule_default_background)
++            rule.background.inherited_background = self.background
+ 
+ 
+ class Rule(ScenarioContainer):
+@@ -630,6 +683,7 @@ class Rule(ScenarioContainer):
+                                    description, scenarios, background)
+         self.parent = parent
+         self.feature = parent
++        self._use_background_inheritance = True
+ 
+     def _setup_context_for_run(self, context):
+         context.rule = self
+@@ -638,10 +692,43 @@ class Rule(ScenarioContainer):
+         return '<Rule "%s": %d scenario(s)>' % \
+             (self.name, len(self.scenarios))
+ 
++    def add_background(self, background, inherited=None):
++        if inherited is None:
++            feature = self.feature or self.parent
++            inherited = feature.background
++
++        self.background = background
++        self.background.inherited_background = inherited
++        self.background.use_inheritance = self.use_background_inheritance
++        self.background.parent = self
++        # -- ENSURE: Normally background is added before scenarios.
++        for scenario in self.walk_scenarios():
++            scenario.background = self.background
++
++    @property
++    def use_background_inheritance(self):
++        return self._use_background_inheritance
++
++    @use_background_inheritance.setter
++    def use_background_inheritance(self, value):
++        self._use_background_inheritance = value
++        if self.background:
++            self.background.use_inheritance = value
++
+ 
+ class Background(BasicStatement, Replayable):
+     """A `background`_ parsed from a *feature file*.
+ 
++    Behaviour:
++
++    * Each scenario of a scenario container (Feature, Rule)
++      inherits the Background of its scenario container
++    * Background steps in a scenario are executed before scenario steps
++    * Rule Background inherits the Feature Background (outer background) if any
++    * Inherited Background steps are used/executed first
++    * Optionally, background inheritance can be disabled
++      (normally: by using a fixture/fixture-tag)
++
+     The attributes are:
+ 
+     .. attribute:: keyword
+@@ -679,23 +766,65 @@ class Background(BasicStatement, Replayable):
+ 
+     .. _`background`: gherkin.html#backgrounds
+     """
+-    # TODO: Background inheritance
+-    # Rule.background should inherit its Feature.background steps (if available)
+-    # Rule.background = Feature.background iff not Rule.background exists (ALREADY-SOLVED)
+-    # Rule may override background inheritance mechanism
+     type = "background"
+ 
+-    def __init__(self, filename, line, keyword, name, steps=None, description=None):
++    def __init__(self, filename, line, keyword=u"Background", name=u"",
++                 steps=None, description=None):
+         super(Background, self).__init__(filename, line, keyword, name)
+         self.description = description or []
+         self.steps = steps or []
++        self.inherited_background = None
++        self._inherited_steps = None
++        self._use_inheritance = True
+ 
+-    def __repr__(self):
+-        return '<Background "%s">' % self.name
++    @property
++    def use_inheritance(self):
++        """Indicates if this Background should inherit from an outer Background.
++        Background inheritance mechanism is enabled (per default).
++        Optionally, this mechanism can be disabled (or overridden).
+ 
+-    def __iter__(self):
++        :return: Current background inheritance state (as bool).
++
++        .. versionadded:: 1.2.7
++        """
++        return self._use_inheritance
++
++    @use_inheritance.setter
++    def use_inheritance(self, value):
++        """Enable/disable background inheritance mechanism for this Background.
++
++        :param value:   New value (as bool).
++
++        .. versionadded:: 1.2.7
++        """
++        # -- ENSURE: inherited_steps are reinitialized (later).
++        self._use_inheritance = bool(value)
++        self._inherited_steps = None
++
++    @property
++    def inherited_steps(self):
++        # versionadded:: 1.2.7
++        if self._inherited_steps is None:
++            # -- LAZY-INIT: Support enable/disable the inheritance mechanism.
++            steps = []
++            if self.inherited_background and self._use_inheritance:
++                steps = copy_and_reset_steps(self.inherited_background.steps)
++            self._inherited_steps = steps
++        return self._inherited_steps
++
++    def iter_steps(self):
++        """Returns iterator to all steps, including inherited steps (if any).
++
++        .. versionadded:: 1.2.7
++        """
++        if self.inherited_steps:
++            return itertools.chain(self.inherited_steps, self.steps)
+         return iter(self.steps)
+ 
++    @property
++    def all_steps(self):
++        return self.iter_steps()
++
+     @property
+     def duration(self):
+         duration = 0
+@@ -703,6 +832,12 @@ class Background(BasicStatement, Replayable):
+             duration += step.duration
+         return duration
+ 
++    def __repr__(self):
++        return '<Background "%s">' % self.name
++
++    def __iter__(self):
++        return self.iter_steps()
++
+ 
+ class Scenario(TagAndStatusStatement, Replayable):
+     """A `scenario`_ parsed from a *feature file*.
+@@ -799,6 +934,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+         self.feature = None  # REFER-TO: owner=Feature
+         self.hook_failed = False
+         self._background_steps = None
++        self._use_background = True
+         self._row = None
+         self.was_dry_run = False
+ 
+@@ -813,6 +949,27 @@ class Scenario(TagAndStatusStatement, Replayable):
+         for step in self.all_steps:
+             step.reset()
+ 
++    @property
++    def use_background(self):
++        """Indicates if the background is/would be used (if any exists).
++        NOTE: The Background (steps) are normally used.
++
++        .. versionadded:: 1.2.7
++        """
++        return self._use_background
++
++    @use_background.setter
++    def use_background(self, value):
++        """Enable/disable the usage of the background (steps).
++
++        :param value:  New value (as bool).
++
++        .. versionadded:: 1.2.7
++        """
++        # -- ENSURE: background_steps are reinitialized.
++        self._use_background = value
++        self._background_steps = None
++
+     @property
+     def background_steps(self):
+         """Provide background steps if feature/rule has a background.
+@@ -828,24 +985,29 @@ class Scenario(TagAndStatusStatement, Replayable):
+             # Each scenario needs own background.steps.
+             # Otherwise, background step status of the last-run scenario is used.
+             steps = []
+-            if self.background:
+-                steps = [copy.copy(step) for step in self.background.steps]
++            if self.background and self.use_background:
++                steps = copy_and_reset_steps(self.background.all_steps)
+             self._background_steps = steps
+         return self._background_steps
+ 
+-    @property
+-    def all_steps(self):
+-        """Returns iterator to all steps, including background steps if any."""
++    def iter_steps(self):
++        """Returns iterator to all steps, including background steps if any.
++
++        .. versionadded:: 1.2.7
++        """
+         if self.background is not None:
+             return itertools.chain(self.background_steps, self.steps)
+-        else:
+-            return iter(self.steps)
++        return iter(self.steps)
++
++    @property
++    def all_steps(self):
++        return self.iter_steps()
+ 
+     def __repr__(self):
+         return '<Scenario "%s">' % self.name
+ 
+     def __iter__(self):
+-        return self.all_steps
++        return self.iter_steps()
+ 
+     def compute_status(self):
+         """Compute the status of the scenario from its steps
+@@ -862,9 +1024,8 @@ class Scenario(TagAndStatusStatement, Replayable):
+                     # -- SPECIAL CASE: In dry-run with undefined-step discovery
+                     #    Undefined steps should not cause failed scenario.
+                     return Status.untested
+-                else:
+-                    # -- NORMALLY: Undefined steps cause failed scenario.
+-                    return Status.failed
++                # -- NORMALLY: Undefined steps cause failed scenario.
++                return Status.failed
+             elif step.status != Status.passed:
+                 # pylint: disable=line-too-long
+                 assert step.status in (Status.failed, Status.skipped, Status.untested)
+@@ -1029,7 +1190,6 @@ class Scenario(TagAndStatusStatement, Replayable):
+                     # BUT: Detect all remaining undefined steps.
+                     step.status = Status.skipped
+                     if dry_run_scenario:
+-                        # pylint: disable=redefined-variable-type
+                         step.status = Status.untested
+                     found_step_match = runner.step_registry.find_match(step)
+                     if not found_step_match:
+@@ -1067,7 +1227,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+         # -- PERFORM CONTEXT-CLEANUP: May raise cleanup errors.
+         try:
+             runner.context._pop()       # pylint: disable=protected-access
+-        except Exception:
++        except Exception:               # pylint: disable=broad-except
+             self.set_status(Status.failed)
+             failed = True
+ 
+@@ -1176,9 +1336,9 @@ class ScenarioOutlineBuilder(object):
+                 placeholder = u"<%s>" % name
+                 for i, cell in enumerate(new_step.table.headings):
+                     new_step.table.headings[i] = cell.replace(placeholder, value)
+-                for row in new_step.table:
+-                    for i, cell in enumerate(row.cells):
+-                        row.cells[i] = cell.replace(placeholder, value)
++                for step_row in new_step.table:
++                    for i, cell in enumerate(step_row.cells):
++                        step_row.cells[i] = cell.replace(placeholder, value)
+         return new_step
+ 
+     def build_scenarios(self, scenario_outline):
+@@ -1640,7 +1800,6 @@ class Step(BasicStatement, Replayable):
+                 match.run(runner.context)
+                 if self.status == Status.untested:
+                     # -- NOTE: Executed step may have skipped scenario and itself.
+-                    # pylint: disable=redefined-variable-type
+                     self.status = Status.passed
+             except KeyboardInterrupt as e:
+                 runner.aborted = True
+@@ -1815,8 +1974,7 @@ class Table(Replayable):
+         """
+         if self.has_column(column_name):
+             return self.get_column_index(column_name)
+-        else:
+-            return self.add_column(column_name)
++        return self.add_column(column_name)
+ 
+     def __repr__(self):
+         return "<Table: %dx%d>" % (len(self.headings), len(self.rows))
+diff --git a/behave/parser.py b/behave/parser.py
+index 993c9dc..520f678 100644
+--- a/behave/parser.py
++++ b/behave/parser.py
+@@ -249,7 +249,6 @@ class Parser(object):
+         self.rule = rule
+         self.scenario_container = rule
+         self.statement = rule
+-        # MAYBE: self.background = None
+         self.feature.add_rule(self.statement)
+         # -- RESET STATE:
+         self.tags = []
+@@ -258,11 +257,15 @@ class Parser(object):
+         if self.tags:
+             msg = u"Background supports no tags: @%s" % (u" @".join(self.tags))
+             raise ParserError(msg, self.line, self.filename, line)
++        elif self.scenario_container and self.scenario_container.background:
++            if self.scenario_container.background.steps:
++                # -- HINT: Rule may have default background w/o steps.
++                msg = u"Second Background (can have only one)"
++                raise ParserError(msg, self.line, self.filename, line)
+         name = line[len(keyword) + 1:].strip()
+         background = model.Background(self.filename, self.line, keyword, name)
++        self.scenario_container.add_background(background)
+         self.statement = background
+-        self.scenario_container.background = background
+-        # OLD: self.feature.background = self.statement
+ 
+     def _build_scenario_statement(self, keyword, line):
+         name = line[len(keyword) + 1:].strip()
+diff --git a/examples/fixture.override_background/README.rst b/examples/fixture.override_background/README.rst
+deleted file mode 100644
+index 9c150cc..0000000
+--- a/examples/fixture.override_background/README.rst
++++ /dev/null
+@@ -1,116 +0,0 @@
+-EXAMPLE: Override / Disable Background Inheritance Mechanism for Scenario
+-===============================================================================
+-
+-:RELATED-TO: #756
+-
+-This example shows how the Background inheritance mechanism in Gherkin
+-can be disabled in ``behave``.
+-
+-Parts of the recipe:
+-
+-* features/example.feature (Feature file as example)
+-* features/environment.py (glue code and hooks for fixture-tag / fixture)
+-* behave_fixture_lib/override_background.py (fixture implementation, workhorse)
+-
+-
+-.. warning:: BEWARE: This shows you how can do it, not that you should do it
+-
+-    BETTER:
+-
+-    * Use Rules to group Scenarios, each with its own Background (in Gherkin v6)
+-    * Split Feature aspects into multiple feature files (if needed)
+-    * ... (see issue #756 above)
+-
+-
+-Explanation
+-------------------------------------------------------------------------
+-
+-Example code how to provide a behave fixture to disable the
+-background inheritance mechanism by using a fixture / fixture-tag.
+-The fixture-tag "@ixture.behave.override_background" marks the
+-location in Gherkin (which Scenario) where the fixture should be used
+-
+-.. code-block:: gherkin
+-
+-    # -- FILE: features/example.feature
+-    Feature: Show how @fixture.behave.override_background is used
+-
+-        Background:
+-          Given a background step
+-
+-        Scenario: Alice
+-          When a step passes
+-          And note that "Background steps are executed here"
+-
+-        @fixture.behave.overide_background
+-        Scenario: Bob
+-          Given I need another scenario setup
+-          When another step passes
+-          And note that "NO-BACKGROUND STEPS are executed here"
+-
+-When the feature is executed, you see that:
+-
+-* First Scenario "Alice": Background steps are inherited and executed first.
+-* Second Scenario "Bob": No Background step is executed.
+-
+-.. code-block:: sh
+-
+-    $ ../../bin/behave -f plain features/example.feature
+-    Feature: Override the Background Inheritance Mechanism in some Scenarios
+-      Background:
+-
+-      Scenario: Alice
+-        Given a background step passes ... passed
+-        When a step passes ... passed
+-        And note that "Background steps are executed here" ... passed
+-    FIXTURE-HINT: DISABLE-BACKGROUND FOR: Bob
+-
+-      Scenario: Bob
+-        Given I need another scenario setup ... passed
+-        When another step passes ... passed
+-        And note that "NO-BACKGROUND STEPS are executed here" ... passed
+-
+-    1 feature passed, 0 failed, 0 skipped
+-    2 scenarios passed, 0 failed, 0 skipped
+-    6 steps passed, 0 failed, 0 skipped, 0 undefined
+-
+-
+-The environment file provides the glue code that the fixture is called:
+-
+-.. code-block:: python
+-
+-    # -- FILE: features/environment.py
+-    from behave_fixture_lib.override_background import behave_override_background
+-    from behave.fixture import use_fixture_by_tag
+-
+-    # -- FIXTURE REGISTRY:
+-    fixture_registry = {
+-        "fixture.behave.overide_background": behave_override_background,
+-    }
+-
+-    # -----------------------------------------------------------------------------
+-    # HOOKS:
+-    # -----------------------------------------------------------------------------
+-    def before_tag(context, tag):
+-        if tag.startswith("fixture."):
+-            return use_fixture_by_tag(tag, context, fixture_registry)
+-
+-
+-.. code-block:: python
+-
+-    # -- FILE: behave_fixture_lib/override_background.py (fixture implementation)
+-    from behave import fixture
+-
+-    @fixture(name="fixture.behave.override_background")
+-    def behave_override_background(ctx):
+-        # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
+-        current_scenario = ctx.scenario
+-        if current_scenario:
+-            behave_disable_background_inheritance_for_scenario(current_scenario)
+-
+-    # -----------------------------------------------------------------------------
+-    # BEHAVE UTILITY:
+-    # -----------------------------------------------------------------------------
+-    def behave_disable_background_inheritance_for_scenario(scenario):
+-        print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
+-        scenario.background = None
+diff --git a/examples/fixture.override_background/behave_fixture_lib/__init__.py b/examples/fixture.override_background/behave_fixture_lib/__init__.py
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/examples/fixture.override_background/behave_fixture_lib/override_background.py b/examples/fixture.override_background/behave_fixture_lib/override_background.py
+deleted file mode 100644
+index 6c572cf..0000000
+--- a/examples/fixture.override_background/behave_fixture_lib/override_background.py
++++ /dev/null
+@@ -1,80 +0,0 @@
+-# -*- coding: UTF-8 -*-
+-# RELATED-TO: #756
+-"""
+-Example code how to provide a behave fixture to disable the
+-background inheritance mechanism.
+-
+-.. code-block:: gherkin
+-
+-    # -- FILE: features/example.feature
+-    Feature: Show how @fixture.behave.override_background is used
+-
+-        Background:
+-          Given a background step
+-
+-        Scenario: Alice
+-          When a step passes
+-          And note that "Background steps are executed here"
+-
+-        @fixture.behave.overide_background
+-        Scenario: Bob
+-          Given I need another scenario setup
+-          When another step passes
+-          And note that "NO-BACKGROUND STEPS are executed here"
+-
+-.. code-block:: python
+-
+-    # -- FILE: features/environment.py
+-    from behave_fixture_lib.override_background import behave_override_background
+-    from behave.fixture import use_fixture_by_tag
+-
+-    # -- FIXTURE REGISTRY:
+-    fixture_registry = {
+-        "fixture.behave.overide_background": behave_override_background,
+-    }
+-
+-    def before_tag(context, tag):
+-        if tag.startswith("fixture."):
+-            return use_fixture_by_tag(tag, context, fixture_registry)
+-
+-"""
+-
+-from __future__ import absolute_import, print_function
+-from behave import fixture
+-
+-
+-# -----------------------------------------------------------------------------
+-# BEHAVE FIXTURES:
+-# -----------------------------------------------------------------------------
+-@fixture(name="fixture.behave.override_background")
+-def behave_override_background(ctx):
+-    """Override the Background inherintance mechanism.
+-    If a Feature / Rule Background exists in a Feature,
+-    all contained Scenarios inherit the Background's steps.
+-
+-    This fixture disables this mechanism.
+-    The tagged Gherkin element will no longer inherit the background steps.
+-
+-    :param ctx: Context object to use (during a test run).
+-    """
+-    # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
+-    current_scenario = ctx.scenario
+-    if current_scenario:
+-        behave_disable_background_inheritance_for_scenario(current_scenario)
+-
+-
+-# -----------------------------------------------------------------------------
+-# BEHAVE UTILITY:
+-# -----------------------------------------------------------------------------
+-def behave_disable_background_inheritance_for_scenario(scenario):
+-    print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
+-    scenario.background = None
+-    # scenario._background_steps = []
+-
+-
+-# -----------------------------------------------------------------------------
+-# MODULE SPECIFIC:
+-# -----------------------------------------------------------------------------
+-fixture_registry = {
+-    "fixture.behave.overide_background": behave_override_background,
+-}
+diff --git a/examples/fixture.override_background/features/environment.py b/examples/fixture.override_background/features/environment.py
+deleted file mode 100644
+index 7a4b735..0000000
+--- a/examples/fixture.override_background/features/environment.py
++++ /dev/null
+@@ -1,35 +0,0 @@
+-# -*- coding: UTF-8 -*-
+-# -- FILE: features/environment.py
+-import os.path
+-import sys
+-
+-# -----------------------------------------------------------------------------
+-# PYTHON PATH SETUP:
+-# -----------------------------------------------------------------------------
+-HERE = os.path.dirname(__file__)
+-TOPA = os.path.abspath(os.path.join(HERE, ".."))
+-
+-def setup_python_path():
+-    sys.path.insert(0, TOPA)
+-
+-setup_python_path()
+-
+-# -----------------------------------------------------------------------------
+-# NORMAL PART:
+-# -----------------------------------------------------------------------------
+-from behave_fixture_lib.override_background import behave_override_background
+-from behave.fixture import use_fixture_by_tag
+-
+-# -- FIXTURE REGISTRY:
+-fixture_registry = {
+-    "fixture.behave.overide_background": behave_override_background,
+-}
+-
+-
+-# -----------------------------------------------------------------------------
+-# HOOKS:
+-# -----------------------------------------------------------------------------
+-def before_tag(context, tag):
+-    if tag.startswith("fixture."):
+-        return use_fixture_by_tag(tag, context, fixture_registry)
+-
+diff --git a/examples/fixture.override_background/features/example.feature b/examples/fixture.override_background/features/example.feature
+deleted file mode 100644
+index 5ddd874..0000000
+--- a/examples/fixture.override_background/features/example.feature
++++ /dev/null
+@@ -1,18 +0,0 @@
+-Feature: Override the Background Inheritance Mechanism in some Scenarios
+-
+-  . BEWARE:
+-  .   This is only an example how this can be done (PROOF-OF-CONCEPT).
+-  .   This is not an example that you should do this !!!
+-
+-    Background:
+-      Given a background step passes
+-
+-    Scenario: Alice
+-      When a step passes
+-      And note that "Background steps are executed here"
+-
+-    @fixture.behave.overide_background
+-    Scenario: Bob
+-      Given I need another scenario setup
+-      When another step passes
+-      And note that "NO-BACKGROUND STEPS are executed here"
+diff --git a/examples/fixture.override_background/features/steps/basic_steps.py b/examples/fixture.override_background/features/steps/basic_steps.py
+deleted file mode 100644
+index 34f2107..0000000
+--- a/examples/fixture.override_background/features/steps/basic_steps.py
++++ /dev/null
+@@ -1,13 +0,0 @@
+-from behave import given, step
+-
+-# @step(u'{word} step passes')
+-# def step_passes_with_word(context, word):
+-#     pass
+-
+-@step(u'{word} background step passes')
+-def step_background_step_passes(context, word):
+-    pass
+-
+-@given(u'I need {word} scenario setup')
+-def step_given_i_need_scenario_setup(context, word):
+-    pass
+diff --git a/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py b/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+deleted file mode 100644
+index bc32a32..0000000
+--- a/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
++++ /dev/null
+@@ -1,12 +0,0 @@
+-# -*- coding: utf-8 -*-
+-"""
+-Use behave4cmd0 step library (predecessor of behave4cmd).
+-"""
+-
+-from __future__ import absolute_import
+-
+-# -- REGISTER-STEPS FROM STEP-LIBRARY:
+-# import behave4cmd0.__all_steps__
+-# import behave4cmd0.failing_steps
+-import behave4cmd0.passing_steps
+-import behave4cmd0.note_steps
+diff --git a/setup.py b/setup.py
+index cea4392..8de3ec0 100644
+--- a/setup.py
++++ b/setup.py
+@@ -131,6 +131,7 @@ setup(
+         "Programming Language :: Python :: 3.5",
+         "Programming Language :: Python :: 3.6",
+         "Programming Language :: Python :: 3.7",
++        "Programming Language :: Python :: 3.8",
+         "Programming Language :: Python :: Implementation :: CPython",
+         "Programming Language :: Python :: Implementation :: Jython",
+         "Programming Language :: Python :: Implementation :: PyPy",
+diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py
+index c1fc424..21d6c27 100644
+--- a/tests/unit/test_model.py
++++ b/tests/unit/test_model.py
+@@ -8,7 +8,7 @@ from mock import Mock, patch
+ import six
+ from six.moves import range     # pylint: disable=redefined-builtin
+ from six.moves import zip       # pylint: disable=redefined-builtin
+-from behave.model_core import FileLocation, Status
++from behave.model_core import Status
+ from behave.model import Feature, Scenario, ScenarioOutline, Step
+ from behave.model import Table, Row
+ from behave.matchers import NoMatch
+@@ -20,19 +20,12 @@ from behave import step_registry
+ 
+ if six.PY2:
+     # pylint: disable=unused-import
+-    import traceback2 as traceback
+     traceback_modname = "traceback2"
+ else:
+     # pylint: disable=unused-import
+-    import traceback
+     traceback_modname = "traceback"
+ 
+ 
+-
+-# -- CONVENIENCE-ALIAS:
+-_text = six.text_type
+-
+-
+ class TestFeatureRun(unittest.TestCase):
+     # pylint: disable=invalid-name
+ 
+@@ -769,111 +762,3 @@ class TestModelRow(unittest.TestCase):
+         assert data1["name"] == u"Alice"
+         assert data1["sex"] == u"female"
+         assert data1["age"] == u"12"
+-
+-
+-class TestFileLocation(unittest.TestCase):
+-    # pylint: disable=invalid-name
+-    ordered_locations1 = [
+-        FileLocation("features/alice.feature", 1),
+-        FileLocation("features/alice.feature", 5),
+-        FileLocation("features/alice.feature", 10),
+-        FileLocation("features/alice.feature", 11),
+-        FileLocation("features/alice.feature", 100),
+-    ]
+-    ordered_locations2 = [
+-        FileLocation("features/alice.feature", 1),
+-        FileLocation("features/alice.feature", 10),
+-        FileLocation("features/bob.feature", 5),
+-        FileLocation("features/charly.feature", None),
+-        FileLocation("features/charly.feature", 0),
+-        FileLocation("features/charly.feature", 100),
+-    ]
+-    same_locations = [
+-        (FileLocation("alice.feature"),
+-         FileLocation("alice.feature", None),
+-        ),
+-        (FileLocation("alice.feature", 10),
+-         FileLocation("alice.feature", 10),
+-        ),
+-        (FileLocation("features/bob.feature", 11),
+-         FileLocation("features/bob.feature", 11),
+-        ),
+-    ]
+-
+-    def test_compare_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert value1 == value2
+-
+-    def test_compare_equal_with_string(self):
+-        for location in self.ordered_locations2:
+-            assert location == location.filename
+-            assert location.filename == location
+-
+-    def test_compare_not_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert not(value1 != value2)    # pylint: disable=unneeded-not, superfluous-parens
+-
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value1 != value2
+-
+-    def test_compare_less_than(self):
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value1 < value2, "FAILED: %s < %s" % (_text(value1), _text(value2))
+-                assert value1 != value2
+-
+-    def test_compare_less_than_with_string(self):
+-        locations = self.ordered_locations2
+-        for value1, value2 in zip(locations, locations[1:]):
+-            if value1.filename == value2.filename:
+-                continue
+-            assert value1 < value2.filename, \
+-                   "FAILED: %s < %s" % (_text(value1), _text(value2.filename))
+-            assert value1.filename < value2, \
+-                   "FAILED: %s < %s" % (_text(value1.filename), _text(value2))
+-
+-    def test_compare_greater_than(self):
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value2 > value1, "FAILED: %s > %s" % (_text(value2), _text(value1))
+-                assert value2 != value1
+-
+-    def test_compare_less_or_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
+-            assert value1 == value2
+-
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
+-                assert value1 != value2
+-
+-    def test_compare_greater_or_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
+-            assert value2 == value1
+-
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
+-                assert value2 != value1
+-
+-    def test_filename_should_be_same_as_self(self):
+-        for location in self.ordered_locations2:
+-            assert location == location.filename
+-            assert location.filename == location
+-
+-    def test_string_conversion(self):
+-        for location in self.ordered_locations2:
+-            expected = u"%s:%s" % (location.filename, location.line)
+-            if location.line is None:
+-                expected = location.filename
+-            assert six.text_type(location) == expected
+-
+-    def test_repr_conversion(self):
+-        for location in self.ordered_locations2:
+-            expected = u'<FileLocation: filename="%s", line=%s>' % \
+-                       (location.filename, location.line)
+-            actual = repr(location)
+-            assert actual == expected, "FAILED: %s == %s" % (actual, expected)
+diff --git a/tests/unit/test_model2.py b/tests/unit/test_model2.py
+index 7884b90..a86b80e 100644
+--- a/tests/unit/test_model2.py
++++ b/tests/unit/test_model2.py
+@@ -35,10 +35,6 @@ def step_to_text(step, indentation="    "):
+     return step_text.rstrip()
+ 
+ 
+-# -- PYTEST MARKERS/ANNOTATIONS:
+-not_implemented_yet = pytest.mark.skip("NOT-IMPLEMENTED-YET")
+-
+-
+ # ----------------------------------------------------------------------------
+ # TEST SUITE:
+ # ----------------------------------------------------------------------------
+diff --git a/tests/unit/test_model_core.py b/tests/unit/test_model_core.py
+index b5f20c4..3cb5efa 100644
+--- a/tests/unit/test_model_core.py
++++ b/tests/unit/test_model_core.py
+@@ -4,10 +4,16 @@
+ """
+ 
+ from __future__ import print_function
+-from behave.model_core import Status
++import six
++from behave.model_core import Status, FileLocation
+ import pytest
+ 
+ 
++# -- CONVENIENCE-ALIAS:
++_text = six.text_type
++
++
++
+ # -----------------------------------------------------------------------------
+ # TESTS:
+ # -----------------------------------------------------------------------------
+@@ -54,3 +60,111 @@ class TestStatus(object):
+     def test_from_name__with_unknown_name_raises_lookuperror(self, unknown_name):
+         with pytest.raises(LookupError):
+             Status.from_name(unknown_name)
++
++
++class TestFileLocation(object):
++    # pylint: disable=invalid-name
++    ordered_locations1 = [
++        FileLocation("features/alice.feature", 1),
++        FileLocation("features/alice.feature", 5),
++        FileLocation("features/alice.feature", 10),
++        FileLocation("features/alice.feature", 11),
++        FileLocation("features/alice.feature", 100),
++    ]
++    ordered_locations2 = [
++        FileLocation("features/alice.feature", 1),
++        FileLocation("features/alice.feature", 10),
++        FileLocation("features/bob.feature", 5),
++        FileLocation("features/charly.feature", None),
++        FileLocation("features/charly.feature", 0),
++        FileLocation("features/charly.feature", 100),
++    ]
++    same_locations = [
++        (FileLocation("alice.feature"),
++         FileLocation("alice.feature", None),
++        ),
++        (FileLocation("alice.feature", 10),
++         FileLocation("alice.feature", 10),
++        ),
++        (FileLocation("features/bob.feature", 11),
++         FileLocation("features/bob.feature", 11),
++        ),
++    ]
++
++    def test_compare_equal(self):
++        for value1, value2 in self.same_locations:
++            assert value1 == value2
++
++    def test_compare_equal_with_string(self):
++        for location in self.ordered_locations2:
++            assert location == location.filename
++            assert location.filename == location
++
++    def test_compare_not_equal(self):
++        for value1, value2 in self.same_locations:
++            assert not(value1 != value2)    # pylint: disable=unneeded-not, superfluous-parens
++
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value1 != value2
++
++    def test_compare_less_than(self):
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value1 < value2, "FAILED: %s < %s" % (_text(value1), _text(value2))
++                assert value1 != value2
++
++    def test_compare_less_than_with_string(self):
++        locations = self.ordered_locations2
++        for value1, value2 in zip(locations, locations[1:]):
++            if value1.filename == value2.filename:
++                continue
++            assert value1 < value2.filename, \
++                   "FAILED: %s < %s" % (_text(value1), _text(value2.filename))
++            assert value1.filename < value2, \
++                   "FAILED: %s < %s" % (_text(value1.filename), _text(value2))
++
++    def test_compare_greater_than(self):
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value2 > value1, "FAILED: %s > %s" % (_text(value2), _text(value1))
++                assert value2 != value1
++
++    def test_compare_less_or_equal(self):
++        for value1, value2 in self.same_locations:
++            assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
++            assert value1 == value2
++
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
++                assert value1 != value2
++
++    def test_compare_greater_or_equal(self):
++        for value1, value2 in self.same_locations:
++            assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
++            assert value2 == value1
++
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
++                assert value2 != value1
++
++    def test_filename_should_be_same_as_self(self):
++        for location in self.ordered_locations2:
++            assert location == location.filename
++            assert location.filename == location
++
++    def test_string_conversion(self):
++        for location in self.ordered_locations2:
++            expected = u"%s:%s" % (location.filename, location.line)
++            if location.line is None:
++                expected = location.filename
++            assert six.text_type(location) == expected
++
++    def test_repr_conversion(self):
++        for location in self.ordered_locations2:
++            expected = u'<FileLocation: filename="%s", line=%s>' % \
++                       (location.filename, location.line)
++            actual = repr(location)
++            assert actual == expected, "FAILED: %s == %s" % (actual, expected)
+diff --git a/tests/unit/test_parser_gherkin_v6.py b/tests/unit/test_parser_gherkin_v6.py
+index 991a57d..43e3d41 100644
+--- a/tests/unit/test_parser_gherkin_v6.py
++++ b/tests/unit/test_parser_gherkin_v6.py
+@@ -227,7 +227,9 @@ Feature: With Rule
+         assert rule1.description == []
+         assert rule1.tags == []
+         assert len(rule1.scenarios) == 1
+-        assert rule1.background is feature.background
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == feature.background.steps
++        assert list(rule1.background.all_steps) == feature.background.steps
+         assert_compare_steps(rule1.scenarios[0].all_steps, [
+             ("given", "Given", "feature background step 1", None, None),
+             ("when", "When", "feature background step 2", None, None),
+@@ -235,7 +237,7 @@ Feature: With Rule
+             ("when", "When", "scenario step 2", None, None),
+         ])
+ 
+-    def test_parses_rule_with_background_should_not_inherit_feature_background(self):
++    def test_parses_rule_with_background_inherits_feature_background(self):
+         """If a Rule has no Background,
+         it inherits the Feature's Background (if one exists).
+         """
+@@ -269,13 +271,15 @@ Feature: With Rule
+         assert rule1.background is not None
+         assert rule1.background is not feature.background
+         assert_compare_steps(rule1.scenarios[0].all_steps, [
++            ("given", "Given", "feature background step 1", None, None),
++            ("when",  "When",  "feature background step 2", None, None),
+             ("given", "Given", "rule background step 1", None, None),
+-            ("when", "When", "rule background step 2", None, None),
++            ("when",  "When",  "rule background step 2", None, None),
+             ("given", "Given", "scenario step 1", None, None),
+-            ("when", "When", "scenario step 2", None, None),
++            ("when",  "When",  "scenario step 2", None, None),
+         ])
+ 
+-    def test_parses_rule_with_empty_background_prevents_inheriting_feature_background(self):
++    def test_parses_rule_with_empty_background_inherits_feature_background(self):
+         """A Rule has empty Background (without any steps) prevents that
+         Feature Background is inherited (if one exists).
+         """
+@@ -308,8 +312,10 @@ Feature: With Rule
+         assert rule1.background is not feature.background
+         assert rule1.background.name == "Rule_R3C.Empty_Background"
+         assert_compare_steps(rule1.scenarios[0].all_steps, [
++            ("given", "Given", "feature background step 1", None, None),
++            ("when",  "When",  "feature background step 2", None, None),
+             ("given", "Given", "scenario step 1", None, None),
+-            ("when", "When", "scenario step 2", None, None),
++            ("when",  "When", "scenario step 2", None, None),
+         ])
+ 
+     def test_parses_rule_with_scenario(self):
+@@ -558,6 +564,7 @@ Feature: With Rule
+             ("when", "When", 'step uses "2"', None, None),
+         ])
+ 
++    # @check.duplicated
+     def test_parse_background_scenario_and_rules(self):
+         """HINT: Some Scenarios may exist before the first Rule."""
+         text = u'''
+@@ -606,10 +613,10 @@ Feature: With Scenarios and Rules
+         assert scenario1.tags == []
+         assert scenario1.description == []
+         assert_compare_steps(scenario1.all_steps, [
+-            ("given", "Given", 'feature background step_1', None, None),
+-            ("when", "When",   'feature background step_2', None, None),
+-            ("given", "Given", 'scenario_1 step_1', None, None),
+-            ("when", "When",   'scenario_1 step_2', None, None),
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"when", u"When",   u'feature background step_2', None, None),
++            (u"given", u"Given", u'scenario_1 step_1', None, None),
++            (u"when", u"When",   u'scenario_1 step_2', None, None),
+         ])
+ 
+         assert rule1.name == "R1"
+@@ -623,9 +630,11 @@ Feature: With Scenarios and Rules
+         assert rule1_scenario1.parent is rule1
+         assert rule1_scenario1.feature is feature
+         assert_compare_steps(rule1_scenario1.all_steps, [
++            ("given", "Given", 'feature background step_1', None, None),
++            ("when",  "When",  'feature background step_2', None, None),
+             ("given", "Given", 'rule R1 background step_1', None, None),
+             ("given", "Given", 'rule R1 scenario_1 step_1', None, None),
+-            ("when", "When",   'rule R1 scenario_1 step_2', None, None),
++            ("when",  "When",  'rule R1 scenario_1 step_2', None, None),
+         ])
+ 
+         assert rule2.name == "R2"
+@@ -633,16 +642,318 @@ Feature: With Scenarios and Rules
+         assert rule2.feature is feature
+         assert rule2.description == []
+         assert rule2.tags == []
+-        assert rule2.background is feature.background
++        assert rule2.background is not feature.background
++        assert list(rule2.background.inherited_steps) == list(feature.background.steps)
++        assert list(rule2.background.all_steps) == list(feature.background.steps)
+         assert len(rule2.scenarios) == 1
+         assert rule2_scenario1.name == "R2.Scenario_1"
+         assert rule2_scenario1.parent is rule2
+         assert rule2_scenario1.feature is feature
+         assert_compare_steps(rule2_scenario1.all_steps, [
+             ("given", "Given", 'feature background step_1', None, None),
+-            ("when", "When",   'feature background step_2', None, None),
++            ("when",  "When",  'feature background step_2', None, None),
+             ("given", "Given", 'rule R2 scenario_1 step_1', None, None),
+-            ("when", "When",   'rule R2 scenario_1 step_2', None, None),
++            ("when",  "When",  'rule R2 scenario_1 step_2', None, None),
++        ])
++
++
++# ---------------------------------------------------------------------------
++# TEST SUITE: Verify Feature Background to Rule Background Inheritance
++# ---------------------------------------------------------------------------
++class TestParser4Background(object):
++    """Verify feature.background to rule.background inheritance, etc."""
++
++    def test_parse__norule_scenarios_use_feature_background(self):
++        """AFFECTED: Scenarios outside of rules (before first rule)."""
++        text = u'''
++            Feature: With Scenarios and Rules
++            
++              Background: Feature.Background
++                Given feature background step_1
++            
++              Scenario: Scenario_1
++                Given scenario_1 step_1
++            
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Scenarios and Rules"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 1
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 2
++
++        scenario1 = feature.scenarios[0]
++        rule1 = feature.rules[0]
++        assert feature.run_items == [scenario1, rule1]
++
++        assert scenario1.name == "Scenario_1"
++        assert scenario1.background is feature.background
++        assert scenario1.background_steps == feature.background.steps
++        assert_compare_steps(scenario1.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__norule_scenarios_with_disabled_background(self):
++        """AFFECTED: Scenarios outside of rules (before first rule)."""
++        text = u'''
++            Feature: Scenario with disabled background
++            
++              Background: Feature.Background
++                Given feature background step_1
++            
++              @fixture.behave.disable_background
++              Scenario: Scenario_1
++                Given scenario_1 step_1
++            
++              Scenario: Scenario_2
++                Given scenario_2 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "Scenario with disabled background"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 2
++        assert len(feature.run_items) == 2
++
++        scenario1 = feature.scenarios[0]
++        scenario2 = feature.scenarios[1]
++        assert feature.run_items == [scenario1, scenario2]
++
++        scenario1.use_background = False    # -- FIXTURE-EFFECT (simulated)
++        assert scenario1.name == "Scenario_1"
++        assert scenario1.background is feature.background
++        assert scenario1.background_steps != feature.background.steps
++        assert scenario1.background_steps == []
++        assert_compare_steps(scenario1.all_steps, [
++            (u"given", u"Given", u'scenario_1 step_1', None, None),
++        ])
++
++        # -- ENSURE: Disabling of background has no effect on other scenarios.
++        assert scenario2.name == "Scenario_2"
++        assert scenario2.background is feature.background
++        assert scenario2.background_steps == feature.background.steps
++        assert_compare_steps(scenario2.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'scenario_2 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_inherit_feature_background_without_rule_background(self):
++        text = u'''
++            Feature: With Background and Rule
++    
++              Background: Feature.Background
++                Given feature background step_1
++    
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Background and Rule"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is not None
++        # assert rule1_scenario1.background is not feature.background
++        assert rule1_scenario1.background_steps == feature.background.steps
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_inherit_feature_background_with_rule_background(self):
++        text = u'''
++            Feature: With Feature.Background and Rule.Background
++
++              Background: Feature.Background
++                Given feature background step_1
++
++              Rule: R1
++                Background: R1.Background
++                  Given rule R1 background step_1
++                
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Feature.Background and Rule.Background"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1.background is not None
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == feature.background.steps
++        assert list(rule1.background.all_steps) != feature.background.steps
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'rule R1 background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_with_rule_background_when_background_inheritance_is_disabled(self):
++        # -- HINT: Background inheritance is enabled (by default).
++        text = u'''
++            Feature: With Feature Background Inheritance disabled
++
++              Background: Feature.Background
++                Given feature background step_1
++
++              @fixture.behave.override_background
++              Rule: R1
++                Background: R1.Background
++                  Given rule R1 background step_1
++
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Feature Background Inheritance disabled"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        rule1.use_background_inheritance = False  # FIXTURE-EFFECT (simulated)
++        assert rule1.background is not None
++        assert rule1.background.use_inheritance is False
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == []
++        assert rule1.background.inherited_steps != feature.background.steps
++        assert list(rule1.background.all_steps) != feature.background.steps
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == rule1.background.steps
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_without_rule_background_when_background_inheritance_is_disabled_without(self):
++        # -- HINT: Background inheritance is enabled (by default).
++        text = u'''
++            Feature: With Feature Background Inheritance disabled
++
++              Background: Feature.Background
++                Given feature background step_1
++
++              @fixture.behave.override_background
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Feature Background Inheritance disabled"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        rule1.use_background_inheritance = False  # FIXTURE-EFFECT (simulated)
++        assert rule1.background is not None
++        assert rule1.background.use_inheritance is False
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == []
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == rule1.background.steps
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_without_feature_background_and_with_rule_background(self):
++        text = u'''
++            Feature: Without Feature.Background and with Rule.Background
++
++              Rule: R1
++                Background: R1.Background
++                  Given rule R1 background step_1
++
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "Without Feature.Background and with Rule.Background"
++        assert feature.background is None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1.background is not None
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == []
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == rule1.background.steps
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_without_feature_and_rule_background(self):
++        text = u'''
++            Feature: Without Feature.Background and Rule.Background
++
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "Without Feature.Background and Rule.Background"
++        assert feature.background is None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1.background is None
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is None
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == []
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
+         ])
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch b/meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch
new file mode 100644
index 000000000..964b83e69
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch
@@ -0,0 +1,269 @@
+From 26e431c821c260a981ca8ed28f21330c8ef17af6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:18:02 +0200
+Subject: [PATCH] Add support for runtime constraints.
+
+---
+ .bumpversion.cfg                 |  2 +-
+ behave/__init__.py               |  2 +-
+ behave/__main__.py               | 13 +++++----
+ behave/api/runtime_constraint.py | 45 ++++++++++++++++++++++++++++++++
+ behave/configuration.py          |  4 ---
+ behave/exception.py              | 40 ++++++++++++++++++++++++++++
+ behave/runner.py                 |  2 +-
+ behave/runner_util.py            | 17 ++----------
+ behave/version.py                |  2 ++
+ tests/unit/test_runner.py        |  2 +-
+ 10 files changed, 101 insertions(+), 28 deletions(-)
+ create mode 100644 behave/api/runtime_constraint.py
+ create mode 100644 behave/exception.py
+ create mode 100644 behave/version.py
+
+diff --git a/.bumpversion.cfg b/.bumpversion.cfg
+index ac913c2..a5d3d2f 100644
+--- a/.bumpversion.cfg
++++ b/.bumpversion.cfg
+@@ -1,6 +1,6 @@
+ [bumpversion]
+ current_version = 1.2.7.dev1
+-files = behave/__init__.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
++files = behave/version.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
+ parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<drop>\w*)
+ serialize = {major}.{minor}.{patch}{drop}
+ commit = False
+diff --git a/behave/__init__.py b/behave/__init__.py
+index 31e4e55..53a5337 100644
+--- a/behave/__init__.py
++++ b/behave/__init__.py
+@@ -20,6 +20,7 @@ from __future__ import absolute_import
+ from behave.step_registry import *      # pylint: disable=wildcard-import
+ from behave.matchers import use_step_matcher, step_matcher, register_type
+ from behave.fixture import fixture, use_fixture
++from behave.version import VERSION as __version__
+ 
+ # pylint: disable=undefined-all-variable
+ __all__ = [
+@@ -29,4 +30,3 @@ __all__ = [
+     # -- DEPRECATING:
+     "step_matcher"
+ ]
+-__version__ = "1.2.7.dev1"
+diff --git a/behave/__main__.py b/behave/__main__.py
+index c340b25..3cae36d 100644
+--- a/behave/__main__.py
++++ b/behave/__main__.py
+@@ -4,12 +4,13 @@ from __future__ import absolute_import, print_function
+ import codecs
+ import sys
+ import six
+-from behave import __version__
+-from behave.configuration import Configuration, ConfigError
++from behave.version import VERSION as BEHAVE_VERSION
++from behave.configuration import Configuration
++from behave.exception import ConstraintError, ConfigError, \
++    FileNotFoundError, InvalidFileLocationError, InvalidFilenameError
+ from behave.parser import ParserError
+ from behave.runner import Runner
+-from behave.runner_util import print_undefined_step_snippets, reset_runtime, \
+-    InvalidFileLocationError, InvalidFilenameError, FileNotFoundError
++from behave.runner_util import print_undefined_step_snippets, reset_runtime
+ from behave.textutil import compute_words_maxsize, text as _text
+ 
+ 
+@@ -62,7 +63,7 @@ def run_behave(config, runner_class=None):
+         runner_class = Runner
+ 
+     if config.version:
+-        print("behave " + __version__)
++        print("behave " + BEHAVE_VERSION)
+         return 0
+ 
+     if config.tags_help:
+@@ -110,6 +111,8 @@ def run_behave(config, runner_class=None):
+         print(u"InvalidFileLocationError: %s" % e)
+     except InvalidFilenameError as e:
+         print(u"InvalidFilenameError: %s" % e)
++    except ConstraintError as e:
++        print(u"ConstraintError: %s" % e)
+     except Exception as e:
+         # -- DIAGNOSTICS:
+         text = _text(e)
+diff --git a/behave/api/runtime_constraint.py b/behave/api/runtime_constraint.py
+new file mode 100644
+index 0000000..310e529
+--- /dev/null
++++ b/behave/api/runtime_constraint.py
+@@ -0,0 +1,45 @@
++# -*- coding: UTF-8 -*-
++"""
++Simplifies to specify runtime constraints in
++
++* features/environment.py file
++* features/steps/*.py" files
++"""
++
++from __future__ import absolute_import
++from behave.exception import ConstraintError
++
++
++# ---------------------------------------------------------------------------
++# UTILITY FUNCTIONS:
++# ---------------------------------------------------------------------------
++def require_min_python_version(minimal_version):
++    """Simplifies to specify the minimal python version that is required.
++
++    :param minimal_version: Minimum version (as string, tuple)
++    :raises: behave.exception.ConstraintError
++    """
++    import six
++    import sys
++    python_version = sys.version_info
++    if isinstance(minimal_version, six.string_types):
++        python_version = "%s.%s" % sys.version_info[:2]
++    elif not isinstance(minimal_version, tuple):
++        raise TypeError("string or tuple (was: %s)" % type(minimal_version))
++
++    if python_version < minimal_version:
++        raise ConstraintError("python >= %s expected (was: %s)" % \
++                              (minimal_version, python_version))
++
++
++def require_min_behave_version(minimal_version):
++    """Simplifies to specify the minimal behave version that is required.
++
++    :param minimal_version: Minimum version (as string, tuple)
++    :raises: behave.exception.ConstraintError
++    """
++    # -- SIMPLISTIC IMPLEMENTATION:
++    from behave.version import VERSION as behave_version
++    if behave_version < minimal_version:
++        raise ConstraintError("behave >= %s expected (was: %s)" % \
++                              (minimal_version, behave_version))
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 861f89f..bd8b039 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -62,10 +62,6 @@ class LogLevel(object):
+         return logging.getLevelName(level)
+ 
+ 
+-class ConfigError(Exception):
+-    pass
+-
+-
+ # -----------------------------------------------------------------------------
+ # CONFIGURATION SCHEMA:
+ # -----------------------------------------------------------------------------
+diff --git a/behave/exception.py b/behave/exception.py
+new file mode 100644
+index 0000000..ba21206
+--- /dev/null
++++ b/behave/exception.py
+@@ -0,0 +1,40 @@
++# -*- coding: UTF-8 -*-
++"""
++Behave exception classes.
++
++.. versionadded:: 1.2.7
++"""
++
++
++# ---------------------------------------------------------------------------
++# EXCEPTION/ERROR CLASSES:
++# ---------------------------------------------------------------------------
++class ConstraintError(RuntimeError):
++    """Used if a constraint/precondition is not fulfilled at runtime.
++
++    .. versionadded:: 1.2.7
++    """
++
++
++class ConfigError(Exception):
++    """Used if the configuration is (partially) invalid."""
++
++
++# ---------------------------------------------------------------------------
++# EXCEPTION/ERROR CLASSES: Related to File Handling
++# ---------------------------------------------------------------------------
++class FileNotFoundError(LookupError):
++    """Used if a specified file was not found."""
++
++
++class InvalidFileLocationError(LookupError):
++    """Used if a :class:`behave.model_core.FileLocation` is invalid.
++    This occurs if the file location is no exactly correct and
++    strict checking is enabled.
++    """
++
++
++class InvalidFilenameError(ValueError):
++    """Used if a filename does not have the expected file extension, etc."""
++
++
+diff --git a/behave/runner.py b/behave/runner.py
+index f209cb0..cbedb5a 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -15,7 +15,7 @@ import six
+ 
+ from behave._types import ExceptionUtil
+ from behave.capture import CaptureController
+-from behave.configuration import ConfigError
++from behave.exception import ConfigError
+ from behave.formatter._registry import make_formatters
+ from behave.runner_util import \
+     collect_feature_locations, parse_features, \
+diff --git a/behave/runner_util.py b/behave/runner_util.py
+index 7e0807f..80b99a0 100644
+--- a/behave/runner_util.py
++++ b/behave/runner_util.py
+@@ -11,26 +11,13 @@ import re
+ import sys
+ from six import string_types
+ from behave import parser
++from behave.exception import \
++    FileNotFoundError, InvalidFileLocationError, InvalidFilenameError
+ from behave.model_core import FileLocation
+ from behave.textutil import ensure_stream_with_encoder
+ # LAZY: from behave.step_registry import setup_step_decorators
+ 
+ 
+-# -----------------------------------------------------------------------------
+-# EXCEPTIONS:
+-# -----------------------------------------------------------------------------
+-class FileNotFoundError(LookupError):
+-    pass
+-
+-
+-class InvalidFileLocationError(LookupError):
+-    pass
+-
+-
+-class InvalidFilenameError(ValueError):
+-    pass
+-
+-
+ # -----------------------------------------------------------------------------
+ # CLASS: FileLocationParser
+ # -----------------------------------------------------------------------------
+diff --git a/behave/version.py b/behave/version.py
+new file mode 100644
+index 0000000..b19cb5e
+--- /dev/null
++++ b/behave/version.py
+@@ -0,0 +1,2 @@
++# -- BEHAVE-VERSION:
++VERSION = "1.2.7.dev1"
+diff --git a/tests/unit/test_runner.py b/tests/unit/test_runner.py
+index 030dffa..f0d03cd 100644
+--- a/tests/unit/test_runner.py
++++ b/tests/unit/test_runner.py
+@@ -17,7 +17,7 @@ from behave import runner_util
+ from behave.model import Table
+ from behave.step_registry import StepRegistry
+ from behave import parser, runner
+-from behave.configuration import ConfigError
++from behave.exception import ConfigError
+ from behave.formatter.base import StreamOpener
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch b/meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch
new file mode 100644
index 000000000..8a07505bf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch
@@ -0,0 +1,196 @@
+From 5917914e415c728e130d828cc1ed4e2199b1fcdc Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:19:13 +0200
+Subject: [PATCH] Use runtime constraints
+
+---
+ .../features/async_dispatch.feature           |  2 ++
+ .../async_step/features/async_run.feature     |  2 ++
+ examples/async_step/features/environment.py   | 13 +++++++++
+ .../{async_steps34.py => _async_steps34.py}   |  6 +++-
+ .../{async_steps35.py => _async_steps35.py}   |  3 +-
+ .../features/steps/async_dispatch_steps.py    | 29 +++++++++++++++----
+ .../async_step/features/steps/async_steps.py  | 12 ++++++++
+ 7 files changed, 59 insertions(+), 8 deletions(-)
+ rename examples/async_step/features/steps/{async_steps34.py => _async_steps34.py} (58%)
+ rename examples/async_step/features/steps/{async_steps35.py => _async_steps35.py} (95%)
+ create mode 100644 examples/async_step/features/steps/async_steps.py
+
+diff --git a/examples/async_step/features/async_dispatch.feature b/examples/async_step/features/async_dispatch.feature
+index 416d3d1..18e9869 100644
+--- a/examples/async_step/features/async_dispatch.feature
++++ b/examples/async_step/features/async_dispatch.feature
+@@ -1,6 +1,8 @@
+ @use.with_python.version=3.4
+ @use.with_python.version=3.5
+ @use.with_python.version=3.6
++@use.with_python.version=3.7
++@use.with_python.version=3.8
+ Feature:
+   Scenario:
+     Given I dispatch an async-call with param "Alice"
+diff --git a/examples/async_step/features/async_run.feature b/examples/async_step/features/async_run.feature
+index 9f506b4..29b8fa7 100644
+--- a/examples/async_step/features/async_run.feature
++++ b/examples/async_step/features/async_run.feature
+@@ -1,6 +1,8 @@
+ @use.with_python.version=3.4
+ @use.with_python.version=3.5
+ @use.with_python.version=3.6
++@use.with_python.version=3.7
++@use.with_python.version=3.8
+ Feature:
+   Scenario:
+     Given an async-step waits 0.3 seconds
+diff --git a/examples/async_step/features/environment.py b/examples/async_step/features/environment.py
+index 9d4302b..02c4d92 100644
+--- a/examples/async_step/features/environment.py
++++ b/examples/async_step/features/environment.py
+@@ -1,8 +1,18 @@
+ # -*- coding: UTF-8 -*-
+ 
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
++from behave.api.runtime_constraint import require_min_python_version
+ import sys
+ 
++# -----------------------------------------------------------------------------
++# REQUIRE: python >= 3.4
++# -----------------------------------------------------------------------------
++require_min_python_version("3.4")
++
++
++# -----------------------------------------------------------------------------
++# SUPPORT: Active-tags
++# -----------------------------------------------------------------------------
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+ python_version = "%s.%s" % sys.version_info[:2]
+@@ -11,6 +21,7 @@ active_tag_value_provider = {
+ }
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+@@ -18,10 +29,12 @@ def before_all(context):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+     setup_active_tag_values(active_tag_value_provider, context.config.userdata)
+ 
++
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/examples/async_step/features/steps/async_steps34.py b/examples/async_step/features/steps/_async_steps34.py
+similarity index 58%
+rename from examples/async_step/features/steps/async_steps34.py
+rename to examples/async_step/features/steps/_async_steps34.py
+index c4962ab..556500f 100644
+--- a/examples/async_step/features/steps/async_steps34.py
++++ b/examples/async_step/features/steps/_async_steps34.py
+@@ -1,8 +1,12 @@
+-# -- REQUIRES: Python >= 3.4
++# -- REQUIRES: Python >= 3.4 and Python < 3.8
++# HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++# USE:  Async generator/coroutine instead.
++
+ from behave import step
+ from behave.api.async_step import async_run_until_complete
+ import asyncio
+ 
++# -- USABLE FOR: "3.4" <= python_version < "3.8"
+ @step('an async-step waits {duration:f} seconds')
+ @async_run_until_complete
+ @asyncio.coroutine
+diff --git a/examples/async_step/features/steps/async_steps35.py b/examples/async_step/features/steps/_async_steps35.py
+similarity index 95%
+rename from examples/async_step/features/steps/async_steps35.py
+rename to examples/async_step/features/steps/_async_steps35.py
+index 018d5ef..edcbe0e 100644
+--- a/examples/async_step/features/steps/async_steps35.py
++++ b/examples/async_step/features/steps/_async_steps35.py
+@@ -1,4 +1,5 @@
+ # -- REQUIRES: Python >= 3.5
++
+ from behave import step
+ from behave.api.async_step import async_run_until_complete
+ import asyncio
+@@ -6,5 +7,5 @@ import asyncio
+ @step('an async-step waits {duration:f} seconds')
+ @async_run_until_complete
+ async def step_async_step_waits_seconds_py35(context, duration):
+-    """Simple example of a coroutine as async-step (in Python 3.5)"""
++    """Simple example of a coroutine as async-step (in Python 3.5 or newer)"""
+     await asyncio.sleep(duration)
+diff --git a/examples/async_step/features/steps/async_dispatch_steps.py b/examples/async_step/features/steps/async_dispatch_steps.py
+index b9b6e15..222e54d 100644
+--- a/examples/async_step/features/steps/async_dispatch_steps.py
++++ b/examples/async_step/features/steps/async_dispatch_steps.py
+@@ -1,21 +1,38 @@
+ # -*- coding: UTF-8 -*-
+-# REQUIRES: Python >= 3.5
++# REQUIRES: Python >= 3.4/3.5
++import sys
+ from behave import given, then, step
+-from behave.api.async_step import use_or_create_async_context, AsyncContext
++from behave.api.async_step import use_or_create_async_context
+ from hamcrest import assert_that, equal_to, empty
+ import asyncio
+ 
+-@asyncio.coroutine
+-def async_func(param):
+-    yield from asyncio.sleep(0.2)
+-    return str(param).upper()
+ 
++# ---------------------------------------------------------------------------
++# ASYNC EXAMPLE FUNCTION:
++# ---------------------------------------------------------------------------
++python_version = "%s.%s" % sys.version_info[:2]
++if python_version >= "3.5":
++    async def async_func(param):
++        await asyncio.sleep(0.2)
++        return str(param).upper()
++else:
++    # -- HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++    @asyncio.coroutine
++    def async_func(param):
++        yield from asyncio.sleep(0.2)
++        return str(param).upper()
++
++
++# ---------------------------------------------------------------------------
++# STEPS:
++# ---------------------------------------------------------------------------
+ @given('I dispatch an async-call with param "{param}"')
+ def step_dispatch_async_call(context, param):
+     async_context = use_or_create_async_context(context, "async_context1")
+     task = async_context.loop.create_task(async_func(param))
+     async_context.tasks.append(task)
+ 
++
+ @then('the collected result of the async-calls is "{expected}"')
+ def step_collected_async_call_result_is(context, expected):
+     async_context = context.async_context1
+diff --git a/examples/async_step/features/steps/async_steps.py b/examples/async_step/features/steps/async_steps.py
+new file mode 100644
+index 0000000..dc03c72
+--- /dev/null
++++ b/examples/async_step/features/steps/async_steps.py
+@@ -0,0 +1,12 @@
++# -*- coding: UTF-8 -*-
++# REQUIRES: Python >= 3.4/3.5
++"""Python import-barrier for python2 or python < 3.4."""
++
++from __future__ import absolute_import
++import sys
++
++python_version = "%s.%s" % sys.version_info[:2]
++if python_version >= "3.5":
++    import _async_steps35
++elif python_version == "3.4":
++    import _async_steps34
diff --git a/meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch b/meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch
new file mode 100644
index 000000000..aebb68589
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch
@@ -0,0 +1,3937 @@
+From 484af9f2be3868f90ae736c040332dcdc04b5d02 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:20:38 +0200
+Subject: [PATCH] CLEANUP: Remove deprecated parts.
+
+---
+ .attic/convert_i18n_yaml.py |   77 +
+ .attic/i18n.yml             |  635 +++++++
+ bin/gherkin-languages.json  | 3193 -----------------------------------
+ 3 files changed, 712 insertions(+), 3193 deletions(-)
+ create mode 100755 .attic/convert_i18n_yaml.py
+ create mode 100644 .attic/i18n.yml
+ delete mode 100644 bin/gherkin-languages.json
+
+diff --git a/.attic/convert_i18n_yaml.py b/.attic/convert_i18n_yaml.py
+new file mode 100755
+index 0000000..d6a6713
+--- /dev/null
++++ b/.attic/convert_i18n_yaml.py
+@@ -0,0 +1,77 @@
++#!/usr/bin/env python
++# -*- coding: UTF-8 -*-
++# USAGE: convert_i18n_yaml.py [--data=i18n.yml] behave/i18n.py
++"""
++Generates I18N python module based on YAML description (i18n.yml).
++
++REQUIRES:
++  * argparse
++  * six
++  * PyYAML
++"""
++
++from __future__ import absolute_import, print_function
++import argparse
++import os.path
++import six
++import sys
++import pprint
++import yaml
++
++HERE = os.path.dirname(__file__)
++NAME = os.path.basename(__file__)
++__version__ = "1.0"
++
++def yaml_normalize(data):
++    for part in data:
++        keywords = data[part]
++        for k in keywords:
++            v = keywords[k]
++            # bloody YAML parser returns a mixture of unicode and str
++            if not isinstance(v, six.text_type):
++                v = v.decode("UTF-8")
++            keywords[k] = v.split("|")
++    return data
++
++def main(args=None):
++    if args is None:
++        args = sys.argv[1:]
++    parser = argparse.ArgumentParser(prog=NAME,
++                description="Generate python module i18n from YAML based data")
++    parser.add_argument("-d", "--data", dest="yaml_file",
++                default=os.path.join(HERE, "i18n.yml"),
++                help="Path to i18n.yml file (YAML file).")
++    parser.add_argument("output_file", default="stdout",
++                help="Filename of Python I18N module (as output).")
++    parser.add_argument("--version", action="version", version=__version__)
++
++    options = parser.parse_args(args)
++    if not os.path.isfile(options.yaml_file):
++        parser.error("YAML file not found: %s" % options.yaml_file)
++
++    # -- STEP 1: Load YAML data.
++    languages = yaml.load(open(options.yaml_file))
++    languages = yaml_normalize(languages)
++
++    # -- STEP 2: Generate python module with i18n data.
++    contents = u"""# -*- coding: UTF-8 -*-
++# -- FILE GENERATED BY: convert_i18n_yaml.py with i18n.yml
++# pylint: disable=line-too-long
++
++languages = \\
++"""
++    if options.output_file in ("-", "stdout"):
++        i18n_py = sys.stdout
++        should_close = False
++    else:
++        i18n_py = open(options.output_file, "w")
++        should_close = True
++    i18n_py.write(contents.encode("UTF-8"))
++    i18n_py.write(pprint.pformat(languages).encode("UTF-8"))
++    i18n_py.write(u"\n")
++    if should_close:
++        i18n_py.close()
++    return 0
++
++if __name__ == "__main__":
++    sys.exit(main())
+diff --git a/.attic/i18n.yml b/.attic/i18n.yml
+new file mode 100644
+index 0000000..82345a4
+--- /dev/null
++++ b/.attic/i18n.yml
+@@ -0,0 +1,635 @@
++# encoding: UTF-8
++#
++# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if applicable):
++# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
++# http://en.wikipedia.org/wiki/ISO_3166-1
++#
++# If you want several aliases for a keyword, just separate them
++# with a | character. The * is a step keyword alias for all translations.
++#
++# If you do *not* want a trailing space after a keyword, end it with a < character.
++# (See Chinese for examples).
++#
++# This file copyright (c) 2009-2011 Mike Sassak, Gregory Hnatiuk, Aslak Hellesøy
++#
++# Permission is hereby granted, free of charge, to any person obtaining
++# a copy of this software and associated documentation files (the
++# "Software"), to deal in the Software without restriction, including
++# without limitation the rights to use, copy, modify, merge, publish,
++# distribute, sublicense, and/or sell copies of the Software, and to
++# permit persons to whom the Software is furnished to do so, subject to
++# the following conditions:
++#
++# The above copyright notice and this permission notice shall be
++# included in all copies or substantial portions of the Software.
++#
++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++
++"en":
++  name: English
++  native: English
++  feature: Feature
++  background: Background
++  scenario: Scenario
++  scenario_outline: Scenario Outline|Scenario Template
++  examples: Examples|Scenarios
++  given: "*|Given"
++  when: "*|When"
++  then: "*|Then"
++  and: "*|And"
++  but: "*|But"
++
++# Please keep the grammars in alphabetical order by name from here and down.
++
++"ar":
++  name: Arabic
++  native: العربية
++  feature: خاصية
++  background: الخلفية
++  scenario: سيناريو
++  scenario_outline: سيناريو مخطط
++  examples: امثلة
++  given: "*|بفرض"
++  when: "*|متى|عندما"
++  then: "*|اذاً|ثم"
++  and: "*|و"
++  but: "*|لكن"
++"bg":
++  name: Bulgarian
++  native: български
++  feature: Функционалност
++  background: Предистория
++  scenario: Сценарий
++  scenario_outline: Рамка на сценарий
++  examples: Примери
++  given: "*|Дадено"
++  when: "*|Когато"
++  then: "*|То"
++  and: "*|И"
++  but: "*|Но"
++"ca":
++  name: Catalan
++  native: català
++  background: Rerefons|Antecedents
++  feature: Característica|Funcionalitat
++  scenario: Escenari
++  scenario_outline: Esquema de l'escenari
++  examples: Exemples
++  given: "*|Donat|Donada|Atès|Atesa"
++  when: "*|Quan"
++  then: "*|Aleshores|Cal"
++  and: "*|I"
++  but: "*|Però"
++"cy-GB":
++  name: Welsh
++  native: Cymraeg
++  background: Cefndir
++  feature: Arwedd
++  scenario: Scenario
++  scenario_outline: Scenario Amlinellol
++  examples: Enghreifftiau
++  given: "*|Anrhegedig a"
++  when: "*|Pryd"
++  then: "*|Yna"
++  and: "*|A"
++  but: "*|Ond"
++"cs":
++  name: Czech
++  native: Česky
++  feature: Požadavek
++  background: Pozadí|Kontext
++  scenario: Scénář
++  scenario_outline: Náčrt Scénáře|Osnova scénáře
++  examples: Příklady
++  given: "*|Pokud|Za předpokladu"
++  when: "*|Když"
++  then: "*|Pak"
++  and: "*|A|A také"
++  but: "*|Ale"
++"da":
++  name: Danish
++  native: dansk
++  feature: Egenskab
++  background: Baggrund
++  scenario: Scenarie
++  scenario_outline: Abstrakt Scenario
++  examples: Eksempler
++  given: "*|Givet"
++  when: "*|Når"
++  then: "*|Så"
++  and: "*|Og"
++  but: "*|Men"
++"de":
++  name: German
++  native: Deutsch
++  feature: Funktionalität
++  background: Grundlage
++  scenario: Szenario
++  scenario_outline: Szenariogrundriss
++  examples: Beispiele
++  given: "*|Angenommen|Gegeben sei"
++  when: "*|Wenn"
++  then: "*|Dann"
++  and: "*|Und"
++  but: "*|Aber"
++"en-au":
++  name: Australian
++  native: Australian
++  feature: Crikey
++  background: Background
++  scenario: Mate
++  scenario_outline: Blokes
++  examples: Cobber
++  given: "*|Ya know how"
++  when: "*|When"
++  then: "*|Ya gotta"
++  and: "*|N"
++  but: "*|Cept"
++"en-lol":
++  name: LOLCAT
++  native: LOLCAT
++  feature: OH HAI
++  background: B4
++  scenario: MISHUN
++  scenario_outline: MISHUN SRSLY
++  examples: EXAMPLZ
++  given: "*|I CAN HAZ"
++  when: "*|WEN"
++  then: "*|DEN"
++  and: "*|AN"
++  but: "*|BUT"
++"en-pirate":
++  name: Pirate
++  native: Pirate
++  feature: Ahoy matey!
++  background: Yo-ho-ho
++  scenario: Heave to
++  scenario_outline: Shiver me timbers
++  examples: Dead men tell no tales
++  given: "*|Gangway!"
++  when: "*|Blimey!"
++  then: "*|Let go and haul"
++  and: "*|Aye"
++  but: "*|Avast!"
++"en-Scouse":
++  name: Scouse
++  native: Scouse
++  feature: Feature
++  background: "Dis is what went down"
++  scenario: "The thing of it is"
++  scenario_outline: "Wharrimean is"
++  examples: Examples
++  given: "*|Givun|Youse know when youse got"
++  when: "*|Wun|Youse know like when"
++  then: "*|Dun|Den youse gotta"
++  and: "*|An"
++  but: "*|Buh"
++"en-tx":
++  name: Texan
++  native: Texan
++  feature: Feature
++  background: Background
++  scenario: Scenario
++  scenario_outline: All y'all
++  examples: Examples
++  given: "*|Given y'all"
++  when: "*|When y'all"
++  then: "*|Then y'all"
++  and: "*|And y'all"
++  but: "*|But y'all"
++"eo":
++  name: Esperanto
++  native: Esperanto
++  feature: Trajto
++  background: Fono
++  scenario: Scenaro
++  scenario_outline: Konturo de la scenaro
++  examples: Ekzemploj
++  given: "*|Donitaĵo"
++  when: "*|Se"
++  then: "*|Do"
++  and: "*|Kaj"
++  but: "*|Sed"
++"es":
++  name: Spanish
++  native: español
++  background: Antecedentes
++  feature: Característica
++  scenario: Escenario
++  scenario_outline: Esquema del escenario
++  examples: Ejemplos
++  given: "*|Dado|Dada|Dados|Dadas"
++  when: "*|Cuando"
++  then: "*|Entonces"
++  and: "*|Y"
++  but: "*|Pero"
++"et":
++  name: Estonian
++  native: eesti keel
++  feature: Omadus
++  background: Taust
++  scenario: Stsenaarium
++  scenario_outline: Raamstsenaarium
++  examples: Juhtumid
++  given: "*|Eeldades"
++  when: "*|Kui"
++  then: "*|Siis"
++  and: "*|Ja"
++  but: "*|Kuid"
++"fi":
++  name: Finnish
++  native: suomi
++  feature: Ominaisuus
++  background: Tausta
++  scenario: Tapaus
++  scenario_outline: Tapausaihio
++  examples: Tapaukset
++  given: "*|Oletetaan"
++  when: "*|Kun"
++  then: "*|Niin"
++  and: "*|Ja"
++  but: "*|Mutta"
++"fr":
++  name: French
++  native: français
++  feature: Fonctionnalité
++  background: Contexte
++  scenario: Scénario
++  scenario_outline: Plan du scénario|Plan du Scénario
++  examples: Exemples
++  given: "*|Soit|Etant donné|Etant donnée|Etant donnés|Etant données|Étant donné|Étant donnée|Étant donnés|Étant données"
++  when: "*|Quand|Lorsque|Lorsqu'<"
++  then: "*|Alors"
++  and: "*|Et"
++  but: "*|Mais"
++"gl":
++  name: Galician
++  native: galego
++  feature: Característica
++  background: Contexto
++  scenario: Escenario
++  scenario_outline: "Esbozo do escenario"
++  examples: Exemplos
++  given: "*|Dado|Dada|Dados|Dadas"
++  when: "*|Cando"
++  then: "*|Entón|Logo"
++  and: "*|E"
++  but: "*|Mais|Pero"
++
++"he":
++  name: Hebrew
++  native: עברית
++  feature: תכונה
++  background: רקע
++  scenario: תרחיש
++  scenario_outline: תבנית תרחיש
++  examples: דוגמאות
++  given: "*|בהינתן"
++  when: "*|כאשר"
++  then: "*|אז|אזי"
++  and: "*|וגם"
++  but: "*|אבל"
++"hr":
++  name: Croatian
++  native: hrvatski
++  feature: Osobina|Mogućnost|Mogucnost
++  background: Pozadina
++  scenario: Scenarij
++  scenario_outline: Skica|Koncept
++  examples: Primjeri|Scenariji
++  given: "*|Zadan|Zadani|Zadano"
++  when: "*|Kada|Kad"
++  then: "*|Onda"
++  and: "*|I"
++  but: "*|Ali"
++"hu":
++  name: Hungarian
++  native: magyar
++  feature: Jellemző
++  background: Háttér
++  scenario: Forgatókönyv
++  scenario_outline: Forgatókönyv vázlat
++  examples: Példák
++  given: "*|Amennyiben|Adott"
++  when: "*|Majd|Ha|Amikor"
++  then: "*|Akkor"
++  and: "*|És"
++  but: "*|De"
++"id":
++  name: Indonesian
++  native: Bahasa Indonesia
++  feature: Fitur
++  background: Dasar
++  scenario: Skenario
++  scenario_outline: Skenario konsep
++  examples: Contoh
++  given: "*|Dengan"
++  when: "*|Ketika"
++  then: "*|Maka"
++  and: "*|Dan"
++  but: "*|Tapi"
++"is":
++  name: Icelandic
++  native: Íslenska
++  feature: Eiginleiki
++  background: Bakgrunnur
++  scenario: Atburðarás
++  scenario_outline: Lýsing Atburðarásar|Lýsing Dæma
++  examples: Dæmi|Atburðarásir
++  given: "*|Ef"
++  when: "*|Þegar"
++  then: "*|Þá"
++  and: "*|Og"
++  but: "*|En"
++"it":
++  name: Italian
++  native: italiano
++  feature: Funzionalità
++  background: Contesto
++  scenario: Scenario
++  scenario_outline: Schema dello scenario
++  examples: Esempi
++  given: "*|Dato|Data|Dati|Date"
++  when: "*|Quando"
++  then: "*|Allora"
++  and: "*|E"
++  but: "*|Ma"
++"ja":
++  name: Japanese
++  native: 日本語
++  feature: フィーチャ|機能
++  background: 背景
++  scenario: シナリオ
++  scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
++  examples: 例|サンプル
++  given: "*|前提<"
++  when: "*|もし<"
++  then: "*|ならば<"
++  and: "*|かつ<"
++  but: "*|しかし<|但し<|ただし<"
++"ko":
++  name: Korean
++  native: 한국어
++  background: 배경
++  feature: 기능
++  scenario: 시나리오
++  scenario_outline: 시나리오 개요
++  examples: 예
++  given: "*|조건<|먼저<"
++  when: "*|만일<|만약<"
++  then: "*|그러면<"
++  and: "*|그리고<"
++  but: "*|하지만<|단<"
++"lt":
++  name: Lithuanian
++  native: lietuvių kalba
++  feature: Savybė
++  background: Kontekstas
++  scenario: Scenarijus
++  scenario_outline: Scenarijaus šablonas
++  examples: Pavyzdžiai|Scenarijai|Variantai
++  given: "*|Duota"
++  when: "*|Kai"
++  then: "*|Tada"
++  and: "*|Ir"
++  but: "*|Bet"
++"lu":
++  name: Luxemburgish
++  native: Lëtzebuergesch
++  feature: Funktionalitéit
++  background: Hannergrond
++  scenario: Szenario
++  scenario_outline: Plang vum Szenario
++  examples: Beispiller
++  given: "*|ugeholl"
++  when: "*|wann"
++  then: "*|dann"
++  and: "*|an|a"
++  but: "*|awer|mä"
++"lv":
++  name: Latvian
++  native: latviešu
++  feature: Funkcionalitāte|Fīča
++  background: Konteksts|Situācija
++  scenario: Scenārijs
++  scenario_outline: Scenārijs pēc parauga
++  examples: Piemēri|Paraugs
++  given: "*|Kad"
++  when: "*|Ja"
++  then: "*|Tad"
++  and: "*|Un"
++  but: "*|Bet"
++"nl":
++  name: Dutch
++  native: Nederlands
++  feature: Functionaliteit
++  background: Achtergrond
++  scenario: Scenario
++  scenario_outline: Abstract Scenario
++  examples: Voorbeelden
++  given: "*|Gegeven|Stel"
++  when: "*|Als"
++  then: "*|Dan"
++  and: "*|En"
++  but: "*|Maar"
++"no":
++  name: Norwegian
++  native: norsk
++  feature: Egenskap
++  background: Bakgrunn
++  scenario: Scenario
++  scenario_outline: Scenariomal|Abstrakt Scenario
++  examples: Eksempler
++  given: "*|Gitt"
++  when: "*|Når"
++  then: "*|Så"
++  and: "*|Og"
++  but: "*|Men"
++"pl":
++  name: Polish
++  native: polski
++  feature: Właściwość
++  background: Założenia
++  scenario: Scenariusz
++  scenario_outline: Szablon scenariusza
++  examples: Przykłady
++  given: "*|Zakładając|Mając"
++  when: "*|Jeżeli|Jeśli"
++  then: "*|Wtedy"
++  and: "*|Oraz|I"
++  but: "*|Ale"
++"pt":
++  name: Portuguese
++  native: português
++  background: Contexto
++  feature: Funcionalidade
++  scenario: Cenário|Cenario
++  scenario_outline: Esquema do Cenário|Esquema do Cenario
++  examples: Exemplos
++  given: "*|Dado|Dada|Dados|Dadas"
++  when: "*|Quando"
++  then: "*|Então|Entao"
++  and: "*|E"
++  but: "*|Mas"
++"ro":
++  name: Romanian
++  native: română
++  background: Context
++  feature: Functionalitate|Funcționalitate|Funcţionalitate
++  scenario: Scenariu
++  scenario_outline: Structura scenariu|Structură scenariu
++  examples: Exemple
++  given: "*|Date fiind|Dat fiind|Dati fiind|Dați fiind|Daţi fiind"
++  when: "*|Cand|Când"
++  then: "*|Atunci"
++  and: "*|Si|Și|Şi"
++  but: "*|Dar"
++"ru":
++  name: Russian
++  native: русский
++  feature: Функция|Функционал|Свойство
++  background: Предыстория|Контекст
++  scenario: Сценарий
++  scenario_outline: Структура сценария
++  examples: Примеры
++  given: "*|Допустим|Дано|Пусть"
++  when: "*|Если|Когда"
++  then: "*|То|Тогда"
++  and: "*|И|К тому же"
++  but: "*|Но|А"
++"sv":
++  name: Swedish
++  native: Svenska
++  feature: Egenskap
++  background: Bakgrund
++  scenario: Scenario
++  scenario_outline: Abstrakt Scenario|Scenariomall
++  examples: Exempel
++  given: "*|Givet"
++  when: "*|När"
++  then: "*|Så"
++  and: "*|Och"
++  but: "*|Men"
++"sk":
++  name: Slovak
++  native: Slovensky
++  feature: Požiadavka
++  background: Pozadie
++  scenario: Scenár
++  scenario_outline: Náčrt Scenáru
++  examples: Príklady
++  given: "*|Pokiaľ"
++  when: "*|Keď"
++  then: "*|Tak"
++  and: "*|A"
++  but: "*|Ale"
++"sr-Latn":
++  name: Serbian (Latin)
++  native: Srpski (Latinica)
++  feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
++  background: Kontekst|Osnova|Pozadina
++  scenario: Scenario|Primer
++  scenario_outline: Struktura scenarija|Skica|Koncept
++  examples: Primeri|Scenariji
++  given: "*|Zadato|Zadate|Zatati"
++  when: "*|Kada|Kad"
++  then: "*|Onda"
++  and: "*|I"
++  but: "*|Ali"
++"sr-Cyrl":
++  name: Serbian
++  native: Српски
++  feature: Функционалност|Могућност|Особина
++  background: Контекст|Основа|Позадина
++  scenario: Сценарио|Пример
++  scenario_outline: Структура сценарија|Скица|Концепт
++  examples: Примери|Сценарији
++  given: "*|Задато|Задате|Задати"
++  when: "*|Када|Кад"
++  then: "*|Онда"
++  and: "*|И"
++  but: "*|Али"
++"tr":
++  name: Turkish
++  native: Türkçe
++  feature: Özellik
++  background: Geçmiş
++  scenario: Senaryo
++  scenario_outline: Senaryo taslağı
++  examples: Örnekler
++  given: "*|Diyelim ki"
++  when: "*|Eğer ki"
++  then: "*|O zaman"
++  and: "*|Ve"
++  but: "*|Fakat|Ama"
++"uk":
++  name: Ukrainian
++  native: Українська
++  feature: Функціонал
++  background: Передумова
++  scenario: Сценарій
++  scenario_outline: Структура сценарію
++  examples: Приклади
++  given: "*|Припустимо|Припустимо, що|Нехай|Дано"
++  when: "*|Якщо|Коли"
++  then: "*|То|Тоді"
++  and: "*|І|А також|Та"
++  but: "*|Але"
++"uz":
++  name: Uzbek
++  native: Узбекча
++  feature: Функционал
++  background: Тарих
++  scenario: Сценарий
++  scenario_outline: Сценарий структураси
++  examples: Мисоллар
++  given: "*|Агар"
++  when: "*|Агар"
++  then: "*|Унда"
++  and: "*|Ва"
++  but: "*|Лекин|Бирок|Аммо"
++"vi":
++  name: Vietnamese
++  native: Tiếng Việt
++  feature: Tính năng
++  background: Bối cảnh
++  scenario: Tình huống|Kịch bản
++  scenario_outline: Khung tình huống|Khung kịch bản
++  examples: Dữ liệu
++  given: "*|Biết|Cho"
++  when: "*|Khi"
++  then: "*|Thì"
++  and: "*|Và"
++  but: "*|Nhưng"
++"zh-CN":
++  name: Chinese simplified
++  native: 简体中文
++  feature: 功能
++  background: 背景
++  scenario: 场景
++  scenario_outline: 场景大纲
++  examples: 例子
++  given: "*|假如<"
++  when: "*|当<"
++  then: "*|那么<"
++  and: "*|而且<"
++  but: "*|但是<"
++"zh-TW":
++  name: Chinese traditional
++  native: 繁體中文
++  feature: 功能
++  background: 背景
++  scenario: 場景|劇本
++  scenario_outline: 場景大綱|劇本大綱
++  examples: 例子
++  given: "*|假設<"
++  when: "*|當<"
++  then: "*|那麼<"
++  and: "*|而且<|並且<"
++  but: "*|但是<"
+diff --git a/bin/gherkin-languages.json b/bin/gherkin-languages.json
+deleted file mode 100644
+index d2d5e93..0000000
+--- a/bin/gherkin-languages.json
++++ /dev/null
+@@ -1,3193 +0,0 @@
+-{
+-  "af": {
+-    "and": [
+-      "* ",
+-      "En "
+-    ],
+-    "background": [
+-      "Agtergrond"
+-    ],
+-    "but": [
+-      "* ",
+-      "Maar "
+-    ],
+-    "examples": [
+-      "Voorbeelde"
+-    ],
+-    "feature": [
+-      "Funksie",
+-      "Besigheid Behoefte",
+-      "Vermoë"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gegewe "
+-    ],
+-    "name": "Afrikaans",
+-    "native": "Afrikaans",
+-    "scenario": [
+-      "Situasie"
+-    ],
+-    "scenarioOutline": [
+-      "Situasie Uiteensetting"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "when": [
+-      "* ",
+-      "Wanneer "
+-    ]
+-  },
+-  "am": {
+-    "and": [
+-      "* ",
+-      "Եվ "
+-    ],
+-    "background": [
+-      "Կոնտեքստ"
+-    ],
+-    "but": [
+-      "* ",
+-      "Բայց "
+-    ],
+-    "examples": [
+-      "Օրինակներ"
+-    ],
+-    "feature": [
+-      "Ֆունկցիոնալություն",
+-      "Հատկություն"
+-    ],
+-    "given": [
+-      "* ",
+-      "Դիցուք "
+-    ],
+-    "name": "Armenian",
+-    "native": "հայերեն",
+-    "scenario": [
+-      "Սցենար"
+-    ],
+-    "scenarioOutline": [
+-      "Սցենարի կառուցվացքը"
+-    ],
+-    "then": [
+-      "* ",
+-      "Ապա "
+-    ],
+-    "when": [
+-      "* ",
+-      "Եթե ",
+-      "Երբ "
+-    ]
+-  },
+-  "ar": {
+-    "and": [
+-      "* ",
+-      "و "
+-    ],
+-    "background": [
+-      "الخلفية"
+-    ],
+-    "but": [
+-      "* ",
+-      "لكن "
+-    ],
+-    "examples": [
+-      "امثلة"
+-    ],
+-    "feature": [
+-      "خاصية"
+-    ],
+-    "given": [
+-      "* ",
+-      "بفرض "
+-    ],
+-    "name": "Arabic",
+-    "native": "العربية",
+-    "scenario": [
+-      "سيناريو"
+-    ],
+-    "scenarioOutline": [
+-      "سيناريو مخطط"
+-    ],
+-    "then": [
+-      "* ",
+-      "اذاً ",
+-      "ثم "
+-    ],
+-    "when": [
+-      "* ",
+-      "متى ",
+-      "عندما "
+-    ]
+-  },
+-  "ast": {
+-    "and": [
+-      "* ",
+-      "Y ",
+-      "Ya "
+-    ],
+-    "background": [
+-      "Antecedentes"
+-    ],
+-    "but": [
+-      "* ",
+-      "Peru "
+-    ],
+-    "examples": [
+-      "Exemplos"
+-    ],
+-    "feature": [
+-      "Carauterística"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dáu ",
+-      "Dada ",
+-      "Daos ",
+-      "Daes "
+-    ],
+-    "name": "Asturian",
+-    "native": "asturianu",
+-    "scenario": [
+-      "Casu"
+-    ],
+-    "scenarioOutline": [
+-      "Esbozu del casu"
+-    ],
+-    "then": [
+-      "* ",
+-      "Entós "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cuando "
+-    ]
+-  },
+-  "az": {
+-    "and": [
+-      "* ",
+-      "Və ",
+-      "Həm "
+-    ],
+-    "background": [
+-      "Keçmiş",
+-      "Kontekst"
+-    ],
+-    "but": [
+-      "* ",
+-      "Amma ",
+-      "Ancaq "
+-    ],
+-    "examples": [
+-      "Nümunələr"
+-    ],
+-    "feature": [
+-      "Özəllik"
+-    ],
+-    "given": [
+-      "* ",
+-      "Tutaq ki ",
+-      "Verilir "
+-    ],
+-    "name": "Azerbaijani",
+-    "native": "Azərbaycanca",
+-    "scenario": [
+-      "Ssenari"
+-    ],
+-    "scenarioOutline": [
+-      "Ssenarinin strukturu"
+-    ],
+-    "then": [
+-      "* ",
+-      "O halda "
+-    ],
+-    "when": [
+-      "* ",
+-      "Əgər ",
+-      "Nə vaxt ki "
+-    ]
+-  },
+-  "bg": {
+-    "and": [
+-      "* ",
+-      "И "
+-    ],
+-    "background": [
+-      "Предистория"
+-    ],
+-    "but": [
+-      "* ",
+-      "Но "
+-    ],
+-    "examples": [
+-      "Примери"
+-    ],
+-    "feature": [
+-      "Функционалност"
+-    ],
+-    "given": [
+-      "* ",
+-      "Дадено "
+-    ],
+-    "name": "Bulgarian",
+-    "native": "български",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Рамка на сценарий"
+-    ],
+-    "then": [
+-      "* ",
+-      "То "
+-    ],
+-    "when": [
+-      "* ",
+-      "Когато "
+-    ]
+-  },
+-  "bm": {
+-    "and": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "background": [
+-      "Latar Belakang"
+-    ],
+-    "but": [
+-      "* ",
+-      "Tetapi ",
+-      "Tapi "
+-    ],
+-    "examples": [
+-      "Contoh"
+-    ],
+-    "feature": [
+-      "Fungsi"
+-    ],
+-    "given": [
+-      "* ",
+-      "Diberi ",
+-      "Bagi "
+-    ],
+-    "name": "Malay",
+-    "native": "Bahasa Melayu",
+-    "scenario": [
+-      "Senario",
+-      "Situasi",
+-      "Keadaan"
+-    ],
+-    "scenarioOutline": [
+-      "Kerangka Senario",
+-      "Kerangka Situasi",
+-      "Kerangka Keadaan",
+-      "Garis Panduan Senario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Maka ",
+-      "Kemudian "
+-    ],
+-    "when": [
+-      "* ",
+-      "Apabila "
+-    ]
+-  },
+-  "bs": {
+-    "and": [
+-      "* ",
+-      "I ",
+-      "A "
+-    ],
+-    "background": [
+-      "Pozadina"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ali "
+-    ],
+-    "examples": [
+-      "Primjeri"
+-    ],
+-    "feature": [
+-      "Karakteristika"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dato "
+-    ],
+-    "name": "Bosnian",
+-    "native": "Bosanski",
+-    "scenario": [
+-      "Scenariju",
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenariju-obris",
+-      "Scenario-outline"
+-    ],
+-    "then": [
+-      "* ",
+-      "Zatim "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kada "
+-    ]
+-  },
+-  "ca": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Rerefons",
+-      "Antecedents"
+-    ],
+-    "but": [
+-      "* ",
+-      "Però "
+-    ],
+-    "examples": [
+-      "Exemples"
+-    ],
+-    "feature": [
+-      "Característica",
+-      "Funcionalitat"
+-    ],
+-    "given": [
+-      "* ",
+-      "Donat ",
+-      "Donada ",
+-      "Atès ",
+-      "Atesa "
+-    ],
+-    "name": "Catalan",
+-    "native": "català",
+-    "scenario": [
+-      "Escenari"
+-    ],
+-    "scenarioOutline": [
+-      "Esquema de l'escenari"
+-    ],
+-    "then": [
+-      "* ",
+-      "Aleshores ",
+-      "Cal "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quan "
+-    ]
+-  },
+-  "cs": {
+-    "and": [
+-      "* ",
+-      "A také ",
+-      "A "
+-    ],
+-    "background": [
+-      "Pozadí",
+-      "Kontext"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ale "
+-    ],
+-    "examples": [
+-      "Příklady"
+-    ],
+-    "feature": [
+-      "Požadavek"
+-    ],
+-    "given": [
+-      "* ",
+-      "Pokud ",
+-      "Za předpokladu "
+-    ],
+-    "name": "Czech",
+-    "native": "Česky",
+-    "scenario": [
+-      "Scénář"
+-    ],
+-    "scenarioOutline": [
+-      "Náčrt Scénáře",
+-      "Osnova scénáře"
+-    ],
+-    "then": [
+-      "* ",
+-      "Pak "
+-    ],
+-    "when": [
+-      "* ",
+-      "Když "
+-    ]
+-  },
+-  "cy-GB": {
+-    "and": [
+-      "* ",
+-      "A "
+-    ],
+-    "background": [
+-      "Cefndir"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ond "
+-    ],
+-    "examples": [
+-      "Enghreifftiau"
+-    ],
+-    "feature": [
+-      "Arwedd"
+-    ],
+-    "given": [
+-      "* ",
+-      "Anrhegedig a "
+-    ],
+-    "name": "Welsh",
+-    "native": "Cymraeg",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenario Amlinellol"
+-    ],
+-    "then": [
+-      "* ",
+-      "Yna "
+-    ],
+-    "when": [
+-      "* ",
+-      "Pryd "
+-    ]
+-  },
+-  "da": {
+-    "and": [
+-      "* ",
+-      "Og "
+-    ],
+-    "background": [
+-      "Baggrund"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Eksempler"
+-    ],
+-    "feature": [
+-      "Egenskab"
+-    ],
+-    "given": [
+-      "* ",
+-      "Givet "
+-    ],
+-    "name": "Danish",
+-    "native": "dansk",
+-    "scenario": [
+-      "Scenarie"
+-    ],
+-    "scenarioOutline": [
+-      "Abstrakt Scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Så "
+-    ],
+-    "when": [
+-      "* ",
+-      "Når "
+-    ]
+-  },
+-  "de": {
+-    "and": [
+-      "* ",
+-      "Und "
+-    ],
+-    "background": [
+-      "Grundlage"
+-    ],
+-    "but": [
+-      "* ",
+-      "Aber "
+-    ],
+-    "examples": [
+-      "Beispiele"
+-    ],
+-    "feature": [
+-      "Funktionalität"
+-    ],
+-    "given": [
+-      "* ",
+-      "Angenommen ",
+-      "Gegeben sei ",
+-      "Gegeben seien "
+-    ],
+-    "name": "German",
+-    "native": "Deutsch",
+-    "scenario": [
+-      "Szenario"
+-    ],
+-    "scenarioOutline": [
+-      "Szenariogrundriss"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dann "
+-    ],
+-    "when": [
+-      "* ",
+-      "Wenn "
+-    ]
+-  },
+-  "el": {
+-    "and": [
+-      "* ",
+-      "Και "
+-    ],
+-    "background": [
+-      "Υπόβαθρο"
+-    ],
+-    "but": [
+-      "* ",
+-      "Αλλά "
+-    ],
+-    "examples": [
+-      "Παραδείγματα",
+-      "Σενάρια"
+-    ],
+-    "feature": [
+-      "Δυνατότητα",
+-      "Λειτουργία"
+-    ],
+-    "given": [
+-      "* ",
+-      "Δεδομένου "
+-    ],
+-    "name": "Greek",
+-    "native": "Ελληνικά",
+-    "scenario": [
+-      "Σενάριο"
+-    ],
+-    "scenarioOutline": [
+-      "Περιγραφή Σεναρίου",
+-      "Περίγραμμα Σεναρίου"
+-    ],
+-    "then": [
+-      "* ",
+-      "Τότε "
+-    ],
+-    "when": [
+-      "* ",
+-      "Όταν "
+-    ]
+-  },
+-  "em": {
+-    "and": [
+-      "* ",
+-      "😂"
+-    ],
+-    "background": [
+-      "💤"
+-    ],
+-    "but": [
+-      "* ",
+-      "😔"
+-    ],
+-    "examples": [
+-      "📓"
+-    ],
+-    "feature": [
+-      "📚"
+-    ],
+-    "given": [
+-      "* ",
+-      "😐"
+-    ],
+-    "name": "Emoji",
+-    "native": "😀",
+-    "scenario": [
+-      "📕"
+-    ],
+-    "scenarioOutline": [
+-      "📖"
+-    ],
+-    "then": [
+-      "* ",
+-      "🙏"
+-    ],
+-    "when": [
+-      "* ",
+-      "🎬"
+-    ]
+-  },
+-  "en": {
+-    "and": [
+-      "* ",
+-      "And "
+-    ],
+-    "background": [
+-      "Background"
+-    ],
+-    "but": [
+-      "* ",
+-      "But "
+-    ],
+-    "examples": [
+-      "Examples",
+-      "Scenarios"
+-    ],
+-    "feature": [
+-      "Feature",
+-      "Business Need",
+-      "Ability"
+-    ],
+-    "given": [
+-      "* ",
+-      "Given "
+-    ],
+-    "name": "English",
+-    "native": "English",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenario Outline",
+-      "Scenario Template"
+-    ],
+-    "then": [
+-      "* ",
+-      "Then "
+-    ],
+-    "when": [
+-      "* ",
+-      "When "
+-    ]
+-  },
+-  "en-Scouse": {
+-    "and": [
+-      "* ",
+-      "An "
+-    ],
+-    "background": [
+-      "Dis is what went down"
+-    ],
+-    "but": [
+-      "* ",
+-      "Buh "
+-    ],
+-    "examples": [
+-      "Examples"
+-    ],
+-    "feature": [
+-      "Feature"
+-    ],
+-    "given": [
+-      "* ",
+-      "Givun ",
+-      "Youse know when youse got "
+-    ],
+-    "name": "Scouse",
+-    "native": "Scouse",
+-    "scenario": [
+-      "The thing of it is"
+-    ],
+-    "scenarioOutline": [
+-      "Wharrimean is"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dun ",
+-      "Den youse gotta "
+-    ],
+-    "when": [
+-      "* ",
+-      "Wun ",
+-      "Youse know like when "
+-    ]
+-  },
+-  "en-au": {
+-    "and": [
+-      "* ",
+-      "Too right "
+-    ],
+-    "background": [
+-      "First off"
+-    ],
+-    "but": [
+-      "* ",
+-      "Yeah nah "
+-    ],
+-    "examples": [
+-      "You'll wanna"
+-    ],
+-    "feature": [
+-      "Pretty much"
+-    ],
+-    "given": [
+-      "* ",
+-      "Y'know "
+-    ],
+-    "name": "Australian",
+-    "native": "Australian",
+-    "scenario": [
+-      "Awww, look mate"
+-    ],
+-    "scenarioOutline": [
+-      "Reckon it's like"
+-    ],
+-    "then": [
+-      "* ",
+-      "But at the end of the day I reckon "
+-    ],
+-    "when": [
+-      "* ",
+-      "It's just unbelievable "
+-    ]
+-  },
+-  "en-lol": {
+-    "and": [
+-      "* ",
+-      "AN "
+-    ],
+-    "background": [
+-      "B4"
+-    ],
+-    "but": [
+-      "* ",
+-      "BUT "
+-    ],
+-    "examples": [
+-      "EXAMPLZ"
+-    ],
+-    "feature": [
+-      "OH HAI"
+-    ],
+-    "given": [
+-      "* ",
+-      "I CAN HAZ "
+-    ],
+-    "name": "LOLCAT",
+-    "native": "LOLCAT",
+-    "scenario": [
+-      "MISHUN"
+-    ],
+-    "scenarioOutline": [
+-      "MISHUN SRSLY"
+-    ],
+-    "then": [
+-      "* ",
+-      "DEN "
+-    ],
+-    "when": [
+-      "* ",
+-      "WEN "
+-    ]
+-  },
+-  "en-old": {
+-    "and": [
+-      "* ",
+-      "Ond ",
+-      "7 "
+-    ],
+-    "background": [
+-      "Aer",
+-      "Ær"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ac "
+-    ],
+-    "examples": [
+-      "Se the",
+-      "Se þe",
+-      "Se ðe"
+-    ],
+-    "feature": [
+-      "Hwaet",
+-      "Hwæt"
+-    ],
+-    "given": [
+-      "* ",
+-      "Thurh ",
+-      "Þurh ",
+-      "Ðurh "
+-    ],
+-    "name": "Old English",
+-    "native": "Englisc",
+-    "scenario": [
+-      "Swa"
+-    ],
+-    "scenarioOutline": [
+-      "Swa hwaer swa",
+-      "Swa hwær swa"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tha ",
+-      "Þa ",
+-      "Ða ",
+-      "Tha the ",
+-      "Þa þe ",
+-      "Ða ðe "
+-    ],
+-    "when": [
+-      "* ",
+-      "Tha ",
+-      "Þa ",
+-      "Ða "
+-    ]
+-  },
+-  "en-pirate": {
+-    "and": [
+-      "* ",
+-      "Aye "
+-    ],
+-    "background": [
+-      "Yo-ho-ho"
+-    ],
+-    "but": [
+-      "* ",
+-      "Avast! "
+-    ],
+-    "examples": [
+-      "Dead men tell no tales"
+-    ],
+-    "feature": [
+-      "Ahoy matey!"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gangway! "
+-    ],
+-    "name": "Pirate",
+-    "native": "Pirate",
+-    "scenario": [
+-      "Heave to"
+-    ],
+-    "scenarioOutline": [
+-      "Shiver me timbers"
+-    ],
+-    "then": [
+-      "* ",
+-      "Let go and haul "
+-    ],
+-    "when": [
+-      "* ",
+-      "Blimey! "
+-    ]
+-  },
+-  "eo": {
+-    "and": [
+-      "* ",
+-      "Kaj "
+-    ],
+-    "background": [
+-      "Fono"
+-    ],
+-    "but": [
+-      "* ",
+-      "Sed "
+-    ],
+-    "examples": [
+-      "Ekzemploj"
+-    ],
+-    "feature": [
+-      "Trajto"
+-    ],
+-    "given": [
+-      "* ",
+-      "Donitaĵo ",
+-      "Komence "
+-    ],
+-    "name": "Esperanto",
+-    "native": "Esperanto",
+-    "scenario": [
+-      "Scenaro",
+-      "Kazo"
+-    ],
+-    "scenarioOutline": [
+-      "Konturo de la scenaro",
+-      "Skizo",
+-      "Kazo-skizo"
+-    ],
+-    "then": [
+-      "* ",
+-      "Do "
+-    ],
+-    "when": [
+-      "* ",
+-      "Se "
+-    ]
+-  },
+-  "es": {
+-    "and": [
+-      "* ",
+-      "Y ",
+-      "E "
+-    ],
+-    "background": [
+-      "Antecedentes"
+-    ],
+-    "but": [
+-      "* ",
+-      "Pero "
+-    ],
+-    "examples": [
+-      "Ejemplos"
+-    ],
+-    "feature": [
+-      "Característica"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dado ",
+-      "Dada ",
+-      "Dados ",
+-      "Dadas "
+-    ],
+-    "name": "Spanish",
+-    "native": "español",
+-    "scenario": [
+-      "Escenario"
+-    ],
+-    "scenarioOutline": [
+-      "Esquema del escenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Entonces "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cuando "
+-    ]
+-  },
+-  "et": {
+-    "and": [
+-      "* ",
+-      "Ja "
+-    ],
+-    "background": [
+-      "Taust"
+-    ],
+-    "but": [
+-      "* ",
+-      "Kuid "
+-    ],
+-    "examples": [
+-      "Juhtumid"
+-    ],
+-    "feature": [
+-      "Omadus"
+-    ],
+-    "given": [
+-      "* ",
+-      "Eeldades "
+-    ],
+-    "name": "Estonian",
+-    "native": "eesti keel",
+-    "scenario": [
+-      "Stsenaarium"
+-    ],
+-    "scenarioOutline": [
+-      "Raamstsenaarium"
+-    ],
+-    "then": [
+-      "* ",
+-      "Siis "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kui "
+-    ]
+-  },
+-  "fa": {
+-    "and": [
+-      "* ",
+-      "و "
+-    ],
+-    "background": [
+-      "زمینه"
+-    ],
+-    "but": [
+-      "* ",
+-      "اما "
+-    ],
+-    "examples": [
+-      "نمونه ها"
+-    ],
+-    "feature": [
+-      "وِیژگی"
+-    ],
+-    "given": [
+-      "* ",
+-      "با فرض "
+-    ],
+-    "name": "Persian",
+-    "native": "فارسی",
+-    "scenario": [
+-      "سناریو"
+-    ],
+-    "scenarioOutline": [
+-      "الگوی سناریو"
+-    ],
+-    "then": [
+-      "* ",
+-      "آنگاه "
+-    ],
+-    "when": [
+-      "* ",
+-      "هنگامی "
+-    ]
+-  },
+-  "fi": {
+-    "and": [
+-      "* ",
+-      "Ja "
+-    ],
+-    "background": [
+-      "Tausta"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mutta "
+-    ],
+-    "examples": [
+-      "Tapaukset"
+-    ],
+-    "feature": [
+-      "Ominaisuus"
+-    ],
+-    "given": [
+-      "* ",
+-      "Oletetaan "
+-    ],
+-    "name": "Finnish",
+-    "native": "suomi",
+-    "scenario": [
+-      "Tapaus"
+-    ],
+-    "scenarioOutline": [
+-      "Tapausaihio"
+-    ],
+-    "then": [
+-      "* ",
+-      "Niin "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kun "
+-    ]
+-  },
+-  "fr": {
+-    "and": [
+-      "* ",
+-      "Et que ",
+-      "Et qu'",
+-      "Et "
+-    ],
+-    "background": [
+-      "Contexte"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mais que ",
+-      "Mais qu'",
+-      "Mais "
+-    ],
+-    "examples": [
+-      "Exemples"
+-    ],
+-    "feature": [
+-      "Fonctionnalité"
+-    ],
+-    "given": [
+-      "* ",
+-      "Soit ",
+-      "Etant donné que ",
+-      "Etant donné qu'",
+-      "Etant donné ",
+-      "Etant donnée ",
+-      "Etant donnés ",
+-      "Etant données ",
+-      "Étant donné que ",
+-      "Étant donné qu'",
+-      "Étant donné ",
+-      "Étant donnée ",
+-      "Étant donnés ",
+-      "Étant données "
+-    ],
+-    "name": "French",
+-    "native": "français",
+-    "scenario": [
+-      "Scénario"
+-    ],
+-    "scenarioOutline": [
+-      "Plan du scénario",
+-      "Plan du Scénario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Alors "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quand ",
+-      "Lorsque ",
+-      "Lorsqu'"
+-    ]
+-  },
+-  "ga": {
+-    "and": [
+-      "* ",
+-      "Agus"
+-    ],
+-    "background": [
+-      "Cúlra"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ach"
+-    ],
+-    "examples": [
+-      "Samplaí"
+-    ],
+-    "feature": [
+-      "Gné"
+-    ],
+-    "given": [
+-      "* ",
+-      "Cuir i gcás go",
+-      "Cuir i gcás nach",
+-      "Cuir i gcás gur",
+-      "Cuir i gcás nár"
+-    ],
+-    "name": "Irish",
+-    "native": "Gaeilge",
+-    "scenario": [
+-      "Cás"
+-    ],
+-    "scenarioOutline": [
+-      "Cás Achomair"
+-    ],
+-    "then": [
+-      "* ",
+-      "Ansin"
+-    ],
+-    "when": [
+-      "* ",
+-      "Nuair a",
+-      "Nuair nach",
+-      "Nuair ba",
+-      "Nuair nár"
+-    ]
+-  },
+-  "gj": {
+-    "and": [
+-      "* ",
+-      "અને "
+-    ],
+-    "background": [
+-      "બેકગ્રાઉન્ડ"
+-    ],
+-    "but": [
+-      "* ",
+-      "પણ "
+-    ],
+-    "examples": [
+-      "ઉદાહરણો"
+-    ],
+-    "feature": [
+-      "લક્ષણ",
+-      "વ્યાપાર જરૂર",
+-      "ક્ષમતા"
+-    ],
+-    "given": [
+-      "* ",
+-      "આપેલ છે "
+-    ],
+-    "name": "Gujarati",
+-    "native": "ગુજરાતી",
+-    "scenario": [
+-      "સ્થિતિ"
+-    ],
+-    "scenarioOutline": [
+-      "પરિદ્દશ્ય રૂપરેખા",
+-      "પરિદ્દશ્ય ઢાંચો"
+-    ],
+-    "then": [
+-      "* ",
+-      "પછી "
+-    ],
+-    "when": [
+-      "* ",
+-      "ક્યારે "
+-    ]
+-  },
+-  "gl": {
+-    "and": [
+-      "* ",
+-      "E "
+-    ],
+-    "background": [
+-      "Contexto"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mais ",
+-      "Pero "
+-    ],
+-    "examples": [
+-      "Exemplos"
+-    ],
+-    "feature": [
+-      "Característica"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dado ",
+-      "Dada ",
+-      "Dados ",
+-      "Dadas "
+-    ],
+-    "name": "Galician",
+-    "native": "galego",
+-    "scenario": [
+-      "Escenario"
+-    ],
+-    "scenarioOutline": [
+-      "Esbozo do escenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Entón ",
+-      "Logo "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cando "
+-    ]
+-  },
+-  "he": {
+-    "and": [
+-      "* ",
+-      "וגם "
+-    ],
+-    "background": [
+-      "רקע"
+-    ],
+-    "but": [
+-      "* ",
+-      "אבל "
+-    ],
+-    "examples": [
+-      "דוגמאות"
+-    ],
+-    "feature": [
+-      "תכונה"
+-    ],
+-    "given": [
+-      "* ",
+-      "בהינתן "
+-    ],
+-    "name": "Hebrew",
+-    "native": "עברית",
+-    "scenario": [
+-      "תרחיש"
+-    ],
+-    "scenarioOutline": [
+-      "תבנית תרחיש"
+-    ],
+-    "then": [
+-      "* ",
+-      "אז ",
+-      "אזי "
+-    ],
+-    "when": [
+-      "* ",
+-      "כאשר "
+-    ]
+-  },
+-  "hi": {
+-    "and": [
+-      "* ",
+-      "और ",
+-      "तथा "
+-    ],
+-    "background": [
+-      "पृष्ठभूमि"
+-    ],
+-    "but": [
+-      "* ",
+-      "पर ",
+-      "परन्तु ",
+-      "किन्तु "
+-    ],
+-    "examples": [
+-      "उदाहरण"
+-    ],
+-    "feature": [
+-      "रूप लेख"
+-    ],
+-    "given": [
+-      "* ",
+-      "अगर ",
+-      "यदि ",
+-      "चूंकि "
+-    ],
+-    "name": "Hindi",
+-    "native": "हिंदी",
+-    "scenario": [
+-      "परिदृश्य"
+-    ],
+-    "scenarioOutline": [
+-      "परिदृश्य रूपरेखा"
+-    ],
+-    "then": [
+-      "* ",
+-      "तब ",
+-      "तदा "
+-    ],
+-    "when": [
+-      "* ",
+-      "जब ",
+-      "कदा "
+-    ]
+-  },
+-  "hr": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Pozadina"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ali "
+-    ],
+-    "examples": [
+-      "Primjeri",
+-      "Scenariji"
+-    ],
+-    "feature": [
+-      "Osobina",
+-      "Mogućnost",
+-      "Mogucnost"
+-    ],
+-    "given": [
+-      "* ",
+-      "Zadan ",
+-      "Zadani ",
+-      "Zadano "
+-    ],
+-    "name": "Croatian",
+-    "native": "hrvatski",
+-    "scenario": [
+-      "Scenarij"
+-    ],
+-    "scenarioOutline": [
+-      "Skica",
+-      "Koncept"
+-    ],
+-    "then": [
+-      "* ",
+-      "Onda "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kada ",
+-      "Kad "
+-    ]
+-  },
+-  "ht": {
+-    "and": [
+-      "* ",
+-      "Ak ",
+-      "Epi ",
+-      "E "
+-    ],
+-    "background": [
+-      "Kontèks",
+-      "Istorik"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Egzanp"
+-    ],
+-    "feature": [
+-      "Karakteristik",
+-      "Mak",
+-      "Fonksyonalite"
+-    ],
+-    "given": [
+-      "* ",
+-      "Sipoze ",
+-      "Sipoze ke ",
+-      "Sipoze Ke "
+-    ],
+-    "name": "Creole",
+-    "native": "kreyòl",
+-    "scenario": [
+-      "Senaryo"
+-    ],
+-    "scenarioOutline": [
+-      "Plan senaryo",
+-      "Plan Senaryo",
+-      "Senaryo deskripsyon",
+-      "Senaryo Deskripsyon",
+-      "Dyagram senaryo",
+-      "Dyagram Senaryo"
+-    ],
+-    "then": [
+-      "* ",
+-      "Lè sa a ",
+-      "Le sa a "
+-    ],
+-    "when": [
+-      "* ",
+-      "Lè ",
+-      "Le "
+-    ]
+-  },
+-  "hu": {
+-    "and": [
+-      "* ",
+-      "És "
+-    ],
+-    "background": [
+-      "Háttér"
+-    ],
+-    "but": [
+-      "* ",
+-      "De "
+-    ],
+-    "examples": [
+-      "Példák"
+-    ],
+-    "feature": [
+-      "Jellemző"
+-    ],
+-    "given": [
+-      "* ",
+-      "Amennyiben ",
+-      "Adott "
+-    ],
+-    "name": "Hungarian",
+-    "native": "magyar",
+-    "scenario": [
+-      "Forgatókönyv"
+-    ],
+-    "scenarioOutline": [
+-      "Forgatókönyv vázlat"
+-    ],
+-    "then": [
+-      "* ",
+-      "Akkor "
+-    ],
+-    "when": [
+-      "* ",
+-      "Majd ",
+-      "Ha ",
+-      "Amikor "
+-    ]
+-  },
+-  "id": {
+-    "and": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "background": [
+-      "Dasar"
+-    ],
+-    "but": [
+-      "* ",
+-      "Tapi "
+-    ],
+-    "examples": [
+-      "Contoh"
+-    ],
+-    "feature": [
+-      "Fitur"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dengan "
+-    ],
+-    "name": "Indonesian",
+-    "native": "Bahasa Indonesia",
+-    "scenario": [
+-      "Skenario"
+-    ],
+-    "scenarioOutline": [
+-      "Skenario konsep"
+-    ],
+-    "then": [
+-      "* ",
+-      "Maka "
+-    ],
+-    "when": [
+-      "* ",
+-      "Ketika "
+-    ]
+-  },
+-  "is": {
+-    "and": [
+-      "* ",
+-      "Og "
+-    ],
+-    "background": [
+-      "Bakgrunnur"
+-    ],
+-    "but": [
+-      "* ",
+-      "En "
+-    ],
+-    "examples": [
+-      "Dæmi",
+-      "Atburðarásir"
+-    ],
+-    "feature": [
+-      "Eiginleiki"
+-    ],
+-    "given": [
+-      "* ",
+-      "Ef "
+-    ],
+-    "name": "Icelandic",
+-    "native": "Íslenska",
+-    "scenario": [
+-      "Atburðarás"
+-    ],
+-    "scenarioOutline": [
+-      "Lýsing Atburðarásar",
+-      "Lýsing Dæma"
+-    ],
+-    "then": [
+-      "* ",
+-      "Þá "
+-    ],
+-    "when": [
+-      "* ",
+-      "Þegar "
+-    ]
+-  },
+-  "it": {
+-    "and": [
+-      "* ",
+-      "E "
+-    ],
+-    "background": [
+-      "Contesto"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ma "
+-    ],
+-    "examples": [
+-      "Esempi"
+-    ],
+-    "feature": [
+-      "Funzionalità"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dato ",
+-      "Data ",
+-      "Dati ",
+-      "Date "
+-    ],
+-    "name": "Italian",
+-    "native": "italiano",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Schema dello scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Allora "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quando "
+-    ]
+-  },
+-  "ja": {
+-    "and": [
+-      "* ",
+-      "かつ"
+-    ],
+-    "background": [
+-      "背景"
+-    ],
+-    "but": [
+-      "* ",
+-      "しかし",
+-      "但し",
+-      "ただし"
+-    ],
+-    "examples": [
+-      "例",
+-      "サンプル"
+-    ],
+-    "feature": [
+-      "フィーチャ",
+-      "機能"
+-    ],
+-    "given": [
+-      "* ",
+-      "前提"
+-    ],
+-    "name": "Japanese",
+-    "native": "日本語",
+-    "scenario": [
+-      "シナリオ"
+-    ],
+-    "scenarioOutline": [
+-      "シナリオアウトライン",
+-      "シナリオテンプレート",
+-      "テンプレ",
+-      "シナリオテンプレ"
+-    ],
+-    "then": [
+-      "* ",
+-      "ならば"
+-    ],
+-    "when": [
+-      "* ",
+-      "もし"
+-    ]
+-  },
+-  "jv": {
+-    "and": [
+-      "* ",
+-      "Lan "
+-    ],
+-    "background": [
+-      "Dasar"
+-    ],
+-    "but": [
+-      "* ",
+-      "Tapi ",
+-      "Nanging ",
+-      "Ananging "
+-    ],
+-    "examples": [
+-      "Conto",
+-      "Contone"
+-    ],
+-    "feature": [
+-      "Fitur"
+-    ],
+-    "given": [
+-      "* ",
+-      "Nalika ",
+-      "Nalikaning "
+-    ],
+-    "name": "Javanese",
+-    "native": "Basa Jawa",
+-    "scenario": [
+-      "Skenario"
+-    ],
+-    "scenarioOutline": [
+-      "Konsep skenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Njuk ",
+-      "Banjur "
+-    ],
+-    "when": [
+-      "* ",
+-      "Manawa ",
+-      "Menawa "
+-    ]
+-  },
+-  "ka": {
+-    "and": [
+-      "* ",
+-      "და"
+-    ],
+-    "background": [
+-      "კონტექსტი"
+-    ],
+-    "but": [
+-      "* ",
+-      "მაგ­რამ"
+-    ],
+-    "examples": [
+-      "მაგალითები"
+-    ],
+-    "feature": [
+-      "თვისება"
+-    ],
+-    "given": [
+-      "* ",
+-      "მოცემული"
+-    ],
+-    "name": "Georgian",
+-    "native": "ქართველი",
+-    "scenario": [
+-      "სცენარის"
+-    ],
+-    "scenarioOutline": [
+-      "სცენარის ნიმუში"
+-    ],
+-    "then": [
+-      "* ",
+-      "მაშინ"
+-    ],
+-    "when": [
+-      "* ",
+-      "როდესაც"
+-    ]
+-  },
+-  "kn": {
+-    "and": [
+-      "* ",
+-      "ಮತ್ತು "
+-    ],
+-    "background": [
+-      "ಹಿನ್ನೆಲೆ"
+-    ],
+-    "but": [
+-      "* ",
+-      "ಆದರೆ "
+-    ],
+-    "examples": [
+-      "ಉದಾಹರಣೆಗಳು"
+-    ],
+-    "feature": [
+-      "ಹೆಚ್ಚಳ"
+-    ],
+-    "given": [
+-      "* ",
+-      "ನೀಡಿದ "
+-    ],
+-    "name": "Kannada",
+-    "native": "ಕನ್ನಡ",
+-    "scenario": [
+-      "ಕಥಾಸಾರಾಂಶ"
+-    ],
+-    "scenarioOutline": [
+-      "ವಿವರಣೆ"
+-    ],
+-    "then": [
+-      "* ",
+-      "ನಂತರ "
+-    ],
+-    "when": [
+-      "* ",
+-      "ಸ್ಥಿತಿಯನ್ನು "
+-    ]
+-  },
+-  "ko": {
+-    "and": [
+-      "* ",
+-      "그리고"
+-    ],
+-    "background": [
+-      "배경"
+-    ],
+-    "but": [
+-      "* ",
+-      "하지만",
+-      "단"
+-    ],
+-    "examples": [
+-      "예"
+-    ],
+-    "feature": [
+-      "기능"
+-    ],
+-    "given": [
+-      "* ",
+-      "조건",
+-      "먼저"
+-    ],
+-    "name": "Korean",
+-    "native": "한국어",
+-    "scenario": [
+-      "시나리오"
+-    ],
+-    "scenarioOutline": [
+-      "시나리오 개요"
+-    ],
+-    "then": [
+-      "* ",
+-      "그러면"
+-    ],
+-    "when": [
+-      "* ",
+-      "만일",
+-      "만약"
+-    ]
+-  },
+-  "lt": {
+-    "and": [
+-      "* ",
+-      "Ir "
+-    ],
+-    "background": [
+-      "Kontekstas"
+-    ],
+-    "but": [
+-      "* ",
+-      "Bet "
+-    ],
+-    "examples": [
+-      "Pavyzdžiai",
+-      "Scenarijai",
+-      "Variantai"
+-    ],
+-    "feature": [
+-      "Savybė"
+-    ],
+-    "given": [
+-      "* ",
+-      "Duota "
+-    ],
+-    "name": "Lithuanian",
+-    "native": "lietuvių kalba",
+-    "scenario": [
+-      "Scenarijus"
+-    ],
+-    "scenarioOutline": [
+-      "Scenarijaus šablonas"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tada "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kai "
+-    ]
+-  },
+-  "lu": {
+-    "and": [
+-      "* ",
+-      "an ",
+-      "a "
+-    ],
+-    "background": [
+-      "Hannergrond"
+-    ],
+-    "but": [
+-      "* ",
+-      "awer ",
+-      "mä "
+-    ],
+-    "examples": [
+-      "Beispiller"
+-    ],
+-    "feature": [
+-      "Funktionalitéit"
+-    ],
+-    "given": [
+-      "* ",
+-      "ugeholl "
+-    ],
+-    "name": "Luxemburgish",
+-    "native": "Lëtzebuergesch",
+-    "scenario": [
+-      "Szenario"
+-    ],
+-    "scenarioOutline": [
+-      "Plang vum Szenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "dann "
+-    ],
+-    "when": [
+-      "* ",
+-      "wann "
+-    ]
+-  },
+-  "lv": {
+-    "and": [
+-      "* ",
+-      "Un "
+-    ],
+-    "background": [
+-      "Konteksts",
+-      "Situācija"
+-    ],
+-    "but": [
+-      "* ",
+-      "Bet "
+-    ],
+-    "examples": [
+-      "Piemēri",
+-      "Paraugs"
+-    ],
+-    "feature": [
+-      "Funkcionalitāte",
+-      "Fīča"
+-    ],
+-    "given": [
+-      "* ",
+-      "Kad "
+-    ],
+-    "name": "Latvian",
+-    "native": "latviešu",
+-    "scenario": [
+-      "Scenārijs"
+-    ],
+-    "scenarioOutline": [
+-      "Scenārijs pēc parauga"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tad "
+-    ],
+-    "when": [
+-      "* ",
+-      "Ja "
+-    ]
+-  },
+-  "mk-Cyrl": {
+-    "and": [
+-      "* ",
+-      "И "
+-    ],
+-    "background": [
+-      "Контекст",
+-      "Содржина"
+-    ],
+-    "but": [
+-      "* ",
+-      "Но "
+-    ],
+-    "examples": [
+-      "Примери",
+-      "Сценарија"
+-    ],
+-    "feature": [
+-      "Функционалност",
+-      "Бизнис потреба",
+-      "Можност"
+-    ],
+-    "given": [
+-      "* ",
+-      "Дадено ",
+-      "Дадена "
+-    ],
+-    "name": "Macedonian",
+-    "native": "Македонски",
+-    "scenario": [
+-      "Сценарио",
+-      "На пример"
+-    ],
+-    "scenarioOutline": [
+-      "Преглед на сценарија",
+-      "Скица",
+-      "Концепт"
+-    ],
+-    "then": [
+-      "* ",
+-      "Тогаш "
+-    ],
+-    "when": [
+-      "* ",
+-      "Кога "
+-    ]
+-  },
+-  "mk-Latn": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Kontekst",
+-      "Sodrzhina"
+-    ],
+-    "but": [
+-      "* ",
+-      "No "
+-    ],
+-    "examples": [
+-      "Primeri",
+-      "Scenaria"
+-    ],
+-    "feature": [
+-      "Funkcionalnost",
+-      "Biznis potreba",
+-      "Mozhnost"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dadeno ",
+-      "Dadena "
+-    ],
+-    "name": "Macedonian (Latin)",
+-    "native": "Makedonski (Latinica)",
+-    "scenario": [
+-      "Scenario",
+-      "Na primer"
+-    ],
+-    "scenarioOutline": [
+-      "Pregled na scenarija",
+-      "Skica",
+-      "Koncept"
+-    ],
+-    "then": [
+-      "* ",
+-      "Togash "
+-    ],
+-    "when": [
+-      "* ",
+-      "Koga "
+-    ]
+-  },
+-  "mn": {
+-    "and": [
+-      "* ",
+-      "Мөн ",
+-      "Тэгээд "
+-    ],
+-    "background": [
+-      "Агуулга"
+-    ],
+-    "but": [
+-      "* ",
+-      "Гэхдээ ",
+-      "Харин "
+-    ],
+-    "examples": [
+-      "Тухайлбал"
+-    ],
+-    "feature": [
+-      "Функц",
+-      "Функционал"
+-    ],
+-    "given": [
+-      "* ",
+-      "Өгөгдсөн нь ",
+-      "Анх "
+-    ],
+-    "name": "Mongolian",
+-    "native": "монгол",
+-    "scenario": [
+-      "Сценар"
+-    ],
+-    "scenarioOutline": [
+-      "Сценарын төлөвлөгөө"
+-    ],
+-    "then": [
+-      "* ",
+-      "Тэгэхэд ",
+-      "Үүний дараа "
+-    ],
+-    "when": [
+-      "* ",
+-      "Хэрэв "
+-    ]
+-  },
+-  "nl": {
+-    "and": [
+-      "* ",
+-      "En "
+-    ],
+-    "background": [
+-      "Achtergrond"
+-    ],
+-    "but": [
+-      "* ",
+-      "Maar "
+-    ],
+-    "examples": [
+-      "Voorbeelden"
+-    ],
+-    "feature": [
+-      "Functionaliteit"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gegeven ",
+-      "Stel "
+-    ],
+-    "name": "Dutch",
+-    "native": "Nederlands",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Abstract Scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "when": [
+-      "* ",
+-      "Als ",
+-      "Wanneer "
+-    ]
+-  },
+-  "no": {
+-    "and": [
+-      "* ",
+-      "Og "
+-    ],
+-    "background": [
+-      "Bakgrunn"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Eksempler"
+-    ],
+-    "feature": [
+-      "Egenskap"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gitt "
+-    ],
+-    "name": "Norwegian",
+-    "native": "norsk",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenariomal",
+-      "Abstrakt Scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Så "
+-    ],
+-    "when": [
+-      "* ",
+-      "Når "
+-    ]
+-  },
+-  "pa": {
+-    "and": [
+-      "* ",
+-      "ਅਤੇ "
+-    ],
+-    "background": [
+-      "ਪਿਛੋਕੜ"
+-    ],
+-    "but": [
+-      "* ",
+-      "ਪਰ "
+-    ],
+-    "examples": [
+-      "ਉਦਾਹਰਨਾਂ"
+-    ],
+-    "feature": [
+-      "ਖਾਸੀਅਤ",
+-      "ਮੁਹਾਂਦਰਾ",
+-      "ਨਕਸ਼ ਨੁਹਾਰ"
+-    ],
+-    "given": [
+-      "* ",
+-      "ਜੇਕਰ ",
+-      "ਜਿਵੇਂ ਕਿ "
+-    ],
+-    "name": "Panjabi",
+-    "native": "ਪੰਜਾਬੀ",
+-    "scenario": [
+-      "ਪਟਕਥਾ"
+-    ],
+-    "scenarioOutline": [
+-      "ਪਟਕਥਾ ਢਾਂਚਾ",
+-      "ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ"
+-    ],
+-    "then": [
+-      "* ",
+-      "ਤਦ "
+-    ],
+-    "when": [
+-      "* ",
+-      "ਜਦੋਂ "
+-    ]
+-  },
+-  "pl": {
+-    "and": [
+-      "* ",
+-      "Oraz ",
+-      "I "
+-    ],
+-    "background": [
+-      "Założenia"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ale "
+-    ],
+-    "examples": [
+-      "Przykłady"
+-    ],
+-    "feature": [
+-      "Właściwość",
+-      "Funkcja",
+-      "Aspekt",
+-      "Potrzeba biznesowa"
+-    ],
+-    "given": [
+-      "* ",
+-      "Zakładając ",
+-      "Mając ",
+-      "Zakładając, że "
+-    ],
+-    "name": "Polish",
+-    "native": "polski",
+-    "scenario": [
+-      "Scenariusz"
+-    ],
+-    "scenarioOutline": [
+-      "Szablon scenariusza"
+-    ],
+-    "then": [
+-      "* ",
+-      "Wtedy "
+-    ],
+-    "when": [
+-      "* ",
+-      "Jeżeli ",
+-      "Jeśli ",
+-      "Gdy ",
+-      "Kiedy "
+-    ]
+-  },
+-  "pt": {
+-    "and": [
+-      "* ",
+-      "E "
+-    ],
+-    "background": [
+-      "Contexto",
+-      "Cenário de Fundo",
+-      "Cenario de Fundo",
+-      "Fundo"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mas "
+-    ],
+-    "examples": [
+-      "Exemplos",
+-      "Cenários",
+-      "Cenarios"
+-    ],
+-    "feature": [
+-      "Funcionalidade",
+-      "Característica",
+-      "Caracteristica"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dado ",
+-      "Dada ",
+-      "Dados ",
+-      "Dadas "
+-    ],
+-    "name": "Portuguese",
+-    "native": "português",
+-    "scenario": [
+-      "Cenário",
+-      "Cenario"
+-    ],
+-    "scenarioOutline": [
+-      "Esquema do Cenário",
+-      "Esquema do Cenario",
+-      "Delineação do Cenário",
+-      "Delineacao do Cenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Então ",
+-      "Entao "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quando "
+-    ]
+-  },
+-  "ro": {
+-    "and": [
+-      "* ",
+-      "Si ",
+-      "Și ",
+-      "Şi "
+-    ],
+-    "background": [
+-      "Context"
+-    ],
+-    "but": [
+-      "* ",
+-      "Dar "
+-    ],
+-    "examples": [
+-      "Exemple"
+-    ],
+-    "feature": [
+-      "Functionalitate",
+-      "Funcționalitate",
+-      "Funcţionalitate"
+-    ],
+-    "given": [
+-      "* ",
+-      "Date fiind ",
+-      "Dat fiind ",
+-      "Dată fiind",
+-      "Dati fiind ",
+-      "Dați fiind ",
+-      "Daţi fiind "
+-    ],
+-    "name": "Romanian",
+-    "native": "română",
+-    "scenario": [
+-      "Scenariu"
+-    ],
+-    "scenarioOutline": [
+-      "Structura scenariu",
+-      "Structură scenariu"
+-    ],
+-    "then": [
+-      "* ",
+-      "Atunci "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cand ",
+-      "Când "
+-    ]
+-  },
+-  "ru": {
+-    "and": [
+-      "* ",
+-      "И ",
+-      "К тому же ",
+-      "Также "
+-    ],
+-    "background": [
+-      "Предыстория",
+-      "Контекст"
+-    ],
+-    "but": [
+-      "* ",
+-      "Но ",
+-      "А "
+-    ],
+-    "examples": [
+-      "Примеры"
+-    ],
+-    "feature": [
+-      "Функция",
+-      "Функциональность",
+-      "Функционал",
+-      "Свойство"
+-    ],
+-    "given": [
+-      "* ",
+-      "Допустим ",
+-      "Дано ",
+-      "Пусть ",
+-      "Если "
+-    ],
+-    "name": "Russian",
+-    "native": "русский",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Структура сценария"
+-    ],
+-    "then": [
+-      "* ",
+-      "То ",
+-      "Затем ",
+-      "Тогда "
+-    ],
+-    "when": [
+-      "* ",
+-      "Когда "
+-    ]
+-  },
+-  "sk": {
+-    "and": [
+-      "* ",
+-      "A ",
+-      "A tiež ",
+-      "A taktiež ",
+-      "A zároveň "
+-    ],
+-    "background": [
+-      "Pozadie"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ale "
+-    ],
+-    "examples": [
+-      "Príklady"
+-    ],
+-    "feature": [
+-      "Požiadavka",
+-      "Funkcia",
+-      "Vlastnosť"
+-    ],
+-    "given": [
+-      "* ",
+-      "Pokiaľ ",
+-      "Za predpokladu "
+-    ],
+-    "name": "Slovak",
+-    "native": "Slovensky",
+-    "scenario": [
+-      "Scenár"
+-    ],
+-    "scenarioOutline": [
+-      "Náčrt Scenáru",
+-      "Náčrt Scenára",
+-      "Osnova Scenára"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tak ",
+-      "Potom "
+-    ],
+-    "when": [
+-      "* ",
+-      "Keď ",
+-      "Ak "
+-    ]
+-  },
+-  "sl": {
+-    "and": [
+-      "In ",
+-      "Ter "
+-    ],
+-    "background": [
+-      "Kontekst",
+-      "Osnova",
+-      "Ozadje"
+-    ],
+-    "but": [
+-      "Toda ",
+-      "Ampak ",
+-      "Vendar "
+-    ],
+-    "examples": [
+-      "Primeri",
+-      "Scenariji"
+-    ],
+-    "feature": [
+-      "Funkcionalnost",
+-      "Funkcija",
+-      "Možnosti",
+-      "Moznosti",
+-      "Lastnost",
+-      "Značilnost"
+-    ],
+-    "given": [
+-      "Dano ",
+-      "Podano ",
+-      "Zaradi ",
+-      "Privzeto "
+-    ],
+-    "name": "Slovenian",
+-    "native": "Slovenski",
+-    "scenario": [
+-      "Scenarij",
+-      "Primer"
+-    ],
+-    "scenarioOutline": [
+-      "Struktura scenarija",
+-      "Skica",
+-      "Koncept",
+-      "Oris scenarija",
+-      "Osnutek"
+-    ],
+-    "then": [
+-      "Nato ",
+-      "Potem ",
+-      "Takrat "
+-    ],
+-    "when": [
+-      "Ko ",
+-      "Ce ",
+-      "Če ",
+-      "Kadar "
+-    ]
+-  },
+-  "sr-Cyrl": {
+-    "and": [
+-      "* ",
+-      "И "
+-    ],
+-    "background": [
+-      "Контекст",
+-      "Основа",
+-      "Позадина"
+-    ],
+-    "but": [
+-      "* ",
+-      "Али "
+-    ],
+-    "examples": [
+-      "Примери",
+-      "Сценарији"
+-    ],
+-    "feature": [
+-      "Функционалност",
+-      "Могућност",
+-      "Особина"
+-    ],
+-    "given": [
+-      "* ",
+-      "За дато ",
+-      "За дате ",
+-      "За дати "
+-    ],
+-    "name": "Serbian",
+-    "native": "Српски",
+-    "scenario": [
+-      "Сценарио",
+-      "Пример"
+-    ],
+-    "scenarioOutline": [
+-      "Структура сценарија",
+-      "Скица",
+-      "Концепт"
+-    ],
+-    "then": [
+-      "* ",
+-      "Онда "
+-    ],
+-    "when": [
+-      "* ",
+-      "Када ",
+-      "Кад "
+-    ]
+-  },
+-  "sr-Latn": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Kontekst",
+-      "Osnova",
+-      "Pozadina"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ali "
+-    ],
+-    "examples": [
+-      "Primeri",
+-      "Scenariji"
+-    ],
+-    "feature": [
+-      "Funkcionalnost",
+-      "Mogućnost",
+-      "Mogucnost",
+-      "Osobina"
+-    ],
+-    "given": [
+-      "* ",
+-      "Za dato ",
+-      "Za date ",
+-      "Za dati "
+-    ],
+-    "name": "Serbian (Latin)",
+-    "native": "Srpski (Latinica)",
+-    "scenario": [
+-      "Scenario",
+-      "Primer"
+-    ],
+-    "scenarioOutline": [
+-      "Struktura scenarija",
+-      "Skica",
+-      "Koncept"
+-    ],
+-    "then": [
+-      "* ",
+-      "Onda "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kada ",
+-      "Kad "
+-    ]
+-  },
+-  "sv": {
+-    "and": [
+-      "* ",
+-      "Och "
+-    ],
+-    "background": [
+-      "Bakgrund"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Exempel"
+-    ],
+-    "feature": [
+-      "Egenskap"
+-    ],
+-    "given": [
+-      "* ",
+-      "Givet "
+-    ],
+-    "name": "Swedish",
+-    "native": "Svenska",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Abstrakt Scenario",
+-      "Scenariomall"
+-    ],
+-    "then": [
+-      "* ",
+-      "Så "
+-    ],
+-    "when": [
+-      "* ",
+-      "När "
+-    ]
+-  },
+-  "ta": {
+-    "and": [
+-      "* ",
+-      "மேலும்  ",
+-      "மற்றும் "
+-    ],
+-    "background": [
+-      "பின்னணி"
+-    ],
+-    "but": [
+-      "* ",
+-      "ஆனால்  "
+-    ],
+-    "examples": [
+-      "எடுத்துக்காட்டுகள்",
+-      "காட்சிகள்",
+-      " நிலைமைகளில்"
+-    ],
+-    "feature": [
+-      "அம்சம்",
+-      "வணிக தேவை",
+-      "திறன்"
+-    ],
+-    "given": [
+-      "* ",
+-      "கொடுக்கப்பட்ட "
+-    ],
+-    "name": "Tamil",
+-    "native": "தமிழ்",
+-    "scenario": [
+-      "காட்சி"
+-    ],
+-    "scenarioOutline": [
+-      "காட்சி சுருக்கம்",
+-      "காட்சி வார்ப்புரு"
+-    ],
+-    "then": [
+-      "* ",
+-      "அப்பொழுது "
+-    ],
+-    "when": [
+-      "* ",
+-      "எப்போது "
+-    ]
+-  },
+-  "th": {
+-    "and": [
+-      "* ",
+-      "และ "
+-    ],
+-    "background": [
+-      "แนวคิด"
+-    ],
+-    "but": [
+-      "* ",
+-      "แต่ "
+-    ],
+-    "examples": [
+-      "ชุดของตัวอย่าง",
+-      "ชุดของเหตุการณ์"
+-    ],
+-    "feature": [
+-      "โครงหลัก",
+-      "ความต้องการทางธุรกิจ",
+-      "ความสามารถ"
+-    ],
+-    "given": [
+-      "* ",
+-      "กำหนดให้ "
+-    ],
+-    "name": "Thai",
+-    "native": "ไทย",
+-    "scenario": [
+-      "เหตุการณ์"
+-    ],
+-    "scenarioOutline": [
+-      "สรุปเหตุการณ์",
+-      "โครงสร้างของเหตุการณ์"
+-    ],
+-    "then": [
+-      "* ",
+-      "ดังนั้น "
+-    ],
+-    "when": [
+-      "* ",
+-      "เมื่อ "
+-    ]
+-  },
+-  "tl": {
+-    "and": [
+-      "* ",
+-      "మరియు "
+-    ],
+-    "background": [
+-      "నేపథ్యం"
+-    ],
+-    "but": [
+-      "* ",
+-      "కాని "
+-    ],
+-    "examples": [
+-      "ఉదాహరణలు"
+-    ],
+-    "feature": [
+-      "గుణము"
+-    ],
+-    "given": [
+-      "* ",
+-      "చెప్పబడినది "
+-    ],
+-    "name": "Telugu",
+-    "native": "తెలుగు",
+-    "scenario": [
+-      "సన్నివేశం"
+-    ],
+-    "scenarioOutline": [
+-      "కథనం"
+-    ],
+-    "then": [
+-      "* ",
+-      "అప్పుడు "
+-    ],
+-    "when": [
+-      "* ",
+-      "ఈ పరిస్థితిలో "
+-    ]
+-  },
+-  "tlh": {
+-    "and": [
+-      "* ",
+-      "'ej ",
+-      "latlh "
+-    ],
+-    "background": [
+-      "mo'"
+-    ],
+-    "but": [
+-      "* ",
+-      "'ach ",
+-      "'a "
+-    ],
+-    "examples": [
+-      "ghantoH",
+-      "lutmey"
+-    ],
+-    "feature": [
+-      "Qap",
+-      "Qu'meH 'ut",
+-      "perbogh",
+-      "poQbogh malja'",
+-      "laH"
+-    ],
+-    "given": [
+-      "* ",
+-      "ghu' noblu' ",
+-      "DaH ghu' bejlu' "
+-    ],
+-    "name": "Klingon",
+-    "native": "tlhIngan",
+-    "scenario": [
+-      "lut"
+-    ],
+-    "scenarioOutline": [
+-      "lut chovnatlh"
+-    ],
+-    "then": [
+-      "* ",
+-      "vaj "
+-    ],
+-    "when": [
+-      "* ",
+-      "qaSDI' "
+-    ]
+-  },
+-  "tr": {
+-    "and": [
+-      "* ",
+-      "Ve "
+-    ],
+-    "background": [
+-      "Geçmiş"
+-    ],
+-    "but": [
+-      "* ",
+-      "Fakat ",
+-      "Ama "
+-    ],
+-    "examples": [
+-      "Örnekler"
+-    ],
+-    "feature": [
+-      "Özellik"
+-    ],
+-    "given": [
+-      "* ",
+-      "Diyelim ki "
+-    ],
+-    "name": "Turkish",
+-    "native": "Türkçe",
+-    "scenario": [
+-      "Senaryo"
+-    ],
+-    "scenarioOutline": [
+-      "Senaryo taslağı"
+-    ],
+-    "then": [
+-      "* ",
+-      "O zaman "
+-    ],
+-    "when": [
+-      "* ",
+-      "Eğer ki "
+-    ]
+-  },
+-  "tt": {
+-    "and": [
+-      "* ",
+-      "Һәм ",
+-      "Вә "
+-    ],
+-    "background": [
+-      "Кереш"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ләкин ",
+-      "Әмма "
+-    ],
+-    "examples": [
+-      "Үрнәкләр",
+-      "Мисаллар"
+-    ],
+-    "feature": [
+-      "Мөмкинлек",
+-      "Үзенчәлеклелек"
+-    ],
+-    "given": [
+-      "* ",
+-      "Әйтик "
+-    ],
+-    "name": "Tatar",
+-    "native": "Татарча",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Сценарийның төзелеше"
+-    ],
+-    "then": [
+-      "* ",
+-      "Нәтиҗәдә "
+-    ],
+-    "when": [
+-      "* ",
+-      "Әгәр "
+-    ]
+-  },
+-  "uk": {
+-    "and": [
+-      "* ",
+-      "І ",
+-      "А також ",
+-      "Та "
+-    ],
+-    "background": [
+-      "Передумова"
+-    ],
+-    "but": [
+-      "* ",
+-      "Але "
+-    ],
+-    "examples": [
+-      "Приклади"
+-    ],
+-    "feature": [
+-      "Функціонал"
+-    ],
+-    "given": [
+-      "* ",
+-      "Припустимо ",
+-      "Припустимо, що ",
+-      "Нехай ",
+-      "Дано "
+-    ],
+-    "name": "Ukrainian",
+-    "native": "Українська",
+-    "scenario": [
+-      "Сценарій"
+-    ],
+-    "scenarioOutline": [
+-      "Структура сценарію"
+-    ],
+-    "then": [
+-      "* ",
+-      "То ",
+-      "Тоді "
+-    ],
+-    "when": [
+-      "* ",
+-      "Якщо ",
+-      "Коли "
+-    ]
+-  },
+-  "ur": {
+-    "and": [
+-      "* ",
+-      "اور "
+-    ],
+-    "background": [
+-      "پس منظر"
+-    ],
+-    "but": [
+-      "* ",
+-      "لیکن "
+-    ],
+-    "examples": [
+-      "مثالیں"
+-    ],
+-    "feature": [
+-      "صلاحیت",
+-      "کاروبار کی ضرورت",
+-      "خصوصیت"
+-    ],
+-    "given": [
+-      "* ",
+-      "اگر ",
+-      "بالفرض ",
+-      "فرض کیا "
+-    ],
+-    "name": "Urdu",
+-    "native": "اردو",
+-    "scenario": [
+-      "منظرنامہ"
+-    ],
+-    "scenarioOutline": [
+-      "منظر نامے کا خاکہ"
+-    ],
+-    "then": [
+-      "* ",
+-      "پھر ",
+-      "تب "
+-    ],
+-    "when": [
+-      "* ",
+-      "جب "
+-    ]
+-  },
+-  "uz": {
+-    "and": [
+-      "* ",
+-      "Ва "
+-    ],
+-    "background": [
+-      "Тарих"
+-    ],
+-    "but": [
+-      "* ",
+-      "Лекин ",
+-      "Бирок ",
+-      "Аммо "
+-    ],
+-    "examples": [
+-      "Мисоллар"
+-    ],
+-    "feature": [
+-      "Функционал"
+-    ],
+-    "given": [
+-      "* ",
+-      "Агар "
+-    ],
+-    "name": "Uzbek",
+-    "native": "Узбекча",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Сценарий структураси"
+-    ],
+-    "then": [
+-      "* ",
+-      "Унда "
+-    ],
+-    "when": [
+-      "* ",
+-      "Агар "
+-    ]
+-  },
+-  "vi": {
+-    "and": [
+-      "* ",
+-      "Và "
+-    ],
+-    "background": [
+-      "Bối cảnh"
+-    ],
+-    "but": [
+-      "* ",
+-      "Nhưng "
+-    ],
+-    "examples": [
+-      "Dữ liệu"
+-    ],
+-    "feature": [
+-      "Tính năng"
+-    ],
+-    "given": [
+-      "* ",
+-      "Biết ",
+-      "Cho "
+-    ],
+-    "name": "Vietnamese",
+-    "native": "Tiếng Việt",
+-    "scenario": [
+-      "Tình huống",
+-      "Kịch bản"
+-    ],
+-    "scenarioOutline": [
+-      "Khung tình huống",
+-      "Khung kịch bản"
+-    ],
+-    "then": [
+-      "* ",
+-      "Thì "
+-    ],
+-    "when": [
+-      "* ",
+-      "Khi "
+-    ]
+-  },
+-  "zh-CN": {
+-    "and": [
+-      "* ",
+-      "而且",
+-      "并且",
+-      "同时"
+-    ],
+-    "background": [
+-      "背景"
+-    ],
+-    "but": [
+-      "* ",
+-      "但是"
+-    ],
+-    "examples": [
+-      "例子"
+-    ],
+-    "feature": [
+-      "功能"
+-    ],
+-    "given": [
+-      "* ",
+-      "假如",
+-      "假设",
+-      "假定"
+-    ],
+-    "name": "Chinese simplified",
+-    "native": "简体中文",
+-    "scenario": [
+-      "场景",
+-      "剧本"
+-    ],
+-    "scenarioOutline": [
+-      "场景大纲",
+-      "剧本大纲"
+-    ],
+-    "then": [
+-      "* ",
+-      "那么"
+-    ],
+-    "when": [
+-      "* ",
+-      "当"
+-    ]
+-  },
+-  "zh-TW": {
+-    "and": [
+-      "* ",
+-      "而且",
+-      "並且",
+-      "同時"
+-    ],
+-    "background": [
+-      "背景"
+-    ],
+-    "but": [
+-      "* ",
+-      "但是"
+-    ],
+-    "examples": [
+-      "例子"
+-    ],
+-    "feature": [
+-      "功能"
+-    ],
+-    "given": [
+-      "* ",
+-      "假如",
+-      "假設",
+-      "假定"
+-    ],
+-    "name": "Chinese traditional",
+-    "native": "繁體中文",
+-    "scenario": [
+-      "場景",
+-      "劇本"
+-    ],
+-    "scenarioOutline": [
+-      "場景大綱",
+-      "劇本大綱"
+-    ],
+-    "then": [
+-      "* ",
+-      "那麼"
+-    ],
+-    "when": [
+-      "* ",
+-      "當"
+-    ]
+-  }
+-}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch b/meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch
new file mode 100644
index 000000000..101a887e5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch
@@ -0,0 +1,736 @@
+From f66a9fd1bf7c2ed117fe697b80a0ea4b071773f3 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:21:27 +0200
+Subject: [PATCH] CLEANUP: Remove deprecated parts.
+
+---
+ bin/convert_i18n_yaml.py |  77 -----
+ bin/i18n.yml             | 635 ---------------------------------------
+ 2 files changed, 712 deletions(-)
+ delete mode 100755 bin/convert_i18n_yaml.py
+ delete mode 100644 bin/i18n.yml
+
+diff --git a/bin/convert_i18n_yaml.py b/bin/convert_i18n_yaml.py
+deleted file mode 100755
+index d6a6713..0000000
+--- a/bin/convert_i18n_yaml.py
++++ /dev/null
+@@ -1,77 +0,0 @@
+-#!/usr/bin/env python
+-# -*- coding: UTF-8 -*-
+-# USAGE: convert_i18n_yaml.py [--data=i18n.yml] behave/i18n.py
+-"""
+-Generates I18N python module based on YAML description (i18n.yml).
+-
+-REQUIRES:
+-  * argparse
+-  * six
+-  * PyYAML
+-"""
+-
+-from __future__ import absolute_import, print_function
+-import argparse
+-import os.path
+-import six
+-import sys
+-import pprint
+-import yaml
+-
+-HERE = os.path.dirname(__file__)
+-NAME = os.path.basename(__file__)
+-__version__ = "1.0"
+-
+-def yaml_normalize(data):
+-    for part in data:
+-        keywords = data[part]
+-        for k in keywords:
+-            v = keywords[k]
+-            # bloody YAML parser returns a mixture of unicode and str
+-            if not isinstance(v, six.text_type):
+-                v = v.decode("UTF-8")
+-            keywords[k] = v.split("|")
+-    return data
+-
+-def main(args=None):
+-    if args is None:
+-        args = sys.argv[1:]
+-    parser = argparse.ArgumentParser(prog=NAME,
+-                description="Generate python module i18n from YAML based data")
+-    parser.add_argument("-d", "--data", dest="yaml_file",
+-                default=os.path.join(HERE, "i18n.yml"),
+-                help="Path to i18n.yml file (YAML file).")
+-    parser.add_argument("output_file", default="stdout",
+-                help="Filename of Python I18N module (as output).")
+-    parser.add_argument("--version", action="version", version=__version__)
+-
+-    options = parser.parse_args(args)
+-    if not os.path.isfile(options.yaml_file):
+-        parser.error("YAML file not found: %s" % options.yaml_file)
+-
+-    # -- STEP 1: Load YAML data.
+-    languages = yaml.load(open(options.yaml_file))
+-    languages = yaml_normalize(languages)
+-
+-    # -- STEP 2: Generate python module with i18n data.
+-    contents = u"""# -*- coding: UTF-8 -*-
+-# -- FILE GENERATED BY: convert_i18n_yaml.py with i18n.yml
+-# pylint: disable=line-too-long
+-
+-languages = \\
+-"""
+-    if options.output_file in ("-", "stdout"):
+-        i18n_py = sys.stdout
+-        should_close = False
+-    else:
+-        i18n_py = open(options.output_file, "w")
+-        should_close = True
+-    i18n_py.write(contents.encode("UTF-8"))
+-    i18n_py.write(pprint.pformat(languages).encode("UTF-8"))
+-    i18n_py.write(u"\n")
+-    if should_close:
+-        i18n_py.close()
+-    return 0
+-
+-if __name__ == "__main__":
+-    sys.exit(main())
+diff --git a/bin/i18n.yml b/bin/i18n.yml
+deleted file mode 100644
+index 82345a4..0000000
+--- a/bin/i18n.yml
++++ /dev/null
+@@ -1,635 +0,0 @@
+-# encoding: UTF-8
+-#
+-# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if applicable):
+-# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+-# http://en.wikipedia.org/wiki/ISO_3166-1
+-#
+-# If you want several aliases for a keyword, just separate them
+-# with a | character. The * is a step keyword alias for all translations.
+-#
+-# If you do *not* want a trailing space after a keyword, end it with a < character.
+-# (See Chinese for examples).
+-#
+-# This file copyright (c) 2009-2011 Mike Sassak, Gregory Hnatiuk, Aslak Hellesøy
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining
+-# a copy of this software and associated documentation files (the
+-# "Software"), to deal in the Software without restriction, including
+-# without limitation the rights to use, copy, modify, merge, publish,
+-# distribute, sublicense, and/or sell copies of the Software, and to
+-# permit persons to whom the Software is furnished to do so, subject to
+-# the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be
+-# included in all copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+-
+-"en":
+-  name: English
+-  native: English
+-  feature: Feature
+-  background: Background
+-  scenario: Scenario
+-  scenario_outline: Scenario Outline|Scenario Template
+-  examples: Examples|Scenarios
+-  given: "*|Given"
+-  when: "*|When"
+-  then: "*|Then"
+-  and: "*|And"
+-  but: "*|But"
+-
+-# Please keep the grammars in alphabetical order by name from here and down.
+-
+-"ar":
+-  name: Arabic
+-  native: العربية
+-  feature: خاصية
+-  background: الخلفية
+-  scenario: سيناريو
+-  scenario_outline: سيناريو مخطط
+-  examples: امثلة
+-  given: "*|بفرض"
+-  when: "*|متى|عندما"
+-  then: "*|اذاً|ثم"
+-  and: "*|و"
+-  but: "*|لكن"
+-"bg":
+-  name: Bulgarian
+-  native: български
+-  feature: Функционалност
+-  background: Предистория
+-  scenario: Сценарий
+-  scenario_outline: Рамка на сценарий
+-  examples: Примери
+-  given: "*|Дадено"
+-  when: "*|Когато"
+-  then: "*|То"
+-  and: "*|И"
+-  but: "*|Но"
+-"ca":
+-  name: Catalan
+-  native: català
+-  background: Rerefons|Antecedents
+-  feature: Característica|Funcionalitat
+-  scenario: Escenari
+-  scenario_outline: Esquema de l'escenari
+-  examples: Exemples
+-  given: "*|Donat|Donada|Atès|Atesa"
+-  when: "*|Quan"
+-  then: "*|Aleshores|Cal"
+-  and: "*|I"
+-  but: "*|Però"
+-"cy-GB":
+-  name: Welsh
+-  native: Cymraeg
+-  background: Cefndir
+-  feature: Arwedd
+-  scenario: Scenario
+-  scenario_outline: Scenario Amlinellol
+-  examples: Enghreifftiau
+-  given: "*|Anrhegedig a"
+-  when: "*|Pryd"
+-  then: "*|Yna"
+-  and: "*|A"
+-  but: "*|Ond"
+-"cs":
+-  name: Czech
+-  native: Česky
+-  feature: Požadavek
+-  background: Pozadí|Kontext
+-  scenario: Scénář
+-  scenario_outline: Náčrt Scénáře|Osnova scénáře
+-  examples: Příklady
+-  given: "*|Pokud|Za předpokladu"
+-  when: "*|Když"
+-  then: "*|Pak"
+-  and: "*|A|A také"
+-  but: "*|Ale"
+-"da":
+-  name: Danish
+-  native: dansk
+-  feature: Egenskab
+-  background: Baggrund
+-  scenario: Scenarie
+-  scenario_outline: Abstrakt Scenario
+-  examples: Eksempler
+-  given: "*|Givet"
+-  when: "*|Når"
+-  then: "*|Så"
+-  and: "*|Og"
+-  but: "*|Men"
+-"de":
+-  name: German
+-  native: Deutsch
+-  feature: Funktionalität
+-  background: Grundlage
+-  scenario: Szenario
+-  scenario_outline: Szenariogrundriss
+-  examples: Beispiele
+-  given: "*|Angenommen|Gegeben sei"
+-  when: "*|Wenn"
+-  then: "*|Dann"
+-  and: "*|Und"
+-  but: "*|Aber"
+-"en-au":
+-  name: Australian
+-  native: Australian
+-  feature: Crikey
+-  background: Background
+-  scenario: Mate
+-  scenario_outline: Blokes
+-  examples: Cobber
+-  given: "*|Ya know how"
+-  when: "*|When"
+-  then: "*|Ya gotta"
+-  and: "*|N"
+-  but: "*|Cept"
+-"en-lol":
+-  name: LOLCAT
+-  native: LOLCAT
+-  feature: OH HAI
+-  background: B4
+-  scenario: MISHUN
+-  scenario_outline: MISHUN SRSLY
+-  examples: EXAMPLZ
+-  given: "*|I CAN HAZ"
+-  when: "*|WEN"
+-  then: "*|DEN"
+-  and: "*|AN"
+-  but: "*|BUT"
+-"en-pirate":
+-  name: Pirate
+-  native: Pirate
+-  feature: Ahoy matey!
+-  background: Yo-ho-ho
+-  scenario: Heave to
+-  scenario_outline: Shiver me timbers
+-  examples: Dead men tell no tales
+-  given: "*|Gangway!"
+-  when: "*|Blimey!"
+-  then: "*|Let go and haul"
+-  and: "*|Aye"
+-  but: "*|Avast!"
+-"en-Scouse":
+-  name: Scouse
+-  native: Scouse
+-  feature: Feature
+-  background: "Dis is what went down"
+-  scenario: "The thing of it is"
+-  scenario_outline: "Wharrimean is"
+-  examples: Examples
+-  given: "*|Givun|Youse know when youse got"
+-  when: "*|Wun|Youse know like when"
+-  then: "*|Dun|Den youse gotta"
+-  and: "*|An"
+-  but: "*|Buh"
+-"en-tx":
+-  name: Texan
+-  native: Texan
+-  feature: Feature
+-  background: Background
+-  scenario: Scenario
+-  scenario_outline: All y'all
+-  examples: Examples
+-  given: "*|Given y'all"
+-  when: "*|When y'all"
+-  then: "*|Then y'all"
+-  and: "*|And y'all"
+-  but: "*|But y'all"
+-"eo":
+-  name: Esperanto
+-  native: Esperanto
+-  feature: Trajto
+-  background: Fono
+-  scenario: Scenaro
+-  scenario_outline: Konturo de la scenaro
+-  examples: Ekzemploj
+-  given: "*|Donitaĵo"
+-  when: "*|Se"
+-  then: "*|Do"
+-  and: "*|Kaj"
+-  but: "*|Sed"
+-"es":
+-  name: Spanish
+-  native: español
+-  background: Antecedentes
+-  feature: Característica
+-  scenario: Escenario
+-  scenario_outline: Esquema del escenario
+-  examples: Ejemplos
+-  given: "*|Dado|Dada|Dados|Dadas"
+-  when: "*|Cuando"
+-  then: "*|Entonces"
+-  and: "*|Y"
+-  but: "*|Pero"
+-"et":
+-  name: Estonian
+-  native: eesti keel
+-  feature: Omadus
+-  background: Taust
+-  scenario: Stsenaarium
+-  scenario_outline: Raamstsenaarium
+-  examples: Juhtumid
+-  given: "*|Eeldades"
+-  when: "*|Kui"
+-  then: "*|Siis"
+-  and: "*|Ja"
+-  but: "*|Kuid"
+-"fi":
+-  name: Finnish
+-  native: suomi
+-  feature: Ominaisuus
+-  background: Tausta
+-  scenario: Tapaus
+-  scenario_outline: Tapausaihio
+-  examples: Tapaukset
+-  given: "*|Oletetaan"
+-  when: "*|Kun"
+-  then: "*|Niin"
+-  and: "*|Ja"
+-  but: "*|Mutta"
+-"fr":
+-  name: French
+-  native: français
+-  feature: Fonctionnalité
+-  background: Contexte
+-  scenario: Scénario
+-  scenario_outline: Plan du scénario|Plan du Scénario
+-  examples: Exemples
+-  given: "*|Soit|Etant donné|Etant donnée|Etant donnés|Etant données|Étant donné|Étant donnée|Étant donnés|Étant données"
+-  when: "*|Quand|Lorsque|Lorsqu'<"
+-  then: "*|Alors"
+-  and: "*|Et"
+-  but: "*|Mais"
+-"gl":
+-  name: Galician
+-  native: galego
+-  feature: Característica
+-  background: Contexto
+-  scenario: Escenario
+-  scenario_outline: "Esbozo do escenario"
+-  examples: Exemplos
+-  given: "*|Dado|Dada|Dados|Dadas"
+-  when: "*|Cando"
+-  then: "*|Entón|Logo"
+-  and: "*|E"
+-  but: "*|Mais|Pero"
+-
+-"he":
+-  name: Hebrew
+-  native: עברית
+-  feature: תכונה
+-  background: רקע
+-  scenario: תרחיש
+-  scenario_outline: תבנית תרחיש
+-  examples: דוגמאות
+-  given: "*|בהינתן"
+-  when: "*|כאשר"
+-  then: "*|אז|אזי"
+-  and: "*|וגם"
+-  but: "*|אבל"
+-"hr":
+-  name: Croatian
+-  native: hrvatski
+-  feature: Osobina|Mogućnost|Mogucnost
+-  background: Pozadina
+-  scenario: Scenarij
+-  scenario_outline: Skica|Koncept
+-  examples: Primjeri|Scenariji
+-  given: "*|Zadan|Zadani|Zadano"
+-  when: "*|Kada|Kad"
+-  then: "*|Onda"
+-  and: "*|I"
+-  but: "*|Ali"
+-"hu":
+-  name: Hungarian
+-  native: magyar
+-  feature: Jellemző
+-  background: Háttér
+-  scenario: Forgatókönyv
+-  scenario_outline: Forgatókönyv vázlat
+-  examples: Példák
+-  given: "*|Amennyiben|Adott"
+-  when: "*|Majd|Ha|Amikor"
+-  then: "*|Akkor"
+-  and: "*|És"
+-  but: "*|De"
+-"id":
+-  name: Indonesian
+-  native: Bahasa Indonesia
+-  feature: Fitur
+-  background: Dasar
+-  scenario: Skenario
+-  scenario_outline: Skenario konsep
+-  examples: Contoh
+-  given: "*|Dengan"
+-  when: "*|Ketika"
+-  then: "*|Maka"
+-  and: "*|Dan"
+-  but: "*|Tapi"
+-"is":
+-  name: Icelandic
+-  native: Íslenska
+-  feature: Eiginleiki
+-  background: Bakgrunnur
+-  scenario: Atburðarás
+-  scenario_outline: Lýsing Atburðarásar|Lýsing Dæma
+-  examples: Dæmi|Atburðarásir
+-  given: "*|Ef"
+-  when: "*|Þegar"
+-  then: "*|Þá"
+-  and: "*|Og"
+-  but: "*|En"
+-"it":
+-  name: Italian
+-  native: italiano
+-  feature: Funzionalità
+-  background: Contesto
+-  scenario: Scenario
+-  scenario_outline: Schema dello scenario
+-  examples: Esempi
+-  given: "*|Dato|Data|Dati|Date"
+-  when: "*|Quando"
+-  then: "*|Allora"
+-  and: "*|E"
+-  but: "*|Ma"
+-"ja":
+-  name: Japanese
+-  native: 日本語
+-  feature: フィーチャ|機能
+-  background: 背景
+-  scenario: シナリオ
+-  scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
+-  examples: 例|サンプル
+-  given: "*|前提<"
+-  when: "*|もし<"
+-  then: "*|ならば<"
+-  and: "*|かつ<"
+-  but: "*|しかし<|但し<|ただし<"
+-"ko":
+-  name: Korean
+-  native: 한국어
+-  background: 배경
+-  feature: 기능
+-  scenario: 시나리오
+-  scenario_outline: 시나리오 개요
+-  examples: 예
+-  given: "*|조건<|먼저<"
+-  when: "*|만일<|만약<"
+-  then: "*|그러면<"
+-  and: "*|그리고<"
+-  but: "*|하지만<|단<"
+-"lt":
+-  name: Lithuanian
+-  native: lietuvių kalba
+-  feature: Savybė
+-  background: Kontekstas
+-  scenario: Scenarijus
+-  scenario_outline: Scenarijaus šablonas
+-  examples: Pavyzdžiai|Scenarijai|Variantai
+-  given: "*|Duota"
+-  when: "*|Kai"
+-  then: "*|Tada"
+-  and: "*|Ir"
+-  but: "*|Bet"
+-"lu":
+-  name: Luxemburgish
+-  native: Lëtzebuergesch
+-  feature: Funktionalitéit
+-  background: Hannergrond
+-  scenario: Szenario
+-  scenario_outline: Plang vum Szenario
+-  examples: Beispiller
+-  given: "*|ugeholl"
+-  when: "*|wann"
+-  then: "*|dann"
+-  and: "*|an|a"
+-  but: "*|awer|mä"
+-"lv":
+-  name: Latvian
+-  native: latviešu
+-  feature: Funkcionalitāte|Fīča
+-  background: Konteksts|Situācija
+-  scenario: Scenārijs
+-  scenario_outline: Scenārijs pēc parauga
+-  examples: Piemēri|Paraugs
+-  given: "*|Kad"
+-  when: "*|Ja"
+-  then: "*|Tad"
+-  and: "*|Un"
+-  but: "*|Bet"
+-"nl":
+-  name: Dutch
+-  native: Nederlands
+-  feature: Functionaliteit
+-  background: Achtergrond
+-  scenario: Scenario
+-  scenario_outline: Abstract Scenario
+-  examples: Voorbeelden
+-  given: "*|Gegeven|Stel"
+-  when: "*|Als"
+-  then: "*|Dan"
+-  and: "*|En"
+-  but: "*|Maar"
+-"no":
+-  name: Norwegian
+-  native: norsk
+-  feature: Egenskap
+-  background: Bakgrunn
+-  scenario: Scenario
+-  scenario_outline: Scenariomal|Abstrakt Scenario
+-  examples: Eksempler
+-  given: "*|Gitt"
+-  when: "*|Når"
+-  then: "*|Så"
+-  and: "*|Og"
+-  but: "*|Men"
+-"pl":
+-  name: Polish
+-  native: polski
+-  feature: Właściwość
+-  background: Założenia
+-  scenario: Scenariusz
+-  scenario_outline: Szablon scenariusza
+-  examples: Przykłady
+-  given: "*|Zakładając|Mając"
+-  when: "*|Jeżeli|Jeśli"
+-  then: "*|Wtedy"
+-  and: "*|Oraz|I"
+-  but: "*|Ale"
+-"pt":
+-  name: Portuguese
+-  native: português
+-  background: Contexto
+-  feature: Funcionalidade
+-  scenario: Cenário|Cenario
+-  scenario_outline: Esquema do Cenário|Esquema do Cenario
+-  examples: Exemplos
+-  given: "*|Dado|Dada|Dados|Dadas"
+-  when: "*|Quando"
+-  then: "*|Então|Entao"
+-  and: "*|E"
+-  but: "*|Mas"
+-"ro":
+-  name: Romanian
+-  native: română
+-  background: Context
+-  feature: Functionalitate|Funcționalitate|Funcţionalitate
+-  scenario: Scenariu
+-  scenario_outline: Structura scenariu|Structură scenariu
+-  examples: Exemple
+-  given: "*|Date fiind|Dat fiind|Dati fiind|Dați fiind|Daţi fiind"
+-  when: "*|Cand|Când"
+-  then: "*|Atunci"
+-  and: "*|Si|Și|Şi"
+-  but: "*|Dar"
+-"ru":
+-  name: Russian
+-  native: русский
+-  feature: Функция|Функционал|Свойство
+-  background: Предыстория|Контекст
+-  scenario: Сценарий
+-  scenario_outline: Структура сценария
+-  examples: Примеры
+-  given: "*|Допустим|Дано|Пусть"
+-  when: "*|Если|Когда"
+-  then: "*|То|Тогда"
+-  and: "*|И|К тому же"
+-  but: "*|Но|А"
+-"sv":
+-  name: Swedish
+-  native: Svenska
+-  feature: Egenskap
+-  background: Bakgrund
+-  scenario: Scenario
+-  scenario_outline: Abstrakt Scenario|Scenariomall
+-  examples: Exempel
+-  given: "*|Givet"
+-  when: "*|När"
+-  then: "*|Så"
+-  and: "*|Och"
+-  but: "*|Men"
+-"sk":
+-  name: Slovak
+-  native: Slovensky
+-  feature: Požiadavka
+-  background: Pozadie
+-  scenario: Scenár
+-  scenario_outline: Náčrt Scenáru
+-  examples: Príklady
+-  given: "*|Pokiaľ"
+-  when: "*|Keď"
+-  then: "*|Tak"
+-  and: "*|A"
+-  but: "*|Ale"
+-"sr-Latn":
+-  name: Serbian (Latin)
+-  native: Srpski (Latinica)
+-  feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
+-  background: Kontekst|Osnova|Pozadina
+-  scenario: Scenario|Primer
+-  scenario_outline: Struktura scenarija|Skica|Koncept
+-  examples: Primeri|Scenariji
+-  given: "*|Zadato|Zadate|Zatati"
+-  when: "*|Kada|Kad"
+-  then: "*|Onda"
+-  and: "*|I"
+-  but: "*|Ali"
+-"sr-Cyrl":
+-  name: Serbian
+-  native: Српски
+-  feature: Функционалност|Могућност|Особина
+-  background: Контекст|Основа|Позадина
+-  scenario: Сценарио|Пример
+-  scenario_outline: Структура сценарија|Скица|Концепт
+-  examples: Примери|Сценарији
+-  given: "*|Задато|Задате|Задати"
+-  when: "*|Када|Кад"
+-  then: "*|Онда"
+-  and: "*|И"
+-  but: "*|Али"
+-"tr":
+-  name: Turkish
+-  native: Türkçe
+-  feature: Özellik
+-  background: Geçmiş
+-  scenario: Senaryo
+-  scenario_outline: Senaryo taslağı
+-  examples: Örnekler
+-  given: "*|Diyelim ki"
+-  when: "*|Eğer ki"
+-  then: "*|O zaman"
+-  and: "*|Ve"
+-  but: "*|Fakat|Ama"
+-"uk":
+-  name: Ukrainian
+-  native: Українська
+-  feature: Функціонал
+-  background: Передумова
+-  scenario: Сценарій
+-  scenario_outline: Структура сценарію
+-  examples: Приклади
+-  given: "*|Припустимо|Припустимо, що|Нехай|Дано"
+-  when: "*|Якщо|Коли"
+-  then: "*|То|Тоді"
+-  and: "*|І|А також|Та"
+-  but: "*|Але"
+-"uz":
+-  name: Uzbek
+-  native: Узбекча
+-  feature: Функционал
+-  background: Тарих
+-  scenario: Сценарий
+-  scenario_outline: Сценарий структураси
+-  examples: Мисоллар
+-  given: "*|Агар"
+-  when: "*|Агар"
+-  then: "*|Унда"
+-  and: "*|Ва"
+-  but: "*|Лекин|Бирок|Аммо"
+-"vi":
+-  name: Vietnamese
+-  native: Tiếng Việt
+-  feature: Tính năng
+-  background: Bối cảnh
+-  scenario: Tình huống|Kịch bản
+-  scenario_outline: Khung tình huống|Khung kịch bản
+-  examples: Dữ liệu
+-  given: "*|Biết|Cho"
+-  when: "*|Khi"
+-  then: "*|Thì"
+-  and: "*|Và"
+-  but: "*|Nhưng"
+-"zh-CN":
+-  name: Chinese simplified
+-  native: 简体中文
+-  feature: 功能
+-  background: 背景
+-  scenario: 场景
+-  scenario_outline: 场景大纲
+-  examples: 例子
+-  given: "*|假如<"
+-  when: "*|当<"
+-  then: "*|那么<"
+-  and: "*|而且<"
+-  but: "*|但是<"
+-"zh-TW":
+-  name: Chinese traditional
+-  native: 繁體中文
+-  feature: 功能
+-  background: 背景
+-  scenario: 場景|劇本
+-  scenario_outline: 場景大綱|劇本大綱
+-  examples: 例子
+-  given: "*|假設<"
+-  when: "*|當<"
+-  then: "*|那麼<"
+-  and: "*|而且<|並且<"
+-  but: "*|但是<"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch b/meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch
new file mode 100644
index 000000000..b5bac22cf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch
@@ -0,0 +1,155 @@
+From 65ec9d5d69251746a2723f7d2455c23166f3d1a9 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:22:21 +0200
+Subject: [PATCH] more.features: Perform more Gherkin v6 checks and run
+ examples.
+
+---
+ invoke.yaml                                   | 10 ++---
+ more.features/environment.py                  | 28 +++++++++++++
+ .../formatter.json.validate_output.feature    | 22 +++++++++-
+ more.features/run_examples.feature            | 41 +++++++++++++++++++
+ 4 files changed, 93 insertions(+), 8 deletions(-)
+ create mode 100644 more.features/environment.py
+ create mode 100644 more.features/run_examples.feature
+
+diff --git a/invoke.yaml b/invoke.yaml
+index d6f141c..a32345e 100644
+--- a/invoke.yaml
++++ b/invoke.yaml
+@@ -24,13 +24,6 @@ sphinx:
+       - de
+       # PREPARED: - zh-CN
+ 
+-cleanup:
+-    extra_directories:
+-      - "build"
+-      - "dist"
+-      - "__WORKDIR__"
+-      - reports
+-
+ cleanup:
+     extra_directories:
+       - "build"
+@@ -47,6 +40,9 @@ cleanup_all:
+       - .hypothesis
+       - .pytest_cache
+ 
++    extra_files:
++      - "**/testrun*.json"
++
+ behave_test:
+     scopes:
+       - features
+diff --git a/more.features/environment.py b/more.features/environment.py
+new file mode 100644
+index 0000000..9d4302b
+--- /dev/null
++++ b/more.features/environment.py
+@@ -0,0 +1,28 @@
++# -*- coding: UTF-8 -*-
++
++from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
++import sys
++
++# -- MATCHES ANY TAGS: @use.with_{category}={value}
++# NOTE: active_tag_value_provider provides category values for active tags.
++python_version = "%s.%s" % sys.version_info[:2]
++active_tag_value_provider = {
++    "python.version": python_version,
++}
++active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
++
++# -----------------------------------------------------------------------------
++# HOOKS:
++# -----------------------------------------------------------------------------
++def before_all(context):
++    # -- SETUP ACTIVE-TAG MATCHER (with userdata):
++    setup_active_tag_values(active_tag_value_provider, context.config.userdata)
++
++def before_feature(context, feature):
++    if active_tag_matcher.should_exclude_with(feature.tags):
++        feature.skip(reason=active_tag_matcher.exclude_reason)
++
++def before_scenario(context, scenario):
++    if active_tag_matcher.should_exclude_with(scenario.effective_tags):
++        scenario.skip(reason=active_tag_matcher.exclude_reason)
++
+diff --git a/more.features/formatter.json.validate_output.feature b/more.features/formatter.json.validate_output.feature
+index a5f8ab6..31550d5 100644
+--- a/more.features/formatter.json.validate_output.feature
++++ b/more.features/formatter.json.validate_output.feature
+@@ -34,4 +34,24 @@ Feature: Validate JSON Formatter Output
+     Then it should pass with:
+         """
+         validate: testrun3.json ... OK
+-        """
+\ No newline at end of file
++        """
++
++  @gherkin_v6
++  Scenario: Validate JSON output from example/gherkin_v6/ test run
++    Given I use the directory "examples/gherkin_v6" as working directory
++    When I run "behave -f json -o testrun_gherkin6_1.json features/"
++    When I run "../../bin/jsonschema_validate.py testrun_gherkin6_1.json"
++    Then it should pass with:
++        """
++        validate: testrun_gherkin6_1.json ... OK
++        """
++
++  @gherkin_v6
++  Scenario: Validate JSON output from example/gherkin_v6/ test run (case: partly failing)
++    Given I use the directory "examples/gherkin_v6" as working directory
++    When I run "behave --tags=fail -f json -o testrun_gherkin6_2.json features/"
++    When I run "../../bin/jsonschema_validate.py testrun_gherkin6_2.json"
++    Then it should pass with:
++        """
++        validate: testrun_gherkin6_2.json ... OK
++        """
+diff --git a/more.features/run_examples.feature b/more.features/run_examples.feature
+new file mode 100644
+index 0000000..4778866
+--- /dev/null
++++ b/more.features/run_examples.feature
+@@ -0,0 +1,41 @@
++Feature: Ensure that all examples are usable
++
++  Scenario Outline: Use <example_dir>
++    Given I use the directory "<example_dir>" as working directory
++    When I run "behave <behave_cmdline>"
++    Then it should <outcome>
++
++    Examples:
++      | example_dir         | behave_cmdline        | outcome |
++      | examples/env_vars   | features/             | pass    |
++      | examples/fixture.no_background | features/  | pass    |
++      | examples/gherkin_v6 | features/             | pass    |
++
++
++  Scenario: examples/gherkin_v6 -- @xfail parts
++    Given I use the directory "examples/gherkin_v6" as working directory
++    When I run "behave --tags=fail features/"
++    Then it should fail with:
++      """
++      0 features passed, 1 failed, 2 skipped
++      0 rules passed, 1 failed, 6 skipped
++      1 scenario passed, 2 failed, 12 skipped
++      2 steps passed, 2 failed, 39 skipped, 0 undefined
++      """
++    And the command output should contain:
++      """
++      Failing scenarios:
++        features/rule_fails.feature:7  F0 -- Fails
++        features/rule_fails.feature:16  F2 -- Fails
++      """
++
++
++  @use.with_python.version=3.4
++  @use.with_python.version=3.5
++  @use.with_python.version=3.6
++  @use.with_python.version=3.7
++  @use.with_python.version=3.8
++  Scenario: examples/async_step (needs: py34 or newer)
++    Given I use the directory "examples/async_step" as working directory
++    When I run "behave features/"
++    Then it should pass
diff --git a/meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch b/meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch
new file mode 100644
index 000000000..79718261c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch
@@ -0,0 +1,72 @@
+From da0a88f5311e4181a9c24a5853f6392209dceabe Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:39:49 +0200
+Subject: [PATCH] UTIL: Correct URL and python module (old was broken, no
+ longer exists).
+
+---
+ bin/behave2cucumber_json.py | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/bin/behave2cucumber_json.py b/bin/behave2cucumber_json.py
+index 738e444..541061e 100755
+--- a/bin/behave2cucumber_json.py
++++ b/bin/behave2cucumber_json.py
+@@ -3,9 +3,10 @@
+ # CONVERT: behave JSON dialect to cucumber JSON dialect
+ # =============================================================================
+ # STATUS: __PROTOTYPE__
+-# REQUIRES: Python >= 2.6
+-# REQUIRES: https://github.com/behalfinc/b2c/
+-# SEE: https://github.com/behave/behave/issues/267#issuecomment-249607191
++# REQUIRES: Python >= 2.7
++# REQUIRES: https://github.com/behalf-oss/behave2cucumber
++# SEE:
++# * https://github.com/behave/behave/issues/267#issuecomment-251746565
+ # =============================================================================
+ """
+ Convert a file with behave JSON data into a file with cucumber JSON data.
+@@ -17,15 +18,16 @@ import json
+ import sys
+ import os.path
+ try:
+-    import b2c
++    import behave2cucumber
+ except ImportError:
+-    print("REQUIRE: https://github.com/behalfinc/b2c/  (not installed yet)")
+-    print("INSTALL: pip install b2c")
++    print("REQUIRE: https://github.com/behalf-oss/behave2cucumber (not installed yet)")
++    print("INSTALL: pip install behave2cucumber")
+     sys.exit(2)
+ 
+ 
+ NAME = os.path.basename(__file__)
+ 
++
+ def convert_behave_to_cucumber_json(behave_filename, cucumber_filename,
+                                     encoding="UTF-8", pretty=True):
+     """Convert behave JSON dialect into cucumber JSON dialect.
+@@ -39,12 +41,14 @@ def convert_behave_to_cucumber_json(behave_filename, cucumber_filename,
+ 
+     with open(behave_filename, "r") as behave_json:
+         with open(cucumber_filename, "w+") as output_file:
+-            cucumber_json = b2c.convert(json.load(behave_json, encoding))
++            behave_json = json.load(behave_json, encoding)
++            cucumber_json = behave2cucumber.convert(behave_json)
+             # cucumber_text = json.dumps(cucumber_json, **dump_kwargs)
+             # output_file.write(cucumber_text)
+             json.dump(cucumber_json, output_file, **dump_kwargs)
+     return 0
+ 
++
+ def main(args=None):
+     """Main function to run the script."""
+     if args is None:
+@@ -58,6 +62,7 @@ def main(args=None):
+     cucumber_filename = args[1]
+     return convert_behave_to_cucumber_json(behave_filename, cucumber_filename)
+ 
++
+ # -- AUTO-MAIN:
+ if __name__ == "__main__":
+     sys.exit(main())
diff --git a/meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch
new file mode 100644
index 000000000..4b708fa94
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch
@@ -0,0 +1,22 @@
+From 709d7c3604cc8f958dbd6360c66cabf612419c99 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:40:46 +0200
+Subject: [PATCH] UTIL: Formatting tweaks.
+
+---
+ bin/behave2cucumber_json.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bin/behave2cucumber_json.py b/bin/behave2cucumber_json.py
+index 541061e..893a5ef 100755
+--- a/bin/behave2cucumber_json.py
++++ b/bin/behave2cucumber_json.py
+@@ -20,7 +20,7 @@ import os.path
+ try:
+     import behave2cucumber
+ except ImportError:
+-    print("REQUIRE: https://github.com/behalf-oss/behave2cucumber (not installed yet)")
++    print("REQUIRE: https://github.com/behalf-oss/behave2cucumber")
+     print("INSTALL: pip install behave2cucumber")
+     sys.exit(2)
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch b/meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch
new file mode 100644
index 000000000..ff0a4238f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch
@@ -0,0 +1,23 @@
+From c507804a610e09aaabe7c5da7665857ce7947736 Mon Sep 17 00:00:00 2001
+From: Jon-Pierre Gentil <jgentil@sebistar.net>
+Date: Thu, 1 Aug 2019 11:21:36 -0500
+Subject: [PATCH] Fixed a bug where use_fixture_by_tag didn't return the actual
+ fixture if the registry entry was just a direct function.
+
+---
+ behave/fixture.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/behave/fixture.py b/behave/fixture.py
+index 3a9f1bc..51e18bf 100644
+--- a/behave/fixture.py
++++ b/behave/fixture.py
+@@ -272,7 +272,7 @@ def use_fixture_by_tag(tag, context, fixture_registry):
+ 
+     if callable(fixture_data):
+         fixture_func = fixture_data
+-        use_fixture(fixture_func, context)
++        return use_fixture(fixture_func, context)
+     elif isinstance(fixture_data, (tuple, list)):
+         assert len(fixture_data) == 3
+         fixture_func, fixture_args, fixture_kwargs = fixture_data
diff --git a/meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch b/meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch
new file mode 100644
index 000000000..b35ba1448
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch
@@ -0,0 +1,62 @@
+From ee4784efbbf1cbd18390e2dd36f61dee1b003858 Mon Sep 17 00:00:00 2001
+From: Jon-Pierre Gentil <jgentil@sebistar.net>
+Date: Thu, 1 Aug 2019 11:48:08 -0500
+Subject: [PATCH] Added issue unit test
+
+---
+ tests/issues/test_issue0767.py | 46 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+ create mode 100644 tests/issues/test_issue0767.py
+
+diff --git a/tests/issues/test_issue0767.py b/tests/issues/test_issue0767.py
+new file mode 100644
+index 0000000..1de3589
+--- /dev/null
++++ b/tests/issues/test_issue0767.py
+@@ -0,0 +1,46 @@
++"""
++https://github.com/behave/behave/issues/767
++
++When trying to do something like::
++
++    fixture_registry = {'fixture.foo': foo_fixture}
++    f = use_fixture_by_tag('fixture.foo', context, fixture_registry)
++
++Behave returns nothing. ::
++
++    repr(f)
++    'None'
++
++This seems to be an oversight.
++"""
++
++from mock import Mock
++
++def test_issue_767_use_feature_by_tag_has_no_return():
++    """Verifies that issue #767 is fixed."""
++    from behave.fixture import fixture, use_fixture_by_tag
++    from behave.runner import Context
++
++    @fixture(name='fixture.foo')
++    def foo_fixture(context, *args, **kwargs):
++        context.foo = 'foo'
++        return context.foo
++
++    # -- SCHEMA 1: fixture_func
++    fixture_registry1 = {
++        "fixture.foo": foo_fixture
++    }
++    # -- SCHEMA 2: fixture_func, fixture_args, fixture_kwargs
++    fixture_registry2 = {
++        "fixture.foo": (foo_fixture, (), {})
++    }
++
++    context = Context(runner=Mock())
++    f1 = use_fixture_by_tag('fixture.foo', context, fixture_registry1)
++    assert f1 == 'foo'
++    assert context.foo is f1
++
++    context = Context(runner=Mock())
++    f2 = use_fixture_by_tag('fixture.foo', context, fixture_registry2)
++    assert f2 == 'foo'
++    assert context.foo is f2
diff --git a/meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch
new file mode 100644
index 000000000..b59ebabe1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch
@@ -0,0 +1,60 @@
+From 2c3c2a4217d033c3f7157046765e0888bde3bfbd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 7 Aug 2019 23:14:59 +0200
+Subject: [PATCH] Merge pull-request #767 with minor tweaks. FIX:
+ use_fixture_by_tag didn't return the actual fixture in all cases.
+
+---
+ CHANGES.rst                    |  1 +
+ tests/issues/test_issue0767.py | 17 +++++++++--------
+ 2 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 15a4ef9..7a9163f 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -43,6 +43,7 @@ FIXED:
+ 
+ MINOR:
+ 
++* pull  #767: FIX: use_fixture_by_tag didn't return the actual fixture in all cases (provided by: jgentil)
+ * pull  #751: gherkin: Adding Rule keyword translation in portuguese and spanish to gherkin-languages.json (provided by: dunossauro)
+ * pull  #660: Fix minor typos (provided by: rrueth)
+ * pull  #655: Use pytest instead of py.test per upstream recommendation (provided by: scop)
+diff --git a/tests/issues/test_issue0767.py b/tests/issues/test_issue0767.py
+index 1de3589..401dbd0 100644
+--- a/tests/issues/test_issue0767.py
++++ b/tests/issues/test_issue0767.py
+@@ -15,11 +15,12 @@ This seems to be an oversight.
+ """
+ 
+ from mock import Mock
++from behave.fixture import fixture, use_fixture_by_tag
++from behave.runner import Context
++
+ 
+ def test_issue_767_use_feature_by_tag_has_no_return():
+     """Verifies that issue #767 is fixed."""
+-    from behave.fixture import fixture, use_fixture_by_tag
+-    from behave.runner import Context
+ 
+     @fixture(name='fixture.foo')
+     def foo_fixture(context, *args, **kwargs):
+@@ -36,11 +37,11 @@ def test_issue_767_use_feature_by_tag_has_no_return():
+     }
+ 
+     context = Context(runner=Mock())
+-    f1 = use_fixture_by_tag('fixture.foo', context, fixture_registry1)
+-    assert f1 == 'foo'
+-    assert context.foo is f1
++    fixture1 = use_fixture_by_tag("fixture.foo", context, fixture_registry1)
++    assert fixture1 == "foo"
++    assert context.foo is fixture1
+ 
+     context = Context(runner=Mock())
+-    f2 = use_fixture_by_tag('fixture.foo', context, fixture_registry2)
+-    assert f2 == 'foo'
+-    assert context.foo is f2
++    fixture2 = use_fixture_by_tag("fixture.foo", context, fixture_registry2)
++    assert fixture2 == "foo"
++    assert context.foo is fixture2
diff --git a/meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch b/meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch
new file mode 100644
index 000000000..0b8f63408
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch
@@ -0,0 +1,83 @@
+From 2034f2d33b24d43c9f0c120ace578ca53656fab6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 7 Aug 2019 23:55:05 +0200
+Subject: [PATCH] CHECK: Issue #766 -- PrettyFormatter: UnicodeError
+
+---
+ issue.features/issue0766.feature        | 47 +++++++++++++++++++++++++
+ issue.features/steps/issue0766_steps.py | 12 +++++++
+ 2 files changed, 59 insertions(+)
+ create mode 100644 issue.features/issue0766.feature
+ create mode 100644 issue.features/steps/issue0766_steps.py
+
+diff --git a/issue.features/issue0766.feature b/issue.features/issue0766.feature
+new file mode 100644
+index 0000000..94d44d8
+--- /dev/null
++++ b/issue.features/issue0766.feature
+@@ -0,0 +1,47 @@
++@issue
++@not_reproducible
++Feature: Issue #766 -- UnicodeEncodeError in PrettyFormatter
++
++  Explore the described problem.
++
++  Scenario Outline:
++    Given a step with name="<name>"
++
++    Examples:
++      | name | value | comment |
++      | 😄   | 123   | Use emoticon (smiley) in a table |
++
++  Scenario:
++    Given a step with table data:
++      | name | value | comment |
++      | 😄   | 123   | Use emoticon (smiley) in a table |
++
++  Scenario: Explore problem by using the pretty formatter
++    Given a new working directory
++    And a file named "features/syndrome_766.feature" with:
++      """
++      Feature: Alice
++        Scenario Outline:
++          Given a step with name="<name>"
++
++          Examples:
++            | name | value | comment |
++            | 😄   | 123   | Use emoticon (smiley) in a table |
++      """
++    And a file named "features/steps/issue766_steps.py" with:
++      """
++      from behave import given
++
++      @given(u'a step with name="{name}"')
++      def step_with_table_data(ctx, name):
++          pass
++      """
++    When I run "behave -f pretty features/syndrome_766.feature"
++    Then it should pass with:
++      """
++      1 feature passed, 0 failed, 0 skipped
++      1 scenario passed, 0 failed, 0 skipped
++      1 step passed, 0 failed, 0 skipped, 0 undefine
++      """
++    And the command output should not contain "UnicodeEncodeError"
++    And the command output should not contain "Traceback"
+diff --git a/issue.features/steps/issue0766_steps.py b/issue.features/steps/issue0766_steps.py
+new file mode 100644
+index 0000000..33ed317
+--- /dev/null
++++ b/issue.features/steps/issue0766_steps.py
+@@ -0,0 +1,12 @@
++# -*- coding: UTF-8 -*-
++
++from __future__ import print_function
++from behave import given
++
++@given(u'a step with table data')
++def step_with_table_data(ctx):
++    assert ctx.table is not None, "REQUIRE: step.table"
++
++@given(u'a step with name="{name}"')
++def step_with_table_data(ctx, name):
++    print(u"name: {}".format(name))
diff --git a/meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch b/meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
new file mode 100644
index 000000000..ffa265eed
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
@@ -0,0 +1,74 @@
+From 82065e999bfc125461c2e3db17856bf5a1384443 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 22 Sep 2019 18:08:22 +0200
+Subject: [PATCH] FIX issue #772: ScenarioOutline.Examples without table.
+
+---
+ behave/model.py                  |  8 +++++++-
+ issue.features/issue0772.feature | 31 +++++++++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+), 1 deletion(-)
+ create mode 100644 issue.features/issue0772.feature
+
+diff --git a/behave/model.py b/behave/model.py
+index 69f38ab..f46d2c2 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -10,7 +10,7 @@ This module provides the model element class that represent a behave model:
+ * ...
+ """
+ 
+-from __future__ import absolute_import, with_statement
++from __future__ import absolute_import, with_statement, print_function
+ import copy
+ import difflib
+ import logging
+@@ -1355,6 +1355,12 @@ class ScenarioOutlineBuilder(object):
+             example.index = example_index+1
+             params["examples.name"] = example.name
+             params["examples.index"] = _text(example.index)
++            if not example.table:
++                # -- SYNDROME: Examples keyword without table
++                print("ERROR: ScenarioOutline.Examples: Has NO-TABLE syndrome ({0})"\
++                      .format(example.location))
++                continue
++
+             for row_index, row in enumerate(example.table):
+                 row.index = row_index+1
+                 row.id = "%d.%d" % (example.index, row.index)
+diff --git a/issue.features/issue0772.feature b/issue.features/issue0772.feature
+new file mode 100644
+index 0000000..eba0ea5
+--- /dev/null
++++ b/issue.features/issue0772.feature
+@@ -0,0 +1,31 @@
++@issue
++Feature: Issue #772 -- Syndrome: ScenarioOutline with Examples keyword w/o Table
++
++
++
++  Background: Setup
++    Given a new working directory
++    And a file named "features/syndrome_772.feature" with:
++      """
++      Feature: Examples without table
++
++        Scenario Outline:
++          Given a step passes
++          When another step passes
++
++          Examples: Without table
++      """
++    And a file named "features/steps/use_step_library.py" with:
++      """
++      # -- REUSE STEPS:
++      import behave4cmd0.passing_steps
++      """
++
++  Scenario: Use ScenarioOutline with Examples keyword without table
++    When I run "behave -f plain features/syndrome_772.feature"
++    Then it should pass with:
++      """
++      Feature: Examples without table
++      ERROR: ScenarioOutline.Examples: Has NO-TABLE syndrome (features/syndrome_772.feature:7)
++      """
++    And the command output should not contain "Parser failure in state"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch b/meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
new file mode 100644
index 000000000..243cb82d0
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
@@ -0,0 +1,21 @@
+From 1d45845ffb9a30ca66806ba165bea54f7d43cd46 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 22 Sep 2019 18:09:50 +0200
+Subject: [PATCH] FIX issue #772: ScenarioOutline.Examples without table.
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 7a9163f..ba4daad 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -33,6 +33,7 @@ ENHANCEMENTS:
+ 
+ FIXED:
+ 
++* issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+ * issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch b/meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch
new file mode 100644
index 000000000..683ed9275
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch
@@ -0,0 +1,21 @@
+From 5c181e07ca0fda2ea26cf8c8949dd8baaa2be953 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 11 Dec 2019 08:23:08 +0100
+Subject: [PATCH] Nibble TravisCI to wake up.
+
+---
+ .travis.yml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/.travis.yml b/.travis.yml
+index c6027e0..781a610 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -6,6 +6,7 @@ python:
+   - "3.7"
+   - "2.7"
+ 
++
+ # -- DISABLE-TEMPORARILY: Ensure faster builds
+ #  - "3.6"
+ #  - "3.5"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch b/meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch
new file mode 100644
index 000000000..143c178d0
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch
@@ -0,0 +1,37 @@
+From ba6f76873dadead64be57c215ba2f7eb40d0ea6d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 11 Dec 2019 08:30:11 +0100
+Subject: [PATCH] Tweak pytest version selection
+
+---
+ py.requirements/ci.travis.txt | 3 ++-
+ setup.py                      | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 73d65f6..5f31802 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,6 +1,7 @@
+ mock
+ PyHamcrest >= 1.9
+-pytest >= 3.0
++pytest <  5.0; python_version <  '3.0'
++pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+diff --git a/setup.py b/setup.py
+index 8de3ec0..75d6847 100644
+--- a/setup.py
++++ b/setup.py
+@@ -87,7 +87,8 @@ setup(
+         "colorama",
+     ],
+     tests_require=[
+-        "pytest >= 4.2",
++        "pytest <  5.0; python_version <  '3.0'", # >= 4.2
++        "pytest >= 5.0; python_version >= '3.0'",
+         "pytest-html >= 1.19.0",
+         "mock >= 1.1",
+         "PyHamcrest >= 1.9",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch b/meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch
new file mode 100644
index 000000000..f0e642634
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch
@@ -0,0 +1,37 @@
+From 7bd632e11a5ab75cec3e20722cf8fa3cebb1983f Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 11 Dec 2019 08:37:11 +0100
+Subject: [PATCH] Tweak pytest configuration to silence JUnit XML dialect
+ warning.
+
+---
+ pytest.ini | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/pytest.ini b/pytest.ini
+index ff2a8a2..228279c 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -16,9 +16,10 @@
+ # ============================================================================
+ 
+ [pytest]
+-minversion    = 2.8
++minversion    = 4.2
+ testpaths     = tests
+ python_files  = test_*.py
++junit_family = xunit2
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+     --metadata PACKAGE_VERSION 1.2.7.dev1
+     --html=build/testing/report.html --self-contained-html
+@@ -27,6 +28,10 @@ markers =
+     smoke
+     slow
+ 
++# -- PREPARED:
++# filterwarnings =
++#    ignore:.*invalid escape sequence.*:DeprecationWarning
++
+ # -- BACKWARD COMPATIBILITY: pytest < 2.8
+ # norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch b/meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch
new file mode 100644
index 000000000..97db40580
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch
@@ -0,0 +1,56 @@
+From 56c4ee34b403d69ed3c7092edee95ae6f3b6fd74 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 15:50:37 +0100
+Subject: [PATCH] Add basic feature-test for wildcard pattern-matching that is
+ supported by cucumber-tag-expressions (python-only).
+
+---
+ .../tags.tag_expression_v2.wildcards.feature  | 39 +++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+ create mode 100644 features/tags.tag_expression_v2.wildcards.feature
+
+diff --git a/features/tags.tag_expression_v2.wildcards.feature b/features/tags.tag_expression_v2.wildcards.feature
+new file mode 100644
+index 0000000..372a731
+--- /dev/null
++++ b/features/tags.tag_expression_v2.wildcards.feature
+@@ -0,0 +1,39 @@
++Feature: Tag Expression v2 Extension: Wildcards for tag matching
++
++  As a tester
++  I want to use a wildcard pattern to select tags following a naming scheme
++  So that it is simpler to select a subset of scenarios and features.
++
++  . SPECIFICATION: Wildcards in tag-expressions v2
++  .   * Use file-name matching wildcards (fnmatch): *, ?
++  .   * a tag expression is a boolean expression
++  .   * a tag expression supports the operators: and, or, not
++  .   * a tag expression supports '(' and ')' for grouping expressions
++  .
++  . EXAMPLES:
++  .   | Tag expression          | Comment |
++  .   | @foo.*                  | Matches any tags that start with "@foo." |
++  .   | not @foo.*              | Excludes any element that have tags that start with "@foo." |
++
++
++  Scenario: Select tags that match the "@foo.*" pattern
++    Given the tag expression "@foo.*"
++    Then the tag expression selects elements with tags:
++        | tags          | selected? |
++        |               |   no      |
++        | @foo          |   no      |
++        | @foo.one      |   yes     |
++        | @foo.two      |   yes     |
++        | @other        |   no      |
++        | @foo.3 @other |   yes     |
++
++  Scenario: Select tags that do not match the "@foo.*" pattern
++    Given the tag expression "not @foo.*"
++    Then the tag expression selects elements with tags:
++        | tags          | selected? |
++        |               |   yes     |
++        | @foo          |   yes     |
++        | @foo.one      |   no      |
++        | @foo.two      |   no      |
++        | @other        |   yes     |
++        | @foo.3 @other |   no      |
diff --git a/meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch b/meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch
new file mode 100644
index 000000000..1cdf70944
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch
@@ -0,0 +1,141 @@
+From ff1f1e74f5f81eb634d72d472ce18f8d543bf3c0 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 20:12:14 +0100
+Subject: [PATCH] UPDATE: dependencies (path.py <=> path, pytest, ...)
+
+---
+ py.requirements/ci.tox.txt    |  8 ++++++--
+ py.requirements/ci.travis.txt | 11 ++++++++---
+ py.requirements/develop.txt   |  5 ++++-
+ py.requirements/testing.txt   |  7 +++++--
+ setup.py                      |  6 ++++--
+ tasks/py.requirements.txt     |  5 ++++-
+ 6 files changed, 31 insertions(+), 11 deletions(-)
+
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 6b3b3ae..4001bc2 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -2,8 +2,12 @@
+ # BEHAVE: PYTHON PACKAGE REQUIREMENTS: ci.tox.txt
+ # ============================================================================
+ 
+-pytest >= 4.2
++pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
++pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock >= 2.0
+ PyHamcrest >= 1.9
+-path.py >= 10.1
++
++# -- HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 5f31802..de4120a 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,12 +1,17 @@
+-mock
+-PyHamcrest >= 1.9
++# ============================================================================
++# PYTHON PACKAGE REQUIREMENTS FOR: behave -- ci.travis.txt
++# ============================================================================
+ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
++mock  >= 2.0
++PyHamcrest >= 1.9
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+-path.py >= 10.1
++# HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
+ 
+ # -- NOTE: Travis.CI tweak related w/ invalid linecache2 tests.
+ #    This problem does not exist if you use pip.
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index a16d7bf..a92ee5f 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -6,10 +6,13 @@
+ # PREPARE USAGE: invoke
+ # ALREADY: six >= 1.11.0
+ invoke >= 1.2.0
+-path.py >= 11.5.0
+ pathlib;    python_version <= '3.4'
+ pycmd
+ 
++# -- HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
++
+ # -- CONFIGURATION MANAGEMENT (helpers):
+ # FORMER: bumpversion >= 0.4.0
+ bump2version >= 0.5.6
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index a418739..85b0908 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -4,11 +4,14 @@
+ 
+ # -- TESTING: Unit tests and behave self-tests.
+ # PREPARED-FUTURE: behave4cmd0, behave4cmd
+-pytest >= 4.2
++pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
++pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+ PyHamcrest >= 1.9
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+-path.py >= 11.5.0
++# HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
+diff --git a/setup.py b/setup.py
+index 75d6847..2afc147 100644
+--- a/setup.py
++++ b/setup.py
+@@ -77,7 +77,7 @@ setup(
+     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*",
+     install_requires=[
+         "cucumber-tag-expressions >= 1.1.2",
+-        "parse >= 1.8.2",
++        "parse >= 1.9.1",
+         "parse_type >= 0.4.2",
+         "six >= 1.12.0",
+         "traceback2; python_version < '3.0'",
+@@ -92,7 +92,9 @@ setup(
+         "pytest-html >= 1.19.0",
+         "mock >= 1.1",
+         "PyHamcrest >= 1.9",
+-        "path.py >= 11.5.0"
++        # -- HINT: path.py => path (python-install-package was renamed for python3)
++        "path.py >= 11.5.0; python_version <  '3.5'",
++        "path >= 13.1.0;    python_version >= '3.5'",
+     ],
+     cmdclass = {
+         "behave_test": behave_test,
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index a77d3bc..810f834 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -9,10 +9,13 @@
+ # ============================================================================
+ 
+ invoke >= 1.2.0
+-path.py >= 11.5.0
+ pycmd
+ six >= 1.12.0
+ 
++# -- HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
++
+ # -- PYTHON2 BACKPORTS:
+ pathlib;    python_version <= '3.4'
+ backports.shutil_which; python_version <= '3.3'
diff --git a/meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch b/meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch
new file mode 100644
index 000000000..df5b0d372
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch
@@ -0,0 +1,25 @@
+From 451f88ab5d1ea7da9737ef701a4309963516f3c4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 20:16:43 +0100
+Subject: [PATCH] pytest: Disable DeprecatedWarning from distutils package.
+
+---
+ pytest.ini | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/pytest.ini b/pytest.ini
+index 228279c..b9f281a 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -29,8 +29,9 @@ markers =
+     slow
+ 
+ # -- PREPARED:
+-# filterwarnings =
+-#    ignore:.*invalid escape sequence.*:DeprecationWarning
++filterwarnings =
++   ignore:.*the imp module is deprecated in favour of importlib.*:DeprecationWarning
++#   ignore:.*invalid escape sequence.*:DeprecationWarning
+ 
+ # -- BACKWARD COMPATIBILITY: pytest < 2.8
+ # norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
diff --git a/meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch b/meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch
new file mode 100644
index 000000000..122a63af8
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch
@@ -0,0 +1,216 @@
+From 37fd19b56ba31634a34349d956120b6a5898e2d9 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:20:18 +0100
+Subject: [PATCH] CLEANUP: Add ContextMode enum related to #797
+
+Add ContextMode enum to cleanup weirdness related to issue #797.
+Pre-existing Context.BEHAVE/USER constants overshadowed user attributes
+in Context.attribute retrieval case.
+---
+ behave/runner.py          | 33 ++++++++++++++++++++++-----------
+ tests/unit/test_runner.py | 29 +++++++++++++++--------------
+ 2 files changed, 37 insertions(+), 25 deletions(-)
+
+diff --git a/behave/runner.py b/behave/runner.py
+index cbedb5a..bcf4ab2 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -21,6 +21,7 @@ from behave.runner_util import \
+     collect_feature_locations, parse_features, \
+     exec_file, load_step_modules, PathManager
+ from behave.step_registry import registry as the_step_registry
++from enum import Enum
+ 
+ if six.PY2:
+     # -- USE PYTHON3 BACKPORT: With unicode traceback support.
+@@ -45,6 +46,16 @@ class ContextMaskWarning(UserWarning):
+     pass
+ 
+ 
++class ContextMode(Enum):
++    """Used to distinguish between the two usage modes while using the context:
++
++    * BEHAVE: Indicates "behave" (internal) mode
++    * USER: Indicates "user" mode (in steps, hooks, fixtures, ...)
++    """
++    BEHAVE = 1
++    USER = 2
++
++
+ class Context(object):
+     """Hold contextual information during the running of tests.
+ 
+@@ -147,8 +158,8 @@ class Context(object):
+     .. _`configuration file section names`: behave.html#configuration-files
+     """
+     # pylint: disable=too-many-instance-attributes
+-    BEHAVE = "behave"
+-    USER = "user"
++    # BEHAVE = "behave"
++    # USER = "user"
+     FAIL_ON_CLEANUP_ERRORS = True
+ 
+     def __init__(self, runner):
+@@ -166,7 +177,7 @@ class Context(object):
+         self._stack = [d]
+         self._record = {}
+         self._origin = {}
+-        self._mode = self.BEHAVE
++        self._mode = ContextMode.BEHAVE
+ 
+         # -- MODEL ENTITY REFERENCES/SUPPORT:
+         self.feature = None
+@@ -260,11 +271,11 @@ class Context(object):
+ 
+     def _use_with_behave_mode(self):
+         """Provides a context manager for using the context in BEHAVE mode."""
+-        return use_context_with_mode(self, Context.BEHAVE)
++        return use_context_with_mode(self, ContextMode.BEHAVE)
+ 
+     def use_with_user_mode(self):
+         """Provides a context manager for using the context in USER mode."""
+-        return use_context_with_mode(self, Context.USER)
++        return use_context_with_mode(self, ContextMode.USER)
+ 
+     def user_mode(self):
+         warnings.warn("Use 'use_with_user_mode()' instead",
+@@ -291,11 +302,11 @@ class Context(object):
+ 
+     def _emit_warning(self, attr, params):
+         msg = ""
+-        if self._mode is self.BEHAVE and self._origin[attr] is not self.BEHAVE:
++        if self._mode is ContextMode.BEHAVE and self._origin[attr] is not ContextMode.BEHAVE:
+             msg = "behave runner is masking context attribute '%(attr)s' " \
+                   "originally set in %(function)s (%(filename)s:%(line)s)"
+-        elif self._mode is self.USER:
+-            if self._origin[attr] is not self.USER:
++        elif self._mode is ContextMode.USER:
++            if self._origin[attr] is not ContextMode.USER:
+                 msg = "user code is masking context attribute '%(attr)s' " \
+                       "originally set by behave"
+             elif self._config.verbose:
+@@ -442,13 +453,13 @@ class Context(object):
+ 
+ @contextlib.contextmanager
+ def use_context_with_mode(context, mode):
+-    """Switch context to BEHAVE or USER mode.
++    """Switch context to ContextMode.BEHAVE or ContextMode.USER mode.
+     Provides a context manager for switching between the two context modes.
+ 
+     .. sourcecode:: python
+ 
+         context = Context()
+-        with use_context_with_mode(context, Context.BEHAVE):
++        with use_context_with_mode(context, ContextMode.BEHAVE):
+             ...     # Do something
+         # -- POSTCONDITION: Original context._mode is restored.
+ 
+@@ -456,7 +467,7 @@ def use_context_with_mode(context, mode):
+     :param mode:     Mode to apply to context object.
+     """
+     # pylint: disable=protected-access
+-    assert mode in (Context.BEHAVE, Context.USER)
++    assert mode in (ContextMode.BEHAVE, ContextMode.USER)
+     current_mode = context._mode
+     try:
+         context._mode = mode
+diff --git a/tests/unit/test_runner.py b/tests/unit/test_runner.py
+index f0d03cd..beaff8f 100644
+--- a/tests/unit/test_runner.py
++++ b/tests/unit/test_runner.py
+@@ -17,6 +17,7 @@ from behave import runner_util
+ from behave.model import Table
+ from behave.step_registry import StepRegistry
+ from behave import parser, runner
++from behave.runner import ContextMode
+ from behave.exception import ConfigError
+ from behave.formatter.base import StreamOpener
+ 
+@@ -36,29 +37,29 @@ class TestContext(unittest.TestCase):
+ 
+     def test_user_mode_shall_restore_behave_mode(self):
+         # -- CASE: No exception is raised.
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         assert self.context._mode == initial_mode
+         with self.context.use_with_user_mode():
+-            assert self.context._mode == runner.Context.USER
++            assert self.context._mode == ContextMode.USER
+             self.context.thing = "stuff"
+         assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_assert_fails(self):
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                assert self.context._mode == runner.Context.USER
++                assert self.context._mode == ContextMode.USER
+                 assert False, "XFAIL"
+         except AssertionError:
+             assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_exception_is_raised(self):
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                assert self.context._mode == runner.Context.USER
++                assert self.context._mode == ContextMode.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+             assert self.context._mode == initial_mode
+@@ -66,21 +67,21 @@ class TestContext(unittest.TestCase):
+     def test_use_with_user_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         self.context._mode = initial_mode
+         with self.context.use_with_user_mode():
+-            assert self.context._mode == runner.Context.USER
++            assert self.context._mode == ContextMode.USER
+             self.context.thing = "stuff"
+         assert self.context._mode == initial_mode
+ 
+     def test_use_with_user_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         self.context._mode = initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                assert self.context._mode == runner.Context.USER
++                assert self.context._mode == ContextMode.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+             assert self.context._mode == initial_mode
+@@ -88,21 +89,21 @@ class TestContext(unittest.TestCase):
+     def test_use_with_behave_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.USER
++        initial_mode = ContextMode.USER
+         self.context._mode = initial_mode
+         with self.context._use_with_behave_mode():
+-            assert self.context._mode == runner.Context.BEHAVE
++            assert self.context._mode == ContextMode.BEHAVE
+             self.context.thing = "stuff"
+         assert self.context._mode == initial_mode
+ 
+     def test_use_with_behave_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.USER
++        initial_mode = ContextMode.USER
+         self.context._mode = initial_mode
+         try:
+             with self.context._use_with_behave_mode():
+-                assert self.context._mode == runner.Context.BEHAVE
++                assert self.context._mode == ContextMode.BEHAVE
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+             assert self.context._mode == initial_mode
diff --git a/meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch b/meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch
new file mode 100644
index 000000000..9b0e77d1b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch
@@ -0,0 +1,22 @@
+From 1c3eab0fed1d0eb33da64eb568e42971822655df Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:25:00 +0100
+Subject: [PATCH] Cleanup comments
+
+---
+ behave/runner.py | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/behave/runner.py b/behave/runner.py
+index bcf4ab2..6b20937 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -158,8 +158,6 @@ class Context(object):
+     .. _`configuration file section names`: behave.html#configuration-files
+     """
+     # pylint: disable=too-many-instance-attributes
+-    # BEHAVE = "behave"
+-    # USER = "user"
+     FAIL_ON_CLEANUP_ERRORS = True
+ 
+     def __init__(self, runner):
diff --git a/meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch b/meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch
new file mode 100644
index 000000000..79755daa7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch
@@ -0,0 +1,29 @@
+From f9977969e7fabad5644b57f53462954ed097e66e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:51:47 +0100
+Subject: [PATCH] FIX: sphinx-build problem: async_steps3x.py
+
+---
+ docs/new_and_noteworthy_v1.2.6.rst | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/docs/new_and_noteworthy_v1.2.6.rst b/docs/new_and_noteworthy_v1.2.6.rst
+index 848c409..2c8e865 100644
+--- a/docs/new_and_noteworthy_v1.2.6.rst
++++ b/docs/new_and_noteworthy_v1.2.6.rst
+@@ -325,13 +325,13 @@ A simple example for the implementation of the async-steps is shown for:
+ * Python 3.5 with new ``async``/``await`` keywords
+ * Python 3.4 with ``@asyncio.coroutine`` decorator and ``yield from`` keyword
+ 
+-.. literalinclude:: ../examples/async_step/features/steps/async_steps35.py
++.. literalinclude:: ../examples/async_step/features/steps/_async_steps35.py
+     :language: python
+     :prepend:
+         # -- FILE: features/steps/async_steps35.py
+ 
+ 
+-.. literalinclude:: ../examples/async_step/features/steps/async_steps34.py
++.. literalinclude:: ../examples/async_step/features/steps/_async_steps34.py
+     :language: python
+     :prepend:
+         # -- FILE: features/steps/async_steps34.py
diff --git a/meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch b/meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch
new file mode 100644
index 000000000..444ed5d14
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch
@@ -0,0 +1,185 @@
+From 70943d9fae75cce204052ac0f498e603f1c7f4c4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:52:53 +0100
+Subject: [PATCH] docs: Rename page 'parse_expressions' (was:
+ parse_builtin_types) and update table to current parse-1.12.1
+
+---
+ docs/appendix.rst            |  2 +-
+ docs/parse_builtin_types.rst | 59 ------------------------
+ docs/parse_expressions.rst   | 87 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 88 insertions(+), 60 deletions(-)
+ delete mode 100644 docs/parse_builtin_types.rst
+ create mode 100644 docs/parse_expressions.rst
+
+diff --git a/docs/appendix.rst b/docs/appendix.rst
+index 8c0cb05..79b5455 100644
+--- a/docs/appendix.rst
++++ b/docs/appendix.rst
+@@ -11,7 +11,7 @@ Appendix
+ 
+     formatters
+     context_attributes
+-    parse_builtin_types
++    parse_expressions
+     regular_expressions
+     test_domains
+     behave_ecosystem
+diff --git a/docs/parse_builtin_types.rst b/docs/parse_builtin_types.rst
+deleted file mode 100644
+index 32e18ec..0000000
+--- a/docs/parse_builtin_types.rst
++++ /dev/null
+@@ -1,59 +0,0 @@
+-.. _id.appendix.parse_builtin_types:
+-
+-Predefined Data Types in ``parse``
+-==============================================================================
+-
+-:pypi:`behave` uses the :pypi:`parse` module (inverse of Python `string.format`_)
+-under the hoods to parse parameters in step definitions.
+-This leads to rather simple and readable parse expressions for step parameters.
+-
+-.. code-block:: python
+-
+-    # -- FILE: features/steps/type_transform_example_steps.py
+-    from behave import given
+-
+-    @given('I have {number:d} friends')  #< Convert 'number' into int type.
+-    def step_given_i_have_number_friends(context, number):
+-        assert number > 0
+-        ...
+-
+-Therefore, the following ``parse types`` are already supported
+-in step definitions without registration of any *user-defined type*:
+-
+-
+-===== =========================================== ============
+-Type  Characters Matched                          Output Type
+-===== =========================================== ============
+- w    Letters and underscore                      str
+- W    Non-letter and underscore                   str
+- s    Whitespace                                  str
+- S    Non-whitespace                              str
+- d    Digits (effectively integer numbers)        int
+- D    Non-digit                                   str
+- n    Numbers with thousands separators (, or .)  int
+- %    Percentage (converted to value/100.0)       float
+- f    Fixed-point numbers                         float
+- e    Floating-point numbers with exponent        float
+-      e.g. 1.1e-10, NAN (all case insensitive)
+- g    General number format (either d, f or e)    float
+- b    Binary numbers                              int
+- o    Octal numbers                               int
+- x    Hexadecimal numbers (lower and upper case)  int
+- ti   ISO 8601 format date/time                   datetime
+-      e.g. 1972-01-20T10:21:36Z
+- te   RFC2822 e-mail format date/time             datetime
+-      e.g. Mon, 20 Jan 1972 10:21:36 +1000
+- tg   Global (day/month) format date/time         datetime
+-      e.g. 20/1/1972 10:21:36 AM +1:00
+- ta   US (month/day) format date/time             datetime
+-      e.g. 1/20/1972 10:21:36 PM +10:30
+- tc   ctime() format date/time                    datetime
+-      e.g. Sun Sep 16 01:03:52 1973
+- th   HTTP log format date/time                   datetime
+-      e.g. 21/Nov/2011:00:07:11 +0000
+- tt   Time                                        time
+-      e.g. 10:21:36 PM -5:30
+-===== =========================================== ============
+-
+-
+-.. _string.format: https://docs.python.org/3/library/string.html#format-string-syntax
+diff --git a/docs/parse_expressions.rst b/docs/parse_expressions.rst
+new file mode 100644
+index 0000000..36ca549
+--- /dev/null
++++ b/docs/parse_expressions.rst
+@@ -0,0 +1,87 @@
++.. _id.appendix.parse_expressions:
++
++==============================================================================
++Parse Expressions
++==============================================================================
++
++.. index:: parse expressions, regexp
++
++`Parse expressions`_ are a simplified form of regular expressions.
++The actual regular expression is hidden behind the **type** name / hint.
++
++`Parse expressions`_ are used in step definitions as a simplified alternative
++to regular expressions. They are used for parameters and type conversions
++(which are not supported for regular expression patterns).
++
++.. code-block:: python
++
++    # -- FILE: features/steps/example_steps.py
++    from behave import when
++
++    @when('we implement {number:d} tests')
++    def step_impl(context, number):  # -- NOTE: number is converted into integer
++        assert number > 1 or number == 0
++        context.tests_count = number
++
++The following tables provide a overview of the `parse expressions`_ syntax.
++See also `Python regular expressions`_ description in the Python `re module`_.
++
++===== =========================================== ========
++Type  Characters Matched                          Output
++===== =========================================== ========
++l     Letters (ASCII)                             str
++w     Letters, numbers and underscore             str
++W     Not letters, numbers and underscore         str
++s     Whitespace                                  str
++S     Non-whitespace                              str
++d     Digits (effectively integer numbers)        int
++D     Non-digit                                   str
++n     Numbers with thousands separators (, or .)  int
++%     Percentage (converted to value/100.0)       float
++f     Fixed-point numbers                         float
++F     Decimal numbers                             Decimal
++e     Floating-point numbers with exponent        float
++      e.g. 1.1e-10, NAN (all case insensitive)
++g     General number format (either d, f or e)    float
++b     Binary numbers                              int
++o     Octal numbers                               int
++x     Hexadecimal numbers (lower and upper case)  int
++ti    ISO 8601 format date/time                   datetime
++      e.g. 1972-01-20T10:21:36Z ("T" and "Z"
++      optional)
++te    RFC2822 e-mail format date/time             datetime
++      e.g. Mon, 20 Jan 1972 10:21:36 +1000
++tg    Global (day/month) format date/time         datetime
++      e.g. 20/1/1972 10:21:36 AM +1:00
++ta    US (month/day) format date/time             datetime
++      e.g. 1/20/1972 10:21:36 PM +10:30
++tc    ctime() format date/time                    datetime
++      e.g. Sun Sep 16 01:03:52 1973
++th    HTTP log format date/time                   datetime
++      e.g. 21/Nov/2011:00:07:11 +0000
++ts    Linux system log format date/time           datetime
++      e.g. Nov  9 03:37:44
++tt    Time                                        time
++      e.g. 10:21:36 PM -5:30
++===== =========================================== ========
++
++
++=====================  ==============================================================
++Cardinality            Description
++=====================  ==============================================================
++``?``                   Pattern with cardinality 0..1: optional part (question mark).
++``*``                   Pattern with cardinality zero or more, 0.. (asterisk).
++``+``                   Pattern with cardinality one or more, 1.. (plus sign).
++``{m}``                 Matches ``m`` repetitions of a pattern.
++``{m,n}``               Matches from ``m`` to ``n`` repetitions of a pattern.
++``[A-Za-z]+``           EXAMPLE: Matches one or more alphabetical characters.
++=====================  ==============================================================
++
++
++.. _parse module: https://github.com/r1chardj0n3s/parse
++.. _string.format: https://docs.python.org/3/library/string.html#format-string-syntax
++
++.. _re module: https://docs.python.org/3/library/re.html#module-re
++.. _Python regular expressions: https://docs.python.org/3/library/re.html#module-re
++.. _`regular expressions`: https://en.wikipedia.org/wiki/Regular_expression
++
diff --git a/meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch b/meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch
new file mode 100644
index 000000000..6bdf151fe
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch
@@ -0,0 +1,40 @@
+From f2704149ae1bc11b01b6be854a28f178e20d00e4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 22:08:05 +0100
+Subject: [PATCH] docs: parse_expression, add links to parse_type module and
+ CardinalityField support.
+
+---
+ docs/parse_expressions.rst | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/docs/parse_expressions.rst b/docs/parse_expressions.rst
+index 36ca549..3810222 100644
+--- a/docs/parse_expressions.rst
++++ b/docs/parse_expressions.rst
+@@ -65,6 +65,8 @@ tt    Time                                        time
+       e.g. 10:21:36 PM -5:30
+ ===== =========================================== ========
+ 
++If `parse_type`_ module is used, the cardinality of a type can be specified, too
++(by using the `CardinalityField`_ support):
+ 
+ =====================  ==============================================================
+ Cardinality            Description
+@@ -72,14 +74,13 @@ Cardinality            Description
+ ``?``                   Pattern with cardinality 0..1: optional part (question mark).
+ ``*``                   Pattern with cardinality zero or more, 0.. (asterisk).
+ ``+``                   Pattern with cardinality one or more, 1.. (plus sign).
+-``{m}``                 Matches ``m`` repetitions of a pattern.
+-``{m,n}``               Matches from ``m`` to ``n`` repetitions of a pattern.
+-``[A-Za-z]+``           EXAMPLE: Matches one or more alphabetical characters.
+ =====================  ==============================================================
+ 
+ 
+ .. _parse module: https://github.com/r1chardj0n3s/parse
++.. _parse_type: https://github.com/jenisys/parse_type
+ .. _string.format: https://docs.python.org/3/library/string.html#format-string-syntax
++.. _CardinalityField: https://github.com/jenisys/parse_type/blob/master/README.rst#extended-parser-with-cardinalityfield-support
+ 
+ .. _re module: https://docs.python.org/3/library/re.html#module-re
+ .. _Python regular expressions: https://docs.python.org/3/library/re.html#module-re
diff --git a/meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch b/meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch
new file mode 100644
index 000000000..e71056e1f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch
@@ -0,0 +1,65 @@
+From 95812437eba0154b91108890dd53aab9615f7860 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 19 Dec 2019 12:31:47 +0100
+Subject: [PATCH] BUMP-VERSION: 1.2.7.dev2 (was: 1.2.7.dev1)
+
+---
+ .bumpversion.cfg  | 2 +-
+ VERSION.txt       | 2 +-
+ behave/version.py | 2 +-
+ pytest.ini        | 2 +-
+ setup.py          | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/.bumpversion.cfg b/.bumpversion.cfg
+index a5d3d2f..4f2bb76 100644
+--- a/.bumpversion.cfg
++++ b/.bumpversion.cfg
+@@ -1,5 +1,5 @@
+ [bumpversion]
+-current_version = 1.2.7.dev1
++current_version = 1.2.7.dev2
+ files = behave/version.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
+ parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<drop>\w*)
+ serialize = {major}.{minor}.{patch}{drop}
+diff --git a/VERSION.txt b/VERSION.txt
+index c0ef36b..c4e75f6 100644
+--- a/VERSION.txt
++++ b/VERSION.txt
+@@ -1 +1 @@
+-1.2.7.dev1
++1.2.7.dev2
+diff --git a/behave/version.py b/behave/version.py
+index b19cb5e..67f4a41 100644
+--- a/behave/version.py
++++ b/behave/version.py
+@@ -1,2 +1,2 @@
+ # -- BEHAVE-VERSION:
+-VERSION = "1.2.7.dev1"
++VERSION = "1.2.7.dev2"
+diff --git a/pytest.ini b/pytest.ini
+index b9f281a..df2a81f 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -21,7 +21,7 @@ testpaths     = tests
+ python_files  = test_*.py
+ junit_family = xunit2
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+-    --metadata PACKAGE_VERSION 1.2.7.dev1
++    --metadata PACKAGE_VERSION 1.2.7.dev2
+     --html=build/testing/report.html --self-contained-html
+     --junit-xml=build/testing/report.xml
+ markers =
+diff --git a/setup.py b/setup.py
+index 2afc147..23f6654 100644
+--- a/setup.py
++++ b/setup.py
+@@ -55,7 +55,7 @@ def find_packages_by_root_package(where):
+ # -----------------------------------------------------------------------------
+ setup(
+     name="behave",
+-    version="1.2.7.dev1",
++    version="1.2.7.dev2",
+     description="behave is behaviour-driven development, Python style",
+     long_description=description,
+     author="Jens Engel, Benno Rice and Richard Jones",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch b/meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch
new file mode 100644
index 000000000..d244eea22
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch
@@ -0,0 +1,223 @@
+From dcde4bb2e1b32d676bb0ff16de80dfdf7df6b085 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 20 Dec 2019 16:45:46 +0100
+Subject: [PATCH] Gherkin parser: Cleanups related to question in #800
+ (ParseError usage)
+
+---
+ CHANGES.rst                                  |  1 +
+ behave/parser.py                             | 41 +++++++++++++-------
+ features/background.feature                  |  4 +-
+ features/parser.background.sad_cases.feature | 10 ++---
+ features/parser.feature.sad_cases.feature    |  6 +--
+ issue.features/issue0148.feature             |  2 +-
+ 6 files changed, 38 insertions(+), 26 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index ba4daad..5653492 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -44,6 +44,7 @@ FIXED:
+ 
+ MINOR:
+ 
++* issue #800: Cleanups related to Gherkin parser/ParseError question (submitted by: otstanteplz)
+ * pull  #767: FIX: use_fixture_by_tag didn't return the actual fixture in all cases (provided by: jgentil)
+ * pull  #751: gherkin: Adding Rule keyword translation in portuguese and spanish to gherkin-languages.json (provided by: dunossauro)
+ * pull  #660: Fix minor typos (provided by: rrueth)
+diff --git a/behave/parser.py b/behave/parser.py
+index 520f678..58c68be 100644
+--- a/behave/parser.py
++++ b/behave/parser.py
+@@ -132,13 +132,24 @@ def parse_tags(text):
+ 
+ 
+ class ParserError(Exception):
+-    def __init__(self, message, line, filename=None, line_text=None):
+-        if line:
+-            message += u" at line %d" % line
+-            if line_text:
+-                message += u': "%s"' % line_text.strip()
++    @staticmethod
++    def make_annotated(message, line_number, line_text=None, reason=None):
++        """Make annotated message enriched w/ line_number, line_text."""
++        if line_number:
++            message += u" at line %d" % line_number
++        if line_text:
++            message += u': "%s"' % line_text.strip()
++        if reason:
++            message += u"\nREASON: %s" % reason
++        return message
++
++    def __init__(self, message, line, filename=None, line_text=None,
++                 reason=None, use_annotated_message=True):
++        if use_annotated_message:
++            message = self.make_annotated(message, line, line_text, reason)
++
+         super(ParserError, self).__init__(message)
+-        self.line = line
++        self.line = line    # Line number of parse failure.
+         self.line_text = line_text
+         self.filename = filename
+ 
+@@ -386,14 +397,13 @@ class Parser(object):
+             line = line.strip()
+             msg = u"Parser in unknown state %s;" % self.state
+             raise ParserError(msg, self.line, self.filename, line)
++
+         if not func(line):
+             line = line.strip()
+-            msg = u'\nParser failure in state %s, at line %d: "%s"\n' % \
+-                  (self.state, self.line, line)
++            msg = u'\nParser failure in state=%s' % self.state
+             reason = self.ask_parse_failure_oracle(line)
+-            if reason:
+-                msg += u"REASON: %s" % reason
+-            raise ParserError(msg, None, self.filename)
++            raise ParserError(msg, self.line, self.filename,
++                              line_text=line, reason=reason)
+ 
+     def action_init(self, line):
+         line = line.strip()
+@@ -642,7 +652,7 @@ class Parser(object):
+             self.table = model.Table(cells, self.line)
+         else:
+             if len(cells) != len(self.table.headings):
+-                raise ParserError(u"Malformed table", self.line)
++                raise ParserError(u"Malformed table", self.line, self.filename)
+                 # MAYBE: self.filename)
+             self.table.add_row(cells, self.line)
+         return True
+@@ -704,8 +714,8 @@ class Parser(object):
+                 break   # -- COMMENT: Skip rest of line.
+             else:
+                 # -- BAD-TAG: Abort here.
+-                raise ParserError(u"tag: %s (line: %s)" % (word, line),
+-                                  self.line, self.filename)
++                message = u"tag: %s (line: %s)" % (word, line)
++                raise ParserError(message, self.line, self.filename)
+         return tags
+ 
+     def parse_step(self, line):
+@@ -723,7 +733,8 @@ class Parser(object):
+                 step_text_after_keyword = line[len(kw):].strip()
+                 if step_type in ("and", "but"):
+                     if not self.last_step:
+-                        raise ParserError(u"No previous step", self.line)
++                        raise ParserError(u"No previous step",
++                                          self.line, self.filename)
+                     step_type = self.last_step
+                 else:
+                     self.last_step = step_type
+diff --git a/features/background.feature b/features/background.feature
+index b2f5833..65c4882 100644
+--- a/features/background.feature
++++ b/features/background.feature
+@@ -362,7 +362,7 @@ Feature: Background
+     When I run "behave -f plain -T features/background_sad_example1.feature"
+     Then it should fail with:
+         """
+-        Parser failure in state steps, at line 5: "Background: B1"
++        Parser failure in state=steps at line 5: "Background: B1"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -387,6 +387,6 @@ Feature: Background
+     When I run "behave -f plain -T features/background_sad_example2.feature"
+     Then it should fail with:
+         """
+-        Parser failure in state steps, at line 5: "Background: B2 (XFAIL)"
++        Parser failure in state=steps at line 5: "Background: B2 (XFAIL)"
+         REASON: Background should not be used here.
+         """
+diff --git a/features/parser.background.sad_cases.feature b/features/parser.background.sad_cases.feature
+index 37956ad..eb234ae 100644
+--- a/features/parser.background.sad_cases.feature
++++ b/features/parser.background.sad_cases.feature
+@@ -37,7 +37,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       Then it should fail with
+         """
+         Failed to parse "{__WORKDIR__}/features/syndrome.background_with_tags.feature":
+-        Parser failure in state taggable_statement, at line 4: "Background: Oops..."
++        Parser failure in state=taggable_statement at line 4: "Background: Oops..."
+         REASON: Background does not support tags.
+         """
+ 
+@@ -57,7 +57,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       Then it should fail with
+         """
+         Failed to parse "{__WORKDIR__}/features/syndrome.background_after_scenario.feature":
+-        Parser failure in state steps, at line 6: "Background: Oops, too late (after Scenario)"
++        Parser failure in state=steps at line 6: "Background: Oops, too late (after Scenario)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -77,7 +77,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       When I run "behave -f plain -T features/syndrome.tagged_background_after_scenario.feature"
+       Then it should fail with
+         """
+-        Parser failure in state taggable_statement, at line 7: "Background: Oops, too late (after Scenario)"
++        Parser failure in state=taggable_statement at line 7: "Background: Oops, too late (after Scenario)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -100,7 +100,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       When I run "behave -f plain -T features/syndrome.background_after_scenario_outline.feature"
+       Then it should fail with
+         """
+-        Parser failure in state steps, at line 10: "Background: Oops, too late (after Scenario Outline)"
++        Parser failure in state=steps at line 10: "Background: Oops, too late (after Scenario Outline)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -124,6 +124,6 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       When I run "behave -f plain -T features/syndrome.background_after_scenario_outline.feature"
+       Then it should fail with
+         """
+-        Parser failure in state taggable_statement, at line 11: "Background: Oops, too late (after Scenario Outline)"
++        Parser failure in state=taggable_statement at line 11: "Background: Oops, too late (after Scenario Outline)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+diff --git a/features/parser.feature.sad_cases.feature b/features/parser.feature.sad_cases.feature
+index d89d9b7..0e12d9f 100644
+--- a/features/parser.feature.sad_cases.feature
++++ b/features/parser.feature.sad_cases.feature
+@@ -84,7 +84,7 @@ Feature: Parsing a Feature File without a Feature or with several Features
+       Then it should fail with:
+         """
+         Failed to parse "{__WORKDIR__}/features/only_text.feature":
+-        Parser failure in state init, at line 1: "This File: Contains only text without keywords."
++        Parser failure in state=init at line 1: "This File: Contains only text without keywords."
+         REASON: No feature found.
+         """
+ 
+@@ -103,7 +103,7 @@ Feature: Parsing a Feature File without a Feature or with several Features
+       Then it should fail with:
+         """
+         Failed to parse "{__WORKDIR__}/features/naked_scenario_only.feature":
+-        Parser failure in state init, at line 1: "Scenario:"
++        Parser failure in state=init at line 1: "Scenario:"
+         REASON: Scenario may not occur before Feature.
+         """
+ 
+@@ -139,6 +139,6 @@ Feature: Parsing a Feature File without a Feature or with several Features
+           Then it should fail with:
+             """
+             Failed to parse "{__WORKDIR__}/features/two_features.feature":
+-            Parser failure in state steps, at line 7: "Feature: F2"
++            Parser failure in state=steps at line 7: "Feature: F2"
+             REASON: Multiple features in one file are not supported.
+             """
+diff --git a/issue.features/issue0148.feature b/issue.features/issue0148.feature
+index 4387795..667d196 100644
+--- a/issue.features/issue0148.feature
++++ b/issue.features/issue0148.feature
+@@ -67,7 +67,7 @@ Feature: Issue #148: Substeps do not fail
+     And the command output should contain:
+         """
+         ParserError: Failed to parse <string>:
+-        Parser failure in state steps, at line 2: "I do something stupid"
++        Parser failure in state=steps at line 2: "I do something stupid"
+         """
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch b/meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch
new file mode 100644
index 000000000..60e9e9309
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch
@@ -0,0 +1,82 @@
+From 230b5bf8184beb02a3fa2678def7f11acf916e37 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Feb 2020 20:30:53 +0100
+Subject: [PATCH] Clarify select-by-name uses regex pattern (related to: issue
+ #810)
+
+Clarifiy select-by-name uses regex pattern:
+
+* Adapt command-line option --name help text
+* Update command-line args docs for behave
+---
+ CHANGES.rst             |  4 ++++
+ behave/configuration.py | 10 +++++-----
+ docs/behave.rst         | 12 ++++++------
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 5653492..d0bf6fd 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -31,6 +31,10 @@ ENHANCEMENTS:
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ 
++CLARIFICATION:
++
++* issue #810: Clarify select-by-name using regex pattern (submitted by: xv-chris-w)
++
+ FIXED:
+ 
+ * issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+diff --git a/behave/configuration.py b/behave/configuration.py
+index bd8b039..65e2e3e 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -164,11 +164,11 @@ options = [
+                   override a configuration file setting.""")),
+ 
+     (("-n", "--name"),
+-     dict(action="append",
+-          help="""Only execute the feature elements which match part
+-                  of the given name. If this option is given more
+-                  than once, it will match against all the given
+-                  names.""")),
++     dict(action="append", metavar="NAME_PATTERN",
++          help="""Select feature elements (scenarios, ...) to run
++                  which match part of the given name (regex pattern).
++                  If this option is given more than once,
++                  it will match against all the given names.""")),
+ 
+     (("--no-capture",),
+      dict(action="store_false", dest="stdout_capture",
+diff --git a/docs/behave.rst b/docs/behave.rst
+index dfb390a..25ce523 100644
+--- a/docs/behave.rst
++++ b/docs/behave.rst
+@@ -95,9 +95,9 @@ You may see the same information presented below at any time using ``behave
+ 
+ .. option:: -n, --name
+ 
+-    Only execute the feature elements which match part of the given name.
+-    If this option is given more than once, it will match against all
+-    the given names.
++    Select feature elements (scenarios, ...) to run which match part of
++    the given name (regex pattern). If this option is given more than
++    once, it will match against all the given names.
+ 
+ .. option:: --no-capture
+ 
+@@ -449,9 +449,9 @@ Configuration Parameters
+ 
+ .. describe:: name : sequence<text>
+ 
+-    Only execute the feature elements which match part of the given name.
+-    If this option is given more than once, it will match against all
+-    the given names.
++    Select feature elements (scenarios, ...) to run which match part of
++    the given name (regex pattern). If this option is given more than
++    once, it will match against all the given names.
+ 
+ .. index::
+     single: configuration param; stdout_capture
diff --git a/meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch b/meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch
new file mode 100644
index 000000000..bd55ca5f2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch
@@ -0,0 +1,34 @@
+From e55569d0a3fd1aa653fd702705e09359bdd90685 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 13 Apr 2020 10:31:54 +0200
+Subject: [PATCH] FIX: Cross-reference problem (copy+paste) in Rule class
+ docstring.
+
+---
+ behave/model.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/behave/model.py b/behave/model.py
+index f46d2c2..cb69f9e 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -84,8 +84,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+     .. attribute:: keyword
+ 
+-       This is the keyword as seen in the *feature file*. In English this will
+-       be "Feature" or "Rule".
++       This is the keyword as seen in the *feature file*.
++       In English this will be "Feature" or "Rule".
+ 
+     .. attribute:: name
+ 
+@@ -671,7 +671,7 @@ class Rule(ScenarioContainer):
+ 
+ 
+     .. versionadded:: 1.2.7
+-    .. _`feature`: gherkin.html#rule
++    .. _`rule`: gherkin.html#rule
+     """
+     type = "rule"
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch b/meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch
new file mode 100644
index 000000000..da7b2be63
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch
@@ -0,0 +1,195 @@
+From 7b5f6f27a281714c6fef8e609416b7f405e8b1ba Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 13 Apr 2020 10:33:44 +0200
+Subject: [PATCH] DOCS: Update API description for "Runner Operation".
+
+* Provide description Gherkin grammar containments
+* Add description for Rule(s).
+---
+ docs/api.rst | 137 ++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 96 insertions(+), 41 deletions(-)
+
+diff --git a/docs/api.rst b/docs/api.rst
+index 5e4b7b4..39fa755 100644
+--- a/docs/api.rst
++++ b/docs/api.rst
+@@ -196,24 +196,34 @@ Environment File Functions
+ The environment.py module may define code to run before and after certain
+ events during your testing:
+ 
+-**before_step(context, step), after_step(context, step)**
+-  These run before and after every step. The step passed in is an instance
+-  of :class:`~behave.model.Step`.
++**before_all(context), after_all(context)**
++  These run before and after the whole shooting match.
++
++**before_feature(context, feature), after_feature(context, feature)**
++  These run before and after each feature is executed.
++  The feature object, that is passed in, is an instance of :class:`~behave.model.Feature`.
++
++**before_rule(context, rule), after_rule(context, rule)**
++  These run before and after each rule is execured.
++  The rule object, that is passed in, is an instance of :class:`~behave.model.Rule`.
+ 
+ **before_scenario(context, scenario), after_scenario(context, scenario)**
+-  These run before and after each scenario is run. The scenario passed in is an
+-  instance of :class:`~behave.model.Scenario`.
++  These run before and after each scenario is run.
++  The scenario object, that is passed in, is an instance of :class:`~behave.model.Scenario`.
+ 
+-**before_feature(context, feature), after_feature(context, feature)**
+-  These run before and after each feature file is exercised. The feature
+-  passed in is an instance of :class:`~behave.model.Feature`.
++**before_step(context, step), after_step(context, step)**
++  These run before and after every step.
++  The step object, that is passed in, is an instance of :class:`~behave.model.Step`.
+ 
+ **before_tag(context, tag), after_tag(context, tag)**
+   These run before and after a section tagged with the given name. They are
+   invoked for each tag encountered in the order they're found in the
+-  feature file. See  :ref:`controlling things with tags`. The tag passed in is
+-  an instance of :class:`~behave.model.Tag` and because it's a subclass of
+-  string you can do simple tests like:
++  feature file. See  :ref:`controlling things with tags`.
++
++  Taggable statements are: Feature, Rule, Scenario, ScenarioOutline, Examples.
++
++  The tag, that is passed in, is an instance of :class:`~behave.model.Tag` and
++  because it's a subclass of string you can do simple tests like:
+ 
+   .. code-block:: python
+ 
+@@ -227,8 +237,6 @@ events during your testing:
+               else:
+                   context.browser = webdriver.PlainVanilla()
+ 
+-**before_all(context), after_all(context)**
+-  These run before and after the whole shooting match.
+ 
+ 
+ Some Useful Environment Ideas
+@@ -311,42 +319,87 @@ Use Fixtures
+ Runner Operation
+ ================
+ 
+-Given all the code that could be run by *behave*, this is the order in
+-which that code is invoked (if they exist.)
++The execution of code is based on the Gherkin description in `*.feature` files.
++The following section provides a short overview of the hierarchical containment
++that is possible in the Gherkin grammer:
+ 
+ .. parsed-literal::
+ 
+-    before_all
+-    for feature in all_features:
+-        before_feature
+-        for scenario in feature.scenarios:
+-            before_scenario
+-            for step in scenario.steps:
+-                before_step
+-                    step.run()
+-                after_step
+-            after_scenario
+-        after_feature
+-    after_all
++    # -- SIMPLIFIED GHERKIN GRAMMAR (for Gherkin v6):
++    # CARDINALITY DECORATOR: '*' means 0..N (many), '?' means 0..1 (optional)
++    # EXAMPLE: Feature
++    #   A Feature can have many Tags (as TaggableStatement: zero or more tags before its keyword).
++    #   A Feature can have an optional Background.
++    #   A Feature can have many Scenario(s), meaning zero or more Scenarios.
++    #   A Feature can have many ScenarioOutline(s).
++    #   A Feature can have many Rule(s).
++    Feature(TaggableStatement):
++        Background?
++        Scenario*
++        ScenarioOutline*
++        Rule*
++
++    Background:
++        Step*           # Background steps are injected into any Scenario of its scope.
++
++    Scenario(TaggableStatement):
++        Step*
+ 
+-If the feature contains scenario outlines then there is an additional loop
+-over all the scenarios in the outline making the running look like this:
++    ScenarioOutline(ScenarioTemplateWithPlaceholders):
++        Scenario*       # Rendered Template by using ScenarioOutline.Examples.rows placeholder values.
++
++    Rule(TaggableStatement):
++        Background?     # Behave-specific extension (after removal from final Gherkin v6).
++        Scenario*
++        ScenarioOutline*
++
++
++Given all the code that could be run by *behave*,
++this is the order in which that code is invoked (if they exist.)
+ 
+ .. parsed-literal::
+ 
+-    before_all
++    # -- PSEUDO-CODE:
++    # HOOK: before_tag(), after_tag() is called for Feature, Rule, Scenario
++    ctx = createContext()
++    call-optional-hook before_all(ctx)
+     for feature in all_features:
+-        before_feature
+-        for outline in feature.scenarios:
+-            for scenario in outline.scenarios:
+-                before_scenario
+-                for step in scenario.steps:
+-                    before_step
+-                        step.run()
+-                    after_step
+-                after_scenario
+-        after_feature
+-    after_all
++        for tag in feature.tags: call-optional-hook before_tag(ctx, tag)
++        call-optional-hook before_feature(ctx, feature)
++        for run_item in feature.run_items:  # CAN BE: Rule, Scenario, ScenarioOutline
++            execute_run_item(ctx, run_item)
++        call-optional-hook after_feature(ctx, feature)
++        for tag in feature.tags: call-optional-hook after_tag(ctx, tag)
++    call-optional-hook after_all(ctx)
++
++    function execute_run_item(run_item, ctx):
++        if run_item isa Rule:
++            # -- CASE: Rule
++            rule = run_item
++            for tag in rule.tags: call-optional-hook before_tag(ctx, tag)
++            call-optional-hook before_rule(ctx, rule)
++            for run_item in rule.run_items:     # CAN BE: Scenario, ScenarioOutline
++                execute_run_item(run_item, ctx)
++            call-optional-hook after_rule(ctx, rule)
++            for tag in rule.tags: call-optional-hook after_tag(ctx, tag)
++        else if run_item isa ScenarioOutline:
++            # -- CASE: ScenarioOutline
++            # HINT: All Scenarios are already created from Example(s) rows.
++            scenario_outline = run_item
++            for scenario in scenario_outline.scenarios:
++                execute_run_item(scenario, ctx)
++        else if run_item isa Scenario:
++            # -- CASE: Scenario
++            # HINT: Background steps are injected before scenario steps.
++            scenario = run_item
++            for tag in scenario.tags: call-optional-hook before_tag(ctx, tag)
++            call-optional-hook before_scenario(ctx, scenario)
++            for step in scenario.steps:
++                call-optional-hook before_step(ctx, step)
++                step.run(ctx)
++                call-optional-hook after_step(ctx, step)
++            call-optional-hook after_scenario(ctx, scenario)
++            for tag in scenario.tags: call-optional-hook after_tag(ctx, tag)
+ 
+ 
+ Model Objects
+@@ -397,6 +450,8 @@ be:
+ 
+ .. autoclass:: behave.model.Feature
+ 
++.. autoclass:: behave.model.Rule
++
+ .. autoclass:: behave.model.Background
+ 
+ .. autoclass:: behave.model.Scenario
diff --git a/meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch b/meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch
new file mode 100644
index 000000000..3b6b83a1b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch
@@ -0,0 +1,22 @@
+From 07ad7958eab96a4dadae514f7f963fa73d356191 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 13 Apr 2020 10:38:17 +0200
+Subject: [PATCH] FIX DOCS: Runner operations typo.
+
+---
+ docs/api.rst | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/docs/api.rst b/docs/api.rst
+index 39fa755..4763ad6 100644
+--- a/docs/api.rst
++++ b/docs/api.rst
+@@ -367,7 +367,7 @@ this is the order in which that code is invoked (if they exist.)
+         for tag in feature.tags: call-optional-hook before_tag(ctx, tag)
+         call-optional-hook before_feature(ctx, feature)
+         for run_item in feature.run_items:  # CAN BE: Rule, Scenario, ScenarioOutline
+-            execute_run_item(ctx, run_item)
++            execute_run_item(run_item, ctx)
+         call-optional-hook after_feature(ctx, feature)
+         for tag in feature.tags: call-optional-hook after_tag(ctx, tag)
+     call-optional-hook after_all(ctx)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch b/meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch
new file mode 100644
index 000000000..843f53113
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch
@@ -0,0 +1,295 @@
+From 2cf10215b5e8fcbb9162bde48456b60786d828cf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 23 Sep 2020 23:22:45 +0200
+Subject: [PATCH] issue #740: Enhancement: Context.add_cleanup() with
+ layer-name
+
+Context.add_cleanup() can choose which cleanup layer to use (outer layer).
+This provides the possibility that a cleanup-funcion, registered with
+Context.add_cleanup(cleanup_func, ...) to be called upon leaving
+the outer context stack frames.
+
+Submitted by: nizwiz
+Requested by: dcvmoole
+---
+ CHANGES.rst                         |  7 +++
+ behave/model.py                     |  4 +-
+ behave/runner.py                    | 45 ++++++++++++---
+ tests/unit/test_context_cleanups.py | 86 ++++++++++++++++++++++++++++-
+ 4 files changed, 130 insertions(+), 12 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d0bf6fd..d758364 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -28,6 +28,7 @@ ENHANCEMENTS:
+ * Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Support emojis in ``*.feature`` files and steps
+ * Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
++* issue #740: Enhancement: possibility to add cleanup to be called upon leaving outer context stack frames (submitted by: nizwiz, dcvmoole)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ 
+@@ -65,6 +66,12 @@ DOCUMENTATION:
+ * pull  #684: Fix typo in "install.rst" (provided by: mstred)
+ * pull  #628: Changed pythonhosted.org links to readthedocs.io (provided by: chrisbrake)
+ 
++BREAKING CHANGES (naming):
++
++* behave.runner.Context._push(layer=None): Was Context._push(layer_name=None)
++* behave.runner.scoped_context_layer(context, layer=None):
++  Was scoped_context_layer(context.layer_name=None)
++
+ 
+ .. _`cucumber-tag-expressions`: https://pypi.org/project/cucumber-tag-expressions/
+ 
+diff --git a/behave/model.py b/behave/model.py
+index cb69f9e..f1ec725 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -363,7 +363,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         hook_before_entity = "before_{0}".format(entity_name)
+         hook_after_entity = "after_{0}".format(entity_name)
+ 
+-        runner.context._push(layer_name=entity_name)      # pylint: disable=protected-access
++        runner.context._push(layer=entity_name)      # pylint: disable=protected-access
+         runner.context.tags = set(self.tags)
+         self._setup_context_for_run(runner.context)
+ 
+@@ -1136,7 +1136,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+         dry_run_scenario = run_scenario and runner.config.dry_run
+         self.was_dry_run = dry_run_scenario
+ 
+-        runner.context._push(layer_name="scenario")      # pylint: disable=protected-access
++        runner.context._push(layer="scenario")      # pylint: disable=protected-access
+         runner.context.scenario = self
+         runner.context.tags = set(self.effective_tags)
+ 
+diff --git a/behave/runner.py b/behave/runner.py
+index 6b20937..d01bff0 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -145,7 +145,7 @@ class Context(object):
+     tries to overwrite a user-set variable.
+ 
+     You may use the "in" operator to test whether a certain value has been set
+-    on the context, for example:
++    on the context, for example::
+ 
+         "feature" in context
+ 
+@@ -158,6 +158,7 @@ class Context(object):
+     .. _`configuration file section names`: behave.html#configuration-files
+     """
+     # pylint: disable=too-many-instance-attributes
++    LAYER_NAMES = ["testrun", "feature", "rule", "scenario"]
+     FAIL_ON_CLEANUP_ERRORS = True
+ 
+     def __init__(self, runner):
+@@ -245,16 +246,15 @@ class Context(object):
+             del cleanup_errors  # -- ENSURE: Release other exception frames.
+             six.reraise(*first_cleanup_erro_info)
+ 
+-
+-    def _push(self, layer_name=None):
++    def _push(self, layer=None):
+         """Push a new layer on the context stack.
+-        HINT: Use layer_name values: "scenario", "feature", "testrun".
++        HINT: Use layer values: "testrun", "feature", "rule, "scenario".
+ 
+-        :param layer_name:   Layer name to use (or None).
++        :param layer:   Layer name to use (or None).
+         """
+         initial_data = {"@cleanups": []}
+-        if layer_name:
+-            initial_data["@layer"] = layer_name
++        if layer:
++            initial_data["@layer"] = layer
+         self._stack.insert(0, initial_data)
+ 
+     def _pop(self):
+@@ -426,6 +426,20 @@ class Context(object):
+             self.text = original_text
+         return True
+ 
++    def _select_stack_frame_by_layer(self, layer):
++        """Select context stack frame by layer name.
++
++        :param layer:   Layer name (as string).
++        :return: Selected frame object (if any)
++        :raises: LookupError, if layer was not found.
++        """
++        for frame in self._stack:
++            frame_layer = frame.get("@layer", None)
++            if layer == frame_layer:
++                return frame
++        # -- OOPS, NOT FOUND:
++        raise LookupError("Context.stack: layer=%s not found" % layer)
++
+     def add_cleanup(self, cleanup_func, *args, **kwargs):
+         """Adds a cleanup function that is called when :meth:`Context._pop()`
+         is called. This is intended for user-cleanups.
+@@ -433,10 +447,21 @@ class Context(object):
+         :param cleanup_func:    Callable function
+         :param args:            Args for cleanup_func() call (optional).
+         :param kwargs:          Kwargs for cleanup_func() call (optional).
++
++        .. note:: RESERVED :obj:`layer` : optional-string
++
++            The keyword argument ``layer="LAYER_NAME"`` can to be used to
++            assign the :obj:`cleanup_func` to specific a layer on the context stack
++            (instead of the current layer).
++
++            Known layer names are: "testrun", "feature", "rule", "scenario"
++
++        .. seealso:: :attr:`.Context.LAYER_NAMES`
+         """
+         # MAYBE:
+         assert callable(cleanup_func), "REQUIRES: callable(cleanup_func)"
+         assert self._stack
++        layer = kwargs.pop("layer", None)
+         if args or kwargs:
+             def internal_cleanup_func():
+                 cleanup_func(*args, **kwargs)
+@@ -444,6 +469,8 @@ class Context(object):
+             internal_cleanup_func = cleanup_func
+ 
+         current_frame = self._stack[0]
++        if layer:
++            current_frame = self._select_stack_frame_by_layer(layer)
+         if cleanup_func not in current_frame["@cleanups"]:
+             # -- AVOID DUPLICATES:
+             current_frame["@cleanups"].append(internal_cleanup_func)
+@@ -477,7 +504,7 @@ def use_context_with_mode(context, mode):
+ 
+ 
+ @contextlib.contextmanager
+-def scoped_context_layer(context, layer_name=None):
++def scoped_context_layer(context, layer=None):
+     """Provides context manager for context layer (push/do-something/pop cycle).
+ 
+     .. code-block::
+@@ -487,7 +514,7 @@ def scoped_context_layer(context, layer_name=None):
+     """
+     # pylint: disable=protected-access
+     try:
+-        context._push(layer_name)
++        context._push(layer)
+         yield context
+     finally:
+         context._pop()
+diff --git a/tests/unit/test_context_cleanups.py b/tests/unit/test_context_cleanups.py
+index bf0ab50..c32c572 100644
+--- a/tests/unit/test_context_cleanups.py
++++ b/tests/unit/test_context_cleanups.py
+@@ -23,6 +23,9 @@ import pytest
+ def cleanup_func():
+     pass
+ 
++def cleanup_func_with_args(*args, **kwargs):
++    pass
++
+ class CleanupFunction(object):
+     def __init__(self, name="CLEANUP-FUNC", listener=None):
+         self.name = name
+@@ -42,7 +45,6 @@ class CallListener(object):
+         self.collected.append(message)
+ 
+ 
+-
+ # ------------------------------------------------------------------------------
+ # TESTS:
+ # ------------------------------------------------------------------------------
+@@ -145,6 +147,24 @@ class TestContextCleanup(object):
+         my_cleanup_B2M.assert_called_once()
+         my_cleanup_B3M.assert_called_once()
+ 
++    def test_add_cleanup_with_args(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context):
++            context.add_cleanup(my_cleanup, 1, 2, 3)
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(1, 2, 3)
++
++    def test_add_cleanup_with_args_and_kwargs(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context):
++            context.add_cleanup(my_cleanup, 1, 2, 3, name="alice")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(1, 2, 3, name="alice")
++
+     def test_add_cleanup__rejects_noncallable_cleanup_func(self):
+         class NonCallable(object): pass
+         non_callable = NonCallable()
+@@ -218,3 +238,67 @@ class TestContextCleanup(object):
+         assert collect_cleanup_error.collected[0][:-1] == expected[0][:-1]
+         assert collect_cleanup_error.collected[1][:-1] == expected[1][:-1]
+ 
++
++class TestContextCleanupWithLayer(object):
++    """Tests :meth:`behave.runner.Context.add_cleanup()`
++    with layer parameter.
++
++    :meth:`cleanup_func()` is called when Context layer is removed/popped.
++    """
++
++    def test_add_cleanup_with_known_layer(self):
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="scenario"):
++            context.add_cleanup(my_cleanup, layer="scenario")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once()
++
++    def test_add_cleanup_with_known_layer_and_args(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="scenario"):
++            context.add_cleanup(my_cleanup, 1, 2, 3, layer="scenario")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(1, 2, 3)
++
++    def test_add_cleanup_with_known_layer_and_kwargs(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="scenario"):
++            context.add_cleanup(my_cleanup, layer="scenario", name="alice")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(name="alice")
++
++    def test_add_cleanup_with_known_deeper_layer2(self):
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="feature"):
++            with scoped_context_layer(context, layer="scenario"):
++                context.add_cleanup(my_cleanup, layer="feature")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once()
++
++    def test_add_cleanup_with_known_deeper_layer3(self):
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="testrun"):
++            with scoped_context_layer(context, layer="feature"):
++                with scoped_context_layer(context, layer="scenario"):
++                    context.add_cleanup(my_cleanup, layer="feature")
++                my_cleanup.assert_not_called()
++            my_cleanup.assert_called_once()     # LEFT: layer="feature"
++        my_cleanup.assert_called_once()
++
++    def test_add_cleanup_with_unknown_layer_raises_lookup_error(self):
++        """Cleanup function is not registered"""
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context):   # CALLS-HERE: context._push()
++            with pytest.raises(LookupError) as error:
++                context.add_cleanup(my_cleanup, layer="other")
++        my_cleanup.assert_not_called()
diff --git a/meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch b/meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch
new file mode 100644
index 000000000..d03a7ccae
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch
@@ -0,0 +1,37 @@
+From a53e82fa963696988c743aaca2341390332e7e3b Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 20 Oct 2020 22:40:46 +0200
+Subject: [PATCH] UPDATE: parse >= 1.18.0 (parse versions: 1.16.0 .. 1.17.x has
+ a problem; parse issue #119, #121)
+
+---
+ py.requirements/basic.txt | 2 +-
+ setup.py                  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index ad5b9a6..f976748 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -9,7 +9,7 @@
+ # ============================================================================
+ 
+ cucumber-tag-expressions >= 1.1.2
+-parse >= 1.8.2
++parse >= 1.18.0
+ parse_type >= 0.4.2
+ six >= 1.12.0
+ 
+diff --git a/setup.py b/setup.py
+index 23f6654..fd89bda 100644
+--- a/setup.py
++++ b/setup.py
+@@ -77,7 +77,7 @@ setup(
+     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*",
+     install_requires=[
+         "cucumber-tag-expressions >= 1.1.2",
+-        "parse >= 1.9.1",
++        "parse >= 1.18.0",
+         "parse_type >= 0.4.2",
+         "six >= 1.12.0",
+         "traceback2; python_version < '3.0'",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch b/meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch
new file mode 100644
index 000000000..32304e345
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch
@@ -0,0 +1,34 @@
+From fb3f43735f7c9b8363940595d12d7b59544f64c0 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 2 Nov 2020 17:50:10 +0100
+Subject: [PATCH] RELATED TO: Duplicated steps/AmbiguousStepErrors
+
+* Remove @xfail from third scenario (it worked already for some time).
+* Added more detailled description to third scenario.
+---
+ features/step.duplicated_step.feature | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/features/step.duplicated_step.feature b/features/step.duplicated_step.feature
+index 396cca2..f204307 100644
+--- a/features/step.duplicated_step.feature
++++ b/features/step.duplicated_step.feature
+@@ -76,8 +76,17 @@ Feature: Duplicated Step Definitions
+     #    File "features/steps/bob2_steps.py", line 3, in <module>
+     #    """
+ 
+-  @xfail
++
+   Scenario: Duplicated Same Step Definition via import from another File
++
++    VERIFY THAT: Duplicated step-detection works.
++    Duplicated step-registration occured through a twice imported step-module:
++    First registration may occurs by step-loading the step-module,
++    second registration due to import of first step-module.
++
++    The step registry detects that the same step-function should be registered
++    another time and ignores it (step is already registered).
++
+     Given a new working directory
+     And a file named "features/steps/charly1_steps.py" with:
+       """
diff --git a/meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch b/meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch
new file mode 100644
index 000000000..8b0f22d8f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch
@@ -0,0 +1,21 @@
+From d65b38953bfe1cc346a2548a8e617229df87058b Mon Sep 17 00:00:00 2001
+From: Renovate Bot <bot@renovateapp.com>
+Date: Wed, 4 Nov 2020 08:43:32 +0000
+Subject: [PATCH] Add renovate.json
+
+---
+ renovate.json | 5 +++++
+ 1 file changed, 5 insertions(+)
+ create mode 100644 renovate.json
+
+diff --git a/renovate.json b/renovate.json
+new file mode 100644
+index 0000000..f45d8f1
+--- /dev/null
++++ b/renovate.json
+@@ -0,0 +1,5 @@
++{
++  "extends": [
++    "config:base"
++  ]
++}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch b/meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch
new file mode 100644
index 000000000..39a6d76c2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch
@@ -0,0 +1,175 @@
+From 61f3a341b7accd0580af7c7b2e8db4cb6a7f4bec Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 10:28:59 +0100
+Subject: [PATCH] PRPEPARE-RENOVATE: With adaptions
+
+* Provide locations/patterns for pip requirements file(s)
+* Move "renovate.json" to ".github/"
+---
+ .github/renovate.json                         | 13 ++++++++
+ MANIFEST.in                                   |  4 +--
+ issue.features/README.rst                     | 32 +++++++++++++++++++
+ issue.features/README.txt                     | 17 ----------
+ .../{requirements.txt => py.requirements.txt} |  7 ++--
+ py.requirements/{README.txt => README.rst}    |  0
+ py.requirements/testing.txt                   |  4 ++-
+ renovate.json                                 |  5 ---
+ 8 files changed, 53 insertions(+), 29 deletions(-)
+ create mode 100644 .github/renovate.json
+ create mode 100644 issue.features/README.rst
+ delete mode 100644 issue.features/README.txt
+ rename issue.features/{requirements.txt => py.requirements.txt} (82%)
+ rename py.requirements/{README.txt => README.rst} (100%)
+ delete mode 100644 renovate.json
+
+diff --git a/.github/renovate.json b/.github/renovate.json
+new file mode 100644
+index 0000000..3399a00
+--- /dev/null
++++ b/.github/renovate.json
+@@ -0,0 +1,13 @@
++{
++  "extends": [
++    "config:base"
++  ],
++  "pip_requirements": {
++    "fileMatch": [
++        "py.requirements/all.txt",
++        "py.requirements/*.txt",
++        "tasks/py.requirements.txt",
++        "issue.features/py.requirements.txt"
++    ]
++}
++}
+diff --git a/MANIFEST.in b/MANIFEST.in
+index 60c2601..84d20f4 100644
+--- a/MANIFEST.in
++++ b/MANIFEST.in
+@@ -28,8 +28,8 @@ recursive-include tasks         *.py *.zip *.txt *.rst
+ recursive-include tools         *.feature *.py *.yml *.sh
+ recursive-include features      *.feature *.py *.txt
+ recursive-include issue.features  *.feature *.py *.txt
+-recursive-include more.features *.feature *.py *.txt
+-recursive-include py.requirements  *.txt
++recursive-include more.features *.feature *.py *.txt *.rst
++recursive-include py.requirements  *.txt *.rst
+ 
+ prune .tox
+ prune .venv*
+diff --git a/issue.features/README.rst b/issue.features/README.rst
+new file mode 100644
+index 0000000..1d1d980
+--- /dev/null
++++ b/issue.features/README.rst
+@@ -0,0 +1,32 @@
++issue.features:
++===============================================================================
++
++:Requires: Python >= 2.7 or Python >= 3.5
++
++This directory contains behave self-tests to ensure that behave related
++issues are fixed.
++
++PROCEDURE:
++
++    * ONCE: Install python requirements ("py.requirements.txt")
++    * Run the tests with behave
++
++.. code-block:: shell
++
++    # -- FOR:
++    # pip:  For python2.7 or python3 (depends on platform and/or user))
++    # pip3: For python3
++    pip  install -U -r issue.features/testing.txt
++    pip3 install -U -r issue.features/testing.txt
++
++
++ALTERNATIVE:
++
++.. code-block:: shell
++
++    pip  install -U -r py.requirements/testing.txt
++    pip3 install -U -r py.requirements/testing.txt
++
++.. code-block:: shell
++
++    bin/behave -f progress issue.features/
+diff --git a/issue.features/README.txt b/issue.features/README.txt
+deleted file mode 100644
+index af499f3..0000000
+--- a/issue.features/README.txt
++++ /dev/null
+@@ -1,17 +0,0 @@
+-issue.features:
+-===============================================================================
+-
+-:Status:   PREPARED (fixes are being applied).
+-:Requires: Python >= 2.6 (due to step implementations)
+-
+-This directory contains behave self-tests to ensure that behave related
+-issues are fixed.
+-
+-PROCEDURE:
+-
+-    * ONCE: Install python requirements ("requirements.txt")
+-    * Run the tests with behave
+-
+-::
+-
+-    bin/behave -f progress issue.features/
+diff --git a/issue.features/requirements.txt b/issue.features/py.requirements.txt
+similarity index 82%
+rename from issue.features/requirements.txt
+rename to issue.features/py.requirements.txt
+index d0c4bab..f0def9d 100644
+--- a/issue.features/requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -1,12 +1,11 @@
+ # ============================================================================
+ # PYTHON PACKAGE REQUIREMENTS: For running issue.features/
+ # ============================================================================
+-# REQUIRES: Python >= 2.5
+-# REQUIRES: Python >= 3.2
++# REQUIRES: Python >= 2.7
++# REQUIRES: Python >= 3.5
+ # DESCRIPTION:
+ #    pip install -r <THIS_FILE>
+ #
+ # ============================================================================
+ 
+-PyHamcrest >= 1.6
+-
++PyHamcrest >= 2.0.2
+diff --git a/py.requirements/README.txt b/py.requirements/README.rst
+similarity index 100%
+rename from py.requirements/README.txt
+rename to py.requirements/README.rst
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 85b0908..5ccdda8 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -8,10 +8,12 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+-PyHamcrest >= 1.9
++PyHamcrest >= 2.0.2
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+ # HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
++
++-r ../issue.features/py.requirements.txt
+diff --git a/renovate.json b/renovate.json
+deleted file mode 100644
+index f45d8f1..0000000
+--- a/renovate.json
++++ /dev/null
+@@ -1,5 +0,0 @@
+-{
+-  "extends": [
+-    "config:base"
+-  ]
+-}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch b/meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch
new file mode 100644
index 000000000..eeebd7be3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch
@@ -0,0 +1,36 @@
+From 9271668477574b317c72099eab587f516ae082de Mon Sep 17 00:00:00 2001
+From: Renovate Bot <bot@renovateapp.com>
+Date: Wed, 4 Nov 2020 09:32:34 +0000
+Subject: [PATCH] Pin dependencies
+
+---
+ issue.features/py.requirements.txt | 2 +-
+ tasks/py.requirements.txt          | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/issue.features/py.requirements.txt b/issue.features/py.requirements.txt
+index f0def9d..38f452d 100644
+--- a/issue.features/py.requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -8,4 +8,4 @@
+ #
+ # ============================================================================
+ 
+-PyHamcrest >= 2.0.2
++PyHamcrest==2.0.2
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index 810f834..9c82d11 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -8,9 +8,9 @@
+ #  * http://www.pip-installer.org/
+ # ============================================================================
+ 
+-invoke >= 1.2.0
++invoke==1.4.1
+ pycmd
+-six >= 1.12.0
++six==1.15.0
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
diff --git a/meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch b/meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch
new file mode 100644
index 000000000..33ec83848
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch
@@ -0,0 +1,31 @@
+From 85d1f009d933d356e65a548f29e4d5a1e78a72d2 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 10:54:02 +0100
+Subject: [PATCH] renovate: Extend pip requirements file list.
+
+---
+ .github/renovate.json | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/.github/renovate.json b/.github/renovate.json
+index 3399a00..9b72f76 100644
+--- a/.github/renovate.json
++++ b/.github/renovate.json
+@@ -4,10 +4,15 @@
+   ],
+   "pip_requirements": {
+     "fileMatch": [
+-        "py.requirements/all.txt",
+         "py.requirements/*.txt",
++        "py.requirements/all.txt",
++        "py.requirements/basic.txt",
++        "py.requirements/develop.txt",
++        "py.requirements/testing.txt",
++        "py.requirements/ci.tox.txt",
++        "py.requirements/ci.travis.txt",
+         "tasks/py.requirements.txt",
+         "issue.features/py.requirements.txt"
+     ]
+-}
++  }
+ }
diff --git a/meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch b/meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch
new file mode 100644
index 000000000..758bd9878
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch
@@ -0,0 +1,92 @@
+From a45ef62144036b481e8432bcd2698a5f7bfcddd2 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 10:54:48 +0100
+Subject: [PATCH] PIN REQUIREMENTS: Extend to all places. PINNED: invoke, six,
+ PyHamcrest
+
+---
+ issue.features/py.requirements.txt | 2 +-
+ py.requirements/basic.txt          | 2 +-
+ py.requirements/ci.tox.txt         | 2 +-
+ py.requirements/ci.travis.txt      | 2 +-
+ py.requirements/develop.txt        | 4 +---
+ py.requirements/testing.txt        | 2 +-
+ 6 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/issue.features/py.requirements.txt b/issue.features/py.requirements.txt
+index 38f452d..6e3cf83 100644
+--- a/issue.features/py.requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -8,4 +8,4 @@
+ #
+ # ============================================================================
+ 
+-PyHamcrest==2.0.2
++PyHamcrest == 2.0.2
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index f976748..6c644e0 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -11,7 +11,7 @@
+ cucumber-tag-expressions >= 1.1.2
+ parse >= 1.18.0
+ parse_type >= 0.4.2
+-six >= 1.12.0
++six == 1.15.0
+ 
+ traceback2;  python_version < '3.0'
+ contextlib2     # MAYBE: python_version < '3.5'
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 4001bc2..20ae791 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -6,7 +6,7 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock >= 2.0
+-PyHamcrest >= 1.9
++PyHamcrest == 2.0.2
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index de4120a..c69445c 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -5,7 +5,7 @@ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+-PyHamcrest >= 1.9
++PyHamcrest == 2.0.2
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index a92ee5f..e7dc418 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -3,9 +3,7 @@
+ # ============================================================================
+ 
+ # -- BUILD-TOOL:
+-# PREPARE USAGE: invoke
+-# ALREADY: six >= 1.11.0
+-invoke >= 1.2.0
++invoke == 1.4.1
+ pathlib;    python_version <= '3.4'
+ pycmd
+ 
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 5ccdda8..d3bca18 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -8,7 +8,7 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+-PyHamcrest >= 2.0.2
++PyHamcrest == 2.0.2
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
diff --git a/meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch b/meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch
new file mode 100644
index 000000000..9c6735886
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch
@@ -0,0 +1,8116 @@
+From dc91d552ba45dd34022f37a4d4f328d5de5c1e17 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 21:18:12 +0100
+Subject: [PATCH] tasks: Add invoke_cleanup (replaces: _tasklet_cleanup),
+ remove _vendor/ directory.
+
+---
+ py.requirements/docs.txt  |    3 +-
+ tasks/__init__.py         |   10 +-
+ tasks/_setup.py           |   10 +-
+ tasks/_tasklet_cleanup.py |  295 -------
+ tasks/_vendor/README.rst  |   35 -
+ tasks/_vendor/invoke.zip  |  Bin 172281 -> 0 bytes
+ tasks/_vendor/path.py     | 1725 -------------------------------------
+ tasks/_vendor/pathlib.py  | 1280 ---------------------------
+ tasks/_vendor/six.py      |  868 -------------------
+ tasks/docs.py             |   33 +-
+ tasks/invoke_cleanup.py   |  447 ++++++++++
+ tasks/py.requirements.txt |    2 +-
+ tasks/release.py          |    2 +-
+ tasks/test.py             |    3 +-
+ 14 files changed, 497 insertions(+), 4216 deletions(-)
+ delete mode 100644 tasks/_tasklet_cleanup.py
+ delete mode 100644 tasks/_vendor/README.rst
+ delete mode 100644 tasks/_vendor/invoke.zip
+ delete mode 100644 tasks/_vendor/path.py
+ delete mode 100644 tasks/_vendor/pathlib.py
+ delete mode 100644 tasks/_vendor/six.py
+ create mode 100644 tasks/invoke_cleanup.py
+
+diff --git a/py.requirements/docs.txt b/py.requirements/docs.txt
+index 6839ba9..1384e00 100644
+--- a/py.requirements/docs.txt
++++ b/py.requirements/docs.txt
+@@ -3,7 +3,8 @@
+ # ============================================================================
+ # REQUIRES: pip >= 8.0
+ 
+-Sphinx >= 1.6
++sphinx >= 1.6
++sphinx-autobuild
+ sphinx_bootstrap_theme >= 0.6.0
+ 
+ # -- SUPPORT: sphinx-doc translations (prepared)
+diff --git a/tasks/__init__.py b/tasks/__init__.py
+index a572465..9ae899b 100644
+--- a/tasks/__init__.py
++++ b/tasks/__init__.py
+@@ -20,7 +20,7 @@ from __future__ import absolute_import
+ from . import _setup    # pylint: disable=wrong-import-order
+ import os.path
+ import sys
+-INVOKE_MINVERSION = "1.2.0"
++INVOKE_MINVERSION = "1.4.0"
+ _setup.setup_path()
+ _setup.require_invoke_minversion(INVOKE_MINVERSION)
+ 
+@@ -35,7 +35,8 @@ import sys
+ from invoke import Collection
+ 
+ # -- TASK-LIBRARY:
+-from . import _tasklet_cleanup as cleanup
++# PREPARED: import invoke_cleanup as cleanup
++from . import invoke_cleanup as cleanup
+ from . import docs
+ from . import test
+ from . import release
+@@ -52,19 +53,18 @@ from . import develop
+ # TASK CONFIGURATION:
+ # -----------------------------------------------------------------------------
+ namespace = Collection()
+-# DISABLED: namespace.add_task(clean.clean)
+-# DISABLED: namespace.add_task(clean.clean_all)
+ namespace.add_collection(Collection.from_module(cleanup), name="cleanup")
+ namespace.add_collection(Collection.from_module(docs))
+ namespace.add_collection(Collection.from_module(test))
+ namespace.add_collection(Collection.from_module(release))
+ namespace.add_collection(Collection.from_module(develop))
+-cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+ 
++# -- ENSURE: python cleanup is used for this project.
+ cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+ 
+ # -- INJECT: clean configuration into this namespace
+ namespace.configure(cleanup.namespace.configuration())
++namespace.configure(test.namespace.configuration())
+ if sys.platform.startswith("win"):
+     # -- OVERRIDE SETTINGS: For platform=win32, ... (Windows)
+     from ._compat_shutil import which
+diff --git a/tasks/_setup.py b/tasks/_setup.py
+index eda5ca9..e69ec82 100644
+--- a/tasks/_setup.py
++++ b/tasks/_setup.py
+@@ -14,7 +14,7 @@ import sys
+ HERE = os.path.dirname(__file__)
+ TASKS_VENDOR_DIR = os.path.join(HERE, "_vendor")
+ INVOKE_BUNDLE = os.path.join(TASKS_VENDOR_DIR, "invoke.zip")
+-INVOKE_BUNDLE_VERSION = "0.13.0"    # pylint: disable=invalid-name
++INVOKE_BUNDLE_VERSION = "1.4.0"
+ 
+ DEBUG_SYSPATH = False
+ 
+@@ -25,6 +25,7 @@ DEBUG_SYSPATH = False
+ class VersionRequirementError(SystemExit):
+     pass
+ 
++
+ # -----------------------------------------------------------------------------
+ # FUNCTIONS:
+ # -----------------------------------------------------------------------------
+@@ -32,7 +33,7 @@ def setup_path(invoke_minversion=None):
+     """Setup python search and add ``TASKS_VENDOR_DIR`` (if available)."""
+     # print("INVOKE.tasks: setup_path")
+     if not os.path.isdir(TASKS_VENDOR_DIR):
+-        print("SKIP: TASKS_VENDOR_DIR=%s is missing" % TASKS_VENDOR_DIR)
++        # SILENT: print("SKIP: TASKS_VENDOR_DIR=%s is missing" % os.path.relpath(TASKS_VENDOR_DIR))
+         return
+     elif os.path.abspath(TASKS_VENDOR_DIR) in sys.path:
+         # -- SETUP ALREADY DONE:
+@@ -86,6 +87,7 @@ def require_invoke_minversion(min_version, verbose=False):
+         os.environ["INVOKE_VERSION"] = invoke_version
+         print("USING: invoke.version=%s" % invoke_version)
+ 
++
+ def need_vendor_bundles(invoke_minversion=None):
+     invoke_minversion = invoke_minversion or "0.0.0"
+     need_vendor_answers = []
+@@ -102,6 +104,7 @@ def need_vendor_bundles(invoke_minversion=None):
+     # return need_bundle1 or need_bundle2
+     return any(need_vendor_answers)
+ 
++
+ def need_vendor_bundle_invoke(invoke_minversion="0.0.0"):
+     # -- REQUIRE: invoke
+     try:
+@@ -116,6 +119,7 @@ def need_vendor_bundle_invoke(invoke_minversion="0.0.0"):
+         need_bundle = True
+     return need_bundle
+ 
++
+ # -----------------------------------------------------------------------------
+ # UTILITY FUNCTIONS:
+ # -----------------------------------------------------------------------------
+@@ -125,11 +129,13 @@ def setup_path_for_bundle(bundle_path, pos=0):
+         return True
+     return False
+ 
++
+ def syspath_insert(pos, path):
+     if path in sys.path:
+         sys.path.remove(path)
+     sys.path.insert(pos, path)
+ 
++
+ def syspath_append(path):
+     if path in sys.path:
+         sys.path.remove(path)
+diff --git a/tasks/_tasklet_cleanup.py b/tasks/_tasklet_cleanup.py
+deleted file mode 100644
+index 2999bc6..0000000
+--- a/tasks/_tasklet_cleanup.py
++++ /dev/null
+@@ -1,295 +0,0 @@
+-# -*- coding: UTF-8 -*-
+-"""
+-Provides cleanup tasks for invoke build scripts (as generic invoke tasklet).
+-Simplifies writing common, composable and extendable cleanup tasks.
+-
+-PYTHON PACKAGE REQUIREMENTS:
+-* path.py >= 8.2.1  (as path-object abstraction)
+-* pathlib (for ant-like wildcard patterns; since: python > 3.5)
+-* pycmd (required-by: clean_python())
+-
+-clean task: Add Additional Directories and Files to be removed
+--------------------------------------------------------------------------------
+-
+-Create an invoke configuration file (YAML of JSON) with the additional
+-configuration data:
+-
+-.. code-block:: yaml
+-
+-    # -- FILE: invoke.yaml
+-    # USE: clean.directories, clean.files to override current configuration.
+-    clean:
+-        extra_directories:
+-            - **/tmp/
+-        extra_files:
+-            - **/*.log
+-            - **/*.bak
+-
+-
+-Registration of Cleanup Tasks
+-------------------------------
+-
+-Other task modules often have an own cleanup task to recover the clean state.
+-The :meth:`clean` task, that is provided here, supports the registration
+-of additional cleanup tasks. Therefore, when the :meth:`clean` task is executed,
+-all registered cleanup tasks will be executed.
+-
+-EXAMPLE::
+-
+-    # -- FILE: tasks/docs.py
+-    from __future__ import absolute_import
+-    from invoke import task, Collection
+-    from tasklet_cleanup import cleanup_tasks, cleanup_dirs
+-
+-    @task
+-    def clean(ctx, dry_run=False):
+-        "Cleanup generated documentation artifacts."
+-        cleanup_dirs(["build/docs"])
+-
+-    namespace = Collection(clean)
+-    ...
+-
+-    # -- REGISTER CLEANUP TASK:
+-    cleanup_tasks.add_task(clean, "clean_docs")
+-    cleanup_tasks.configure(namespace.configuration())
+-"""
+-
+-from __future__ import absolute_import, print_function
+-import os.path
+-import sys
+-import pathlib
+-from invoke import task, Collection
+-from invoke.executor import Executor
+-from invoke.exceptions import Exit, Failure, UnexpectedExit
+-from path import Path
+-
+-
+-# -----------------------------------------------------------------------------
+-# CLEANUP UTILITIES:
+-# -----------------------------------------------------------------------------
+-def cleanup_accept_old_config(ctx):
+-    ctx.cleanup.directories.extend(ctx.clean.directories or [])
+-    ctx.cleanup.extra_directories.extend(ctx.clean.extra_directories or [])
+-    ctx.cleanup.files.extend(ctx.clean.files or [])
+-    ctx.cleanup.extra_files.extend(ctx.clean.extra_files or [])
+-
+-    ctx.cleanup_all.directories.extend(ctx.clean_all.directories or [])
+-    ctx.cleanup_all.extra_directories.extend(ctx.clean_all.extra_directories or [])
+-    ctx.cleanup_all.files.extend(ctx.clean_all.files or [])
+-    ctx.cleanup_all.extra_files.extend(ctx.clean_all.extra_files or [])
+-
+-
+-def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
+-    """Execute several cleanup tasks as part of the cleanup.
+-
+-    REQUIRES: ``clean(ctx, dry_run=False)`` signature in cleanup tasks.
+-
+-    :param ctx:             Context object for the tasks.
+-    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
+-    :param dry_run:         Indicates dry-run mode (bool)
+-    """
+-    # pylint: disable=redefined-outer-name
+-    executor = Executor(cleanup_tasks, ctx.config)
+-    failure_count = 0
+-    for cleanup_task in cleanup_tasks.tasks:
+-        try:
+-            print("CLEANUP TASK: %s" % cleanup_task)
+-            executor.execute((cleanup_task, dict(dry_run=dry_run)))
+-        except (Exit, Failure, UnexpectedExit) as e:
+-            print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" % cleanup_task)
+-            failure_count += 1
+-
+-    if failure_count:
+-        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
+-
+-
+-def cleanup_dirs(patterns, dry_run=False, workdir="."):
+-    """Remove directories (and their contents) recursively.
+-    Skips removal if directories does not exist.
+-
+-    :param patterns:    Directory name patterns, like "**/tmp*" (as list).
+-    :param dry_run:     Dry-run mode indicator (as bool).
+-    :param workdir:     Current work directory (default=".")
+-    """
+-    current_dir = Path(workdir)
+-    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
+-    warn2_counter = 0
+-    for dir_pattern in patterns:
+-        for directory in path_glob(dir_pattern, current_dir):
+-            directory2 = directory.abspath()
+-            if sys.executable.startswith(directory2):
+-                # pylint: disable=line-too-long
+-                print("SKIP-SUICIDE: '%s' contains current python executable" % directory)
+-                continue
+-            elif directory2.startswith(python_basedir):
+-                # -- PROTECT CURRENTLY USED VIRTUAL ENVIRONMENT:
+-                if warn2_counter <= 4:
+-                    print("SKIP-SUICIDE: '%s'" % directory)
+-                warn2_counter += 1
+-                continue
+-
+-            if not directory.isdir():
+-                print("RMTREE: %s (SKIPPED: Not a directory)" % directory)
+-                continue
+-
+-            if dry_run:
+-                print("RMTREE: %s (dry-run)" % directory)
+-            else:
+-                print("RMTREE: %s" % directory)
+-                directory.rmtree_p()
+-
+-
+-def cleanup_files(patterns, dry_run=False, workdir="."):
+-    """Remove files or files selected by file patterns.
+-    Skips removal if file does not exist.
+-
+-    :param patterns:    File patterns, like "**/*.pyc" (as list).
+-    :param dry_run:     Dry-run mode indicator (as bool).
+-    :param workdir:     Current work directory (default=".")
+-    """
+-    current_dir = Path(workdir)
+-    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
+-    error_message = None
+-    error_count = 0
+-    for file_pattern in patterns:
+-        for file_ in path_glob(file_pattern, current_dir):
+-            if file_.abspath().startswith(python_basedir):
+-                # -- PROTECT CURRENTLY USED VIRTUAL ENVIRONMENT:
+-                continue
+-            if not file_.isfile():
+-                print("REMOVE: %s (SKIPPED: Not a file)" % file_)
+-                continue
+-
+-            if dry_run:
+-                print("REMOVE: %s (dry-run)" % file_)
+-            else:
+-                print("REMOVE: %s" % file_)
+-                try:
+-                    file_.remove_p()
+-                except os.error as e:
+-                    message = "%s: %s" % (e.__class__.__name__, e)
+-                    print(message + " basedir: "+ python_basedir)
+-                    error_count += 1
+-                    if not error_message:
+-                        error_message = message
+-    if False and error_message:
+-        class CleanupError(RuntimeError):
+-            pass
+-        raise CleanupError(error_message)
+-
+-
+-def path_glob(pattern, current_dir=None):
+-    """Use pathlib for ant-like patterns, like: "**/*.py"
+-
+-    :param pattern:      File/directory pattern to use (as string).
+-    :param current_dir:  Current working directory (as Path, pathlib.Path, str)
+-    :return Resolved Path (as path.Path).
+-    """
+-    if not current_dir:
+-        current_dir = pathlib.Path.cwd()
+-    elif not isinstance(current_dir, pathlib.Path):
+-        # -- CASE: string, path.Path (string-like)
+-        current_dir = pathlib.Path(str(current_dir))
+-
+-    for p in current_dir.glob(pattern):
+-        yield Path(str(p))
+-
+-
+-# -----------------------------------------------------------------------------
+-# GENERIC CLEANUP TASKS:
+-# -----------------------------------------------------------------------------
+-@task
+-def clean(ctx, dry_run=False):
+-    """Cleanup temporary dirs/files to regain a clean state."""
+-    cleanup_accept_old_config(ctx)
+-    directories = ctx.cleanup.directories or []
+-    directories.extend(ctx.cleanup.extra_directories or [])
+-    files = ctx.cleanup.files or []
+-    files.extend(ctx.cleanup.extra_files or [])
+-
+-    # -- PERFORM CLEANUP:
+-    execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=dry_run)
+-    cleanup_dirs(directories, dry_run=dry_run)
+-    cleanup_files(files, dry_run=dry_run)
+-
+-
+-@task(name="all", aliases=("distclean",))
+-def clean_all(ctx, dry_run=False):
+-    """Clean up everything, even the precious stuff.
+-    NOTE: clean task is executed first.
+-    """
+-    cleanup_accept_old_config(ctx)
+-    directories = ctx.config.cleanup_all.directories or []
+-    directories.extend(ctx.config.cleanup_all.extra_directories or [])
+-    files = ctx.config.cleanup_all.files or []
+-    files.extend(ctx.config.cleanup_all.extra_files or [])
+-
+-    # -- PERFORM CLEANUP:
+-    # HINT: Remove now directories, files first before cleanup-tasks.
+-    cleanup_dirs(directories, dry_run=dry_run)
+-    cleanup_files(files, dry_run=dry_run)
+-    execute_cleanup_tasks(ctx, cleanup_all_tasks, dry_run=dry_run)
+-    clean(ctx, dry_run=dry_run)
+-
+-
+-@task(name="python")
+-def clean_python(ctx, dry_run=False):
+-    """Cleanup python related files/dirs: *.pyc, *.pyo, ..."""
+-    # MAYBE NOT: "**/__pycache__"
+-    cleanup_dirs(["build", "dist", "*.egg-info", "**/__pycache__"],
+-                 dry_run=dry_run)
+-    if not dry_run:
+-        ctx.run("py.cleanup")
+-    cleanup_files(["**/*.pyc", "**/*.pyo", "**/*$py.class"], dry_run=dry_run)
+-
+-
+-# -----------------------------------------------------------------------------
+-# TASK CONFIGURATION:
+-# -----------------------------------------------------------------------------
+-CLEANUP_EMPTY_CONFIG = {
+-    "directories": [],
+-    "files": [],
+-    "extra_directories": [],
+-    "extra_files": [],
+-}
+-def make_cleanup_config(**kwargs):
+-    config_data = CLEANUP_EMPTY_CONFIG.copy()
+-    config_data.update(kwargs)
+-    return config_data
+-
+-
+-namespace = Collection(clean_all, clean_python)
+-namespace.add_task(clean, default=True)
+-namespace.configure({
+-    "cleanup": make_cleanup_config(
+-        files=["*.bak", "*.log", "*.tmp", "**/.DS_Store", "**/*.~*~"]
+-    ),
+-    "cleanup_all": make_cleanup_config(
+-        directories=[".venv*", ".tox", "downloads", "tmp"]
+-    ),
+-    # -- BACKWARD-COMPATIBLE: OLD-STYLE
+-    "clean":     CLEANUP_EMPTY_CONFIG.copy(),
+-    "clean_all": CLEANUP_EMPTY_CONFIG.copy(),
+-})
+-
+-
+-# -- EXTENSION-POINT: CLEANUP TASKS (called by: clean, clean_all task)
+-# NOTE: Can be used by other tasklets to register cleanup tasks.
+-cleanup_tasks = Collection("cleanup_tasks")
+-cleanup_all_tasks = Collection("cleanup_all_tasks")
+-
+-# -- EXTEND NORMAL CLEANUP-TASKS:
+-# DISABLED: cleanup_tasks.add_task(clean_python)
+-#
+-# -----------------------------------------------------------------------------
+-# EXTENSION-POINT: CONFIGURATION HELPERS: Can be used from other task modules
+-# -----------------------------------------------------------------------------
+-def config_add_cleanup_dirs(directories):
+-    # pylint: disable=protected-access
+-    the_cleanup_directories = namespace._configuration["clean"]["directories"]
+-    the_cleanup_directories.extend(directories)
+-
+-def config_add_cleanup_files(files):
+-    # pylint: disable=protected-access
+-    the_cleanup_files = namespace._configuration["clean"]["files"]
+-    the_cleanup_files.extend(files)
+diff --git a/tasks/_vendor/README.rst b/tasks/_vendor/README.rst
+deleted file mode 100644
+index 68fc06a..0000000
+--- a/tasks/_vendor/README.rst
++++ /dev/null
+@@ -1,35 +0,0 @@
+-tasks/_vendor: Bundled vendor parts -- needed by tasks
+-===============================================================================
+-
+-This directory contains bundled archives that may be needed to run the tasks.
+-Especially, it contains an executable "invoke.zip" archive.
+-This archive can be used when invoke is not installed.
+-
+-To execute invoke from the bundled ZIP archive::
+-
+-
+-    python -m tasks/_vendor/invoke.zip --help
+-    python -m tasks/_vendor/invoke.zip --version
+-
+-
+-Example for a local "bin/invoke" script in a UNIX like platform environment::
+-
+-    #!/bin/bash
+-    # RUN INVOKE: From bundled ZIP file.
+-
+-    HERE=$(dirname $0)
+-
+-    python ${HERE}/../tasks/_vendor/invoke.zip $*
+-
+-Example for a local "bin/invoke.cmd" script in a Windows environment::
+-
+-    @echo off
+-    REM ==========================================================================
+-    REM RUN INVOKE: From bundled ZIP file.
+-    REM ==========================================================================
+-
+-    setlocal
+-    set HERE=%~dp0
+-    if not defined PYTHON   set PYTHON=python
+-
+-    %PYTHON% %HERE%../tasks/_vendor/invoke.zip "%*"
+diff --git a/tasks/_vendor/invoke.zip b/tasks/_vendor/invoke.zip
+deleted file mode 100644
+index bd1941289b427b6cd6beaf188c85def58ee4ce33..0000000000000000000000000000000000000000
+GIT binary patch
+literal 0
+HcmV?d00001
+
+literal 172281
+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
+zGGZqJEe%^irYHi$5Y*76Dh4>&<!%0AfH2K(?hj9A8%&MPJ$V+x5Uh_eLLl~WVHG$B
+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
+z%0A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
+
+diff --git a/tasks/_vendor/path.py b/tasks/_vendor/path.py
+deleted file mode 100644
+index 2c7a71c..0000000
+--- a/tasks/_vendor/path.py
++++ /dev/null
+@@ -1,1725 +0,0 @@
+-#
+-# SOURCE: https://pypi.python.org/pypi/path.py
+-# VERSION: 8.2.1
+-# -----------------------------------------------------------------------------
+-# Copyright (c) 2010 Mikhail Gusarov
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy
+-# of this software and associated documentation files (the "Software"), to deal
+-# in the Software without restriction, including without limitation the rights
+-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-# copies of the Software, and to permit persons to whom the Software is
+-# furnished to do so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in
+-# all copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+-#
+-
+-"""
+-path.py - An object representing a path to a file or directory.
+-
+-https://github.com/jaraco/path.py
+-
+-Example::
+-
+-    from path import Path
+-    d = Path('/home/guido/bin')
+-    for f in d.files('*.py'):
+-        f.chmod(0o755)
+-"""
+-
+-from __future__ import unicode_literals
+-
+-import sys
+-import warnings
+-import os
+-import fnmatch
+-import glob
+-import shutil
+-import codecs
+-import hashlib
+-import errno
+-import tempfile
+-import functools
+-import operator
+-import re
+-import contextlib
+-import io
+-from distutils import dir_util
+-import importlib
+-
+-try:
+-    import win32security
+-except ImportError:
+-    pass
+-
+-try:
+-    import pwd
+-except ImportError:
+-    pass
+-
+-try:
+-    import grp
+-except ImportError:
+-    pass
+-
+-##############################################################################
+-# Python 2/3 support
+-PY3 = sys.version_info >= (3,)
+-PY2 = not PY3
+-
+-string_types = str,
+-text_type = str
+-getcwdu = os.getcwd
+-
+-def surrogate_escape(error):
+-    """
+-    Simulate the Python 3 ``surrogateescape`` handler, but for Python 2 only.
+-    """
+-    chars = error.object[error.start:error.end]
+-    assert len(chars) == 1
+-    val = ord(chars)
+-    val += 0xdc00
+-    return __builtin__.unichr(val), error.end
+-
+-if PY2:
+-    import __builtin__
+-    string_types = __builtin__.basestring,
+-    text_type = __builtin__.unicode
+-    getcwdu = os.getcwdu
+-    codecs.register_error('surrogateescape', surrogate_escape)
+-
+-@contextlib.contextmanager
+-def io_error_compat():
+-    try:
+-        yield
+-    except IOError as io_err:
+-        # On Python 2, io.open raises IOError; transform to OSError for
+-        # future compatibility.
+-        os_err = OSError(*io_err.args)
+-        os_err.filename = getattr(io_err, 'filename', None)
+-        raise os_err
+-
+-##############################################################################
+-
+-__all__ = ['Path', 'CaseInsensitivePattern']
+-
+-
+-LINESEPS = ['\r\n', '\r', '\n']
+-U_LINESEPS = LINESEPS + ['\u0085', '\u2028', '\u2029']
+-NEWLINE = re.compile('|'.join(LINESEPS))
+-U_NEWLINE = re.compile('|'.join(U_LINESEPS))
+-NL_END = re.compile(r'(?:{0})$'.format(NEWLINE.pattern))
+-U_NL_END = re.compile(r'(?:{0})$'.format(U_NEWLINE.pattern))
+-
+-
+-try:
+-    import pkg_resources
+-    __version__ = pkg_resources.require('path.py')[0].version
+-except Exception:
+-    __version__ = '8.2.1'   # XXX-MODIFIED-WAS: 'unknown'
+-
+-
+-class TreeWalkWarning(Warning):
+-    pass
+-
+-
+-# from jaraco.functools
+-def compose(*funcs):
+-    compose_two = lambda f1, f2: lambda *args, **kwargs: f1(f2(*args, **kwargs))
+-    return functools.reduce(compose_two, funcs)
+-
+-
+-def simple_cache(func):
+-    """
+-    Save results for the :meth:'path.using_module' classmethod.
+-    When Python 3.2 is available, use functools.lru_cache instead.
+-    """
+-    saved_results = {}
+-
+-    def wrapper(cls, module):
+-        if module in saved_results:
+-            return saved_results[module]
+-        saved_results[module] = func(cls, module)
+-        return saved_results[module]
+-    return wrapper
+-
+-
+-class ClassProperty(property):
+-    def __get__(self, cls, owner):
+-        return self.fget.__get__(None, owner)()
+-
+-
+-class multimethod(object):
+-    """
+-    Acts like a classmethod when invoked from the class and like an
+-    instancemethod when invoked from the instance.
+-    """
+-    def __init__(self, func):
+-        self.func = func
+-
+-    def __get__(self, instance, owner):
+-        return (
+-            functools.partial(self.func, owner) if instance is None
+-            else functools.partial(self.func, owner, instance)
+-        )
+-
+-
+-class Path(text_type):
+-    """
+-    Represents a filesystem path.
+-
+-    For documentation on individual methods, consult their
+-    counterparts in :mod:`os.path`.
+-
+-    Some methods are additionally included from :mod:`shutil`.
+-    The functions are linked directly into the class namespace
+-    such that they will be bound to the Path instance. For example,
+-    ``Path(src).copy(target)`` is equivalent to
+-    ``shutil.copy(src, target)``. Therefore, when referencing
+-    the docs for these methods, assume `src` references `self`,
+-    the Path instance.
+-    """
+-
+-    module = os.path
+-    """ The path module to use for path operations.
+-
+-    .. seealso:: :mod:`os.path`
+-    """
+-
+-    def __init__(self, other=''):
+-        if other is None:
+-            raise TypeError("Invalid initial value for path: None")
+-
+-    @classmethod
+-    @simple_cache
+-    def using_module(cls, module):
+-        subclass_name = cls.__name__ + '_' + module.__name__
+-        if PY2:
+-            subclass_name = str(subclass_name)
+-        bases = (cls,)
+-        ns = {'module': module}
+-        return type(subclass_name, bases, ns)
+-
+-    @ClassProperty
+-    @classmethod
+-    def _next_class(cls):
+-        """
+-        What class should be used to construct new instances from this class
+-        """
+-        return cls
+-
+-    @classmethod
+-    def _always_unicode(cls, path):
+-        """
+-        Ensure the path as retrieved from a Python API, such as :func:`os.listdir`,
+-        is a proper Unicode string.
+-        """
+-        if PY3 or isinstance(path, text_type):
+-            return path
+-        return path.decode(sys.getfilesystemencoding(), 'surrogateescape')
+-
+-    # --- Special Python methods.
+-
+-    def __repr__(self):
+-        return '%s(%s)' % (type(self).__name__, super(Path, self).__repr__())
+-
+-    # Adding a Path and a string yields a Path.
+-    def __add__(self, more):
+-        try:
+-            return self._next_class(super(Path, self).__add__(more))
+-        except TypeError:  # Python bug
+-            return NotImplemented
+-
+-    def __radd__(self, other):
+-        if not isinstance(other, string_types):
+-            return NotImplemented
+-        return self._next_class(other.__add__(self))
+-
+-    # The / operator joins Paths.
+-    def __div__(self, rel):
+-        """ fp.__div__(rel) == fp / rel == fp.joinpath(rel)
+-
+-        Join two path components, adding a separator character if
+-        needed.
+-
+-        .. seealso:: :func:`os.path.join`
+-        """
+-        return self._next_class(self.module.join(self, rel))
+-
+-    # Make the / operator work even when true division is enabled.
+-    __truediv__ = __div__
+-
+-    # The / operator joins Paths the other way around
+-    def __rdiv__(self, rel):
+-        """ fp.__rdiv__(rel) == rel / fp
+-
+-        Join two path components, adding a separator character if
+-        needed.
+-
+-        .. seealso:: :func:`os.path.join`
+-        """
+-        return self._next_class(self.module.join(rel, self))
+-
+-    # Make the / operator work even when true division is enabled.
+-    __rtruediv__ = __rdiv__
+-
+-    def __enter__(self):
+-        self._old_dir = self.getcwd()
+-        os.chdir(self)
+-        return self
+-
+-    def __exit__(self, *_):
+-        os.chdir(self._old_dir)
+-
+-    @classmethod
+-    def getcwd(cls):
+-        """ Return the current working directory as a path object.
+-
+-        .. seealso:: :func:`os.getcwdu`
+-        """
+-        return cls(getcwdu())
+-
+-    #
+-    # --- Operations on Path strings.
+-
+-    def abspath(self):
+-        """ .. seealso:: :func:`os.path.abspath` """
+-        return self._next_class(self.module.abspath(self))
+-
+-    def normcase(self):
+-        """ .. seealso:: :func:`os.path.normcase` """
+-        return self._next_class(self.module.normcase(self))
+-
+-    def normpath(self):
+-        """ .. seealso:: :func:`os.path.normpath` """
+-        return self._next_class(self.module.normpath(self))
+-
+-    def realpath(self):
+-        """ .. seealso:: :func:`os.path.realpath` """
+-        return self._next_class(self.module.realpath(self))
+-
+-    def expanduser(self):
+-        """ .. seealso:: :func:`os.path.expanduser` """
+-        return self._next_class(self.module.expanduser(self))
+-
+-    def expandvars(self):
+-        """ .. seealso:: :func:`os.path.expandvars` """
+-        return self._next_class(self.module.expandvars(self))
+-
+-    def dirname(self):
+-        """ .. seealso:: :attr:`parent`, :func:`os.path.dirname` """
+-        return self._next_class(self.module.dirname(self))
+-
+-    def basename(self):
+-        """ .. seealso:: :attr:`name`, :func:`os.path.basename` """
+-        return self._next_class(self.module.basename(self))
+-
+-    def expand(self):
+-        """ Clean up a filename by calling :meth:`expandvars()`,
+-        :meth:`expanduser()`, and :meth:`normpath()` on it.
+-
+-        This is commonly everything needed to clean up a filename
+-        read from a configuration file, for example.
+-        """
+-        return self.expandvars().expanduser().normpath()
+-
+-    @property
+-    def namebase(self):
+-        """ The same as :meth:`name`, but with one file extension stripped off.
+-
+-        For example,
+-        ``Path('/home/guido/python.tar.gz').name == 'python.tar.gz'``,
+-        but
+-        ``Path('/home/guido/python.tar.gz').namebase == 'python.tar'``.
+-        """
+-        base, ext = self.module.splitext(self.name)
+-        return base
+-
+-    @property
+-    def ext(self):
+-        """ The file extension, for example ``'.py'``. """
+-        f, ext = self.module.splitext(self)
+-        return ext
+-
+-    @property
+-    def drive(self):
+-        """ The drive specifier, for example ``'C:'``.
+-
+-        This is always empty on systems that don't use drive specifiers.
+-        """
+-        drive, r = self.module.splitdrive(self)
+-        return self._next_class(drive)
+-
+-    parent = property(
+-        dirname, None, None,
+-        """ This path's parent directory, as a new Path object.
+-
+-        For example,
+-        ``Path('/usr/local/lib/libpython.so').parent ==
+-        Path('/usr/local/lib')``
+-
+-        .. seealso:: :meth:`dirname`, :func:`os.path.dirname`
+-        """)
+-
+-    name = property(
+-        basename, None, None,
+-        """ The name of this file or directory without the full path.
+-
+-        For example,
+-        ``Path('/usr/local/lib/libpython.so').name == 'libpython.so'``
+-
+-        .. seealso:: :meth:`basename`, :func:`os.path.basename`
+-        """)
+-
+-    def splitpath(self):
+-        """ p.splitpath() -> Return ``(p.parent, p.name)``.
+-
+-        .. seealso:: :attr:`parent`, :attr:`name`, :func:`os.path.split`
+-        """
+-        parent, child = self.module.split(self)
+-        return self._next_class(parent), child
+-
+-    def splitdrive(self):
+-        """ p.splitdrive() -> Return ``(p.drive, <the rest of p>)``.
+-
+-        Split the drive specifier from this path.  If there is
+-        no drive specifier, :samp:`{p.drive}` is empty, so the return value
+-        is simply ``(Path(''), p)``.  This is always the case on Unix.
+-
+-        .. seealso:: :func:`os.path.splitdrive`
+-        """
+-        drive, rel = self.module.splitdrive(self)
+-        return self._next_class(drive), rel
+-
+-    def splitext(self):
+-        """ p.splitext() -> Return ``(p.stripext(), p.ext)``.
+-
+-        Split the filename extension from this path and return
+-        the two parts.  Either part may be empty.
+-
+-        The extension is everything from ``'.'`` to the end of the
+-        last path segment.  This has the property that if
+-        ``(a, b) == p.splitext()``, then ``a + b == p``.
+-
+-        .. seealso:: :func:`os.path.splitext`
+-        """
+-        filename, ext = self.module.splitext(self)
+-        return self._next_class(filename), ext
+-
+-    def stripext(self):
+-        """ p.stripext() -> Remove one file extension from the path.
+-
+-        For example, ``Path('/home/guido/python.tar.gz').stripext()``
+-        returns ``Path('/home/guido/python.tar')``.
+-        """
+-        return self.splitext()[0]
+-
+-    def splitunc(self):
+-        """ .. seealso:: :func:`os.path.splitunc` """
+-        unc, rest = self.module.splitunc(self)
+-        return self._next_class(unc), rest
+-
+-    @property
+-    def uncshare(self):
+-        """
+-        The UNC mount point for this path.
+-        This is empty for paths on local drives.
+-        """
+-        unc, r = self.module.splitunc(self)
+-        return self._next_class(unc)
+-
+-    @multimethod
+-    def joinpath(cls, first, *others):
+-        """
+-        Join first to zero or more :class:`Path` components, adding a separator
+-        character (:samp:`{first}.module.sep`) if needed.  Returns a new instance of
+-        :samp:`{first}._next_class`.
+-
+-        .. seealso:: :func:`os.path.join`
+-        """
+-        if not isinstance(first, cls):
+-            first = cls(first)
+-        return first._next_class(first.module.join(first, *others))
+-
+-    def splitall(self):
+-        r""" Return a list of the path components in this path.
+-
+-        The first item in the list will be a Path.  Its value will be
+-        either :data:`os.curdir`, :data:`os.pardir`, empty, or the root
+-        directory of this path (for example, ``'/'`` or ``'C:\\'``).  The
+-        other items in the list will be strings.
+-
+-        ``path.Path.joinpath(*result)`` will yield the original path.
+-        """
+-        parts = []
+-        loc = self
+-        while loc != os.curdir and loc != os.pardir:
+-            prev = loc
+-            loc, child = prev.splitpath()
+-            if loc == prev:
+-                break
+-            parts.append(child)
+-        parts.append(loc)
+-        parts.reverse()
+-        return parts
+-
+-    def relpath(self, start='.'):
+-        """ Return this path as a relative path,
+-        based from `start`, which defaults to the current working directory.
+-        """
+-        cwd = self._next_class(start)
+-        return cwd.relpathto(self)
+-
+-    def relpathto(self, dest):
+-        """ Return a relative path from `self` to `dest`.
+-
+-        If there is no relative path from `self` to `dest`, for example if
+-        they reside on different drives in Windows, then this returns
+-        ``dest.abspath()``.
+-        """
+-        origin = self.abspath()
+-        dest = self._next_class(dest).abspath()
+-
+-        orig_list = origin.normcase().splitall()
+-        # Don't normcase dest!  We want to preserve the case.
+-        dest_list = dest.splitall()
+-
+-        if orig_list[0] != self.module.normcase(dest_list[0]):
+-            # Can't get here from there.
+-            return dest
+-
+-        # Find the location where the two paths start to differ.
+-        i = 0
+-        for start_seg, dest_seg in zip(orig_list, dest_list):
+-            if start_seg != self.module.normcase(dest_seg):
+-                break
+-            i += 1
+-
+-        # Now i is the point where the two paths diverge.
+-        # Need a certain number of "os.pardir"s to work up
+-        # from the origin to the point of divergence.
+-        segments = [os.pardir] * (len(orig_list) - i)
+-        # Need to add the diverging part of dest_list.
+-        segments += dest_list[i:]
+-        if len(segments) == 0:
+-            # If they happen to be identical, use os.curdir.
+-            relpath = os.curdir
+-        else:
+-            relpath = self.module.join(*segments)
+-        return self._next_class(relpath)
+-
+-    # --- Listing, searching, walking, and matching
+-
+-    def listdir(self, pattern=None):
+-        """ D.listdir() -> List of items in this directory.
+-
+-        Use :meth:`files` or :meth:`dirs` instead if you want a listing
+-        of just files or just subdirectories.
+-
+-        The elements of the list are Path objects.
+-
+-        With the optional `pattern` argument, this only lists
+-        items whose names match the given pattern.
+-
+-        .. seealso:: :meth:`files`, :meth:`dirs`
+-        """
+-        if pattern is None:
+-            pattern = '*'
+-        return [
+-            self / child
+-            for child in map(self._always_unicode, os.listdir(self))
+-            if self._next_class(child).fnmatch(pattern)
+-        ]
+-
+-    def dirs(self, pattern=None):
+-        """ D.dirs() -> List of this directory's subdirectories.
+-
+-        The elements of the list are Path objects.
+-        This does not walk recursively into subdirectories
+-        (but see :meth:`walkdirs`).
+-
+-        With the optional `pattern` argument, this only lists
+-        directories whose names match the given pattern.  For
+-        example, ``d.dirs('build-*')``.
+-        """
+-        return [p for p in self.listdir(pattern) if p.isdir()]
+-
+-    def files(self, pattern=None):
+-        """ D.files() -> List of the files in this directory.
+-
+-        The elements of the list are Path objects.
+-        This does not walk into subdirectories (see :meth:`walkfiles`).
+-
+-        With the optional `pattern` argument, this only lists files
+-        whose names match the given pattern.  For example,
+-        ``d.files('*.pyc')``.
+-        """
+-
+-        return [p for p in self.listdir(pattern) if p.isfile()]
+-
+-    def walk(self, pattern=None, errors='strict'):
+-        """ D.walk() -> iterator over files and subdirs, recursively.
+-
+-        The iterator yields Path objects naming each child item of
+-        this directory and its descendants.  This requires that
+-        ``D.isdir()``.
+-
+-        This performs a depth-first traversal of the directory tree.
+-        Each directory is returned just before all its children.
+-
+-        The `errors=` keyword argument controls behavior when an
+-        error occurs.  The default is ``'strict'``, which causes an
+-        exception.  Other allowed values are ``'warn'`` (which
+-        reports the error via :func:`warnings.warn()`), and ``'ignore'``.
+-        `errors` may also be an arbitrary callable taking a msg parameter.
+-        """
+-        class Handlers:
+-            def strict(msg):
+-                raise
+-
+-            def warn(msg):
+-                warnings.warn(msg, TreeWalkWarning)
+-
+-            def ignore(msg):
+-                pass
+-
+-        if not callable(errors) and errors not in vars(Handlers):
+-            raise ValueError("invalid errors parameter")
+-        errors = vars(Handlers).get(errors, errors)
+-
+-        try:
+-            childList = self.listdir()
+-        except Exception:
+-            exc = sys.exc_info()[1]
+-            tmpl = "Unable to list directory '%(self)s': %(exc)s"
+-            msg = tmpl % locals()
+-            errors(msg)
+-            return
+-
+-        for child in childList:
+-            if pattern is None or child.fnmatch(pattern):
+-                yield child
+-            try:
+-                isdir = child.isdir()
+-            except Exception:
+-                exc = sys.exc_info()[1]
+-                tmpl = "Unable to access '%(child)s': %(exc)s"
+-                msg = tmpl % locals()
+-                errors(msg)
+-                isdir = False
+-
+-            if isdir:
+-                for item in child.walk(pattern, errors):
+-                    yield item
+-
+-    def walkdirs(self, pattern=None, errors='strict'):
+-        """ D.walkdirs() -> iterator over subdirs, recursively.
+-
+-        With the optional `pattern` argument, this yields only
+-        directories whose names match the given pattern.  For
+-        example, ``mydir.walkdirs('*test')`` yields only directories
+-        with names ending in ``'test'``.
+-
+-        The `errors=` keyword argument controls behavior when an
+-        error occurs.  The default is ``'strict'``, which causes an
+-        exception.  The other allowed values are ``'warn'`` (which
+-        reports the error via :func:`warnings.warn()`), and ``'ignore'``.
+-        """
+-        if errors not in ('strict', 'warn', 'ignore'):
+-            raise ValueError("invalid errors parameter")
+-
+-        try:
+-            dirs = self.dirs()
+-        except Exception:
+-            if errors == 'ignore':
+-                return
+-            elif errors == 'warn':
+-                warnings.warn(
+-                    "Unable to list directory '%s': %s"
+-                    % (self, sys.exc_info()[1]),
+-                    TreeWalkWarning)
+-                return
+-            else:
+-                raise
+-
+-        for child in dirs:
+-            if pattern is None or child.fnmatch(pattern):
+-                yield child
+-            for subsubdir in child.walkdirs(pattern, errors):
+-                yield subsubdir
+-
+-    def walkfiles(self, pattern=None, errors='strict'):
+-        """ D.walkfiles() -> iterator over files in D, recursively.
+-
+-        The optional argument `pattern` limits the results to files
+-        with names that match the pattern.  For example,
+-        ``mydir.walkfiles('*.tmp')`` yields only files with the ``.tmp``
+-        extension.
+-        """
+-        if errors not in ('strict', 'warn', 'ignore'):
+-            raise ValueError("invalid errors parameter")
+-
+-        try:
+-            childList = self.listdir()
+-        except Exception:
+-            if errors == 'ignore':
+-                return
+-            elif errors == 'warn':
+-                warnings.warn(
+-                    "Unable to list directory '%s': %s"
+-                    % (self, sys.exc_info()[1]),
+-                    TreeWalkWarning)
+-                return
+-            else:
+-                raise
+-
+-        for child in childList:
+-            try:
+-                isfile = child.isfile()
+-                isdir = not isfile and child.isdir()
+-            except:
+-                if errors == 'ignore':
+-                    continue
+-                elif errors == 'warn':
+-                    warnings.warn(
+-                        "Unable to access '%s': %s"
+-                        % (self, sys.exc_info()[1]),
+-                        TreeWalkWarning)
+-                    continue
+-                else:
+-                    raise
+-
+-            if isfile:
+-                if pattern is None or child.fnmatch(pattern):
+-                    yield child
+-            elif isdir:
+-                for f in child.walkfiles(pattern, errors):
+-                    yield f
+-
+-    def fnmatch(self, pattern, normcase=None):
+-        """ Return ``True`` if `self.name` matches the given `pattern`.
+-
+-        `pattern` - A filename pattern with wildcards,
+-            for example ``'*.py'``. If the pattern contains a `normcase`
+-            attribute, it is applied to the name and path prior to comparison.
+-
+-        `normcase` - (optional) A function used to normalize the pattern and
+-            filename before matching. Defaults to :meth:`self.module`, which defaults
+-            to :meth:`os.path.normcase`.
+-
+-        .. seealso:: :func:`fnmatch.fnmatch`
+-        """
+-        default_normcase = getattr(pattern, 'normcase', self.module.normcase)
+-        normcase = normcase or default_normcase
+-        name = normcase(self.name)
+-        pattern = normcase(pattern)
+-        return fnmatch.fnmatchcase(name, pattern)
+-
+-    def glob(self, pattern):
+-        """ Return a list of Path objects that match the pattern.
+-
+-        `pattern` - a path relative to this directory, with wildcards.
+-
+-        For example, ``Path('/users').glob('*/bin/*')`` returns a list
+-        of all the files users have in their :file:`bin` directories.
+-
+-        .. seealso:: :func:`glob.glob`
+-        """
+-        cls = self._next_class
+-        return [cls(s) for s in glob.glob(self / pattern)]
+-
+-    #
+-    # --- Reading or writing an entire file at once.
+-
+-    def open(self, *args, **kwargs):
+-        """ Open this file and return a corresponding :class:`file` object.
+-
+-        Keyword arguments work as in :func:`io.open`.  If the file cannot be
+-        opened, an :class:`~exceptions.OSError` is raised.
+-        """
+-        with io_error_compat():
+-            return io.open(self, *args, **kwargs)
+-
+-    def bytes(self):
+-        """ Open this file, read all bytes, return them as a string. """
+-        with self.open('rb') as f:
+-            return f.read()
+-
+-    def chunks(self, size, *args, **kwargs):
+-        """ Returns a generator yielding chunks of the file, so it can
+-            be read piece by piece with a simple for loop.
+-
+-           Any argument you pass after `size` will be passed to :meth:`open`.
+-
+-           :example:
+-
+-               >>> hash = hashlib.md5()
+-               >>> for chunk in Path("path.py").chunks(8192, mode='rb'):
+-               ...     hash.update(chunk)
+-
+-            This will read the file by chunks of 8192 bytes.
+-        """
+-        with self.open(*args, **kwargs) as f:
+-            for chunk in iter(lambda: f.read(size) or None, None):
+-                yield chunk
+-
+-    def write_bytes(self, bytes, append=False):
+-        """ Open this file and write the given bytes to it.
+-
+-        Default behavior is to overwrite any existing file.
+-        Call ``p.write_bytes(bytes, append=True)`` to append instead.
+-        """
+-        if append:
+-            mode = 'ab'
+-        else:
+-            mode = 'wb'
+-        with self.open(mode) as f:
+-            f.write(bytes)
+-
+-    def text(self, encoding=None, errors='strict'):
+-        r""" Open this file, read it in, return the content as a string.
+-
+-        All newline sequences are converted to ``'\n'``.  Keyword arguments
+-        will be passed to :meth:`open`.
+-
+-        .. seealso:: :meth:`lines`
+-        """
+-        with self.open(mode='r', encoding=encoding, errors=errors) as f:
+-            return U_NEWLINE.sub('\n', f.read())
+-
+-    def write_text(self, text, encoding=None, errors='strict',
+-                   linesep=os.linesep, append=False):
+-        r""" Write the given text to this file.
+-
+-        The default behavior is to overwrite any existing file;
+-        to append instead, use the `append=True` keyword argument.
+-
+-        There are two differences between :meth:`write_text` and
+-        :meth:`write_bytes`: newline handling and Unicode handling.
+-        See below.
+-
+-        Parameters:
+-
+-          `text` - str/unicode - The text to be written.
+-
+-          `encoding` - str - The Unicode encoding that will be used.
+-              This is ignored if `text` isn't a Unicode string.
+-
+-          `errors` - str - How to handle Unicode encoding errors.
+-              Default is ``'strict'``.  See ``help(unicode.encode)`` for the
+-              options.  This is ignored if `text` isn't a Unicode
+-              string.
+-
+-          `linesep` - keyword argument - str/unicode - The sequence of
+-              characters to be used to mark end-of-line.  The default is
+-              :data:`os.linesep`.  You can also specify ``None`` to
+-              leave all newlines as they are in `text`.
+-
+-          `append` - keyword argument - bool - Specifies what to do if
+-              the file already exists (``True``: append to the end of it;
+-              ``False``: overwrite it.)  The default is ``False``.
+-
+-
+-        --- Newline handling.
+-
+-        ``write_text()`` converts all standard end-of-line sequences
+-        (``'\n'``, ``'\r'``, and ``'\r\n'``) to your platform's default
+-        end-of-line sequence (see :data:`os.linesep`; on Windows, for example,
+-        the end-of-line marker is ``'\r\n'``).
+-
+-        If you don't like your platform's default, you can override it
+-        using the `linesep=` keyword argument.  If you specifically want
+-        ``write_text()`` to preserve the newlines as-is, use ``linesep=None``.
+-
+-        This applies to Unicode text the same as to 8-bit text, except
+-        there are three additional standard Unicode end-of-line sequences:
+-        ``u'\x85'``, ``u'\r\x85'``, and ``u'\u2028'``.
+-
+-        (This is slightly different from when you open a file for
+-        writing with ``fopen(filename, "w")`` in C or ``open(filename, 'w')``
+-        in Python.)
+-
+-
+-        --- Unicode
+-
+-        If `text` isn't Unicode, then apart from newline handling, the
+-        bytes are written verbatim to the file.  The `encoding` and
+-        `errors` arguments are not used and must be omitted.
+-
+-        If `text` is Unicode, it is first converted to :func:`bytes` using the
+-        specified `encoding` (or the default encoding if `encoding`
+-        isn't specified).  The `errors` argument applies only to this
+-        conversion.
+-
+-        """
+-        if isinstance(text, text_type):
+-            if linesep is not None:
+-                text = U_NEWLINE.sub(linesep, text)
+-            text = text.encode(encoding or sys.getdefaultencoding(), errors)
+-        else:
+-            assert encoding is None
+-            text = NEWLINE.sub(linesep, text)
+-        self.write_bytes(text, append=append)
+-
+-    def lines(self, encoding=None, errors='strict', retain=True):
+-        r""" Open this file, read all lines, return them in a list.
+-
+-        Optional arguments:
+-            `encoding` - The Unicode encoding (or character set) of
+-                the file.  The default is ``None``, meaning the content
+-                of the file is read as 8-bit characters and returned
+-                as a list of (non-Unicode) str objects.
+-            `errors` - How to handle Unicode errors; see help(str.decode)
+-                for the options.  Default is ``'strict'``.
+-            `retain` - If ``True``, retain newline characters; but all newline
+-                character combinations (``'\r'``, ``'\n'``, ``'\r\n'``) are
+-                translated to ``'\n'``.  If ``False``, newline characters are
+-                stripped off.  Default is ``True``.
+-
+-        This uses ``'U'`` mode.
+-
+-        .. seealso:: :meth:`text`
+-        """
+-        if encoding is None and retain:
+-            with self.open('U') as f:
+-                return f.readlines()
+-        else:
+-            return self.text(encoding, errors).splitlines(retain)
+-
+-    def write_lines(self, lines, encoding=None, errors='strict',
+-                    linesep=os.linesep, append=False):
+-        r""" Write the given lines of text to this file.
+-
+-        By default this overwrites any existing file at this path.
+-
+-        This puts a platform-specific newline sequence on every line.
+-        See `linesep` below.
+-
+-            `lines` - A list of strings.
+-
+-            `encoding` - A Unicode encoding to use.  This applies only if
+-                `lines` contains any Unicode strings.
+-
+-            `errors` - How to handle errors in Unicode encoding.  This
+-                also applies only to Unicode strings.
+-
+-            linesep - The desired line-ending.  This line-ending is
+-                applied to every line.  If a line already has any
+-                standard line ending (``'\r'``, ``'\n'``, ``'\r\n'``,
+-                ``u'\x85'``, ``u'\r\x85'``, ``u'\u2028'``), that will
+-                be stripped off and this will be used instead.  The
+-                default is os.linesep, which is platform-dependent
+-                (``'\r\n'`` on Windows, ``'\n'`` on Unix, etc.).
+-                Specify ``None`` to write the lines as-is, like
+-                :meth:`file.writelines`.
+-
+-        Use the keyword argument ``append=True`` to append lines to the
+-        file.  The default is to overwrite the file.
+-
+-        .. warning ::
+-
+-            When you use this with Unicode data, if the encoding of the
+-            existing data in the file is different from the encoding
+-            you specify with the `encoding=` parameter, the result is
+-            mixed-encoding data, which can really confuse someone trying
+-            to read the file later.
+-        """
+-        with self.open('ab' if append else 'wb') as f:
+-            for l in lines:
+-                isUnicode = isinstance(l, text_type)
+-                if linesep is not None:
+-                    pattern = U_NL_END if isUnicode else NL_END
+-                    l = pattern.sub('', l) + linesep
+-                if isUnicode:
+-                    l = l.encode(encoding or sys.getdefaultencoding(), errors)
+-                f.write(l)
+-
+-    def read_md5(self):
+-        """ Calculate the md5 hash for this file.
+-
+-        This reads through the entire file.
+-
+-        .. seealso:: :meth:`read_hash`
+-        """
+-        return self.read_hash('md5')
+-
+-    def _hash(self, hash_name):
+-        """ Returns a hash object for the file at the current path.
+-
+-            `hash_name` should be a hash algo name (such as ``'md5'`` or ``'sha1'``)
+-            that's available in the :mod:`hashlib` module.
+-        """
+-        m = hashlib.new(hash_name)
+-        for chunk in self.chunks(8192, mode="rb"):
+-            m.update(chunk)
+-        return m
+-
+-    def read_hash(self, hash_name):
+-        """ Calculate given hash for this file.
+-
+-        List of supported hashes can be obtained from :mod:`hashlib` package.
+-        This reads the entire file.
+-
+-        .. seealso:: :meth:`hashlib.hash.digest`
+-        """
+-        return self._hash(hash_name).digest()
+-
+-    def read_hexhash(self, hash_name):
+-        """ Calculate given hash for this file, returning hexdigest.
+-
+-        List of supported hashes can be obtained from :mod:`hashlib` package.
+-        This reads the entire file.
+-
+-        .. seealso:: :meth:`hashlib.hash.hexdigest`
+-        """
+-        return self._hash(hash_name).hexdigest()
+-
+-    # --- Methods for querying the filesystem.
+-    # N.B. On some platforms, the os.path functions may be implemented in C
+-    # (e.g. isdir on Windows, Python 3.2.2), and compiled functions don't get
+-    # bound. Playing it safe and wrapping them all in method calls.
+-
+-    def isabs(self):
+-        """ .. seealso:: :func:`os.path.isabs` """
+-        return self.module.isabs(self)
+-
+-    def exists(self):
+-        """ .. seealso:: :func:`os.path.exists` """
+-        return self.module.exists(self)
+-
+-    def isdir(self):
+-        """ .. seealso:: :func:`os.path.isdir` """
+-        return self.module.isdir(self)
+-
+-    def isfile(self):
+-        """ .. seealso:: :func:`os.path.isfile` """
+-        return self.module.isfile(self)
+-
+-    def islink(self):
+-        """ .. seealso:: :func:`os.path.islink` """
+-        return self.module.islink(self)
+-
+-    def ismount(self):
+-        """ .. seealso:: :func:`os.path.ismount` """
+-        return self.module.ismount(self)
+-
+-    def samefile(self, other):
+-        """ .. seealso:: :func:`os.path.samefile` """
+-        if not hasattr(self.module, 'samefile'):
+-            other = Path(other).realpath().normpath().normcase()
+-            return self.realpath().normpath().normcase() == other
+-        return self.module.samefile(self, other)
+-
+-    def getatime(self):
+-        """ .. seealso:: :attr:`atime`, :func:`os.path.getatime` """
+-        return self.module.getatime(self)
+-
+-    atime = property(
+-        getatime, None, None,
+-        """ Last access time of the file.
+-
+-        .. seealso:: :meth:`getatime`, :func:`os.path.getatime`
+-        """)
+-
+-    def getmtime(self):
+-        """ .. seealso:: :attr:`mtime`, :func:`os.path.getmtime` """
+-        return self.module.getmtime(self)
+-
+-    mtime = property(
+-        getmtime, None, None,
+-        """ Last-modified time of the file.
+-
+-        .. seealso:: :meth:`getmtime`, :func:`os.path.getmtime`
+-        """)
+-
+-    def getctime(self):
+-        """ .. seealso:: :attr:`ctime`, :func:`os.path.getctime` """
+-        return self.module.getctime(self)
+-
+-    ctime = property(
+-        getctime, None, None,
+-        """ Creation time of the file.
+-
+-        .. seealso:: :meth:`getctime`, :func:`os.path.getctime`
+-        """)
+-
+-    def getsize(self):
+-        """ .. seealso:: :attr:`size`, :func:`os.path.getsize` """
+-        return self.module.getsize(self)
+-
+-    size = property(
+-        getsize, None, None,
+-        """ Size of the file, in bytes.
+-
+-        .. seealso:: :meth:`getsize`, :func:`os.path.getsize`
+-        """)
+-
+-    if hasattr(os, 'access'):
+-        def access(self, mode):
+-            """ Return ``True`` if current user has access to this path.
+-
+-            mode - One of the constants :data:`os.F_OK`, :data:`os.R_OK`,
+-            :data:`os.W_OK`, :data:`os.X_OK`
+-
+-            .. seealso:: :func:`os.access`
+-            """
+-            return os.access(self, mode)
+-
+-    def stat(self):
+-        """ Perform a ``stat()`` system call on this path.
+-
+-        .. seealso:: :meth:`lstat`, :func:`os.stat`
+-        """
+-        return os.stat(self)
+-
+-    def lstat(self):
+-        """ Like :meth:`stat`, but do not follow symbolic links.
+-
+-        .. seealso:: :meth:`stat`, :func:`os.lstat`
+-        """
+-        return os.lstat(self)
+-
+-    def __get_owner_windows(self):
+-        """
+-        Return the name of the owner of this file or directory. Follow
+-        symbolic links.
+-
+-        Return a name of the form ``r'DOMAIN\\User Name'``; may be a group.
+-
+-        .. seealso:: :attr:`owner`
+-        """
+-        desc = win32security.GetFileSecurity(
+-            self, win32security.OWNER_SECURITY_INFORMATION)
+-        sid = desc.GetSecurityDescriptorOwner()
+-        account, domain, typecode = win32security.LookupAccountSid(None, sid)
+-        return domain + '\\' + account
+-
+-    def __get_owner_unix(self):
+-        """
+-        Return the name of the owner of this file or directory. Follow
+-        symbolic links.
+-
+-        .. seealso:: :attr:`owner`
+-        """
+-        st = self.stat()
+-        return pwd.getpwuid(st.st_uid).pw_name
+-
+-    def __get_owner_not_implemented(self):
+-        raise NotImplementedError("Ownership not available on this platform.")
+-
+-    if 'win32security' in globals():
+-        get_owner = __get_owner_windows
+-    elif 'pwd' in globals():
+-        get_owner = __get_owner_unix
+-    else:
+-        get_owner = __get_owner_not_implemented
+-
+-    owner = property(
+-        get_owner, None, None,
+-        """ Name of the owner of this file or directory.
+-
+-        .. seealso:: :meth:`get_owner`""")
+-
+-    if hasattr(os, 'statvfs'):
+-        def statvfs(self):
+-            """ Perform a ``statvfs()`` system call on this path.
+-
+-            .. seealso:: :func:`os.statvfs`
+-            """
+-            return os.statvfs(self)
+-
+-    if hasattr(os, 'pathconf'):
+-        def pathconf(self, name):
+-            """ .. seealso:: :func:`os.pathconf` """
+-            return os.pathconf(self, name)
+-
+-    #
+-    # --- Modifying operations on files and directories
+-
+-    def utime(self, times):
+-        """ Set the access and modified times of this file.
+-
+-        .. seealso:: :func:`os.utime`
+-        """
+-        os.utime(self, times)
+-        return self
+-
+-    def chmod(self, mode):
+-        """
+-        Set the mode. May be the new mode (os.chmod behavior) or a `symbolic
+-        mode <http://en.wikipedia.org/wiki/Chmod#Symbolic_modes>`_.
+-
+-        .. seealso:: :func:`os.chmod`
+-        """
+-        if isinstance(mode, string_types):
+-            mask = _multi_permission_mask(mode)
+-            mode = mask(self.stat().st_mode)
+-        os.chmod(self, mode)
+-        return self
+-
+-    def chown(self, uid=-1, gid=-1):
+-        """
+-        Change the owner and group by names rather than the uid or gid numbers.
+-
+-        .. seealso:: :func:`os.chown`
+-        """
+-        if hasattr(os, 'chown'):
+-            if 'pwd' in globals() and isinstance(uid, string_types):
+-                uid = pwd.getpwnam(uid).pw_uid
+-            if 'grp' in globals() and isinstance(gid, string_types):
+-                gid = grp.getgrnam(gid).gr_gid
+-            os.chown(self, uid, gid)
+-        else:
+-            raise NotImplementedError("Ownership not available on this platform.")
+-        return self
+-
+-    def rename(self, new):
+-        """ .. seealso:: :func:`os.rename` """
+-        os.rename(self, new)
+-        return self._next_class(new)
+-
+-    def renames(self, new):
+-        """ .. seealso:: :func:`os.renames` """
+-        os.renames(self, new)
+-        return self._next_class(new)
+-
+-    #
+-    # --- Create/delete operations on directories
+-
+-    def mkdir(self, mode=0o777):
+-        """ .. seealso:: :func:`os.mkdir` """
+-        os.mkdir(self, mode)
+-        return self
+-
+-    def mkdir_p(self, mode=0o777):
+-        """ Like :meth:`mkdir`, but does not raise an exception if the
+-        directory already exists. """
+-        try:
+-            self.mkdir(mode)
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    def makedirs(self, mode=0o777):
+-        """ .. seealso:: :func:`os.makedirs` """
+-        os.makedirs(self, mode)
+-        return self
+-
+-    def makedirs_p(self, mode=0o777):
+-        """ Like :meth:`makedirs`, but does not raise an exception if the
+-        directory already exists. """
+-        try:
+-            self.makedirs(mode)
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    def rmdir(self):
+-        """ .. seealso:: :func:`os.rmdir` """
+-        os.rmdir(self)
+-        return self
+-
+-    def rmdir_p(self):
+-        """ Like :meth:`rmdir`, but does not raise an exception if the
+-        directory is not empty or does not exist. """
+-        try:
+-            self.rmdir()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOTEMPTY and e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    def removedirs(self):
+-        """ .. seealso:: :func:`os.removedirs` """
+-        os.removedirs(self)
+-        return self
+-
+-    def removedirs_p(self):
+-        """ Like :meth:`removedirs`, but does not raise an exception if the
+-        directory is not empty or does not exist. """
+-        try:
+-            self.removedirs()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOTEMPTY and e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    # --- Modifying operations on files
+-
+-    def touch(self):
+-        """ Set the access/modified times of this file to the current time.
+-        Create the file if it does not exist.
+-        """
+-        fd = os.open(self, os.O_WRONLY | os.O_CREAT, 0o666)
+-        os.close(fd)
+-        os.utime(self, None)
+-        return self
+-
+-    def remove(self):
+-        """ .. seealso:: :func:`os.remove` """
+-        os.remove(self)
+-        return self
+-
+-    def remove_p(self):
+-        """ Like :meth:`remove`, but does not raise an exception if the
+-        file does not exist. """
+-        try:
+-            self.unlink()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOENT:
+-                raise
+-        return self
+-
+-    def unlink(self):
+-        """ .. seealso:: :func:`os.unlink` """
+-        os.unlink(self)
+-        return self
+-
+-    def unlink_p(self):
+-        """ Like :meth:`unlink`, but does not raise an exception if the
+-        file does not exist. """
+-        self.remove_p()
+-        return self
+-
+-    # --- Links
+-
+-    if hasattr(os, 'link'):
+-        def link(self, newpath):
+-            """ Create a hard link at `newpath`, pointing to this file.
+-
+-            .. seealso:: :func:`os.link`
+-            """
+-            os.link(self, newpath)
+-            return self._next_class(newpath)
+-
+-    if hasattr(os, 'symlink'):
+-        def symlink(self, newlink):
+-            """ Create a symbolic link at `newlink`, pointing here.
+-
+-            .. seealso:: :func:`os.symlink`
+-            """
+-            os.symlink(self, newlink)
+-            return self._next_class(newlink)
+-
+-    if hasattr(os, 'readlink'):
+-        def readlink(self):
+-            """ Return the path to which this symbolic link points.
+-
+-            The result may be an absolute or a relative path.
+-
+-            .. seealso:: :meth:`readlinkabs`, :func:`os.readlink`
+-            """
+-            return self._next_class(os.readlink(self))
+-
+-        def readlinkabs(self):
+-            """ Return the path to which this symbolic link points.
+-
+-            The result is always an absolute path.
+-
+-            .. seealso:: :meth:`readlink`, :func:`os.readlink`
+-            """
+-            p = self.readlink()
+-            if p.isabs():
+-                return p
+-            else:
+-                return (self.parent / p).abspath()
+-
+-    # High-level functions from shutil
+-    # These functions will be bound to the instance such that
+-    # Path(name).copy(target) will invoke shutil.copy(name, target)
+-
+-    copyfile = shutil.copyfile
+-    copymode = shutil.copymode
+-    copystat = shutil.copystat
+-    copy = shutil.copy
+-    copy2 = shutil.copy2
+-    copytree = shutil.copytree
+-    if hasattr(shutil, 'move'):
+-        move = shutil.move
+-    rmtree = shutil.rmtree
+-
+-    def rmtree_p(self):
+-        """ Like :meth:`rmtree`, but does not raise an exception if the
+-        directory does not exist. """
+-        try:
+-            self.rmtree()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOENT:
+-                raise
+-        return self
+-
+-    def chdir(self):
+-        """ .. seealso:: :func:`os.chdir` """
+-        os.chdir(self)
+-
+-    cd = chdir
+-
+-    def merge_tree(self, dst, symlinks=False, *args, **kwargs):
+-        """
+-        Copy entire contents of self to dst, overwriting existing
+-        contents in dst with those in self.
+-
+-        If the additional keyword `update` is True, each
+-        `src` will only be copied if `dst` does not exist,
+-        or `src` is newer than `dst`.
+-
+-        Note that the technique employed stages the files in a temporary
+-        directory first, so this function is not suitable for merging
+-        trees with large files, especially if the temporary directory
+-        is not capable of storing a copy of the entire source tree.
+-        """
+-        update = kwargs.pop('update', False)
+-        with tempdir() as _temp_dir:
+-            # first copy the tree to a stage directory to support
+-            #  the parameters and behavior of copytree.
+-            stage = _temp_dir / str(hash(self))
+-            self.copytree(stage, symlinks, *args, **kwargs)
+-            # now copy everything from the stage directory using
+-            #  the semantics of dir_util.copy_tree
+-            dir_util.copy_tree(stage, dst, preserve_symlinks=symlinks,
+-                update=update)
+-
+-    #
+-    # --- Special stuff from os
+-
+-    if hasattr(os, 'chroot'):
+-        def chroot(self):
+-            """ .. seealso:: :func:`os.chroot` """
+-            os.chroot(self)
+-
+-    if hasattr(os, 'startfile'):
+-        def startfile(self):
+-            """ .. seealso:: :func:`os.startfile` """
+-            os.startfile(self)
+-            return self
+-
+-    # in-place re-writing, courtesy of Martijn Pieters
+-    # http://www.zopatista.com/python/2013/11/26/inplace-file-rewriting/
+-    @contextlib.contextmanager
+-    def in_place(self, mode='r', buffering=-1, encoding=None, errors=None,
+-            newline=None, backup_extension=None):
+-        """
+-        A context in which a file may be re-written in-place with new content.
+-
+-        Yields a tuple of :samp:`({readable}, {writable})` file objects, where `writable`
+-        replaces `readable`.
+-
+-        If an exception occurs, the old file is restored, removing the
+-        written data.
+-
+-        Mode *must not* use ``'w'``, ``'a'``, or ``'+'``; only read-only-modes are
+-        allowed. A :exc:`ValueError` is raised on invalid modes.
+-
+-        For example, to add line numbers to a file::
+-
+-            p = Path(filename)
+-            assert p.isfile()
+-            with p.in_place() as (reader, writer):
+-                for number, line in enumerate(reader, 1):
+-                    writer.write('{0:3}: '.format(number)))
+-                    writer.write(line)
+-
+-        Thereafter, the file at `filename` will have line numbers in it.
+-        """
+-        import io
+-
+-        if set(mode).intersection('wa+'):
+-            raise ValueError('Only read-only file modes can be used')
+-
+-        # move existing file to backup, create new file with same permissions
+-        # borrowed extensively from the fileinput module
+-        backup_fn = self + (backup_extension or os.extsep + 'bak')
+-        try:
+-            os.unlink(backup_fn)
+-        except os.error:
+-            pass
+-        os.rename(self, backup_fn)
+-        readable = io.open(backup_fn, mode, buffering=buffering,
+-            encoding=encoding, errors=errors, newline=newline)
+-        try:
+-            perm = os.fstat(readable.fileno()).st_mode
+-        except OSError:
+-            writable = open(self, 'w' + mode.replace('r', ''),
+-                buffering=buffering, encoding=encoding, errors=errors,
+-                newline=newline)
+-        else:
+-            os_mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
+-            if hasattr(os, 'O_BINARY'):
+-                os_mode |= os.O_BINARY
+-            fd = os.open(self, os_mode, perm)
+-            writable = io.open(fd, "w" + mode.replace('r', ''),
+-                buffering=buffering, encoding=encoding, errors=errors,
+-                newline=newline)
+-            try:
+-                if hasattr(os, 'chmod'):
+-                    os.chmod(self, perm)
+-            except OSError:
+-                pass
+-        try:
+-            yield readable, writable
+-        except Exception:
+-            # move backup back
+-            readable.close()
+-            writable.close()
+-            try:
+-                os.unlink(self)
+-            except os.error:
+-                pass
+-            os.rename(backup_fn, self)
+-            raise
+-        else:
+-            readable.close()
+-            writable.close()
+-        finally:
+-            try:
+-                os.unlink(backup_fn)
+-            except os.error:
+-                pass
+-
+-    @ClassProperty
+-    @classmethod
+-    def special(cls):
+-        """
+-        Return a SpecialResolver object suitable referencing a suitable
+-        directory for the relevant platform for the given
+-        type of content.
+-
+-        For example, to get a user config directory, invoke:
+-
+-            dir = Path.special().user.config
+-
+-        Uses the `appdirs
+-        <https://pypi.python.org/pypi/appdirs/1.4.0>`_ to resolve
+-        the paths in a platform-friendly way.
+-
+-        To create a config directory for 'My App', consider:
+-
+-            dir = Path.special("My App").user.config.makedirs_p()
+-
+-        If the ``appdirs`` module is not installed, invocation
+-        of special will raise an ImportError.
+-        """
+-        return functools.partial(SpecialResolver, cls)
+-
+-
+-class SpecialResolver(object):
+-    class ResolverScope:
+-        def __init__(self, paths, scope):
+-            self.paths = paths
+-            self.scope = scope
+-
+-        def __getattr__(self, class_):
+-            return self.paths.get_dir(self.scope, class_)
+-
+-    def __init__(self, path_class, *args, **kwargs):
+-        appdirs = importlib.import_module('appdirs')
+-
+-        # let appname default to None until
+-        # https://github.com/ActiveState/appdirs/issues/55 is solved.
+-        not args and kwargs.setdefault('appname', None)
+-
+-        vars(self).update(
+-            path_class=path_class,
+-            wrapper=appdirs.AppDirs(*args, **kwargs),
+-        )
+-
+-    def __getattr__(self, scope):
+-        return self.ResolverScope(self, scope)
+-
+-    def get_dir(self, scope, class_):
+-        """
+-        Return the callable function from appdirs, but with the
+-        result wrapped in self.path_class
+-        """
+-        prop_name = '{scope}_{class_}_dir'.format(**locals())
+-        value = getattr(self.wrapper, prop_name)
+-        MultiPath = Multi.for_class(self.path_class)
+-        return MultiPath.detect(value)
+-
+-
+-class Multi:
+-    """
+-    A mix-in for a Path which may contain multiple Path separated by pathsep.
+-    """
+-    @classmethod
+-    def for_class(cls, path_cls):
+-        name = 'Multi' + path_cls.__name__
+-        if PY2:
+-            name = str(name)
+-        return type(name, (cls, path_cls), {})
+-
+-    @classmethod
+-    def detect(cls, input):
+-        if os.pathsep not in input:
+-            cls = cls._next_class
+-        return cls(input)
+-
+-    def __iter__(self):
+-        return iter(map(self._next_class, self.split(os.pathsep)))
+-
+-    @ClassProperty
+-    @classmethod
+-    def _next_class(cls):
+-        """
+-        Multi-subclasses should use the parent class
+-        """
+-        return next(
+-            class_
+-            for class_ in cls.__mro__
+-            if not issubclass(class_, Multi)
+-        )
+-
+-
+-class tempdir(Path):
+-    """
+-    A temporary directory via :func:`tempfile.mkdtemp`, and constructed with the
+-    same parameters that you can use as a context manager.
+-
+-    Example:
+-
+-        with tempdir() as d:
+-            # do stuff with the Path object "d"
+-
+-        # here the directory is deleted automatically
+-
+-    .. seealso:: :func:`tempfile.mkdtemp`
+-    """
+-
+-    @ClassProperty
+-    @classmethod
+-    def _next_class(cls):
+-        return Path
+-
+-    def __new__(cls, *args, **kwargs):
+-        dirname = tempfile.mkdtemp(*args, **kwargs)
+-        return super(tempdir, cls).__new__(cls, dirname)
+-
+-    def __init__(self, *args, **kwargs):
+-        pass
+-
+-    def __enter__(self):
+-        return self
+-
+-    def __exit__(self, exc_type, exc_value, traceback):
+-        if not exc_value:
+-            self.rmtree()
+-
+-
+-def _multi_permission_mask(mode):
+-    """
+-    Support multiple, comma-separated Unix chmod symbolic modes.
+-
+-    >>> _multi_permission_mask('a=r,u+w')(0) == 0o644
+-    True
+-    """
+-    compose = lambda f, g: lambda *args, **kwargs: g(f(*args, **kwargs))
+-    return functools.reduce(compose, map(_permission_mask, mode.split(',')))
+-
+-
+-def _permission_mask(mode):
+-    """
+-    Convert a Unix chmod symbolic mode like ``'ugo+rwx'`` to a function
+-    suitable for applying to a mask to affect that change.
+-
+-    >>> mask = _permission_mask('ugo+rwx')
+-    >>> mask(0o554) == 0o777
+-    True
+-
+-    >>> _permission_mask('go-x')(0o777) == 0o766
+-    True
+-
+-    >>> _permission_mask('o-x')(0o445) == 0o444
+-    True
+-
+-    >>> _permission_mask('a+x')(0) == 0o111
+-    True
+-
+-    >>> _permission_mask('a=rw')(0o057) == 0o666
+-    True
+-
+-    >>> _permission_mask('u=x')(0o666) == 0o166
+-    True
+-
+-    >>> _permission_mask('g=')(0o157) == 0o107
+-    True
+-    """
+-    # parse the symbolic mode
+-    parsed = re.match('(?P<who>[ugoa]+)(?P<op>[-+=])(?P<what>[rwx]*)$', mode)
+-    if not parsed:
+-        raise ValueError("Unrecognized symbolic mode", mode)
+-
+-    # generate a mask representing the specified permission
+-    spec_map = dict(r=4, w=2, x=1)
+-    specs = (spec_map[perm] for perm in parsed.group('what'))
+-    spec = functools.reduce(operator.or_, specs, 0)
+-
+-    # now apply spec to each subject in who
+-    shift_map = dict(u=6, g=3, o=0)
+-    who = parsed.group('who').replace('a', 'ugo')
+-    masks = (spec << shift_map[subj] for subj in who)
+-    mask = functools.reduce(operator.or_, masks)
+-
+-    op = parsed.group('op')
+-
+-    # if op is -, invert the mask
+-    if op == '-':
+-        mask ^= 0o777
+-
+-    # if op is =, retain extant values for unreferenced subjects
+-    if op == '=':
+-        masks = (0o7 << shift_map[subj] for subj in who)
+-        retain = functools.reduce(operator.or_, masks) ^ 0o777
+-
+-    op_map = {
+-        '+': operator.or_,
+-        '-': operator.and_,
+-        '=': lambda mask, target: target & retain ^ mask,
+-    }
+-    return functools.partial(op_map[op], mask)
+-
+-
+-class CaseInsensitivePattern(text_type):
+-    """
+-    A string with a ``'normcase'`` property, suitable for passing to
+-    :meth:`listdir`, :meth:`dirs`, :meth:`files`, :meth:`walk`,
+-    :meth:`walkdirs`, or :meth:`walkfiles` to match case-insensitive.
+-
+-    For example, to get all files ending in .py, .Py, .pY, or .PY in the
+-    current directory::
+-
+-        from path import Path, CaseInsensitivePattern as ci
+-        Path('.').files(ci('*.py'))
+-    """
+-
+-    @property
+-    def normcase(self):
+-        return __import__('ntpath').normcase
+-
+-########################
+-# Backward-compatibility
+-class path(Path):
+-    def __new__(cls, *args, **kwargs):
+-        msg = "path is deprecated. Use Path instead."
+-        warnings.warn(msg, DeprecationWarning)
+-        return Path.__new__(cls, *args, **kwargs)
+-
+-
+-__all__ += ['path']
+-########################
+diff --git a/tasks/_vendor/pathlib.py b/tasks/_vendor/pathlib.py
+deleted file mode 100644
+index 9ab0e70..0000000
+--- a/tasks/_vendor/pathlib.py
++++ /dev/null
+@@ -1,1280 +0,0 @@
+-import fnmatch
+-import functools
+-import io
+-import ntpath
+-import os
+-import posixpath
+-import re
+-import sys
+-import time
+-from collections import Sequence
+-from contextlib import contextmanager
+-from errno import EINVAL, ENOENT
+-from operator import attrgetter
+-from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
+-try:
+-    from urllib import quote as urlquote, quote as urlquote_from_bytes
+-except ImportError:
+-    from urllib.parse import quote as urlquote, quote_from_bytes as urlquote_from_bytes
+-
+-
+-try:
+-    intern = intern
+-except NameError:
+-    intern = sys.intern
+-try:
+-    basestring = basestring
+-except NameError:
+-    basestring = str
+-
+-supports_symlinks = True
+-try:
+-    import nt
+-except ImportError:
+-    nt = None
+-else:
+-    if sys.getwindowsversion()[:2] >= (6, 0) and sys.version_info >= (3, 2):
+-        from nt import _getfinalpathname
+-    else:
+-        supports_symlinks = False
+-        _getfinalpathname = None
+-
+-
+-__all__ = [
+-    "PurePath", "PurePosixPath", "PureWindowsPath",
+-    "Path", "PosixPath", "WindowsPath",
+-    ]
+-
+-#
+-# Internals
+-#
+-
+-_py2 = sys.version_info < (3,)
+-_py2_fs_encoding = 'ascii'
+-
+-def _py2_fsencode(parts):
+-    # py2 => minimal unicode support
+-    return [part.encode(_py2_fs_encoding) if isinstance(part, unicode)
+-            else part for part in parts]
+-
+-def _is_wildcard_pattern(pat):
+-    # Whether this pattern needs actual matching using fnmatch, or can
+-    # be looked up directly as a file.
+-    return "*" in pat or "?" in pat or "[" in pat
+-
+-
+-class _Flavour(object):
+-    """A flavour implements a particular (platform-specific) set of path
+-    semantics."""
+-
+-    def __init__(self):
+-        self.join = self.sep.join
+-
+-    def parse_parts(self, parts):
+-        if _py2:
+-            parts = _py2_fsencode(parts)
+-        parsed = []
+-        sep = self.sep
+-        altsep = self.altsep
+-        drv = root = ''
+-        it = reversed(parts)
+-        for part in it:
+-            if not part:
+-                continue
+-            if altsep:
+-                part = part.replace(altsep, sep)
+-            drv, root, rel = self.splitroot(part)
+-            if sep in rel:
+-                for x in reversed(rel.split(sep)):
+-                    if x and x != '.':
+-                        parsed.append(intern(x))
+-            else:
+-                if rel and rel != '.':
+-                    parsed.append(intern(rel))
+-            if drv or root:
+-                if not drv:
+-                    # If no drive is present, try to find one in the previous
+-                    # parts. This makes the result of parsing e.g.
+-                    # ("C:", "/", "a") reasonably intuitive.
+-                    for part in it:
+-                        drv = self.splitroot(part)[0]
+-                        if drv:
+-                            break
+-                break
+-        if drv or root:
+-            parsed.append(drv + root)
+-        parsed.reverse()
+-        return drv, root, parsed
+-
+-    def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2):
+-        """
+-        Join the two paths represented by the respective
+-        (drive, root, parts) tuples.  Return a new (drive, root, parts) tuple.
+-        """
+-        if root2:
+-            if not drv2 and drv:
+-                return drv, root2, [drv + root2] + parts2[1:]
+-        elif drv2:
+-            if drv2 == drv or self.casefold(drv2) == self.casefold(drv):
+-                # Same drive => second path is relative to the first
+-                return drv, root, parts + parts2[1:]
+-        else:
+-            # Second path is non-anchored (common case)
+-            return drv, root, parts + parts2
+-        return drv2, root2, parts2
+-
+-
+-class _WindowsFlavour(_Flavour):
+-    # Reference for Windows paths can be found at
+-    # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
+-
+-    sep = '\\'
+-    altsep = '/'
+-    has_drv = True
+-    pathmod = ntpath
+-
+-    is_supported = (nt is not None)
+-
+-    drive_letters = (
+-        set(chr(x) for x in range(ord('a'), ord('z') + 1)) |
+-        set(chr(x) for x in range(ord('A'), ord('Z') + 1))
+-    )
+-    ext_namespace_prefix = '\\\\?\\'
+-
+-    reserved_names = (
+-        set(['CON', 'PRN', 'AUX', 'NUL']) |
+-        set(['COM%d' % i for i in range(1, 10)]) |
+-        set(['LPT%d' % i for i in range(1, 10)])
+-        )
+-
+-    # Interesting findings about extended paths:
+-    # - '\\?\c:\a', '//?/c:\a' and '//?/c:/a' are all supported
+-    #   but '\\?\c:/a' is not
+-    # - extended paths are always absolute; "relative" extended paths will
+-    #   fail.
+-
+-    def splitroot(self, part, sep=sep):
+-        first = part[0:1]
+-        second = part[1:2]
+-        if (second == sep and first == sep):
+-            # XXX extended paths should also disable the collapsing of "."
+-            # components (according to MSDN docs).
+-            prefix, part = self._split_extended_path(part)
+-            first = part[0:1]
+-            second = part[1:2]
+-        else:
+-            prefix = ''
+-        third = part[2:3]
+-        if (second == sep and first == sep and third != sep):
+-            # is a UNC path:
+-            # vvvvvvvvvvvvvvvvvvvvv root
+-            # \\machine\mountpoint\directory\etc\...
+-            #            directory ^^^^^^^^^^^^^^
+-            index = part.find(sep, 2)
+-            if index != -1:
+-                index2 = part.find(sep, index + 1)
+-                # a UNC path can't have two slashes in a row
+-                # (after the initial two)
+-                if index2 != index + 1:
+-                    if index2 == -1:
+-                        index2 = len(part)
+-                    if prefix:
+-                        return prefix + part[1:index2], sep, part[index2+1:]
+-                    else:
+-                        return part[:index2], sep, part[index2+1:]
+-        drv = root = ''
+-        if second == ':' and first in self.drive_letters:
+-            drv = part[:2]
+-            part = part[2:]
+-            first = third
+-        if first == sep:
+-            root = first
+-            part = part.lstrip(sep)
+-        return prefix + drv, root, part
+-
+-    def casefold(self, s):
+-        return s.lower()
+-
+-    def casefold_parts(self, parts):
+-        return [p.lower() for p in parts]
+-
+-    def resolve(self, path):
+-        s = str(path)
+-        if not s:
+-            return os.getcwd()
+-        if _getfinalpathname is not None:
+-            return self._ext_to_normal(_getfinalpathname(s))
+-        # Means fallback on absolute
+-        return None
+-
+-    def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix):
+-        prefix = ''
+-        if s.startswith(ext_prefix):
+-            prefix = s[:4]
+-            s = s[4:]
+-            if s.startswith('UNC\\'):
+-                prefix += s[:3]
+-                s = '\\' + s[3:]
+-        return prefix, s
+-
+-    def _ext_to_normal(self, s):
+-        # Turn back an extended path into a normal DOS-like path
+-        return self._split_extended_path(s)[1]
+-
+-    def is_reserved(self, parts):
+-        # NOTE: the rules for reserved names seem somewhat complicated
+-        # (e.g. r"..\NUL" is reserved but not r"foo\NUL").
+-        # We err on the side of caution and return True for paths which are
+-        # not considered reserved by Windows.
+-        if not parts:
+-            return False
+-        if parts[0].startswith('\\\\'):
+-            # UNC paths are never reserved
+-            return False
+-        return parts[-1].partition('.')[0].upper() in self.reserved_names
+-
+-    def make_uri(self, path):
+-        # Under Windows, file URIs use the UTF-8 encoding.
+-        drive = path.drive
+-        if len(drive) == 2 and drive[1] == ':':
+-            # It's a path on a local drive => 'file:///c:/a/b'
+-            rest = path.as_posix()[2:].lstrip('/')
+-            return 'file:///%s/%s' % (
+-                drive, urlquote_from_bytes(rest.encode('utf-8')))
+-        else:
+-            # It's a path on a network drive => 'file://host/share/a/b'
+-            return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8'))
+-
+-
+-class _PosixFlavour(_Flavour):
+-    sep = '/'
+-    altsep = ''
+-    has_drv = False
+-    pathmod = posixpath
+-
+-    is_supported = (os.name != 'nt')
+-
+-    def splitroot(self, part, sep=sep):
+-        if part and part[0] == sep:
+-            stripped_part = part.lstrip(sep)
+-            # According to POSIX path resolution:
+-            # http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11
+-            # "A pathname that begins with two successive slashes may be
+-            # interpreted in an implementation-defined manner, although more
+-            # than two leading slashes shall be treated as a single slash".
+-            if len(part) - len(stripped_part) == 2:
+-                return '', sep * 2, stripped_part
+-            else:
+-                return '', sep, stripped_part
+-        else:
+-            return '', '', part
+-
+-    def casefold(self, s):
+-        return s
+-
+-    def casefold_parts(self, parts):
+-        return parts
+-
+-    def resolve(self, path):
+-        sep = self.sep
+-        accessor = path._accessor
+-        seen = {}
+-        def _resolve(path, rest):
+-            if rest.startswith(sep):
+-                path = ''
+-
+-            for name in rest.split(sep):
+-                if not name or name == '.':
+-                    # current dir
+-                    continue
+-                if name == '..':
+-                    # parent dir
+-                    path, _, _ = path.rpartition(sep)
+-                    continue
+-                newpath = path + sep + name
+-                if newpath in seen:
+-                    # Already seen this path
+-                    path = seen[newpath]
+-                    if path is not None:
+-                        # use cached value
+-                        continue
+-                    # The symlink is not resolved, so we must have a symlink loop.
+-                    raise RuntimeError("Symlink loop from %r" % newpath)
+-                # Resolve the symbolic link
+-                try:
+-                    target = accessor.readlink(newpath)
+-                except OSError as e:
+-                    if e.errno != EINVAL:
+-                        raise
+-                    # Not a symlink
+-                    path = newpath
+-                else:
+-                    seen[newpath] = None # not resolved symlink
+-                    path = _resolve(path, target)
+-                    seen[newpath] = path # resolved symlink
+-
+-            return path
+-        # NOTE: according to POSIX, getcwd() cannot contain path components
+-        # which are symlinks.
+-        base = '' if path.is_absolute() else os.getcwd()
+-        return _resolve(base, str(path)) or sep
+-
+-    def is_reserved(self, parts):
+-        return False
+-
+-    def make_uri(self, path):
+-        # We represent the path using the local filesystem encoding,
+-        # for portability to other applications.
+-        bpath = bytes(path)
+-        return 'file://' + urlquote_from_bytes(bpath)
+-
+-
+-_windows_flavour = _WindowsFlavour()
+-_posix_flavour = _PosixFlavour()
+-
+-
+-class _Accessor:
+-    """An accessor implements a particular (system-specific or not) way of
+-    accessing paths on the filesystem."""
+-
+-
+-class _NormalAccessor(_Accessor):
+-
+-    def _wrap_strfunc(strfunc):
+-        @functools.wraps(strfunc)
+-        def wrapped(pathobj, *args):
+-            return strfunc(str(pathobj), *args)
+-        return staticmethod(wrapped)
+-
+-    def _wrap_binary_strfunc(strfunc):
+-        @functools.wraps(strfunc)
+-        def wrapped(pathobjA, pathobjB, *args):
+-            return strfunc(str(pathobjA), str(pathobjB), *args)
+-        return staticmethod(wrapped)
+-
+-    stat = _wrap_strfunc(os.stat)
+-
+-    lstat = _wrap_strfunc(os.lstat)
+-
+-    open = _wrap_strfunc(os.open)
+-
+-    listdir = _wrap_strfunc(os.listdir)
+-
+-    chmod = _wrap_strfunc(os.chmod)
+-
+-    if hasattr(os, "lchmod"):
+-        lchmod = _wrap_strfunc(os.lchmod)
+-    else:
+-        def lchmod(self, pathobj, mode):
+-            raise NotImplementedError("lchmod() not available on this system")
+-
+-    mkdir = _wrap_strfunc(os.mkdir)
+-
+-    unlink = _wrap_strfunc(os.unlink)
+-
+-    rmdir = _wrap_strfunc(os.rmdir)
+-
+-    rename = _wrap_binary_strfunc(os.rename)
+-
+-    if sys.version_info >= (3, 3):
+-        replace = _wrap_binary_strfunc(os.replace)
+-
+-    if nt:
+-        if supports_symlinks:
+-            symlink = _wrap_binary_strfunc(os.symlink)
+-        else:
+-            def symlink(a, b, target_is_directory):
+-                raise NotImplementedError("symlink() not available on this system")
+-    else:
+-        # Under POSIX, os.symlink() takes two args
+-        @staticmethod
+-        def symlink(a, b, target_is_directory):
+-            return os.symlink(str(a), str(b))
+-
+-    utime = _wrap_strfunc(os.utime)
+-
+-    # Helper for resolve()
+-    def readlink(self, path):
+-        return os.readlink(path)
+-
+-
+-_normal_accessor = _NormalAccessor()
+-
+-
+-#
+-# Globbing helpers
+-#
+-
+-@contextmanager
+-def _cached(func):
+-    try:
+-        func.__cached__
+-        yield func
+-    except AttributeError:
+-        cache = {}
+-        def wrapper(*args):
+-            try:
+-                return cache[args]
+-            except KeyError:
+-                value = cache[args] = func(*args)
+-                return value
+-        wrapper.__cached__ = True
+-        try:
+-            yield wrapper
+-        finally:
+-            cache.clear()
+-
+-def _make_selector(pattern_parts):
+-    pat = pattern_parts[0]
+-    child_parts = pattern_parts[1:]
+-    if pat == '**':
+-        cls = _RecursiveWildcardSelector
+-    elif '**' in pat:
+-        raise ValueError("Invalid pattern: '**' can only be an entire path component")
+-    elif _is_wildcard_pattern(pat):
+-        cls = _WildcardSelector
+-    else:
+-        cls = _PreciseSelector
+-    return cls(pat, child_parts)
+-
+-if hasattr(functools, "lru_cache"):
+-    _make_selector = functools.lru_cache()(_make_selector)
+-
+-
+-class _Selector:
+-    """A selector matches a specific glob pattern part against the children
+-    of a given path."""
+-
+-    def __init__(self, child_parts):
+-        self.child_parts = child_parts
+-        if child_parts:
+-            self.successor = _make_selector(child_parts)
+-        else:
+-            self.successor = _TerminatingSelector()
+-
+-    def select_from(self, parent_path):
+-        """Iterate over all child paths of `parent_path` matched by this
+-        selector.  This can contain parent_path itself."""
+-        path_cls = type(parent_path)
+-        is_dir = path_cls.is_dir
+-        exists = path_cls.exists
+-        listdir = parent_path._accessor.listdir
+-        return self._select_from(parent_path, is_dir, exists, listdir)
+-
+-
+-class _TerminatingSelector:
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        yield parent_path
+-
+-
+-class _PreciseSelector(_Selector):
+-
+-    def __init__(self, name, child_parts):
+-        self.name = name
+-        _Selector.__init__(self, child_parts)
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        if not is_dir(parent_path):
+-            return
+-        path = parent_path._make_child_relpath(self.name)
+-        if exists(path):
+-            for p in self.successor._select_from(path, is_dir, exists, listdir):
+-                yield p
+-
+-
+-class _WildcardSelector(_Selector):
+-
+-    def __init__(self, pat, child_parts):
+-        self.pat = re.compile(fnmatch.translate(pat))
+-        _Selector.__init__(self, child_parts)
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        if not is_dir(parent_path):
+-            return
+-        cf = parent_path._flavour.casefold
+-        for name in listdir(parent_path):
+-            casefolded = cf(name)
+-            if self.pat.match(casefolded):
+-                path = parent_path._make_child_relpath(name)
+-                for p in self.successor._select_from(path, is_dir, exists, listdir):
+-                    yield p
+-
+-
+-class _RecursiveWildcardSelector(_Selector):
+-
+-    def __init__(self, pat, child_parts):
+-        _Selector.__init__(self, child_parts)
+-
+-    def _iterate_directories(self, parent_path, is_dir, listdir):
+-        yield parent_path
+-        for name in listdir(parent_path):
+-            path = parent_path._make_child_relpath(name)
+-            if is_dir(path):
+-                for p in self._iterate_directories(path, is_dir, listdir):
+-                    yield p
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        if not is_dir(parent_path):
+-            return
+-        with _cached(listdir) as listdir:
+-            yielded = set()
+-            try:
+-                successor_select = self.successor._select_from
+-                for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
+-                    for p in successor_select(starting_point, is_dir, exists, listdir):
+-                        if p not in yielded:
+-                            yield p
+-                            yielded.add(p)
+-            finally:
+-                yielded.clear()
+-
+-
+-#
+-# Public API
+-#
+-
+-class _PathParents(Sequence):
+-    """This object provides sequence-like access to the logical ancestors
+-    of a path.  Don't try to construct it yourself."""
+-    __slots__ = ('_pathcls', '_drv', '_root', '_parts')
+-
+-    def __init__(self, path):
+-        # We don't store the instance to avoid reference cycles
+-        self._pathcls = type(path)
+-        self._drv = path._drv
+-        self._root = path._root
+-        self._parts = path._parts
+-
+-    def __len__(self):
+-        if self._drv or self._root:
+-            return len(self._parts) - 1
+-        else:
+-            return len(self._parts)
+-
+-    def __getitem__(self, idx):
+-        if idx < 0 or idx >= len(self):
+-            raise IndexError(idx)
+-        return self._pathcls._from_parsed_parts(self._drv, self._root,
+-                                                self._parts[:-idx - 1])
+-
+-    def __repr__(self):
+-        return "<{0}.parents>".format(self._pathcls.__name__)
+-
+-
+-class PurePath(object):
+-    """PurePath represents a filesystem path and offers operations which
+-    don't imply any actual filesystem I/O.  Depending on your system,
+-    instantiating a PurePath will return either a PurePosixPath or a
+-    PureWindowsPath object.  You can also instantiate either of these classes
+-    directly, regardless of your system.
+-    """
+-    __slots__ = (
+-        '_drv', '_root', '_parts',
+-        '_str', '_hash', '_pparts', '_cached_cparts',
+-    )
+-
+-    def __new__(cls, *args):
+-        """Construct a PurePath from one or several strings and or existing
+-        PurePath objects.  The strings and path objects are combined so as
+-        to yield a canonicalized path, which is incorporated into the
+-        new PurePath object.
+-        """
+-        if cls is PurePath:
+-            cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
+-        return cls._from_parts(args)
+-
+-    def __reduce__(self):
+-        # Using the parts tuple helps share interned path parts
+-        # when pickling related paths.
+-        return (self.__class__, tuple(self._parts))
+-
+-    @classmethod
+-    def _parse_args(cls, args):
+-        # This is useful when you don't want to create an instance, just
+-        # canonicalize some constructor arguments.
+-        parts = []
+-        for a in args:
+-            if isinstance(a, PurePath):
+-                parts += a._parts
+-            elif isinstance(a, basestring):
+-                parts.append(a)
+-            else:
+-                raise TypeError(
+-                    "argument should be a path or str object, not %r"
+-                    % type(a))
+-        return cls._flavour.parse_parts(parts)
+-
+-    @classmethod
+-    def _from_parts(cls, args, init=True):
+-        # We need to call _parse_args on the instance, so as to get the
+-        # right flavour.
+-        self = object.__new__(cls)
+-        drv, root, parts = self._parse_args(args)
+-        self._drv = drv
+-        self._root = root
+-        self._parts = parts
+-        if init:
+-            self._init()
+-        return self
+-
+-    @classmethod
+-    def _from_parsed_parts(cls, drv, root, parts, init=True):
+-        self = object.__new__(cls)
+-        self._drv = drv
+-        self._root = root
+-        self._parts = parts
+-        if init:
+-            self._init()
+-        return self
+-
+-    @classmethod
+-    def _format_parsed_parts(cls, drv, root, parts):
+-        if drv or root:
+-            return drv + root + cls._flavour.join(parts[1:])
+-        else:
+-            return cls._flavour.join(parts)
+-
+-    def _init(self):
+-        # Overriden in concrete Path
+-        pass
+-
+-    def _make_child(self, args):
+-        drv, root, parts = self._parse_args(args)
+-        drv, root, parts = self._flavour.join_parsed_parts(
+-            self._drv, self._root, self._parts, drv, root, parts)
+-        return self._from_parsed_parts(drv, root, parts)
+-
+-    def __str__(self):
+-        """Return the string representation of the path, suitable for
+-        passing to system calls."""
+-        try:
+-            return self._str
+-        except AttributeError:
+-            self._str = self._format_parsed_parts(self._drv, self._root,
+-                                                  self._parts) or '.'
+-            return self._str
+-
+-    def as_posix(self):
+-        """Return the string representation of the path with forward (/)
+-        slashes."""
+-        f = self._flavour
+-        return str(self).replace(f.sep, '/')
+-
+-    def __bytes__(self):
+-        """Return the bytes representation of the path.  This is only
+-        recommended to use under Unix."""
+-        if sys.version_info < (3, 2):
+-            raise NotImplementedError("needs Python 3.2 or later")
+-        return os.fsencode(str(self))
+-
+-    def __repr__(self):
+-        return "{0}({1!r})".format(self.__class__.__name__, self.as_posix())
+-
+-    def as_uri(self):
+-        """Return the path as a 'file' URI."""
+-        if not self.is_absolute():
+-            raise ValueError("relative path can't be expressed as a file URI")
+-        return self._flavour.make_uri(self)
+-
+-    @property
+-    def _cparts(self):
+-        # Cached casefolded parts, for hashing and comparison
+-        try:
+-            return self._cached_cparts
+-        except AttributeError:
+-            self._cached_cparts = self._flavour.casefold_parts(self._parts)
+-            return self._cached_cparts
+-
+-    def __eq__(self, other):
+-        if not isinstance(other, PurePath):
+-            return NotImplemented
+-        return self._cparts == other._cparts and self._flavour is other._flavour
+-
+-    def __ne__(self, other):
+-        return not self == other
+-
+-    def __hash__(self):
+-        try:
+-            return self._hash
+-        except AttributeError:
+-            self._hash = hash(tuple(self._cparts))
+-            return self._hash
+-
+-    def __lt__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts < other._cparts
+-
+-    def __le__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts <= other._cparts
+-
+-    def __gt__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts > other._cparts
+-
+-    def __ge__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts >= other._cparts
+-
+-    drive = property(attrgetter('_drv'),
+-                     doc="""The drive prefix (letter or UNC path), if any.""")
+-
+-    root = property(attrgetter('_root'),
+-                    doc="""The root of the path, if any.""")
+-
+-    @property
+-    def anchor(self):
+-        """The concatenation of the drive and root, or ''."""
+-        anchor = self._drv + self._root
+-        return anchor
+-
+-    @property
+-    def name(self):
+-        """The final path component, if any."""
+-        parts = self._parts
+-        if len(parts) == (1 if (self._drv or self._root) else 0):
+-            return ''
+-        return parts[-1]
+-
+-    @property
+-    def suffix(self):
+-        """The final component's last suffix, if any."""
+-        name = self.name
+-        i = name.rfind('.')
+-        if 0 < i < len(name) - 1:
+-            return name[i:]
+-        else:
+-            return ''
+-
+-    @property
+-    def suffixes(self):
+-        """A list of the final component's suffixes, if any."""
+-        name = self.name
+-        if name.endswith('.'):
+-            return []
+-        name = name.lstrip('.')
+-        return ['.' + suffix for suffix in name.split('.')[1:]]
+-
+-    @property
+-    def stem(self):
+-        """The final path component, minus its last suffix."""
+-        name = self.name
+-        i = name.rfind('.')
+-        if 0 < i < len(name) - 1:
+-            return name[:i]
+-        else:
+-            return name
+-
+-    def with_name(self, name):
+-        """Return a new path with the file name changed."""
+-        if not self.name:
+-            raise ValueError("%r has an empty name" % (self,))
+-        return self._from_parsed_parts(self._drv, self._root,
+-                                       self._parts[:-1] + [name])
+-
+-    def with_suffix(self, suffix):
+-        """Return a new path with the file suffix changed (or added, if none)."""
+-        # XXX if suffix is None, should the current suffix be removed?
+-        drv, root, parts = self._flavour.parse_parts((suffix,))
+-        if drv or root or len(parts) != 1:
+-            raise ValueError("Invalid suffix %r" % (suffix))
+-        suffix = parts[0]
+-        if not suffix.startswith('.'):
+-            raise ValueError("Invalid suffix %r" % (suffix))
+-        name = self.name
+-        if not name:
+-            raise ValueError("%r has an empty name" % (self,))
+-        old_suffix = self.suffix
+-        if not old_suffix:
+-            name = name + suffix
+-        else:
+-            name = name[:-len(old_suffix)] + suffix
+-        return self._from_parsed_parts(self._drv, self._root,
+-                                       self._parts[:-1] + [name])
+-
+-    def relative_to(self, *other):
+-        """Return the relative path to another path identified by the passed
+-        arguments.  If the operation is not possible (because this is not
+-        a subpath of the other path), raise ValueError.
+-        """
+-        # For the purpose of this method, drive and root are considered
+-        # separate parts, i.e.:
+-        #   Path('c:/').relative_to('c:')  gives Path('/')
+-        #   Path('c:/').relative_to('/')   raise ValueError
+-        if not other:
+-            raise TypeError("need at least one argument")
+-        parts = self._parts
+-        drv = self._drv
+-        root = self._root
+-        if root:
+-            abs_parts = [drv, root] + parts[1:]
+-        else:
+-            abs_parts = parts
+-        to_drv, to_root, to_parts = self._parse_args(other)
+-        if to_root:
+-            to_abs_parts = [to_drv, to_root] + to_parts[1:]
+-        else:
+-            to_abs_parts = to_parts
+-        n = len(to_abs_parts)
+-        cf = self._flavour.casefold_parts
+-        if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts):
+-            formatted = self._format_parsed_parts(to_drv, to_root, to_parts)
+-            raise ValueError("{!r} does not start with {!r}"
+-                             .format(str(self), str(formatted)))
+-        return self._from_parsed_parts('', root if n == 1 else '',
+-                                       abs_parts[n:])
+-
+-    @property
+-    def parts(self):
+-        """An object providing sequence-like access to the
+-        components in the filesystem path."""
+-        # We cache the tuple to avoid building a new one each time .parts
+-        # is accessed.  XXX is this necessary?
+-        try:
+-            return self._pparts
+-        except AttributeError:
+-            self._pparts = tuple(self._parts)
+-            return self._pparts
+-
+-    def joinpath(self, *args):
+-        """Combine this path with one or several arguments, and return a
+-        new path representing either a subpath (if all arguments are relative
+-        paths) or a totally different path (if one of the arguments is
+-        anchored).
+-        """
+-        return self._make_child(args)
+-
+-    def __truediv__(self, key):
+-        return self._make_child((key,))
+-
+-    def __rtruediv__(self, key):
+-        return self._from_parts([key] + self._parts)
+-
+-    if sys.version_info < (3,):
+-        __div__ = __truediv__
+-        __rdiv__ = __rtruediv__
+-
+-    @property
+-    def parent(self):
+-        """The logical parent of the path."""
+-        drv = self._drv
+-        root = self._root
+-        parts = self._parts
+-        if len(parts) == 1 and (drv or root):
+-            return self
+-        return self._from_parsed_parts(drv, root, parts[:-1])
+-
+-    @property
+-    def parents(self):
+-        """A sequence of this path's logical parents."""
+-        return _PathParents(self)
+-
+-    def is_absolute(self):
+-        """True if the path is absolute (has both a root and, if applicable,
+-        a drive)."""
+-        if not self._root:
+-            return False
+-        return not self._flavour.has_drv or bool(self._drv)
+-
+-    def is_reserved(self):
+-        """Return True if the path contains one of the special names reserved
+-        by the system, if any."""
+-        return self._flavour.is_reserved(self._parts)
+-
+-    def match(self, path_pattern):
+-        """
+-        Return True if this path matches the given pattern.
+-        """
+-        cf = self._flavour.casefold
+-        path_pattern = cf(path_pattern)
+-        drv, root, pat_parts = self._flavour.parse_parts((path_pattern,))
+-        if not pat_parts:
+-            raise ValueError("empty pattern")
+-        if drv and drv != cf(self._drv):
+-            return False
+-        if root and root != cf(self._root):
+-            return False
+-        parts = self._cparts
+-        if drv or root:
+-            if len(pat_parts) != len(parts):
+-                return False
+-            pat_parts = pat_parts[1:]
+-        elif len(pat_parts) > len(parts):
+-            return False
+-        for part, pat in zip(reversed(parts), reversed(pat_parts)):
+-            if not fnmatch.fnmatchcase(part, pat):
+-                return False
+-        return True
+-
+-
+-class PurePosixPath(PurePath):
+-    _flavour = _posix_flavour
+-    __slots__ = ()
+-
+-
+-class PureWindowsPath(PurePath):
+-    _flavour = _windows_flavour
+-    __slots__ = ()
+-
+-
+-# Filesystem-accessing classes
+-
+-
+-class Path(PurePath):
+-    __slots__ = (
+-        '_accessor',
+-    )
+-
+-    def __new__(cls, *args, **kwargs):
+-        if cls is Path:
+-            cls = WindowsPath if os.name == 'nt' else PosixPath
+-        self = cls._from_parts(args, init=False)
+-        if not self._flavour.is_supported:
+-            raise NotImplementedError("cannot instantiate %r on your system"
+-                                      % (cls.__name__,))
+-        self._init()
+-        return self
+-
+-    def _init(self,
+-              # Private non-constructor arguments
+-              template=None,
+-              ):
+-        if template is not None:
+-            self._accessor = template._accessor
+-        else:
+-            self._accessor = _normal_accessor
+-
+-    def _make_child_relpath(self, part):
+-        # This is an optimization used for dir walking.  `part` must be
+-        # a single part relative to this path.
+-        parts = self._parts + [part]
+-        return self._from_parsed_parts(self._drv, self._root, parts)
+-
+-    def _opener(self, name, flags, mode=0o666):
+-        # A stub for the opener argument to built-in open()
+-        return self._accessor.open(self, flags, mode)
+-
+-    def _raw_open(self, flags, mode=0o777):
+-        """
+-        Open the file pointed by this path and return a file descriptor,
+-        as os.open() does.
+-        """
+-        return self._accessor.open(self, flags, mode)
+-
+-    # Public API
+-
+-    @classmethod
+-    def cwd(cls):
+-        """Return a new path pointing to the current working directory
+-        (as returned by os.getcwd()).
+-        """
+-        return cls(os.getcwd())
+-
+-    def iterdir(self):
+-        """Iterate over the files in this directory.  Does not yield any
+-        result for the special paths '.' and '..'.
+-        """
+-        for name in self._accessor.listdir(self):
+-            if name in ('.', '..'):
+-                # Yielding a path object for these makes little sense
+-                continue
+-            yield self._make_child_relpath(name)
+-
+-    def glob(self, pattern):
+-        """Iterate over this subtree and yield all existing files (of any
+-        kind, including directories) matching the given pattern.
+-        """
+-        pattern = self._flavour.casefold(pattern)
+-        drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
+-        if drv or root:
+-            raise NotImplementedError("Non-relative patterns are unsupported")
+-        selector = _make_selector(tuple(pattern_parts))
+-        for p in selector.select_from(self):
+-            yield p
+-
+-    def rglob(self, pattern):
+-        """Recursively yield all existing files (of any kind, including
+-        directories) matching the given pattern, anywhere in this subtree.
+-        """
+-        pattern = self._flavour.casefold(pattern)
+-        drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
+-        if drv or root:
+-            raise NotImplementedError("Non-relative patterns are unsupported")
+-        selector = _make_selector(("**",) + tuple(pattern_parts))
+-        for p in selector.select_from(self):
+-            yield p
+-
+-    def absolute(self):
+-        """Return an absolute version of this path.  This function works
+-        even if the path doesn't point to anything.
+-
+-        No normalization is done, i.e. all '.' and '..' will be kept along.
+-        Use resolve() to get the canonical path to a file.
+-        """
+-        # XXX untested yet!
+-        if self.is_absolute():
+-            return self
+-        # FIXME this must defer to the specific flavour (and, under Windows,
+-        # use nt._getfullpathname())
+-        obj = self._from_parts([os.getcwd()] + self._parts, init=False)
+-        obj._init(template=self)
+-        return obj
+-
+-    def resolve(self):
+-        """
+-        Make the path absolute, resolving all symlinks on the way and also
+-        normalizing it (for example turning slashes into backslashes under
+-        Windows).
+-        """
+-        s = self._flavour.resolve(self)
+-        if s is None:
+-            # No symlink resolution => for consistency, raise an error if
+-            # the path doesn't exist or is forbidden
+-            self.stat()
+-            s = str(self.absolute())
+-        # Now we have no symlinks in the path, it's safe to normalize it.
+-        normed = self._flavour.pathmod.normpath(s)
+-        obj = self._from_parts((normed,), init=False)
+-        obj._init(template=self)
+-        return obj
+-
+-    def stat(self):
+-        """
+-        Return the result of the stat() system call on this path, like
+-        os.stat() does.
+-        """
+-        return self._accessor.stat(self)
+-
+-    def owner(self):
+-        """
+-        Return the login name of the file owner.
+-        """
+-        import pwd
+-        return pwd.getpwuid(self.stat().st_uid).pw_name
+-
+-    def group(self):
+-        """
+-        Return the group name of the file gid.
+-        """
+-        import grp
+-        return grp.getgrgid(self.stat().st_gid).gr_name
+-
+-    def open(self, mode='r', buffering=-1, encoding=None,
+-             errors=None, newline=None):
+-        """
+-        Open the file pointed by this path and return a file object, as
+-        the built-in open() function does.
+-        """
+-        if sys.version_info >= (3, 3):
+-            return io.open(str(self), mode, buffering, encoding, errors, newline,
+-                           opener=self._opener)
+-        else:
+-            return io.open(str(self), mode, buffering, encoding, errors, newline)
+-
+-    def touch(self, mode=0o666, exist_ok=True):
+-        """
+-        Create this file with the given access mode, if it doesn't exist.
+-        """
+-        if exist_ok:
+-            # First try to bump modification time
+-            # Implementation note: GNU touch uses the UTIME_NOW option of
+-            # the utimensat() / futimens() functions.
+-            t = time.time()
+-            try:
+-                self._accessor.utime(self, (t, t))
+-            except OSError:
+-                # Avoid exception chaining
+-                pass
+-            else:
+-                return
+-        flags = os.O_CREAT | os.O_WRONLY
+-        if not exist_ok:
+-            flags |= os.O_EXCL
+-        fd = self._raw_open(flags, mode)
+-        os.close(fd)
+-
+-    def mkdir(self, mode=0o777, parents=False):
+-        if not parents:
+-            self._accessor.mkdir(self, mode)
+-        else:
+-            try:
+-                self._accessor.mkdir(self, mode)
+-            except OSError as e:
+-                if e.errno != ENOENT:
+-                    raise
+-                self.parent.mkdir(parents=True)
+-                self._accessor.mkdir(self, mode)
+-
+-    def chmod(self, mode):
+-        """
+-        Change the permissions of the path, like os.chmod().
+-        """
+-        self._accessor.chmod(self, mode)
+-
+-    def lchmod(self, mode):
+-        """
+-        Like chmod(), except if the path points to a symlink, the symlink's
+-        permissions are changed, rather than its target's.
+-        """
+-        self._accessor.lchmod(self, mode)
+-
+-    def unlink(self):
+-        """
+-        Remove this file or link.
+-        If the path is a directory, use rmdir() instead.
+-        """
+-        self._accessor.unlink(self)
+-
+-    def rmdir(self):
+-        """
+-        Remove this directory.  The directory must be empty.
+-        """
+-        self._accessor.rmdir(self)
+-
+-    def lstat(self):
+-        """
+-        Like stat(), except if the path points to a symlink, the symlink's
+-        status information is returned, rather than its target's.
+-        """
+-        return self._accessor.lstat(self)
+-
+-    def rename(self, target):
+-        """
+-        Rename this path to the given path.
+-        """
+-        self._accessor.rename(self, target)
+-
+-    def replace(self, target):
+-        """
+-        Rename this path to the given path, clobbering the existing
+-        destination if it exists.
+-        """
+-        if sys.version_info < (3, 3):
+-            raise NotImplementedError("replace() is only available "
+-                                      "with Python 3.3 and later")
+-        self._accessor.replace(self, target)
+-
+-    def symlink_to(self, target, target_is_directory=False):
+-        """
+-        Make this path a symlink pointing to the given path.
+-        Note the order of arguments (self, target) is the reverse of os.symlink's.
+-        """
+-        self._accessor.symlink(target, self, target_is_directory)
+-
+-    # Convenience functions for querying the stat results
+-
+-    def exists(self):
+-        """
+-        Whether this path exists.
+-        """
+-        try:
+-            self.stat()
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            return False
+-        return True
+-
+-    def is_dir(self):
+-        """
+-        Whether this path is a directory.
+-        """
+-        try:
+-            return S_ISDIR(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_file(self):
+-        """
+-        Whether this path is a regular file (also True for symlinks pointing
+-        to regular files).
+-        """
+-        try:
+-            return S_ISREG(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_symlink(self):
+-        """
+-        Whether this path is a symbolic link.
+-        """
+-        try:
+-            return S_ISLNK(self.lstat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist
+-            return False
+-
+-    def is_block_device(self):
+-        """
+-        Whether this path is a block device.
+-        """
+-        try:
+-            return S_ISBLK(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_char_device(self):
+-        """
+-        Whether this path is a character device.
+-        """
+-        try:
+-            return S_ISCHR(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_fifo(self):
+-        """
+-        Whether this path is a FIFO.
+-        """
+-        try:
+-            return S_ISFIFO(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_socket(self):
+-        """
+-        Whether this path is a socket.
+-        """
+-        try:
+-            return S_ISSOCK(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-
+-class PosixPath(Path, PurePosixPath):
+-    __slots__ = ()
+-
+-class WindowsPath(Path, PureWindowsPath):
+-    __slots__ = ()
+-
+diff --git a/tasks/_vendor/six.py b/tasks/_vendor/six.py
+deleted file mode 100644
+index 190c023..0000000
+--- a/tasks/_vendor/six.py
++++ /dev/null
+@@ -1,868 +0,0 @@
+-"""Utilities for writing code that runs on Python 2 and 3"""
+-
+-# Copyright (c) 2010-2015 Benjamin Peterson
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy
+-# of this software and associated documentation files (the "Software"), to deal
+-# in the Software without restriction, including without limitation the rights
+-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-# copies of the Software, and to permit persons to whom the Software is
+-# furnished to do so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+-
+-from __future__ import absolute_import
+-
+-import functools
+-import itertools
+-import operator
+-import sys
+-import types
+-
+-__author__ = "Benjamin Peterson <benjamin@python.org>"
+-__version__ = "1.10.0"
+-
+-
+-# Useful for very coarse version differentiation.
+-PY2 = sys.version_info[0] == 2
+-PY3 = sys.version_info[0] == 3
+-PY34 = sys.version_info[0:2] >= (3, 4)
+-
+-if PY3:
+-    string_types = str,
+-    integer_types = int,
+-    class_types = type,
+-    text_type = str
+-    binary_type = bytes
+-
+-    MAXSIZE = sys.maxsize
+-else:
+-    string_types = basestring,
+-    integer_types = (int, long)
+-    class_types = (type, types.ClassType)
+-    text_type = unicode
+-    binary_type = str
+-
+-    if sys.platform.startswith("java"):
+-        # Jython always uses 32 bits.
+-        MAXSIZE = int((1 << 31) - 1)
+-    else:
+-        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+-        class X(object):
+-
+-            def __len__(self):
+-                return 1 << 31
+-        try:
+-            len(X())
+-        except OverflowError:
+-            # 32-bit
+-            MAXSIZE = int((1 << 31) - 1)
+-        else:
+-            # 64-bit
+-            MAXSIZE = int((1 << 63) - 1)
+-        del X
+-
+-
+-def _add_doc(func, doc):
+-    """Add documentation to a function."""
+-    func.__doc__ = doc
+-
+-
+-def _import_module(name):
+-    """Import module, returning the module after the last dot."""
+-    __import__(name)
+-    return sys.modules[name]
+-
+-
+-class _LazyDescr(object):
+-
+-    def __init__(self, name):
+-        self.name = name
+-
+-    def __get__(self, obj, tp):
+-        result = self._resolve()
+-        setattr(obj, self.name, result)  # Invokes __set__.
+-        try:
+-            # This is a bit ugly, but it avoids running this again by
+-            # removing this descriptor.
+-            delattr(obj.__class__, self.name)
+-        except AttributeError:
+-            pass
+-        return result
+-
+-
+-class MovedModule(_LazyDescr):
+-
+-    def __init__(self, name, old, new=None):
+-        super(MovedModule, self).__init__(name)
+-        if PY3:
+-            if new is None:
+-                new = name
+-            self.mod = new
+-        else:
+-            self.mod = old
+-
+-    def _resolve(self):
+-        return _import_module(self.mod)
+-
+-    def __getattr__(self, attr):
+-        _module = self._resolve()
+-        value = getattr(_module, attr)
+-        setattr(self, attr, value)
+-        return value
+-
+-
+-class _LazyModule(types.ModuleType):
+-
+-    def __init__(self, name):
+-        super(_LazyModule, self).__init__(name)
+-        self.__doc__ = self.__class__.__doc__
+-
+-    def __dir__(self):
+-        attrs = ["__doc__", "__name__"]
+-        attrs += [attr.name for attr in self._moved_attributes]
+-        return attrs
+-
+-    # Subclasses should override this
+-    _moved_attributes = []
+-
+-
+-class MovedAttribute(_LazyDescr):
+-
+-    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+-        super(MovedAttribute, self).__init__(name)
+-        if PY3:
+-            if new_mod is None:
+-                new_mod = name
+-            self.mod = new_mod
+-            if new_attr is None:
+-                if old_attr is None:
+-                    new_attr = name
+-                else:
+-                    new_attr = old_attr
+-            self.attr = new_attr
+-        else:
+-            self.mod = old_mod
+-            if old_attr is None:
+-                old_attr = name
+-            self.attr = old_attr
+-
+-    def _resolve(self):
+-        module = _import_module(self.mod)
+-        return getattr(module, self.attr)
+-
+-
+-class _SixMetaPathImporter(object):
+-
+-    """
+-    A meta path importer to import six.moves and its submodules.
+-
+-    This class implements a PEP302 finder and loader. It should be compatible
+-    with Python 2.5 and all existing versions of Python3
+-    """
+-
+-    def __init__(self, six_module_name):
+-        self.name = six_module_name
+-        self.known_modules = {}
+-
+-    def _add_module(self, mod, *fullnames):
+-        for fullname in fullnames:
+-            self.known_modules[self.name + "." + fullname] = mod
+-
+-    def _get_module(self, fullname):
+-        return self.known_modules[self.name + "." + fullname]
+-
+-    def find_module(self, fullname, path=None):
+-        if fullname in self.known_modules:
+-            return self
+-        return None
+-
+-    def __get_module(self, fullname):
+-        try:
+-            return self.known_modules[fullname]
+-        except KeyError:
+-            raise ImportError("This loader does not know module " + fullname)
+-
+-    def load_module(self, fullname):
+-        try:
+-            # in case of a reload
+-            return sys.modules[fullname]
+-        except KeyError:
+-            pass
+-        mod = self.__get_module(fullname)
+-        if isinstance(mod, MovedModule):
+-            mod = mod._resolve()
+-        else:
+-            mod.__loader__ = self
+-        sys.modules[fullname] = mod
+-        return mod
+-
+-    def is_package(self, fullname):
+-        """
+-        Return true, if the named module is a package.
+-
+-        We need this method to get correct spec objects with
+-        Python 3.4 (see PEP451)
+-        """
+-        return hasattr(self.__get_module(fullname), "__path__")
+-
+-    def get_code(self, fullname):
+-        """Return None
+-
+-        Required, if is_package is implemented"""
+-        self.__get_module(fullname)  # eventually raises ImportError
+-        return None
+-    get_source = get_code  # same as get_code
+-
+-_importer = _SixMetaPathImporter(__name__)
+-
+-
+-class _MovedItems(_LazyModule):
+-
+-    """Lazy loading of moved objects"""
+-    __path__ = []  # mark as package
+-
+-
+-_moved_attributes = [
+-    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+-    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+-    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+-    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+-    MovedAttribute("intern", "__builtin__", "sys"),
+-    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+-    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+-    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+-    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+-    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+-    MovedAttribute("reduce", "__builtin__", "functools"),
+-    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+-    MovedAttribute("StringIO", "StringIO", "io"),
+-    MovedAttribute("UserDict", "UserDict", "collections"),
+-    MovedAttribute("UserList", "UserList", "collections"),
+-    MovedAttribute("UserString", "UserString", "collections"),
+-    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+-    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+-    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+-    MovedModule("builtins", "__builtin__"),
+-    MovedModule("configparser", "ConfigParser"),
+-    MovedModule("copyreg", "copy_reg"),
+-    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+-    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+-    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+-    MovedModule("http_cookies", "Cookie", "http.cookies"),
+-    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+-    MovedModule("html_parser", "HTMLParser", "html.parser"),
+-    MovedModule("http_client", "httplib", "http.client"),
+-    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+-    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+-    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+-    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+-    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+-    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+-    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+-    MovedModule("cPickle", "cPickle", "pickle"),
+-    MovedModule("queue", "Queue"),
+-    MovedModule("reprlib", "repr"),
+-    MovedModule("socketserver", "SocketServer"),
+-    MovedModule("_thread", "thread", "_thread"),
+-    MovedModule("tkinter", "Tkinter"),
+-    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+-    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+-    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+-    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+-    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+-    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+-    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+-    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+-    MovedModule("tkinter_colorchooser", "tkColorChooser",
+-                "tkinter.colorchooser"),
+-    MovedModule("tkinter_commondialog", "tkCommonDialog",
+-                "tkinter.commondialog"),
+-    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+-    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+-    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+-    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+-                "tkinter.simpledialog"),
+-    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+-    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+-    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+-    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+-    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+-    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+-]
+-# Add windows specific modules.
+-if sys.platform == "win32":
+-    _moved_attributes += [
+-        MovedModule("winreg", "_winreg"),
+-    ]
+-
+-for attr in _moved_attributes:
+-    setattr(_MovedItems, attr.name, attr)
+-    if isinstance(attr, MovedModule):
+-        _importer._add_module(attr, "moves." + attr.name)
+-del attr
+-
+-_MovedItems._moved_attributes = _moved_attributes
+-
+-moves = _MovedItems(__name__ + ".moves")
+-_importer._add_module(moves, "moves")
+-
+-
+-class Module_six_moves_urllib_parse(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_parse"""
+-
+-
+-_urllib_parse_moved_attributes = [
+-    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+-    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+-    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+-    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+-    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+-    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+-    MovedAttribute("quote", "urllib", "urllib.parse"),
+-    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+-    MovedAttribute("unquote", "urllib", "urllib.parse"),
+-    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+-    MovedAttribute("urlencode", "urllib", "urllib.parse"),
+-    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+-    MovedAttribute("splittag", "urllib", "urllib.parse"),
+-    MovedAttribute("splituser", "urllib", "urllib.parse"),
+-    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+-]
+-for attr in _urllib_parse_moved_attributes:
+-    setattr(Module_six_moves_urllib_parse, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+-                      "moves.urllib_parse", "moves.urllib.parse")
+-
+-
+-class Module_six_moves_urllib_error(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_error"""
+-
+-
+-_urllib_error_moved_attributes = [
+-    MovedAttribute("URLError", "urllib2", "urllib.error"),
+-    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+-    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+-]
+-for attr in _urllib_error_moved_attributes:
+-    setattr(Module_six_moves_urllib_error, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+-                      "moves.urllib_error", "moves.urllib.error")
+-
+-
+-class Module_six_moves_urllib_request(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_request"""
+-
+-
+-_urllib_request_moved_attributes = [
+-    MovedAttribute("urlopen", "urllib2", "urllib.request"),
+-    MovedAttribute("install_opener", "urllib2", "urllib.request"),
+-    MovedAttribute("build_opener", "urllib2", "urllib.request"),
+-    MovedAttribute("pathname2url", "urllib", "urllib.request"),
+-    MovedAttribute("url2pathname", "urllib", "urllib.request"),
+-    MovedAttribute("getproxies", "urllib", "urllib.request"),
+-    MovedAttribute("Request", "urllib2", "urllib.request"),
+-    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+-    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+-    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+-    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+-    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+-    MovedAttribute("URLopener", "urllib", "urllib.request"),
+-    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+-    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+-]
+-for attr in _urllib_request_moved_attributes:
+-    setattr(Module_six_moves_urllib_request, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+-                      "moves.urllib_request", "moves.urllib.request")
+-
+-
+-class Module_six_moves_urllib_response(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_response"""
+-
+-
+-_urllib_response_moved_attributes = [
+-    MovedAttribute("addbase", "urllib", "urllib.response"),
+-    MovedAttribute("addclosehook", "urllib", "urllib.response"),
+-    MovedAttribute("addinfo", "urllib", "urllib.response"),
+-    MovedAttribute("addinfourl", "urllib", "urllib.response"),
+-]
+-for attr in _urllib_response_moved_attributes:
+-    setattr(Module_six_moves_urllib_response, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+-                      "moves.urllib_response", "moves.urllib.response")
+-
+-
+-class Module_six_moves_urllib_robotparser(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+-
+-
+-_urllib_robotparser_moved_attributes = [
+-    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+-]
+-for attr in _urllib_robotparser_moved_attributes:
+-    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+-                      "moves.urllib_robotparser", "moves.urllib.robotparser")
+-
+-
+-class Module_six_moves_urllib(types.ModuleType):
+-
+-    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+-    __path__ = []  # mark as package
+-    parse = _importer._get_module("moves.urllib_parse")
+-    error = _importer._get_module("moves.urllib_error")
+-    request = _importer._get_module("moves.urllib_request")
+-    response = _importer._get_module("moves.urllib_response")
+-    robotparser = _importer._get_module("moves.urllib_robotparser")
+-
+-    def __dir__(self):
+-        return ['parse', 'error', 'request', 'response', 'robotparser']
+-
+-_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+-                      "moves.urllib")
+-
+-
+-def add_move(move):
+-    """Add an item to six.moves."""
+-    setattr(_MovedItems, move.name, move)
+-
+-
+-def remove_move(name):
+-    """Remove item from six.moves."""
+-    try:
+-        delattr(_MovedItems, name)
+-    except AttributeError:
+-        try:
+-            del moves.__dict__[name]
+-        except KeyError:
+-            raise AttributeError("no such move, %r" % (name,))
+-
+-
+-if PY3:
+-    _meth_func = "__func__"
+-    _meth_self = "__self__"
+-
+-    _func_closure = "__closure__"
+-    _func_code = "__code__"
+-    _func_defaults = "__defaults__"
+-    _func_globals = "__globals__"
+-else:
+-    _meth_func = "im_func"
+-    _meth_self = "im_self"
+-
+-    _func_closure = "func_closure"
+-    _func_code = "func_code"
+-    _func_defaults = "func_defaults"
+-    _func_globals = "func_globals"
+-
+-
+-try:
+-    advance_iterator = next
+-except NameError:
+-    def advance_iterator(it):
+-        return it.next()
+-next = advance_iterator
+-
+-
+-try:
+-    callable = callable
+-except NameError:
+-    def callable(obj):
+-        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+-
+-
+-if PY3:
+-    def get_unbound_function(unbound):
+-        return unbound
+-
+-    create_bound_method = types.MethodType
+-
+-    def create_unbound_method(func, cls):
+-        return func
+-
+-    Iterator = object
+-else:
+-    def get_unbound_function(unbound):
+-        return unbound.im_func
+-
+-    def create_bound_method(func, obj):
+-        return types.MethodType(func, obj, obj.__class__)
+-
+-    def create_unbound_method(func, cls):
+-        return types.MethodType(func, None, cls)
+-
+-    class Iterator(object):
+-
+-        def next(self):
+-            return type(self).__next__(self)
+-
+-    callable = callable
+-_add_doc(get_unbound_function,
+-         """Get the function out of a possibly unbound function""")
+-
+-
+-get_method_function = operator.attrgetter(_meth_func)
+-get_method_self = operator.attrgetter(_meth_self)
+-get_function_closure = operator.attrgetter(_func_closure)
+-get_function_code = operator.attrgetter(_func_code)
+-get_function_defaults = operator.attrgetter(_func_defaults)
+-get_function_globals = operator.attrgetter(_func_globals)
+-
+-
+-if PY3:
+-    def iterkeys(d, **kw):
+-        return iter(d.keys(**kw))
+-
+-    def itervalues(d, **kw):
+-        return iter(d.values(**kw))
+-
+-    def iteritems(d, **kw):
+-        return iter(d.items(**kw))
+-
+-    def iterlists(d, **kw):
+-        return iter(d.lists(**kw))
+-
+-    viewkeys = operator.methodcaller("keys")
+-
+-    viewvalues = operator.methodcaller("values")
+-
+-    viewitems = operator.methodcaller("items")
+-else:
+-    def iterkeys(d, **kw):
+-        return d.iterkeys(**kw)
+-
+-    def itervalues(d, **kw):
+-        return d.itervalues(**kw)
+-
+-    def iteritems(d, **kw):
+-        return d.iteritems(**kw)
+-
+-    def iterlists(d, **kw):
+-        return d.iterlists(**kw)
+-
+-    viewkeys = operator.methodcaller("viewkeys")
+-
+-    viewvalues = operator.methodcaller("viewvalues")
+-
+-    viewitems = operator.methodcaller("viewitems")
+-
+-_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+-_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+-_add_doc(iteritems,
+-         "Return an iterator over the (key, value) pairs of a dictionary.")
+-_add_doc(iterlists,
+-         "Return an iterator over the (key, [values]) pairs of a dictionary.")
+-
+-
+-if PY3:
+-    def b(s):
+-        return s.encode("latin-1")
+-
+-    def u(s):
+-        return s
+-    unichr = chr
+-    import struct
+-    int2byte = struct.Struct(">B").pack
+-    del struct
+-    byte2int = operator.itemgetter(0)
+-    indexbytes = operator.getitem
+-    iterbytes = iter
+-    import io
+-    StringIO = io.StringIO
+-    BytesIO = io.BytesIO
+-    _assertCountEqual = "assertCountEqual"
+-    if sys.version_info[1] <= 1:
+-        _assertRaisesRegex = "assertRaisesRegexp"
+-        _assertRegex = "assertRegexpMatches"
+-    else:
+-        _assertRaisesRegex = "assertRaisesRegex"
+-        _assertRegex = "assertRegex"
+-else:
+-    def b(s):
+-        return s
+-    # Workaround for standalone backslash
+-
+-    def u(s):
+-        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+-    unichr = unichr
+-    int2byte = chr
+-
+-    def byte2int(bs):
+-        return ord(bs[0])
+-
+-    def indexbytes(buf, i):
+-        return ord(buf[i])
+-    iterbytes = functools.partial(itertools.imap, ord)
+-    import StringIO
+-    StringIO = BytesIO = StringIO.StringIO
+-    _assertCountEqual = "assertItemsEqual"
+-    _assertRaisesRegex = "assertRaisesRegexp"
+-    _assertRegex = "assertRegexpMatches"
+-_add_doc(b, """Byte literal""")
+-_add_doc(u, """Text literal""")
+-
+-
+-def assertCountEqual(self, *args, **kwargs):
+-    return getattr(self, _assertCountEqual)(*args, **kwargs)
+-
+-
+-def assertRaisesRegex(self, *args, **kwargs):
+-    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+-
+-
+-def assertRegex(self, *args, **kwargs):
+-    return getattr(self, _assertRegex)(*args, **kwargs)
+-
+-
+-if PY3:
+-    exec_ = getattr(moves.builtins, "exec")
+-
+-    def reraise(tp, value, tb=None):
+-        if value is None:
+-            value = tp()
+-        if value.__traceback__ is not tb:
+-            raise value.with_traceback(tb)
+-        raise value
+-
+-else:
+-    def exec_(_code_, _globs_=None, _locs_=None):
+-        """Execute code in a namespace."""
+-        if _globs_ is None:
+-            frame = sys._getframe(1)
+-            _globs_ = frame.f_globals
+-            if _locs_ is None:
+-                _locs_ = frame.f_locals
+-            del frame
+-        elif _locs_ is None:
+-            _locs_ = _globs_
+-        exec("""exec _code_ in _globs_, _locs_""")
+-
+-    exec_("""def reraise(tp, value, tb=None):
+-    raise tp, value, tb
+-""")
+-
+-
+-if sys.version_info[:2] == (3, 2):
+-    exec_("""def raise_from(value, from_value):
+-    if from_value is None:
+-        raise value
+-    raise value from from_value
+-""")
+-elif sys.version_info[:2] > (3, 2):
+-    exec_("""def raise_from(value, from_value):
+-    raise value from from_value
+-""")
+-else:
+-    def raise_from(value, from_value):
+-        raise value
+-
+-
+-print_ = getattr(moves.builtins, "print", None)
+-if print_ is None:
+-    def print_(*args, **kwargs):
+-        """The new-style print function for Python 2.4 and 2.5."""
+-        fp = kwargs.pop("file", sys.stdout)
+-        if fp is None:
+-            return
+-
+-        def write(data):
+-            if not isinstance(data, basestring):
+-                data = str(data)
+-            # If the file has an encoding, encode unicode with it.
+-            if (isinstance(fp, file) and
+-                    isinstance(data, unicode) and
+-                    fp.encoding is not None):
+-                errors = getattr(fp, "errors", None)
+-                if errors is None:
+-                    errors = "strict"
+-                data = data.encode(fp.encoding, errors)
+-            fp.write(data)
+-        want_unicode = False
+-        sep = kwargs.pop("sep", None)
+-        if sep is not None:
+-            if isinstance(sep, unicode):
+-                want_unicode = True
+-            elif not isinstance(sep, str):
+-                raise TypeError("sep must be None or a string")
+-        end = kwargs.pop("end", None)
+-        if end is not None:
+-            if isinstance(end, unicode):
+-                want_unicode = True
+-            elif not isinstance(end, str):
+-                raise TypeError("end must be None or a string")
+-        if kwargs:
+-            raise TypeError("invalid keyword arguments to print()")
+-        if not want_unicode:
+-            for arg in args:
+-                if isinstance(arg, unicode):
+-                    want_unicode = True
+-                    break
+-        if want_unicode:
+-            newline = unicode("\n")
+-            space = unicode(" ")
+-        else:
+-            newline = "\n"
+-            space = " "
+-        if sep is None:
+-            sep = space
+-        if end is None:
+-            end = newline
+-        for i, arg in enumerate(args):
+-            if i:
+-                write(sep)
+-            write(arg)
+-        write(end)
+-if sys.version_info[:2] < (3, 3):
+-    _print = print_
+-
+-    def print_(*args, **kwargs):
+-        fp = kwargs.get("file", sys.stdout)
+-        flush = kwargs.pop("flush", False)
+-        _print(*args, **kwargs)
+-        if flush and fp is not None:
+-            fp.flush()
+-
+-_add_doc(reraise, """Reraise an exception.""")
+-
+-if sys.version_info[0:2] < (3, 4):
+-    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+-              updated=functools.WRAPPER_UPDATES):
+-        def wrapper(f):
+-            f = functools.wraps(wrapped, assigned, updated)(f)
+-            f.__wrapped__ = wrapped
+-            return f
+-        return wrapper
+-else:
+-    wraps = functools.wraps
+-
+-
+-def with_metaclass(meta, *bases):
+-    """Create a base class with a metaclass."""
+-    # This requires a bit of explanation: the basic idea is to make a dummy
+-    # metaclass for one level of class instantiation that replaces itself with
+-    # the actual metaclass.
+-    class metaclass(meta):
+-
+-        def __new__(cls, name, this_bases, d):
+-            return meta(name, bases, d)
+-    return type.__new__(metaclass, 'temporary_class', (), {})
+-
+-
+-def add_metaclass(metaclass):
+-    """Class decorator for creating a class with a metaclass."""
+-    def wrapper(cls):
+-        orig_vars = cls.__dict__.copy()
+-        slots = orig_vars.get('__slots__')
+-        if slots is not None:
+-            if isinstance(slots, str):
+-                slots = [slots]
+-            for slots_var in slots:
+-                orig_vars.pop(slots_var)
+-        orig_vars.pop('__dict__', None)
+-        orig_vars.pop('__weakref__', None)
+-        return metaclass(cls.__name__, cls.__bases__, orig_vars)
+-    return wrapper
+-
+-
+-def python_2_unicode_compatible(klass):
+-    """
+-    A decorator that defines __unicode__ and __str__ methods under Python 2.
+-    Under Python 3 it does nothing.
+-
+-    To support Python 2 and 3 with a single code base, define a __str__ method
+-    returning text and apply this decorator to the class.
+-    """
+-    if PY2:
+-        if '__str__' not in klass.__dict__:
+-            raise ValueError("@python_2_unicode_compatible cannot be applied "
+-                             "to %s because it doesn't define __str__()." %
+-                             klass.__name__)
+-        klass.__unicode__ = klass.__str__
+-        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+-    return klass
+-
+-
+-# Complete the moves implementation.
+-# This code is at the end of this module to speed up module loading.
+-# Turn this module into a package.
+-__path__ = []  # required for PEP 302 and PEP 451
+-__package__ = __name__  # see PEP 366 @ReservedAssignment
+-if globals().get("__spec__") is not None:
+-    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+-# Remove other six meta path importers, since they cause problems. This can
+-# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+-# this for some reason.)
+-if sys.meta_path:
+-    for i, importer in enumerate(sys.meta_path):
+-        # Here's some real nastiness: Another "instance" of the six module might
+-        # be floating around. Therefore, we can't use isinstance() to check for
+-        # the six meta path importer, since the other six instance will have
+-        # inserted an importer with different class.
+-        if (type(importer).__name__ == "_SixMetaPathImporter" and
+-                importer.name == __name__):
+-            del sys.meta_path[i]
+-            break
+-    del i, importer
+-# Finally, add the importer to the meta path import hook.
+-sys.meta_path.append(_importer)
+diff --git a/tasks/docs.py b/tasks/docs.py
+index 3360279..77c1d83 100644
+--- a/tasks/docs.py
++++ b/tasks/docs.py
+@@ -11,7 +11,8 @@ from invoke.util import cd
+ from path import Path
+ 
+ # -- TASK-LIBRARY:
+-from ._tasklet_cleanup import cleanup_tasks, cleanup_dirs
++# PREPARED: from invoke_cleanup import cleanup_tasks, cleanup_dirs
++from .invoke_cleanup import cleanup_tasks, cleanup_dirs
+ 
+ 
+ # -----------------------------------------------------------------------------
+@@ -69,6 +70,7 @@ def build(ctx, builder="html", language=None, options=""):
+                             opts=options)
+         ctx.run(command)
+ 
++
+ @task(help={
+     "builder": "Builder to use (html, ...)",
+     "language": "Language to use (en, ...)",
+@@ -81,12 +83,38 @@ def rebuild(ctx, builder="html", language=None, options=""):
+     clean(ctx)
+     build(ctx, builder=builder, language=None, options=options)
+ 
++
++@task(aliases=["auto", "watch"],
++    help={
++        "builder": "Builder to use (html, ...)",
++        "language": "Language to use (en, ...)",
++        "options": "Additional options for sphinx-build",
++})
++def autobuild(ctx, builder="html", language=None, options=""):
++    """Build docs with sphinx-build"""
++    language = _sphinxdoc_get_language(ctx, language)
++    sourcedir = ctx.config.sphinx.sourcedir
++    destdir = _sphinxdoc_get_destdir(ctx, builder, language=language)
++    destdir = destdir.abspath()
++    with cd(sourcedir):
++        destdir_relative = Path(".").relpathto(destdir)
++        command = "sphinx-autobuild {opts} -b {builder} -D language={language} {sourcedir} {destdir}" \
++                    .format(builder=builder, sourcedir=".",
++                            destdir=destdir_relative,
++                            language=language,
++                            opts=options)
++        ctx.run(command)
++
++
+ @task
+ def linkcheck(ctx):
+     """Check if all links are corect."""
+     build(ctx, builder="linkcheck")
+ 
+-@task(help={"language": "Language to use (en, ...)"})
++
++@task(aliases=["open"],
++    help={"language": "Language to use (en, ...)"}
++)
+ def browse(ctx, language=None):
+     """Open documentation in web browser."""
+     output_dir = _sphinxdoc_get_destdir(ctx, "html", language=language)
+@@ -182,6 +210,7 @@ def update_translation(ctx, language="all"):
+ # -----------------------------------------------------------------------------
+ namespace = Collection(clean, rebuild, linkcheck, browse, save, update_translation)
+ namespace.add_task(build, default=True)
++namespace.add_task(autobuild)
+ namespace.configure({
+     "sphinx": {
+         # -- FOR TASKS: docs.build, docs.rebuild, docs.clean, ...
+diff --git a/tasks/invoke_cleanup.py b/tasks/invoke_cleanup.py
+new file mode 100644
+index 0000000..4e631c4
+--- /dev/null
++++ b/tasks/invoke_cleanup.py
+@@ -0,0 +1,447 @@
++# -*- coding: UTF-8 -*-
++"""
++Provides cleanup tasks for invoke build scripts (as generic invoke tasklet).
++Simplifies writing common, composable and extendable cleanup tasks.
++
++PYTHON PACKAGE DEPENDENCIES:
++
++* path (python >= 3.5) or path.py >= 11.5.0 (as path-object abstraction)
++* pathlib (for ant-like wildcard patterns; since: python > 3.5)
++* pycmd (required-by: clean_python())
++
++
++cleanup task: Add Additional Directories and Files to be removed
++-------------------------------------------------------------------------------
++
++Create an invoke configuration file (YAML of JSON) with the additional
++configuration data:
++
++.. code-block:: yaml
++
++    # -- FILE: invoke.yaml
++    # USE: cleanup.directories, cleanup.files to override current configuration.
++    cleanup:
++        # directories: Default directory patterns (can be overwritten).
++        # files:       Default file patterns      (can be ovewritten).
++        extra_directories:
++            - **/tmp/
++        extra_files:
++            - **/*.log
++            - **/*.bak
++
++
++Registration of Cleanup Tasks
++------------------------------
++
++Other task modules often have an own cleanup task to recover the clean state.
++The :meth:`cleanup` task, that is provided here, supports the registration
++of additional cleanup tasks. Therefore, when the :meth:`cleanup` task is executed,
++all registered cleanup tasks will be executed.
++
++EXAMPLE::
++
++    # -- FILE: tasks/docs.py
++    from __future__ import absolute_import
++    from invoke import task, Collection
++    from invoke_cleanup import cleanup_tasks, cleanup_dirs
++
++    @task
++    def clean(ctx):
++        "Cleanup generated documentation artifacts."
++        dry_run = ctx.config.run.dry
++        cleanup_dirs(["build/docs"], dry_run=dry_run)
++
++    namespace = Collection(clean)
++    ...
++
++    # -- REGISTER CLEANUP TASK:
++    cleanup_tasks.add_task(clean, "clean_docs")
++    cleanup_tasks.configure(namespace.configuration())
++"""
++
++from __future__ import absolute_import, print_function
++import os
++import sys
++from invoke import task, Collection
++from invoke.executor import Executor
++from invoke.exceptions import Exit, Failure, UnexpectedExit
++from invoke.util import cd
++from path import Path
++
++# -- PYTHON BACKWARD COMPATIBILITY:
++python_version = sys.version_info[:2]
++python35 = (3, 5)   # HINT: python3.8 does not raise OSErrors.
++if python_version < python35:   # noqa
++    import pathlib2 as pathlib
++else:
++    import pathlib              # noqa
++
++
++# -----------------------------------------------------------------------------
++# CONSTANTS:
++# -----------------------------------------------------------------------------
++VERSION = "0.3.6"
++
++
++# -----------------------------------------------------------------------------
++# CLEANUP UTILITIES:
++# -----------------------------------------------------------------------------
++def execute_cleanup_tasks(ctx, cleanup_tasks, workdir=".", verbose=False):
++    """Execute several cleanup tasks as part of the cleanup.
++
++    :param ctx:             Context object for the tasks.
++    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
++    """
++    # pylint: disable=redefined-outer-name
++    executor = Executor(cleanup_tasks, ctx.config)
++    failure_count = 0
++    with cd(workdir) as cwd:
++        for cleanup_task in cleanup_tasks.tasks:
++            try:
++                print("CLEANUP TASK: %s" % cleanup_task)
++                executor.execute(cleanup_task)
++            except (Exit, Failure, UnexpectedExit) as e:
++                print(e)
++                print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" % cleanup_task)
++                failure_count += 1
++
++    if failure_count:
++        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
++
++
++def make_excluded(excluded, config_dir=None, workdir=None):
++    workdir = workdir or Path.getcwd()
++    config_dir = config_dir or workdir
++    workdir = Path(workdir)
++    config_dir = Path(config_dir)
++
++    excluded2 = []
++    for p in excluded:
++        assert p, "REQUIRE: non-empty"
++        p = Path(p)
++        if p.isabs():
++            excluded2.append(p.normpath())
++        else:
++            # -- RELATIVE PATH:
++            # Described relative to config_dir.
++            # Recompute it relative to current workdir.
++            p = Path(config_dir)/p
++            p = workdir.relpathto(p)
++            excluded2.append(p.normpath())
++            excluded2.append(p.abspath())
++    return set(excluded2)
++
++
++def is_directory_excluded(directory, excluded):
++    directory = Path(directory).normpath()
++    directory2 = directory.abspath()
++    if (directory in excluded) or (directory2 in excluded):
++        return True
++    # -- OTHERWISE:
++    return False
++
++
++def cleanup_dirs(patterns, workdir=".", excluded=None,
++                 dry_run=False, verbose=False, show_skipped=False):
++    """Remove directories (and their contents) recursively.
++    Skips removal if directories does not exist.
++
++    :param patterns:    Directory name patterns, like "**/tmp*" (as list).
++    :param workdir:     Current work directory (default=".")
++    :param dry_run:     Dry-run mode indicator (as bool).
++    """
++    excluded = excluded or []
++    excluded = set([Path(p) for p in excluded])
++    show_skipped = show_skipped or verbose
++    current_dir = Path(workdir)
++    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
++    warn2_counter = 0
++    for dir_pattern in patterns:
++        for directory in path_glob(dir_pattern, current_dir):
++            if is_directory_excluded(directory, excluded):
++                print("SKIP-DIR: %s (excluded)" % directory)
++                continue
++            directory2 = directory.abspath()
++            if sys.executable.startswith(directory2):
++                # -- PROTECT VIRTUAL ENVIRONMENT (currently in use):
++                # pylint: disable=line-too-long
++                print("SKIP-SUICIDE: '%s' contains current python executable" % directory)
++                continue
++            elif directory2.startswith(python_basedir):
++                # -- PROTECT VIRTUAL ENVIRONMENT (currently in use):
++                # HINT: Limit noise in DIAGNOSTIC OUTPUT to X messages.
++                if warn2_counter <= 4:  # noqa
++                    print("SKIP-SUICIDE: '%s'" % directory)
++                warn2_counter += 1
++                continue
++
++            if not directory.isdir():
++                if show_skipped:
++                    print("RMTREE: %s (SKIPPED: Not a directory)" % directory)
++                continue
++
++            if dry_run:
++                print("RMTREE: %s (dry-run)" % directory)
++            else:
++                try:
++                    # -- MAYBE: directory.rmtree(ignore_errors=True)
++                    print("RMTREE: %s" % directory)
++                    directory.rmtree_p()
++                except OSError as e:
++                    print("RMTREE-FAILED: %s (for: %s)" % (e, directory))
++
++
++def cleanup_files(patterns, workdir=".", dry_run=False, verbose=False, show_skipped=False):
++    """Remove files or files selected by file patterns.
++    Skips removal if file does not exist.
++
++    :param patterns:    File patterns, like "**/*.pyc" (as list).
++    :param workdir:     Current work directory (default=".")
++    :param dry_run:     Dry-run mode indicator (as bool).
++    """
++    show_skipped = show_skipped or verbose
++    current_dir = Path(workdir)
++    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
++    error_message = None
++    error_count = 0
++    for file_pattern in patterns:
++        for file_ in path_glob(file_pattern, current_dir):
++            if file_.abspath().startswith(python_basedir):
++                # -- PROTECT VIRTUAL ENVIRONMENT (currently in use):
++                continue
++            if not file_.isfile():
++                if show_skipped:
++                    print("REMOVE: %s (SKIPPED: Not a file)" % file_)
++                continue
++
++            if dry_run:
++                print("REMOVE: %s (dry-run)" % file_)
++            else:
++                print("REMOVE: %s" % file_)
++                try:
++                    file_.remove_p()
++                except os.error as e:
++                    message = "%s: %s" % (e.__class__.__name__, e)
++                    print(message + " basedir: "+ python_basedir)
++                    error_count += 1
++                    if not error_message:
++                        error_message = message
++    if False and error_message: # noqa
++        class CleanupError(RuntimeError):
++            pass
++        raise CleanupError(error_message)
++
++
++def path_glob(pattern, current_dir=None):
++    """Use pathlib for ant-like patterns, like: "**/*.py"
++
++    :param pattern:      File/directory pattern to use (as string).
++    :param current_dir:  Current working directory (as Path, pathlib.Path, str)
++    :return Resolved Path (as path.Path).
++    """
++    if not current_dir: # noqa
++        current_dir = pathlib.Path.cwd()
++    elif not isinstance(current_dir, pathlib.Path):
++        # -- CASE: string, path.Path (string-like)
++        current_dir = pathlib.Path(str(current_dir))
++
++    pattern_path = Path(pattern)
++    if pattern_path.isabs():
++        # -- SPECIAL CASE: Path.glob() only supports relative-path(s) / pattern(s).
++        if pattern_path.isdir():
++            yield pattern_path
++        return
++
++    # -- HINT: OSError is no longer raised in pathlib2 or python35.pathlib
++    # try:
++    for p in current_dir.glob(pattern):
++        yield Path(str(p))
++    # except OSError as e:
++    #     # -- CORNER-CASE 1: x.glob(pattern) may fail with:
++    #     # OSError: [Errno 13] Permission denied: <filename>
++    #     # HINT: Directory lacks excutable permissions for traversal.
++    #     # -- CORNER-CASE 2: symlinked endless loop
++    #     # OSError: [Errno 62] Too many levels of symbolic links: <filename>
++    #     print("{0}: {1}".format(e.__class__.__name__, e))
++
++
++# -----------------------------------------------------------------------------
++# GENERIC CLEANUP TASKS:
++# -----------------------------------------------------------------------------
++@task(help={
++    "workdir": "Directory to clean(up) (default: $CWD).",
++    "verbose": "Enable verbose mode (default: OFF).",
++})
++def clean(ctx, workdir=".", verbose=False):
++    """Cleanup temporary dirs/files to regain a clean state."""
++    dry_run = ctx.config.run.dry
++    config_dir = getattr(ctx.config, "config_dir", workdir)
++    directories = list(ctx.config.cleanup.directories or [])
++    directories.extend(ctx.config.cleanup.extra_directories or [])
++    files = list(ctx.config.cleanup.files or [])
++    files.extend(ctx.config.cleanup.extra_files or [])
++    excluded_directories = list(ctx.config.cleanup.excluded_directories or [])
++    excluded_directories = make_excluded(excluded_directories,
++                                         config_dir=config_dir, workdir=".")
++
++    # -- PERFORM CLEANUP:
++    execute_cleanup_tasks(ctx, cleanup_tasks)
++    cleanup_dirs(directories, workdir=workdir, excluded=excluded_directories,
++                 dry_run=dry_run, verbose=verbose)
++    cleanup_files(files, workdir=workdir, dry_run=dry_run, verbose=verbose)
++
++    # -- CONFIGURABLE EXTENSION-POINT:
++    # use_cleanup_python = ctx.config.cleanup.use_cleanup_python or False
++    # if use_cleanup_python:
++    #     clean_python(ctx)
++
++
++@task(name="all", aliases=("distclean",),
++      help={
++        "workdir": "Directory to clean(up) (default: $CWD).",
++        "verbose": "Enable verbose mode (default: OFF).",
++})
++def clean_all(ctx, workdir=".", verbose=False):
++    """Clean up everything, even the precious stuff.
++    NOTE: clean task is executed last.
++    """
++    dry_run = ctx.config.run.dry
++    config_dir = getattr(ctx.config, "config_dir", workdir)
++    directories = list(ctx.config.cleanup_all.directories or [])
++    directories.extend(ctx.config.cleanup_all.extra_directories or [])
++    files = list(ctx.config.cleanup_all.files or [])
++    files.extend(ctx.config.cleanup_all.extra_files or [])
++    excluded_directories = list(ctx.config.cleanup_all.excluded_directories or [])
++    excluded_directories.extend(ctx.config.cleanup.excluded_directories or [])
++    excluded_directories = make_excluded(excluded_directories,
++                                         config_dir=config_dir, workdir=".")
++
++    # -- PERFORM CLEANUP:
++    # HINT: Remove now directories, files first before cleanup-tasks.
++    cleanup_dirs(directories, workdir=workdir, excluded=excluded_directories,
++                 dry_run=dry_run, verbose=verbose)
++    cleanup_files(files, workdir=workdir, dry_run=dry_run, verbose=verbose)
++    execute_cleanup_tasks(ctx, cleanup_all_tasks)
++    clean(ctx, workdir=workdir, verbose=verbose)
++
++    # -- CONFIGURABLE EXTENSION-POINT:
++    # use_cleanup_python1 = ctx.config.cleanup.use_cleanup_python or False
++    # use_cleanup_python2 = ctx.config.cleanup_all.use_cleanup_python or False
++    # if use_cleanup_python2 and not use_cleanup_python1:
++    #     clean_python(ctx)
++
++
++@task(aliases=["python"])
++def clean_python(ctx, workdir=".", verbose=False):
++    """Cleanup python related files/dirs: *.pyc, *.pyo, ..."""
++    dry_run = ctx.config.run.dry or False
++    # MAYBE NOT: "**/__pycache__"
++    cleanup_dirs(["build", "dist", "*.egg-info", "**/__pycache__"],
++                 workdir=workdir, dry_run=dry_run, verbose=verbose)
++    if not dry_run:
++        ctx.run("py.cleanup")
++    cleanup_files(["**/*.pyc", "**/*.pyo", "**/*$py.class"],
++                  workdir=workdir, dry_run=dry_run, verbose=verbose)
++
++
++@task(help={
++    "path": "Path to cleanup.",
++    "interactive": "Enable interactive mode.",
++    "force": "Enable force mode.",
++    "options": "Additional git-clean options",
++})
++def git_clean(ctx, path=None, interactive=False, force=False,
++              dry_run=False, options=None):
++    """Perform git-clean command to cleanup the worktree of a git repository.
++
++    BEWARE: This may remove any precious files that are not checked in.
++    WARNING: DANGEROUS COMMAND.
++    """
++    args = []
++    force = force or ctx.config.git_clean.force
++    path = path or ctx.config.git_clean.path or "."
++    interactive = interactive or ctx.config.git_clean.interactive
++    dry_run = dry_run or ctx.config.run.dry or ctx.config.git_clean.dry_run
++
++    if interactive:
++        args.append("--interactive")
++    if force:
++        args.append("--force")
++    if dry_run:
++        args.append("--dry-run")
++    args.append(options or "")
++    args = " ".join(args).strip()
++
++    ctx.run("git clean {options} {path}".format(options=args, path=path))
++
++
++# -----------------------------------------------------------------------------
++# TASK CONFIGURATION:
++# -----------------------------------------------------------------------------
++CLEANUP_EMPTY_CONFIG = {
++    "directories": [],
++    "files": [],
++    "extra_directories": [],
++    "extra_files": [],
++    "excluded_directories": [],
++    "excluded_files": [],
++    "use_cleanup_python": False,
++}
++def make_cleanup_config(**kwargs):
++    config_data = CLEANUP_EMPTY_CONFIG.copy()
++    config_data.update(kwargs)
++    return config_data
++
++
++namespace = Collection(clean_all, clean_python)
++namespace.add_task(clean, default=True)
++namespace.add_task(git_clean)
++namespace.configure({
++    "cleanup": make_cleanup_config(
++        files=["**/*.bak", "**/*.log", "**/*.tmp", "**/.DS_Store"],
++        excluded_directories=[".git", ".hg", ".bzr", ".svn"],
++    ),
++    "cleanup_all": make_cleanup_config(
++        directories=[".venv*", ".tox", "downloads", "tmp"],
++    ),
++    "git_clean": {
++        "interactive": True,
++        "force": False,
++        "path": ".",
++        "dry_run": False,
++    },
++})
++
++
++# -- EXTENSION-POINT: CLEANUP TASKS (called by: clean, clean_all task)
++# NOTE: Can be used by other tasklets to register cleanup tasks.
++cleanup_tasks = Collection("cleanup_tasks")
++cleanup_all_tasks = Collection("cleanup_all_tasks")
++
++# -- EXTEND NORMAL CLEANUP-TASKS:
++# DISABLED: cleanup_tasks.add_task(clean_python)
++
++# -----------------------------------------------------------------------------
++# EXTENSION-POINT: CONFIGURATION HELPERS: Can be used from other task modules
++# -----------------------------------------------------------------------------
++def config_add_cleanup_dirs(directories):
++    # pylint: disable=protected-access
++    the_cleanup_directories = namespace._configuration["cleanup"]["directories"]
++    the_cleanup_directories.extend(directories)
++
++def config_add_cleanup_files(files):
++    # pylint: disable=protected-access
++    the_cleanup_files = namespace._configuration["cleanup"]["files"]
++    the_cleanup_files.extend(files)
++    # namespace.configure({"cleanup": {"files": files}})
++    # print("DIAG cleanup.config.cleanup: %r" % namespace.configuration())
++
++def config_add_cleanup_all_dirs(directories):
++    # pylint: disable=protected-access
++    the_cleanup_directories = namespace._configuration["cleanup_all"]["directories"]
++    the_cleanup_directories.extend(directories)
++
++def config_add_cleanup_all_files(files):
++    # pylint: disable=protected-access
++    the_cleanup_files = namespace._configuration["cleanup_all"]["files"]
++    the_cleanup_files.extend(files)
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index 9c82d11..ac19e94 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -13,8 +13,8 @@ pycmd
+ six==1.15.0
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+-path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
++path.py >= 11.5.0; python_version <  '3.5'
+ 
+ # -- PYTHON2 BACKPORTS:
+ pathlib;    python_version <= '3.4'
+diff --git a/tasks/release.py b/tasks/release.py
+index dba85c8..e17a46f 100644
+--- a/tasks/release.py
++++ b/tasks/release.py
+@@ -51,7 +51,7 @@ Configuration file for pypi repositories:
+ 
+ from __future__ import absolute_import, print_function
+ from invoke import Collection, task
+-from ._tasklet_cleanup import path_glob
++from .invoke_cleanup import path_glob
+ from ._dry_run import DryRunContext
+ 
+ 
+diff --git a/tasks/test.py b/tasks/test.py
+index bfa2d80..d6b4189 100644
+--- a/tasks/test.py
++++ b/tasks/test.py
+@@ -9,7 +9,8 @@ import sys
+ from invoke import task, Collection
+ 
+ # -- TASK-LIBRARY:
+-from ._tasklet_cleanup import cleanup_tasks, cleanup_dirs, cleanup_files
++# PREPARED: from invoke_cleanup import cleanup_tasks, cleanup_dirs, cleanup_files
++from .invoke_cleanup import cleanup_tasks, cleanup_dirs, cleanup_files
+ 
+ 
+ # ---------------------------------------------------------------------------
diff --git a/meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch b/meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch
new file mode 100644
index 000000000..b849cc5e1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch
@@ -0,0 +1,36 @@
+From 87f19edd9048494b22d7c18c737c54844b1a8138 Mon Sep 17 00:00:00 2001
+From: Daniel Lemm <61800298+ffe4@users.noreply.github.com>
+Date: Fri, 26 Jun 2020 11:27:10 +0200
+Subject: [PATCH] Docs: change code blocks from bash to console
+
+---
+ README.rst              | 2 +-
+ docs/practical_tips.rst | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/README.rst b/README.rst
+index 4a905ab..22b0352 100644
+--- a/README.rst
++++ b/README.rst
+@@ -76,7 +76,7 @@ In that directory create a file called "example_steps.py" containing:
+ 
+ Run behave:
+ 
+-.. code-block:: bash
++.. code-block:: console
+ 
+     $ behave
+     Feature: Showing off behave # features/example.feature:2
+diff --git a/docs/practical_tips.rst b/docs/practical_tips.rst
+index b70569f..75bc736 100644
+--- a/docs/practical_tips.rst
++++ b/docs/practical_tips.rst
+@@ -30,7 +30,7 @@ For example, if you want to use the feature files in the same directory for
+ testing the model layer and the UI layer, this can be done by using the
+ ``--stage`` option, like with:
+ 
+-.. code-block:: bash
++.. code-block:: console
+ 
+     $ behave --stage=model features/
+     $ behave --stage=ui    features/  # NOTE: Normally used on a subset of features.
diff --git a/meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch b/meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch
new file mode 100644
index 000000000..69a82b784
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch
@@ -0,0 +1,24 @@
+From b8c3a3f553f8f45342f366c98bde08c5d50b98ed Mon Sep 17 00:00:00 2001
+From: Alex McLarty <alexjmclarty@gmail.com>
+Date: Fri, 12 Jul 2019 08:22:31 +0100
+Subject: [PATCH] Fix typo in tutorial
+
+---
+ docs/tutorial.rst | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/docs/tutorial.rst b/docs/tutorial.rst
+index 04b2f63..27698a4 100644
+--- a/docs/tutorial.rst
++++ b/docs/tutorial.rst
+@@ -157,8 +157,8 @@ basic actions. You may use a Scenario Outline to achieve this:
+ 
+   Scenario Outline: Blenders
+      Given I put <thing> in a blender,
+-      when I switch the blender on
+-      then it should transform into <other thing>
++      When I switch the blender on
++      Then it should transform into <other thing>
+ 
+    Examples: Amphibians
+      | thing         | other thing |
diff --git a/meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch b/meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch
new file mode 100644
index 000000000..ef86a84c3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch
@@ -0,0 +1,80 @@
+From de1d5c096cabbbc63e597d1289350c4e33151f14 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 1 Dec 2020 23:19:51 +0100
+Subject: [PATCH] py.requirements: Use PyHamcrest < 2.0 for python2.7
+
+---
+ issue.features/py.requirements.txt | 3 ++-
+ py.requirements/ci.tox.txt         | 6 ++++--
+ py.requirements/ci.travis.txt      | 7 +++++--
+ py.requirements/testing.txt        | 6 ++++--
+ 4 files changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/issue.features/py.requirements.txt b/issue.features/py.requirements.txt
+index 6e3cf83..f8a2f8d 100644
+--- a/issue.features/py.requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -8,4 +8,5 @@
+ #
+ # ============================================================================
+ 
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 20ae791..5bee524 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -4,9 +4,11 @@
+ 
+ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+-pytest-html >= 1.19.0
++
++pytest-html >= 1.19.0,<2.0
+ mock >= 2.0
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index c69445c..372116a 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,11 +1,14 @@
+ # ============================================================================
+ # PYTHON PACKAGE REQUIREMENTS FOR: behave -- ci.travis.txt
+ # ============================================================================
++
+ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+-pytest-html >= 1.19.0
++
++pytest-html >= 1.19.0,<2.0
+ mock  >= 2.0
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index d3bca18..fc8fd82 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -6,9 +6,11 @@
+ # PREPARED-FUTURE: behave4cmd0, behave4cmd
+ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+-pytest-html >= 1.19.0
++
++pytest-html >= 1.19.0,<2.0
+ mock  >= 2.0
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
diff --git a/meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch b/meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch
new file mode 100644
index 000000000..d20deff2e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch
@@ -0,0 +1,21 @@
+From bce68e9ff14ebf7ee69ad7e75bf5f13ab475c462 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 5 Dec 2020 00:33:22 +0100
+Subject: [PATCH] UPDATE: PR #877 was merged.
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d758364..4e20bb8 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -58,6 +58,7 @@ MINOR:
+ 
+ DOCUMENTATION:
+ 
++* pull  #877: docs: API reference - Capitalizing Step Keywords in example (provided by: Ibrian93)
+ * pull  #731: Update links to Django docs (provided by: bittner)
+ * pull  #722: DOC remove remaining pythonhosted links (provided by: leszekhanusz)
+ * pull  #701: behave/runner.py docstrings (provided by: spitGlued)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch b/meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch
new file mode 100644
index 000000000..fcf7651d4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch
@@ -0,0 +1,28 @@
+From da598db70063a591e065857cf5135070f6d85704 Mon Sep 17 00:00:00 2001
+From: Brian Icochea <ibrian93@gmail.com>
+Date: Sun, 15 Nov 2020 18:35:16 +0100
+Subject: [PATCH] capitalizing steps
+
+---
+ docs/api.rst | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/docs/api.rst b/docs/api.rst
+index 4763ad6..7463863 100644
+--- a/docs/api.rst
++++ b/docs/api.rst
+@@ -74,10 +74,10 @@ the name of their preceding keyword, so given the following feature file:
+ .. code-block:: gherkin
+ 
+     Given some known state
+-      and some other known state
+-     when some action is taken
+-     then some outcome is observed
+-      but some other outcome is not observed.
++      And some other known state
++     When some action is taken
++     Then some outcome is observed
++      But some other outcome is not observed.
+ 
+ the first "and" step will be renamed internally to "given" and *behave*
+ will look for a step implementation decorated with either "given" or "step":
diff --git a/meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch b/meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch
new file mode 100644
index 000000000..05220be2f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch
@@ -0,0 +1,56 @@
+From cdaa39ca2ac2ef603e94f26da575fa8dca160865 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 11 Dec 2020 20:51:44 +0100
+Subject: [PATCH] FIX: invoke-task develop.update-gherkin that aborted after
+ diff
+
+* Show now if "gherkin-languages.json" does not change
+* Add --verbose option to show diff output if file has changed
+---
+ tasks/develop.py | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/tasks/develop.py b/tasks/develop.py
+index 9a21363..eb5fedd 100644
+--- a/tasks/develop.py
++++ b/tasks/develop.py
+@@ -9,6 +9,7 @@ from invoke.util import cd
+ from path import Path
+ import requests
+ 
++
+ # -----------------------------------------------------------------------------
+ # CONSTANTS:
+ # -----------------------------------------------------------------------------
+@@ -18,8 +19,8 @@ GHERKIN_LANGUAGES_URL = "https://raw.githubusercontent.com/cucumber/cucumber/mas
+ # -----------------------------------------------------------------------------
+ # TASKS:
+ # -----------------------------------------------------------------------------
+-@task
+-def update_gherkin(ctx, dry_run=False):
++@task(aliases=["update-languages"])
++def update_gherkin(ctx, dry_run=False, verbose=False):
+     """Update "gherkin-languages.json" file from cucumber-repo.
+ 
+     * Download "gherkin-languages.json" from cucumber repo
+@@ -41,8 +42,18 @@ def update_gherkin(ctx, dry_run=False):
+ 
+         print('Generating "i18n.py" ...')
+         ctx.run("./convert_gherkin-languages.py")
+-        ctx.run("diff i18n.py ../../behave/i18n.py")
+-        if not dry_run:
++
++        # -- DIFF: Returns normally w/ non-zero exitcode => NEEDS: warn=True
++        languages_have_changed = False
++        result = ctx.run("diff i18n.py ../../behave/i18n.py", warn=True, hide=True)
++        languages_have_changed = not result.ok
++        if verbose and languages_have_changed:
++            # -- SHOW DIFF:
++            print(result.stdout)
++
++        if not languages_have_changed:
++            print("NO_CHANGED: gherkin-languages.json")
++        elif not dry_run:
+             print("Updating behave/i18n.py ...")
+             Path("i18n.py").move("../../behave/i18n.py")
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch b/meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch
new file mode 100644
index 000000000..829eea2e4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch
@@ -0,0 +1,22 @@
+From 6f9f088271161adf4ce7a4bdc840b16ddd95b39e Mon Sep 17 00:00:00 2001
+From: santosh653 <70637961+santosh653@users.noreply.github.com>
+Date: Mon, 14 Dec 2020 12:05:50 -0500
+Subject: [PATCH] Test against PowerPC CPU support (Travis) (#867)
+
+Run test suite against both AMD and PowerPC architecture
+---
+ .travis.yml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/.travis.yml b/.travis.yml
+index 781a610..2b78d97 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -1,3 +1,7 @@
++arch: 
++  - amd64
++  - ppc64le
++  
+ language: python
+ sudo: false
+ dist: xenial   # required for Python >= 3.7
diff --git a/meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch b/meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch
new file mode 100644
index 000000000..ac0197202
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch
@@ -0,0 +1,132 @@
+From e1be95bbc0080eacb20bc5b263a838784c2a1ea2 Mon Sep 17 00:00:00 2001
+From: Korijn van Golen <k.vangolen@clinicalgraphics.com>
+Date: Sat, 28 Nov 2020 11:39:28 +0100
+Subject: [PATCH] Add Context.attach, docs and test
+
+---
+ behave/formatter/json.py        |  6 +++--
+ behave/runner.py                | 11 +++++++++
+ docs/formatters.rst             | 18 ++++++++++++++
+ features/formatter.json.feature | 42 +++++++++++++++++++++++++++++++++
+ 4 files changed, 75 insertions(+), 2 deletions(-)
+
+diff --git a/behave/formatter/json.py b/behave/formatter/json.py
+index 6da0d59..edfe3d7 100644
+--- a/behave/formatter/json.py
++++ b/behave/formatter/json.py
+@@ -168,10 +168,12 @@ class JSONFormatter(Formatter):
+         self._step_index += 1
+ 
+     def embedding(self, mime_type, data):
+-        step = self.current_feature_element["steps"][-1]
++        step = self.current_feature_element["steps"][self._step_index]
++        if "embeddings" not in step:
++            step["embeddings"] = []
+         step["embeddings"].append({
+             "mime_type": mime_type,
+-            "data": base64.b64encode(data).replace("\n", ""),
++            "data": base64.b64encode(data).decode(self.stream.encoding or "utf-8"),
+         })
+ 
+     def eof(self):
+diff --git a/behave/runner.py b/behave/runner.py
+index d01bff0..c583caf 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -475,6 +475,17 @@ class Context(object):
+             # -- AVOID DUPLICATES:
+             current_frame["@cleanups"].append(internal_cleanup_func)
+ 
++    def attach(self, mime_type, data):
++        """Embeds data (e.g. a screenshot) in reports for all
++        formatters that support it, such as the JSON formatter.
++
++        :param mime_type:       MIME type of the binary data.
++        :param data:            Bytes-like object to embed.
++        """
++        is_compatible = lambda f: hasattr(f, "embedding")
++        for formatter in filter(is_compatible, self._runner.formatters):
++            formatter.embedding(mime_type, data)
++
+ 
+ @contextlib.contextmanager
+ def use_context_with_mode(context, mode):
+diff --git a/docs/formatters.rst b/docs/formatters.rst
+index a40fd8d..534468a 100644
+--- a/docs/formatters.rst
++++ b/docs/formatters.rst
+@@ -116,3 +116,21 @@ teamcity       :pypi:`behave-teamcity`, a formatter for Jetbrains TeamCity CI te
+     [behave.formatters]
+     allure   = allure_behave.formatter:AllureFormatter
+     teamcity = behave_teamcity:TeamcityFormatter
++
++
++Embedding data (e.g. screenshots) in reports
++------------------------------------------------------------------------------
++
++You can embed data in reports with the :class:`~behave.runner.Context` method
++:func:`~behave.runner.Context.attach`, if you have configured a formatter that
++supports it. Currently only the JSON formatter supports embedding data.
++
++For example:
++
++.. code-block:: python
++
++    @when(u'I open the Google webpage')
++    def step_impl(context):
++        context.browser.get('http://www.google.com')
++        img = context.browser.get_full_page_screenshot_as_png()
++        context.attach("image/png", img)
+diff --git a/features/formatter.json.feature b/features/formatter.json.feature
+index 96b28c7..67c97ae 100644
+--- a/features/formatter.json.feature
++++ b/features/formatter.json.feature
+@@ -309,6 +309,48 @@ Feature: JSON Formatter
+       But note that "both matched arguments.values are provided as string"
+ 
+ 
++    Scenario: Use JSON formatter and embed binary data in report from two steps
++      Given a file named "features/json_embeddings.feature" with:
++          """
++          Feature:
++            Scenario: Use embeddings
++                Given "foobar" as plain text
++                And "red" as plain text
++          """
++      And a file named "features/steps/json_embeddings_steps.py" with:
++          """
++          from behave import step
++
++          @step('"{data}" as plain text')
++          def step_string(context, data):
++              context.attach("text/plain", data.encode("utf-8"))
++          """
++      When I run "behave -f json.pretty features/json_embeddings.feature"
++      Then it should pass with:
++          """
++          1 feature passed, 0 failed, 0 skipped
++          1 scenario passed, 0 failed, 0 skipped
++          """
++      And the command output should contain:
++          """
++                    "embeddings": [
++                      {
++                        "data": "Zm9vYmFy",
++                        "mime_type": "text/plain"
++                      }
++                    ],
++          """
++      And the command output should contain:
++          """
++                    "embeddings": [
++                      {
++                        "data": "cmVk",
++                        "mime_type": "text/plain"
++                      }
++                    ],
++          """
++
++
+     @xfail
+     @regression_problem.with_duration
+     Scenario: Use JSON formatter with feature and one scenario with steps
diff --git a/meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch b/meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch
new file mode 100644
index 000000000..63b4e7ce5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch
@@ -0,0 +1,125 @@
+From 5838eafe65cf0ebcda3d192318015326a8afb52a Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Sat, 12 Dec 2020 19:45:26 +0100
+Subject: [PATCH] Add Contributing chapter
+
+---
+ docs/conf.py          |  2 +-
+ docs/contributing.rst | 82 +++++++++++++++++++++++++++++++++++++++++++
+ docs/index.rst        |  1 +
+ 3 files changed, 84 insertions(+), 1 deletion(-)
+ create mode 100644 docs/contributing.rst
+
+diff --git a/docs/conf.py b/docs/conf.py
+index e55fb21..1579a36 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -108,7 +108,7 @@ if USE_SPHINX_INTERNATIONAL:
+ # -----------------------------------------------------------------------------
+ project = u"behave"
+ authors = u"Jens Engel, Benno Rice and Richard Jones"
+-copyright = u"2012-2019, %s" % authors
++copyright = u"2012-2020, %s" % authors
+ 
+ # The version info for the project you're documenting, acts as replacement for
+ # |version| and |release|, also used in various other places throughout the
+diff --git a/docs/contributing.rst b/docs/contributing.rst
+new file mode 100644
+index 0000000..78f36bd
+--- /dev/null
++++ b/docs/contributing.rst
+@@ -0,0 +1,82 @@
++Contributing
++============
++
++If you find a bug you can fix or want to contribute an enhancement you're
++welcome to `open an issue`_ on GitHub or create a `pull request`_ directly.
++
++.. _open an issue: https://github.com/behave/behave/issues
++.. _pull request: https://github.com/behave/behave/pulls
++
++Using ``invoke`` for Development
++--------------------------------
++
++For most development tasks we have `invoke`_ commands.
++
++Install all requirements for running tasks using Pip, e.g.
++
++.. code-block:: console
++
++    python3 -m pip install -r tasks/py.requirements.txt
++
++Display all available ``invoke`` commands like this:
++
++.. code-block:: console
++
++    invoke -l
++
++If you're curious, all ``invoke`` tasks are located in the ``tasks/``
++folder.
++
++.. _invoke: https://www.pyinvoke.org/
++
++Update Gherkin Language Specification
++-------------------------------------
++
++An ``invoke`` command will download the latest Gherkin language
++specification and update the `behave/i18n.py`_ module:
++
++.. code-block:: console
++
++    invoke develop.update-gherkin
++
++If there were changes this command will have updated two files:
++
++#. ``etc/gherkin/gherkin-languages.json`` (original Cucumber JSON spec)
++#. ``behave/i18n.py`` (Python module generated from the JSON spec)
++
++Put both under version control and open a PR to merge them.
++
++.. _behave/i18n.py:
++    https://github.com/behave/behave/blob/master/behave/i18n.py
++
++Update Documentation
++--------------------
++
++Our documentation is written in `reStructuredText`_, and built and hosted
++on `ReadTheDocs`_. Make your changes to the files in the ``docs/`` folder
++and build the documentation with:
++
++.. code-block:: console
++
++    invoke docs
++
++or, alternatively, using Tox:
++
++.. code-block:: console
++
++    tox -e docs
++
++.. hint::
++
++    Building the docs requires Sphinx and DocUtils. If your build fails
++    because those are missing, run:
++
++        python3 -m pip install -r py.requirements/docs.txt
++
++Once the docs are built successfully, ``sphinx`` will tell you where it
++generated the HTML output (typically ``build/docs/html``), which you can
++then inspect locally.
++
++.. _reStructuredText:
++    https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
++.. _ReadTheDocs: https://readthedocs.org/
+diff --git a/docs/index.rst b/docs/index.rst
+index f0dd20e..e00079c 100644
+--- a/docs/index.rst
++++ b/docs/index.rst
+@@ -43,6 +43,7 @@ Contents
+    comparison
+    new_and_noteworthy
+    more_info
++   contributing
+    appendix
+ 
+ .. seealso::
diff --git a/meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch b/meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch
new file mode 100644
index 000000000..4dd3996a3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch
@@ -0,0 +1,34 @@
+From 25c2601d1d8d8836c9673dcbbf852515297e926a Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Sat, 12 Dec 2020 19:46:29 +0100
+Subject: [PATCH] Adapt Tox target for building the docs
+
+This will generate the HTML docs in the same location as `invoke docs`.
+---
+ tox.ini | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/tox.ini b/tox.ini
+index b825921..8ccb58b 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -77,12 +77,9 @@ setenv =
+ 
+ 
+ [testenv:docs]
+-basepython= python2
+ changedir = docs
+-commands=
+-    sphinx-build -W -b html -D language=en -d {envtmpdir}/doctrees . {envtmpdir}/html/en
+-deps=
+-    -r{toxinidir}/py.requirements/docs.txt
++commands = sphinx-build -W -b html -D language=en -d {toxinidir}/build/docs/doctrees . {toxinidir}/build/docs/html/en
++deps = -r{toxinidir}/py.requirements/docs.txt
+ 
+ 
+ [testenv:cleanroom2]
+@@ -146,4 +143,3 @@ commands=
+ deps=
+     jit
+     {[testenv]deps}
+-
diff --git a/meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch b/meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch
new file mode 100644
index 000000000..048e927bf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch
@@ -0,0 +1,83 @@
+From 3bfc68099983191d1bc095d9ff4491fff41157eb Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Tue, 15 Dec 2020 11:30:17 +0100
+Subject: [PATCH] Mention HTML formatter in documentation
+
+---
+ docs/formatters.rst | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/docs/formatters.rst b/docs/formatters.rst
+index 534468a..6080fc4 100644
+--- a/docs/formatters.rst
++++ b/docs/formatters.rst
+@@ -1,8 +1,8 @@
+ .. _id.appendix.formatters:
+ 
+-==============================================================================
++========================
+ Formatters and Reporters
+-==============================================================================
++========================
+ 
+ :pypi:`behave` provides 2 different concepts for reporting results of a test run:
+ 
+@@ -15,7 +15,7 @@ The ``Reporter`` has a more coarse-grained API.
+ 
+ 
+ Reporters
+-------------------------------------------------------------------------------
++---------
+ 
+ The following reporters are currently supported:
+ 
+@@ -28,7 +28,7 @@ summary         Provides a summary of the test run.
+ 
+ 
+ Formatters
+-------------------------------------------------------------------------------
++----------
+ 
+ The following formatters are currently supported:
+ 
+@@ -62,7 +62,7 @@ tags.location  dry-run  Shows tags and the location where they are used.
+ 
+ 
+ User-Defined Formatters
+-------------------------------------------------------------------------------
++-----------------------
+ 
+ Behave allows you to provide your own formatter (class)::
+ 
+@@ -96,16 +96,16 @@ to provide them. The formatter should use the attribute schema:
+ 
+ 
+ More Formatters
+-------------------------------------------------------------------------------
++---------------
+ 
+-The following formatters are currently known:
++The following contributed formatters are currently known:
+ 
+ ============== =========================================================================
+ Name           Description
+ ============== =========================================================================
+-allure         :pypi:`allure-behave`, an Allure formatter for behave:
+-               ``allure_behave.formatter:AllureFormatter``
+-teamcity       :pypi:`behave-teamcity`, a formatter for Jetbrains TeamCity CI testruns
++allure         :pypi:`allure-behave`, an Allure formatter for behave.
++html           :pypi:`behave-html-formatter`, a simple HTML formatter for behave.
++teamcity       :pypi:`behave-teamcity`, a formatter for JetBrains TeamCity CI testruns
+                with behave.
+ ============== =========================================================================
+ 
+@@ -114,7 +114,8 @@ teamcity       :pypi:`behave-teamcity`, a formatter for Jetbrains TeamCity CI te
+     # -- FILE: behave.ini
+     # FORMATTER ALIASES: behave -f allure ...
+     [behave.formatters]
+-    allure   = allure_behave.formatter:AllureFormatter
++    allure = allure_behave.formatter:AllureFormatter
++    html = behave_html_formatter:HTMLFormatter
+     teamcity = behave_teamcity:TeamcityFormatter
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch b/meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch
new file mode 100644
index 000000000..6b09b9360
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch
@@ -0,0 +1,22 @@
+From 709c32be819afbbb7c7aecc392fac4986e9ae90f Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Tue, 15 Dec 2020 12:44:52 +0100
+Subject: [PATCH] Use console highlighting for `pip install` (docs)
+
+---
+ docs/contributing.rst | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/docs/contributing.rst b/docs/contributing.rst
+index 78f36bd..f3deb87 100644
+--- a/docs/contributing.rst
++++ b/docs/contributing.rst
+@@ -71,6 +71,8 @@ or, alternatively, using Tox:
+     Building the docs requires Sphinx and DocUtils. If your build fails
+     because those are missing, run:
+ 
++    .. code-block:: console
++
+         python3 -m pip install -r py.requirements/docs.txt
+ 
+ Once the docs are built successfully, ``sphinx`` will tell you where it
diff --git a/meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch b/meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch
new file mode 100644
index 000000000..f216c29a7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch
@@ -0,0 +1,52 @@
+From 7a122510a7d4843b5f8c64c0a34a807757184a26 Mon Sep 17 00:00:00 2001
+From: Tim Gates <tim.gates@iress.com>
+Date: Sun, 27 Dec 2020 08:16:16 +1100
+Subject: [PATCH] docs: fix simple typo, tuorial -> tutorial
+
+There is a small typo in docs/more_info.rst.
+
+Should read `tutorial` rather than `tuorial`.
+---
+ docs/more_info.rst | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/docs/more_info.rst b/docs/more_info.rst
+index d0b9fcd..0d87a9c 100644
+--- a/docs/more_info.rst
++++ b/docs/more_info.rst
+@@ -66,7 +66,7 @@ Presentation Videos
+ * Benno Rice: `Making Your Application Behave`_ (30min),
+   2012-08-12, PyCon Australia.
+ 
+-* Selenium: `First behave python tuorial with selenium`_ (8min), 2015-01-28,
++* Selenium: `First behave python tutorial with selenium`_ (8min), 2015-01-28,
+   http://www.seleniumframework.com/python-basic/first-behave-gherkin/
+ 
+ * Jessica Ingrasselino: `Automation with Python and Behave`_ (67min), 2015-12-16
+@@ -84,7 +84,7 @@ Presentation Videos
+         * Benno Rice: `Making Your Application Behave`_ (30min),
+           PyCon Australia, 2012-08-12
+ 
+-        * Selenium: `First behave python tuorial with selenium`_ (8min), 2015-01-28,
++        * Selenium: `First behave python tutorial with selenium`_ (8min), 2015-01-28,
+           http://www.seleniumframework.com/python-basic/first-behave-gherkin/
+ 
+         * Jessica Ingrasselino: `Automation with Python and Behave`_ (67min), 2015-12-16
+@@ -112,7 +112,7 @@ Presentation Videos
+             :width: 600
+             :height: 400
+ 
+-        Selenium: `First behave python tuorial with selenium`_
++        Selenium: `First behave python tutorial with selenium`_
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 
+         :Date: 2015-01-28
+@@ -146,7 +146,7 @@ Presentation Videos
+ 
+ 
+ .. _`Making Your Application Behave`: https://www.youtube.com/watch?v=u8BOKuNkmhg
+-.. _`First behave python tuorial with selenium`: https://www.youtube.com/watch?v=D24_QrGUCFk
++.. _`First behave python tutorial with selenium`: https://www.youtube.com/watch?v=D24_QrGUCFk
+ .. _`Automation with Python and Behave`: https://www.youtube.com/watch?v=e78c7h6DRDQ
+ .. _`Selenium Python Webdriver Tutorial - Behave (BDD)`: https://www.youtube.com/watch?v=mextSo0UExc
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch b/meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch
new file mode 100644
index 000000000..dcdbc4cf3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch
@@ -0,0 +1,227 @@
+From 5c6fd7eaeba958759ccedaaa483fe213859cfa6d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 12 Oct 2020 21:52:25 +0200
+Subject: [PATCH] Add support for python3.9 (by using active-tags).
+
+---
+ features/step.async_steps.feature | 21 +++++++++++++++++++++
+ issue.features/issue0330.feature  |  6 ++++++
+ issue.features/issue0446.feature  |  4 ++++
+ issue.features/issue0457.feature  |  5 +++++
+ issue.features/issue0657.feature  |  3 +++
+ 5 files changed, 39 insertions(+)
+
+diff --git a/features/step.async_steps.feature b/features/step.async_steps.feature
+index 3a18fa9..06709d9 100644
+--- a/features/step.async_steps.feature
++++ b/features/step.async_steps.feature
+@@ -32,6 +32,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use async-step with @async_run_until_complete (async)
+       Given a new working directory
+       And a file named "features/steps/async_steps35.py" with:
+@@ -63,6 +66,9 @@ Feature: Async-Test Support (async-step, ...)
+     @use.with_python.version=3.4
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use async-step with @async_run_until_complete (@coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps34.py" with:
+@@ -93,6 +99,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (async)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout35.py" with:
+@@ -128,6 +137,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     @async_step_fails
+     Scenario: Use @async_run_until_complete and async-step fails
+       Given a new working directory
+@@ -170,6 +182,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     @async_step_fails
+     Scenario: Use @async_run_until_complete and async-step raises error
+       Given a new working directory
+@@ -213,6 +228,9 @@ Feature: Async-Test Support (async-step, ...)
+     @use.with_python.version=3.4
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (@coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout34.py" with:
+@@ -250,6 +268,9 @@ Feature: Async-Test Support (async-step, ...)
+     @use.with_python.version=3.4
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use async-dispatch and async-collect concepts
+       Given a new working directory
+       And a file named "features/steps/async_dispatch_steps.py" with:
+diff --git a/issue.features/issue0330.feature b/issue.features/issue0330.feature
+index 81cb6e2..be4d378 100644
+--- a/issue.features/issue0330.feature
++++ b/issue.features/issue0330.feature
+@@ -71,6 +71,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+ 
+   @not.with_python.version=3.8
++  @not.with_python.version=3.9
+   Scenario: Junit report for skipped feature is created with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+@@ -85,6 +86,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       """
+ 
+   @use.with_python.version=3.8
++  @use.with_python.version=3.9
+   Scenario: Junit report for skipped feature is created with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+@@ -101,6 +103,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       # <testsuite errors="0" failures="0" name="bob.Bob" skipped="1" tests="1" time="0.0">
+ 
+   @not.with_python.version=3.8
++  @not.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+@@ -121,6 +124,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+     And note that "Charly2 is the skipped scenarion in charly.feature"
+ 
+   @use.with_python.version=3.8
++  @use.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+@@ -144,6 +148,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+ 
+   @not.with_python.version=3.8
++  @not.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+@@ -165,6 +170,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+ 
+   @use.with_python.version=3.8
++  @use.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+diff --git a/issue.features/issue0446.feature b/issue.features/issue0446.feature
+index 901bdec..12de37a 100644
+--- a/issue.features/issue0446.feature
++++ b/issue.features/issue0446.feature
+@@ -59,6 +59,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+         """
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Hook error in before_scenario()
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+@@ -88,6 +89,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+ 
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Hook error in before_scenario()
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+@@ -121,6 +123,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Hook error in after_scenario()
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+@@ -152,6 +155,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+ 
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Hook error in after_scenario()
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+diff --git a/issue.features/issue0457.feature b/issue.features/issue0457.feature
+index 46f96e9..6d2f48f 100644
+--- a/issue.features/issue0457.feature
++++ b/issue.features/issue0457.feature
+@@ -25,6 +25,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Use failing assertation in a JUnit XML report
+       Given a file named "features/fails1.feature" with:
+         """
+@@ -46,6 +47,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         """
+ 
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use failing assertation in a JUnit XML report
+       Given a file named "features/fails1.feature" with:
+         """
+@@ -70,6 +72,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Use exception in a JUnit XML report
+       Given a file named "features/fails2.feature" with:
+         """
+@@ -90,7 +93,9 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         <error message="My name is &quot;Bob&quot; and &lt;here&gt; I am"
+         """
+ 
++
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use exception in a JUnit XML report
+       Given a file named "features/fails2.feature" with:
+         """
+diff --git a/issue.features/issue0657.feature b/issue.features/issue0657.feature
+index f667893..aeaefd2 100644
+--- a/issue.features/issue0657.feature
++++ b/issue.features/issue0657.feature
+@@ -5,6 +5,9 @@ Feature: Issue #657 -- Allow async steps with timeouts to fail when they raise e
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     @async_step_fails
+     Scenario: Use @async_run_until_complete and async-step fails
+       Given a new working directory
diff --git a/meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch b/meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch
new file mode 100644
index 000000000..27c77b7b5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch
@@ -0,0 +1,19 @@
+From 1ff8338ea1d8a27a5c45492507ed64154cc2cfc7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 12 Oct 2020 22:14:59 +0200
+Subject: [PATCH] PREFER: python3 from now on.
+
+---
+ bin/behave | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bin/behave b/bin/behave
+index c02e8d3..9ebb584 100755
+--- a/bin/behave
++++ b/bin/behave
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/env python3
+ # -*- coding: utf-8 -*-
+ 
+ from __future__ import absolute_import
diff --git a/meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch b/meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch
new file mode 100644
index 000000000..cbbfe6d6b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch
@@ -0,0 +1,41 @@
+From c947c0726673bcb8d8d3114d0e39fc926040559e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 21:52:04 +0100
+Subject: [PATCH] REMOVE: invoke scripts
+
+---
+ bin/invoke     | 8 --------
+ bin/invoke.cmd | 9 ---------
+ 2 files changed, 17 deletions(-)
+ delete mode 100755 bin/invoke
+ delete mode 100644 bin/invoke.cmd
+
+diff --git a/bin/invoke b/bin/invoke
+deleted file mode 100755
+index e9800e8..0000000
+--- a/bin/invoke
++++ /dev/null
+@@ -1,8 +0,0 @@
+-#!/bin/sh
+-#!/bin/bash
+-# RUN INVOKE: From bundled ZIP file.
+-
+-HERE=$(dirname $0)
+-export INVOKE_TASKS_USE_VENDOR_BUNDLES="yes"
+-
+-python ${HERE}/../tasks/_vendor/invoke.zip $*
+diff --git a/bin/invoke.cmd b/bin/invoke.cmd
+deleted file mode 100644
+index 9303432..0000000
+--- a/bin/invoke.cmd
++++ /dev/null
+@@ -1,9 +0,0 @@
+-@echo off
+-REM RUN INVOKE: From bundled ZIP file.
+-
+-setlocal
+-set HERE=%~dp0
+-set INVOKE_TASKS_USE_VENDOR_BUNDLES="yes"
+-if not defined PYTHON   set PYTHON=python
+-
+-%PYTHON% %HERE%../tasks/_vendor/invoke.zip "%*"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch b/meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch
new file mode 100644
index 000000000..e4cb51acf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch
@@ -0,0 +1,124 @@
+From 3fb11ef19d2265b6e29fc69191079b32c79225dd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 21:52:42 +0100
+Subject: [PATCH] FIX: Deprecated warnings for Python 3.x
+
+---
+ bin/json.format.py         | 15 ++++++++++-----
+ bin/jsonschema_validate.py | 23 ++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 12 deletions(-)
+
+diff --git a/bin/json.format.py b/bin/json.format.py
+index b7eb05f..b75d88a 100755
+--- a/bin/json.format.py
++++ b/bin/json.format.py
+@@ -10,8 +10,8 @@ LICENSE:  BSD
+ from __future__ import absolute_import
+ 
+ __author__    = "Jens Engel"
+-__copyright__ = "(c) 2011-2013 by Jens Engel"
+-VERSION = "0.2.2"
++__copyright__ = "(c) 2011-2021 by Jens Engel"
++VERSION = "0.3.0"
+ 
+ # -- IMPORTS:
+ import os.path
+@@ -29,6 +29,7 @@ except ImportError:
+ # CONSTANTS:
+ # ----------------------------------------------------------------------------
+ DEFAULT_INDENT_SIZE = 2
++PYTHON_VERSION = sys.version_info[:2]
+ 
+ # ----------------------------------------------------------------------------
+ # FUNCTIONS:
+@@ -58,7 +59,11 @@ def json_format(filename, indent=DEFAULT_INDENT_SIZE, **kwargs):
+ #        return 0
+ 
+     contents = open(filename, "r").read()
+-    data      = json.loads(contents, encoding=encoding)
++    if PYTHON_VERSION >= (3, 1):
++        # -- NOTE: encoding keyword is deprecated since python 3.1
++        data = json.loads(contents)
++    else:
++        data = json.loads(contents, encoding=encoding)
+     contents2 = json.dumps(data, indent=indent, sort_keys=sort_keys)
+     contents2 = contents2.strip()
+     contents2 = "%s\n" % contents2
+@@ -69,7 +74,7 @@ def json_format(filename, indent=DEFAULT_INDENT_SIZE, **kwargs):
+         outfile = open(filename, "w")
+         outfile.write(contents2)
+         outfile.close()
+-        console.warn("%s OK", message)
++        console.warning("%s OK", message)
+         return 1 #< OK
+ 
+ def json_formatall(filenames, indent=DEFAULT_INDENT_SIZE, dry_run=False):
+@@ -143,7 +148,7 @@ Format/Beautify one or more JSON file(s)."""
+                 console.info("SKIP %s, no JSON files found in dir.", filename)
+                 skipped += 1
+         elif not os.path.exists(filename):
+-            console.warn("SKIP %s, file not found.", filename)
++            console.warning("SKIP %s, file not found.", filename)
+             skipped += 1
+             continue
+         else:
+diff --git a/bin/jsonschema_validate.py b/bin/jsonschema_validate.py
+index db2edb1..fe7596e 100755
+--- a/bin/jsonschema_validate.py
++++ b/bin/jsonschema_validate.py
+@@ -18,11 +18,11 @@ from __future__ import absolute_import, print_function
+ __author__  = "Jens Engel"
+ __version__ = "0.1.0"
+ 
+-from jsonschema import validate
+ import argparse
+ import os.path
+ import sys
+ import textwrap
++from jsonschema import validate
+ try:
+     import json
+ except ImportError:
+@@ -38,16 +38,28 @@ except ImportError:
+ HERE = os.path.dirname(__file__)
+ TOP  = os.path.normpath(os.path.join(HERE, ".."))
+ SCHEMA = os.path.join(TOP, "etc", "json", "behave.json-schema")
++PYTHON_VERSION = sys.version_info[:2]
+ 
+ 
+ # -----------------------------------------------------------------------------
+ # FUNCTIONS:
+ # -----------------------------------------------------------------------------
+-def jsonschema_validate(filename, schema, encoding=None):
++def json_loads(text, encoding=None):
++    kwargs = {}
++    if encoding and PYTHON_VERSION < (3, 1):
++        # -- NOTE: encoding keyword is deprecated since python 3.1
++        kwargs["encoding"] = encoding
++    return json.loads(text, **kwargs)
++
++def json_load(filename, encoding=None):
+     f = open(filename, "r")
+     contents = f.read()
+     f.close()
+-    data = json.loads(contents, encoding=encoding)
++    data = json_loads(contents, encoding=encoding)
++    return data
++
++def jsonschema_validate(filename, schema, encoding=None):
++    data = json_load(filename, encoding=encoding)
+     return validate(data, schema)
+ 
+ 
+@@ -89,10 +101,7 @@ def main(args=None):
+         parser.error("SCHEMA not found: %s" % options.schema)
+ 
+     try:
+-        f = open(options.schema, "r")
+-        contents = f.read()
+-        f.close()
+-        schema = json.loads(contents, encoding=options.encoding)
++        schema = json_load(options.schema, encoding=options.encoding)
+     except Exception as e:
+         msg = "ERROR: %s: %s (while loading schema)" % (e.__class__.__name__, e)
+         sys.exit(msg)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch b/meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch
new file mode 100644
index 000000000..615d10bd6
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch
@@ -0,0 +1,18 @@
+From 961e4f93259a0c1176a53a34d8e8de592c03db55 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 21:53:32 +0100
+Subject: [PATCH] FIX: Python2 problems in virtualenvs w/ behave4cmd0 steps.
+
+---
+ bin/behave | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/bin/behave b/bin/behave
+index 9ebb584..0f37dec 100755
+--- a/bin/behave
++++ b/bin/behave
+@@ -1,3 +1,4 @@
++#!/usr/bin/env python
+ #!/usr/bin/env python3
+ # -*- coding: utf-8 -*-
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch b/meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch
new file mode 100644
index 000000000..d45aba3d4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch
@@ -0,0 +1,875 @@
+From 2c38a8787409ddb50ff9ee93006d5e30a40110de Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 22:04:18 +0100
+Subject: [PATCH] FIX: Active-tag logic
+
+Fix active-tag computation logic if multiple active-tags exist
+that use the same category. It is now possible to use
+positive (use.with_xxx) and negative (not.with_xxx) tags
+on the same model element (Feature, Scenario, ...).
+---
+ behave/api/runtime_constraint.py     |  12 +-
+ behave/tag_matcher.py                |  82 ++++-
+ features/tags.active_tags.feature    |  22 +-
+ tests/functional/test_active_tags.py | 529 +++++++++++++++++++++++++++
+ tests/unit/test_tag_matcher.py       |  45 +--
+ 5 files changed, 624 insertions(+), 66 deletions(-)
+ create mode 100644 tests/functional/test_active_tags.py
+
+diff --git a/behave/api/runtime_constraint.py b/behave/api/runtime_constraint.py
+index 310e529..e5a36a0 100644
+--- a/behave/api/runtime_constraint.py
++++ b/behave/api/runtime_constraint.py
+@@ -7,6 +7,8 @@ Simplifies to specify runtime constraints in
+ """
+ 
+ from __future__ import absolute_import
++import six
++import sys
+ from behave.exception import ConstraintError
+ 
+ 
+@@ -19,11 +21,10 @@ def require_min_python_version(minimal_version):
+     :param minimal_version: Minimum version (as string, tuple)
+     :raises: behave.exception.ConstraintError
+     """
+-    import six
+-    import sys
+     python_version = sys.version_info
+     if isinstance(minimal_version, six.string_types):
+-        python_version = "%s.%s" % sys.version_info[:2]
++        python_version = float("%s.%s" % sys.version_info[:2])
++        minimal_version = float(minimal_version)
+     elif not isinstance(minimal_version, tuple):
+         raise TypeError("string or tuple (was: %s)" % type(minimal_version))
+ 
+@@ -40,6 +41,9 @@ def require_min_behave_version(minimal_version):
+     """
+     # -- SIMPLISTIC IMPLEMENTATION:
+     from behave.version import VERSION as behave_version
+-    if behave_version < minimal_version:
++    behave_version2 = behave_version.split(".")
++    minimal_version2 = minimal_version.split(".")
++    if behave_version2 < minimal_version2:
++        # -- USE: Tuple comparison as version comparison.
+         raise ConstraintError("behave >= %s expected (was: %s)" % \
+                               (minimal_version, behave_version))
+diff --git a/behave/tag_matcher.py b/behave/tag_matcher.py
+index 5f9dce0..e2b1e82 100644
+--- a/behave/tag_matcher.py
++++ b/behave/tag_matcher.py
+@@ -1,7 +1,7 @@
+ # -*- coding: UTF-8 -*-
+ """
+-Contains classes and functionality to provide a skip-if logic based on tags
+-in feature files.
++Contains classes and functionality to provide the active-tag mechanism.
++Active-tags provide a skip-if logic based on tags in feature files.
+ """
+ 
+ from __future__ import absolute_import
+@@ -10,6 +10,11 @@ import operator
+ import six
+ 
+ 
++def bool_to_string(value):
++    """Converts a Boolean value into its normalized string representation."""
++    return str(bool(value)).lower()
++
++
+ class TagMatcher(object):
+     """Abstract base class that defines the TagMatcher protocol."""
+ 
+@@ -36,12 +41,13 @@ class TagMatcher(object):
+ class ActiveTagMatcher(TagMatcher):
+     """Provides an active tag matcher for many categories.
+ 
+-    TAG SCHEMA:
++    TAG SCHEMA 1 (preferred):
+       * use.with_{category}={value}
+       * not.with_{category}={value}
++
++    TAG SCHEMA 2:
+       * active.with_{category}={value}
+       * not_active.with_{category}={value}
+-      * only.with_{category}={value}        (NOTE: For backward compatibility)
+ 
+     TAG LOGIC
+     ----------
+@@ -52,7 +58,7 @@ class ActiveTagMatcher(TagMatcher):
+         active_group.enabled := enabled(group.tag1) or enabled(group.tag2) or ...
+         active_tags.enabled  := enabled(group1) and enabled(group2) and ...
+ 
+-    All active-tag groups must be turned "on".
++    All active-tag groups must be turned "on" (enabled).
+     Otherwise, the model element should be excluded.
+ 
+     CONCEPT: ValueProvider
+@@ -81,12 +87,12 @@ class ActiveTagMatcher(TagMatcher):
+         # -- FILE: features/alice.feature
+         Feature:
+ 
+-          @active.with_os=win32
++          @use.with_os=win32
+           Scenario: Alice (Run only on Windows)
+             Given I do something
+             ...
+ 
+-          @not_active.with_browser=chrome
++          @not.with_browser=chrome
+           Scenario: Bob (Excluded with Web-Browser Chrome)
+             Given I do something else
+             ...
+@@ -116,7 +122,7 @@ class ActiveTagMatcher(TagMatcher):
+                 scenario.skip(exclude_reason)   #< LATE-EXCLUDE from run-set.
+     """
+     value_separator = "="
+-    tag_prefixes = ["active", "not_active", "use", "not", "only"]
++    tag_prefixes = ["use", "not", "active", "not_active", "only"]
+     tag_schema = r"^(?P<prefix>%s)\.with_(?P<category>\w+(\.\w+)*)%s(?P<value>.*)$"
+     ignore_unknown_categories = True
+     use_exclude_reason = False
+@@ -163,21 +169,49 @@ class ActiveTagMatcher(TagMatcher):
+ 
+     def is_tag_group_enabled(self, group_category, group_tag_pairs):
+         """Provides boolean logic to determine if all active-tags
+-        which use the same category result in a enabled value.
+-
+-        Use LOGICAL-OR expression for active-tags with same category::
+-
+-            category_tag_group.enabled := enabled(tag1) or enabled(tag2) or ...
++        which use the same category result in an enabled value.
+ 
+         .. code-block:: gherkin
+ 
+             @use.with_xxx=alice
+             @use.with_xxx=bob
+             @not.with_xxx=charly
++            @not.with_xxx=doro
+             Scenario:
+                 Given a step passes
+                 ...
+ 
++        Use LOGICAL expression for active-tags with same category::
++
++            category_tag_group.enabled := positive-tag-expression and not negative-tag-expression
++              positive-tag-expression  := enabled(tag1) or enabled(tag2) or ...
++              negative-tag-expression  := enabled(tag3) or enabled(tag4) or ...
++               tag1, tag2 are positive-tags, like @use.with_category=value
++               tag3, tag4 are negative-tags, like @not.with_category=value
++
++             xxx   | Only use parts: (xxx == "alice") or (xxx == "bob")
++            -------+-------------------
++            alice  | true
++            bob    | true
++            other  | false
++
++             xxx   | Only not parts:
++                   | (not xxx == "charly") and (not xxx == "doro")
++                   | = not((xxx == "charly") or (xxx == "doro"))
++            -------+-------------------
++            charly | false
++            doro   | false
++            other  | true
++
++             xxx   | Use and not parts:
++                   | ((xxx == "alice") or (xxx == "bob")) and not((xxx == "charly") or (xxx == "doro"))
++            -------+-------------------
++            alice  | true
++            bob    | true
++            charly | false
++            doro   | false
++            other  | false
++
+         :param group_category:      Category for this tag-group (as string).
+         :param category_tag_group:  List of active-tag match-pairs.
+         :return: True, if tag-group is enabled.
+@@ -191,20 +225,28 @@ class ActiveTagMatcher(TagMatcher):
+             # -- CASE: Unknown category, ignore it.
+             return True
+ 
+-        tags_enabled = []
++        positive_tags_matched = []
++        negative_tags_matched = []
+         for category_tag, tag_match in group_tag_pairs:
+             tag_prefix = tag_match.group("prefix")
+             category = tag_match.group("category")
+             tag_value = tag_match.group("value")
+             assert category == group_category
+ 
+-            is_category_tag_switched_on = operator.eq       # equal_to
+             if self.is_tag_negated(tag_prefix):
+-                is_category_tag_switched_on = operator.ne   # not_equal_to
+-
+-            tag_enabled = is_category_tag_switched_on(tag_value, current_value)
+-            tags_enabled.append(tag_enabled)
+-        return any(tags_enabled)    # -- PROVIDES: LOGICAL-OR expression
++                # -- CASE: @not.with_CATEGORY=VALUE
++                tag_matched = (tag_value == current_value)
++                negative_tags_matched.append(tag_matched)
++            else:
++                # -- CASE: @use.with_CATEGORY=VALUE
++                tag_matched = (tag_value == current_value)
++                positive_tags_matched.append(tag_matched)
++        tag_expression1 = any(positive_tags_matched)    #< LOGICAL-OR expression
++        tag_expression2 = any(negative_tags_matched)    #< LOGICAL-OR expression
++        if not positive_tags_matched:
++            tag_expression1 = True
++        tag_group_enabled = bool(tag_expression1 and not tag_expression2)
++        return tag_group_enabled
+ 
+     def should_exclude_with(self, tags):
+         group_categories = self.group_active_tags_by_category(tags)
+diff --git a/features/tags.active_tags.feature b/features/tags.active_tags.feature
+index 4ab55c2..6adcb60 100644
+--- a/features/tags.active_tags.feature
++++ b/features/tags.active_tags.feature
+@@ -240,9 +240,25 @@ Feature: Active Tags
+         | tags                                      | enabled? | Comment |
+         | @use.with_foo=xxx   @use.with_foo=other   |  yes     | Enabled: tag1 |
+         | @use.with_foo=xxx   @not.with_foo=other   |  yes     | Enabled: tag1, tag2|
+-        | @use.with_foo=xxx   @not.with_foo=xxx     |  yes     | Enabled: tag1 (BAD-SPEC) |
+-        | @use.with_foo=other @not.with_foo=xxx     |  no      | Enabled: none |
+-        | @not.with_foo=other @not.with_foo=xxx     |  yes     | Enabled: tag1 |
++        | @use.with_foo=other @not.with_foo=xxx     |  no      | Disabled: none |
++        | @not.with_foo=other @not.with_foo=xxx     |  no      | Disabled: tag1 |
++        | @use.with_foo=xxx   @not.with_foo=xxx     |  no      | Disabled: tag1 (BAD-SPEC, CONFLICTS) |
++
++
++  Scenario: Tag logic with three active tags of same category
++      Given I setup the current values for active tags with:
++        | category | value |
++        | foo      | xxx   |
++      Then the following active tag combinations are enabled:
++        | tags                                                        | enabled? | Comment |
++        | @use.with_foo=xxx  @use.with_foo=other @use.with_foo=other2|  yes     | Enabled: tag1  |
++        | @use.with_foo=xxx  @use.with_foo=other @not.with_foo=other2|  yes     | Enabled: tag1  |
++        | @use.with_foo=xxx  @not.with_foo=other @use.with_foo=other2|  yes     | Enabled: tag1  |
++        | @use.with_foo=xxx  @not.with_foo=other @not.with_foo=other2|  yes     | Enabled: tag1  |
++        | @not.with_foo=xxx  @use.with_foo=other @use.with_foo=other2|  no      | Disabled: tag1 |
++        | @not.with_foo=xxx  @use.with_foo=other @not.with_foo=other2|  no      | Disabled: tag1 |
++        | @not.with_foo=xxx  @not.with_foo=other @use.with_foo=other2|  no      | Disabled: tag1 |
++        | @not.with_foo=xxx  @not.with_foo=other @not.with_foo=other2|  no      | Disabled: tag1 |
+ 
+ 
+     Scenario: Tag logic with unknown categories (case: ignored)
+diff --git a/tests/functional/test_active_tags.py b/tests/functional/test_active_tags.py
+new file mode 100644
+index 0000000..fd6138f
+--- /dev/null
++++ b/tests/functional/test_active_tags.py
+@@ -0,0 +1,529 @@
++# -*- coding: utf-8 -*-
++"""
++Functionals tests for active tag-matcher (mod:`behave.tag_matcher`).
++"""
++
++from __future__ import absolute_import, print_function
++import pytest
++from behave.tag_matcher import ActiveTagMatcher
++
++# =============================================================================
++# TEST DATA:
++# =============================================================================
++# VALUE_PROVIDER = {
++#     "foo": "alice",
++#     "bar": "BOB",
++# }
++
++# =============================================================================
++# PYTEST FIXTURES:
++# =============================================================================
++# @pytest.fixture
++# def active_tag_matcher():
++#     tag_matcher = ActiveTagMatcher(VALUE_PROVIDER)
++#     return tag_matcher
++
++
++# =============================================================================
++# TEST SUITE:
++# =============================================================================
++class TestActivateTags(object):
++    VALUE_PROVIDER = {
++        "foo": "Frank",
++        "bar": "Bob",
++        # "OTHER": "VALUE",
++    }
++
++    def check_should_run_with_active_tags(self, case, expected, tags):
++        # -- tag_matcher.should_run_with(tags).result := expected
++        case += " (tags: {tags})"
++        tag_matcher = ActiveTagMatcher(self.VALUE_PROVIDER)
++        actual_result1 = tag_matcher.should_run_with(tags)
++        actual_result2 = tag_matcher.should_exclude_with(tags)
++        assert expected == actual_result1, case.format(tags=tags)
++        assert (not expected) == actual_result2
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("use.with_foo=VALUE matches",     True, ["use.with_foo=Frank"]),
++        ("use.with_foo=VALUE mismatches", False, ["use.with_foo=OTHER"]),
++        ("not.with_foo=VALUE matches",    False, ["not.with_foo=Frank"]),
++        ("not.with_foo=VALUE mismatches",  True, ["not.with_foo=OTHER"]),
++        ("NO_TAGS", True, []),
++    ])
++    def test_one_tag_for_category1(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("use.with_bar=Bob matches",       True, ["use.with_bar=Bob"]),
++        ("use.with_bar=VALUE mismatches", False, ["use.with_bar=OTHER"]),
++        ("not.with_bar=VALUE matches",    False, ["not.with_bar=Bob"]),
++        ("not.with_bar=VALUE mismatches",  True, ["not.with_bar=OTHER"]),
++    ])
++    def test_one_tag_for_category2(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    # @pytest.mark.parametrize("case, expected, tags", [
++    #     ("use.with_OTHER=VALUE matches",     True, ["use.with_OTHER=VALUE"]),
++    #     ("use.with_OTHER=VALUE mismatches", False, ["use.with_OTHER=OTHER"]),
++    #     ("not.with_OTHER=VALUE matches",    False, ["not.with_OTHER=VALUE"]),
++    #     ("not.with_OTHER=VALUE mismatches",  True, ["not.with_OTHER=OTHER"]),
++    # ])
++    # def test_one_tag_for_other_category(self, case, expected, tags):
++    #     self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("2x use.with_foo=VALUE: one matches", True,
++         ["use.with_foo=Frank", "use.with_foo=OTHER"]),
++        ("2x not.with_foo=VALUE: one matches", False,
++         ["not.with_foo=Frank", "not.with_foo=OTHER"]),
++        ("1x use./not.with_foo=VALUE: use-matches", True,
++         ["use.with_foo=Frank", "not.with_foo=OTHER"]),
++        ("1x use./not.with_foo=VALUE: not-matches", False,
++         ["not.with_foo=Frank", "use.with_foo=OTHER"]),
++    ])
++    def test_one_category_with_two_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("3x use.with_foo=VALUE: one matches", True,
++         ["use.with_foo=Frank", "use.with_foo=OTHER_1", "use.with_foo=OTHER_2"]),
++        ("3x not.with_foo=VALUE: one matches", False,
++         ["not.with_foo=Frank", "not.with_foo=OTHER_1", "not.with_foo=OTHER_2"]),
++        ("2x use.with_foo=VALUE: use-matches", True,
++         ["use.with_foo=Frank", "use.with_foo=OTHER_1", "not.with_foo=OTHER_2"]),
++        ("2x not.with_foo=VALUE: not-matches", False,
++         ["not.with_foo=Frank", "not.with_foo=OTHER_1", "use.with_foo=OTHER_2"]),
++        ("1x use.with_foo=VALUE: use-matches", True,
++         ["use.with_foo=Frank", "not.with_foo=OTHER_1", "not.with_foo=OTHER_2"]),
++        ("1x not.with_foo=VALUE: not-matches", False,
++         ["not.with_foo=Frank", "use.with_foo=OTHER_1", "use.with_foo=OTHER_2"]),
++    ])
++    def test_one_category_with_three_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- use.with_CATEGORY=VALUE
++        ("use.with_... 2x matches",      True, ["use.with_foo=Frank", "use.with_bar=Bob"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=Frank", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_bar=Bob"]),
++        ("use.with_... 0x matches",     False, ["use.with_foo=OTHER", "use.with_bar=OTHER"]),
++        # -- not.with_CATEGORY=VALUE
++        ("not.with_... 2x matches", False, ["not.with_foo=Frank", "not.with_bar=Bob"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=Frank", "not.with_bar=OTHER"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("not.with_... 0x matches",  True, ["not.with_foo=OTHER", "not.with_bar=OTHER"]),
++        # -- use.with_CATEGORY_1=VALUE_1, not.with_CATEGORY_2=VALUE_2
++        ("use./not.with_... use-matches",  True, ["use.with_foo=Frank", "not.with_bar=OTHER"]),
++        ("use./not.with_... not-matches", False, ["use.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("use./not.with_... 2x matches",  False, ["use.with_foo=Frank", "not.with_bar=Bob"]),
++        ("use./not.with_... 0x matches",  False, ["use.with_foo=OTHER", "not.with_bar=OTHER"]),
++    ])
++    def test_two_categories_with_two_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- use.with_CATEGORY=VALUE
++        ("use.with_... 2x matches",      True, ["use.with_foo=Frank", "use.with_foo=OTHER", "use.with_bar=Bob"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=Frank", "use.with_foo=OTHER", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_foo=Frank", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_foo=OTHER2", "use.with_bar=Bob"]),
++        ("use.with_... 0x matches",     False, ["use.with_foo=OTHER", "use.with_bar=OTHER2", "use.with_bar=OTHER"]),
++        # -- not.with_CATEGORY=VALUE
++        ("not.with_... 2x matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "not.with_bar=OTHER"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "not.with_bar=Bob"]),
++        ("not.with_... 0x matches",  True, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "not.with_bar=OTHER"]),
++        # -- use.with_CATEGORY_1=VALUE_1, not.with_CATEGORY_2=VALUE_2
++        ("use./not.with_... use-matches",  True, ["use.with_foo=Frank", "use.with_foo=OTHER", "not.with_bar=OTHER"]),
++        ("use./not.with_... not-matches", False, ["use.with_foo=OTHER", "use.with_foo=OTHER2", "not.with_bar=Bob"]),
++        ("use./not.with_... 2x matches",  False, ["use.with_foo=Frank", "use.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("use./not.with_... 0x matches",  False, ["use.with_foo=OTHER", "use.with_foo=OTHER2", "not.with_bar=OTHER"]),
++        # -- not.with_CATEGORY_1=VALUE_1, use.with_CATEGORY_2=VALUE_2
++        ("use./not.with_... not-matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "use.with_bar=OTHER"]),
++        ("use./not.with_... use-matches", True, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "use.with_bar=Bob"]),
++        ("use./not.with_... 2x matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "use.with_bar=Bob"]),
++        ("use./not.with_... 0x matches", False, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "use.with_bar=OTHER"]),
++    ])
++    def test_two_categories_with_three_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++'''
++class Traits4ActiveTagMatcher(object):
++    TagMatcher = ActiveTagMatcher
++    value_provider = {
++        "foo": "alice",
++        "bar": "BOB",
++    }
++
++    category1_enabled_tag = TagMatcher.make_category_tag("foo", "alice")
++    category1_disabled_tag = TagMatcher.make_category_tag("foo", "bob")
++    category1_disabled_tag2 = TagMatcher.make_category_tag("foo", "charly")
++    category1_similar_tag = TagMatcher.make_category_tag("foo", "alice2")
++    category2_enabled_tag = TagMatcher.make_category_tag("bar", "BOB")
++    category2_disabled_tag = TagMatcher.make_category_tag("bar", "CHARLY")
++    category2_similar_tag = TagMatcher.make_category_tag("bar", "BOB2")
++    unknown_category_tag = TagMatcher.make_category_tag("UNKNOWN", "one")
++
++    # -- NEGATED TAGS:
++    category1_not_enabled_tag = \
++        TagMatcher.make_category_tag("foo", "alice", "not_active")
++    category1_not_enabled_tag2 = \
++        TagMatcher.make_category_tag("foo", "alice", "not")
++    category1_not_disabled_tag = \
++        TagMatcher.make_category_tag("foo", "bob", "not_active")
++    category1_negated_similar_tag1 = \
++        TagMatcher.make_category_tag("foo", "alice2", "not_active")
++
++
++    active_tags1 = [
++        category1_enabled_tag, category1_disabled_tag, category1_similar_tag,
++        category1_not_enabled_tag, category1_not_enabled_tag2,
++    ]
++    active_tags2 = [
++        category2_enabled_tag, category2_disabled_tag, category2_similar_tag,
++    ]
++    active_tags = active_tags1 + active_tags2
++
++
++# -- REQUIRES: pytest
++class TestActiveTagMatcher2(object):
++    TagMatcher = ActiveTagMatcher
++    traits = Traits4ActiveTagMatcher
++
++    @classmethod
++    def make_tag_matcher(cls):
++        value_provider = {
++            "foo": "alice",
++            "bar": "BOB",
++        }
++        tag_matcher = cls.TagMatcher(value_provider)
++        return tag_matcher
++
++    @pytest.mark.parametrize("case, expected_len, tags", [
++        ("case: Two enabled tags", 2,
++         [traits.category1_enabled_tag, traits.category2_enabled_tag]),
++        ("case: Active enabled and normal tag", 1,
++         [traits.category1_enabled_tag,  "foo"]),
++        ("case: Active disabled and normal tag", 1,
++         [traits.category1_disabled_tag, "foo"]),
++        ("case: Normal and active negated tag", 1,
++         ["foo", traits.category1_not_enabled_tag]),
++        ("case: Two normal tags", 0,
++         ["foo", "bar"]),
++    ])
++    def test_select_active_tags__with_two_tags(self, case, expected_len, tags):
++        tag_matcher = self.make_tag_matcher()
++        selected = tag_matcher.select_active_tags(tags)
++        selected = list(selected)
++        assert len(selected) == expected_len, case
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- GROUP: With positive logic (non-negated tags)
++        ("case P00: 2 disabled tags", True,
++         [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
++        ("case P01: disabled and enabled tag", True,
++         [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
++        ("case P10: enabled and disabled tag", True,
++         [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
++        ("case P11: 2 enabled tags", False,  # -- SHOULD-RUN
++         [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
++        # -- GROUP: With negated tag
++        ("case N00: not-enabled and disabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category2_disabled_tag]),
++        ("case N01: not-enabled and enabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category2_enabled_tag]),
++        ("case N10: not-disabled and disabled tag", True,
++         [ traits.category1_not_disabled_tag, traits.category2_disabled_tag]),
++        ("case N11: not-disabled and enabled tag", False, # -- SHOULD-RUN
++         [ traits.category1_not_disabled_tag, traits.category2_enabled_tag]),
++        # -- GROUP: With unknown category
++        ("case U0x: disabled and unknown tag", True,
++         [ traits.category1_disabled_tag, traits.unknown_category_tag]),
++        ("case U1x: enabled and unknown tag", False,  # -- SHOULD-RUN
++         [ traits.category1_enabled_tag, traits.unknown_category_tag]),
++    ])
++    def test_should_exclude_with__combinations_of_2_categories(self, case, expected, tags):
++        tag_matcher = self.make_tag_matcher()
++        actual_result = tag_matcher.should_exclude_with(tags)
++        assert expected == actual_result, case
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- GROUP: With positive logic (non-negated tags)
++        ("case P00: 2 disabled tags", True,
++         [ traits.category1_disabled_tag, traits.category1_disabled_tag2]),
++        ("case P01: disabled and enabled tag", False,
++         [ traits.category1_disabled_tag, traits.category1_enabled_tag]),
++        ("case P10: enabled and disabled tag", False,
++         [ traits.category1_enabled_tag, traits.category1_disabled_tag]),
++        ("case P11: 2 enabled tags (same)", False,  # -- SHOULD-RUN
++         [ traits.category1_enabled_tag, traits.category1_enabled_tag]),
++        # -- GROUP: With negated tag
++        ("case N00: not-enabled and disabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category1_disabled_tag]),
++        ("case N01: not-enabled and enabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category1_enabled_tag]),
++        ("case N10: not-disabled and disabled tag", True,
++         [ traits.category1_not_disabled_tag, traits.category1_disabled_tag]),
++        ("case N11: not-disabled and enabled tag", False, # -- SHOULD-RUN
++         [ traits.category1_not_disabled_tag, traits.category1_enabled_tag]),
++    ])
++    def test_should_exclude_with__combinations_with_same_category(self,
++                                                        case, expected, tags):
++        tag_matcher = self.make_tag_matcher()
++        print("tags: {}".format(tags) )
++        print("tag_matcher.value: {}".format(tag_matcher.value_provider) )
++        actual_result = tag_matcher.should_exclude_with(tags)
++        assert expected == actual_result, case
++
++
++class TestActiveTags(TestCase):
++    TagMatcher = ActiveTagMatcher
++    traits = Traits4ActiveTagMatcher
++
++    @classmethod
++    def make_tag_matcher(cls):
++        tag_matcher = cls.TagMatcher(cls.traits.value_provider)
++        return tag_matcher
++
++    def setUp(self):
++        self.tag_matcher = self.make_tag_matcher()
++
++    def test_select_active_tags__basics(self):
++        active_tag = "active.with_CATEGORY=VALUE"
++        tags = ["foo", active_tag, "bar"]
++        selected = list(self.tag_matcher.select_active_tags(tags))
++        self.assertEqual(len(selected), 1)
++        selected_tag, selected_match = selected[0]
++        self.assertEqual(selected_tag, active_tag)
++
++    def test_select_active_tags__matches_tag_parts(self):
++        tags = ["active.with_CATEGORY=VALUE"]
++        selected = list(self.tag_matcher.select_active_tags(tags))
++        self.assertEqual(len(selected), 1)
++        selected_tag, selected_match = selected[0]
++        self.assertEqual(selected_match.group("prefix"), "active")
++        self.assertEqual(selected_match.group("category"), "CATEGORY")
++        self.assertEqual(selected_match.group("value"), "VALUE")
++
++    def test_select_active_tags__finds_tag_with_any_valid_tag_prefix(self):
++        TagMatcher = self.TagMatcher
++        for tag_prefix in TagMatcher.tag_prefixes:
++            tag = TagMatcher.make_category_tag("foo", "alice", tag_prefix)
++            tags = [ tag ]
++            selected = self.tag_matcher.select_active_tags(tags)
++            selected = list(selected)
++            self.assertEqual(len(selected), 1)
++            selected_tag0 = selected[0][0]
++            self.assertEqual(selected_tag0, tag)
++            self.assertTrue(selected_tag0.startswith(tag_prefix))
++
++    def test_select_active_tags__ignores_invalid_active_tags(self):
++        invalid_active_tags = [
++            ("foo.alice",               "case: Normal tag"),
++            ("with_foo=Frank",          "case: Subset of an active tag"),
++            ("ACTIVE.with_foo.alice",   "case: Wrong tag_prefix (uppercase)"),
++            ("only.with_foo.alice",     "case: Wrong value_separator"),
++        ]
++        for invalid_tag, case in invalid_active_tags:
++            tags = [ invalid_tag ]
++            selected = self.tag_matcher.select_active_tags(tags)
++            selected = list(selected)
++            self.assertEqual(len(selected), 0, case)
++
++    def test_select_active_tags__with_two_tags(self):
++        # XXX-JE-DUPLICATED:
++        traits = self.traits
++        test_patterns = [
++            ("case: Two enabled tags",
++             [traits.category1_enabled_tag, traits.category2_enabled_tag]),
++            ("case: Active enabled and normal tag",
++             [traits.category1_enabled_tag,  "foo"]),
++            ("case: Active disabled and normal tag",
++             [traits.category1_disabled_tag, "foo"]),
++            ("case: Active negated and normal tag",
++             [traits.category1_not_enabled_tag, "foo"]),
++        ]
++        for case, tags in test_patterns:
++            selected = self.tag_matcher.select_active_tags(tags)
++            selected = list(selected)
++            self.assertTrue(len(selected) >= 1, case)
++
++
++    def test_should_exclude_with__returns_false_with_enabled_tag(self):
++        traits = self.traits
++        tags1 = [ traits.category1_enabled_tag ]
++        tags2 = [ traits.category2_enabled_tag ]
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags1))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags2))
++
++    def test_should_exclude_with__returns_false_with_disabled_tag_and_more(self):
++        # -- NOTE: Need 1+ enabled active-tags of same category => ENABLED
++        # pylint: disable=line-too-long
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
++            ([ traits.category1_disabled_tag, traits.category1_enabled_tag ], "case: last"),
++            ([ "foo", traits.category1_enabled_tag, traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        enabled = True  # EXPECTED
++        for tags, case in test_patterns:
++            self.assertEqual(not enabled, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_disabled_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_disabled_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_disabled_tag ], "case: last"),
++            ([ "foo", traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_similar_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_similar_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_similar_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_similar_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_similar_tag ], "case: last"),
++            ([ "foo", traits.category1_similar_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_without_category_tag(self):
++        test_patterns = [
++            ([ ],           "case: No tags"),
++            ([ "foo" ],     "case: One tag"),
++            ([ "foo", "bar" ], "case: Two tags"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_with_unknown_category_tag(self):
++        """Tags from unknown categories, not supported by value_provider,
++        should not be excluded.
++        """
++        traits = self.traits
++        tags = [ traits.unknown_category_tag ]
++        self.assertEqual("use.with_UNKNOWN=one", traits.unknown_category_tag)
++        self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__combinations_of_2_categories(self):
++        # XXX-JE-DUPLICATED:
++        traits = self.traits
++        test_patterns = [
++            ("case P00: 2 disabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
++            ("case P01: disabled and enabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
++            ("case P10: enabled and disabled category tags", True,
++             [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
++            ("case P11: 2 enabled category tags", False,  # -- SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
++            # -- SPECIAL CASE: With negated category
++            ("case N00: not-enabled and disabled category tags", True,
++             [ traits.category1_not_enabled_tag, traits.category2_disabled_tag]),
++            ("case N01: not-enabled and enabled category tags", True,
++             [ traits.category1_not_enabled_tag, traits.category2_enabled_tag]),
++            ("case N10: not-disabled and disabled category tags", True,
++             [ traits.category1_not_disabled_tag, traits.category2_disabled_tag]),
++            ("case N11: not-enabled and enabled category tags", False,  # -- SHOULD-RUN
++             [ traits.category1_not_disabled_tag, traits.category2_enabled_tag]),
++            # -- SPECIAL CASE: With unknown category
++            ("case 0x: disabled and unknown category tags", True,
++             [ traits.category1_disabled_tag, traits.unknown_category_tag]),
++            ("case 1x: enabled and unknown category tags", False,  # SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.unknown_category_tag]),
++        ]
++        for case, expected, tags in test_patterns:
++            actual_result = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(expected, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_run_with__negates_result_of_should_exclude_with(self):
++        traits = self.traits
++        test_patterns = [
++            ([ ],                   "case: No tags"),
++            ([ "foo" ],             "case: One non-category tag"),
++            ([ "foo", "bar" ],      "case: Two non-category tags"),
++            ([ traits.category1_enabled_tag ],   "case: enabled tag"),
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ],  "case: enabled and other tag"),
++            ([ traits.category1_enabled_tag, "foo" ],    "case: enabled and foo tag"),
++            ([ traits.category1_disabled_tag ],            "case: other tag"),
++            ([ traits.category1_disabled_tag, "foo" ],     "case: other and foo tag"),
++            ([ traits.category1_similar_tag ],          "case: similar tag"),
++            ([ "foo", traits.category1_similar_tag ],   "case: foo and similar tag"),
++        ]
++        for tags, case in test_patterns:
++            result1 = self.tag_matcher.should_run_with(tags)
++            result2 = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
++            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
++
++
++class TestCompositeTagMatcher(TestCase):
++
++    @staticmethod
++    def count_tag_matcher_with_result(tag_matchers, tags, result_value):
++        count = 0
++        for tag_matcher in tag_matchers:
++            current_result = tag_matcher.should_exclude_with(tags)
++            if current_result == result_value:
++                count += 1
++        return count
++
++    def setUp(self):
++        predicate_false = lambda tags: False
++        predicate_contains_foo = lambda tags: any(x == "foo" for x in tags)
++        self.tag_matcher_false = PredicateTagMatcher(predicate_false)
++        self.tag_matcher_foo = PredicateTagMatcher(predicate_contains_foo)
++        tag_matchers = [
++            self.tag_matcher_foo,
++            self.tag_matcher_false
++        ]
++        self.ctag_matcher = CompositeTagMatcher(tag_matchers)
++
++    def test_should_exclude_with__returns_true_when_any_tag_matcher_returns_true(self):
++        test_patterns = [
++            ("case: with foo",  ["foo", "bar"]),
++            ("case: with foo2", ["foozy", "foo", "bar"]),
++        ]
++        for case, tags in test_patterns:
++            actual_result = self.ctag_matcher.should_exclude_with(tags)
++            self.assertEqual(True, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++            actual_true_count = self.count_tag_matcher_with_result(
++                                self.ctag_matcher.tag_matchers, tags, True)
++            self.assertEqual(1, actual_true_count)
++
++    def test_should_exclude_with__returns_false_when_no_tag_matcher_return_true(self):
++        test_patterns = [
++            ("case: without foo",   ["fool", "bar"]),
++            ("case: without foo2",  ["foozy", "bar"]),
++        ]
++        for case, tags in test_patterns:
++            actual_result = self.ctag_matcher.should_exclude_with(tags)
++            self.assertEqual(False, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++            actual_true_count = self.count_tag_matcher_with_result(
++                                    self.ctag_matcher.tag_matchers, tags, True)
++            self.assertEqual(0, actual_true_count)
++'''
++
+diff --git a/tests/unit/test_tag_matcher.py b/tests/unit/test_tag_matcher.py
+index a04c1d4..43f5af0 100644
+--- a/tests/unit/test_tag_matcher.py
++++ b/tests/unit/test_tag_matcher.py
+@@ -128,9 +128,9 @@ class TestActiveTagMatcher2(object):
+         # -- GROUP: With negated tag
+         ("case N00: not-enabled and disabled tag", True,
+          [ traits.category1_not_enabled_tag, traits.category1_disabled_tag]),
+-        ("case N01: not-enabled and enabled tag", False,
++        ("case N01: not-enabled and enabled tag", True,
+          [ traits.category1_not_enabled_tag, traits.category1_enabled_tag]),
+-        ("case N10: not-disabled and disabled tag", False,
++        ("case N10: not-disabled and disabled tag", True,
+          [ traits.category1_not_disabled_tag, traits.category1_disabled_tag]),
+         ("case N11: not-disabled and enabled tag", False, # -- SHOULD-RUN
+          [ traits.category1_not_disabled_tag, traits.category1_enabled_tag]),
+@@ -138,6 +138,8 @@ class TestActiveTagMatcher2(object):
+     def test_should_exclude_with__combinations_with_same_category(self,
+                                                         case, expected, tags):
+         tag_matcher = self.make_tag_matcher()
++        print("tags: {}".format(tags) )
++        print("tag_matcher.value: {}".format(tag_matcher.value_provider) )
+         actual_result = tag_matcher.should_exclude_with(tags)
+         assert expected == actual_result, case
+ 
+@@ -224,6 +226,7 @@ class TestActiveTagMatcher1(TestCase):
+ 
+     def test_should_exclude_with__returns_false_with_disabled_tag_and_more(self):
+         # -- NOTE: Need 1+ enabled active-tags of same category => ENABLED
++        # pylint: disable=line-too-long
+         traits = self.traits
+         test_patterns = [
+             ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
+@@ -283,7 +286,7 @@ class TestActiveTagMatcher1(TestCase):
+         """
+         traits = self.traits
+         tags = [ traits.unknown_category_tag ]
+-        self.assertEqual("active.with_UNKNOWN=one", traits.unknown_category_tag)
++        self.assertEqual("use.with_UNKNOWN=one", traits.unknown_category_tag)
+         self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
+         self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
+ 
+@@ -376,42 +379,6 @@ class TestPredicateTagMatcher(TestCase):
+         self.assertEqual(False, predicate_always_false(tags))
+ 
+ 
+-class TestPredicateTagMatcher(TestCase):
+-
+-    def test_exclude_with__mechanics(self):
+-        predicate_function_blueprint = lambda tags: False
+-        predicate_function = Mock(predicate_function_blueprint)
+-        predicate_function.return_value = True
+-        tag_matcher = PredicateTagMatcher(predicate_function)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(True, tag_matcher.should_exclude_with(tags))
+-        predicate_function.assert_called_once_with(tags)
+-        self.assertEqual(True, predicate_function(tags))
+-
+-    def test_should_exclude_with__returns_true_when_predicate_is_true(self):
+-        predicate_always_true = lambda tags: True
+-        tag_matcher1 = PredicateTagMatcher(predicate_always_true)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(True, tag_matcher1.should_exclude_with(tags))
+-        self.assertEqual(True, predicate_always_true(tags))
+-
+-    def test_should_exclude_with__returns_true_when_predicate_is_true2(self):
+-        # -- CASE: Use predicate function instead of lambda.
+-        def predicate_contains_foo(tags):
+-            return any(x == "foo" for x in tags)
+-        tag_matcher2 = PredicateTagMatcher(predicate_contains_foo)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(True, tag_matcher2.should_exclude_with(tags))
+-        self.assertEqual(True, predicate_contains_foo(tags))
+-
+-    def test_should_exclude_with__returns_false_when_predicate_is_false(self):
+-        predicate_always_false = lambda tags: False
+-        tag_matcher1 = PredicateTagMatcher(predicate_always_false)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(False, tag_matcher1.should_exclude_with(tags))
+-        self.assertEqual(False, predicate_always_false(tags))
+-
+-
+ class TestCompositeTagMatcher(TestCase):
+ 
+     @staticmethod
diff --git a/meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch b/meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch
new file mode 100644
index 000000000..35e26b0bd
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch
@@ -0,0 +1,56 @@
+From 63e15e8f89e0e9144bda18df3e08e96e8c9bfe50 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 22:09:59 +0100
+Subject: [PATCH] FIX: Tests w/ more.features/
+
+---
+ py.requirements/ci.tox.txt    | 2 ++
+ py.requirements/ci.travis.txt | 2 ++
+ tox.ini                       | 4 ++--
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 5bee524..387e905 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -13,3 +13,5 @@ PyHamcrest <  2.0;   python_version <  '3.0'
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
++
++jsonschema
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 372116a..cbc60c0 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -16,6 +16,8 @@ PyHamcrest <  2.0;   python_version <  '3.0'
+ path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
+ 
++jsonschema
++
+ # -- NOTE: Travis.CI tweak related w/ invalid linecache2 tests.
+ #    This problem does not exist if you use pip.
+ linecache2 >= 1.0; python_version < '3.0'
+diff --git a/tox.ini b/tox.ini
+index 8ccb58b..c145b51 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -6,7 +6,7 @@
+ #   Use tox to run tasks (tests, ...) in a clean virtual environment.
+ #   Afterwards you can run tox in offline mode, like:
+ #
+-#       tox -e py27
++#       tox -e py38
+ #
+ #   Tox can be configured for offline usage.
+ #   Initialize local workspace once (download packages, create PyPI index):
+@@ -28,7 +28,7 @@
+ 
+ [tox]
+ minversion   = 2.3
+-envlist      = py27, py37, py38, py36, py35, pypy, docs
++envlist      = py39, py38, py27, py37, py36, py35, pypy3, pypy, docs
+ skip_missing_interpreters = True
+ sitepackages = False
+ indexserver =
diff --git a/meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch b/meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch
new file mode 100644
index 000000000..5d560ad3d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch
@@ -0,0 +1,741 @@
+From 3c207ac9ac83d3966a7a84b8782394dc603030cd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 22:11:38 +0100
+Subject: [PATCH] FIX: Some regressions with Python 3.9
+
+* async-steps: Use more stable active-tags now.
+* JUnit XML related: Adapt to XML attribute ordering changes since Python 3.8.
+* Prepare active-tags usage for Python 3.10
+* Behave jsonschema: Add some extra elements (related to: gherkin v6 Rule).
+---
+ .gitignore                                    |  1 +
+ CHANGES.rst                                   |  2 +
+ behave/python_feature.py                      | 81 +++++++++++++++++++
+ etc/json/behave.json-schema                   | 28 ++++++-
+ .../features/async_dispatch.feature           |  7 +-
+ .../async_step/features/async_run.feature     |  7 +-
+ examples/async_step/features/environment.py   | 16 ++--
+ .../features/steps/_async_steps34.py          |  4 +-
+ .../features/steps/async_dispatch_steps.py    | 13 +--
+ .../async_step/features/steps/async_steps.py  |  6 +-
+ features/environment.py                       | 12 ++-
+ features/step.async_steps.feature             | 64 ++++-----------
+ issue.features/issue0330.feature              | 18 +++--
+ issue.features/issue0446.feature              | 12 ++-
+ issue.features/issue0457.feature              | 12 ++-
+ issue.features/issue0657.feature              | 11 +--
+ more.features/environment.py                  | 10 +--
+ more.features/run_examples.feature            |  9 +--
+ 18 files changed, 195 insertions(+), 118 deletions(-)
+ create mode 100644 behave/python_feature.py
+
+diff --git a/.gitignore b/.gitignore
+index 9c5c33d..8d7c28e 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -25,3 +25,4 @@ tools/virtualenvs
+ .ropeproject
+ nosetests.xml
+ rerun.txt
++testrun*.json
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 4e20bb8..a3398d8 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -38,6 +38,8 @@ CLARIFICATION:
+ 
+ FIXED:
+ 
++* FIXED: Some tests related to python3.9
++* FIXED: active-tag logic if multiple tags with same category exists.
+ * issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+ * issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+diff --git a/behave/python_feature.py b/behave/python_feature.py
+new file mode 100644
+index 0000000..4e134de
+--- /dev/null
++++ b/behave/python_feature.py
+@@ -0,0 +1,81 @@
++# -*- coding: UTF-8 -*-
++"""
++Provides a knowledge database if some Python features are supported
++in the current python version.
++"""
++
++from __future__ import absolute_import
++import sys
++import six
++from behave.tag_matcher import bool_to_string
++
++
++# -----------------------------------------------------------------------------
++# CONSTANTS:
++# -----------------------------------------------------------------------------
++PYTHON_VERSION = sys.version_info[:2]
++
++
++# -----------------------------------------------------------------------------
++# CLASSES:
++# -----------------------------------------------------------------------------
++class PythonFeature(object):
++
++    @staticmethod
++    def has_asyncio_coroutine_decorator():
++        """Indicates if python supports ``@asyncio.coroutine`` decorator.
++
++        EXAMPLE::
++
++            import asyncio
++            @asyncio.coroutine
++            def async_waits_seconds(duration):
++                yield from asyncio.sleep(duration)
++
++        :returns: True, if this python version supports this feature.
++
++        .. since:: Python >= 3.4
++        .. deprecated:: Since Python 3.8 (use async-function instead)
++        """
++        # -- NOTE: @asyncio.coroutine is deprecated in py3.8, removed in py3.10
++        return (3, 4) <= PYTHON_VERSION < (3, 10)
++
++    @staticmethod
++    def has_async_function():
++        """Indicates if python supports async-functions / async-keyword.
++
++        EXAMPLE::
++
++            import asyncio
++            async def async_waits_seconds(duration):
++                yield from asyncio.sleep(duration)
++
++        :returns: True, if this python version supports this feature.
++        .. since:: Python >= 3.5
++        """
++        return (3, 5) <= PYTHON_VERSION
++
++    @classmethod
++    def has_coroutine(cls):
++        return cls.has_async_function() or cls.has_asyncio_coroutine_decorator()
++
++
++# -----------------------------------------------------------------------------
++# SUPPORTED: ACTIVE-TAGS
++# -----------------------------------------------------------------------------
++PYTHON_HAS_ASYNCIO_COROUTINE_DECORATOR = PythonFeature.has_asyncio_coroutine_decorator()
++PYTHON_HAS_ASYNC_FUNCTION = PythonFeature.has_async_function()
++PYTHON_HAS_COROUTINE = PythonFeature.has_coroutine()
++ACTIVE_TAG_VALUE_PROVIDER = {
++    "python2": bool_to_string(six.PY2),
++    "python3": bool_to_string(six.PY3),
++    "python.version": "%s.%s" % PYTHON_VERSION,
++    "os":      sys.platform.lower(),
++
++    # -- PYTHON FEATURE, like: @use.with_py.feature_asyncio.coroutine
++    "python_has_coroutine": bool_to_string(PYTHON_HAS_COROUTINE),
++    "python_has_asyncio.coroutine_decorator":
++        bool_to_string(PYTHON_HAS_ASYNCIO_COROUTINE_DECORATOR),
++    "python_has_async_function": bool_to_string(PYTHON_HAS_ASYNC_FUNCTION),
++    "python_has_async_keyword": bool_to_string(PYTHON_HAS_ASYNC_FUNCTION),
++}
+diff --git a/etc/json/behave.json-schema b/etc/json/behave.json-schema
+index 9cf3e62..110e240 100644
+--- a/etc/json/behave.json-schema
++++ b/etc/json/behave.json-schema
+@@ -28,10 +28,36 @@
+             "type": "object",
+             "anyOf": [
+                 { "$ref": "#/definitions/Background" },
++                { "$ref": "#/definitions/Rule" },
+                 { "$ref": "#/definitions/Scenario" },
+                 { "$ref": "#/definitions/ScenarioOutline" }
+             ]
+         },
++        "Rule": {
++            "type": "object",
++            "description": "Represents a Rule object.",
++            "properties": {
++                "name":     { "type": "string" },
++                "keyword":  { "type": "string" },
++                "location": { "type": "string" },
++                "status":   { "type": "string" },
++                "tags":     { "$ref": "#/definitions/Tags" },
++                "description": { "$ref": "#/definitions/MultiLineText" },
++                "elements": {
++                    "type": "array",
++                    "items": { "$ref": "#/definitions/RuleElement" }
++                }
++            },
++            "required": [ "name", "keyword", "location" ]
++        },
++        "RuleElement": {
++            "type": "object",
++            "anyOf": [
++                { "$ref": "#/definitions/Scenario" },
++                { "$ref": "#/definitions/ScenarioOutline" },
++                { "$ref": "#/definitions/Background" }
++            ]
++        },
+         "Background": {
+             "type": "object",
+             "properties": {
+@@ -169,4 +195,4 @@
+             "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
+         }
+     }
+-}
+\ No newline at end of file
++}
+diff --git a/examples/async_step/features/async_dispatch.feature b/examples/async_step/features/async_dispatch.feature
+index 18e9869..e0eba1e 100644
+--- a/examples/async_step/features/async_dispatch.feature
++++ b/examples/async_step/features/async_dispatch.feature
+@@ -1,8 +1,5 @@
+-@use.with_python.version=3.4
+-@use.with_python.version=3.5
+-@use.with_python.version=3.6
+-@use.with_python.version=3.7
+-@use.with_python.version=3.8
++@use.with_python_has_async_function=true
++@use.with_python_has_asyncio.coroutine_decorator=true
+ Feature:
+   Scenario:
+     Given I dispatch an async-call with param "Alice"
+diff --git a/examples/async_step/features/async_run.feature b/examples/async_step/features/async_run.feature
+index 29b8fa7..8b6e555 100644
+--- a/examples/async_step/features/async_run.feature
++++ b/examples/async_step/features/async_run.feature
+@@ -1,8 +1,5 @@
+-@use.with_python.version=3.4
+-@use.with_python.version=3.5
+-@use.with_python.version=3.6
+-@use.with_python.version=3.7
+-@use.with_python.version=3.8
++@use.with_python_has_async_function=true
++@use.with_python_has_asyncio.coroutine_decorator=true
+ Feature:
+   Scenario:
+     Given an async-step waits 0.3 seconds
+diff --git a/examples/async_step/features/environment.py b/examples/async_step/features/environment.py
+index 02c4d92..3fa9604 100644
+--- a/examples/async_step/features/environment.py
++++ b/examples/async_step/features/environment.py
+@@ -2,7 +2,8 @@
+ 
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+ from behave.api.runtime_constraint import require_min_python_version
+-import sys
++from behave import python_feature
++
+ 
+ # -----------------------------------------------------------------------------
+ # REQUIRE: python >= 3.4
+@@ -15,27 +16,24 @@ require_min_python_version("3.4")
+ # -----------------------------------------------------------------------------
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+-python_version = "%s.%s" % sys.version_info[:2]
+-active_tag_value_provider = {
+-    "python.version": python_version,
+-}
++active_tag_value_provider = python_feature.ACTIVE_TAG_VALUE_PROVIDER.copy()
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+-def before_all(context):
++def before_all(ctx):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+-    setup_active_tag_values(active_tag_value_provider, context.config.userdata)
++    setup_active_tag_values(active_tag_value_provider, ctx.config.userdata)
+ 
+ 
+-def before_feature(context, feature):
++def before_feature(ctx, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
+ 
+-def before_scenario(context, scenario):
++def before_scenario(ctx, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+ 
+diff --git a/examples/async_step/features/steps/_async_steps34.py b/examples/async_step/features/steps/_async_steps34.py
+index 556500f..fc4c8d1 100644
+--- a/examples/async_step/features/steps/_async_steps34.py
++++ b/examples/async_step/features/steps/_async_steps34.py
+@@ -1,5 +1,5 @@
+-# -- REQUIRES: Python >= 3.4 and Python < 3.8
+-# HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++# -- REQUIRES: Python >= 3.4 and Python < 3.10 (removed in: 3.10)
++# HINT: @asyncio.coroutine decorator is deprecated since python 3.8
+ # USE:  Async generator/coroutine instead.
+ 
+ from behave import step
+diff --git a/examples/async_step/features/steps/async_dispatch_steps.py b/examples/async_step/features/steps/async_dispatch_steps.py
+index 222e54d..def9616 100644
+--- a/examples/async_step/features/steps/async_dispatch_steps.py
++++ b/examples/async_step/features/steps/async_dispatch_steps.py
+@@ -1,8 +1,9 @@
+ # -*- coding: UTF-8 -*-
+ # REQUIRES: Python >= 3.4/3.5
+-import sys
++
+ from behave import given, then, step
+ from behave.api.async_step import use_or_create_async_context
++from behave.python_feature import PythonFeature
+ from hamcrest import assert_that, equal_to, empty
+ import asyncio
+ 
+@@ -10,13 +11,15 @@ import asyncio
+ # ---------------------------------------------------------------------------
+ # ASYNC EXAMPLE FUNCTION:
+ # ---------------------------------------------------------------------------
+-python_version = "%s.%s" % sys.version_info[:2]
+-if python_version >= "3.5":
++if PythonFeature.has_async_function():
++    # -- USE: async-function as coroutine-function
++    # SINCE: Python 3.5 (preferred)
+     async def async_func(param):
+         await asyncio.sleep(0.2)
+         return str(param).upper()
+-else:
+-    # -- HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++elif PythonFeature.has_asyncio_coroutine_decorator():
++    # -- USE: @asyncio.coroutine decorator
++    # SINCE: Python 3.4, deprecated since Python 3.8, removed in Python 3.10
+     @asyncio.coroutine
+     def async_func(param):
+         yield from asyncio.sleep(0.2)
+diff --git a/examples/async_step/features/steps/async_steps.py b/examples/async_step/features/steps/async_steps.py
+index dc03c72..33d2392 100644
+--- a/examples/async_step/features/steps/async_steps.py
++++ b/examples/async_step/features/steps/async_steps.py
+@@ -5,8 +5,8 @@
+ from __future__ import absolute_import
+ import sys
+ 
+-python_version = "%s.%s" % sys.version_info[:2]
+-if python_version >= "3.5":
++python_version = sys.version_info[:2]
++if python_version >= (3, 5):
+     import _async_steps35
+-elif python_version == "3.4":
++elif python_version == (3, 4):
+     import _async_steps34
+diff --git a/features/environment.py b/features/environment.py
+index 3769ee4..6faf4e2 100644
+--- a/features/environment.py
++++ b/features/environment.py
+@@ -4,22 +4,19 @@
+ from __future__ import absolute_import, print_function
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
++from behave import python_feature
+ import platform
+ import sys
+-import six
++
+ 
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+-python_version = "%s.%s" % sys.version_info[:2]
+ active_tag_value_provider = {
+-    "python2": str(six.PY2).lower(),
+-    "python3": str(six.PY3).lower(),
+-    "python.version": python_version,
+     # -- python.implementation: cpython, pypy, jython, ironpython
+     "python.implementation": platform.python_implementation().lower(),
+     "pypy":    str("__pypy__" in sys.modules).lower(),
+-    "os":      sys.platform,
+ }
++active_tag_value_provider.update(python_feature.ACTIVE_TAG_VALUE_PROVIDER)
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+@@ -27,7 +24,7 @@ def print_active_tags_summary():
+     active_tag_data = active_tag_value_provider
+     print("ACTIVE-TAG SUMMARY:")
+     print("use.with_python.version=%s" % active_tag_data.get("python.version"))
+-    # print("use.with_os=%s" % active_tag_data.get("os"))
++    print("use.with_os=%s" % active_tag_data.get("os"))
+     print()
+ 
+ 
+@@ -53,6 +50,7 @@ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ # -----------------------------------------------------------------------------
+ # SPECIFIC FUNCTIONALITY:
+ # -----------------------------------------------------------------------------
+diff --git a/features/step.async_steps.feature b/features/step.async_steps.feature
+index 06709d9..5919397 100644
+--- a/features/step.async_steps.feature
++++ b/features/step.async_steps.feature
+@@ -1,4 +1,5 @@
+ @not.with_python2=true
++@use.with_python_has_coroutine=true
+ Feature: Async-Test Support (async-step, ...)
+ 
+   As a test writer and step provider
+@@ -16,11 +17,11 @@ Feature: Async-Test Support (async-step, ...)
+   .    * an async-function as coroutine using async/await keywords (Python 3.5)
+   .    * an async-function tagged with @asyncio.coroutine and using "yield from"
+   .
+-  .  # -- EXAMPLE CASE 1 (since Python 3.5):
++  .  # -- EXAMPLE CASE 1 (since Python 3.5; preferred):
+   .  async def coroutine1(duration):
+   .      await asyncio.sleep(duration)
+   .
+-  .  # -- EXAMPLE CASE 2 (since Python 3.4):
++  .  # -- EXAMPLE CASE 2 (since Python 3.4; deprecated since Python 3.8; removed in Python 3.10):
+   .  @asyncio.coroutine
+   .  def coroutine2(duration):
+   .      yield from asyncio.sleep(duration)
+@@ -30,12 +31,8 @@ Feature: Async-Test Support (async-step, ...)
+   .   The async-step can directly interact with other async-functions.
+ 
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use async-step with @async_run_until_complete (async)
++    @use.with_python_has_async_function=true
++    Scenario: Use async-step with @async_run_until_complete (async; requires: py.version >= 3.5)
+       Given a new working directory
+       And a file named "features/steps/async_steps35.py" with:
+         """
+@@ -63,13 +60,8 @@ Feature: Async-Test Support (async-step, ...)
+         """
+ 
+ 
+-    @use.with_python.version=3.4
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use async-step with @async_run_until_complete (@coroutine)
++    @use.with_python_has_asyncio.coroutine_decorator=true
++    Scenario: Use async-step with @async_run_until_complete (@asyncio.coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps34.py" with:
+         """
+@@ -97,12 +89,8 @@ Feature: Async-Test Support (async-step, ...)
+              Given an async-step waits 0.3 seconds ... passed in 0.3
+         """
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (async)
++    @use.with_python_has_async_function=true
++    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (async-function)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout35.py" with:
+         """
+@@ -135,13 +123,9 @@ Feature: Async-Test Support (async-step, ...)
+         Assertion Failed: TIMEOUT-OCCURED: timeout=0.1
+         """
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
++    @use.with_python_has_async_function=true
+     @async_step_fails
+-    Scenario: Use @async_run_until_complete and async-step fails
++    Scenario: Use @async_run_until_complete and async-step fails (async-function)
+       Given a new working directory
+       And a file named "features/steps/async_steps_fails35.py" with:
+         """
+@@ -180,13 +164,9 @@ Feature: Async-Test Support (async-step, ...)
+         Assertion Failed: XFAIL in async-step
+         """
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
++    @use.with_python_has_async_function=true
+     @async_step_fails
+-    Scenario: Use @async_run_until_complete and async-step raises error
++    Scenario: Use @async_run_until_complete and async-step raises error (async-function)
+       Given a new working directory
+       And a file named "features/steps/async_steps_exception35.py" with:
+         """
+@@ -225,13 +205,8 @@ Feature: Async-Test Support (async-step, ...)
+         raise RuntimeError("XFAIL in async-step")
+         """
+ 
+-    @use.with_python.version=3.4
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (@coroutine)
++    @use.with_python_has_asyncio.coroutine_decorator=true
++    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (@asyncio.coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout34.py" with:
+         """
+@@ -265,13 +240,8 @@ Feature: Async-Test Support (async-step, ...)
+         Assertion Failed: TIMEOUT-OCCURED: timeout=0.2
+         """
+ 
+-    @use.with_python.version=3.4
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use async-dispatch and async-collect concepts
++    @use.with_python_has_asyncio.coroutine_decorator=true
++    Scenario: Use async-dispatch and async-collect concepts (@asyncio.coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_dispatch_steps.py" with:
+         """
+diff --git a/issue.features/issue0330.feature b/issue.features/issue0330.feature
+index be4d378..56ac238 100644
+--- a/issue.features/issue0330.feature
++++ b/issue.features/issue0330.feature
+@@ -72,7 +72,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @not.with_python.version=3.8
+   @not.with_python.version=3.9
+-  Scenario: Junit report for skipped feature is created with --show-skipped
++  @not.with_python.version=3.10
++  Scenario: Junit report for skipped feature is created with --show-skipped (py.version < 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+       """
+@@ -87,7 +88,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @use.with_python.version=3.8
+   @use.with_python.version=3.9
+-  Scenario: Junit report for skipped feature is created with --show-skipped
++  @use.with_python.version=3.10
++  Scenario: Junit report for skipped feature is created with --show-skipped (py.version >= 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+       """
+@@ -104,7 +106,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @not.with_python.version=3.8
+   @not.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
++  @not.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped (py.version < 3.8)
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+       """
+@@ -125,7 +128,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @use.with_python.version=3.8
+   @use.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
++  @use.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped (py.version >= 3.8)
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+       """
+@@ -149,7 +153,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @not.with_python.version=3.8
+   @not.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
++  @not.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped (py.version < 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+       """
+@@ -171,7 +176,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @use.with_python.version=3.8
+   @use.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
++  @use.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped (py.version >= 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+       """
+diff --git a/issue.features/issue0446.feature b/issue.features/issue0446.feature
+index 12de37a..d7db764 100644
+--- a/issue.features/issue0446.feature
++++ b/issue.features/issue0446.feature
+@@ -60,7 +60,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Hook error in before_scenario()
++    @not.with_python.version=3.10
++    Scenario: Hook error in before_scenario() (py.version < 3.8)
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+         """
+@@ -90,7 +91,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Hook error in before_scenario()
++    @use.with_python.version=3.10
++    Scenario: Hook error in before_scenario() (py.version >= 3.8)
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+         """
+@@ -124,7 +126,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Hook error in after_scenario()
++    @not.with_python.version=3.10
++    Scenario: Hook error in after_scenario() (py.version < 3.8)
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+         """
+@@ -156,7 +159,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Hook error in after_scenario()
++    @use.with_python.version=3.10
++    Scenario: Hook error in after_scenario() (py.version >= 3.8)
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+         """
+diff --git a/issue.features/issue0457.feature b/issue.features/issue0457.feature
+index 6d2f48f..c14c7a4 100644
+--- a/issue.features/issue0457.feature
++++ b/issue.features/issue0457.feature
+@@ -26,7 +26,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Use failing assertation in a JUnit XML report
++    @not.with_python.version=3.10
++    Scenario: Use failing assertation in a JUnit XML report (py.version < 3.8)
+       Given a file named "features/fails1.feature" with:
+         """
+         Feature:
+@@ -48,7 +49,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Use failing assertation in a JUnit XML report
++    @use.with_python.version=3.10
++    Scenario: Use failing assertation in a JUnit XML report (py.version >= 3.8)
+       Given a file named "features/fails1.feature" with:
+         """
+         Feature:
+@@ -73,7 +75,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Use exception in a JUnit XML report
++    @not.with_python.version=3.10
++    Scenario: Use exception in a JUnit XML report (py.version < 3.8)
+       Given a file named "features/fails2.feature" with:
+         """
+         Feature:
+@@ -96,7 +99,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Use exception in a JUnit XML report
++    @use.with_python.version=3.10
++    Scenario: Use exception in a JUnit XML report (py.version >= 3.8)
+       Given a file named "features/fails2.feature" with:
+         """
+         Feature:
+diff --git a/issue.features/issue0657.feature b/issue.features/issue0657.feature
+index aeaefd2..a674a26 100644
+--- a/issue.features/issue0657.feature
++++ b/issue.features/issue0657.feature
+@@ -1,15 +1,10 @@
+-@not.with_python2=true
+ @issue
++@not.with_python2=true
+ Feature: Issue #657 -- Allow async steps with timeouts to fail when they raise exceptions
+ 
+-
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
++    @use.with_python_has_async_function=true
+     @async_step_fails
+-    Scenario: Use @async_run_until_complete and async-step fails
++    Scenario: Use @async_run_until_complete and async-step fails (py.version >= 3.8)
+       Given a new working directory
+       And a file named "features/steps/async_steps_fails35.py" with:
+         """
+diff --git a/more.features/environment.py b/more.features/environment.py
+index 9d4302b..14d904c 100644
+--- a/more.features/environment.py
++++ b/more.features/environment.py
+@@ -1,16 +1,14 @@
+ # -*- coding: UTF-8 -*-
+ 
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+-import sys
++from behave import python_feature
+ 
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+-python_version = "%s.%s" % sys.version_info[:2]
+-active_tag_value_provider = {
+-    "python.version": python_version,
+-}
++active_tag_value_provider = python_feature.ACTIVE_TAG_VALUE_PROVIDER.copy()
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+@@ -18,10 +16,12 @@ def before_all(context):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+     setup_active_tag_values(active_tag_value_provider, context.config.userdata)
+ 
++
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/more.features/run_examples.feature b/more.features/run_examples.feature
+index 4778866..14acf98 100644
+--- a/more.features/run_examples.feature
++++ b/more.features/run_examples.feature
+@@ -29,13 +29,8 @@ Feature: Ensure that all examples are usable
+         features/rule_fails.feature:16  F2 -- Fails
+       """
+ 
+-
+-  @use.with_python.version=3.4
+-  @use.with_python.version=3.5
+-  @use.with_python.version=3.6
+-  @use.with_python.version=3.7
+-  @use.with_python.version=3.8
+-  Scenario: examples/async_step (needs: py34 or newer)
++  @use.with_python_has_coroutine=true
++  Scenario: examples/async_step (requires: python.version >= 3.4)
+     Given I use the directory "examples/async_step" as working directory
+     When I run "behave features/"
+     Then it should pass
diff --git a/meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch b/meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch
new file mode 100644
index 000000000..d8ecc09ac
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch
@@ -0,0 +1,84 @@
+From d38703153f7df501ceb48395f756b2427ee15e57 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 23:48:52 +0100
+Subject: [PATCH] docs: Update new and noteworthy
+
+* Add section on improved active-tag logic
+---
+ docs/conf.py                       |  2 +-
+ docs/new_and_noteworthy_v1.2.7.rst | 45 ++++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index 1579a36..cece86a 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -108,7 +108,7 @@ if USE_SPHINX_INTERNATIONAL:
+ # -----------------------------------------------------------------------------
+ project = u"behave"
+ authors = u"Jens Engel, Benno Rice and Richard Jones"
+-copyright = u"2012-2020, %s" % authors
++copyright = u"2012-2021, %s" % authors
+ 
+ # The version info for the project you're documenting, acts as replacement for
+ # |version| and |release|, also used in various other places throughout the
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index b7242f7..2eb94ad 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -9,6 +9,7 @@ Summary:
+   to match partial tag names, like: ``@foo.*``
+ * `Select-by-location for Scenario Containers`_ (Feature, Rule, ScenarioOutline)
+ * `Support for emojis in feature files and steps`_
++* `Improve Active-Tags Logic`_
+ 
+ .. _`Example Mapping`: https://cucumber.io/blog/example-mapping-introduction/
+ .. _`Example Mapping Webinar`: https://cucumber.io/blog/example-mapping-webinar/
+@@ -152,3 +153,47 @@ Support for Emojis in Feature Files and Steps
+ .. literalinclude:: ../features/steps/i18n_emoji_steps.py
+     :prepend:  # -- FILE: features/steps/i18n_emoji_steps.py
+     :language: python
++
++
++Improve Active-Tags Logic
++-------------------------------------------------------------------------------
++
++The active-tag computation logic was slightly changed (and fixed):
++
++* if multiple active-tags with same category are used
++* combination of positive active-tags (``use.with_{category}={value}``) and
++  negative active-tags (``not.with_{category}={value}``) with same category
++  are now supported
++
++All active-tags with same category are combined into one category tag-group.
++The following logical expression is used for active-tags with the same category::
++
++    category_tag_group.enabled := positive-tag-expression and not negative-tag-expression
++      positive-tag-expression  := enabled(tag1) or enabled(tag2) or ...
++      negative-tag-expression  := enabled(tag3) or enabled(tag4) or ...
++       tag1, tag2 are positive-tags, like @use.with_category=value
++       tag3, tag4 are negative-tags, like @not.with_category=value
++
++
++EXAMPLE:
++
++.. code-block:: gherkin
++
++    Feature: Active-Tag Example
++
++      @use.with_browser=Safari
++      @use.with_browser=Chrome
++      @not.with_browser=Firefox
++      Scenario: Use one active-tag group/category
++
++        HINT: Only executed with web browser Safari and Chrome, Firefox is explicitly excluded.
++        ...
++
++      @use.with_browser=Firefox
++      @use.with_os=linux
++      @use.with_os=darwin
++      Scenario: Use two active-tag groups/categories
++
++        HINT 1: Only executed with browser: Firefox
++        HINT 2: Only executed on OS: Linux and Darwin (macOS)
++        ...
diff --git a/meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch b/meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch
new file mode 100644
index 000000000..83b6b982e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch
@@ -0,0 +1,278 @@
+From 18261d6c2dfd563ac542eb69d12a8ad648575c67 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 10 Jan 2021 13:40:26 +0100
+Subject: [PATCH] * Add diagnostic helper function to print the current values
+ of active-tags. * Add helper classes for active-tag value providers.
+
+---
+ behave/compat/collections.py  |  25 ++++++
+ behave/tag_matcher.py         | 145 +++++++++++++++++++++++++++++++---
+ features/environment.py       |   9 +--
+ issue.features/environment.py |   9 +--
+ 4 files changed, 166 insertions(+), 22 deletions(-)
+
+diff --git a/behave/compat/collections.py b/behave/compat/collections.py
+index 00444f4..f4eea2c 100644
+--- a/behave/compat/collections.py
++++ b/behave/compat/collections.py
+@@ -18,3 +18,28 @@ except ImportError:     # pragma: no cover
+         warnings.warn(message)
+         # -- BACKWARD-COMPATIBLE: Better than nothing (for behave use case).
+         OrderedDict = dict
++
++try:
++    from collections import UserDict
++except ImportError:      # pragma: no cover
++    class UserDict(object):
++        """Emulate collections.UserDict class in python3."""
++        def __init__(self, data=None):
++            if data is None:
++                data = {}
++            self.data = data
++
++        def __len__(self):
++            return len(self.data)
++
++        def __iter__(self):
++            return len(self.data)
++
++        def keys(self):
++            return self.data.keys()
++
++        def values(self):
++            return self.data.values()
++
++        def items(self):
++            return self.data.items()
+diff --git a/behave/tag_matcher.py b/behave/tag_matcher.py
+index e2b1e82..78d7061 100644
+--- a/behave/tag_matcher.py
++++ b/behave/tag_matcher.py
+@@ -4,17 +4,16 @@ Contains classes and functionality to provide the active-tag mechanism.
+ Active-tags provide a skip-if logic based on tags in feature files.
+ """
+ 
+-from __future__ import absolute_import
++from __future__ import absolute_import, print_function
+ import re
+-import operator
+ import six
++from ._types import Unknown
++from .compat.collections import UserDict
+ 
+ 
+-def bool_to_string(value):
+-    """Converts a Boolean value into its normalized string representation."""
+-    return str(bool(value)).lower()
+-
+-
++# -----------------------------------------------------------------------------
++# CLASSES FOR: Active-Tags and ActiveTagMatchers
++# -----------------------------------------------------------------------------
+ class TagMatcher(object):
+     """Abstract base class that defines the TagMatcher protocol."""
+ 
+@@ -220,8 +219,8 @@ class ActiveTagMatcher(TagMatcher):
+             # -- CASE: Empty group is always enabled (CORNER-CASE).
+             return True
+ 
+-        current_value = self.value_provider.get(group_category, None)
+-        if current_value is None and self.ignore_unknown_categories:
++        current_value = self.value_provider.get(group_category, Unknown)
++        if current_value is Unknown and self.ignore_unknown_categories:
+             # -- CASE: Unknown category, ignore it.
+             return True
+ 
+@@ -320,6 +319,115 @@ class CompositeTagMatcher(TagMatcher):
+         return False
+ 
+ 
++# -----------------------------------------------------------------------------
++# ACTIVE TAG VALUE PROVIDER CLASSES:
++# -----------------------------------------------------------------------------
++class IActiveTagValueProvider(object):
++    """Protocol/Interface for active-tag value providers."""
++
++    def get(self, category, default=None):
++        return NotImplemented
++
++
++class ActiveTagValueProvider(UserDict):
++    def __init__(self, data=None):
++        if data is None:
++            data = {}
++        UserDict.__init__(self, data)
++
++    @staticmethod
++    def use_value(value):
++        if callable(value):
++            # -- RE-EVALUATE VALUE: Each time
++            value_func = value
++            value = value_func()
++        return value
++
++    def __getitem__(self, name):
++        value = self.data[name]
++        return self.use_value(value)
++
++    def get(self, category, default=None):
++        value = self.data.get(category, default)
++        return self.use_value(value)
++
++    def values(self):
++        for value in self.data.values(self):
++            yield self.use_value(value)
++
++    def items(self):
++        for category, value in self.data.items():
++            yield (category, self.use_value(value))
++
++    def categories(self):
++        return self.keys()
++
++
++class CompositeActiveTagValueProvider(ActiveTagValueProvider):
++    """Provides a composite helper class to resolve active-tag values
++    from a list of value-providers.
++    """
++
++    def __init__(self, value_providers=None):
++        if value_providers is None:
++            value_providers = []
++        super(CompositeActiveTagValueProvider, self).__init__()
++        self.value_providers = list(value_providers)
++
++    def get(self, category, default=None):
++        # -- FIRST: Check category cached-map (=self.data)
++        value = self.data.get(category, Unknown)
++        if value is Unknown:
++            # -- NOT DISCOVERED: Search over value_providers.
++            for value_provider in self.value_providers:
++                value = value_provider.get(category, Unknown)
++                if value is Unknown:
++                    continue
++
++                # -- FOUND CATEGORY:
++                self.data[category] = value
++                break
++            # -- FOUND-CATEGORY or NOT-FOUND:
++            if value is Unknown:
++                value = default
++
++        return self.use_value(value)
++
++    # -- MORE: Provide a dict-like interface.
++    def keys(self):
++        for value_provider in self.value_providers:
++            try:
++                for category in value_provider.keys():
++                    yield category
++            except AttributeError:
++                # -- keys() method not supported.
++                pass
++
++    def values(self):
++        for category in self.keys():
++            value = self.get(category)
++            yield value
++
++    def items(self):
++        for category in self.keys():
++            value = self.get(category)
++            yield (category, value)
++
++
++
++# -----------------------------------------------------------------------------
++# UTILITY FUNCTIONS:
++# -----------------------------------------------------------------------------
++def bool_to_string(value):
++    """Converts a boolean active-tag value into its normalized
++    string representation.
++
++    :param value:  Boolean value to use (or value converted into bool).
++    :returns: Boolean value converted into a normalized string.
++    """
++    return str(bool(value)).lower()
++
++
+ def setup_active_tag_values(active_tag_values, data):
+     """Setup/update active_tag values with dict-like data.
+     Only values for keys that are already present are updated.
+@@ -330,3 +438,22 @@ def setup_active_tag_values(active_tag_values, data):
+     for category in list(active_tag_values.keys()):
+         if category in data:
+             active_tag_values[category] = data[category]
++
++
++def print_active_tags(active_tag_value_provider, categories=None):
++    """Print a summary of the current active-tag values."""
++    if categories is None:
++        try:
++            categories = list(active_tag_value_provider)
++        except TypeError:   # TypeError: object is not iterable
++            categories = []
++
++    active_tag_data = active_tag_value_provider
++    print("ACTIVE-TAGS:")
++    for category in categories:
++        active_tag_value = active_tag_data.get(category)
++        print("use.with_{category}={value}".format(
++            category=category, value=active_tag_value))
++
++    # -- FINALLY: TRAILING NEW-LINE
++    print()
+diff --git a/features/environment.py b/features/environment.py
+index 6faf4e2..72ebaa0 100644
+--- a/features/environment.py
++++ b/features/environment.py
+@@ -2,7 +2,8 @@
+ # FILE: features/environemnt.py
+ 
+ from __future__ import absolute_import, print_function
+-from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
++from behave.tag_matcher import \
++    ActiveTagMatcher, setup_active_tag_values, print_active_tags
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+ from behave import python_feature
+ import platform
+@@ -21,11 +22,7 @@ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+ def print_active_tags_summary():
+-    active_tag_data = active_tag_value_provider
+-    print("ACTIVE-TAG SUMMARY:")
+-    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
+-    print("use.with_os=%s" % active_tag_data.get("os"))
+-    print()
++    print_active_tags(active_tag_value_provider, ["python.version", "os"])
+ 
+ 
+ # -----------------------------------------------------------------------------
+diff --git a/issue.features/environment.py b/issue.features/environment.py
+index 7e48ee0..ab85e6c 100644
+--- a/issue.features/environment.py
++++ b/issue.features/environment.py
+@@ -13,7 +13,7 @@ import sys
+ import platform
+ import os.path
+ import six
+-from behave.tag_matcher import ActiveTagMatcher
++from behave.tag_matcher import ActiveTagMatcher, print_active_tags
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+ # PREPARED: from behave.tag_matcher import setup_active_tag_values
+ 
+@@ -94,12 +94,7 @@ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+ def print_active_tags_summary():
+-    active_tag_data = active_tag_value_provider
+-    print("ACTIVE-TAG SUMMARY:")
+-    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
+-    # print("use.with_platform=%s" % active_tag_data.get("platform"))
+-    # print("use.with_os=%s" % active_tag_data.get("os"))
+-    print()
++    print_active_tags(active_tag_value_provider, ["python.version", "os"])
+ 
+ 
+ # ---------------------------------------------------------------------------
diff --git a/meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch b/meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch
new file mode 100644
index 000000000..9d370c299
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch
@@ -0,0 +1,541 @@
+From 715079cc08a7672d51c376a9d884873469ffa009 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 12 Jan 2021 13:21:44 +0100
+Subject: [PATCH] UPDATE: i18n/gherkin-languages.json from cucumber repository.
+
+CONTAINS: PR #827 (Estonian language updates contained)
+LAST COMMIT: 2021-01-07 (in Cucumber repository)
+LANGUAGE CHANGES:
+
+* Swedish: Rule keyword
+* Telugu: Fixing ISO 639-1 code
+* Russian: Rule keyword
+* Hebrew: Rule keyword
+* German: Addition keywords
+* Estonian: Rule keyword, ScenarioOutline keyword
+* Indonesian: Given keywords, whitespace
+---
+ behave/i18n.py                     |  92 ++++++++++++------
+ etc/gherkin/gherkin-languages.json | 145 +++++++++++++++++++++++++----
+ features/cmdline.lang_list.feature |  64 +++++++++----
+ issue.features/issue0309.feature   |   2 +-
+ 4 files changed, 240 insertions(+), 63 deletions(-)
+
+diff --git a/behave/i18n.py b/behave/i18n.py
+index 2781afe..a572626 100644
+--- a/behave/i18n.py
++++ b/behave/i18n.py
+@@ -188,16 +188,19 @@ languages = \
+         'then': ['* ', 'Så '],
+         'when': ['* ', 'Når ']},
+  'de': {'and': ['* ', 'Und '],
+-        'background': ['Grundlage'],
++        'background': ['Grundlage',
++                       'Hintergrund',
++                       'Voraussetzungen',
++                       'Vorbedingungen'],
+         'but': ['* ', 'Aber '],
+         'examples': ['Beispiele'],
+-        'feature': ['Funktionalität'],
++        'feature': ['Funktionalität', 'Funktion'],
+         'given': ['* ', 'Angenommen ', 'Gegeben sei ', 'Gegeben seien '],
+         'name': 'German',
+         'native': 'Deutsch',
+-        'rule': ['Rule'],
++        'rule': ['Rule', 'Regel'],
+         'scenario': ['Beispiel', 'Szenario'],
+-        'scenario_outline': ['Szenariogrundriss'],
++        'scenario_outline': ['Szenariogrundriss', 'Szenarien'],
+         'then': ['* ', 'Dann '],
+         'when': ['* ', 'Wenn ']},
+  'el': {'and': ['* ', 'Και '],
+@@ -344,9 +347,9 @@ languages = \
+         'given': ['* ', 'Eeldades '],
+         'name': 'Estonian',
+         'native': 'eesti keel',
+-        'rule': ['Rule'],
++        'rule': ['Reegel'],
+         'scenario': ['Juhtum', 'Stsenaarium'],
+-        'scenario_outline': ['Raamstjuhtum', 'Raamstsenaarium'],
++        'scenario_outline': ['Raamjuhtum', 'Raamstsenaarium'],
+         'then': ['* ', 'Siis '],
+         'when': ['* ', 'Kui ']},
+  'fa': {'and': ['* ', 'و '],
+@@ -455,7 +458,7 @@ languages = \
+         'given': ['* ', 'בהינתן '],
+         'name': 'Hebrew',
+         'native': 'עברית',
+-        'rule': ['Rule'],
++        'rule': ['כלל'],
+         'scenario': ['דוגמא', 'תרחיש'],
+         'scenario_outline': ['תבנית תרחיש'],
+         'then': ['* ', 'אז ', 'אזי '],
+@@ -518,17 +521,22 @@ languages = \
+         'then': ['* ', 'Akkor '],
+         'when': ['* ', 'Majd ', 'Ha ', 'Amikor ']},
+  'id': {'and': ['* ', 'Dan '],
+-        'background': ['Dasar'],
+-        'but': ['* ', 'Tapi '],
+-        'examples': ['Contoh'],
++        'background': ['Dasar', 'Latar Belakang'],
++        'but': ['* ', 'Tapi ', 'Tetapi '],
++        'examples': ['Contoh', 'Misal'],
+         'feature': ['Fitur'],
+-        'given': ['* ', 'Dengan '],
++        'given': ['* ',
++                  'Dengan ',
++                  'Diketahui ',
++                  'Diasumsikan ',
++                  'Bila ',
++                  'Jika '],
+         'name': 'Indonesian',
+         'native': 'Bahasa Indonesia',
+-        'rule': ['Rule'],
++        'rule': ['Rule', 'Aturan'],
+         'scenario': ['Skenario'],
+-        'scenario_outline': ['Skenario konsep'],
+-        'then': ['* ', 'Maka '],
++        'scenario_outline': ['Skenario konsep', 'Garis-Besar Skenario'],
++        'then': ['* ', 'Maka ', 'Kemudian '],
+         'when': ['* ', 'Ketika ']},
+  'is': {'and': ['* ', 'Og '],
+         'background': ['Bakgrunnur'],
+@@ -699,6 +707,32 @@ languages = \
+         'scenario_outline': ['Сценарын төлөвлөгөө'],
+         'then': ['* ', 'Тэгэхэд ', 'Үүний дараа '],
+         'when': ['* ', 'Хэрэв ']},
++ 'mr': {'and': ['* ', 'आणि ', 'तसेच '],
++        'background': ['पार्श्वभूमी'],
++        'but': ['* ', 'पण ', 'परंतु '],
++        'examples': ['उदाहरण'],
++        'feature': ['वैशिष्ट्य', 'सुविधा'],
++        'given': ['* ', 'जर', 'दिलेल्या प्रमाणे '],
++        'name': 'Marathi',
++        'native': 'मराठी',
++        'rule': ['नियम'],
++        'scenario': ['परिदृश्य'],
++        'scenario_outline': ['परिदृश्य रूपरेखा'],
++        'then': ['* ', 'मग ', 'तेव्हा '],
++        'when': ['* ', 'जेव्हा ']},
++ 'ne': {'and': ['* ', 'र ', 'अनी '],
++        'background': ['पृष्ठभूमी'],
++        'but': ['* ', 'तर '],
++        'examples': ['उदाहरण', 'उदाहरणहरु'],
++        'feature': ['सुविधा', 'विशेषता'],
++        'given': ['* ', 'दिइएको ', 'दिएको ', 'यदि '],
++        'name': 'Nepali',
++        'native': 'नेपाली',
++        'rule': ['नियम'],
++        'scenario': ['परिदृश्य'],
++        'scenario_outline': ['परिदृश्य रूपरेखा'],
++        'then': ['* ', 'त्यसपछि ', 'अनी '],
++        'when': ['* ', 'जब ']},
+  'nl': {'and': ['* ', 'En '],
+         'background': ['Achtergrond'],
+         'but': ['* ', 'Maar '],
+@@ -797,7 +831,7 @@ languages = \
+         'given': ['* ', 'Допустим ', 'Дано ', 'Пусть '],
+         'name': 'Russian',
+         'native': 'русский',
+-        'rule': ['Rule'],
++        'rule': ['Правило'],
+         'scenario': ['Пример', 'Сценарий'],
+         'scenario_outline': ['Структура сценария'],
+         'then': ['* ', 'То ', 'Затем ', 'Тогда '],
+@@ -873,7 +907,7 @@ languages = \
+         'given': ['* ', 'Givet '],
+         'name': 'Swedish',
+         'native': 'Svenska',
+-        'rule': ['Rule'],
++        'rule': ['Regel'],
+         'scenario': ['Scenario'],
+         'scenario_outline': ['Abstrakt Scenario', 'Scenariomall'],
+         'then': ['* ', 'Så '],
+@@ -891,6 +925,19 @@ languages = \
+         'scenario_outline': ['காட்சி சுருக்கம்', 'காட்சி வார்ப்புரு'],
+         'then': ['* ', 'அப்பொழுது '],
+         'when': ['* ', 'எப்போது ']},
++ 'te': {'and': ['* ', 'మరియు '],
++        'background': ['నేపథ్యం'],
++        'but': ['* ', 'కాని '],
++        'examples': ['ఉదాహరణలు'],
++        'feature': ['గుణము'],
++        'given': ['* ', 'చెప్పబడినది '],
++        'name': 'Telugu',
++        'native': 'తెలుగు',
++        'rule': ['Rule'],
++        'scenario': ['ఉదాహరణ', 'సన్నివేశం'],
++        'scenario_outline': ['కథనం'],
++        'then': ['* ', 'అప్పుడు '],
++        'when': ['* ', 'ఈ పరిస్థితిలో ']},
+  'th': {'and': ['* ', 'และ '],
+         'background': ['แนวคิด'],
+         'but': ['* ', 'แต่ '],
+@@ -904,19 +951,6 @@ languages = \
+         'scenario_outline': ['สรุปเหตุการณ์', 'โครงสร้างของเหตุการณ์'],
+         'then': ['* ', 'ดังนั้น '],
+         'when': ['* ', 'เมื่อ ']},
+- 'tl': {'and': ['* ', 'మరియు '],
+-        'background': ['నేపథ్యం'],
+-        'but': ['* ', 'కాని '],
+-        'examples': ['ఉదాహరణలు'],
+-        'feature': ['గుణము'],
+-        'given': ['* ', 'చెప్పబడినది '],
+-        'name': 'Telugu',
+-        'native': 'తెలుగు',
+-        'rule': ['Rule'],
+-        'scenario': ['ఉదాహరణ', 'సన్నివేశం'],
+-        'scenario_outline': ['కథనం'],
+-        'then': ['* ', 'అప్పుడు '],
+-        'when': ['* ', 'ఈ పరిస్థితిలో ']},
+  'tlh': {'and': ['* ', "'ej ", 'latlh '],
+          'background': ["mo'"],
+          'but': ['* ', "'ach ", "'a "],
+diff --git a/etc/gherkin/gherkin-languages.json b/etc/gherkin/gherkin-languages.json
+index 29cbca1..6069664 100644
+--- a/etc/gherkin/gherkin-languages.json
++++ b/etc/gherkin/gherkin-languages.json
+@@ -605,7 +605,10 @@
+       "Und "
+     ],
+     "background": [
+-      "Grundlage"
++      "Grundlage",
++      "Hintergrund",
++      "Voraussetzungen",
++      "Vorbedingungen"
+     ],
+     "but": [
+       "* ",
+@@ -615,7 +618,8 @@
+       "Beispiele"
+     ],
+     "feature": [
+-      "Funktionalität"
++      "Funktionalität",
++      "Funktion"
+     ],
+     "given": [
+       "* ",
+@@ -626,14 +630,16 @@
+     "name": "German",
+     "native": "Deutsch",
+     "rule": [
+-      "Rule"
++      "Rule",
++      "Regel"
+     ],
+     "scenario": [
+       "Beispiel",
+       "Szenario"
+     ],
+     "scenarioOutline": [
+-      "Szenariogrundriss"
++      "Szenariogrundriss",
++      "Szenarien"
+     ],
+     "then": [
+       "* ",
+@@ -1127,14 +1133,14 @@
+     "name": "Estonian",
+     "native": "eesti keel",
+     "rule": [
+-      "Rule"
++      "Reegel"
+     ],
+     "scenario": [
+       "Juhtum",
+       "Stsenaarium"
+     ],
+     "scenarioOutline": [
+-      "Raamstjuhtum",
++      "Raamjuhtum",
+       "Raamstsenaarium"
+     ],
+     "then": [
+@@ -1465,7 +1471,7 @@
+     "name": "Hebrew",
+     "native": "עברית",
+     "rule": [
+-      "Rule"
++      "כלל"
+     ],
+     "scenario": [
+       "דוגמא",
+@@ -1692,36 +1698,46 @@
+       "Dan "
+     ],
+     "background": [
+-      "Dasar"
++      "Dasar",
++      "Latar Belakang"
+     ],
+     "but": [
+       "* ",
+-      "Tapi "
++      "Tapi ",
++      "Tetapi "
+     ],
+     "examples": [
+-      "Contoh"
++      "Contoh",
++      "Misal"
+     ],
+     "feature": [
+       "Fitur"
+     ],
+     "given": [
+       "* ",
+-      "Dengan "
++      "Dengan ",
++      "Diketahui ",
++      "Diasumsikan ",
++      "Bila ",
++      "Jika "
+     ],
+     "name": "Indonesian",
+     "native": "Bahasa Indonesia",
+     "rule": [
+-      "Rule"
++      "Rule",
++      "Aturan"
+     ],
+     "scenario": [
+       "Skenario"
+     ],
+     "scenarioOutline": [
+-      "Skenario konsep"
++      "Skenario konsep",
++      "Garis-Besar Skenario"
+     ],
+     "then": [
+       "* ",
+-      "Maka "
++      "Maka ",
++      "Kemudian "
+     ],
+     "when": [
+       "* ",
+@@ -2330,6 +2346,54 @@
+       "Хэрэв "
+     ]
+   },
++  "ne": {
++    "and": [
++      "* ",
++      "र ",
++      "अनी "
++    ],
++    "background": [
++      "पृष्ठभूमी"
++    ],
++    "but": [
++      "* ",
++      "तर "
++    ],
++    "examples": [
++      "उदाहरण",
++      "उदाहरणहरु"
++    ],
++    "feature": [
++      "सुविधा",
++      "विशेषता"
++    ],
++    "given": [
++      "* ",
++      "दिइएको ",
++      "दिएको ",
++      "यदि "
++    ],
++    "name": "Nepali",
++    "native": "नेपाली",
++    "rule": [
++      "नियम"
++    ],
++    "scenario": [
++      "परिदृश्य"
++    ],
++    "scenarioOutline": [
++      "परिदृश्य रूपरेखा"
++    ],
++    "then": [
++      "* ",
++      "त्यसपछि ",
++      "अनी "
++    ],
++    "when": [
++      "* ",
++      "जब "
++    ]
++  },
+   "nl": {
+     "and": [
+       "* ",
+@@ -2665,7 +2729,7 @@
+     "name": "Russian",
+     "native": "русский",
+     "rule": [
+-      "Rule"
++      "Правило"
+     ],
+     "scenario": [
+       "Пример",
+@@ -2933,7 +2997,7 @@
+     "name": "Swedish",
+     "native": "Svenska",
+     "rule": [
+-      "Rule"
++      "Regel"
+     ],
+     "scenario": [
+       "Scenario"
+@@ -3046,7 +3110,7 @@
+       "เมื่อ "
+     ]
+   },
+-  "tl": {
++  "te": {
+     "and": [
+       "* ",
+       "మరియు "
+@@ -3510,5 +3574,52 @@
+       "* ",
+       "當"
+     ]
++  },
++  "mr": {
++    "and": [
++      "* ",
++      "आणि ",
++      "तसेच "
++    ],
++    "background": [
++      "पार्श्वभूमी"
++    ],
++    "but": [
++      "* ",
++      "पण ",
++      "परंतु "
++    ],
++    "examples": [
++      "उदाहरण"
++    ],
++    "feature": [
++      "वैशिष्ट्य",
++      "सुविधा"
++    ],
++    "given": [
++      "* ",
++      "जर",
++      "दिलेल्या प्रमाणे "
++    ],
++    "name": "Marathi",
++    "native": "मराठी",
++    "rule": [
++      "नियम"
++    ],
++    "scenario": [
++      "परिदृश्य"
++    ],
++    "scenarioOutline": [
++      "परिदृश्य रूपरेखा"
++    ],
++    "then": [
++      "* ",
++      "मग ",
++      "तेव्हा "
++    ],
++    "when": [
++      "* ",
++      "जेव्हा "
++    ]
+   }
+ }
+diff --git a/features/cmdline.lang_list.feature b/features/cmdline.lang_list.feature
+index f77e747..20822ec 100644
+--- a/features/cmdline.lang_list.feature
++++ b/features/cmdline.lang_list.feature
+@@ -39,21 +39,53 @@ Feature: Command-line options: Use behave --lang-list
+           fa: فارسی / Persian
+           fi: suomi / Finnish
+           fr: français / French
+-        """
+-    And the command output should contain:
+-        """
+-        sv: Svenska / Swedish
+-        ta: தமிழ் / Tamil
+-        th: ไทย / Thai
+-        tl: తెలుగు / Telugu
+-        tlh: tlhIngan / Klingon
+-        tr: Türkçe / Turkish
+-        tt: Татарча / Tatar
+-        uk: Українська / Ukrainian
+-        ur: اردو / Urdu
+-        uz: Узбекча / Uzbek
+-        vi: Tiếng Việt / Vietnamese
+-        zh-CN: 简体中文 / Chinese simplified
+-        zh-TW: 繁體中文 / Chinese traditional
++          ga: Gaeilge / Irish
++          gj: ગુજરાતી / Gujarati
++          gl: galego / Galician
++          he: עברית / Hebrew
++          hi: हिंदी / Hindi
++          hr: hrvatski / Croatian
++          ht: kreyòl / Creole
++          hu: magyar / Hungarian
++          id: Bahasa Indonesia / Indonesian
++          is: Íslenska / Icelandic
++          it: italiano / Italian
++          ja: 日本語 / Japanese
++          jv: Basa Jawa / Javanese
++          ka: ქართველი / Georgian
++          kn: ಕನ್ನಡ / Kannada
++          ko: 한국어 / Korean
++          lt: lietuvių kalba / Lithuanian
++          lu: Lëtzebuergesch / Luxemburgish
++          lv: latviešu / Latvian
++          mk-Cyrl: Македонски / Macedonian
++          mk-Latn: Makedonski (Latinica) / Macedonian (Latin)
++          mn: монгол / Mongolian
++          mr: मराठी / Marathi
++          ne: नेपाली / Nepali
++          nl: Nederlands / Dutch
++          no: norsk / Norwegian
++          pa: ਪੰਜਾਬੀ / Panjabi
++          pl: polski / Polish
++          pt: português / Portuguese
++          ro: română / Romanian
++          ru: русский / Russian
++          sk: Slovensky / Slovak
++          sl: Slovenski / Slovenian
++          sr-Cyrl: Српски / Serbian
++          sr-Latn: Srpski (Latinica) / Serbian (Latin)
++          sv: Svenska / Swedish
++          ta: தமிழ் / Tamil
++          te: తెలుగు / Telugu
++          th: ไทย / Thai
++          tlh: tlhIngan / Klingon
++          tr: Türkçe / Turkish
++          tt: Татарча / Tatar
++          uk: Українська / Ukrainian
++          ur: اردو / Urdu
++          uz: Узбекча / Uzbek
++          vi: Tiếng Việt / Vietnamese
++          zh-CN: 简体中文 / Chinese simplified
++          zh-TW: 繁體中文 / Chinese traditional
+         """
+     But the command output should not contain "Traceback"
+diff --git a/issue.features/issue0309.feature b/issue.features/issue0309.feature
+index c8a8857..b50e32d 100644
+--- a/issue.features/issue0309.feature
++++ b/issue.features/issue0309.feature
+@@ -52,8 +52,8 @@ Feature: Issue #309 -- behave --lang-list fails on Python3
+         """
+         sv: Svenska / Swedish
+         ta: தமிழ் / Tamil
++        te: తెలుగు / Telugu
+         th: ไทย / Thai
+-        tl: తెలుగు / Telugu
+         tlh: tlhIngan / Klingon
+         tr: Türkçe / Turkish
+         tt: Татарча / Tatar
diff --git a/meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch b/meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch
new file mode 100644
index 000000000..44532ab9b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch
@@ -0,0 +1,22 @@
+From cfbf492ce859c817703e4c986d9ab9dcea30223a Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 12 Jan 2021 13:40:58 +0100
+Subject: [PATCH] UPDATE CHANGES: Related to PR #895 and #827
+
+---
+ CHANGES.rst | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index a3398d8..ff82132 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -28,6 +28,8 @@ ENHANCEMENTS:
+ * Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Support emojis in ``*.feature`` files and steps
+ * Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
++* pull  #895: UPDATE: i18n/gherkin-languages.json from cucumber repository #895 (related to: #827)
++* pull  #827: Fixed keyword translation in Estonian #827 (provided by: ookull)
+ * issue #740: Enhancement: possibility to add cleanup to be called upon leaving outer context stack frames (submitted by: nizwiz, dcvmoole)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch b/meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch
new file mode 100644
index 000000000..78127d14e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch
@@ -0,0 +1,39 @@
+From ac1d98381de62b900af89aee5127c901fbe82c38 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 12 Jan 2021 13:51:02 +0100
+Subject: [PATCH] FIX CI-TRAVIS: For python 2.7 builds (mock >= 4.0 only for
+ python.version >= 3.6)
+
+---
+ py.requirements/ci.travis.txt | 3 ++-
+ py.requirements/testing.txt   | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index cbc60c0..1d6e050 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -6,7 +6,8 @@ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+ 
+ pytest-html >= 1.19.0,<2.0
+-mock  >= 2.0
++mock  <  4.0;   python_version <  '3.6'
++mock  >= 4.0;   python_version >= '3.6'
+ PyHamcrest >= 2.0.2; python_version >= '3.0'
+ PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index fc8fd82..9230c1f 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -8,7 +8,8 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ 
+ pytest-html >= 1.19.0,<2.0
+-mock  >= 2.0
++mock  <  4.0;   python_version <  '3.6'
++mock  >= 4.0;   python_version >= '3.6'
+ PyHamcrest >= 2.0.2; python_version >= '3.0'
+ PyHamcrest <  2.0;   python_version <  '3.0'
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch b/meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch
new file mode 100644
index 000000000..17ee076d8
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch
@@ -0,0 +1,126 @@
+From 346aa055cd0cde2cc6a1fe92d874644b06dbdb17 Mon Sep 17 00:00:00 2001
+From: kingbuzzman <buzzi.javier@gmail.com>
+Date: Fri, 19 Jun 2020 09:18:51 -0400
+Subject: [PATCH] Adds the ability to use a custom runner in the behave command
+
+---
+ behave/__main__.py               |  2 +-
+ behave/configuration.py          | 16 ++++++++++++++++
+ docs/behave.rst                  |  5 +++++
+ tests/unit/test_configuration.py | 19 +++++++++++++++++++
+ 4 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/behave/__main__.py b/behave/__main__.py
+index 3cae36d..edb99c4 100644
+--- a/behave/__main__.py
++++ b/behave/__main__.py
+@@ -215,7 +215,7 @@ def main(args=None):
+     :return: 0, if successful. Non-zero, in case of errors/failures.
+     """
+     config = Configuration(args)
+-    return run_behave(config)
++    return run_behave(config, runner_class=config.runner_class)
+ 
+ 
+ if __name__ == "__main__":
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 65e2e3e..04c014a 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -8,6 +8,7 @@ import re
+ import sys
+ import shlex
+ import six
++from importlib import import_module
+ from six.moves import configparser
+ 
+ from behave.model import ScenarioOutline
+@@ -65,6 +66,16 @@ class LogLevel(object):
+ # -----------------------------------------------------------------------------
+ # CONFIGURATION SCHEMA:
+ # -----------------------------------------------------------------------------
++
++def valid_python_module(path):
++    try:
++        module_path, class_name = path.rsplit('.', 1)
++        module = import_module(module_path)
++        return getattr(module, class_name)
++    except (ValueError, AttributeError, ImportError):
++        raise argparse.ArgumentTypeError("No module named '%s' was found." % path)
++
++
+ options = [
+     (("-c", "--no-color"),
+      dict(action="store_false", dest="color",
+@@ -111,6 +122,11 @@ options = [
+      dict(metavar="PATH", dest="junit_directory",
+           default="reports",
+           help="""Directory in which to store JUnit reports.""")),
++    
++    (("--runner-class",),
++     dict(action="store",
++          default="behave.runner.Runner", type=valid_python_module,
++          help="Tells Behave to use a specific runner. (default: %(default)s)")),
+ 
+     ((),  # -- CONFIGFILE only
+      dict(dest="default_format",
+diff --git a/docs/behave.rst b/docs/behave.rst
+index 25ce523..8c1c125 100644
+--- a/docs/behave.rst
++++ b/docs/behave.rst
+@@ -55,6 +55,11 @@ You may see the same information presented below at any time using ``behave
+ 
+     Directory in which to store JUnit reports.
+ 
++.. option:: --runner-class
++
++    This allows you to use your own custom runner. The default is 
++    ``behave.runner.Runner``.
++
+ .. option:: -f, --format
+ 
+     Specify a formatter. If none is specified the default formatter is
+diff --git a/tests/unit/test_configuration.py b/tests/unit/test_configuration.py
+index c96cf63..025a6d0 100644
+--- a/tests/unit/test_configuration.py
++++ b/tests/unit/test_configuration.py
+@@ -5,6 +5,7 @@ import six
+ import pytest
+ from behave import configuration
+ from behave.configuration import Configuration, UserData
++from behave.runner import Runner as BaseRunner
+ from unittest import TestCase
+ 
+ 
+@@ -37,6 +38,10 @@ if sys.platform.startswith("win"):
+     ROOTDIR_PREFIX = os.environ.get("BEHAVE_ROOTDIR_PREFIX", ROOTDIR_PREFIX_DEFAULT)
+ 
+ 
++class CustomTestRunner(BaseRunner):
++    """Custom, dummy runner"""
++
++
+ class TestConfiguration(object):
+ 
+     def test_read_file(self):
+@@ -92,6 +97,20 @@ class TestConfiguration(object):
+         assert "STAGE2_environment.py" == config.environment_file
+         del os.environ["BEHAVE_STAGE"]
+ 
++    def test_settings_runner_class(self, capsys):
++        config = Configuration("")
++        assert BaseRunner == config.runner_class
++
++    def test_settings_runner_class_custom(self, capsys):
++        config = Configuration(["--runner-class=tests.unit.test_configuration.CustomTestRunner"])
++        assert CustomTestRunner == config.runner_class
++
++    def test_settings_runner_class_invalid(self, capsys):
++        with pytest.raises(SystemExit):
++            Configuration(["--runner-class=does.not.exist.Runner"])
++        captured = capsys.readouterr()
++        assert "No module named 'does.not.exist.Runner' was found." in captured.err
++
+ 
+ class TestConfigurationUserData(TestCase):
+     """Test userdata aspects in behave.configuration.Configuration class."""
diff --git a/meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch b/meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch
new file mode 100644
index 000000000..dc39f98db
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch
@@ -0,0 +1,59 @@
+From ccccbe478ac05d6093a076f61aaa00d8867b8760 Mon Sep 17 00:00:00 2001
+From: Marc Abramowitz <abramowi@adobe.com>
+Date: Thu, 3 Aug 2017 07:29:38 -0700
+Subject: [PATCH] Allow forcing color with --color=always
+
+even if stdout is not a tty (e.g.: Jenkins)
+---
+ behave/configuration.py    |  7 ++++---
+ behave/formatter/pretty.py | 12 +++++++++---
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 04c014a..1b0bc2b 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -82,9 +82,10 @@ options = [
+           help="Disable the use of ANSI color escapes.")),
+ 
+     (("--color",),
+-     dict(action="store_true", dest="color",
+-          help="""Use ANSI color escapes. This is the default
+-                  behaviour. This switch is used to override a
++     dict(dest="color", choices=["never", "always", "auto"],
++          default="auto", const="auto", nargs="?",
++          help="""Use ANSI color escapes. Defaults to %(const)r.
++                  This switch is used to override a
+                   configuration file setting.""")),
+ 
+     (("-d", "--dry-run"),
+diff --git a/behave/formatter/pretty.py b/behave/formatter/pretty.py
+index 794e1d7..b97438a 100644
+--- a/behave/formatter/pretty.py
++++ b/behave/formatter/pretty.py
+@@ -66,9 +66,7 @@ class PrettyFormatter(Formatter):
+         super(PrettyFormatter, self).__init__(stream_opener, config)
+         # -- ENSURE: Output stream is open.
+         self.stream = self.open()
+-        isatty = getattr(self.stream, "isatty", lambda: True)
+-        stream_supports_colors = isatty()
+-        self.monochrome = not config.color or not stream_supports_colors
++        self.monochrome = self._get_monochrome(config)
+         self.show_source = config.show_source
+         self.show_timings = config.show_timings
+         self.show_multiline = config.show_multiline
+@@ -83,6 +81,14 @@ class PrettyFormatter(Formatter):
+         self.indentations = []
+         self.step_lines = 0
+ 
++    def _get_monochrome(self, config):
++        isatty = getattr(self.stream, "isatty", lambda: True)
++        if config.color == 'always':
++            return False
++        elif config.color == 'never':
++            return True
++        else:
++            return not isatty()
+ 
+     def reset(self):
+         # -- UNUSED: self.tag_statement = None
diff --git a/meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch b/meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch
new file mode 100644
index 000000000..cc4e52676
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch
@@ -0,0 +1,43 @@
+From 0821f7664961e3dae0d0f6bcf939b1a63ccdaa80 Mon Sep 17 00:00:00 2001
+From: Marc Abramowitz <abramowi@adobe.com>
+Date: Thu, 3 Aug 2017 09:11:22 -0700
+Subject: [PATCH] Allow --color with no value followed by posarg
+
+Allow commands like `--color features/whizbang.feature` to work
+Without this, argparse will treat the positional arg as the value to
+--color and we'd get:
+  argument --color: invalid choice: 'features/whizbang.feature'
+---
+ behave/configuration.py | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 1b0bc2b..0fdfd5e 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -83,7 +83,7 @@ options = [
+ 
+     (("--color",),
+      dict(dest="color", choices=["never", "always", "auto"],
+-          default="auto", const="auto", nargs="?",
++          default=None, const="auto", nargs="?",
+           help="""Use ANSI color escapes. Defaults to %(const)r.
+                   This switch is used to override a
+                   configuration file setting.""")),
+@@ -562,6 +562,16 @@ class Configuration(object):
+             # -- AUTO-DISCOVER: Verbose mode from command-line args.
+             verbose = ("-v" in command_args) or ("--verbose" in command_args)
+ 
++        # Allow commands like `--color features/whizbang.feature` to work
++        # Without this, argparse will treat the positional arg as the value to
++        # --color and we'd get:
++        #   argument --color: invalid choice: 'features/whizbang.feature'
++        #   (choose from 'never', 'always', 'auto')
++        if '--color' in command_args:
++            color_arg_pos = command_args.index('--color')
++            if os.path.exists(command_args[color_arg_pos + 1]):
++                command_args.insert(color_arg_pos + 1, '--')
++
+         self.version = None
+         self.tags_help = None
+         self.lang_list = None
diff --git a/meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch b/meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch
new file mode 100644
index 000000000..63975a42b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch
@@ -0,0 +1,31 @@
+From a59dc80e1a8292e3a465c69e79bd7591ed513eb7 Mon Sep 17 00:00:00 2001
+From: Marc Abramowitz <abramowi@adobe.com>
+Date: Thu, 3 Aug 2017 13:29:55 -0700
+Subject: [PATCH] Add BEHAVE_COLOR env var
+
+---
+ behave/configuration.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 0fdfd5e..e7d385d 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -83,7 +83,7 @@ options = [
+ 
+     (("--color",),
+      dict(dest="color", choices=["never", "always", "auto"],
+-          default=None, const="auto", nargs="?",
++          default=os.getenv('BEHAVE_COLOR'), const="auto", nargs="?",
+           help="""Use ANSI color escapes. Defaults to %(const)r.
+                   This switch is used to override a
+                   configuration file setting.""")),
+@@ -507,7 +507,7 @@ class Configuration(object):
+     """Configuration object for behave and behave runners."""
+     # pylint: disable=too-many-instance-attributes
+     defaults = dict(
+-        color=sys.platform != "win32",
++        color='never' if sys.platform == "win32" else os.getenv('BEHAVE_COLOR', 'auto'),
+         show_snippets=True,
+         show_skipped=True,
+         dry_run=False,
diff --git a/meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch b/meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch
new file mode 100644
index 000000000..9c54c8abe
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch
@@ -0,0 +1,33 @@
+From 8463e94459382e8e21d0b5bd19a23356bc674c28 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pablo=20Dom=C3=ADnguez?=
+ <pablo.dominguezsantana@telefonica.com>
+Date: Thu, 9 Sep 2021 12:19:21 +0200
+Subject: [PATCH] fix: malformed table rows warning
+
+---
+ behave/parser.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/behave/parser.py b/behave/parser.py
+index 58c68be..b71adfe 100644
+--- a/behave/parser.py
++++ b/behave/parser.py
+@@ -41,6 +41,7 @@ Keyword aliases:
+ # pylint: enable=line-too-long
+ 
+ from __future__ import absolute_import, with_statement
++import logging
+ import re
+ import sys
+ import six
+@@ -644,6 +645,10 @@ class Parser(object):
+             self.state = "steps"
+             return self.action_steps(line)
+ 
++        if not re.match(r"^(|.+)\|$", line):
++            logger = logging.getLogger("behave")
++            logger.warning(u"Malformed table row at %s: line %i", self.feature.filename, self.line)
++
+         # -- SUPPORT: Escaped-pipe(s) in Gherkin cell values.
+         #    Search for pipe(s) that are not preceeded with an escape char.
+         cells = [cell.replace("\\|", "|").strip()
diff --git a/meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch b/meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch
new file mode 100644
index 000000000..34886e1f3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch
@@ -0,0 +1,42 @@
+From e7353c14b2a6b877eb31ebd029c613c91f8b7f11 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 12 Sep 2021 16:07:32 +0200
+Subject: [PATCH] FIX #955: setup: Remove attribute 'use_2to3'
+
+REASON:
+* This attribute is deprecated since setuptools >= v58.0.2 (2021-09-06).
+* 2to3 conversion should not be needed anymore.
+  Currently, code should run on python2 and python3 (by using six, etc.).
+---
+ setup.py | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/setup.py b/setup.py
+index fd89bda..ba407fd 100644
+--- a/setup.py
++++ b/setup.py
+@@ -118,8 +118,8 @@ setup(
+             "pylint",
+         ],
+     },
+-    # MAYBE-DISABLE: use_2to3
+-    use_2to3= bool(python_version >= 3.0),
++    # DISABLED: use_2to3= bool(python_version >= 3.0),
++    # DEPRECATED SINCE: setuptools v58.0.2 (2021-09-06)
+     license="BSD",
+     classifiers=[
+         "Development Status :: 4 - Beta",
+@@ -129,12 +129,11 @@ setup(
+         "Programming Language :: Python :: 2",
+         "Programming Language :: Python :: 2.7",
+         "Programming Language :: Python :: 3",
+-        "Programming Language :: Python :: 3.3",
+-        "Programming Language :: Python :: 3.4",
+         "Programming Language :: Python :: 3.5",
+         "Programming Language :: Python :: 3.6",
+         "Programming Language :: Python :: 3.7",
+         "Programming Language :: Python :: 3.8",
++        "Programming Language :: Python :: 3.9",
+         "Programming Language :: Python :: Implementation :: CPython",
+         "Programming Language :: Python :: Implementation :: Jython",
+         "Programming Language :: Python :: Implementation :: PyPy",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch b/meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch
new file mode 100644
index 000000000..7806d9e9c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch
@@ -0,0 +1,21 @@
+From c6e1f74e9e670ba789467888bc34d64e71999a24 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 20 Sep 2021 16:13:59 +0200
+Subject: [PATCH] Add info for fixed issue #955
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index ff82132..880fd91 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -42,6 +42,7 @@ FIXED:
+ 
+ * FIXED: Some tests related to python3.9
+ * FIXED: active-tag logic if multiple tags with same category exists.
++* issue #955: setup: Remove attribute 'use_2to3' (submitted by: krisgesling)
+ * issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+ * issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
diff --git a/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb b/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
index 1dcc7d218..745d1e2b2 100644
--- a/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
+++ b/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
@@ -4,8 +4,131 @@ LICENSE = "BSD-2-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=d950439e8ea6ed233e4288f5e1a49c06"
 
 PV .= "+git${SRCREV}"
-SRCREV = "9520119376046aeff73804b5f1ea05d87a63f370"
-SRC_URI += "git://github.com/behave/behave;branch=master;protocol=https"
+SRCREV = "c0f3faf47ff05f549ec049599eb2f24069b0e51e"
+SRC_URI += "file://0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch \
+           file://0002-UPDATE-FIXED-725.patch \
+           file://0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch \
+           file://0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch \
+           file://0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch \
+           file://0006-Formatter-Add-basic-support-output-for-Rules.patch \
+           file://0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch \
+           file://0008-Correct-examples-and-docstring.patch \
+           file://0009-FIX-feature.run_items-processing-with-Rule-s.patch \
+           file://0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch \
+           file://0011-Cleanup-Dependent-package-versions-in-requirements.patch \
+           file://0012-docs-conf.py-tweaks.patch \
+           file://0013-FIX-Misspelled-after_rule-hook-was-after_after.patch \
+           file://0014-Add-hints-on-Gherkin-v6-grammar-issues.patch \
+           file://0015-README-ReST-tweaks.patch \
+           file://0016-Example-using-Gherkin-v6-grammar.patch \
+           file://0017-PREPARE-Python-3.8-support.patch \
+           file://0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch \
+           file://0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch \
+           file://0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch \
+           file://0021-FIX-py3.8-logging.Formatter.validate-problem.patch \
+           file://0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch \
+           file://0023-UPDATE-Add-755-info.patch \
+           file://0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch \
+           file://0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch \
+           file://0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch \
+           file://0027-Comment-tweaks.patch \
+           file://0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch \
+           file://0029-Steps-catalog-should-not-break-configured-rerun-sett.patch \
+           file://0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch \
+           file://0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch \
+           file://0032-Add-info-on-merged-pull-588.patch \
+           file://0033-Tweak-tests-required-by-pytest-5.0.patch \
+           file://0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch \
+           file://0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch \
+           file://0036-FIX-Remove-test-from-pytest-run.patch \
+           file://0037-Select-by-location-Add-support-for-Scenario-containe.patch \
+           file://0038-docs-Add-description-for-Select-by-location-for-Scen.patch \
+           file://0039-tests-Fix-warnings-for-python3.patch \
+           file://0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch \
+           file://0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch \
+           file://0042-FIX-Invalid-escape-char-in-regex-w-python3.patch \
+           file://0043-Example-related-to-question-in-756.patch \
+           file://0044-FIX-python3.8-regressions-on-CI-server.patch \
+           file://0045-UPDATE-Mark-issue-755-as-fixed.patch \
+           file://0046-UPDATE-Cucumber-gherkin-languages.json.patch \
+           file://0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch \
+           file://0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch \
+           file://0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch \
+           file://0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch \
+           file://0051-Improve-support-for-feature.background-inheritance-f.patch \
+           file://0052-Add-support-for-runtime-constraints.patch \
+           file://0053-Use-runtime-constraints.patch \
+           file://0054-CLEANUP-Remove-deprecated-parts.patch \
+           file://0055-CLEANUP-Remove-deprecated-parts.patch \
+           file://0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch \
+           file://0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch \
+           file://0058-UTIL-Formatting-tweaks.patch \
+           file://0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch \
+           file://0060-Added-issue-unit-test.patch \
+           file://0061-Merge-pull-request-767-with-minor-tweaks.patch \
+           file://0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch \
+           file://0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch \
+           file://0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch \
+           file://0065-Nibble-TravisCI-to-wake-up.patch \
+           file://0066-Tweak-pytest-version-selection.patch \
+           file://0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch \
+           file://0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch \
+           file://0069-UPDATE-dependencies-path.py-path-pytest.patch \
+           file://0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch \
+           file://0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch \
+           file://0072-Cleanup-comments.patch \
+           file://0073-FIX-sphinx-build-problem-async_steps3x.py.patch \
+           file://0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch \
+           file://0075-docs-parse_expression-add-links-to-parse_type-module.patch \
+           file://0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch \
+           file://0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch \
+           file://0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch \
+           file://0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch \
+           file://0080-DOCS-Update-API-description-for-Runner-Operation.patch \
+           file://0081-FIX-DOCS-Runner-operations-typo.patch \
+           file://0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch \
+           file://0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch \
+           file://0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch \
+           file://0085-Add-renovate.json.patch \
+           file://0086-PRPEPARE-RENOVATE-With-adaptions.patch \
+           file://0087-Pin-dependencies.patch \
+           file://0088-renovate-Extend-pip-requirements-file-list.patch \
+           file://0089-PIN-REQUIREMENTS-Extend-to-all-places.patch \
+           file://0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch \
+           file://0091-Docs-change-code-blocks-from-bash-to-console.patch \
+           file://0092-Fix-typo-in-tutorial.patch \
+           file://0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch \
+           file://0094-UPDATE-PR-877-was-merged.patch \
+           file://0095-capitalizing-steps.patch \
+           file://0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch \
+           file://0097-Test-against-PowerPC-CPU-support-Travis-867.patch \
+           file://0098-Add-Context.attach-docs-and-test.patch \
+           file://0099-Add-Contributing-chapter.patch \
+           file://0100-Adapt-Tox-target-for-building-the-docs.patch \
+           file://0101-Mention-HTML-formatter-in-documentation.patch \
+           file://0102-Use-console-highlighting-for-pip-install-docs.patch \
+           file://0103-docs-fix-simple-typo-tuorial-tutorial.patch \
+           file://0104-Add-support-for-python3.9-by-using-active-tags.patch \
+           file://0105-PREFER-python3-from-now-on.patch \
+           file://0106-REMOVE-invoke-scripts.patch \
+           file://0107-FIX-Deprecated-warnings-for-Python-3.x.patch \
+           file://0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch \
+           file://0109-FIX-Active-tag-logic.patch \
+           file://0110-FIX-Tests-w-more.features.patch \
+           file://0111-FIX-Some-regressions-with-Python-3.9.patch \
+           file://0112-docs-Update-new-and-noteworthy.patch \
+           file://0113-Add-diagnostic-helper-function-to-print-the-current-.patch \
+           file://0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch \
+           file://0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch \
+           file://0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch \
+           file://0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch \
+           file://0118-Allow-forcing-color-with-color-always.patch \
+           file://0119-Allow-color-with-no-value-followed-by-posarg.patch \
+           file://0120-Add-BEHAVE_COLOR-env-var.patch \
+           file://0121-fix-malformed-table-rows-warning.patch \
+           file://0122-FIX-955-setup-Remove-attribute-use_2to3.patch \
+           file://0123-Add-info-for-fixed-issue-955.patch \
+           "
 
 S = "${WORKDIR}/git"
 
@@ -16,3 +139,5 @@ RDEPENDS:${PN} += " \
     ${PYTHON_PN}-setuptools \
     ${PYTHON_PN}-six \
     "
+
+PV = "6"
-- 
2.25.1


[-- Attachment #2: 0001-python3-behave-upgrade-1.2.6-git9520119376046aeff738.patch --]
[-- Type: text/x-diff, Size: 1246021 bytes --]

From 815d53cd9a095b0b67dc6f98ad9a7fa251edefbf Mon Sep 17 00:00:00 2001
From: Upgrade Helper <auh@moto-timo.dev>
Date: Tue, 11 Jul 2023 17:12:25 -0500
Subject: [PATCH] python3-behave: upgrade
 1.2.6+git9520119376046aeff73804b5f1ea05d87a63f370 -> 6

---
 ...ioOutlineBuilder-was-not-copying-des.patch |   22 +
 .../0002-UPDATE-FIXED-725.patch               |   21 +
 ...ST-to-verify-that-issue-725-is-fixed.patch |   60 +
 ...ter-counts-computation-when-Rules-ar.patch |  342 +
 ...print_summary-Simplify-if-Rules-are-.patch |   60 +
 ...r-Add-basic-support-output-for-Rules.patch |  395 +
 ...MP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch |   67 +
 .../0008-Correct-examples-and-docstring.patch |   41 +
 ...ure.run_items-processing-with-Rule-s.patch |   58 +
 ...-sphinx-intl-support-for-READTHEDOCS.patch |   58 +
 ...ent-package-versions-in-requirements.patch |   81 +
 .../0012-docs-conf.py-tweaks.patch            |   30 +
 ...lled-after_rule-hook-was-after_after.patch |   30 +
 ...d-hints-on-Gherkin-v6-grammar-issues.patch |   45 +
 .../0015-README-ReST-tweaks.patch             |   18 +
 ...016-Example-using-Gherkin-v6-grammar.patch |  228 +
 .../0017-PREPARE-Python-3.8-support.patch     |   39 +
 ...x-logging.Formatter-validate-problem.patch |   22 +
 ...arily-move-py38-dev-to-front-build-f.patch |   28 +
 ...Tweaks-for-faster-builds-temporarily.patch |   35 +
 ...8-logging.Formatter.validate-problem.patch |   47 +
 ...on-3.8-asyncio.coroutine-is-deprecat.patch |   42 +
 .../0023-UPDATE-Add-755-info.patch            |   24 +
 ...ted-to-docstring-example-and-weird-b.patch |   25 +
 ...pe-sequence-warnings-w-regex-pattern.patch |   29 +
 ...NUP-Move-deprecated-tag-matcher-clas.patch | 1020 +++
 .../python3-behave/0027-Comment-tweaks.patch  |   30 +
 ...-related-to-invalid-escapes-in-regex.patch |   79 +
 ...ould-not-break-configured-rerun-sett.patch |   73 +
 ...les-and-failing-scenarios-enable-via.patch |   36 +
 ..._v6-Tweak-ScenarioOutline-Examples-t.patch |   27 +
 .../0032-Add-info-on-merged-pull-588.patch    |   21 +
 ...3-Tweak-tests-required-by-pytest-5.0.patch |   97 +
 ...st-instead-of-nose-to-remove-nose.im.patch |  180 +
 ...Y-nose-to-avoid-nose.importer-warnin.patch | 1815 ++++
 ...0036-FIX-Remove-test-from-pytest-run.patch |   22 +
 ...on-Add-support-for-Scenario-containe.patch |  652 ++
 ...tion-for-Select-by-location-for-Scen.patch |   58 +
 .../0039-tests-Fix-warnings-for-python3.patch |   50 +
 ...ag-expressions-1.1.2-to-fix-warnings.patch |   55 +
 ...ENT-Support-emojis-in-feature-files-.patch |   91 +
 ...valid-escape-char-in-regex-w-python3.patch |  250 +
 ...3-Example-related-to-question-in-756.patch |  335 +
 ...X-python3.8-regressions-on-CI-server.patch |  489 +
 .../0045-UPDATE-Mark-issue-755-as-fixed.patch |   46 +
 ...DATE-Cucumber-gherkin-languages.json.patch |   57 +
 ...ule-keyword-translation-in-portugues.patch |  202 +
 ...-generate-from-gherkin-languages.jso.patch |  141 +
 ...ming-to-fixture.behave.no_background.patch |  322 +
 ...50-EXAMPLE-Cleanup-Gherkin-v6-README.patch |   64 +
 ...for-feature.background-inheritance-f.patch | 1510 +++
 ...-Add-support-for-runtime-constraints.patch |  269 +
 .../0053-Use-runtime-constraints.patch        |  196 +
 ...0054-CLEANUP-Remove-deprecated-parts.patch | 3937 ++++++++
 ...0055-CLEANUP-Remove-deprecated-parts.patch |  736 ++
 ...rform-more-Gherkin-v6-checks-and-run.patch |  155 +
 ...-and-python-module-old-was-broken-no.patch |   72 +
 .../0058-UTIL-Formatting-tweaks.patch         |   22 +
 ...e-use_fixture_by_tag-didn-t-return-t.patch |   23 +
 .../0060-Added-issue-unit-test.patch          |   62 +
 ...e-pull-request-767-with-minor-tweaks.patch |   60 +
 ...sue-766-PrettyFormatter-UnicodeError.patch |   83 +
 ...enarioOutline.Examples-without-table.patch |   74 +
 ...enarioOutline.Examples-without-table.patch |   21 +
 .../0065-Nibble-TravisCI-to-wake-up.patch     |   21 +
 .../0066-Tweak-pytest-version-selection.patch |   37 +
 ...figuration-to-silence-JUnit-XML-dial.patch |   37 +
 ...e-test-for-wildcard-pattern-matching.patch |   56 +
 ...ATE-dependencies-path.py-path-pytest.patch |  141 +
 ...eprecatedWarning-from-distutils-pack.patch |   25 +
 ...-Add-ContextMode-enum-related-to-797.patch |  216 +
 .../0072-Cleanup-comments.patch               |   22 +
 ...phinx-build-problem-async_steps3x.py.patch |   29 +
 ...-parse_expressions-was-parse_builtin.patch |  185 +
 ...ssion-add-links-to-parse_type-module.patch |   40 +
 ...MP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch |   65 +
 ...leanups-related-to-question-in-800-P.patch |  223 +
 ...y-name-uses-regex-pattern-related-to.patch |   82 +
 ...nce-problem-copy-paste-in-Rule-class.patch |   34 +
 ...API-description-for-Runner-Operation.patch |  195 +
 ...0081-FIX-DOCS-Runner-operations-typo.patch |   22 +
 ...ement-Context.add_cleanup-with-layer.patch |  295 +
 ...8.0-parse-versions-1.16.0-.-1.17.x-h.patch |   37 +
 ...Duplicated-steps-AmbiguousStepErrors.patch |   34 +
 .../0085-Add-renovate.json.patch              |   21 +
 ...086-PRPEPARE-RENOVATE-With-adaptions.patch |  175 +
 .../0087-Pin-dependencies.patch               |   36 +
 ...te-Extend-pip-requirements-file-list.patch |   31 +
 ...IN-REQUIREMENTS-Extend-to-all-places.patch |   92 +
 ..._cleanup-replaces-_tasklet_cleanup-r.patch | 8116 +++++++++++++++++
 ...nge-code-blocks-from-bash-to-console.patch |   36 +
 .../0092-Fix-typo-in-tutorial.patch           |   24 +
 ...nts-Use-PyHamcrest-2.0-for-python2.7.patch |   80 +
 .../0094-UPDATE-PR-877-was-merged.patch       |   21 +
 .../0095-capitalizing-steps.patch             |   28 +
 ...develop.update-gherkin-that-aborted-.patch |   56 +
 ...ainst-PowerPC-CPU-support-Travis-867.patch |   22 +
 ...098-Add-Context.attach-docs-and-test.patch |  132 +
 .../0099-Add-Contributing-chapter.patch       |  125 +
 ...apt-Tox-target-for-building-the-docs.patch |   34 +
 ...tion-HTML-formatter-in-documentation.patch |   83 +
 ...le-highlighting-for-pip-install-docs.patch |   22 +
 ...ocs-fix-simple-typo-tuorial-tutorial.patch |   52 +
 ...t-for-python3.9-by-using-active-tags.patch |  227 +
 .../0105-PREFER-python3-from-now-on.patch     |   19 +
 .../0106-REMOVE-invoke-scripts.patch          |   41 +
 ...X-Deprecated-warnings-for-Python-3.x.patch |  124 +
 ...lems-in-virtualenvs-w-behave4cmd0-st.patch |   18 +
 .../0109-FIX-Active-tag-logic.patch           |  875 ++
 .../0110-FIX-Tests-w-more.features.patch      |   56 +
 ...FIX-Some-regressions-with-Python-3.9.patch |  741 ++
 .../0112-docs-Update-new-and-noteworthy.patch |   84 +
 ...elper-function-to-print-the-current-.patch |  278 +
 ...kin-languages.json-from-cucumber-rep.patch |  541 ++
 ...TE-CHANGES-Related-to-PR-895-and-827.patch |   22 +
 ...r-python-2.7-builds-mock-4.0-only-fo.patch |   39 +
 ...-to-use-a-custom-runner-in-the-behav.patch |  126 +
 ...llow-forcing-color-with-color-always.patch |   59 +
 ...lor-with-no-value-followed-by-posarg.patch |   43 +
 .../0120-Add-BEHAVE_COLOR-env-var.patch       |   31 +
 ...121-fix-malformed-table-rows-warning.patch |   33 +
 ...-955-setup-Remove-attribute-use_2to3.patch |   42 +
 .../0123-Add-info-for-fixed-issue-955.patch   |   21 +
 .../python/python3-behave_1.2.6.bb            |  129 +-
 124 files changed, 29808 insertions(+), 2 deletions(-)
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch
 create mode 100644 meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch

diff --git a/meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch b/meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
new file mode 100644
index 000000000..5c49cc00c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
@@ -0,0 +1,22 @@
+From b941f353c129f73934853082f3f3a01cebe6f944 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 11 Mar 2019 22:37:04 +0100
+Subject: [PATCH] FIXES #725: ScenarioOutlineBuilder was not copying
+ description to created Scenario.
+
+---
+ behave/model.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/behave/model.py b/behave/model.py
+index 4ad4b9d..9dd68fd 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -1196,6 +1196,7 @@ class ScenarioOutlineBuilder(object):
+                 scenario.feature = scenario_outline.feature
+                 scenario.parent = scenario_outline
+                 scenario.background = scenario_outline.background
++                scenario.description = scenario_outline.description
+                 scenario._row = row     # pylint: disable=protected-access
+                 scenarios.append(scenario)
+         return scenarios
diff --git a/meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch b/meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch
new file mode 100644
index 000000000..2be6811fb
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0002-UPDATE-FIXED-725.patch
@@ -0,0 +1,21 @@
+From 0e26bbae1f9f8d60c3ab9470b3685af1dde5b6d8 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 11 Mar 2019 22:40:13 +0100
+Subject: [PATCH] UPDATE: FIXED #725
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index c11840f..d6e96af 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -32,6 +32,7 @@ ENHANCEMENTS:
+ 
+ FIXED:
+ 
++* issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
+ * pull  #657: Allow async steps with timeouts to fail when they raise exceptions (provided by: ALSchwalm)
+ * issue #631: ScenarioOutline variables not possible in table headings (provided by: mschnelle, pull #642)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch b/meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch
new file mode 100644
index 000000000..3e4f6fdf2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch
@@ -0,0 +1,60 @@
+From 66324f8dc74715a5018d1eced225557c40bd7acd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 11 Mar 2019 23:08:00 +0100
+Subject: [PATCH] ADD TEST to verify that issue #725 is fixed.
+
+---
+ tests/issues/test_issue0725.py | 44 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+ create mode 100644 tests/issues/test_issue0725.py
+
+diff --git a/tests/issues/test_issue0725.py b/tests/issues/test_issue0725.py
+new file mode 100644
+index 0000000..7479f59
+--- /dev/null
++++ b/tests/issues/test_issue0725.py
+@@ -0,0 +1,44 @@
++# -*- coding: UTF-8 -*-
++"""
++https://github.com/behave/behave/issues/725
++
++ANALYSIS:
++----------
++
++ScenarioOutlineBuilder did not copy ScenarioOutline.description
++to the Scenarios that were created from the ScenarioOutline.
++"""
++
++from __future__ import absolute_import, print_function
++from behave.parser import parse_feature
++
++
++def test_issue():
++    """Verifies that issue #725 is fixed."""
++    text = u'''
++Feature: ScenarioOutline with description
++
++  Scenario Outline: SO_1
++    Description line 1 for ScenarioOutline.
++    Description line 2 for ScenarioOutline.
++
++    Given a step with "<name>"
++    
++    Examples:
++      | name  |
++      | Alice |
++      | Bob   |
++'''.lstrip()
++    feature = parse_feature(text)
++    assert len(feature.scenarios) == 1
++    scenario_outline_1 = feature.scenarios[0]
++    assert len(scenario_outline_1.scenarios) == 2
++    # -- HINT: Last line triggers building of the Scenarios from ScenarioOutline.
++
++    expected_description = [
++        "Description line 1 for ScenarioOutline.",
++        "Description line 2 for ScenarioOutline.",
++    ]
++    assert scenario_outline_1.description == expected_description
++    assert scenario_outline_1.scenarios[0].description == expected_description
++    assert scenario_outline_1.scenarios[1].description == expected_description
diff --git a/meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch b/meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch
new file mode 100644
index 000000000..ec55efb50
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch
@@ -0,0 +1,342 @@
+From 74d539b86ca52e83255183d96b93ff7492751b6f Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 08:29:02 +0100
+Subject: [PATCH] FIX: SummaryReporter counts computation when Rules are used.
+
+---
+ behave/model.py                               |  39 +++---
+ behave/reporter/summary.py                    | 114 ++++++++++++++----
+ .../unit/{reporters => reporter}/__init__.py  |   0
+ .../{reporters => reporter}/test_summary.py   |   4 +
+ 4 files changed, 116 insertions(+), 41 deletions(-)
+ rename tests/unit/{reporters => reporter}/__init__.py (100%)
+ rename tests/unit/{reporters => reporter}/test_summary.py (99%)
+
+diff --git a/behave/model.py b/behave/model.py
+index 9dd68fd..6238313 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -144,18 +144,18 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         self.hook_failed = False
+         self.run_starttime = 0
+         self.run_endtime = 0
+-        for scenario in self.scenarios:
+-            scenario.reset()
++        for run_item in self.run_items:
++            run_item.reset()
+ 
+     def __iter__(self):
+-        return iter(self.scenarios)
++        return iter(self.run_items)
+ 
+     def add_scenario(self, scenario):
+         feature = getattr(self, "feature", None)
+         if isinstance(self, Feature):
+             feature = self
+ 
+-        scenario.parent = self      # XXX-NEW
++        scenario.parent = self
+         scenario.feature = feature
+         scenario.background = self.background
+         self.scenarios.append(scenario)
+@@ -174,17 +174,17 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+         skipped = True
+         passed_count = 0
+-        for scenario in self.scenarios:
+-            scenario_status = scenario.status
+-            if scenario_status == Status.failed:
++        for run_item in self.run_items:
++            run_item_status = run_item.status
++            if run_item_status == Status.failed:
+                 return Status.failed
+-            elif scenario_status == Status.untested:
++            elif run_item_status == Status.untested:
+                 if passed_count > 0:
+                     return Status.failed  # ABORTED: Some passed, now untested.
+                 return Status.untested
+-            if scenario_status != Status.skipped:
++            if run_item_status != Status.skipped:
+                 skipped = False
+-            if scenario_status == Status.passed:
++            if run_item_status == Status.passed:
+                 passed_count += 1
+ 
+         if skipped:
+@@ -217,14 +217,19 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         """
+         # TODO: Better use self.run_items
+         all_scenarios = []
+-        for scenario in self.scenarios:
+-            if isinstance(scenario, ScenarioOutline):
+-                scenario_outline = scenario
++        # for scenario in self.scenarios:
++        for run_item in self.run_items:
++            if isinstance(run_item, Rule):
++                rule = run_item
++                all_scenarios.extend(rule.walk_scenarios(with_outlines=with_outlines))
++            if isinstance(run_item, ScenarioOutline):
++                scenario_outline = run_item
+                 if with_outlines:
+                     all_scenarios.append(scenario_outline)
+                 all_scenarios.extend(scenario_outline.scenarios)
+             else:
+-                all_scenarios.append(scenario)
++                assert isinstance(run_item, Scenario)
++                all_scenarios.append(run_item)
+         return all_scenarios
+ 
+     def should_run(self, config=None):
+@@ -285,9 +290,9 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         self.clear_status()
+         self.should_skip = True
+         self.skip_reason = reason
+-        for scenario in self.scenarios:
+-            scenario.skip(reason, require_not_executed)
+-        if not self.scenarios:
++        for run_item in self.run_items:
++            run_item.skip(reason, require_not_executed)
++        if not self.run_items:
+             # -- SPECIAL CASE: Feature without scenarios
+             self.set_status(Status.skipped)
+         assert self.status in self.final_status #< skipped, failed or passed.
+diff --git a/behave/reporter/summary.py b/behave/reporter/summary.py
+index c82daa1..2ccdc8f 100644
+--- a/behave/reporter/summary.py
++++ b/behave/reporter/summary.py
+@@ -6,25 +6,52 @@ Provides a summary after each test run.
+ from __future__ import absolute_import, division, print_function
+ import sys
+ from time import time as time_now
+-from behave.model import ScenarioOutline
++from behave.model import Rule, ScenarioOutline  # MAYBE: Scenario
+ from behave.model_core import Status
+ from behave.reporter.base import Reporter
+ from behave.formatter.base import StreamOpener
+ 
+ 
+-# -- DISABLED: optional_steps = ('untested', 'undefined')
+-optional_steps = (Status.untested,) # MAYBE: Status.undefined
+-status_order = (Status.passed, Status.failed, Status.skipped,
++# ---------------------------------------------------------------------------
++# CONSTANTS:
++# ---------------------------------------------------------------------------
++# -- DISABLED: OPTIONAL_STEPS = ('untested', 'undefined')
++OPTIONAL_STEPS = (Status.untested,) # MAYBE: Status.undefined
++STATUS_ORDER = (Status.passed, Status.failed, Status.skipped,
+                 Status.undefined, Status.untested)
+ 
+ 
+-def format_summary(statement_type, summary):
++# ---------------------------------------------------------------------------
++# UTILITY FUNCTIONS:
++# ---------------------------------------------------------------------------
++def pluralize(word, count=1, suffix="s"):
++    if count == 1:
++        return word
++    # -- OTHERWISE:
++    return "{0}{1}".format(word, suffix)
++
++
++def compute_summary_sum(summary):
++    """Compute sum of all summary counts (except: all)
++
++    :param summary: Summary counts (as dict).
++    :return: Sum of all counts (as integer).
++    """
++    counts_sum = 0
++    for name, count in summary.items():
++        if name == "all":
++            continue    # IGNORE IT.
++        counts_sum += count
++    return counts_sum
++
++
++def format_summary0(statement_type, summary):
+     parts = []
+-    for status in status_order:
++    for status in STATUS_ORDER:
+         if status.name not in summary:
+             continue
+         counts = summary[status.name]
+-        if status in optional_steps and counts == 0:
++        if status in OPTIONAL_STEPS and counts == 0:
+             # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
+             continue
+ 
+@@ -40,11 +67,23 @@ def format_summary(statement_type, summary):
+     return ", ".join(parts) + "\n"
+ 
+ 
+-def pluralize(word, count=1, suffix="s"):
+-    if count == 1:
+-        return word
+-    # -- OTHERWISE:
+-    return "{0}{1}".format(word, suffix)
++def format_summary(statement_type, summary):
++    parts = []
++    for status in STATUS_ORDER:
++        if status.name not in summary:
++            continue
++        counts = summary[status.name]
++        if status in OPTIONAL_STEPS and counts == 0:
++            # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
++            continue
++
++        name = status.name
++        if status.name == "passed":
++            statement = pluralize(statement_type, counts)
++            name = u"%s passed" % statement
++        part = u"%d %s" % (counts, name)
++        parts.append(part)
++    return ", ".join(parts) + "\n"
+ 
+ 
+ # -- PREPARED:
+@@ -60,18 +99,16 @@ def format_summary2(statement_type, summary, end="\n"):
+     :return:
+     """
+     parts = []
+-    counts_sum = 0
+-    for status in status_order:
++    for status in STATUS_ORDER:
+         if status.name not in summary:
+             continue
+         counts = summary[status.name]
+-        if status in optional_steps and counts == 0:
++        if status in OPTIONAL_STEPS and counts == 0:
+             # -- SHOW-ONLY: For relevant counts, suppress: untested items, etc.
+             continue
+-
+-        counts_sum += counts
+         parts.append((status.name, counts))
+ 
++    counts_sum = summary["all"]
+     statement = pluralize(statement_type, sum)
+     parts_text = ", ".join(["{0}: {1}".format(name, value)
+                             for name, value in parts])
+@@ -79,6 +116,9 @@ def format_summary2(statement_type, summary, end="\n"):
+         count=counts_sum, statement=statement, parts=parts_text, end=end)
+ 
+ 
++# ---------------------------------------------------------------------------
++# REPORTERS:
++# ---------------------------------------------------------------------------
+ class SummaryReporter(Reporter):
+     show_failed_scenarios = True
+     output_stream_name = "stdout"
+@@ -88,6 +128,7 @@ class SummaryReporter(Reporter):
+         stream = getattr(sys, self.output_stream_name, sys.stderr)
+         self.stream = StreamOpener.ensure_stream_with_encoder(stream)
+         summary_zero_data = {
++            "all": 0,
+             Status.passed.name: 0,
+             Status.failed.name: 0,
+             Status.skipped.name: 0,
+@@ -122,10 +163,22 @@ class SummaryReporter(Reporter):
+         for scenario in self.failed_scenarios:
+             stream.write(u"  %s  %s\n" % (scenario.location, scenario.name))
+ 
++    def compute_summary_sums(self):
++        """(Re)Compute summary sum of all counts (except: all)."""
++        summaries = [
++            self.feature_summary,
++            self.rule_summary,
++            self.scenario_summary,
++            self.step_summary
++        ]
++        for summary in summaries:
++            summary["all"] = compute_summary_sum(summary)
++
+     def print_summary(self, stream=None, with_duration=True):
+         if stream is None:
+             stream = self.stream
+ 
++        self.compute_summary_sums()
+         stream.write(format_summary("feature", self.feature_summary))
+         rules_summary = format_summary("rule", self.rule_summary)
+         if self.show_rules and not rules_summary.strip().startswith("0"):
+@@ -145,13 +198,7 @@ class SummaryReporter(Reporter):
+             # -- DISCOVER: TEST-RUN started.
+             self.testrun_started()
+ 
+-        self.feature_summary[feature.status.name] += 1
+-        self.duration += feature.duration
+-        for scenario in feature:
+-            if isinstance(scenario, ScenarioOutline):
+-                self.process_scenario_outline(scenario)
+-            else:
+-                self.process_scenario(scenario)
++        self.process_feature(feature)
+ 
+     def end(self):
+         self.testrun_finished()
+@@ -164,6 +211,25 @@ class SummaryReporter(Reporter):
+         # -- SHOW SUMMARY COUNTS:
+         self.print_summary()
+ 
++    def process_run_items_for(self, parent):
++        for run_item in parent:
++            if isinstance(run_item, Rule):
++                self.process_rule(run_item)
++            elif isinstance(run_item, ScenarioOutline):
++                self.process_scenario_outline(run_item)
++            else:
++                # assert isinstance(run_item, Scenario)
++                self.process_scenario(run_item)
++
++    def process_feature(self, feature):
++        self.duration += feature.duration
++        self.feature_summary[feature.status.name] += 1
++        self.process_run_items_for(feature)
++
++    def process_rule(self, rule):
++        self.rule_summary[rule.status.name] += 1
++        self.process_run_items_for(rule)
++
+     def process_scenario(self, scenario):
+         if scenario.status == Status.failed:
+             self.failed_scenarios.append(scenario)
+diff --git a/tests/unit/reporters/__init__.py b/tests/unit/reporter/__init__.py
+similarity index 100%
+rename from tests/unit/reporters/__init__.py
+rename to tests/unit/reporter/__init__.py
+diff --git a/tests/unit/reporters/test_summary.py b/tests/unit/reporter/test_summary.py
+similarity index 99%
+rename from tests/unit/reporters/test_summary.py
+rename to tests/unit/reporter/test_summary.py
+index 02154db..97adbb5 100644
+--- a/tests/unit/reporters/test_summary.py
++++ b/tests/unit/reporter/test_summary.py
+@@ -120,6 +120,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 5,
+             Status.passed.name: 2,
+             Status.failed.name: 1,
+             Status.skipped.name: 1,
+@@ -156,6 +157,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 5,
+             Status.passed.name: 1,
+             Status.failed.name: 2,
+             Status.skipped.name: 1,
+@@ -201,6 +203,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 7,
+             Status.passed.name: 2,
+             Status.failed.name: 3,
+             Status.skipped.name: 2,
+@@ -241,6 +244,7 @@ class TestSummaryReporter(object):
+         reporter.end()
+ 
+         expected = {
++            "all": 5,
+             Status.passed.name: 2,
+             Status.failed.name: 1,
+             Status.skipped.name: 1,
diff --git a/meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch b/meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch
new file mode 100644
index 000000000..2cbf02925
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch
@@ -0,0 +1,60 @@
+From db1ead991924fb71d87e02aa43ffa73eae60594e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 08:41:37 +0100
+Subject: [PATCH] SummaryReporter.print_summary: Simplify if Rules are used.
+
+---
+ behave/reporter/summary.py          | 7 ++++---
+ tests/unit/reporter/test_summary.py | 6 +++---
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/behave/reporter/summary.py b/behave/reporter/summary.py
+index 2ccdc8f..09285ea 100644
+--- a/behave/reporter/summary.py
++++ b/behave/reporter/summary.py
+@@ -179,11 +179,12 @@ class SummaryReporter(Reporter):
+             stream = self.stream
+ 
+         self.compute_summary_sums()
++        has_rules = (self.rule_summary["all"] > 0)
++
+         stream.write(format_summary("feature", self.feature_summary))
+-        rules_summary = format_summary("rule", self.rule_summary)
+-        if self.show_rules and not rules_summary.strip().startswith("0"):
++        if self.show_rules and has_rules:
+             # -- HINT: Show only rules, if any exists.
+-            self.stream.write(rules_summary)
++            self.stream.write(format_summary("rule", self.rule_summary))
+         stream.write(format_summary("scenario", self.scenario_summary))
+         stream.write(format_summary("step", self.step_summary))
+ 
+diff --git a/tests/unit/reporter/test_summary.py b/tests/unit/reporter/test_summary.py
+index 97adbb5..d4e85b5 100644
+--- a/tests/unit/reporter/test_summary.py
++++ b/tests/unit/reporter/test_summary.py
+@@ -164,7 +164,7 @@ class TestSummaryReporter(object):
+             Status.untested.name: 1,
+         }
+ 
+-        scenario_index = 2
++        scenario_index = 1  # -- HINT: Index for scenarios if no Rules are used.
+         expected_parts = ("scenario", expected)
+         assert format_summary.call_args_list[scenario_index][0] == expected_parts
+ 
+@@ -209,7 +209,7 @@ class TestSummaryReporter(object):
+             Status.skipped.name: 2,
+             Status.untested.name: 0,
+         }
+-        scenario_index = 2
++        scenario_index = 1  # -- HINT: Index for scenarios if no Rules are used.
+         expected_parts = ("scenario", expected)
+         assert format_summary.call_args_list[scenario_index][0] == expected_parts
+ 
+@@ -252,6 +252,6 @@ class TestSummaryReporter(object):
+             Status.undefined.name: 1,
+         }
+ 
+-        step_index = 3
++        step_index = 2  # HINT: Index for steps if not rules are used.
+         expected_parts = ("step", expected)
+         assert format_summary.call_args_list[step_index][0] == expected_parts
diff --git a/meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch b/meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch
new file mode 100644
index 000000000..bcfe315bf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0006-Formatter-Add-basic-support-output-for-Rules.patch
@@ -0,0 +1,395 @@
+From 24811b631e0eed92347880f1dac3f932f4b46f9d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 23:08:19 +0100
+Subject: [PATCH] Formatter: Add basic support/output for Rules.
+
+---
+ behave/formatter/base.py     | 18 +++++------
+ behave/formatter/plain.py    | 63 +++++++++++++++++++++++++++++-------
+ behave/formatter/pretty.py   | 33 +++++++++++++++----
+ behave/formatter/progress.py | 18 ++++++++++-
+ behave/model.py              | 14 ++++----
+ 5 files changed, 110 insertions(+), 36 deletions(-)
+
+diff --git a/behave/formatter/base.py b/behave/formatter/base.py
+index f7268fa..a8b9f7c 100644
+--- a/behave/formatter/base.py
++++ b/behave/formatter/base.py
+@@ -129,15 +129,6 @@ class Formatter(object):
+         """
+         pass
+ 
+-    def background(self, background):
+-        """Called when a (Feature) Background is provided.
+-        Called after :method:`feature()` is called.
+-        Called before processing any scenarios or scenario outlines.
+-
+-        :param background:  Background object (as :class:`behave.model.Background`)
+-        """
+-        pass
+-
+     def rule(self, rule):
+         """Called before a rule is executed.
+ 
+@@ -153,6 +144,15 @@ class Formatter(object):
+     #     """
+     #     pass
+ 
++    def background(self, background):
++        """Called when a (Feature) Background is provided.
++        Called after :method:`feature()` is called.
++        Called before processing any scenarios or scenario outlines.
++
++        :param background:  Background object (as :class:`behave.model.Background`)
++        """
++        pass
++
+     def scenario(self, scenario):
+         """Called before a scenario is executed (or ScenarioOutline scenarios).
+ 
+diff --git a/behave/formatter/plain.py b/behave/formatter/plain.py
+index 9f1f833..e720829 100644
+--- a/behave/formatter/plain.py
++++ b/behave/formatter/plain.py
+@@ -23,6 +23,8 @@ class PlainFormatter(Formatter):
+ 
+     SHOW_MULTI_LINE = True
+     SHOW_TAGS = False
++    SHOW_RULES = True
++    SHOW_BACKGROUNDS = True
+     SHOW_ALIGNED_KEYWORDS = False
+     DEFAULT_INDENT_SIZE = 2
+     RAISE_OUTPUT_ERRORS = True
+@@ -35,6 +37,7 @@ class PlainFormatter(Formatter):
+         self.show_aligned_keywords = self.SHOW_ALIGNED_KEYWORDS
+         self.show_tags = self.SHOW_TAGS
+         self.indent_size = self.DEFAULT_INDENT_SIZE
++        self.current_rule = None
+         # -- ENSURE: Output stream is open.
+         self.stream = self.open()
+         self.printer = ModelPrinter(self.stream)
+@@ -49,6 +52,10 @@ class PlainFormatter(Formatter):
+                 offset = 2
+             indentation = make_indentation(3 * self.indent_size + offset)
+             self._multiline_indentation = indentation
++
++        if self.current_rule:
++            indent_extra = make_indentation(self.indent_size)
++            return self._multiline_indentation + indent_extra
+         return self._multiline_indentation
+ 
+     def reset_steps(self):
+@@ -60,37 +67,69 @@ class PlainFormatter(Formatter):
+             text = " @".join(tags)
+             self.stream.write(u"%s@%s\n" % (indent, text))
+ 
++    def write_entity(self, entity, indent="", has_tags=True):
++        if has_tags:
++            self.write_tags(entity.tags, indent)
++        text = u"%s%s: %s\n" % (indent, entity.keyword, entity.name)
++        self.stream.write(text)
++
+     # -- IMPLEMENT-INTERFACE FOR: Formatter
+     def feature(self, feature):
++        self.current_rule = None
+         self.reset_steps()
+-        self.write_tags(feature.tags)
+-        self.stream.write(u"%s: %s\n" % (feature.keyword, feature.name))
++        self.write_entity(feature)
++        # self.write_tags(feature.tags)
++        # self.stream.write(u"%s: %s\n" % (feature.keyword, feature.name))
+ 
+-    def background(self, background):
++    def rule(self, rule):
++        self.current_rule = rule
+         self.reset_steps()
+         indent = make_indentation(self.indent_size)
+-        text = u"%s%s: %s\n" % (indent, background.keyword, background.name)
+-        self.stream.write(text)
++        self.stream.write(u"\n")
++        self.write_entity(rule, indent)
++        # self.stream.write(u"%s%s: %s\n" % (indent, rule.keyword, rule.name))
++
++    def background(self, background):
++        self.reset_steps()
++        if not self.SHOW_BACKGROUNDS:
++            return
++
++        indent_extra = 0
++        if self.current_rule:
++            indent_extra = self.indent_size
++
++        indent = make_indentation(self.indent_size + indent_extra)
++        self.write_entity(background, indent, has_tags=False)
++        # text = u"%s%s: %s\n" % (indent, background.keyword, background.name)
++        # self.stream.write(text)
+ 
+     def scenario(self, scenario):
++        indent_extra = 0
++        if self.current_rule:
++            indent_extra = self.indent_size
++
+         self.reset_steps()
+         self.stream.write(u"\n")
+-        indent = make_indentation(self.indent_size)
+-        text = u"%s%s: %s\n" % (indent, scenario.keyword, scenario.name)
+-        self.write_tags(scenario.tags, indent)
+-        self.stream.write(text)
++        indent = make_indentation(self.indent_size + indent_extra)
++        self.write_entity(scenario, indent)
++        # text = u"%s%s: %s\n" % (indent, scenario.keyword, scenario.name)
++        # self.write_tags(scenario.tags, indent)
++        # self.stream.write(text)
+ 
+     def step(self, step):
+         self.steps.append(step)
+ 
+     def result(self, step):
+-        """
+-        Process the result of a step (after step execution).
++        """Process the result of a step (after step execution).
+ 
+         :param step:   Step object with result to process.
+         """
++        indent_extra = 0
++        if self.current_rule:
++            indent_extra = self.indent_size
++
+         step = self.steps.pop(0)
+-        indent = make_indentation(2 * self.indent_size)
++        indent = make_indentation(2 * self.indent_size + indent_extra)
+         if self.show_aligned_keywords:
+             # -- RIGHT-ALIGN KEYWORDS (max. keyword width: 6):
+             text = u"%s%6s %s ... " % (indent, step.keyword, step.name)
+diff --git a/behave/formatter/pretty.py b/behave/formatter/pretty.py
+index b6f0eac..794e1d7 100644
+--- a/behave/formatter/pretty.py
++++ b/behave/formatter/pretty.py
+@@ -6,7 +6,7 @@ from behave.formatter.ansi_escapes import escapes, up
+ from behave.formatter.base import Formatter
+ from behave.model_core import Status
+ from behave.model_describe import escape_cell, escape_triple_quotes
+-from behave.textutil import indent, text as _text
++from behave.textutil import indent, make_indentation, text as _text
+ import six
+ from six.moves import range, zip
+ 
+@@ -86,6 +86,7 @@ class PrettyFormatter(Formatter):
+ 
+     def reset(self):
+         # -- UNUSED: self.tag_statement = None
++        self.current_rule = None
+         self.steps = []
+         self._uri = None
+         self._match = None
+@@ -99,7 +100,9 @@ class PrettyFormatter(Formatter):
+ 
+     def feature(self, feature):
+         #self.print_comments(feature.comments, '')
+-        self.print_tags(feature.tags, '')
++        self.current_rule = None
++        prefix = ""
++        self.print_tags(feature.tags, prefix)
+         self.stream.write(u"%s: %s" % (feature.keyword, feature.name))
+         if self.show_source:
+             # pylint: disable=redefined-builtin
+@@ -109,6 +112,11 @@ class PrettyFormatter(Formatter):
+         self.print_description(feature.description, "  ", False)
+         self.stream.flush()
+ 
++    def rule(self, rule):
++        self.replay()
++        self.current_rule = rule
++        self.statement = rule
++
+     def background(self, background):
+         self.replay()
+         self.statement = background
+@@ -176,6 +184,10 @@ class PrettyFormatter(Formatter):
+         self.stream.flush()
+ 
+     def table(self, table):
++        prefix = u"      "
++        if self.current_rule:
++            prefix += u"  "
++
+         cell_lengths = []
+         all_rows = [table.headings] + table.rows
+         for row in all_rows:
+@@ -189,7 +201,7 @@ class PrettyFormatter(Formatter):
+         for i, row in enumerate(all_rows):
+             #for comment in row.comments:
+             #    self.stream.write("      %s\n" % comment.value)
+-            self.stream.write("      |")
++            self.stream.write(u"%s|" % prefix)
+             for j, (cell, max_length) in enumerate(zip(row, max_lengths)):
+                 self.stream.write(" ")
+                 self.stream.write(self.color(cell, None, j))
+@@ -202,6 +214,8 @@ class PrettyFormatter(Formatter):
+         #self.stream.write('      """' + doc_string.content_type + '\n')
+         doc_string = _text(doc_string)
+         prefix = u"      "
++        if self.current_rule:
++            prefix += u"  "
+         self.stream.write(u'%s"""\n' % prefix)
+         doc_string = escape_triple_quotes(indent(doc_string, prefix))
+         self.stream.write(doc_string)
+@@ -251,12 +265,16 @@ class PrettyFormatter(Formatter):
+         if self.statement is None:
+             return
+ 
++        prefix = u"  "
++        if self.current_rule and self.statement.type != "rule":
++            prefix += prefix
++
+         self.calculate_location_indentations()
+         self.stream.write(u"\n")
+         #self.print_comments(self.statement.comments, "  ")
+         if hasattr(self.statement, "tags"):
+-            self.print_tags(self.statement.tags, u"  ")
+-        self.stream.write(u"  %s: %s " % (self.statement.keyword,
++            self.print_tags(self.statement.tags, prefix)
++        self.stream.write(u"%s%s: %s " % (prefix, self.statement.keyword,
+                                           self.statement.name))
+ 
+         location = self.indented_text(six.text_type(self.statement.location), True)
+@@ -279,8 +297,11 @@ class PrettyFormatter(Formatter):
+         text_format = self.format(status.name)
+         arg_format = self.arg_format(status.name)
+ 
++        prefix = u"    "
++        if self.current_rule:
++            prefix += u"  "
+         #self.print_comments(step.comments, "    ")
+-        self.stream.write("    ")
++        self.stream.write(prefix)
+         self.stream.write(text_format.text(step.keyword + " "))
+         line_length = 5 + len(step.keyword)
+ 
+diff --git a/behave/formatter/progress.py b/behave/formatter/progress.py
+index 6d8adf6..3b471ed 100644
+--- a/behave/formatter/progress.py
++++ b/behave/formatter/progress.py
+@@ -43,6 +43,7 @@ class ProgressFormatterBase(Formatter):
+         self.steps = []
+         self.failures = []
+         self.current_feature = None
++        self.current_rule = None
+         self.current_scenario = None
+         self.show_timings = config.show_timings and self.show_timings
+ 
+@@ -50,14 +51,19 @@ class ProgressFormatterBase(Formatter):
+         self.steps = []
+         self.failures = []
+         self.current_feature = None
++        self.current_rule = None
+         self.current_scenario = None
+ 
+     # -- FORMATTER API:
+     def feature(self, feature):
++        self.current_rule = None
+         self.current_feature = feature
+         self.stream.write("%s  " % six.text_type(feature.filename))
+         self.stream.flush()
+ 
++    def rule(self, rule):
++        self.current_rule = rule
++
+     def background(self, background):
+         pass
+ 
+@@ -219,9 +225,16 @@ class ScenarioStepProgressFormatter(StepProgressFormatter):
+ 
+     # -- FORMATTER API:
+     def feature(self, feature):
++        self.current_rule = None
+         self.current_feature = feature
+         self.stream.write(u"%s    # %s" % (feature.name, feature.filename))
+ 
++    def rule(self, rule):
++        self.current_rule = rule
++        self.stream.write(u"\n\n  %s: %s    # %s" %
++                          (rule.keyword, rule.name, rule.location))
++        self.stream.flush()
++
+     def scenario(self, scenario):
+         """Process the next scenario."""
+         # -- LAST SCENARIO: Report failures (if any).
+@@ -231,9 +244,12 @@ class ScenarioStepProgressFormatter(StepProgressFormatter):
+         assert not self.failures
+         self.current_scenario = scenario
+         scenario_name = scenario.name
++        prefix = self.scenario_prefix
++        if self.current_rule:
++            prefix += u"  "
+         if scenario_name:
+             scenario_name += " "
+-        self.stream.write(u"%s%s " % (self.scenario_prefix, scenario_name))
++        self.stream.write(u"%s%s " % (prefix, scenario_name))
+         self.stream.flush()
+ 
+     # -- DISABLED:
+diff --git a/behave/model.py b/behave/model.py
+index 6238313..3084850 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -318,10 +318,10 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         runner.context.tags = set(self.tags)
+ 
+         skip_entity_untested = runner.aborted
+-        run_entity = self.should_run(runner.config)
++        should_run_entity = self.should_run(runner.config)
+         failed_count = 0
+         hooks_called = False
+-        if not runner.config.dry_run and run_entity:
++        if not runner.config.dry_run and should_run_entity:
+             hooks_called = True
+             for tag in self.tags:
+                 runner.run_hook("before_tag", runner.context, tag)
+@@ -332,10 +332,10 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+             # -- RE-EVALUATE SHOULD-RUN STATE:
+             # Hook may call entity.mark_skipped() to exclude it.
+             skip_entity_untested = self.hook_failed or runner.aborted
+-            run_entity = self.should_run()
++            should_run_entity = self.should_run()
+ 
+         # run this entity if the tags say so or any one of its scenarios
+-        if run_entity or runner.config.show_skipped:
++        if should_run_entity or runner.config.show_skipped:
+             for formatter in runner.formatters:
+                 formatter_callback = getattr(formatter, entity_name, None)
+                 if formatter_callback:
+@@ -363,7 +363,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+                         break
+ 
+         self.clear_status()  # -- ENFORCE: compute_status() after run.
+-        if not self.run_items and not run_entity:
++        if not self.run_items and not should_run_entity:
+             # -- SPECIAL CASE: Feature without scenarios
+             self.set_status(Status.skipped)
+ 
+@@ -382,7 +382,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+             # -- CLEANUP-ERROR:
+             self.set_status(Status.failed)
+ 
+-        if run_entity or runner.config.show_skipped:
++        if should_run_entity or runner.config.show_skipped:
+             callback_name = "{0}_finished".format(entity_name)
+             if entity_name == "feature":
+                 callback_name = "eof"
+@@ -608,7 +608,6 @@ class Rule(ScenarioContainer):
+     .. versionadded:: 1.2.7
+     .. _`feature`: gherkin.html#rule
+     """
+-
+     type = "rule"
+ 
+     def __init__(self, filename, line, keyword, name, tags=None,
+@@ -625,7 +624,6 @@ class Rule(ScenarioContainer):
+             (self.name, len(self.scenarios))
+ 
+ 
+-
+ class Background(BasicStatement, Replayable):
+     """A `background`_ parsed from a *feature file*.
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch b/meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch
new file mode 100644
index 000000000..b8e804269
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch
@@ -0,0 +1,67 @@
+From 19a4134596217540832ed394d790d7b509ec865a Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 13 Mar 2019 23:11:50 +0100
+Subject: [PATCH] BUMP-VERSION: 1.2.7.dev1 (was: 1.2.7.dev0)
+
+---
+ .bumpversion.cfg   | 2 +-
+ VERSION.txt        | 2 +-
+ behave/__init__.py | 2 +-
+ pytest.ini         | 2 +-
+ setup.py           | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/.bumpversion.cfg b/.bumpversion.cfg
+index f387d43..ac913c2 100644
+--- a/.bumpversion.cfg
++++ b/.bumpversion.cfg
+@@ -1,5 +1,5 @@
+ [bumpversion]
+-current_version = 1.2.7.dev0
++current_version = 1.2.7.dev1
+ files = behave/__init__.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
+ parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<drop>\w*)
+ serialize = {major}.{minor}.{patch}{drop}
+diff --git a/VERSION.txt b/VERSION.txt
+index 4e63eef..c0ef36b 100644
+--- a/VERSION.txt
++++ b/VERSION.txt
+@@ -1 +1 @@
+-1.2.7.dev0
++1.2.7.dev1
+diff --git a/behave/__init__.py b/behave/__init__.py
+index 8888355..31e4e55 100644
+--- a/behave/__init__.py
++++ b/behave/__init__.py
+@@ -29,4 +29,4 @@ __all__ = [
+     # -- DEPRECATING:
+     "step_matcher"
+ ]
+-__version__ = "1.2.7.dev0"
++__version__ = "1.2.7.dev1"
+diff --git a/pytest.ini b/pytest.ini
+index 70e10cd..17ad388 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -20,7 +20,7 @@ minversion    = 2.8
+ testpaths     = test tests
+ python_files  = test_*.py
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+-    --metadata PACKAGE_VERSION 1.2.7.dev0
++    --metadata PACKAGE_VERSION 1.2.7.dev1
+     --html=build/testing/report.html --self-contained-html
+     --junit-xml=build/testing/report.xml
+ markers =
+diff --git a/setup.py b/setup.py
+index cb3b338..c5af262 100644
+--- a/setup.py
++++ b/setup.py
+@@ -55,7 +55,7 @@ def find_packages_by_root_package(where):
+ # -----------------------------------------------------------------------------
+ setup(
+     name="behave",
+-    version="1.2.7.dev0",
++    version="1.2.7.dev1",
+     description="behave is behaviour-driven development, Python style",
+     long_description=description,
+     author="Jens Engel, Benno Rice and Richard Jones",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch b/meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch
new file mode 100644
index 000000000..9ab6cee15
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0008-Correct-examples-and-docstring.patch
@@ -0,0 +1,41 @@
+From 29d3ef4d3ff8c836bc592b92687a28bf873d0e0c Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 14 Mar 2019 22:14:54 +0100
+Subject: [PATCH] Correct examples and docstring
+
+---
+ behave/contrib/scenario_autoretry.py | 2 +-
+ behave/formatter/base.py             | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/behave/contrib/scenario_autoretry.py b/behave/contrib/scenario_autoretry.py
+index 2b7f94f..2592d10 100644
+--- a/behave/contrib/scenario_autoretry.py
++++ b/behave/contrib/scenario_autoretry.py
+@@ -24,7 +24,7 @@ EXAMPLE:
+     from behave.contrib.scenario_autoretry import patch_scenario_with_autoretry
+ 
+     def before_feature(context, feature):
+-        for scenario in feature.scenarios:
++        for scenario in feature.walk_scenarios():
+             if "autoretry" in scenario.effective_tags:
+                 patch_scenario_with_autoretry(scenario, max_attempts=2)
+ 
+diff --git a/behave/formatter/base.py b/behave/formatter/base.py
+index a8b9f7c..7f59ad4 100644
+--- a/behave/formatter/base.py
++++ b/behave/formatter/base.py
+@@ -74,11 +74,12 @@ class Formatter(object):
+ 
+     Processing Logic (simplified, without ScenarioOutline and skip logic)::
+ 
++        # -- HINT: Rule processing is missing.
+         for feature in runner.features:
+             formatter = make_formatters(...)
+             formatter.uri(feature.filename)
+             formatter.feature(feature)
+-            for scenario in feature.scenarios:
++            for scenario in feature.walk_scenarios():
+                 formatter.scenario(scenario)
+                 for step in scenario.all_steps:
+                     formatter.step(step)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch b/meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch
new file mode 100644
index 000000000..0c70cc566
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0009-FIX-feature.run_items-processing-with-Rule-s.patch
@@ -0,0 +1,58 @@
+From dee5266820aabcfe09d103cf007bb26b9db54849 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 14 Mar 2019 22:15:34 +0100
+Subject: [PATCH] FIX: feature.run_items processing with Rule(s).
+
+---
+ behave/reporter/junit.py | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/behave/reporter/junit.py b/behave/reporter/junit.py
+index 48e1411..9018399 100644
+--- a/behave/reporter/junit.py
++++ b/behave/reporter/junit.py
+@@ -75,7 +75,7 @@ import codecs
+ from xml.etree import ElementTree
+ from datetime import datetime
+ from behave.reporter.base import Reporter
+-from behave.model import Scenario, ScenarioOutline, Step
++from behave.model import Rule, Scenario, ScenarioOutline, Step
+ from behave.model_core import Status
+ from behave.formatter import ansi_escapes
+ from behave.model_describe import ModelDescriptor
+@@ -236,13 +236,8 @@ class JUnitReporter(Reporter):
+         feature_name = feature.name or feature_filename
+         suite.set(u'name', u'%s.%s' % (classname, feature_name))
+ 
+-        # -- BUILD-TESTCASES: From scenarios
+-        for scenario in feature:
+-            if isinstance(scenario, ScenarioOutline):
+-                scenario_outline = scenario
+-                self._process_scenario_outline(scenario_outline, report)
+-            else:
+-                self._process_scenario(scenario, report)
++        # -- BUILD-TESTCASES: From run_items (and scenarios)
++        self._process_run_items_for(feature, report)
+ 
+         # -- ADD TESTCASES to testsuite:
+         for testcase in report.testcases:
+@@ -457,6 +452,19 @@ class JUnitReporter(Reporter):
+         if scenario.status != Status.skipped or self.show_skipped:
+             report.testcases.append(case)
+ 
++    def _process_run_items_for(self, parent, report):
++        for run_item in parent.run_items:
++            if isinstance(run_item, Rule):
++                self._process_rule(run_item, report)
++            elif isinstance(run_item, ScenarioOutline):
++                self._process_scenario_outline(run_item, report)
++            else:
++                assert isinstance(run_item, Scenario)
++                self._process_scenario(run_item, report)
++
++    def _process_rule(self, rule, report):
++        self._process_run_items_for(rule, report)
++
+     def _process_scenario_outline(self, scenario_outline, report):
+         assert isinstance(scenario_outline, ScenarioOutline)
+         for scenario in scenario_outline:
diff --git a/meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch b/meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch
new file mode 100644
index 000000000..122b7e9f2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch
@@ -0,0 +1,58 @@
+From b4a40c4df5872b0c9c7293b3a9fa057e208361d6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 26 May 2019 14:40:38 +0200
+Subject: [PATCH] docs: Disable sphinx-intl support for READTHEDOCS.
+
+---
+ docs/conf.py | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index d38db7a..f9dfb6a 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -3,6 +3,7 @@
+ # SPHINX CONFIGURATION: behave documentation build configuration file
+ # =============================================================================
+ 
++from __future__ import print_function
+ import os.path
+ import sys
+ import importlib
+@@ -13,6 +14,13 @@ import importlib
+ # documentation root, use os.path.abspath to make it absolute, like shown here.
+ sys.path.insert(0, os.path.abspath(".."))
+ 
++# ------------------------------------------------------------------------------
++# DETECT BUILD CONTEXT
++# ------------------------------------------------------------------------------
++ON_READTHEDOCS = os.environ.get("READTHEDOCS", None) == "True"
++USE_SPHINX_INTERNATIONAL = not ON_READTHEDOCS
++
++
+ # ------------------------------------------------------------------------------
+ # EXTENSIONS CONFIGURATION
+ # ------------------------------------------------------------------------------
+@@ -82,8 +90,10 @@ master_doc = "index"
+ # -- MULTI-LANGUAGE SUPPORT: en, ...
+ # SEE: https://pypi.org/project/sphinx-intl/
+ # SEE: https://github.com/sphinx-doc/sphinx-intl/
+-locale_dirs = ["locale/"]   # path is example but recommended.
+-gettext_compact = False     # optional.
++if USE_SPHINX_INTERNATIONAL:
++    locale_dirs = ["locale/"]   # path is example but recommended.
++    gettext_compact = False     # optional.
++    print("USE SPHINX-INTL: locale_dirs=%s" % ",".join(locale_dirs))
+ 
+ # STEPS:
+ #   make gettext
+@@ -155,8 +165,7 @@ todo_include_todos = False
+ html_theme = "kr"
+ html_theme = "bootstrap"
+ 
+-on_rtd = os.environ.get("READTHEDOCS", None) == "True"
+-if on_rtd:
++if ON_READTHEDOCS:
+     html_theme = "default"
+ 
+ if html_theme == "bootstrap":
diff --git a/meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch b/meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch
new file mode 100644
index 000000000..726402a8e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0011-Cleanup-Dependent-package-versions-in-requirements.patch
@@ -0,0 +1,81 @@
+From ffbd9840d2c2e273a0ce2ea8fe20afad034bdeb2 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 18 Apr 2019 19:02:43 +0200
+Subject: [PATCH] Cleanup: Dependent package versions in requirements.
+
+---
+ py.requirements/basic.txt   | 2 +-
+ py.requirements/develop.txt | 4 ++--
+ py.requirements/testing.txt | 2 +-
+ setup.py                    | 6 +++---
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index 9eebcad..3b71bfb 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -11,7 +11,7 @@
+ cucumber-tag-expressions >= 1.1.1
+ parse >= 1.8.2
+ parse_type >= 0.4.2
+-six >= 1.11.0
++six >= 1.12.0
+ 
+ traceback2;  python_version < '3.0'
+ contextlib2     # MAYBE: python_version < '3.5'
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index c55d3cd..3deedc7 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -5,8 +5,8 @@
+ # -- BUILD-TOOL:
+ # PREPARE USAGE: invoke
+ # ALREADY: six >= 1.11.0
+-invoke >= 0.21.0
+-path.py >= 10.1
++invoke >= 1.2.0
++path.py >= 11.5.0
+ pathlib;    python_version <= '3.4'
+ pycmd
+ 
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 5876e29..3806d39 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -12,4 +12,4 @@ PyHamcrest >= 1.9
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+-path.py >= 10.1
++path.py >= 11.5.0
+diff --git a/setup.py b/setup.py
+index c5af262..ac7bddf 100644
+--- a/setup.py
++++ b/setup.py
+@@ -79,7 +79,7 @@ setup(
+         "cucumber-tag-expressions >= 1.1.1",
+         "parse >= 1.8.2",
+         "parse_type >= 0.4.2",
+-        "six >= 1.11.0",
++        "six >= 1.12.0",
+         "traceback2; python_version < '3.0'",
+         "enum34; python_version < '3.4'",
+         # -- PREPARED:
+@@ -93,7 +93,7 @@ setup(
+         "nose >= 1.3",
+         "mock >= 1.1",
+         "PyHamcrest >= 1.8",
+-        "path.py >= 10.1"
++        "path.py >= 11.5.0"
+     ],
+     cmdclass = {
+         "behave_test": behave_test,
+@@ -110,7 +110,7 @@ setup(
+             "pytest-cov",
+             "tox",
+             "invoke >= 1.2.0",
+-            "path.py >= 10.1",
++            "path.py >= 11.5.0",
+             "pycmd",
+             "pathlib; python_version <= '3.4'",
+             "modernize >= 0.5",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch
new file mode 100644
index 000000000..22c6c6bb6
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0012-docs-conf.py-tweaks.patch
@@ -0,0 +1,30 @@
+From 430d19123b3a7adc21075b1befda8b550b7eb641 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 26 May 2019 14:55:20 +0200
+Subject: [PATCH] docs: conf.py tweaks.
+
+---
+ docs/conf.py | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index f9dfb6a..f7c2c24 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -18,7 +18,7 @@ sys.path.insert(0, os.path.abspath(".."))
+ # DETECT BUILD CONTEXT
+ # ------------------------------------------------------------------------------
+ ON_READTHEDOCS = os.environ.get("READTHEDOCS", None) == "True"
+-USE_SPHINX_INTERNATIONAL = not ON_READTHEDOCS
++USE_SPHINX_INTERNATIONAL = True
+ 
+ 
+ # ------------------------------------------------------------------------------
+@@ -164,7 +164,6 @@ todo_include_todos = False
+ # a list of builtin themes.
+ html_theme = "kr"
+ html_theme = "bootstrap"
+-
+ if ON_READTHEDOCS:
+     html_theme = "default"
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch b/meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch
new file mode 100644
index 000000000..aa67bd2f4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0013-FIX-Misspelled-after_rule-hook-was-after_after.patch
@@ -0,0 +1,30 @@
+From 5ea1f1b47c14cf9aeabe7d8e22511d54b15e5f1e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:11:23 +0200
+Subject: [PATCH] FIX: Misspelled after_rule hook (was: after_after)
+
+---
+ docs/context_attributes.rst | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/docs/context_attributes.rst b/docs/context_attributes.rst
+index a4817d1..163664b 100644
+--- a/docs/context_attributes.rst
++++ b/docs/context_attributes.rst
+@@ -23,6 +23,7 @@ config          test run  :class:`~behave.configuration.Configuration`  Configur
+ aborted         test run  bool                                          Set to true if test run is aborted by the user.
+ failed          test run  bool                                          Set to true if a step fails.
+ feature         feature   :class:`~behave.model.Feature`                Current feature.
++rule            rule      :class:`~behave.model.Feature`                Current rule.
+ tags            feature,  list<:class:`~behave.model.Tag`>              Effective tags of current feature, rule, scenario, scenario outline.
+                 rule,
+                 scenario
+@@ -62,7 +63,7 @@ Hook    :func:`after_tags`          feature, rule or scenario
+ Hook    :func:`before_feature`      feature
+ Hook    :func:`after_feature`       feature
+ Hook    :func:`before_rule`         rule
+-Hook    :func:`after_after`         rule
++Hook    :func:`after_rule`          rule
+ Hook    :func:`before_scenario`     scenario
+ Hook    :func:`after_scenario`      scenario
+ Hook    :func:`before_step`         scenario
diff --git a/meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch b/meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch
new file mode 100644
index 000000000..7322216cc
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0014-Add-hints-on-Gherkin-v6-grammar-issues.patch
@@ -0,0 +1,45 @@
+From 14e4c88e9bd1a12a2f081dfb2709df9f78106ca6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:12:23 +0200
+Subject: [PATCH] Add hints on Gherkin v6 grammar issues.
+
+---
+ docs/conf.py                       | 4 +++-
+ docs/new_and_noteworthy_v1.2.7.rst | 8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index f7c2c24..e55fb21 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -54,9 +54,11 @@ for optional_module_name in optional_extensions:
+ extlinks = {
+     "pypi": ("https://pypi.org/project/%s", ""),
+     "github": ("https://github.com/%s", "github:/"),
+-    "issue":  ("https://github.com/behave/behave/issue/%s", "issue #"),
++    "issue":  ("https://github.com/behave/behave/issues/%s", "issue #"),
+     "youtube": ("https://www.youtube.com/watch?v=%s", "youtube:video="),
+     "behave": ("https://github.com/behave/behave", None),
++    "cucumber": ("https://github.com/cucumber/cucumber/", None),
++    "cucumber.issue": ("https://github.com/cucumber/cucumber/issues/%s", "issue #"),
+ }
+ 
+ intersphinx_mapping = {
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index 451ed8c..80d9576 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -92,5 +92,13 @@ Overview of the `Example Mapping`_ concepts:
+     * https://lisacrispin.com/2016/06/02/experiment-example-mapping/
+     * https://tobythetesterblog.wordpress.com/2016/05/25/how-to-do-example-mapping/
+ 
++.. hint:: **Gherkin v6 Grammar Issues**
++
++    * :cucumber.issue:`632`: Rule tags are currently only supported in `behave`.
++      The Cucumber Gherkin v6 grammar currently lacks this functionality.
++
++    * :cucumber.issue:`590`: Rule Background:
++      A proposal is pending to remove Rule Backgrounds again
++
+ 
+ .. include:: _content.tag_expressions_v2.rst
diff --git a/meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch
new file mode 100644
index 000000000..04e45f3f3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0015-README-ReST-tweaks.patch
@@ -0,0 +1,18 @@
+From 12d37ec6af46d3edb806679183ab2138e4f1f5bf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:13:08 +0200
+Subject: [PATCH] README: ReST tweaks
+
+---
+ etc/gherkin/README.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/etc/gherkin/README.rst b/etc/gherkin/README.rst
+index ad3cedb..7ec2108 100644
+--- a/etc/gherkin/README.rst
++++ b/etc/gherkin/README.rst
+@@ -1,3 +1,4 @@
+ SOURCE:
++
+ * https://github.com/cucumber/cucumber/blob/master/gherkin/gherkin-languages.json
+ * https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/gherkin-languages.json
diff --git a/meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch b/meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch
new file mode 100644
index 000000000..cbbcfd541
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0016-Example-using-Gherkin-v6-grammar.patch
@@ -0,0 +1,228 @@
+From eabcf73f0e7f26ef021cef30950c7bb3d2442226 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:16:01 +0200
+Subject: [PATCH] Example using Gherkin v6 grammar.
+
+---
+ examples/gherkin_v6/README.rst                | 18 ++++++++
+ examples/gherkin_v6/behave.ini                | 42 +++++++++++++++++++
+ examples/gherkin_v6/features/rule_1.feature   | 42 +++++++++++++++++++
+ examples/gherkin_v6/features/rule_2.feature   | 42 +++++++++++++++++++
+ .../features/steps/example_steps.py           | 21 ++++++++++
+ .../gherkin_v6/features/steps/person_steps.py |  7 ++++
+ 6 files changed, 172 insertions(+)
+ create mode 100644 examples/gherkin_v6/README.rst
+ create mode 100644 examples/gherkin_v6/behave.ini
+ create mode 100644 examples/gherkin_v6/features/rule_1.feature
+ create mode 100644 examples/gherkin_v6/features/rule_2.feature
+ create mode 100644 examples/gherkin_v6/features/steps/example_steps.py
+ create mode 100644 examples/gherkin_v6/features/steps/person_steps.py
+
+diff --git a/examples/gherkin_v6/README.rst b/examples/gherkin_v6/README.rst
+new file mode 100644
+index 0000000..58199dd
+--- /dev/null
++++ b/examples/gherkin_v6/README.rst
+@@ -0,0 +1,18 @@
++Gherkin v6 Examples
++=============================================================================
++
++
++SCRATCHPAD: Problems
++-----------------------------------------------------------------------------
++
++- SummaryReporter: Shows wrong counts when Rules are present::
++
++    ...
++    0 features passed, 0 failed, 1 skipped XXX
++    3 rules passed, 0 failed, 0 skipped
++    5 scenarios passed, 0 failed, 0 skipped
++    13 steps passed, 0 failed, 0 skipped, 0 undefined
++
++
++- Formatters: PrettyFormatter, PlainFormatter (at least) need Rule support
++
+diff --git a/examples/gherkin_v6/behave.ini b/examples/gherkin_v6/behave.ini
+new file mode 100644
+index 0000000..45c0f0d
+--- /dev/null
++++ b/examples/gherkin_v6/behave.ini
+@@ -0,0 +1,42 @@
++# =============================================================================
++# BEHAVE CONFIGURATION
++# =============================================================================
++# FILE: .behaverc, behave.ini, setup.cfg, tox.ini
++#
++# SEE ALSO:
++#  * http://packages.python.org/behave/behave.html#configuration-files
++#  * https://github.com/behave/behave
++#  * http://pypi.python.org/pypi/behave/
++# =============================================================================
++
++[behave]
++default_tags = not (@xfail or @not_implemented)
++show_skipped = false
++format   = rerun
++    progress3
++outfiles = rerun.txt
++    reports/report_progress3.txt
++junit = true
++logging_level = INFO
++# logging_format = LOG.%(levelname)-8s  %(name)-10s: %(message)s
++# logging_format = LOG.%(levelname)-8s  %(asctime)s  %(name)-10s: %(message)s
++
++# -- ALLURE-FORMATTER REQUIRES:
++# brew install allure
++# pip install allure-behave
++# ALLURE_REPORTS_DIR=allure.reports
++# behave -f allure -o $ALLURE_REPORTS_DIR ...
++# allure serve $ALLURE_REPORTS_DIR
++#
++# SEE ALSO:
++# * https://github.com/allure-framework/allure2
++# * https://github.com/allure-framework/allure-python
++[behave.formatters]
++allure = allure_behave.formatter:AllureFormatter
++
++# PREPARED:
++#  [behave]
++#  format = ... missing_steps ...
++#  output = ... features/steps/missing_steps.py ...
++#  [behave.formatters]
++#  missing_steps = behave.contrib.formatter_missing_steps:MissingStepsFormatter
+diff --git a/examples/gherkin_v6/features/rule_1.feature b/examples/gherkin_v6/features/rule_1.feature
+new file mode 100644
+index 0000000..a802e19
+--- /dev/null
++++ b/examples/gherkin_v6/features/rule_1.feature
+@@ -0,0 +1,42 @@
++Feature: Gherkin v6 Example -- with Rules
++  Feature description line 1.
++
++  Background: Feature.Background
++    Given feature background step_1
++
++  Rule: R1 (with Rule.Background)
++    Rule R1 description line 1.
++
++    Background: R1.Background
++      Given rule R1 background step_1
++      When  rule R1 background step_2
++
++    Example: R1.Scenario_1
++      When rule R1 scenario_1 step_1
++      Then rule R1 scenario_1 step_2
++
++    Example: R1.Scenario_2
++      Given rule R1 scenario_2 step_1
++      Then  rule R1 scenario_2 step_2
++
++  Rule: R2 (without Rule.Background)
++    Rule R2 description line 1.
++
++    Example: R2.Scenario_1
++      When rule R2 scenario_1 step_1
++      Then rule R2 scenario_1 step_2
++
++
++  Rule: R3 (with empty Rule.Background)
++    Rule R3 description line 1.
++    Rule R3 description line 2.
++
++    Background: R3.EmptyBackground
++
++    Scenario Template: R3.Scenario
++      Given a person named "<name>"
++
++      Examples:
++        | name  |
++        | Alice |
++        | Bob   |
+diff --git a/examples/gherkin_v6/features/rule_2.feature b/examples/gherkin_v6/features/rule_2.feature
+new file mode 100644
+index 0000000..a802e19
+--- /dev/null
++++ b/examples/gherkin_v6/features/rule_2.feature
+@@ -0,0 +1,42 @@
++Feature: Gherkin v6 Example -- with Rules
++  Feature description line 1.
++
++  Background: Feature.Background
++    Given feature background step_1
++
++  Rule: R1 (with Rule.Background)
++    Rule R1 description line 1.
++
++    Background: R1.Background
++      Given rule R1 background step_1
++      When  rule R1 background step_2
++
++    Example: R1.Scenario_1
++      When rule R1 scenario_1 step_1
++      Then rule R1 scenario_1 step_2
++
++    Example: R1.Scenario_2
++      Given rule R1 scenario_2 step_1
++      Then  rule R1 scenario_2 step_2
++
++  Rule: R2 (without Rule.Background)
++    Rule R2 description line 1.
++
++    Example: R2.Scenario_1
++      When rule R2 scenario_1 step_1
++      Then rule R2 scenario_1 step_2
++
++
++  Rule: R3 (with empty Rule.Background)
++    Rule R3 description line 1.
++    Rule R3 description line 2.
++
++    Background: R3.EmptyBackground
++
++    Scenario Template: R3.Scenario
++      Given a person named "<name>"
++
++      Examples:
++        | name  |
++        | Alice |
++        | Bob   |
+diff --git a/examples/gherkin_v6/features/steps/example_steps.py b/examples/gherkin_v6/features/steps/example_steps.py
+new file mode 100644
+index 0000000..f4822f3
+--- /dev/null
++++ b/examples/gherkin_v6/features/steps/example_steps.py
+@@ -0,0 +1,21 @@
++# -*- coding: UTF-8 -*-
++from __future__ import absolute_import, print_function
++from behave import step
++
++
++@step(u'feature background step_{step_id:d}')
++def step_rule_background(ctx, step_id):
++    print("feature background step_{0}".format(step_id))
++
++
++@step(u'rule {rule_id:w} background step_{step_id:d}')
++def step_rule_background(ctx, rule_id, step_id):
++    print("rule {0} background step_{1}".format(rule_id, step_id))
++
++
++@step(u'rule {rule_id:w} scenario_{scenario_id:d} step_{step_id:d}')
++def step_rule_scenario(ctx, rule_id, scenario_id, step_id):
++    print("rule {0} scenario_{1} step_{2}".format(
++        rule_id, scenario_id, step_id))
++
++
+diff --git a/examples/gherkin_v6/features/steps/person_steps.py b/examples/gherkin_v6/features/steps/person_steps.py
+new file mode 100644
+index 0000000..714ac01
+--- /dev/null
++++ b/examples/gherkin_v6/features/steps/person_steps.py
+@@ -0,0 +1,7 @@
++# -*- coding: UTF-8 -*-
++from behave import given
++
++
++@given(u'a person named "{name}"')
++def step_given_person_with_name(ctx, name):
++    pass
diff --git a/meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch b/meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch
new file mode 100644
index 000000000..7c6e9b521
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0017-PREPARE-Python-3.8-support.patch
@@ -0,0 +1,39 @@
+From 5e529b9ae17c15231f989c17fe1a09897edf6477 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 8 Jun 2019 20:39:42 +0200
+Subject: [PATCH] PREPARE: Python-3.8 support
+
+---
+ .travis.yml | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index 7015b88..d8f2443 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -1,12 +1,14 @@
+ language: python
+ sudo: false
++dist: xenial   # required for Python >= 3.7
+ python:
+-  - "3.6"
++  - "3.7"
+   - "2.7"
++  - "3.6"
+   - "3.5"
+   - "pypy"
+   - "pypy3"
+-  - "3.7-dev"
++  - "3.8-dev"
+ 
+ # -- DISABLED:
+ #  - "nightly"
+@@ -19,7 +21,7 @@ python:
+ # -- TEST-BALLON: Check if Python 3.6 is actually Python 3.5.1 or newer
+ matrix:
+   allow_failures:
+-    - python: "3.7-dev"
++    - python: "3.8-dev"
+     - python: "nightly"
+ 
+ cache:
diff --git a/meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch b/meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch
new file mode 100644
index 000000000..4fe596a2f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch
@@ -0,0 +1,22 @@
+From c046c3a31322c7c29ff6d7f6172df41da3530683 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:17:10 +0200
+Subject: [PATCH] py3.8: Try to fix logging.Formatter validate problem
+
+---
+ tests/unit/test_capture.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tests/unit/test_capture.py b/tests/unit/test_capture.py
+index ac2655e..d9a3f3a 100644
+--- a/tests/unit/test_capture.py
++++ b/tests/unit/test_capture.py
+@@ -20,6 +20,8 @@ def create_capture_controller(config=None):
+         config.log_capture = True
+         config.logging_filter = None
+         config.logging_level = "INFO"
++        config.logging_format = "%(levelname)s:%(name)s:%(message)s"
++        config.logging_datefmt = None
+     return CaptureController(config)
+ 
+ def setup_capture_controller(capture_controller, context=None):
diff --git a/meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch b/meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch
new file mode 100644
index 000000000..121da7094
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch
@@ -0,0 +1,28 @@
+From fbe6b2937087db11f96e21b36a540270d7c2b165 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:19:58 +0200
+Subject: [PATCH] travis.ci: Temporarily move py38-dev to front (build first).
+
+---
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index d8f2443..35bce8c 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -2,13 +2,13 @@ language: python
+ sudo: false
+ dist: xenial   # required for Python >= 3.7
+ python:
++  - "3.8-dev"
+   - "3.7"
+   - "2.7"
+   - "3.6"
+   - "3.5"
+   - "pypy"
+   - "pypy3"
+-  - "3.8-dev"
+ 
+ # -- DISABLED:
+ #  - "nightly"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch b/meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch
new file mode 100644
index 000000000..cf9aff701
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch
@@ -0,0 +1,35 @@
+From 41525c748413405d0faf6c8fc9a345047e31a1a7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:26:19 +0200
+Subject: [PATCH] travis.ci: Tweaks for faster builds (temporarily).
+
+---
+ .travis.yml | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index 35bce8c..fbc3520 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -5,15 +5,15 @@ python:
+   - "3.8-dev"
+   - "3.7"
+   - "2.7"
+-  - "3.6"
+-  - "3.5"
+-  - "pypy"
+-  - "pypy3"
++
++# -- DISABLE-TEMPORARILY: Ensure faster builds
++#  - "3.6"
++#  - "3.5"
++#  - "pypy"
++#  - "pypy3"
+ 
+ # -- DISABLED:
+ #  - "nightly"
+-#  - "3.4"
+-#  - "3.3"
+ #
+ # NOW SUPPORTED: "3.5" => python 3.5.2 (>= 3.5.1)
+ # NOTE: nightly = 3.7-dev
diff --git a/meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch b/meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch
new file mode 100644
index 000000000..5fb1176ac
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0021-FIX-py3.8-logging.Formatter.validate-problem.patch
@@ -0,0 +1,47 @@
+From fed4bb3273633e5f81fc8ba21c8b62255c7eefcd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:42:20 +0200
+Subject: [PATCH] FIX py3.8: logging.Formatter.validate() problem.
+
+---
+ test/test_runner.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/test/test_runner.py b/test/test_runner.py
+index 57c9445..6647283 100644
+--- a/test/test_runner.py
++++ b/test/test_runner.py
+@@ -286,6 +286,7 @@ class TestContext(unittest.TestCase):
+         eq_("thing" in self.context, True)
+         del self.context.thing
+ 
++
+ class ExampleSteps(object):
+     text = None
+     table = None
+@@ -320,6 +321,7 @@ class ExampleSteps(object):
+         for keyword, pattern, func in step_definitions:
+             step_registry.add_step_definition(keyword, pattern, func)
+ 
++
+ class TestContext_ExecuteSteps(unittest.TestCase):
+     """
+     Test the behave.runner.Context.execute_steps() functionality.
+@@ -341,6 +343,8 @@ class TestContext_ExecuteSteps(unittest.TestCase):
+         runner_.config.stdout_capture = False
+         runner_.config.stderr_capture = False
+         runner_.config.log_capture = False
++        runner_.config.logging_format = None
++        runner_.config.logging_datefmt = None
+         runner_.step_registry = self.step_registry
+ 
+         self.context = runner.Context(runner_)
+@@ -658,6 +662,8 @@ class TestRunWithPaths(unittest.TestCase):
+         self.config.logging_filter = None
+         self.config.outputs = [Mock(), StreamOpener(stream=sys.stdout)]
+         self.config.format = ["plain", "progress"]
++        self.config.logging_format = None
++        self.config.logging_datefmt = None
+         self.runner = runner.Runner(self.config)
+         self.load_hooks = self.runner.load_hooks = Mock()
+         self.load_step_definitions = self.runner.load_step_definitions = Mock()
diff --git a/meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch b/meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch
new file mode 100644
index 000000000..b46846478
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch
@@ -0,0 +1,42 @@
+From d54d8c038a7e5f9d2168daa6e13362d1df7d17a5 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 13:58:22 +0200
+Subject: [PATCH] PREPARE FOR: Python 3.8, @asyncio.coroutine is deprecated
+ since py38.
+
+---
+ tests/api/_test_async_step34.py | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tests/api/_test_async_step34.py b/tests/api/_test_async_step34.py
+index 8242be7..1c0c31f 100644
+--- a/tests/api/_test_async_step34.py
++++ b/tests/api/_test_async_step34.py
+@@ -37,13 +37,16 @@ from .testing_support_async import AsyncStepTheory
+ # -----------------------------------------------------------------------------
+ # TEST MARKERS:
+ # -----------------------------------------------------------------------------
++# DEPRECATED: @asyncio.coroutine decorator (since: Python >= 3.8)
+ _python_version = float("%s.%s" % sys.version_info[:2])
+-py34_or_newer = pytest.mark.skipif(_python_version < 3.4, reason="Needs Python >= 3.4")
++requires_py34_to_py37 = pytest.mark.skipif(not (3.4 <= _python_version < 3.8),
++    reason="Supported only for python.versions: 3.4 .. 3.7 (inclusive)")
++
+ 
+ # -----------------------------------------------------------------------------
+ # TESTSUITE:
+ # -----------------------------------------------------------------------------
+-@py34_or_newer
++@requires_py34_to_py37
+ class TestAsyncStepDecoratorPy34(object):
+ 
+     def test_step_decorator_async_run_until_complete2(self):
+@@ -128,7 +131,7 @@ class TestAsyncContext(object):
+         assert async_context.loop is loop0
+ 
+ 
+-@py34_or_newer
++@requires_py34_to_py37
+ class TestAsyncStepRunPy34(object):
+     """Ensure that execution of async-steps works as expected."""
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch b/meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch
new file mode 100644
index 000000000..56b8bd6c7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0023-UPDATE-Add-755-info.patch
@@ -0,0 +1,24 @@
+From db66eecf4c5301ca45db9f71c7b2c3c26d5927a1 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 14:06:14 +0200
+Subject: [PATCH] UPDATE: Add #755 info
+
+---
+ CHANGES.rst | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d6e96af..a91e22a 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -30,6 +30,10 @@ ENHANCEMENTS:
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ 
+ 
++PARTIALLY FIXED:
++
++* issue #755: Failures with Python 3.8 (submitted by: hroncok)
++
+ FIXED:
+ 
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch b/meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch
new file mode 100644
index 000000000..8f9464a2d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch
@@ -0,0 +1,25 @@
+From 467b223dc84f52933b2782ce9d116e89d48a26f1 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 14:27:23 +0200
+Subject: [PATCH] FIX-WARNING: Related to docstring-example and weird backslash
+ usage.
+
+---
+ behave/matchers.py | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/behave/matchers.py b/behave/matchers.py
+index c896f52..0fee0c7 100644
+--- a/behave/matchers.py
++++ b/behave/matchers.py
+@@ -261,9 +261,7 @@ class CFParseMatcher(ParseMatcher):
+ 
+ 
+ def register_type(**kw):
+-    # pylint: disable=anomalous-backslash-in-string
+-    # REQUIRED-BY: code example
+-    """Registers a custom type that will be available to "parse"
++    r"""Registers a custom type that will be available to "parse"
+     for type conversion during step matching.
+ 
+     Converters should be supplied as ``name=callable`` arguments (or as dict).
diff --git a/meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch b/meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch
new file mode 100644
index 000000000..9213ccd2e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch
@@ -0,0 +1,29 @@
+From 11ea2c45d5b88c92b25ab8e8027a931df81c2abc Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 14:37:41 +0200
+Subject: [PATCH] FIX: invalid escape sequence warnings (w/ regex patterns).
+
+---
+ tests/unit/test_behave4cmd_command_shell_proc.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/unit/test_behave4cmd_command_shell_proc.py b/tests/unit/test_behave4cmd_command_shell_proc.py
+index aae5e9f..c45ab3b 100644
+--- a/tests/unit/test_behave4cmd_command_shell_proc.py
++++ b/tests/unit/test_behave4cmd_command_shell_proc.py
+@@ -1,5 +1,5 @@
+ # -*- coding: UTF-8 -*-
+-"""
++r"""
+ 
+ Regular expressions for winpath:
+ http://regexlib.com/Search.aspx?k=file+name
+@@ -61,7 +61,7 @@ line_processor_ioerrors = [
+ 
+ line_processor_traceback = [
+     ExceptionWithPathNormalizer(
+-        '^\s*File "(?P<path>.*)", line \d+, in ',
++        r'^\s*File "(?P<path>.*)", line \d+, in ',
+         '  File "'),
+     BehaveWinCommandOutputProcessor.line_processors[4],
+ ]
diff --git a/meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch b/meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch
new file mode 100644
index 000000000..67ea8860e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch
@@ -0,0 +1,1020 @@
+From 72279d87372cf21d980c40d01fce2f59bb734884 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 16:04:43 +0200
+Subject: [PATCH] DEPRECATING-CLEANUP: Move deprecated tag matcher classes
+
+- behave.tag_matcher.OnlyWithCategoryTagMatcher
+- behave.tag_matcher.OnlyWithAnyCategoryTagMatcher
+
+to "behave.attic.tag_matcher".
+Move related unit tests to "tests.attic/unit/test_tag_matcher.py".
+---
+ behave/attic/__init__.py             |   0
+ behave/attic/tag_matcher.py          | 181 +++++++++++++++++
+ behave/tag_matcher.py                | 189 +-----------------
+ tests.attic/__init__.py              |   0
+ tests.attic/unit/__init__.py         |   0
+ tests.attic/unit/test_tag_matcher.py | 280 +++++++++++++++++++++++++++
+ tests/unit/test_tag_matcher.py       | 279 +-------------------------
+ 7 files changed, 470 insertions(+), 459 deletions(-)
+ create mode 100644 behave/attic/__init__.py
+ create mode 100644 behave/attic/tag_matcher.py
+ create mode 100644 tests.attic/__init__.py
+ create mode 100644 tests.attic/unit/__init__.py
+ create mode 100644 tests.attic/unit/test_tag_matcher.py
+
+diff --git a/behave/attic/__init__.py b/behave/attic/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/behave/attic/tag_matcher.py b/behave/attic/tag_matcher.py
+new file mode 100644
+index 0000000..f07dcbf
+--- /dev/null
++++ b/behave/attic/tag_matcher.py
+@@ -0,0 +1,181 @@
++# -----------------------------------------------------------------------------
++# PROTOTYPING CLASSES: Should no longer be used
++# -----------------------------------------------------------------------------
++
++import warnings
++from behave.tag_matcher import TagMatcher
++
++
++class OnlyWithCategoryTagMatcher(TagMatcher):
++    """
++    Provides a tag matcher that allows to determine if feature/scenario
++    should run or should be excluded from the run-set (at runtime).
++
++    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
++
++    EXAMPLE:
++    --------
++
++    Run some scenarios only when runtime conditions are met:
++
++      * Run scenario Alice only on Windows OS
++      * Run scenario Bob only on MACOSX
++
++    .. code-block:: gherkin
++
++        # -- FILE: features/alice.feature
++        # TAG SCHEMA: @only.with_{category}={current_value}
++        Feature:
++
++          @only.with_os=win32
++          Scenario: Alice (Run only on Windows)
++            Given I do something
++            ...
++
++          @only.with_os=darwin
++          Scenario: Bob (Run only on MACOSX)
++            Given I do something else
++            ...
++
++
++    .. code-block:: python
++
++        # -- FILE: features/environment.py
++        from behave.tag_matcher import OnlyWithCategoryTagMatcher
++        import sys
++
++        # -- MATCHES TAGS: @only.with_{category}=* = @only.with_os=*
++        active_tag_matcher = OnlyWithCategoryTagMatcher("os", sys.platform)
++
++        def before_scenario(context, scenario):
++            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
++                scenario.skip()   #< LATE-EXCLUDE from run-set.
++    """
++    tag_prefix = "only.with_"
++    value_separator = "="
++
++    def __init__(self, category, value, tag_prefix=None, value_sep=None):
++        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
++        super(OnlyWithCategoryTagMatcher, self).__init__()
++        self.active_tag = self.make_category_tag(category, value,
++                                                 tag_prefix, value_sep)
++        self.category_tag_prefix = self.make_category_tag(category, None,
++                                                          tag_prefix, value_sep)
++
++    def should_exclude_with(self, tags):
++        category_tags = self.select_category_tags(tags)
++        if category_tags and self.active_tag not in category_tags:
++            return True
++        # -- OTHERWISE: feature/scenario with theses tags should run.
++        return False
++
++    def select_category_tags(self, tags):
++        return [tag  for tag in tags
++                if tag.startswith(self.category_tag_prefix)]
++
++    @classmethod
++    def make_category_tag(cls, category, value=None, tag_prefix=None,
++                          value_sep=None):
++        if tag_prefix is None:
++            tag_prefix = cls.tag_prefix
++        if value_sep is None:
++            value_sep = cls.value_separator
++        value = value or ""
++        return "%s%s%s%s" % (tag_prefix, category, value_sep, value)
++
++
++class OnlyWithAnyCategoryTagMatcher(TagMatcher):
++    """
++    Provides a tag matcher that matches any category that follows the
++    "@only.with_" tag schema and determines if it should run or
++    should be excluded from the run-set (at runtime).
++
++    TAG SCHEMA: @only.with_{category}={value}
++
++    .. seealso:: OnlyWithCategoryTagMatcher
++    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
++
++    EXAMPLE:
++    --------
++
++    Run some scenarios only when runtime conditions are met:
++
++      * Run scenario Alice only on Windows OS
++      * Run scenario Bob only with browser Chrome
++
++    .. code-block:: gherkin
++
++        # -- FILE: features/alice.feature
++        # TAG SCHEMA: @only.with_{category}={current_value}
++        Feature:
++
++          @only.with_os=win32
++          Scenario: Alice (Run only on Windows)
++            Given I do something
++            ...
++
++          @only.with_browser=chrome
++          Scenario: Bob (Run only with Web-Browser Chrome)
++            Given I do something else
++            ...
++
++
++    .. code-block:: python
++
++        # -- FILE: features/environment.py
++        from behave.tag_matcher import OnlyWithAnyCategoryTagMatcher
++        import sys
++
++        # -- MATCHES ANY TAGS: @only.with_{category}={value}
++        # NOTE: active_tag_value_provider provides current category values.
++        active_tag_value_provider = {
++            "browser": os.environ.get("BEHAVE_BROWSER", "chrome"),
++            "os":      sys.platform,
++        }
++        active_tag_matcher = OnlyWithAnyCategoryTagMatcher(active_tag_value_provider)
++
++        def before_scenario(context, scenario):
++            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
++                scenario.skip()   #< LATE-EXCLUDE from run-set.
++    """
++
++    def __init__(self, value_provider, tag_prefix=None, value_sep=None):
++        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
++        super(OnlyWithAnyCategoryTagMatcher, self).__init__()
++        if value_sep is None:
++            value_sep = OnlyWithCategoryTagMatcher.value_separator
++        self.value_provider = value_provider
++        self.tag_prefix = tag_prefix or OnlyWithCategoryTagMatcher.tag_prefix
++        self.value_separator = value_sep
++
++    def should_exclude_with(self, tags):
++        exclude_decision_map = {}
++        for category_tag in self.select_category_tags(tags):
++            category, value = self.parse_category_tag(category_tag)
++            active_value = self.value_provider.get(category, None)
++            if active_value is None:
++                # -- CASE: Unknown category, ignore it.
++                continue
++            elif active_value == value:
++                # -- CASE: Active category value selected, decision should run.
++                exclude_decision_map[category] = False
++            else:
++                # -- CASE: Inactive category value selected, may exclude it.
++                if category not in exclude_decision_map:
++                    exclude_decision_map[category] = True
++        return any(exclude_decision_map.values())
++
++    def select_category_tags(self, tags):
++        return [tag  for tag in tags
++                if tag.startswith(self.tag_prefix)]
++
++    def parse_category_tag(self, tag):
++        assert tag and tag.startswith(self.tag_prefix)
++        category_value = tag[len(self.tag_prefix):]
++        if self.value_separator in category_value:
++            category, value = category_value.split(self.value_separator, 1)
++        else:
++            # -- OOPS: TAG SCHEMA FORMAT MISMATCH
++            category = category_value
++            value = None
++        return category, value
+diff --git a/behave/tag_matcher.py b/behave/tag_matcher.py
+index f1f955b..5f9dce0 100644
+--- a/behave/tag_matcher.py
++++ b/behave/tag_matcher.py
+@@ -1,9 +1,12 @@
+-# -*- coding: utf-8 -*-
++# -*- coding: UTF-8 -*-
++"""
++Contains classes and functionality to provide a skip-if logic based on tags
++in feature files.
++"""
+ 
+ from __future__ import absolute_import
+ import re
+ import operator
+-import warnings
+ import six
+ 
+ 
+@@ -34,10 +37,10 @@ class ActiveTagMatcher(TagMatcher):
+     """Provides an active tag matcher for many categories.
+ 
+     TAG SCHEMA:
+-      * active.with_{category}={value}
+-      * not_active.with_{category}={value}
+       * use.with_{category}={value}
+       * not.with_{category}={value}
++      * active.with_{category}={value}
++      * not_active.with_{category}={value}
+       * only.with_{category}={value}        (NOTE: For backward compatibility)
+ 
+     TAG LOGIC
+@@ -285,181 +288,3 @@ def setup_active_tag_values(active_tag_values, data):
+     for category in list(active_tag_values.keys()):
+         if category in data:
+             active_tag_values[category] = data[category]
+-
+-
+-# -----------------------------------------------------------------------------
+-# PROTOTYPING CLASSES:
+-# -----------------------------------------------------------------------------
+-class OnlyWithCategoryTagMatcher(TagMatcher):
+-    """
+-    Provides a tag matcher that allows to determine if feature/scenario
+-    should run or should be excluded from the run-set (at runtime).
+-
+-    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
+-
+-    EXAMPLE:
+-    --------
+-
+-    Run some scenarios only when runtime conditions are met:
+-
+-      * Run scenario Alice only on Windows OS
+-      * Run scenario Bob only on MACOSX
+-
+-    .. code-block:: gherkin
+-
+-        # -- FILE: features/alice.feature
+-        # TAG SCHEMA: @only.with_{category}={current_value}
+-        Feature:
+-
+-          @only.with_os=win32
+-          Scenario: Alice (Run only on Windows)
+-            Given I do something
+-            ...
+-
+-          @only.with_os=darwin
+-          Scenario: Bob (Run only on MACOSX)
+-            Given I do something else
+-            ...
+-
+-
+-    .. code-block:: python
+-
+-        # -- FILE: features/environment.py
+-        from behave.tag_matcher import OnlyWithCategoryTagMatcher
+-        import sys
+-
+-        # -- MATCHES TAGS: @only.with_{category}=* = @only.with_os=*
+-        active_tag_matcher = OnlyWithCategoryTagMatcher("os", sys.platform)
+-
+-        def before_scenario(context, scenario):
+-            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+-                scenario.skip()   #< LATE-EXCLUDE from run-set.
+-    """
+-    tag_prefix = "only.with_"
+-    value_separator = "="
+-
+-    def __init__(self, category, value, tag_prefix=None, value_sep=None):
+-        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
+-        super(OnlyWithCategoryTagMatcher, self).__init__()
+-        self.active_tag = self.make_category_tag(category, value,
+-                                                 tag_prefix, value_sep)
+-        self.category_tag_prefix = self.make_category_tag(category, None,
+-                                                          tag_prefix, value_sep)
+-
+-    def should_exclude_with(self, tags):
+-        category_tags = self.select_category_tags(tags)
+-        if category_tags and self.active_tag not in category_tags:
+-            return True
+-        # -- OTHERWISE: feature/scenario with theses tags should run.
+-        return False
+-
+-    def select_category_tags(self, tags):
+-        return [tag  for tag in tags
+-                if tag.startswith(self.category_tag_prefix)]
+-
+-    @classmethod
+-    def make_category_tag(cls, category, value=None, tag_prefix=None,
+-                          value_sep=None):
+-        if tag_prefix is None:
+-            tag_prefix = cls.tag_prefix
+-        if value_sep is None:
+-            value_sep = cls.value_separator
+-        value = value or ""
+-        return "%s%s%s%s" % (tag_prefix, category, value_sep, value)
+-
+-
+-class OnlyWithAnyCategoryTagMatcher(TagMatcher):
+-    """
+-    Provides a tag matcher that matches any category that follows the
+-    "@only.with_" tag schema and determines if it should run or
+-    should be excluded from the run-set (at runtime).
+-
+-    TAG SCHEMA: @only.with_{category}={value}
+-
+-    .. seealso:: OnlyWithCategoryTagMatcher
+-    .. deprecated:: Use :class:`ActiveTagMatcher` instead.
+-
+-    EXAMPLE:
+-    --------
+-
+-    Run some scenarios only when runtime conditions are met:
+-
+-      * Run scenario Alice only on Windows OS
+-      * Run scenario Bob only with browser Chrome
+-
+-    .. code-block:: gherkin
+-
+-        # -- FILE: features/alice.feature
+-        # TAG SCHEMA: @only.with_{category}={current_value}
+-        Feature:
+-
+-          @only.with_os=win32
+-          Scenario: Alice (Run only on Windows)
+-            Given I do something
+-            ...
+-
+-          @only.with_browser=chrome
+-          Scenario: Bob (Run only with Web-Browser Chrome)
+-            Given I do something else
+-            ...
+-
+-
+-    .. code-block:: python
+-
+-        # -- FILE: features/environment.py
+-        from behave.tag_matcher import OnlyWithAnyCategoryTagMatcher
+-        import sys
+-
+-        # -- MATCHES ANY TAGS: @only.with_{category}={value}
+-        # NOTE: active_tag_value_provider provides current category values.
+-        active_tag_value_provider = {
+-            "browser": os.environ.get("BEHAVE_BROWSER", "chrome"),
+-            "os":      sys.platform,
+-        }
+-        active_tag_matcher = OnlyWithAnyCategoryTagMatcher(active_tag_value_provider)
+-
+-        def before_scenario(context, scenario):
+-            if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+-                scenario.skip()   #< LATE-EXCLUDE from run-set.
+-    """
+-
+-    def __init__(self, value_provider, tag_prefix=None, value_sep=None):
+-        warnings.warn("Use ActiveTagMatcher instead.", DeprecationWarning)
+-        super(OnlyWithAnyCategoryTagMatcher, self).__init__()
+-        if value_sep is None:
+-            value_sep = OnlyWithCategoryTagMatcher.value_separator
+-        self.value_provider = value_provider
+-        self.tag_prefix = tag_prefix or OnlyWithCategoryTagMatcher.tag_prefix
+-        self.value_separator = value_sep
+-
+-    def should_exclude_with(self, tags):
+-        exclude_decision_map = {}
+-        for category_tag in self.select_category_tags(tags):
+-            category, value = self.parse_category_tag(category_tag)
+-            active_value = self.value_provider.get(category, None)
+-            if active_value is None:
+-                # -- CASE: Unknown category, ignore it.
+-                continue
+-            elif active_value == value:
+-                # -- CASE: Active category value selected, decision should run.
+-                exclude_decision_map[category] = False
+-            else:
+-                # -- CASE: Inactive category value selected, may exclude it.
+-                if category not in exclude_decision_map:
+-                    exclude_decision_map[category] = True
+-        return any(exclude_decision_map.values())
+-
+-    def select_category_tags(self, tags):
+-        return [tag  for tag in tags
+-                if tag.startswith(self.tag_prefix)]
+-
+-    def parse_category_tag(self, tag):
+-        assert tag and tag.startswith(self.tag_prefix)
+-        category_value = tag[len(self.tag_prefix):]
+-        if self.value_separator in category_value:
+-            category, value = category_value.split(self.value_separator, 1)
+-        else:
+-            # -- OOPS: TAG SCHEMA FORMAT MISMATCH
+-            category = category_value
+-            value = None
+-        return category, value
+diff --git a/tests.attic/__init__.py b/tests.attic/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests.attic/unit/__init__.py b/tests.attic/unit/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests.attic/unit/test_tag_matcher.py b/tests.attic/unit/test_tag_matcher.py
+new file mode 100644
+index 0000000..d767fa7
+--- /dev/null
++++ b/tests.attic/unit/test_tag_matcher.py
+@@ -0,0 +1,280 @@
++# -----------------------------------------------------------------------------
++# PROTOTYPING CLASSES (deprecating) -- Should no longer be used.
++# -----------------------------------------------------------------------------
++
++import warnings
++from unittest import TestCase
++from behave.attic.tag_matcher import \
++    OnlyWithCategoryTagMatcher,  OnlyWithAnyCategoryTagMatcher
++
++
++class TestOnlyWithCategoryTagMatcher(TestCase):
++    TagMatcher = OnlyWithCategoryTagMatcher
++
++    def setUp(self):
++        category = "xxx"
++        with warnings.catch_warnings():
++            warnings.simplefilter("ignore", DeprecationWarning)
++            self.tag_matcher = OnlyWithCategoryTagMatcher(category, "alice")
++        self.enabled_tag = self.TagMatcher.make_category_tag(category, "alice")
++        self.similar_tag = self.TagMatcher.make_category_tag(category, "alice2")
++        self.other_tag = self.TagMatcher.make_category_tag(category, "other")
++        self.category = category
++
++    def test_should_exclude_with__returns_false_with_enabled_tag(self):
++        tags = [ self.enabled_tag ]
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
++        test_patterns = [
++            ([ self.enabled_tag, self.other_tag ], "case: first"),
++            ([ self.other_tag, self.enabled_tag ], "case: last"),
++            ([ "foo", self.enabled_tag, self.other_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag(self):
++        tags = [ self.other_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
++        test_patterns = [
++            ([ self.other_tag, "foo" ], "case: first"),
++            ([ "foo", self.other_tag ], "case: last"),
++            ([ "foo", self.other_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_similar_tag(self):
++        tags = [ self.similar_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_similar_and_more(self):
++        test_patterns = [
++            ([ self.similar_tag, "foo" ], "case: first"),
++            ([ "foo", self.similar_tag ], "case: last"),
++            ([ "foo", self.similar_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_without_category_tag(self):
++        test_patterns = [
++            ([ ],           "case: No tags"),
++            ([ "foo" ],     "case: One tag"),
++            ([ "foo", "bar" ], "case: Two tags"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_run_with__negates_result_of_should_exclude_with(self):
++        test_patterns = [
++            ([ ],                   "case: No tags"),
++            ([ "foo" ],             "case: One non-category tag"),
++            ([ "foo", "bar" ],      "case: Two non-category tags"),
++            ([ self.enabled_tag ],   "case: enabled tag"),
++            ([ self.enabled_tag, self.other_tag ],  "case: enabled and other tag"),
++            ([ self.enabled_tag, "foo" ],    "case: enabled and foo tag"),
++            ([ self.other_tag ],            "case: other tag"),
++            ([ self.other_tag, "foo" ],     "case: other and foo tag"),
++            ([ self.similar_tag ],          "case: similar tag"),
++            ([ "foo", self.similar_tag ],   "case: foo and similar tag"),
++        ]
++        for tags, case in test_patterns:
++            result1 = self.tag_matcher.should_run_with(tags)
++            result2 = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
++            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
++
++    def test_make_category_tag__returns_category_tag_prefix_without_value(self):
++        category = "xxx"
++        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category)
++        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, None)
++        tag3 = OnlyWithCategoryTagMatcher.make_category_tag(category, value=None)
++        self.assertEqual("only.with_xxx=", tag1)
++        self.assertEqual("only.with_xxx=", tag2)
++        self.assertEqual("only.with_xxx=", tag3)
++        self.assertTrue(tag1.startswith(OnlyWithCategoryTagMatcher.tag_prefix))
++
++    def test_make_category_tag__returns_category_tag_with_value(self):
++        category = "xxx"
++        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category, "alice")
++        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, "bob")
++        self.assertEqual("only.with_xxx=alice", tag1)
++        self.assertEqual("only.with_xxx=bob", tag2)
++
++    def test_make_category_tag__returns_category_tag_with_tag_prefix(self):
++        my_tag_prefix = "ONLY_WITH."
++        category = "xxx"
++        TagMatcher = OnlyWithCategoryTagMatcher
++        tag0 = TagMatcher.make_category_tag(category, tag_prefix=my_tag_prefix)
++        tag1 = TagMatcher.make_category_tag(category, "alice", my_tag_prefix)
++        tag2 = TagMatcher.make_category_tag(category, "bob", tag_prefix=my_tag_prefix)
++        self.assertEqual("ONLY_WITH.xxx=", tag0)
++        self.assertEqual("ONLY_WITH.xxx=alice", tag1)
++        self.assertEqual("ONLY_WITH.xxx=bob", tag2)
++        self.assertTrue(tag1.startswith(my_tag_prefix))
++
++    def test_ctor__with_tag_prefix(self):
++        tag_prefix = "ONLY_WITH."
++        tag_matcher = OnlyWithCategoryTagMatcher("xxx", "alice", tag_prefix)
++
++        tags = ["foo", "ONLY_WITH.xxx=foo", "only.with_xxx=bar", "bar"]
++        actual_tags = tag_matcher.select_category_tags(tags)
++        self.assertEqual(["ONLY_WITH.xxx=foo"], actual_tags)
++
++
++class Traits4OnlyWithAnyCategoryTagMatcher(object):
++    """Test data for OnlyWithAnyCategoryTagMatcher."""
++
++    TagMatcher0 = OnlyWithCategoryTagMatcher
++    TagMatcher = OnlyWithAnyCategoryTagMatcher
++    category1_enabled_tag = TagMatcher0.make_category_tag("foo", "alice")
++    category1_similar_tag = TagMatcher0.make_category_tag("foo", "alice2")
++    category1_disabled_tag = TagMatcher0.make_category_tag("foo", "bob")
++    category2_enabled_tag = TagMatcher0.make_category_tag("bar", "BOB")
++    category2_similar_tag = TagMatcher0.make_category_tag("bar", "BOB2")
++    category2_disabled_tag = TagMatcher0.make_category_tag("bar", "CHARLY")
++    unknown_category_tag = TagMatcher0.make_category_tag("UNKNOWN", "one")
++
++
++class TestOnlyWithAnyCategoryTagMatcher(TestCase):
++    TagMatcher = OnlyWithAnyCategoryTagMatcher
++    traits = Traits4OnlyWithAnyCategoryTagMatcher
++
++    def setUp(self):
++        value_provider = {
++            "foo": "alice",
++            "bar": "BOB",
++        }
++        with warnings.catch_warnings():
++            warnings.simplefilter("ignore", DeprecationWarning)
++            self.tag_matcher = self.TagMatcher(value_provider)
++
++    # def test_deprecating_warning_is_issued(self):
++    #     value_provider = {"foo": "alice"}
++    #     with warnings.catch_warnings(record=True) as recorder:
++    #         warnings.simplefilter("always", DeprecationWarning)
++    #         tag_matcher = OnlyWithAnyCategoryTagMatcher(value_provider)
++    #         self.assertEqual(len(recorder), 1)
++    #         last_warning = recorder[-1]
++    #         assert issubclass(last_warning.category, DeprecationWarning)
++    #         assert "deprecated" in str(last_warning.message)
++
++    def test_should_exclude_with__returns_false_with_enabled_tag(self):
++        traits = self.traits
++        tags1 = [ traits.category1_enabled_tag ]
++        tags2 = [ traits.category2_enabled_tag ]
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags1))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags2))
++
++    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
++            ([ traits.category1_disabled_tag, traits.category1_enabled_tag ], "case: last"),
++            ([ "foo", traits.category1_enabled_tag, traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_disabled_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_disabled_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_disabled_tag ], "case: last"),
++            ([ "foo", traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_similar_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_similar_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_similar_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_similar_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_similar_tag ], "case: last"),
++            ([ "foo", traits.category1_similar_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_without_category_tag(self):
++        test_patterns = [
++            ([ ],           "case: No tags"),
++            ([ "foo" ],     "case: One tag"),
++            ([ "foo", "bar" ], "case: Two tags"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_with_unknown_category_tag(self):
++        """Tags from unknown categories, not supported by value_provider,
++        should not be excluded.
++        """
++        traits = self.traits
++        tags = [ traits.unknown_category_tag ]
++        self.assertEqual("only.with_UNKNOWN=one", traits.unknown_category_tag)
++        self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__combinations_of_2_categories(self):
++        traits = self.traits
++        test_patterns = [
++            ("case 00: 2 disabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
++            ("case 01: disabled and enabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
++            ("case 10: enabled and disabled category tags", True,
++             [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
++            ("case 11: 2 enabled category tags", False,  # -- SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
++            # -- SPECIAL CASE: With unknown category
++            ("case 0x: disabled and unknown category tags", True,
++             [ traits.category1_disabled_tag, traits.unknown_category_tag]),
++            ("case 1x: enabled and unknown category tags", False,  # SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.unknown_category_tag]),
++        ]
++        for case, expected, tags in test_patterns:
++            actual_result = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(expected, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_run_with__negates_result_of_should_exclude_with(self):
++        traits = self.traits
++        test_patterns = [
++            ([ ],                   "case: No tags"),
++            ([ "foo" ],             "case: One non-category tag"),
++            ([ "foo", "bar" ],      "case: Two non-category tags"),
++            ([ traits.category1_enabled_tag ],   "case: enabled tag"),
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ],  "case: enabled and other tag"),
++            ([ traits.category1_enabled_tag, "foo" ],    "case: enabled and foo tag"),
++            ([ traits.category1_disabled_tag ],            "case: other tag"),
++            ([ traits.category1_disabled_tag, "foo" ],     "case: other and foo tag"),
++            ([ traits.category1_similar_tag ],          "case: similar tag"),
++            ([ "foo", traits.category1_similar_tag ],   "case: foo and similar tag"),
++        ]
++        for tags, case in test_patterns:
++            result1 = self.tag_matcher.should_run_with(tags)
++            result2 = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
++            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
+diff --git a/tests/unit/test_tag_matcher.py b/tests/unit/test_tag_matcher.py
+index c5d2266..a04c1d4 100644
+--- a/tests/unit/test_tag_matcher.py
++++ b/tests/unit/test_tag_matcher.py
+@@ -8,12 +8,13 @@ Unit tests for active tag-matcher (mod:`behave.tag_matcher`).
+ """
+ 
+ from __future__ import absolute_import
+-from behave.tag_matcher import *
+ from mock import Mock
+ from unittest import TestCase
+ import warnings
+ import pytest
+ 
++from behave.tag_matcher import *
++
+ 
+ class Traits4ActiveTagMatcher(object):
+     TagMatcher = ActiveTagMatcher
+@@ -460,279 +461,3 @@ class TestCompositeTagMatcher(TestCase):
+             actual_true_count = self.count_tag_matcher_with_result(
+                                     self.ctag_matcher.tag_matchers, tags, True)
+             self.assertEqual(0, actual_true_count)
+-
+-
+-# -----------------------------------------------------------------------------
+-# PROTOTYPING CLASSES (deprecating)
+-# -----------------------------------------------------------------------------
+-class TestOnlyWithCategoryTagMatcher(TestCase):
+-    TagMatcher = OnlyWithCategoryTagMatcher
+-
+-    def setUp(self):
+-        category = "xxx"
+-        with warnings.catch_warnings():
+-            warnings.simplefilter("ignore", DeprecationWarning)
+-            self.tag_matcher = OnlyWithCategoryTagMatcher(category, "alice")
+-        self.enabled_tag = self.TagMatcher.make_category_tag(category, "alice")
+-        self.similar_tag = self.TagMatcher.make_category_tag(category, "alice2")
+-        self.other_tag = self.TagMatcher.make_category_tag(category, "other")
+-        self.category = category
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag(self):
+-        tags = [ self.enabled_tag ]
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
+-        test_patterns = [
+-            ([ self.enabled_tag, self.other_tag ], "case: first"),
+-            ([ self.other_tag, self.enabled_tag ], "case: last"),
+-            ([ "foo", self.enabled_tag, self.other_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag(self):
+-        tags = [ self.other_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
+-        test_patterns = [
+-            ([ self.other_tag, "foo" ], "case: first"),
+-            ([ "foo", self.other_tag ], "case: last"),
+-            ([ "foo", self.other_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_tag(self):
+-        tags = [ self.similar_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_and_more(self):
+-        test_patterns = [
+-            ([ self.similar_tag, "foo" ], "case: first"),
+-            ([ "foo", self.similar_tag ], "case: last"),
+-            ([ "foo", self.similar_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_false_without_category_tag(self):
+-        test_patterns = [
+-            ([ ],           "case: No tags"),
+-            ([ "foo" ],     "case: One tag"),
+-            ([ "foo", "bar" ], "case: Two tags"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_run_with__negates_result_of_should_exclude_with(self):
+-        test_patterns = [
+-            ([ ],                   "case: No tags"),
+-            ([ "foo" ],             "case: One non-category tag"),
+-            ([ "foo", "bar" ],      "case: Two non-category tags"),
+-            ([ self.enabled_tag ],   "case: enabled tag"),
+-            ([ self.enabled_tag, self.other_tag ],  "case: enabled and other tag"),
+-            ([ self.enabled_tag, "foo" ],    "case: enabled and foo tag"),
+-            ([ self.other_tag ],            "case: other tag"),
+-            ([ self.other_tag, "foo" ],     "case: other and foo tag"),
+-            ([ self.similar_tag ],          "case: similar tag"),
+-            ([ "foo", self.similar_tag ],   "case: foo and similar tag"),
+-        ]
+-        for tags, case in test_patterns:
+-            result1 = self.tag_matcher.should_run_with(tags)
+-            result2 = self.tag_matcher.should_exclude_with(tags)
+-            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
+-            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
+-
+-    def test_make_category_tag__returns_category_tag_prefix_without_value(self):
+-        category = "xxx"
+-        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category)
+-        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, None)
+-        tag3 = OnlyWithCategoryTagMatcher.make_category_tag(category, value=None)
+-        self.assertEqual("only.with_xxx=", tag1)
+-        self.assertEqual("only.with_xxx=", tag2)
+-        self.assertEqual("only.with_xxx=", tag3)
+-        self.assertTrue(tag1.startswith(OnlyWithCategoryTagMatcher.tag_prefix))
+-
+-    def test_make_category_tag__returns_category_tag_with_value(self):
+-        category = "xxx"
+-        tag1 = OnlyWithCategoryTagMatcher.make_category_tag(category, "alice")
+-        tag2 = OnlyWithCategoryTagMatcher.make_category_tag(category, "bob")
+-        self.assertEqual("only.with_xxx=alice", tag1)
+-        self.assertEqual("only.with_xxx=bob", tag2)
+-
+-    def test_make_category_tag__returns_category_tag_with_tag_prefix(self):
+-        my_tag_prefix = "ONLY_WITH."
+-        category = "xxx"
+-        TagMatcher = OnlyWithCategoryTagMatcher
+-        tag0 = TagMatcher.make_category_tag(category, tag_prefix=my_tag_prefix)
+-        tag1 = TagMatcher.make_category_tag(category, "alice", my_tag_prefix)
+-        tag2 = TagMatcher.make_category_tag(category, "bob", tag_prefix=my_tag_prefix)
+-        self.assertEqual("ONLY_WITH.xxx=", tag0)
+-        self.assertEqual("ONLY_WITH.xxx=alice", tag1)
+-        self.assertEqual("ONLY_WITH.xxx=bob", tag2)
+-        self.assertTrue(tag1.startswith(my_tag_prefix))
+-
+-    def test_ctor__with_tag_prefix(self):
+-        tag_prefix = "ONLY_WITH."
+-        tag_matcher = OnlyWithCategoryTagMatcher("xxx", "alice", tag_prefix)
+-
+-        tags = ["foo", "ONLY_WITH.xxx=foo", "only.with_xxx=bar", "bar"]
+-        actual_tags = tag_matcher.select_category_tags(tags)
+-        self.assertEqual(["ONLY_WITH.xxx=foo"], actual_tags)
+-
+-
+-class Traits4OnlyWithAnyCategoryTagMatcher(object):
+-    """Test data for OnlyWithAnyCategoryTagMatcher."""
+-
+-    TagMatcher0 = OnlyWithCategoryTagMatcher
+-    TagMatcher = OnlyWithAnyCategoryTagMatcher
+-    category1_enabled_tag = TagMatcher0.make_category_tag("foo", "alice")
+-    category1_similar_tag = TagMatcher0.make_category_tag("foo", "alice2")
+-    category1_disabled_tag = TagMatcher0.make_category_tag("foo", "bob")
+-    category2_enabled_tag = TagMatcher0.make_category_tag("bar", "BOB")
+-    category2_similar_tag = TagMatcher0.make_category_tag("bar", "BOB2")
+-    category2_disabled_tag = TagMatcher0.make_category_tag("bar", "CHARLY")
+-    unknown_category_tag = TagMatcher0.make_category_tag("UNKNOWN", "one")
+-
+-
+-class TestOnlyWithAnyCategoryTagMatcher(TestCase):
+-    TagMatcher = OnlyWithAnyCategoryTagMatcher
+-    traits = Traits4OnlyWithAnyCategoryTagMatcher
+-
+-    def setUp(self):
+-        value_provider = {
+-            "foo": "alice",
+-            "bar": "BOB",
+-        }
+-        with warnings.catch_warnings():
+-            warnings.simplefilter("ignore", DeprecationWarning)
+-            self.tag_matcher = self.TagMatcher(value_provider)
+-
+-    # def test_deprecating_warning_is_issued(self):
+-    #     value_provider = {"foo": "alice"}
+-    #     with warnings.catch_warnings(record=True) as recorder:
+-    #         warnings.simplefilter("always", DeprecationWarning)
+-    #         tag_matcher = OnlyWithAnyCategoryTagMatcher(value_provider)
+-    #         self.assertEqual(len(recorder), 1)
+-    #         last_warning = recorder[-1]
+-    #         assert issubclass(last_warning.category, DeprecationWarning)
+-    #         assert "deprecated" in str(last_warning.message)
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag(self):
+-        traits = self.traits
+-        tags1 = [ traits.category1_enabled_tag ]
+-        tags2 = [ traits.category2_enabled_tag ]
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags1))
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags2))
+-
+-    def test_should_exclude_with__returns_false_with_enabled_tag_and_more(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
+-            ([ traits.category1_disabled_tag, traits.category1_enabled_tag ], "case: last"),
+-            ([ "foo", traits.category1_enabled_tag, traits.category1_disabled_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag(self):
+-        traits = self.traits
+-        tags = [ traits.category1_disabled_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ traits.category1_disabled_tag, "foo" ], "case: first"),
+-            ([ "foo", traits.category1_disabled_tag ], "case: last"),
+-            ([ "foo", traits.category1_disabled_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_tag(self):
+-        traits = self.traits
+-        tags = [ traits.category1_similar_tag ]
+-        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__returns_true_with_similar_and_more(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ traits.category1_similar_tag, "foo" ], "case: first"),
+-            ([ "foo", traits.category1_similar_tag ], "case: last"),
+-            ([ "foo", traits.category1_similar_tag, "bar" ], "case: middle"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_false_without_category_tag(self):
+-        test_patterns = [
+-            ([ ],           "case: No tags"),
+-            ([ "foo" ],     "case: One tag"),
+-            ([ "foo", "bar" ], "case: Two tags"),
+-        ]
+-        for tags, case in test_patterns:
+-            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_exclude_with__returns_false_with_unknown_category_tag(self):
+-        """Tags from unknown categories, not supported by value_provider,
+-        should not be excluded.
+-        """
+-        traits = self.traits
+-        tags = [ traits.unknown_category_tag ]
+-        self.assertEqual("only.with_UNKNOWN=one", traits.unknown_category_tag)
+-        self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
+-        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
+-
+-    def test_should_exclude_with__combinations_of_2_categories(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ("case 00: 2 disabled category tags", True,
+-             [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
+-            ("case 01: disabled and enabled category tags", True,
+-             [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
+-            ("case 10: enabled and disabled category tags", True,
+-             [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
+-            ("case 11: 2 enabled category tags", False,  # -- SHOULD-RUN
+-             [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
+-            # -- SPECIAL CASE: With unknown category
+-            ("case 0x: disabled and unknown category tags", True,
+-             [ traits.category1_disabled_tag, traits.unknown_category_tag]),
+-            ("case 1x: enabled and unknown category tags", False,  # SHOULD-RUN
+-             [ traits.category1_enabled_tag, traits.unknown_category_tag]),
+-        ]
+-        for case, expected, tags in test_patterns:
+-            actual_result = self.tag_matcher.should_exclude_with(tags)
+-            self.assertEqual(expected, actual_result,
+-                             "%s: tags=%s" % (case, tags))
+-
+-    def test_should_run_with__negates_result_of_should_exclude_with(self):
+-        traits = self.traits
+-        test_patterns = [
+-            ([ ],                   "case: No tags"),
+-            ([ "foo" ],             "case: One non-category tag"),
+-            ([ "foo", "bar" ],      "case: Two non-category tags"),
+-            ([ traits.category1_enabled_tag ],   "case: enabled tag"),
+-            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ],  "case: enabled and other tag"),
+-            ([ traits.category1_enabled_tag, "foo" ],    "case: enabled and foo tag"),
+-            ([ traits.category1_disabled_tag ],            "case: other tag"),
+-            ([ traits.category1_disabled_tag, "foo" ],     "case: other and foo tag"),
+-            ([ traits.category1_similar_tag ],          "case: similar tag"),
+-            ([ "foo", traits.category1_similar_tag ],   "case: foo and similar tag"),
+-        ]
+-        for tags, case in test_patterns:
+-            result1 = self.tag_matcher.should_run_with(tags)
+-            result2 = self.tag_matcher.should_exclude_with(tags)
+-            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
+-            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
+-
diff --git a/meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch
new file mode 100644
index 000000000..c41068c96
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0027-Comment-tweaks.patch
@@ -0,0 +1,30 @@
+From 362e778e5e57054b45099f1432abea181987d3c9 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 19:24:14 +0200
+Subject: [PATCH] Comment tweaks
+
+---
+ behave/runner.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/behave/runner.py b/behave/runner.py
+index f0f077a..f209cb0 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -167,10 +167,15 @@ class Context(object):
+         self._record = {}
+         self._origin = {}
+         self._mode = self.BEHAVE
++
++        # -- MODEL ENTITY REFERENCES/SUPPORT:
+         self.feature = None
+-        # -- RECHECK: If needed
++        # DISABLED: self.rule = None
++        # DISABLED: self.scenario = None
+         self.text = None
+         self.table = None
++
++        # -- RUNTIME SUPPORT:
+         self.stdout_capture = None
+         self.stderr_capture = None
+         self.log_capture = None
diff --git a/meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch b/meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch
new file mode 100644
index 000000000..8f0ad3a82
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch
@@ -0,0 +1,79 @@
+From d892f81e3bd3e979d3677c39c3a9efc40131b452 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Jun 2019 19:32:10 +0200
+Subject: [PATCH] FIX warnings related to invalid escapes in regex.
+
+---
+ behave4cmd0/command_shell_proc.py           |  3 ++-
+ features/steps/behave_select_files_steps.py | 24 +++++++++++++--------
+ 2 files changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/behave4cmd0/command_shell_proc.py b/behave4cmd0/command_shell_proc.py
+index 07f1c84..03ca55a 100755
+--- a/behave4cmd0/command_shell_proc.py
++++ b/behave4cmd0/command_shell_proc.py
+@@ -251,6 +251,7 @@ class BehaveWinCommandOutputProcessor(LineCommandOutputProcessor):
+             "No such file or directory: '(?P<path>.*)'",
+             "[Errno 2] No such file or directory:"),  # IOError
+         ExceptionWithPathNormalizer(
+-            '^\s*File "(?P<path>.*)", line \d+, in ',
++            # WAS: '^\s*File "(?P<path>.*)", line \d+, in ',
++            r'^\s*File "(?P<path>.*)", line \d+, in ',
+             'File "'),
+     ]
+diff --git a/features/steps/behave_select_files_steps.py b/features/steps/behave_select_files_steps.py
+index 431674e..0d2cd2e 100644
+--- a/features/steps/behave_select_files_steps.py
++++ b/features/steps/behave_select_files_steps.py
+@@ -1,29 +1,34 @@
+ # -*- coding: utf-8 -*-
+-"""
++# DOCSTRING-NEEDS-REGEX-STRING-PREFIX: Due to example w/ wildcard pattern.
++r'''
+ Provides step definitions that test how the behave runner selects feature files.
+ 
+ EXAMPLE:
++
++.. code-block:: gherkin
++
+     Given behave has the following feature fileset:
+-      '''
++      """
+       features/alice.feature
+       features/bob.feature
+       features/barbi.feature
+-      '''
++      """
+     When behave includes feature files with "features/a.*\.feature"
+     And  behave excludes feature files with "features/b.*\.feature"
+     Then the following feature files are selected:
+-      '''
++      """
+       features/alice.feature
+-      '''
+-"""
++      """
++'''
+ 
+ from __future__ import absolute_import
+-from behave import given, when, then
+-from behave.runner_util import FeatureListParser
+-from hamcrest import assert_that, equal_to
+ from copy import copy
+ import re
+ import six
++from hamcrest import assert_that, equal_to
++from behave import given, when, then
++from behave.runner_util import FeatureListParser
++
+ 
+ # -----------------------------------------------------------------------------
+ # STEP UTILS:
+@@ -47,6 +52,7 @@ class BasicBehaveRunner(object):
+ # -----------------------------------------------------------------------------
+ # STEP DEFINITIONS:
+ # -----------------------------------------------------------------------------
++# pylint: disable=invalid-name
+ @given('behave has the following feature fileset')
+ def step_given_behave_has_feature_fileset(context):
+     assert context.text is not None, "REQUIRE: text"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch b/meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch
new file mode 100644
index 000000000..e2d86ca99
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0029-Steps-catalog-should-not-break-configured-rerun-sett.patch
@@ -0,0 +1,73 @@
+From 11c4ac862bdce901ef19864532ef6d17a85799cd Mon Sep 17 00:00:00 2001
+From: Edvin Linge <edvin.linge@gmail.com>
+Date: Mon, 31 Jul 2017 17:05:18 +0200
+Subject: [PATCH] Steps-catalog should not break configured rerun settings
+
+---
+ behave/configuration.py                  |  5 ++++-
+ features/formatter.rerun.feature         | 17 +++++++++++++++++
+ features/formatter.steps_catalog.feature | 13 +++++++++++++
+ 3 files changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 49b1dff..861f89f 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -601,7 +601,10 @@ class Configuration(object):
+         if self.steps_catalog:
+             # -- SHOW STEP-CATALOG: As step summary.
+             self.default_format = "steps.catalog"
+-            self.format = ["steps.catalog"]
++            if self.format:
++                self.format.append("steps.catalog")
++            else:
++                self.format = ["steps.catalog"]
+             self.dry_run = True
+             self.summary = False
+             self.show_skipped = False
+diff --git a/features/formatter.rerun.feature b/features/formatter.rerun.feature
+index 1e645f1..b9d7e1b 100644
+--- a/features/formatter.rerun.feature
++++ b/features/formatter.rerun.feature
+@@ -294,3 +294,20 @@ Feature: Rerun Formatter
+             features/bob.feature:13
+             """
+         And note that "the second RerunFormatter overwrites the output of the first one"
++
++    @with.behave_configfile
++    Scenario: RerunFormatter with steps-catalog
++        Given a file named "behave.ini" with:
++            """
++            [behave]
++            format   = rerun
++            outfiles = rerun.txt
++            """
++        When I run "behave --steps-catalog features/"
++
++        Then it should pass with:
++            """
++            Given a step passes
++            """
++        And a file named "rerun.txt" does not exist
++
+diff --git a/features/formatter.steps_catalog.feature b/features/formatter.steps_catalog.feature
+index 09591bf..936d7f4 100644
+--- a/features/formatter.steps_catalog.feature
++++ b/features/formatter.steps_catalog.feature
+@@ -98,3 +98,16 @@ Feature: Steps Catalog Formatter
+           """
+         But note that "the step definitions are ordered by step type"
+         And note that "'When I visit {person}' has no doc-string"
++
++
++    Scenario: Steps catalog formatter is used for output even when other formatter is specified
++        When I run "behave --steps-catalog -f plain features/"
++        Then it should pass with:
++          """
++          Given {person} lives in {city}
++              Setup the data where a person lives and store in the database.
++
++              :param person:  Person's name (as string).
++              :param city:    City where the person lives (as string).
++          """
++
diff --git a/meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch b/meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch
new file mode 100644
index 000000000..f050c9c85
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch
@@ -0,0 +1,36 @@
+From 502382430f1bee8d0a9031fc70541488224a1029 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 1 Jul 2019 22:07:19 +0200
+Subject: [PATCH] Add feature w/ rules and failing scenarios (enable via
+ tags=fail or tags=xfail).
+
+---
+ .../gherkin_v6/features/rule_fails.feature    | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+ create mode 100644 examples/gherkin_v6/features/rule_fails.feature
+
+diff --git a/examples/gherkin_v6/features/rule_fails.feature b/examples/gherkin_v6/features/rule_fails.feature
+new file mode 100644
+index 0000000..7e3872e
+--- /dev/null
++++ b/examples/gherkin_v6/features/rule_fails.feature
+@@ -0,0 +1,19 @@
++@fail
++Feature: With Rule(s) and Failing Scenario(s)
++
++  HINT: Contains failing scenarios (by intention).
++
++  @xfail
++  Scenario: F0 -- Fails
++    When some step fails
++
++  Rule: Fails in Scenario F2
++
++    Scenario: F1
++      Given a step passes
++
++    @xfail
++    Scenario: F2 -- Fails
++      Given another step passes
++      When a step fails
++      Then another step passes
diff --git a/meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch b/meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch
new file mode 100644
index 000000000..6f71729f5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch
@@ -0,0 +1,27 @@
+From dcbba864209e8784ecaa5a1cf80b346b39b2a5d6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 1 Jul 2019 22:11:13 +0200
+Subject: [PATCH] examples/gherkin_v6: Tweak ScenarioOutline Examples titles.
+
+---
+ examples/gherkin_v6/features/rule_2.feature | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/examples/gherkin_v6/features/rule_2.feature b/examples/gherkin_v6/features/rule_2.feature
+index a802e19..8b8bb04 100644
+--- a/examples/gherkin_v6/features/rule_2.feature
++++ b/examples/gherkin_v6/features/rule_2.feature
+@@ -36,7 +36,12 @@ Feature: Gherkin v6 Example -- with Rules
+     Scenario Template: R3.Scenario
+       Given a person named "<name>"
+ 
+-      Examples:
++      Examples: R3.E1
+         | name  |
+         | Alice |
+         | Bob   |
++
++      Examples: R3.E2
++        | name  |
++        | Charly |
++        | Doro   |
diff --git a/meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch b/meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch
new file mode 100644
index 000000000..4d44fea08
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0032-Add-info-on-merged-pull-588.patch
@@ -0,0 +1,21 @@
+From 9c9bb1e6320a6ffbac0b171d9cf98cbb311104eb Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 1 Jul 2019 08:06:43 +0200
+Subject: [PATCH] Add info on merged pull #588
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index a91e22a..3d805b3 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -36,6 +36,7 @@ PARTIALLY FIXED:
+ 
+ FIXED:
+ 
++* pull  #588: Steps-catalog argument should not break configured rerun settings (provided by: Lego3)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
+ * pull  #657: Allow async steps with timeouts to fail when they raise exceptions (provided by: ALSchwalm)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch b/meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch
new file mode 100644
index 000000000..1fdda3a7d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0033-Tweak-tests-required-by-pytest-5.0.patch
@@ -0,0 +1,97 @@
+From 8fe1bc305aeea5d86de1b3c5dfcd2e7984fc5145 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 5 Jul 2019 08:27:44 +0200
+Subject: [PATCH] Tweak tests, required by pytest >= 5.0. With pytest.raises
+ use str(e.value) instead of str(e) in some cases.
+
+---
+ tests/issues/test_issue0458.py      |  2 +-
+ tests/unit/test_context_cleanups.py |  2 +-
+ tests/unit/test_textutil.py         | 24 +++++++++++++++---------
+ 3 files changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/tests/issues/test_issue0458.py b/tests/issues/test_issue0458.py
+index 1853ad6..f66f6d3 100644
+--- a/tests/issues/test_issue0458.py
++++ b/tests/issues/test_issue0458.py
+@@ -48,7 +48,7 @@ def test_issue(exception_class, message):
+         raise_exception(exception_class, message)
+ 
+     # -- SHOULD NOT RAISE EXCEPTION HERE:
+-    text = _text(e)
++    text = _text(e.value)
+     # -- DIAGNOSTICS:
+     print(u"text"+ text)
+     print(u"exception: %s" % e)
+diff --git a/tests/unit/test_context_cleanups.py b/tests/unit/test_context_cleanups.py
+index b0e8ae6..bf0ab50 100644
+--- a/tests/unit/test_context_cleanups.py
++++ b/tests/unit/test_context_cleanups.py
+@@ -153,7 +153,7 @@ class TestContextCleanup(object):
+         with pytest.raises(AssertionError) as e:
+             with scoped_context_layer(context):
+                 context.add_cleanup(non_callable)
+-        assert "REQUIRES: callable(cleanup_func)" in str(e)
++        assert "REQUIRES: callable(cleanup_func)" in str(e.value)
+ 
+     def test_on_cleanup_error__prints_error_by_default(self, capsys):
+         def bad_cleanup_func():
+diff --git a/tests/unit/test_textutil.py b/tests/unit/test_textutil.py
+index f7f642c..e05e9ad 100644
+--- a/tests/unit/test_textutil.py
++++ b/tests/unit/test_textutil.py
+@@ -214,9 +214,11 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(AssertionError) as e:
+             assert False, message
+ 
+-        text2 = text(e)
+-        expected = u"AssertionError: %s" % message
+-        assert text2.endswith(expected)
++        # -- FOR: pytest < 5.0
++        # expected = u"AssertionError: %s" % message
++        text2 = text(e.value)
++        assert u"AssertionError" in text(e)
++        assert message in text2, "OOPS: text=%r" % text2
+ 
+     @requires_python2
+     @pytest.mark.parametrize("message", [
+@@ -236,10 +238,11 @@ class TestObjectToTextConversion(object):
+                 assert expected_decode_error in str(uni_error)
+                 assert False, bytes_message.decode(self.ENCODING)
+ 
++        # -- FOR: pytest < 5.0
++        # expected = u"AssertionError: %s" % message
+         print("decode_error_occured(ascii)=%s" % decode_error_occured)
+-        text2 = text(e)
+-        expected = u"AssertionError: %s" % message
+-        assert text2.endswith(expected)
++        text2 = text(e.value)
++        assert message in text2, "OOPS: text=%r" % text2
+ 
+     @pytest.mark.parametrize("exception_class, message", [
+         (AssertionError, u"Ärgernis"),
+@@ -251,10 +254,13 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(exception_class) as e:
+             raise exception_class(message)
+ 
+-        text2 = text(e)
++        # -- FOR: pytest < 5.0
++        # expected = u"AssertionError: %s" % message
++        text2 = text(e.value)
+         expected = u"%s: %s" % (exception_class.__name__, message)
+         assert isinstance(text2, six.text_type)
+-        assert text2.endswith(expected)
++        assert exception_class.__name__ in str(e)
++        assert message in text2, "OOPS: text=%r" % text2
+ 
+     @requires_python2
+     @pytest.mark.parametrize("exception_class, message", [
+@@ -268,7 +274,7 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(exception_class) as e:
+             raise exception_class(bytes_message)
+ 
+-        text2 = text(e)
++        text2 = text(e.value)
+         unicode_message = bytes_message.decode(self.ENCODING)
+         expected = u"%s: %s" % (exception_class.__name__, unicode_message)
+         assert isinstance(text2, six.text_type)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch b/meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch
new file mode 100644
index 000000000..7a47c7fe7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch
@@ -0,0 +1,180 @@
+From dce0e40c9689a8d4fe71c9b2e8e4decd72dcf574 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 5 Jul 2019 08:45:51 +0200
+Subject: [PATCH] CLEANUP: Use pytest instead of nose to remove nose.importer
+ DeprecationWarning.
+
+---
+ tests/unit/test_importer.py | 163 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 163 insertions(+)
+ create mode 100644 tests/unit/test_importer.py
+
+diff --git a/tests/unit/test_importer.py b/tests/unit/test_importer.py
+new file mode 100644
+index 0000000..f3f4e2c
+--- /dev/null
++++ b/tests/unit/test_importer.py
+@@ -0,0 +1,163 @@
++# -*- coding: utf-8 -*-
++"""
++Tests for behave.importing.
++The module provides a lazy-loading/importing mechanism.
++"""
++
++from __future__ import absolute_import
++import pytest
++from behave.importer import LazyObject, LazyDict, load_module, parse_scoped_name
++from behave.formatter.base import Formatter
++import sys
++import types
++# import unittest
++
++
++class TestTheory(object):
++    """Marker for test-theory classes as syntactic sugar."""
++    pass
++
++
++class ImportModuleTheory(TestTheory):
++    """
++    Provides a test theory for importing modules.
++    """
++
++    @classmethod
++    def ensure_module_is_not_imported(cls, module_name):
++        if module_name in sys.modules:
++            del sys.modules[module_name]
++        cls.assert_module_is_not_imported(module_name)
++
++    @staticmethod
++    def assert_module_is_imported(module_name):
++        module = sys.modules.get(module_name, None)
++        assert module_name in sys.modules
++        assert module is not None
++
++    @staticmethod
++    def assert_module_is_not_imported(module_name):
++        assert module_name not in sys.modules
++
++    @staticmethod
++    def assert_module_with_name(module, name):
++        assert isinstance(module, types.ModuleType)
++        assert module.__name__ == name
++
++
++class TestLoadModule(object):
++    theory = ImportModuleTheory
++
++    def test_load_module__should_fail_for_unknown_module(self):
++        with pytest.raises(ImportError) as e:
++            load_module("__unknown_module__")
++        # OLD: assert_raises(ImportError, load_module, "__unknown_module__")
++
++    def test_load_module__should_succeed_for_already_imported_module(self):
++        module_name = "behave.importer"
++        self.theory.assert_module_is_imported(module_name)
++
++        module = load_module(module_name)
++        self.theory.assert_module_with_name(module, module_name)
++        self.theory.assert_module_is_imported(module_name)
++
++    def test_load_module__should_succeed_for_existing_module(self):
++        module_name = "test._importer_candidate"
++        self.theory.ensure_module_is_not_imported(module_name)
++
++        module = load_module(module_name)
++        self.theory.assert_module_with_name(module, module_name)
++        self.theory.assert_module_is_imported(module_name)
++
++
++class TestLazyObject(object):
++
++    def test_get__should_succeed_for_known_object(self):
++        lazy = LazyObject("behave.importer", "LazyObject")
++        value = lazy.get()
++        assert value is LazyObject
++
++        lazy2 = LazyObject("behave.importer:LazyObject")
++        value2 = lazy2.get()
++        assert value2 is LazyObject
++
++        lazy3 = LazyObject("behave.formatter.steps", "StepsFormatter")
++        value3 = lazy3.get()
++        assert issubclass(value3, Formatter)
++
++    def test_get__should_fail_for_unknown_module(self):
++        lazy = LazyObject("__unknown_module__", "xxx")
++        with pytest.raises(ImportError):
++            lazy.get()
++
++    def test_get__should_fail_for_unknown_object_in_module(self):
++        lazy = LazyObject("test._importer_candidate", "xxx")
++        with pytest.raises(ImportError):
++            lazy.get()
++
++
++class LazyDictTheory(TestTheory):
++
++    @staticmethod
++    def safe_getitem(data, key):
++        return dict.__getitem__(data, key)
++
++    @classmethod
++    def assert_item_is_lazy(cls, data, key):
++        value = cls.safe_getitem(data, key)
++        cls.assert_is_lazy_object(value)
++
++    @classmethod
++    def assert_item_is_not_lazy(cls, data, key):
++        value = cls.safe_getitem(data, key)
++        cls.assert_is_not_lazy_object(value)
++
++    @staticmethod
++    def assert_is_lazy_object(obj):
++        assert isinstance(obj, LazyObject)
++
++    @staticmethod
++    def assert_is_not_lazy_object(obj):
++        assert not isinstance(obj, LazyObject)
++
++
++class TestLazyDict(object):
++    theory = LazyDictTheory
++
++    def test_unknown_item_access__should_raise_keyerror(self):
++        lazy_dict = LazyDict({"alice": 42})
++        item_access = lambda key: lazy_dict[key]
++        with pytest.raises(KeyError):
++            item_access("unknown")
++
++    def test_plain_item_access__should_succeed(self):
++        theory = LazyDictTheory
++        lazy_dict = LazyDict({"alice": 42})
++        theory.assert_item_is_not_lazy(lazy_dict, "alice")
++
++        value = lazy_dict["alice"]
++        assert value == 42
++
++    def test_lazy_item_access__should_load_object(self):
++        ImportModuleTheory.ensure_module_is_not_imported("inspect")
++        lazy_dict = LazyDict({"alice": LazyObject("inspect:ismodule")})
++        self.theory.assert_item_is_lazy(lazy_dict, "alice")
++        self.theory.assert_item_is_lazy(lazy_dict, "alice")
++
++        value = lazy_dict["alice"]
++        self.theory.assert_is_not_lazy_object(value)
++        self.theory.assert_item_is_not_lazy(lazy_dict, "alice")
++
++    def test_lazy_item_access__should_fail_with_unknown_module(self):
++        lazy_dict = LazyDict({"bob": LazyObject("__unknown_module__", "xxx")})
++        item_access = lambda key: lazy_dict[key]
++        with pytest.raises(ImportError):
++            item_access("bob")
++
++    def test_lazy_item_access__should_fail_with_unknown_object(self):
++        lazy_dict = LazyDict({
++            "bob": LazyObject("behave.importer", "XUnknown")
++        })
++        item_access = lambda key: lazy_dict[key]
++        with pytest.raises(ImportError):
++            item_access("bob")
diff --git a/meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch b/meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch
new file mode 100644
index 000000000..33738459d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch
@@ -0,0 +1,1815 @@
+From 65b17ccbea1a17b26e6191a1d7336088d0dd4181 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 09:10:52 +0200
+Subject: [PATCH] REMOVE-DEPENDENCY: nose (to avoid nose.importer warnings)
+
+Replace nose test-framework functionality w/ pytest.
+Move test/*.py => tests/unit/*.py
+---
+ MANIFEST.in                                   |   2 -
+ conftest.py                                   |  13 ++
+ invoke.yaml                                   |   1 +
+ py.requirements/ci.tox.txt                    |   9 +
+ py.requirements/ci.travis.txt                 |   1 -
+ py.requirements/develop.txt                   |   1 -
+ py.requirements/testing.txt                   |   3 +-
+ pytest.ini                                    |   7 +-
+ setup.py                                      |   8 +-
+ tasks/test.py                                 |   2 +-
+ test/__init__.py                              |   0
+ test/test_importer.py                         | 151 -------------
+ {test => tests/unit}/_importer_candidate.py   |   0
+ tests/unit/reporter/test_summary.py           |   2 -
+ .../test_tag_expression_v1_part1.py           |  17 +-
+ .../test_tag_expression_v1_part2.py           |  18 +-
+ {test => tests/unit}/test_ansi_escapes.py     |  14 +-
+ {test => tests/unit}/test_configuration.py    |  75 +++---
+ {test => tests/unit}/test_formatter.py        |  15 +-
+ .../unit}/test_formatter_progress.py          |   7 +
+ {test => tests/unit}/test_formatter_rerun.py  |  12 +-
+ {test => tests/unit}/test_formatter_tags.py   |   9 +
+ tests/unit/test_importer.py                   |   2 +-
+ {test => tests/unit}/test_log_capture.py      |   9 +-
+ {test => tests/unit}/test_matchers.py         |  24 +-
+ tests/unit/test_parser.py                     |   1 -
+ {test => tests/unit}/test_runner.py           | 213 ++++++++++--------
+ {test => tests/unit}/test_step_registry.py    |   5 +-
+ tests/unit/test_textutil.py                   |  12 +-
+ tox.ini                                       |  19 +-
+ 30 files changed, 283 insertions(+), 369 deletions(-)
+ create mode 100644 py.requirements/ci.tox.txt
+ delete mode 100644 test/__init__.py
+ delete mode 100644 test/test_importer.py
+ rename {test => tests/unit}/_importer_candidate.py (100%)
+ rename {test => tests/unit}/test_ansi_escapes.py (84%)
+ rename {test => tests/unit}/test_configuration.py (72%)
+ rename {test => tests/unit}/test_formatter.py (94%)
+ rename {test => tests/unit}/test_formatter_progress.py (99%)
+ rename {test => tests/unit}/test_formatter_rerun.py (94%)
+ rename {test => tests/unit}/test_formatter_tags.py (99%)
+ rename {test => tests/unit}/test_log_capture.py (87%)
+ rename {test => tests/unit}/test_matchers.py (93%)
+ rename {test => tests/unit}/test_runner.py (82%)
+ rename {test => tests/unit}/test_step_registry.py (95%)
+
+diff --git a/MANIFEST.in b/MANIFEST.in
+index 49cb7c6..60c2601 100644
+--- a/MANIFEST.in
++++ b/MANIFEST.in
+@@ -33,5 +33,3 @@ recursive-include py.requirements  *.txt
+ 
+ prune .tox
+ prune .venv*
+-prune paver_ext
+-exclude pavement.py
+diff --git a/conftest.py b/conftest.py
+index 7b3a883..71a3bd0 100644
+--- a/conftest.py
++++ b/conftest.py
+@@ -10,6 +10,10 @@ Add project-specific information.
+ import behave
+ import pytest
+ 
++
++# ---------------------------------------------------------------------------
++# PYTEST FIXTURES:
++# ---------------------------------------------------------------------------
+ @pytest.fixture(autouse=True)
+ def _annotate_environment(request):
+     """Add project-specific information to test-run environment:
+@@ -25,3 +29,12 @@ def _annotate_environment(request):
+         behave_version = behave.__version__
+         environment.append(("behave", behave_version))
+ 
++_pytest_version = pytest.__version__
++if _pytest_version >= "5.0":
++    # -- SUPPORTED SINCE: pytest 5.0
++    @pytest.fixture(scope="session", autouse=True)
++    def log_global_env_facts(record_testsuite_property):
++        # SEE: https://docs.pytest.org/en/latest/usage.html
++        behave_version = behave.__version__
++        record_testsuite_property("BEHAVE_VERSION", behave_version)
++
+diff --git a/invoke.yaml b/invoke.yaml
+index 4f21328..3e93cfc 100644
+--- a/invoke.yaml
++++ b/invoke.yaml
+@@ -23,6 +23,7 @@ sphinx:
+     languages:
+       - de
+       # PREPARED: - zh-CN
++
+ cleanup:
+     extra_directories:
+       - "build"
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+new file mode 100644
+index 0000000..6b3b3ae
+--- /dev/null
++++ b/py.requirements/ci.tox.txt
+@@ -0,0 +1,9 @@
++# ============================================================================
++# BEHAVE: PYTHON PACKAGE REQUIREMENTS: ci.tox.txt
++# ============================================================================
++
++pytest >= 4.2
++pytest-html >= 1.19.0
++mock >= 2.0
++PyHamcrest >= 1.9
++path.py >= 10.1
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 1cc0239..73d65f6 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,5 +1,4 @@
+ mock
+-nose
+ PyHamcrest >= 1.9
+ pytest >= 3.0
+ pytest-html >= 1.19.0
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index 3deedc7..d823389 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -14,7 +14,6 @@ pycmd
+ bumpversion >= 0.4.0
+ 
+ # -- DEVELOPMENT SUPPORT:
+-# PREPARED: nose-cov >= 1.4
+ tox   >= 1.8.1
+ coverage >= 4.2
+ pytest-cov
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 3806d39..a418739 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -4,9 +4,8 @@
+ 
+ # -- TESTING: Unit tests and behave self-tests.
+ # PREPARED-FUTURE: behave4cmd0, behave4cmd
+-pytest >= 3.0
++pytest >= 4.2
+ pytest-html >= 1.19.0
+-nose  >= 1.3
+ mock  >= 2.0
+ PyHamcrest >= 1.9
+ 
+diff --git a/pytest.ini b/pytest.ini
+index 17ad388..a686596 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -16,8 +16,8 @@
+ # ============================================================================
+ 
+ [pytest]
+-minversion    = 2.8
+-testpaths     = test tests
++minversion    = 4.2
++testpaths     = tests
+ python_files  = test_*.py
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+     --metadata PACKAGE_VERSION 1.2.7.dev1
+@@ -26,6 +26,7 @@ addopts = --metadata PACKAGE_UNDER_TEST behave
+ markers =
+     smoke
+     slow
++
+ # -- BACKWARD COMPATIBILITY: pytest < 2.8
+-norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
++# norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
+ 
+diff --git a/setup.py b/setup.py
+index ac7bddf..9c7560d 100644
+--- a/setup.py
++++ b/setup.py
+@@ -86,13 +86,11 @@ setup(
+         "win_unicode_console; python_version < '3.6'",
+         "colorama",
+     ],
+-    test_suite="nose.collector",
+     tests_require=[
+-        "pytest >= 3.0",
++        "pytest >= 4.2",
+         "pytest-html >= 1.19.0",
+-        "nose >= 1.3",
+         "mock >= 1.1",
+-        "PyHamcrest >= 1.8",
++        "PyHamcrest >= 1.9",
+         "path.py >= 11.5.0"
+     ],
+     cmdclass = {
+@@ -105,7 +103,7 @@ setup(
+         ],
+         "develop": [
+             "coverage",
+-            "pytest >= 3.0",
++            "pytest >= 4.2",
+             "pytest-html >= 1.19.0",
+             "pytest-cov",
+             "tox",
+diff --git a/tasks/test.py b/tasks/test.py
+index 06eb175..bfa2d80 100644
+--- a/tasks/test.py
++++ b/tasks/test.py
+@@ -172,7 +172,7 @@ namespace.configure({
+         },
+     },
+     "pytest": {
+-        "scopes":   ["test", "tests"],
++        "scopes":   ["tests"],
+         "args":   "",
+         "options": "",  # -- NOTE:  Overide in configfile "invoke.yaml"
+     },
+diff --git a/test/__init__.py b/test/__init__.py
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/test/test_importer.py b/test/test_importer.py
+deleted file mode 100644
+index baca21a..0000000
+--- a/test/test_importer.py
++++ /dev/null
+@@ -1,151 +0,0 @@
+-# -*- coding: utf-8 -*-
+-"""
+-Tests for behave.importing.
+-The module provides a lazy-loading/importing mechanism.
+-"""
+-
+-from __future__ import absolute_import
+-from behave.importer import LazyObject, LazyDict, load_module, parse_scoped_name
+-from behave.formatter.base import Formatter
+-from nose.tools import eq_, assert_raises
+-import sys
+-import types
+-# import unittest
+-
+-
+-class TestTheory(object): pass
+-class ImportModuleTheory(TestTheory):
+-    """
+-    Provides a test theory for importing modules.
+-    """
+-
+-    @classmethod
+-    def ensure_module_is_not_imported(cls, module_name):
+-        if module_name in sys.modules:
+-            del sys.modules[module_name]
+-        cls.assert_module_is_not_imported(module_name)
+-
+-    @staticmethod
+-    def assert_module_is_imported(module_name):
+-        module = sys.modules.get(module_name, None)
+-        assert module_name in sys.modules
+-        assert module is not None
+-
+-    @staticmethod
+-    def assert_module_is_not_imported(module_name):
+-        assert module_name not in sys.modules
+-
+-    @staticmethod
+-    def assert_module_with_name(module, name):
+-        assert isinstance(module, types.ModuleType)
+-        eq_(module.__name__, name)
+-
+-
+-class TestLoadModule(object):
+-    theory = ImportModuleTheory
+-
+-    def test_load_module__should_fail_for_unknown_module(self):
+-        assert_raises(ImportError, load_module, "__unknown_module__")
+-
+-    def test_load_module__should_succeed_for_already_imported_module(self):
+-        module_name = "behave.importer"
+-        self.theory.assert_module_is_imported(module_name)
+-
+-        module = load_module(module_name)
+-        self.theory.assert_module_with_name(module, module_name)
+-        self.theory.assert_module_is_imported(module_name)
+-
+-    def test_load_module__should_succeed_for_existing_module(self):
+-        module_name = "test._importer_candidate"
+-        self.theory.ensure_module_is_not_imported(module_name)
+-
+-        module = load_module(module_name)
+-        self.theory.assert_module_with_name(module, module_name)
+-        self.theory.assert_module_is_imported(module_name)
+-
+-class TestLazyObject(object):
+-
+-    def test_get__should_succeed_for_known_object(self):
+-        lazy = LazyObject("behave.importer", "LazyObject")
+-        value = lazy.get()
+-        assert value is LazyObject
+-
+-        lazy2 = LazyObject("behave.importer:LazyObject")
+-        value2 = lazy2.get()
+-        assert value2 is LazyObject
+-
+-        lazy3 = LazyObject("behave.formatter.steps", "StepsFormatter")
+-        value3 = lazy3.get()
+-        assert issubclass(value3, Formatter)
+-
+-    def test_get__should_fail_for_unknown_module(self):
+-        lazy = LazyObject("__unknown_module__", "xxx")
+-        assert_raises(ImportError, lazy.get)
+-
+-    def test_get__should_fail_for_unknown_object_in_module(self):
+-        lazy = LazyObject("test._importer_candidate", "xxx")
+-        assert_raises(ImportError, lazy.get)
+-
+-
+-class LazyDictTheory(TestTheory):
+-
+-    @staticmethod
+-    def safe_getitem(data, key):
+-        return dict.__getitem__(data, key)
+-
+-    @classmethod
+-    def assert_item_is_lazy(cls, data, key):
+-        value = cls.safe_getitem(data, key)
+-        cls.assert_is_lazy_object(value)
+-
+-    @classmethod
+-    def assert_item_is_not_lazy(cls, data, key):
+-        value = cls.safe_getitem(data, key)
+-        cls.assert_is_not_lazy_object(value)
+-
+-    @staticmethod
+-    def assert_is_lazy_object(obj):
+-        assert isinstance(obj, LazyObject)
+-
+-    @staticmethod
+-    def assert_is_not_lazy_object(obj):
+-        assert not isinstance(obj, LazyObject)
+-
+-
+-class TestLazyDict(object):
+-    theory = LazyDictTheory
+-
+-    def test_unknown_item_access__should_raise_keyerror(self):
+-        lazy_dict = LazyDict({"alice": 42})
+-        item_access = lambda key: lazy_dict[key]
+-        assert_raises(KeyError, item_access, "unknown")
+-
+-    def test_plain_item_access__should_succeed(self):
+-        theory = LazyDictTheory
+-        lazy_dict = LazyDict({"alice": 42})
+-        theory.assert_item_is_not_lazy(lazy_dict, "alice")
+-
+-        value = lazy_dict["alice"]
+-        eq_(value, 42)
+-
+-    def test_lazy_item_access__should_load_object(self):
+-        ImportModuleTheory.ensure_module_is_not_imported("inspect")
+-        lazy_dict = LazyDict({"alice": LazyObject("inspect:ismodule")})
+-        self.theory.assert_item_is_lazy(lazy_dict, "alice")
+-        self.theory.assert_item_is_lazy(lazy_dict, "alice")
+-
+-        value = lazy_dict["alice"]
+-        self.theory.assert_is_not_lazy_object(value)
+-        self.theory.assert_item_is_not_lazy(lazy_dict, "alice")
+-
+-    def test_lazy_item_access__should_fail_with_unknown_module(self):
+-        lazy_dict = LazyDict({"bob": LazyObject("__unknown_module__", "xxx")})
+-        item_access = lambda key: lazy_dict[key]
+-        assert_raises(ImportError, item_access, "bob")
+-
+-    def test_lazy_item_access__should_fail_with_unknown_object(self):
+-        lazy_dict = LazyDict({
+-            "bob": LazyObject("behave.importer", "XUnknown")
+-        })
+-        item_access = lambda key: lazy_dict[key]
+-        assert_raises(ImportError, item_access, "bob")
+diff --git a/test/_importer_candidate.py b/tests/unit/_importer_candidate.py
+similarity index 100%
+rename from test/_importer_candidate.py
+rename to tests/unit/_importer_candidate.py
+diff --git a/tests/unit/reporter/test_summary.py b/tests/unit/reporter/test_summary.py
+index d4e85b5..6b947bd 100644
+--- a/tests/unit/reporter/test_summary.py
++++ b/tests/unit/reporter/test_summary.py
+@@ -4,8 +4,6 @@ from __future__ import absolute_import, division
+ import sys
+ import pytest
+ from mock import Mock, patch
+-# NOT-NEEDED: from nose.tools import *
+-
+ from behave.model import ScenarioOutline, Scenario
+ from behave.model_core import Status
+ from behave.reporter.summary import SummaryReporter, format_summary
+diff --git a/tests/unit/tag_expression/test_tag_expression_v1_part1.py b/tests/unit/tag_expression/test_tag_expression_v1_part1.py
+index 619c710..56fb85d 100644
+--- a/tests/unit/tag_expression/test_tag_expression_v1_part1.py
++++ b/tests/unit/tag_expression/test_tag_expression_v1_part1.py
+@@ -2,7 +2,7 @@
+ 
+ from __future__ import absolute_import
+ from behave.tag_expression import TagExpression
+-from nose import tools
++import pytest
+ import unittest
+ 
+ 
+@@ -476,31 +476,34 @@ class TestTagExpressionFoo3OrNotBar4AndZap5(unittest.TestCase):
+         self.e = TagExpression(['foo:3,-bar', 'zap:5'])
+ 
+     def test_should_count_tags_for_positive_tags(self):
+-        tools.eq_(self.e.limits, {'foo': 3, 'zap': 5})
++        assert self.e.limits == {'foo': 3, 'zap': 5}
+ 
+     def test_should_match_foo_zap(self):
+         assert self.e.check(['foo', 'zap'])
+ 
++
+ class TestTagExpressionParsing(unittest.TestCase):
+     def setUp(self):
+         self.e = TagExpression([' foo:3 , -bar ', ' zap:5 '])
+ 
+     def test_should_have_limits(self):
+-        tools.eq_(self.e.limits, {'zap': 5, 'foo': 3})
++        assert self.e.limits == {'zap': 5, 'foo': 3}
++
+ 
+ class TestTagExpressionTagLimits(unittest.TestCase):
+     def test_should_be_counted_for_negative_tags(self):
+         e = TagExpression(['-todo:3'])
+-        tools.eq_(e.limits, {'todo': 3})
++        assert e.limits == {'todo': 3}
+ 
+     def test_should_be_counted_for_positive_tags(self):
+         e = TagExpression(['todo:3'])
+-        tools.eq_(e.limits, {'todo': 3})
++        assert e.limits == {'todo': 3}
+ 
+     def test_should_raise_an_error_for_inconsistent_limits(self):
+-        tools.assert_raises(Exception, TagExpression, ['todo:3', '-todo:4'])
++        with pytest.raises(Exception):
++            _ = TagExpression(['todo:3', '-todo:4'])
+ 
+     def test_should_allow_duplicate_consistent_limits(self):
+         e = TagExpression(['todo:3', '-todo:3'])
+-        tools.eq_(e.limits, {'todo': 3})
++        assert e.limits == {'todo': 3}
+ 
+diff --git a/tests/unit/tag_expression/test_tag_expression_v1_part2.py b/tests/unit/tag_expression/test_tag_expression_v1_part2.py
+index 690235b..cf619da 100644
+--- a/tests/unit/tag_expression/test_tag_expression_v1_part2.py
++++ b/tests/unit/tag_expression/test_tag_expression_v1_part2.py
+@@ -6,10 +6,11 @@ REQUIRES: Python >= 2.6, because itertools.combinations() is used.
+ """
+ 
+ from __future__ import absolute_import
+-from behave.tag_expression import TagExpression
+-from nose import tools
+ import itertools
+ from six.moves import range
++import pytest
++from behave.tag_expression import TagExpression
++
+ 
+ has_combinations = hasattr(itertools, "combinations")
+ if has_combinations:
+@@ -31,6 +32,7 @@ if has_combinations:
+             return "@" + " @".join(tags)
+         return NO_TAGS
+ 
++
+     TestCase = object
+     # ----------------------------------------------------------------------------
+     # TEST: all_combinations() test helper
+@@ -45,8 +47,8 @@ if has_combinations:
+                 ('@one', '@two'),
+             ]
+             actual = all_combinations(items)
+-            tools.eq_(actual, expected)
+-            tools.eq_(len(actual), 4)
++            assert actual == expected
++            assert len(actual) == 4
+ 
+         def test_all_combinations_with_3values(self):
+             items = "@one @two @three".split()
+@@ -61,8 +63,8 @@ if has_combinations:
+                 ('@one', '@two', '@three'),
+             ]
+             actual = all_combinations(items)
+-            tools.eq_(actual, expected)
+-            tools.eq_(len(actual), 8)
++            assert actual == expected
++            assert len(actual) == 8
+ 
+ 
+     # ----------------------------------------------------------------------------
+@@ -74,13 +76,13 @@ if has_combinations:
+                                           tag_combinations, expected):
+             matched = [ make_tags_line(c) for c in tag_combinations
+                                 if tag_expression.check(c) ]
+-            tools.eq_(matched, expected)
++            assert matched == expected
+ 
+         def assert_tag_expression_mismatches(self, tag_expression,
+                                             tag_combinations, expected):
+             mismatched = [ make_tags_line(c) for c in tag_combinations
+                                 if not tag_expression.check(c) ]
+-            tools.eq_(mismatched, expected)
++            assert mismatched == expected
+ 
+ 
+     class TestTagExpressionWith1Term(TagExpressionTestCase):
+diff --git a/test/test_ansi_escapes.py b/tests/unit/test_ansi_escapes.py
+similarity index 84%
+rename from test/test_ansi_escapes.py
+rename to tests/unit/test_ansi_escapes.py
+index 77564fd..969f3a9 100644
+--- a/test/test_ansi_escapes.py
++++ b/tests/unit/test_ansi_escapes.py
+@@ -7,7 +7,7 @@
+ #   W0621   Redefining name ... from outer scope
+ 
+ from __future__ import absolute_import
+-from nose import tools
++import pytest
+ from behave.formatter import ansi_escapes
+ import unittest
+ from six.moves import range
+@@ -44,30 +44,30 @@ class StripEscapesTest(unittest.TestCase):
+ 
+     def test_should_return_same_text_without_escapes(self):
+         for text in self.TEXTS:
+-            tools.eq_(text, ansi_escapes.strip_escapes(text))
++            assert text == ansi_escapes.strip_escapes(text)
+ 
+     def test_should_return_empty_string_for_any_ansi_escape(self):
+         # XXX-JE-CHECK-PY23: If list() is really needed.
+         for text in list(ansi_escapes.colors.values()):
+-            tools.eq_("", ansi_escapes.strip_escapes(text))
++            assert "" == ansi_escapes.strip_escapes(text)
+         for text in list(ansi_escapes.escapes.values()):
+-            tools.eq_("", ansi_escapes.strip_escapes(text))
++            assert "" == ansi_escapes.strip_escapes(text)
+ 
+ 
+     def test_should_strip_color_escapes_from_text(self):
+         for text in self.TEXTS:
+             colored_text = self.colorize_text(text, self.ALL_COLORS)
+-            tools.eq_(text, ansi_escapes.strip_escapes(colored_text))
++            assert text == ansi_escapes.strip_escapes(colored_text)
+             self.assertNotEqual(text, colored_text)
+ 
+             for color in self.ALL_COLORS:
+                 colored_text = self.colorize(text, color)
+-                tools.eq_(text, ansi_escapes.strip_escapes(colored_text))
++                assert text == ansi_escapes.strip_escapes(colored_text)
+                 self.assertNotEqual(text, colored_text)
+ 
+     def test_should_strip_cursor_up_escapes_from_text(self):
+         for text in self.TEXTS:
+             for cursor_up in self.CURSOR_UPS:
+                 colored_text = cursor_up + text + ansi_escapes.escapes["reset"]
+-                tools.eq_(text, ansi_escapes.strip_escapes(colored_text))
++                assert text == ansi_escapes.strip_escapes(colored_text)
+                 self.assertNotEqual(text, colored_text)
+diff --git a/test/test_configuration.py b/tests/unit/test_configuration.py
+similarity index 72%
+rename from test/test_configuration.py
+rename to tests/unit/test_configuration.py
+index e6828e3..c96cf63 100644
+--- a/test/test_configuration.py
++++ b/tests/unit/test_configuration.py
+@@ -2,7 +2,7 @@ import os.path
+ import sys
+ import tempfile
+ import six
+-from nose.tools import *
++import pytest
+ from behave import configuration
+ from behave.configuration import Configuration, UserData
+ from unittest import TestCase
+@@ -36,6 +36,7 @@ if sys.platform.startswith("win"):
+         ROOTDIR_PREFIX_DEFAULT = ROOTDIR_PREFIX_DEFAULT.lower()
+     ROOTDIR_PREFIX = os.environ.get("BEHAVE_ROOTDIR_PREFIX", ROOTDIR_PREFIX_DEFAULT)
+ 
++
+ class TestConfiguration(object):
+ 
+     def test_read_file(self):
+@@ -46,19 +47,19 @@ class TestConfiguration(object):
+ 
+         # -- WINDOWS-REQUIRES: normpath
+         d = configuration.read_configuration(tn)
+-        eq_(d["outfiles"], [
++        assert d["outfiles"] ==[
+             os.path.normpath(ROOTDIR_PREFIX + "/absolute/path1"),
+             os.path.normpath(os.path.join(tndir, "relative/path2")),
+-        ])
+-        eq_(d["paths"], [
++        ]
++        assert d["paths"] == [
+             os.path.normpath(ROOTDIR_PREFIX + "/absolute/path3"),
+             os.path.normpath(os.path.join(tndir, "relative/path4")),
+-            ])
+-        eq_(d["format"], ["pretty", "tag-counter"])
+-        eq_(d["default_tags"], ["@foo,~@bar", "@zap"])
+-        eq_(d["stdout_capture"], False)
+-        ok_("bogus" not in d)
+-        eq_(d["userdata"], {"foo": "bar", "answer": "42"})
++            ]
++        assert d["format"] == ["pretty", "tag-counter"]
++        assert d["default_tags"] == ["@foo,~@bar", "@zap"]
++        assert d["stdout_capture"] == False
++        assert "bogus" not in d
++        assert d["userdata"] == {"foo": "bar", "answer": "42"}
+ 
+     def ensure_stage_environment_is_not_set(self):
+         if "BEHAVE_STAGE" in os.environ:
+@@ -69,26 +70,26 @@ class TestConfiguration(object):
+         self.ensure_stage_environment_is_not_set()
+         assert "BEHAVE_STAGE" not in os.environ
+         config = Configuration("")
+-        eq_("steps", config.steps_dir)
+-        eq_("environment.py", config.environment_file)
++        assert "steps" == config.steps_dir
++        assert "environment.py" == config.environment_file
+ 
+     def test_settings_with_stage(self):
+         config = Configuration(["--stage=STAGE1"])
+-        eq_("STAGE1_steps", config.steps_dir)
+-        eq_("STAGE1_environment.py", config.environment_file)
++        assert "STAGE1_steps" == config.steps_dir
++        assert "STAGE1_environment.py" == config.environment_file
+ 
+     def test_settings_with_stage_and_envvar(self):
+         os.environ["BEHAVE_STAGE"] = "STAGE2"
+         config = Configuration(["--stage=STAGE1"])
+-        eq_("STAGE1_steps", config.steps_dir)
+-        eq_("STAGE1_environment.py", config.environment_file)
++        assert "STAGE1_steps" == config.steps_dir
++        assert "STAGE1_environment.py" == config.environment_file
+         del os.environ["BEHAVE_STAGE"]
+ 
+     def test_settings_with_stage_from_envvar(self):
+         os.environ["BEHAVE_STAGE"] = "STAGE2"
+         config = Configuration("")
+-        eq_("STAGE2_steps", config.steps_dir)
+-        eq_("STAGE2_environment.py", config.environment_file)
++        assert "STAGE2_steps" == config.steps_dir
++        assert "STAGE2_environment.py" == config.environment_file
+         del os.environ["BEHAVE_STAGE"]
+ 
+ 
+@@ -101,33 +102,33 @@ class TestConfigurationUserData(TestCase):
+             "--define=bar=bar_value",
+             "--define", "baz=BAZ_VALUE",
+         ])
+-        eq_("foo_value", config.userdata["foo"])
+-        eq_("bar_value", config.userdata["bar"])
+-        eq_("BAZ_VALUE", config.userdata["baz"])
++        assert "foo_value" == config.userdata["foo"]
++        assert "bar_value" == config.userdata["bar"]
++        assert "BAZ_VALUE" == config.userdata["baz"]
+ 
+     def test_cmdline_defines_override_configfile(self):
+         userdata_init = {"foo": "XXX", "bar": "ZZZ", "baz": 42}
+         config = Configuration(
+                     "-D foo=foo_value --define bar=123",
+                     load_config=False, userdata=userdata_init)
+-        eq_("foo_value", config.userdata["foo"])
+-        eq_("123", config.userdata["bar"])
+-        eq_(42, config.userdata["baz"])
++        assert "foo_value" == config.userdata["foo"]
++        assert "123" == config.userdata["bar"]
++        assert 42 == config.userdata["baz"]
+ 
+     def test_cmdline_defines_without_value_are_true(self):
+         config = Configuration("-D foo --define bar -Dbaz")
+-        eq_("true", config.userdata["foo"])
+-        eq_("true", config.userdata["bar"])
+-        eq_("true", config.userdata["baz"])
+-        eq_(True, config.userdata.getbool("foo"))
++        assert "true" == config.userdata["foo"]
++        assert "true" == config.userdata["bar"]
++        assert "true" == config.userdata["baz"]
++        assert True == config.userdata.getbool("foo")
+ 
+     def test_cmdline_defines_with_empty_value(self):
+         config = Configuration("-D foo=")
+-        eq_("", config.userdata["foo"])
++        assert "" == config.userdata["foo"]
+ 
+     def test_cmdline_defines_with_assign_character_as_value(self):
+         config = Configuration("-D foo=bar=baz")
+-        eq_("bar=baz", config.userdata["foo"])
++        assert "bar=baz" == config.userdata["foo"]
+ 
+     def test_cmdline_defines__with_quoted_name_value_pair(self):
+         cmdlines = [
+@@ -136,7 +137,7 @@ class TestConfigurationUserData(TestCase):
+         ]
+         for cmdline in cmdlines:
+             config = Configuration(cmdline, load_config=False)
+-            eq_(config.userdata, dict(person="Alice and Bob"))
++            assert config.userdata == dict(person="Alice and Bob")
+ 
+     def test_cmdline_defines__with_quoted_value(self):
+         cmdlines = [
+@@ -145,7 +146,7 @@ class TestConfigurationUserData(TestCase):
+         ]
+         for cmdline in cmdlines:
+             config = Configuration(cmdline, load_config=False)
+-            eq_(config.userdata, dict(person="Alice and Bob"))
++            assert config.userdata == dict(person="Alice and Bob")
+ 
+     def test_setup_userdata(self):
+         config = Configuration("", load_config=False)
+@@ -154,7 +155,7 @@ class TestConfigurationUserData(TestCase):
+         config.setup_userdata()
+ 
+         expected_data = dict(person1="Alice", person2="Charly")
+-        eq_(config.userdata, expected_data)
++        assert config.userdata == expected_data
+ 
+     def test_update_userdata__with_cmdline_defines(self):
+         # -- NOTE: cmdline defines are reapplied.
+@@ -163,8 +164,8 @@ class TestConfigurationUserData(TestCase):
+         config.update_userdata(dict(person1="Alice", person2="Bob"))
+ 
+         expected_data = dict(person1="Alice", person2="Bea", person3="Charly")
+-        eq_(config.userdata, expected_data)
+-        eq_(config.userdata_defines, [("person2", "Bea")])
++        assert config.userdata == expected_data
++        assert config.userdata_defines == [("person2", "Bea")]
+ 
+     def test_update_userdata__without_cmdline_defines(self):
+         config = Configuration("", load_config=False)
+@@ -172,5 +173,5 @@ class TestConfigurationUserData(TestCase):
+         config.update_userdata(dict(person1="Alice", person2="Bob"))
+ 
+         expected_data = dict(person1="Alice", person2="Bob", person3="Charly")
+-        eq_(config.userdata, expected_data)
+-        self.assertFalse(config.userdata_defines)
++        assert config.userdata == expected_data
++        assert config.userdata_defines is None
+diff --git a/test/test_formatter.py b/tests/unit/test_formatter.py
+similarity index 94%
+rename from test/test_formatter.py
+rename to tests/unit/test_formatter.py
+index 42e5f0d..c1a0945 100644
+--- a/test/test_formatter.py
++++ b/tests/unit/test_formatter.py
+@@ -6,9 +6,8 @@ import sys
+ import tempfile
+ import unittest
+ import six
++import pytest
+ from mock import Mock, patch
+-from nose.tools import *    # pylint: disable=wildcard-import, unused-wildcard-import
+-
+ from behave.formatter._registry import make_formatters
+ from behave.formatter import pretty
+ from behave.formatter.base import StreamOpener
+@@ -35,7 +34,7 @@ class TestGetTerminalSize(unittest.TestCase):
+         platform = sys.platform
+         sys.platform = "windows"
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+ 
+         sys.platform = platform
+ 
+@@ -46,7 +45,7 @@ class TestGetTerminalSize(unittest.TestCase):
+         except ImportError:
+             pass
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+ 
+     def test_exception_in_ioctl(self):
+         try:
+@@ -59,7 +58,7 @@ class TestGetTerminalSize(unittest.TestCase):
+ 
+         self.ioctl.side_effect = raiser
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+         self.ioctl.assert_called_with(0, termios.TIOCGWINSZ, self.zero_struct)
+ 
+     def test_happy_path(self):
+@@ -70,7 +69,7 @@ class TestGetTerminalSize(unittest.TestCase):
+ 
+         self.ioctl.return_value = struct.pack("HHHH", 17, 23, 5, 5)
+ 
+-        eq_(pretty.get_terminal_size(), (23, 17))
++        assert pretty.get_terminal_size() == (23, 17)
+         self.ioctl.assert_called_with(0, termios.TIOCGWINSZ, self.zero_struct)
+ 
+     def test_zero_size_fallback(self):
+@@ -81,7 +80,7 @@ class TestGetTerminalSize(unittest.TestCase):
+ 
+         self.ioctl.return_value = self.zero_struct
+ 
+-        eq_(pretty.get_terminal_size(), (80, 24))
++        assert pretty.get_terminal_size() == (80, 24)
+         self.ioctl.assert_called_with(0, termios.TIOCGWINSZ, self.zero_struct)
+ 
+ 
+@@ -204,7 +203,7 @@ class TestTagsCount(FormatterTests):
+         p.feature(f)
+         p.scenario(s)
+ 
+-        eq_(p.tag_counts, {"ham": [f, s], "spam": [f], "foo": [s]})
++        assert p.tag_counts == {"ham": [f, s], "spam": [f], "foo": [s]}
+ 
+ 
+ class MultipleFormattersTests(FormatterTests):
+diff --git a/test/test_formatter_progress.py b/tests/unit/test_formatter_progress.py
+similarity index 99%
+rename from test/test_formatter_progress.py
+rename to tests/unit/test_formatter_progress.py
+index 29c8e68..19cdf64 100644
+--- a/test/test_formatter_progress.py
++++ b/tests/unit/test_formatter_progress.py
+@@ -9,6 +9,7 @@ from __future__ import absolute_import
+ from .test_formatter import FormatterTests as FormatterTest
+ from .test_formatter import MultipleFormattersTests as MultipleFormattersTest
+ 
++
+ class TestScenarioProgressFormatter(FormatterTest):
+     formatter_name = "progress"
+ 
+@@ -20,20 +21,26 @@ class TestStepProgressFormatter(FormatterTest):
+ class TestPrettyAndScenarioProgress(MultipleFormattersTest):
+     formatters = ['pretty', 'progress']
+ 
++
+ class TestPlainAndScenarioProgress(MultipleFormattersTest):
+     formatters = ['plain', 'progress']
+ 
++
+ class TestJSONAndScenarioProgress(MultipleFormattersTest):
+     formatters = ['json', 'progress']
+ 
++
+ class TestPrettyAndStepProgress(MultipleFormattersTest):
+     formatters = ['pretty', 'progress2']
+ 
++
+ class TestPlainAndStepProgress(MultipleFormattersTest):
+     formatters = ['plain', 'progress2']
+ 
++
+ class TestJSONAndStepProgress(MultipleFormattersTest):
+     formatters = ['json', 'progress2']
+ 
++
+ class TestScenarioProgressAndStepProgress(MultipleFormattersTest):
+     formatters = ['progress', 'progress2']
+diff --git a/test/test_formatter_rerun.py b/tests/unit/test_formatter_rerun.py
+similarity index 94%
+rename from test/test_formatter_rerun.py
+rename to tests/unit/test_formatter_rerun.py
+index 6357f92..154588f 100644
+--- a/test/test_formatter_rerun.py
++++ b/tests/unit/test_formatter_rerun.py
+@@ -8,7 +8,7 @@ from __future__ import absolute_import
+ from behave.model_core import Status
+ from .test_formatter import FormatterTests as FormatterTest, _tf
+ from .test_formatter import MultipleFormattersTests as MultipleFormattersTest
+-from nose.tools import *
++
+ 
+ class TestRerunFormatter(FormatterTest):
+     formatter_name = "rerun"
+@@ -26,7 +26,7 @@ class TestRerunFormatter(FormatterTest):
+             p.scenario(scenario)
+             assert scenario.status == Status.passed
+         p.eof()
+-        eq_([], p.failed_scenarios)
++        assert [] == p.failed_scenarios
+         # -- EMIT REPORT:
+         p.close()
+ 
+@@ -49,7 +49,7 @@ class TestRerunFormatter(FormatterTest):
+         assert scenarios[0].status == Status.passed
+         assert scenarios[1].status == Status.failed
+         p.eof()
+-        eq_([ failing_scenario ], p.failed_scenarios)
++        assert [ failing_scenario ] == p.failed_scenarios
+         # -- EMIT REPORT:
+         p.close()
+ 
+@@ -76,7 +76,7 @@ class TestRerunFormatter(FormatterTest):
+         assert scenarios[1].status == Status.passed
+         assert scenarios[2].status == Status.failed
+         p.eof()
+-        eq_([ failing_scenario1, failing_scenario2 ], p.failed_scenarios)
++        assert [ failing_scenario1, failing_scenario2 ] == p.failed_scenarios
+         # -- EMIT REPORT:
+         p.close()
+ 
+@@ -84,14 +84,18 @@ class TestRerunFormatter(FormatterTest):
+ class TestRerunAndPrettyFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "pretty"]
+ 
++
+ class TestRerunAndPlainFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "plain"]
+ 
++
+ class TestRerunAndScenarioProgressFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "progress"]
+ 
++
+ class TestRerunAndStepProgressFormatters(MultipleFormattersTest):
+     formatters = ["rerun", "progress2"]
+ 
++
+ class TestRerunAndJsonFormatter(MultipleFormattersTest):
+     formatters = ["rerun", "json"]
+diff --git a/test/test_formatter_tags.py b/tests/unit/test_formatter_tags.py
+similarity index 99%
+rename from test/test_formatter_tags.py
+rename to tests/unit/test_formatter_tags.py
+index 5125d51..9f95374 100644
+--- a/test/test_formatter_tags.py
++++ b/tests/unit/test_formatter_tags.py
+@@ -9,12 +9,14 @@ from __future__ import absolute_import
+ from .test_formatter import FormatterTests as FormatterTest
+ from .test_formatter import MultipleFormattersTests as MultipleFormattersTest
+ 
++
+ # -----------------------------------------------------------------------------
+ # FORMATTER TESTS: With TagCountFormatter
+ # -----------------------------------------------------------------------------
+ class TestTagsCountFormatter(FormatterTest):
+     formatter_name = "tags"
+ 
++
+ # -----------------------------------------------------------------------------
+ # FORMATTER TESTS: With TagLocationFormatter
+ # -----------------------------------------------------------------------------
+@@ -28,12 +30,15 @@ class TestTagsLocationFormatter(FormatterTest):
+ class TestPrettyAndTagsCount(MultipleFormattersTest):
+     formatters = ["pretty", "tags"]
+ 
++
+ class TestPlainAndTagsCount(MultipleFormattersTest):
+     formatters = ["plain", "tags"]
+ 
++
+ class TestJSONAndTagsCount(MultipleFormattersTest):
+     formatters = ["json", "tags"]
+ 
++
+ class TestRerunAndTagsCount(MultipleFormattersTest):
+     formatters = ["rerun", "tags"]
+ 
+@@ -44,14 +49,18 @@ class TestRerunAndTagsCount(MultipleFormattersTest):
+ class TestPrettyAndTagsLocation(MultipleFormattersTest):
+     formatters = ["pretty", "tags.location"]
+ 
++
+ class TestPlainAndTagsLocation(MultipleFormattersTest):
+     formatters = ["plain", "tags.location"]
+ 
++
+ class TestJSONAndTagsLocation(MultipleFormattersTest):
+     formatters = ["json", "tags.location"]
+ 
++
+ class TestRerunAndTagsLocation(MultipleFormattersTest):
+     formatters = ["rerun", "tags.location"]
+ 
++
+ class TestTagsCountAndTagsLocation(MultipleFormattersTest):
+     formatters = ["tags", "tags.location"]
+diff --git a/tests/unit/test_importer.py b/tests/unit/test_importer.py
+index f3f4e2c..055b9fb 100644
+--- a/tests/unit/test_importer.py
++++ b/tests/unit/test_importer.py
+@@ -62,7 +62,7 @@ class TestLoadModule(object):
+         self.theory.assert_module_is_imported(module_name)
+ 
+     def test_load_module__should_succeed_for_existing_module(self):
+-        module_name = "test._importer_candidate"
++        module_name = "tests.unit._importer_candidate"
+         self.theory.ensure_module_is_not_imported(module_name)
+ 
+         module = load_module(module_name)
+diff --git a/test/test_log_capture.py b/tests/unit/test_log_capture.py
+similarity index 87%
+rename from test/test_log_capture.py
+rename to tests/unit/test_log_capture.py
+index bfdbed7..bf1874c 100644
+--- a/test/test_log_capture.py
++++ b/tests/unit/test_log_capture.py
+@@ -1,11 +1,10 @@
+ from __future__ import absolute_import, with_statement
+-
+-from nose.tools import *
++import pytest
+ from mock import patch
+-
+ from behave.log_capture import LoggingCapture
+ from six.moves import range
+ 
++
+ class TestLogCapture(object):
+     def test_get_value_returns_all_log_records(self):
+         class FakeConfig(object):
+@@ -23,7 +22,7 @@ class TestLogCapture(object):
+             format.return_value = 'foo'
+             expected = '\n'.join(['foo'] * len(fake_records))
+ 
+-            eq_(handler.getvalue(), expected)
++            assert handler.getvalue() == expected
+ 
+             calls = [args[0][0] for args in format.call_args_list]
+-            eq_(calls, fake_records)
++            assert calls == fake_records
+diff --git a/test/test_matchers.py b/tests/unit/test_matchers.py
+similarity index 93%
+rename from test/test_matchers.py
+rename to tests/unit/test_matchers.py
+index bfe04fc..815581c 100644
+--- a/test/test_matchers.py
++++ b/tests/unit/test_matchers.py
+@@ -1,7 +1,7 @@
+ # -*- coding: UTF-8 -*-
+ from __future__ import absolute_import, with_statement
++import pytest
+ from mock import Mock, patch
+-from nose.tools import *  # pylint: disable=wildcard-import, unused-wildcard-import
+ import parse
+ from behave.matchers import Match, Matcher, ParseMatcher, RegexMatcher, \
+     SimplifiedRegexMatcher, CucumberRegexMatcher
+@@ -80,7 +80,7 @@ class TestParseMatcher(object):
+             assert m.func is func
+             args = m.arguments
+             have = [(a.start, a.end, a.original, a.value, a.name) for a in args]
+-            eq_(have, expected)
++            assert have == expected
+ 
+     def test_named_arguments(self):
+         text = "has a {string}, an {integer:d} and a {decimal:f}"
+@@ -89,11 +89,11 @@ class TestParseMatcher(object):
+ 
+         m = matcher.match("has a foo, an 11 and a 3.14159")
+         m.run(context)
+-        eq_(self.recorded_args, ((context,), {
++        assert self.recorded_args, ((context,) == {
+             'string': 'foo',
+             'integer': 11,
+             'decimal': 3.14159
+-        }))
++        })
+ 
+     def test_positional_arguments(self):
+         text = "has a {}, an {:d} and a {:f}"
+@@ -102,7 +102,7 @@ class TestParseMatcher(object):
+ 
+         m = matcher.match("has a foo, an 11 and a 3.14159")
+         m.run(context)
+-        eq_(self.recorded_args, ((context, 'foo', 11, 3.14159), {}))
++        assert self.recorded_args == ((context, 'foo', 11, 3.14159), {})
+ 
+ class TestRegexMatcher(object):
+     # pylint: disable=invalid-name, no-self-use
+@@ -151,7 +151,7 @@ class TestRegexMatcher(object):
+         assert m.func is func
+         args = m.arguments
+         have = [(a.start, a.end, a.original, a.value, a.name) for a in args]
+-        eq_(have, expected)
++        assert have == expected
+ 
+ 
+ 
+@@ -179,17 +179,17 @@ class TestSimplifiedRegexMatcher(TestRegexMatcher):
+         assert isinstance(matched1, Match)
+         assert isinstance(matched2, Match)
+ 
+-    @raises(AssertionError)
+     def test_step_should_not_use_regex_begin_marker(self):
+-        SimplifiedRegexMatcher(None, "^I do something")
++        with pytest.raises(AssertionError):
++            SimplifiedRegexMatcher(None, "^I do something")
+ 
+-    @raises(AssertionError)
+     def test_step_should_not_use_regex_end_marker(self):
+-        SimplifiedRegexMatcher(None, "I do something$")
++        with pytest.raises(AssertionError):
++            SimplifiedRegexMatcher(None, "I do something$")
+ 
+-    @raises(AssertionError)
+     def test_step_should_not_use_regex_begin_and_end_marker(self):
+-        SimplifiedRegexMatcher(None, "^I do something$")
++        with pytest.raises(AssertionError):
++            SimplifiedRegexMatcher(None, "^I do something$")
+ 
+ 
+ class TestCucumberRegexMatcher(TestRegexMatcher):
+diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py
+index 5603a4b..ecbb1bf 100644
+--- a/tests/unit/test_parser.py
++++ b/tests/unit/test_parser.py
+@@ -7,7 +7,6 @@ Unit tests for Gherkin parser: :mod:`behave.parser`.
+ from __future__ import absolute_import, print_function
+ import pytest
+ from behave import i18n, model, parser
+-# NOT-NEEDED: from nose.tools import *
+ 
+ 
+ # ---------------------------------------------------------------------------
+diff --git a/test/test_runner.py b/tests/unit/test_runner.py
+similarity index 82%
+rename from test/test_runner.py
+rename to tests/unit/test_runner.py
+index 6647283..030dffa 100644
+--- a/test/test_runner.py
++++ b/tests/unit/test_runner.py
+@@ -11,10 +11,8 @@ import tempfile
+ import unittest
+ import six
+ from six import StringIO
+-
++import pytest
+ from mock import Mock, patch
+-from nose.tools import *  # pylint: disable=wildcard-import, unused-wildcard-import
+-
+ from behave import runner_util
+ from behave.model import Table
+ from behave.step_registry import StepRegistry
+@@ -39,31 +37,31 @@ class TestContext(unittest.TestCase):
+     def test_user_mode_shall_restore_behave_mode(self):
+         # -- CASE: No exception is raised.
+         initial_mode = runner.Context.BEHAVE
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+         with self.context.use_with_user_mode():
+-            eq_(self.context._mode, runner.Context.USER)
++            assert self.context._mode == runner.Context.USER
+             self.context.thing = "stuff"
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_assert_fails(self):
+         initial_mode = runner.Context.BEHAVE
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                eq_(self.context._mode, runner.Context.USER)
++                assert self.context._mode == runner.Context.USER
+                 assert False, "XFAIL"
+         except AssertionError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_exception_is_raised(self):
+         initial_mode = runner.Context.BEHAVE
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                eq_(self.context._mode, runner.Context.USER)
++                assert self.context._mode == runner.Context.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_use_with_user_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+@@ -71,9 +69,9 @@ class TestContext(unittest.TestCase):
+         initial_mode = runner.Context.BEHAVE
+         self.context._mode = initial_mode
+         with self.context.use_with_user_mode():
+-            eq_(self.context._mode, runner.Context.USER)
++            assert self.context._mode == runner.Context.USER
+             self.context.thing = "stuff"
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+ 
+     def test_use_with_user_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+@@ -82,10 +80,10 @@ class TestContext(unittest.TestCase):
+         self.context._mode = initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                eq_(self.context._mode, runner.Context.USER)
++                assert self.context._mode == runner.Context.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_use_with_behave_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+@@ -93,9 +91,9 @@ class TestContext(unittest.TestCase):
+         initial_mode = runner.Context.USER
+         self.context._mode = initial_mode
+         with self.context._use_with_behave_mode():
+-            eq_(self.context._mode, runner.Context.BEHAVE)
++            assert self.context._mode == runner.Context.BEHAVE
+             self.context.thing = "stuff"
+-        eq_(self.context._mode, initial_mode)
++        assert self.context._mode == initial_mode
+ 
+     def test_use_with_behave_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+@@ -104,22 +102,22 @@ class TestContext(unittest.TestCase):
+         self.context._mode = initial_mode
+         try:
+             with self.context._use_with_behave_mode():
+-                eq_(self.context._mode, runner.Context.BEHAVE)
++                assert self.context._mode == runner.Context.BEHAVE
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+-            eq_(self.context._mode, initial_mode)
++            assert self.context._mode == initial_mode
+ 
+     def test_context_contains(self):
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+         self.context.thing = "stuff"
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+         self.context._push()
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+ 
+     def test_attribute_set_at_upper_level_visible_at_lower_level(self):
+         self.context.thing = "stuff"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
++        assert self.context.thing == "stuff"
+ 
+     def test_attribute_set_at_lower_level_not_visible_at_upper_level(self):
+         self.context._push()
+@@ -130,16 +128,16 @@ class TestContext(unittest.TestCase):
+     def test_attributes_set_at_upper_level_visible_at_lower_level(self):
+         self.context.thing = "stuff"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
++        assert self.context.thing == "stuff"
+         self.context.other_thing = "more stuff"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
+         self.context.third_thing = "wombats"
+         self.context._push()
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
+-        eq_(self.context.third_thing, "wombats")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
++        assert self.context.third_thing == "wombats"
+ 
+     def test_attributes_set_at_lower_level_not_visible_at_upper_level(self):
+         self.context.thing = "stuff"
+@@ -149,17 +147,17 @@ class TestContext(unittest.TestCase):
+ 
+         self.context._push()
+         self.context.third_thing = "wombats"
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
+-        eq_(self.context.third_thing, "wombats")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
++        assert self.context.third_thing == "wombats"
+ 
+         self.context._pop()
+-        eq_(self.context.thing, "stuff")
+-        eq_(self.context.other_thing, "more stuff")
++        assert self.context.thing == "stuff"
++        assert self.context.other_thing == "more stuff"
+         assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
+ 
+         self.context._pop()
+-        eq_(self.context.thing, "stuff")
++        assert self.context.thing == "stuff"
+         assert getattr(self.context, "other_thing", None) is None, "%s is not None" % self.context.other_thing
+         assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
+ 
+@@ -270,21 +268,22 @@ class TestContext(unittest.TestCase):
+         assert filename in info, "%r not in %r" % (filename, info)
+ 
+     def test_context_deletable(self):
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+         self.context.thing = "stuff"
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+         del self.context.thing
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+ 
+-    @raises(AttributeError)
++    # OLD: @raises(AttributeError)
+     def test_context_deletable_raises(self):
+         # pylint: disable=protected-access
+-        eq_("thing" in self.context, False)
++        assert "thing" not in self.context
+         self.context.thing = "stuff"
+-        eq_("thing" in self.context, True)
++        assert "thing" in self.context
+         self.context._push()
+-        eq_("thing" in self.context, True)
+-        del self.context.thing
++        assert "thing" in self.context
++        with pytest.raises(AttributeError):
++            del self.context.thing
+ 
+ 
+ class ExampleSteps(object):
+@@ -362,7 +361,7 @@ Then a step passes
+ """.lstrip()
+         with patch("behave.step_registry.registry", self.step_registry):
+             result = self.context.execute_steps(doc)
+-            eq_(result, True)
++            assert result is True
+ 
+     def test_execute_steps_with_failing_step(self):
+         doc = u"""
+@@ -374,7 +373,7 @@ Then a step passes
+             try:
+                 result = self.context.execute_steps(doc)
+             except AssertionError as e:
+-                ok_("FAILED SUB-STEP: When a step fails" in _text(e))
++                assert "FAILED SUB-STEP: When a step fails" in _text(e)
+ 
+     def test_execute_steps_with_undefined_step(self):
+         doc = u"""
+@@ -386,7 +385,7 @@ Then a step passes
+             try:
+                 result = self.context.execute_steps(doc)
+             except AssertionError as e:
+-                ok_("UNDEFINED SUB-STEP: When a step is undefined" in _text(e))
++                assert "UNDEFINED SUB-STEP: When a step is undefined" in _text(e)
+ 
+     def test_execute_steps_with_text(self):
+         doc = u'''
+@@ -401,8 +400,8 @@ Then a step passes
+         with patch("behave.step_registry.registry", self.step_registry):
+             result = self.context.execute_steps(doc)
+             expected_text = "Lorem ipsum\nIpsum lorem"
+-            eq_(result, True)
+-            eq_(expected_text, ExampleSteps.text)
++            assert result is True
++            assert expected_text == ExampleSteps.text
+ 
+     def test_execute_steps_with_table(self):
+         doc = u"""
+@@ -419,8 +418,8 @@ Then a step passes
+                     [u"Alice", u"12"],
+                     [u"Bob",   u"23"],
+             ])
+-            eq_(result, True)
+-            eq_(expected_table, ExampleSteps.table)
++            assert result is True
++            assert expected_table == ExampleSteps.table
+ 
+     def test_context_table_is_restored_after_execute_steps_without_table(self):
+         doc = u"""
+@@ -431,7 +430,7 @@ Then a step passes
+             original_table = "<ORIGINAL_TABLE>"
+             self.context.table = original_table
+             self.context.execute_steps(doc)
+-            eq_(self.context.table, original_table)
++            assert self.context.table == original_table
+ 
+     def test_context_table_is_restored_after_execute_steps_with_table(self):
+         doc = u"""
+@@ -445,7 +444,7 @@ Then a step passes
+             original_table = "<ORIGINAL_TABLE>"
+             self.context.table = original_table
+             self.context.execute_steps(doc)
+-            eq_(self.context.table, original_table)
++            assert self.context.table == original_table
+ 
+     def test_context_text_is_restored_after_execute_steps_without_text(self):
+         doc = u"""
+@@ -456,7 +455,7 @@ Then a step passes
+             original_text = "<ORIGINAL_TEXT>"
+             self.context.text = original_text
+             self.context.execute_steps(doc)
+-            eq_(self.context.text, original_text)
++            assert self.context.text == original_text
+ 
+     def test_context_text_is_restored_after_execute_steps_with_text(self):
+         doc = u'''
+@@ -471,10 +470,10 @@ When a step with text:
+             original_text = "<ORIGINAL_TEXT>"
+             self.context.text = original_text
+             self.context.execute_steps(doc)
+-            eq_(self.context.text, original_text)
++            assert self.context.text == original_text
+ 
+ 
+-    @raises(ValueError)
++    # OLD: @raises(ValueError)
+     def test_execute_steps_should_fail_when_called_without_feature(self):
+         doc = u"""
+ Given a passes
+@@ -482,7 +481,8 @@ Then a step passes
+ """.lstrip()
+         with patch("behave.step_registry.registry", self.step_registry):
+             self.context.feature = None
+-            self.context.execute_steps(doc)
++            with pytest.raises(ValueError):
++                self.context.execute_steps(doc)
+ 
+ 
+ def create_mock_config():
+@@ -588,11 +588,11 @@ class TestRunner(object):
+         r.setup_capture()
+         r.start_capture()
+ 
+-        eq_(sys.stdout, r.capture_controller.stdout_capture)
++        assert sys.stdout == r.capture_controller.stdout_capture
+ 
+         r.stop_capture()
+ 
+-        eq_(sys.stdout, new_stdout)
++        assert sys.stdout == new_stdout
+ 
+         sys.stdout = old_stdout
+ 
+@@ -605,11 +605,11 @@ class TestRunner(object):
+ 
+         r.start_capture()
+ 
+-        eq_(sys.stdout, old_stdout)
++        assert sys.stdout == old_stdout
+ 
+         r.stop_capture()
+ 
+-        eq_(sys.stdout, old_stdout)
++        assert sys.stdout == old_stdout
+ 
+     def test_teardown_capture_removes_log_tap(self):
+         r = runner.Runner(Mock())
+@@ -633,7 +633,7 @@ class TestRunner(object):
+         # pylint: disable=too-many-format-args
+         assert "spam" in l, '"spam" variable not set in locals (%r)' % (g, l)
+         # pylint: enable=too-many-format-args
+-        eq_(l["spam"], fn)
++        assert l["spam"] == fn
+ 
+     def test_run_returns_true_if_everything_passed(self):
+         r = runner.Runner(Mock())
+@@ -694,11 +694,11 @@ class TestRunWithPaths(unittest.TestCase):
+         self.runner.context = Mock()
+         self.runner.run_with_paths()
+ 
+-        eq_(self.run_hook.call_args_list, [
++        assert self.run_hook.call_args_list == [
+             ((), {}),
+             (("before_all", self.runner.context), {}),
+             (("after_all", self.runner.context), {}),
+-        ])
++        ]
+ 
+     @patch("behave.parser.parse_file")
+     @patch("os.path.abspath")
+@@ -724,8 +724,8 @@ class TestRunWithPaths(unittest.TestCase):
+ 
+         expected_parse_file_args = \
+             [((x.upper(),), {"language": "fritz"}) for x in feature_locations]
+-        eq_(parse_file.call_args_list, expected_parse_file_args)
+-        eq_(self.runner.features, [feature] * 3)
++        assert parse_file.call_args_list == expected_parse_file_args
++        assert self.runner.features == [feature] * 3
+ 
+ 
+ class FsMock(object):
+@@ -829,9 +829,12 @@ class TestFeatureDirectory(object):
+ 
+         # will look for a "features" directory and not find one
+         with patch("os.path", fs):
+-            assert_raises(ConfigError, r.setup_paths)
++            with pytest.raises(ConfigError):
++                r.setup_paths()
++            # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        # ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+ 
+     def test_default_path_no_features(self):
+         config = create_mock_config()
+@@ -842,7 +845,9 @@ class TestFeatureDirectory(object):
+         fs = FsMock("features/steps/")
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+     def test_default_path(self):
+         config = create_mock_config()
+@@ -857,7 +862,7 @@ class TestFeatureDirectory(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        eq_(r.base_dir, os.path.abspath("features"))
++        assert r.base_dir == os.path.abspath("features")
+ 
+     def test_supplied_feature_file(self):
+         config = create_mock_config()
+@@ -872,10 +877,12 @@ class TestFeatureDirectory(object):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+                     r.setup_paths()
+-        ok_(("isdir", os.path.join(fs.base, "steps")) in fs.calls)
+-        ok_(("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "steps")) in fs.calls
++        assert ("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls
++        # OLD: ok_(("isdir", os.path.join(fs.base, "steps")) in fs.calls)
++        # OLD: ok_(("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls)
+ 
+-        eq_(r.base_dir, fs.base)
++        assert r.base_dir == fs.base
+ 
+     def test_supplied_feature_file_no_steps(self):
+         config = create_mock_config()
+@@ -888,7 +895,9 @@ class TestFeatureDirectory(object):
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+-                    assert_raises(ConfigError, r.setup_paths)
++                    with pytest.raises(ConfigError):
++                        r.setup_paths()
++                    # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+     def test_supplied_feature_directory(self):
+         config = create_mock_config()
+@@ -903,9 +912,10 @@ class TestFeatureDirectory(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls
++        # OLD ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
+ 
+-        eq_(r.base_dir, os.path.join(fs.base, "spam"))
++        assert r.base_dir == os.path.join(fs.base, "spam")
+ 
+     def test_supplied_feature_directory_no_steps(self):
+         config = create_mock_config()
+@@ -917,9 +927,12 @@ class TestFeatureDirectory(object):
+ 
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls
++        # OLD: ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
+ 
+     def test_supplied_feature_directory_missing(self):
+         config = create_mock_config()
+@@ -931,7 +944,9 @@ class TestFeatureDirectory(object):
+ 
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+ 
+ class TestFeatureDirectoryLayout2(object):
+@@ -955,7 +970,7 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        eq_(r.base_dir, os.path.abspath("features"))
++        assert r.base_dir == os.path.abspath("features")
+ 
+     def test_supplied_root_directory(self):
+         config = create_mock_config()
+@@ -975,8 +990,9 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+-        eq_(r.base_dir, os.path.join(fs.base, "features"))
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        assert r.base_dir == os.path.join(fs.base, "features")
+ 
+     def test_supplied_root_directory_no_steps(self):
+         config = create_mock_config()
+@@ -993,10 +1009,13 @@ class TestFeatureDirectoryLayout2(object):
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+-                    assert_raises(ConfigError, r.setup_paths)
++                    with pytest.raises(ConfigError):
++                        r.setup_paths()
++                    # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+-        eq_(r.base_dir, None)
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        assert r.base_dir is None
+ 
+ 
+     def test_supplied_feature_file(self):
+@@ -1018,9 +1037,11 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps"))  in fs.calls)
+-        ok_(("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls)
+-        eq_(r.base_dir, fs.join(fs.base, "features"))
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps"))  in fs.calls)
++        # OLD: ok_(("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps"))  in fs.calls
++        assert ("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls
++        assert r.base_dir == fs.join(fs.base, "features")
+ 
+     def test_supplied_feature_file_no_steps(self):
+         config = create_mock_config()
+@@ -1037,7 +1058,9 @@ class TestFeatureDirectoryLayout2(object):
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+                 with r.path_manager:
+-                    assert_raises(ConfigError, r.setup_paths)
++                    with pytest.raises(ConfigError):
++                        r.setup_paths()
++                    # OLD assert_raises(ConfigError, r.setup_paths)
+ 
+     def test_supplied_feature_directory(self):
+         config = create_mock_config()
+@@ -1057,8 +1080,9 @@ class TestFeatureDirectoryLayout2(object):
+                 with r.path_manager:
+                     r.setup_paths()
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
+-        eq_(r.base_dir, os.path.join(fs.base, "features"))
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
++        assert r.base_dir == os.path.join(fs.base, "features")
+ 
+ 
+     def test_supplied_feature_directory_no_steps(self):
+@@ -1075,6 +1099,9 @@ class TestFeatureDirectoryLayout2(object):
+ 
+         with patch("os.path", fs):
+             with patch("os.walk", fs.walk):
+-                assert_raises(ConfigError, r.setup_paths)
++                with pytest.raises(ConfigError):
++                    r.setup_paths()
++                # OLD: assert_raises(ConfigError, r.setup_paths)
+ 
+-        ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        # OLD: ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
++        assert ("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls
+diff --git a/test/test_step_registry.py b/tests/unit/test_step_registry.py
+similarity index 95%
+rename from test/test_step_registry.py
+rename to tests/unit/test_step_registry.py
+index f5b5a4d..6f85729 100644
+--- a/test/test_step_registry.py
++++ b/tests/unit/test_step_registry.py
+@@ -2,7 +2,6 @@
+ # pylint: disable=unused-wildcard-import
+ from __future__ import absolute_import, with_statement
+ from mock import Mock, patch
+-from nose.tools import *        # pylint: disable=wildcard-import
+ from six.moves import range     # pylint: disable=redefined-builtin
+ from behave import step_registry
+ 
+@@ -26,7 +25,7 @@ class TestStepRegistry(object):
+ 
+                 registry.add_step_definition(step_type.upper(), pattern, func)
+                 get_matcher.assert_called_with(func, pattern)
+-                eq_(l, [magic_object])
++                assert l == [magic_object]
+ 
+     def test_find_match_with_specific_step_type_also_searches_generic(self):
+         registry = step_registry.StepRegistry()
+@@ -80,7 +79,7 @@ class TestStepRegistry(object):
+ 
+         assert registry.find_match(step) is magic_object
+         for mock in step_defs[6:]:
+-            eq_(mock.match.call_count, 0)
++            assert mock.match.call_count == 0
+ 
+     # pylint: disable=line-too-long
+     @patch.object(step_registry.registry, 'add_step_definition')
+diff --git a/tests/unit/test_textutil.py b/tests/unit/test_textutil.py
+index e05e9ad..3ffab3c 100644
+--- a/tests/unit/test_textutil.py
++++ b/tests/unit/test_textutil.py
+@@ -9,6 +9,10 @@ import pytest
+ import codecs
+ import six
+ 
++
++pytest_version = pytest.__version__
++
++
+ # -----------------------------------------------------------------------------
+ # TEST SUPPORT:
+ # -----------------------------------------------------------------------------
+@@ -263,6 +267,7 @@ class TestObjectToTextConversion(object):
+         assert message in text2, "OOPS: text=%r" % text2
+ 
+     @requires_python2
++    @pytest.mark.skipif(pytest_version >= "5.0", reason="Fails with pytest 5.0")
+     @pytest.mark.parametrize("exception_class, message", [
+         (AssertionError, u"Ärgernis"),
+         (RuntimeError, u"Übermütig"),
+@@ -274,10 +279,15 @@ class TestObjectToTextConversion(object):
+         with pytest.raises(exception_class) as e:
+             raise exception_class(bytes_message)
+ 
+-        text2 = text(e.value)
++        # -- REQUIRES: pytest < 5.0
++        # HINT: pytest >= 5.0 needs: text(e.value)
++        # NEW:  text2 = text(e.value)   # Causes problems w/ decoding and comparison.
++        assert isinstance(e.value, Exception)
++        text2 = text(e)
+         unicode_message = bytes_message.decode(self.ENCODING)
+         expected = u"%s: %s" % (exception_class.__name__, unicode_message)
+         assert isinstance(text2, six.text_type)
++        assert unicode_message in text2
+         assert text2.endswith(expected)
+         # -- DIAGNOSTICS:
+         print(u"text2: "+ text2)
+diff --git a/tox.ini b/tox.ini
+index 392bb39..d2fbce2 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -67,17 +67,11 @@ deps=
+ install_command = pip install -U {opts} {packages}
+ changedir = {toxinidir}
+ commands=
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
+-deps=
+-    pytest>=3.0
+-    pytest-html >= 1.19.0
+-    nose>=1.3
+-    mock>=2.0
+-    PyHamcrest>=1.9
+-    path.py >= 10.1
++deps= -r {toxinidir}/py.requirements/ci.tox.txt
+ setenv =
+      PYTHONPATH = {toxinidir}
+ 
+@@ -97,13 +91,12 @@ changedir = {envdir}
+ commands=
+     behave --version
+     {toxinidir}/bin/toxcmd.py copytree ../../behave4cmd0 .
+-    {toxinidir}/bin/toxcmd.py copytree ../../test .
+     {toxinidir}/bin/toxcmd.py copytree ../../tests .
+     {toxinidir}/bin/toxcmd.py copytree ../../features .
+     {toxinidir}/bin/toxcmd.py copytree ../../tools  .
+     {toxinidir}/bin/toxcmd.py copytree ../../issue.features .
+     {toxinidir}/bin/toxcmd.py copy ../../behave.ini .
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
+@@ -119,18 +112,16 @@ changedir = {envdir}
+ commands=
+     behave --version
+     {toxinidir}/bin/toxcmd.py copytree ../../behave4cmd0 .
+-    {toxinidir}/bin/toxcmd.py copytree ../../test .
+     {toxinidir}/bin/toxcmd.py copytree ../../tests .
+     {toxinidir}/bin/toxcmd.py copytree ../../features .
+     {toxinidir}/bin/toxcmd.py copytree ../../tools  .
+     {toxinidir}/bin/toxcmd.py copytree ../../issue.features .
+     {toxinidir}/bin/toxcmd.py copy ../../behave.ini .
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs behave4cmd0
+-    {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs test
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs tools
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs features
+     {toxinidir}/bin/toxcmd.py 2to3 -w -n --no-diffs issue.features
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
+@@ -148,7 +139,7 @@ setenv =
+ [testenv:jy27]
+ basepython= jython
+ commands=
+-    pytest {posargs:test tests}
++    pytest {posargs:tests}
+     behave --format=progress {posargs:features}
+     behave --format=progress {posargs:tools/test-features}
+     behave --format=progress {posargs:issue.features}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch b/meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch
new file mode 100644
index 000000000..7fe451b2f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0036-FIX-Remove-test-from-pytest-run.patch
@@ -0,0 +1,22 @@
+From 2c886d201c19085ab52065d47e4f86a82a77f991 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 09:17:54 +0200
+Subject: [PATCH] FIX: Remove test/ from pytest run.
+
+---
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index fbc3520..c6027e0 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -35,7 +35,7 @@ install:
+ 
+ script:
+   - python --version
+-  - pytest test tests
++  - pytest tests
+   - behave -f progress --junit features/
+   - behave -f progress --junit tools/test-features/
+   - behave -f progress --junit issue.features/
diff --git a/meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch b/meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch
new file mode 100644
index 000000000..3e9a46a0c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0037-Select-by-location-Add-support-for-Scenario-containe.patch
@@ -0,0 +1,652 @@
+From 57a9cc0e1c99b0ed2ec5dbfd3fcfce456cfe13c8 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 09:50:46 +0200
+Subject: [PATCH] Select-by-location: Add support for "Scenario container"
+ (Feature, Rule, ScenarioOutline) (related to: #391)
+
+---
+ CHANGES.rst                                   |   2 +-
+ behave/model.py                               |  49 +++--
+ behave/runner_util.py                         | 186 +++++++++++++++++-
+ ....select_scenarios_by_file_location.feature |  27 ++-
+ pytest.ini                                    |   2 +-
+ tests/unit/test_runner_util.py                | 175 ++++++++++++++++
+ 6 files changed, 416 insertions(+), 25 deletions(-)
+ create mode 100644 tests/unit/test_runner_util.py
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 3d805b3..01bd1bd 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -28,7 +28,7 @@ ENHANCEMENTS:
+ * Use `cucumber-tag-expressions`_ with tag-matching extension (superceeds: old-style tag-expressions)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+-
++* Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+ 
+ PARTIALLY FIXED:
+ 
+diff --git a/behave/model.py b/behave/model.py
+index 3084850..7fc534a 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -55,11 +55,11 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+     .. attribute:: keyword
+ 
+        This is the keyword as seen in the *feature file*. In English this will
+-       be "Feature".
++       be "Feature" or "Rule".
+ 
+     .. attribute:: name
+ 
+-       The name of the feature (the text after "Feature".)
++       The name (or title) of the model entity (the text after the keyword.)
+ 
+     .. attribute:: description
+ 
+@@ -93,12 +93,16 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+        Status.untested
+          The feature was has not been completely tested yet.
++
+        Status.skipped
+-         One or more steps of this feature was passed over during testing.
++         The execution of this model entity (feature or rule)
++         should be / was skipped (excluded from the test run).
++
+        Status.passed
+-         The feature was tested successfully.
++         The model entity (feature or rule) was tested successfully.
++
+        Status.failed
+-         One or more steps of this feature failed.
++         One or more run items of this model entity failed.
+ 
+        .. versionchanged:: 1.2.6
+             Use Status enum class (was: string).
+@@ -147,6 +151,11 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         for run_item in self.run_items:
+             run_item.reset()
+ 
++    def _setup_context_for_run(self, context):
++        """Setup/Init runner context for run."""
++        # -- OVERRIDDEN: By derived classes.
++        pass
++
+     def __iter__(self):
+         return iter(self.run_items)
+ 
+@@ -204,7 +213,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         # feature_duration = self.run_endtime - self.run_starttime
+         return feature_duration
+ 
+-    def walk_scenarios(self, with_outlines=False):
++    def walk_scenarios(self, with_outlines=False, with_rules=False):
+         """Provides a flat list of all scenarios of this ScenarioContainer.
+         A ScenarioOutline element adds its scenarios to this list.
+         But the ScenarioOutline element itself is only added when specified.
+@@ -215,20 +224,20 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         :param with_outlines: If ScenarioOutline items should be added, too.
+         :return: List of all scenarios of this feature.
+         """
+-        # TODO: Better use self.run_items
+         all_scenarios = []
+-        # for scenario in self.scenarios:
+         for run_item in self.run_items:
+             if isinstance(run_item, Rule):
+                 rule = run_item
++                if with_rules:
++                    all_scenarios.append(rule)
+                 all_scenarios.extend(rule.walk_scenarios(with_outlines=with_outlines))
+-            if isinstance(run_item, ScenarioOutline):
++            elif isinstance(run_item, ScenarioOutline):
+                 scenario_outline = run_item
+                 if with_outlines:
+                     all_scenarios.append(scenario_outline)
+                 all_scenarios.extend(scenario_outline.scenarios)
+             else:
+-                assert isinstance(run_item, Scenario)
++                assert isinstance(run_item, Scenario), "OOPS: %r" % run_item
+                 all_scenarios.append(run_item)
+         return all_scenarios
+ 
+@@ -274,9 +283,9 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         assert self.status == Status.skipped or self.hook_failed
+ 
+     def skip(self, reason=None, require_not_executed=False):
+-        """Skip executing this feature or the remaining parts of it.
+-        Note that this feature may be already partly executed
+-        when this function is called.
++        """Skip executing this model entity or the remaining parts of it.
++        Note that this model entity (feature or rule) may be already partly
++        executed when this function is called.
+ 
+         :param reason:  Optional reason why feature should be skipped (as string).
+         :param require_not_executed: Optional, requires that feature is not
+@@ -314,8 +323,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         hook_after_entity = "after_{0}".format(entity_name)
+ 
+         runner.context._push(layer_name=entity_name)      # pylint: disable=protected-access
+-        runner.context.feature = self
+         runner.context.tags = set(self.tags)
++        self._setup_context_for_run(runner.context)
+ 
+         skip_entity_untested = runner.aborted
+         should_run_entity = self.should_run(runner.config)
+@@ -497,6 +506,9 @@ class Feature(ScenarioContainer):
+             (self.name, len(self.run_items),
+              len(self.rules), len(self.scenarios))
+ 
++    def _setup_context_for_run(self, context):
++        context.feature = self
++
+     def add_rule(self, rule):
+         """Add a rule to this feature."""
+         feature = self
+@@ -619,6 +631,9 @@ class Rule(ScenarioContainer):
+         self.parent = parent
+         self.feature = parent
+ 
++    def _setup_context_for_run(self, context):
++        context.rule = self
++
+     def __repr__(self):
+         return '<Rule "%s": %d scenario(s)>' % \
+             (self.name, len(self.scenarios))
+@@ -664,6 +679,10 @@ class Background(BasicStatement, Replayable):
+ 
+     .. _`background`: gherkin.html#backgrounds
+     """
++    # TODO: Background inheritance
++    # Rule.background should inherit its Feature.background steps (if available)
++    # Rule.background = Feature.background iff not Rule.background exists (ALREADY-SOLVED)
++    # Rule may override background inheritance mechanism
+     type = "background"
+ 
+     def __init__(self, filename, line, keyword, name, steps=None, description=None):
+@@ -796,7 +815,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+ 
+     @property
+     def background_steps(self):
+-        """Provide background steps if feature has a background.
++        """Provide background steps if feature/rule has a background.
+         Lazy init that copies the background steps.
+ 
+         Note that a copy of the background steps is needed to ensure
+diff --git a/behave/runner_util.py b/behave/runner_util.py
+index 2210f78..7e0807f 100644
+--- a/behave/runner_util.py
++++ b/behave/runner_util.py
+@@ -58,6 +58,100 @@ class FileLocationParser(object):
+ # -----------------------------------------------------------------------------
+ # CLASSES:
+ # -----------------------------------------------------------------------------
++from collections import OrderedDict
++from .model import Feature, Rule, ScenarioOutline, Scenario
++
++
++class FeatureLineDatabase(object):
++    """Helper class that supports select-by-location mechanism (FileLocation)
++    within a feature file by storing the feature line numbers for each entity.
++
++    RESPONSIBILITY(s):
++
++    * Can use the line number to select the best matching entity(s) in a feature
++    * Implements the select-by-location mechanism for each entity in the feature
++    """
++
++    def __init__(self, entity=None, line_data=None):
++        if entity and not line_data:
++            line_data = self.make_line_data_for(entity)
++        self.entity = entity
++        self.data = OrderedDict(line_data or [])
++        self._line_numbers = None
++        self._line_entities = None
++
++    def select_run_item_by_line(self, line):
++        """Select one run-items by using the line number.
++
++        * Exact match returns run-time entity (Feature, Rule, ScenarioOutline, Scenario)
++        * Any other line in between uses the predecessor entity
++
++        :param line: Line number in Feature file (as int)
++        :return: Selected run-item object.
++        """
++        run_item = self.data.get(line, None)
++        if run_item is None:
++            # -- CASE: BEST-MATCH in ordered line database
++            if self._line_numbers is None:
++                self._line_numbers = list(self.data.keys())
++                self._line_entities = list(self.data.values())
++
++            pos = bisect(self._line_numbers, line) - 1
++            if pos < 0:
++                pos = 0
++            run_item = self._line_entities[pos]
++        return run_item
++
++    def select_scenarios_by_line(self, line):
++        """Select one or more scenarios by using the line number.
++
++        * line = 0: Selects all scenarios in the Feature file
++        * Feature / Rule / ScenarioOutline.location.line selects its scenarios
++        * Scenario.location.line selects the Scenario
++        * Any other lines use the predecessor entity (and its scenarios)
++
++        :param line: Line number in Feature file (as int)
++        :return: List of selected scenarios
++        """
++        run_item = self.select_run_item_by_line(line)
++        scenarios = []
++        if isinstance(run_item, Feature):
++            scenarios = list(run_item.walk_scenarios())
++        elif isinstance(run_item, Rule):
++            scenarios = list(run_item.walk_scenarios())
++        elif isinstance(run_item, ScenarioOutline):
++            scenarios = list(run_item.scenarios)
++        elif isinstance(run_item, Scenario):
++            scenarios = [run_item]
++        return scenarios
++
++    @classmethod
++    def make_line_data_for(cls, entity):
++        line_data = []
++        run_items = []
++        if isinstance(entity, Feature):
++            line_data.append((0, entity))
++            run_items = entity.run_items
++        elif isinstance(entity, Rule):
++            run_items = entity.run_items
++        elif isinstance(entity, ScenarioOutline):
++            run_items = entity.scenarios
++
++        line_data.append((entity.location.line, entity))
++        for run_item in run_items:
++            line_data.extend(cls.make_line_data_for(run_item))
++        # -- MAYBE:
++        # if isinstance(entity, ScenarioOutline) and run_items:
++        #     # -- SPECIAL CASE: Lines after last Examples row => Use ScenarioOutline
++        #     line_data.append((run_items[-1].location.line + 1, entity))
++        return sorted(line_data)
++
++    @classmethod
++    def make(cls, entity):
++        return cls(entity, cls.make_line_data_for(entity))
++
++
++
+ class FeatureScenarioLocationCollector(object):
+     """
+     Collects FileLocation objects for a feature.
+@@ -200,6 +294,94 @@ class FeatureScenarioLocationCollector(object):
+         return self.feature
+ 
+ 
++class FeatureScenarioLocationCollector1(FeatureScenarioLocationCollector):
++
++    @staticmethod
++    def select_scenario_line_for(line, scenario_lines):
++        """
++        Select scenario line for any given line.
++
++        ALGORITHM: scenario.line <= line < next_scenario.line
++
++        :param line:  A line number in the file (as number).
++        :param scenario_lines: Sorted list of scenario lines.
++        :return: Scenario.line (first line) for the given line.
++        """
++        if not scenario_lines:
++            return 0    # -- Select all scenarios.
++        pos = bisect(scenario_lines, line) - 1
++        if pos < 0:
++            pos = 0
++        return scenario_lines[pos]
++
++    def discover_selected_scenarios(self, strict=False):
++        """
++        Discovers selected scenarios based on the provided file locations.
++        In addition:
++          * discover all scenarios
++          * auto-correct BAD LINE-NUMBERS
++
++        :param strict:  If true, raises exception if file location is invalid.
++        :return: List of selected scenarios of this feature (as set).
++        :raises InvalidFileLocationError:
++            If file location is no exactly correct and strict is true.
++        """
++        assert self.feature
++        if not self.all_scenarios:
++            self.all_scenarios = self.feature.walk_scenarios()
++
++        # -- STEP: Check if lines are correct.
++        existing_lines = [scenario.line for scenario in self.all_scenarios]
++        selected_lines = list(self.scenario_lines)
++        for line in selected_lines:
++            new_line = self.select_scenario_line_for(line, existing_lines)
++            if new_line != line:
++                # -- AUTO-CORRECT BAD-LINE:
++                self.scenario_lines.remove(line)
++                self.scenario_lines.add(new_line)
++                if strict:
++                    msg = "Scenario location '...:%d' should be: '%s:%d'" % \
++                          (line, self.filename, new_line)
++                    raise InvalidFileLocationError(msg)
++
++        # -- STEP: Determine selected scenarios and store them.
++        scenario_lines = set(self.scenario_lines)
++        selected_scenarios = set()
++        for scenario in self.all_scenarios:
++            if scenario.line in scenario_lines:
++                selected_scenarios.add(scenario)
++                scenario_lines.remove(scenario.line)
++        # -- CHECK ALL ARE RESOLVED:
++        assert not scenario_lines
++        return selected_scenarios
++
++
++class FeatureScenarioLocationCollector2(FeatureScenarioLocationCollector):
++
++    def discover_selected_scenarios(self, strict=False):
++        """Discovers selected scenarios based on the provided file locations.
++        In addition:
++          * discover all scenarios
++          * auto-correct BAD LINE-NUMBERS
++
++        :param strict:  If true, raises exception if file location is invalid.
++        :return: List of selected scenarios of this feature (as set).
++        :raises InvalidFileLocationError:
++            If file location is no exactly correct and strict is true.
++        """
++        assert self.feature
++        if not self.all_scenarios:
++            self.all_scenarios = self.feature.walk_scenarios()
++
++        line_database = FeatureLineDatabase.make(self.feature)
++        selected_lines = list(self.scenario_lines)
++        selected_scenarios = set()
++        for line in selected_lines:
++            more_scenarios = line_database.select_scenarios_by_line(line)
++            selected_scenarios.update(more_scenarios)
++        return selected_scenarios
++
++
+ class FeatureListParser(object):
+     """
+     Read textual file, ala '@features.txt'. This file contains:
+@@ -304,7 +486,7 @@ def parse_features(feature_files, language=None):
+     :param language:      Default language to use.
+     :return: List of feature objects.
+     """
+-    scenario_collector = FeatureScenarioLocationCollector()
++    scenario_collector = FeatureScenarioLocationCollector2()
+     features = []
+     for location in feature_files:
+         if not isinstance(location, FileLocation):
+@@ -315,7 +497,7 @@ def parse_features(feature_files, language=None):
+             scenario_collector.add_location(location)
+             continue
+         elif scenario_collector.feature:
+-            # -- ADD CURRENT FEATURE: As collection of scenarios.
++            # -- NEW FEATURE DETECTED: Add current feature.
+             current_feature = scenario_collector.build_feature()
+             features.append(current_feature)
+             scenario_collector.clear()
+diff --git a/features/runner.select_scenarios_by_file_location.feature b/features/runner.select_scenarios_by_file_location.feature
+index f60c43f..69e23fe 100644
+--- a/features/runner.select_scenarios_by_file_location.feature
++++ b/features/runner.select_scenarios_by_file_location.feature
+@@ -13,15 +13,28 @@ Feature: Select Scenarios by File Location
+     .   * A file location with filename but without line number
+     .     refers to the complete file
+     .   * A file location with line number 0 (zero) refers to the complete file
++    .   * A file location within a scenario container (Feature, Rule, ScenarioOutline),
++    .     that does not refer to the file location within a scenario,
++    .     selects all scenarios of this scenario container.
+     .
+     . SPECIFICATION: Scenario selection by file locations
+     .   * scenario.line == file_location.line selects scenario (preferred method).
+     .   * Any line number in the following range is acceptable:
+-    .        scenario.line <= file_location.line < next_scenario.line
+-    .   * The first scenario is selected,
+-    .     if the file location line number is less than first scenario.line.
++    .        scenario.line <= file_location.line < next_entity.line (maybe: scenario)
++    .   * If the file location line number is less than first scenario.line,
++    .     the preceeding scenario container (Feature or Rule) is selected.
+     .   * The last scenario is selected,
+     .     if the file location line number is greater than the lines in the file.
++    .   * For ScenarioOutline.scenarios:
++    .         scenario.line == ScenarioOutline.examples[x].row.line
++    .     The line number of the Examples row that created the scenario is assigned to it.
++    .
++    . SPECIFICATION: "Scenario container" selection by file locations
++    .   * Scenario containers are: Feature, Rule, ScenarioOutline
++    .   * A file location that points into the matching range of a scenario container,
++    .     selects all scenarios / run-items within this scenario container.
++    .   * Any line number in the following range selects the scenario container:
++    .        entity.line <= file_location.line < next_entity.line (maybe: child)
+     .
+     . SPECIFICATION: Runner with scenario locations (file locations)
+     .   * Adjacent file locations are merged if they refer to the same file, like:
+@@ -162,22 +175,24 @@ Feature: Select Scenarios by File Location
+             """
+ 
+     @file_location.select_first
+-    Scenario: Select first scenario if line number is smaller than first scenario line
++    Scenario: Select all scenarios if line number is smaller than first scenario line
+ 
+       CASE: 0 < file_location.line < first_scenario.line
++      HINT: Any line number outside of a scenario may point into a "scenario container".
++            In this case, all the scenarios of the scenario container are selected.
+ 
+         When I run "behave -f plain --dry-run --no-skipped features/alice.feature:1"
+         Then it should pass with:
+             """
+             0 features passed, 0 failed, 0 skipped, 1 untested
+-            0 scenarios passed, 0 failed, 1 skipped, 1 untested
++            0 scenarios passed, 0 failed, 0 skipped, 2 untested
+             """
+         And the command output should contain:
+             """
+             Feature: Alice
+               Scenario: Alice First
+             """
+-        But the command output should not contain:
++        But the command output should contain:
+             """
+             Scenario: Alice Last
+             """
+diff --git a/pytest.ini b/pytest.ini
+index a686596..ff2a8a2 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -16,7 +16,7 @@
+ # ============================================================================
+ 
+ [pytest]
+-minversion    = 4.2
++minversion    = 2.8
+ testpaths     = tests
+ python_files  = test_*.py
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+diff --git a/tests/unit/test_runner_util.py b/tests/unit/test_runner_util.py
+new file mode 100644
+index 0000000..b5019b8
+--- /dev/null
++++ b/tests/unit/test_runner_util.py
+@@ -0,0 +1,175 @@
++# -*- coding: UTF-8 -*-
++
++from __future__ import absolute_import, print_function
++from collections import OrderedDict
++from behave.runner_util import FeatureLineDatabase
++from behave.parser import parse_feature
++from behave.model import Feature, Rule, ScenarioOutline, Scenario, Background
++import pytest
++
++
++# ---------------------------------------------------------------------------------------
++# TEST DATA: FeatureLineDatabase
++# ---------------------------------------------------------------------------------------
++feature_text1 = u"""
++    Feature: Alice
++        Background: Alice.Background
++          Given a background step passes
++          
++        Scenario: A1
++          Given a scenario step passes
++
++        Scenario: A2
++          Given a scenario step passes
++          When a scenario step passes
++    """
++
++feature_text_with_scenario_outline = u"""
++    Feature: Bob
++    
++        Scenario Outline: Bob.SO_2_<row.id>
++          Given a person with name "<Name>"
++          Then the person is born in <Birthyear>
++        
++          Examples:
++            | Name  | Birthyear |
++            | Alice |  1990     |
++            | Bob   |  1991     |
++            
++        Scenario: Bob.S3
++          Given a scenario step passes
++          When a scenario step passes
++    """
++
++feature_text_with_rule = u"""
++    Feature: Charly
++        Background: Charly.Background
++          Given a background step passes
++
++        Scenario: C1
++          Given a scenario step passes
++
++        Rule: Charly.Rule_1
++
++          Scenario: Rule_1.C2
++            Given a scenario step passes
++            When a scenario step passes
++    """
++
++feature_file_map = {
++    "basic.feature": feature_text1,
++    "scenario_outline.feature": feature_text_with_scenario_outline,
++    "rule.feature": feature_text_with_rule,
++}
++
++# ---------------------------------------------------------------------------------------
++# TEST SUITE FOR: FeatureLineDatabase
++# ---------------------------------------------------------------------------------------
++class TestFeatureLineDatabase(object):
++    def test_make(self):
++        feature = parse_feature(feature_text1.strip(),
++                                filename="features/Alice.feature")
++        scenario_0 = feature.scenarios[0]
++        scenario_1 = feature.scenarios[1]
++
++        line_database = FeatureLineDatabase.make(feature)
++        expected = OrderedDict([
++            (0, feature),
++            (feature.location.line, feature),
++            (scenario_0.line, scenario_0),
++            (scenario_1.line, scenario_1),
++        ])
++        assert line_database.data == expected
++        assert feature.location.line == 1
++
++    def test_make__with_scenario_outline(self):
++        feature = parse_feature(feature_text_with_scenario_outline.strip(),
++                                filename="features/Bob.feature")
++        scenarios = feature.walk_scenarios(with_outlines=True)
++        scenario_outline = scenarios[0]
++        assert scenario_outline is feature.run_items[0]
++        scenario_1 = scenarios[1]
++        scenario_2 = scenarios[2]
++        scenario_3 = scenarios[3]
++
++        line_database = FeatureLineDatabase.make(feature)
++        expected = OrderedDict([
++            (0, feature),
++            (feature.location.line, feature),
++            (scenario_outline.line, scenario_outline),
++            (scenario_1.line, scenario_1),
++            (scenario_2.line, scenario_2),
++            (scenario_3.line, scenario_3),
++        ])
++        assert line_database.data == expected
++        assert feature.location.line < scenario_outline.location.line
++        assert scenario_outline.location.line < scenario_1.location.line
++        assert scenario_1.location.line < scenario_2.location.line
++        assert scenario_2.location.line < scenario_3.location.line
++
++
++    def test_select_run_items_by_line__feature_line_selects_feature(self):
++        feature = parse_feature(feature_text1, filename="features/Alice.feature")
++        line_database = FeatureLineDatabase.make(feature)
++        selected = line_database.select_run_item_by_line(feature.location.line)
++        assert selected is feature
++        assert isinstance(selected, Feature)
++
++    @pytest.mark.parametrize("filename", [
++        "basic.feature", "scenario_outline.feature", "rule.feature"
++    ])
++    def test_select_run_items_by_line__entity_line_selects_entity(self, filename):
++        feature_text = feature_file_map[filename]
++        feature = parse_feature(feature_text, filename=filename)
++        line_database = FeatureLineDatabase.make(feature)
++        last_line = 0
++        all_run_items = feature.walk_scenarios(with_outlines=True, with_rules=True)
++        for run_item in all_run_items:
++            selected = line_database.select_run_item_by_line(run_item.location.line)
++            assert selected is run_item
++            assert last_line < selected.location.line
++            last_line = run_item.location.line
++
++    @pytest.mark.parametrize("filename", [
++        "basic.feature", "scenario_outline.feature", "rule.feature"
++    ])
++    def test_select_run_items_by_line__line_before_entity_selects_last_entity(self, filename):
++        feature_text = feature_file_map[filename]
++        feature = parse_feature(feature_text, filename=filename)
++        line_database = FeatureLineDatabase.make(feature)
++        all_run_items = feature.walk_scenarios(with_outlines=True, with_rules=True)
++        last_run_item = feature
++        for run_item in all_run_items:
++            predecessor_line = run_item.location.line - 1
++            selected = line_database.select_run_item_by_line(predecessor_line)
++            assert selected is last_run_item
++            assert selected is not run_item
++            last_run_item = run_item
++
++    @pytest.mark.parametrize("filename", [
++        "basic.feature", "scenario_outline.feature", "rule.feature"
++    ])
++    def test_select_run_items_by_line__line_after_entity_selects_entity(self, filename):
++        # -- HINT: In most cases
++        # EXCEPT:
++        #   * Scenarios of ScenarioOutline: scenario.line == SO.examples.row.line
++        #   * Empty entity without steps is directly followed by other entity
++        feature_text = feature_file_map[filename]
++        feature = parse_feature(feature_text, filename=filename)
++        line_database = FeatureLineDatabase.make(feature)
++        all_run_items = feature.walk_scenarios(with_outlines=True, with_rules=True)
++        file_end_line = all_run_items[-1].location.line + 1000
++        for index, run_item in enumerate(all_run_items):
++            next_line = run_item.location.line + 1
++            next_entity_line = file_end_line
++            if index+1 < len(all_run_items):
++                next_entity = all_run_items[index+1]
++                next_entity_line = next_entity.line
++            if next_line >= next_entity_line:
++                # -- EXCLUDE: Scenarios in a ScenarioOutline
++                print("EXCLUDED: %s: %s (line=%s)" %
++                      (run_item.keyword, run_item.name, run_item.line))
++                continue
++
++            selected = line_database.select_run_item_by_line(next_line)
++            assert selected is run_item
diff --git a/meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch b/meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch
new file mode 100644
index 000000000..14394603f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0038-docs-Add-description-for-Select-by-location-for-Scen.patch
@@ -0,0 +1,58 @@
+From a6388c0e97e4378a4ef628361a46ff6d02d3159e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 10:50:54 +0200
+Subject: [PATCH] docs: Add description for "Select-by-location for Scenario
+ Containers"
+
+---
+ docs/new_and_noteworthy_v1.2.7.rst | 33 ++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index 80d9576..ff1cd1f 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -7,6 +7,7 @@ Summary:
+ * Use/Support :pypi:`cucumber-tag-expressions` (superceed: old-style tag-expressions)
+ * :pypi:`cucumber-tag-expressions` are extended by "tag-matching"
+   to match partial tag names, like: ``@foo.*``
++* `Select-by-location for Scenario Containers`_ (Feature, Rule, ScenarioOutline)
+ 
+ .. _`Example Mapping`: https://cucumber.io/blog/example-mapping-introduction/
+ .. _`Example Mapping Webinar`: https://cucumber.io/blog/example-mapping-webinar/
+@@ -102,3 +103,35 @@ Overview of the `Example Mapping`_ concepts:
+ 
+ 
+ .. include:: _content.tag_expressions_v2.rst
++
++
++Select-by-location for Scenario Containers
++-------------------------------------------------------------------------------
++
++In the past, it was already possible to scenario(s) by using its **file-location**.
++
++A **file-location** has the schema: ``<FILENAME>:<LINE_NUMBER>``.
++Example: ``features/alice.feature:12``
++(refers to ``line 12`` in ``features/alice.feature`` file).
++
++Rules to select **Scenarios** by using the file-location:
++
++* **Scenario:** Use a file-location that points to the keyword/title or its steps
++  (until next Scenario/Entity starts).
++
++* **Scenario of a ScenarioOutline:**
++  Use the file-location of its Examples row.
++
++Now you can select all entities of a **Scenario Container** (Feature, Rule, ScenarioOutline):
++
++* **Feature:**
++  Use file-location before first contained entity/Scenario starts.
++
++* **Rule:**
++  Use file-location from keyword/title line to line before its first Scenario/Background.
++
++* **ScenarioOutline:**
++  Use file-location from keyword/title line to line before its Examples rows.
++
++A file-location into a **Scenario Container** selects all its entities
++(Scenarios, ...).
diff --git a/meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch b/meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch
new file mode 100644
index 000000000..2b80d5df1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0039-tests-Fix-warnings-for-python3.patch
@@ -0,0 +1,50 @@
+From 93f578698844d7276e5b2f287ee7ff3bcfc049bf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 13:35:51 +0200
+Subject: [PATCH] tests: Fix warnings for python3.
+
+---
+ tests/issues/test_issue0336.py |  1 +
+ tests/unit/test_parser.py      | 11 +++++++----
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/tests/issues/test_issue0336.py b/tests/issues/test_issue0336.py
+index eb4c3fd..09201ae 100644
+--- a/tests/issues/test_issue0336.py
++++ b/tests/issues/test_issue0336.py
+@@ -52,6 +52,7 @@ AssertionError
+             assert file_line_text in text2
+ 
+     # @require_python2
++    @pytest.mark.filterwarnings("ignore:invalid escape sequence")
+     def test__problem_exists_with_problematic_encoding(self):
+         """Test ensures that problem exists with encoding=unicode-escape"""
+         # -- NOTE: Explicit use of problematic encoding
+diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py
+index ecbb1bf..01006f9 100644
+--- a/tests/unit/test_parser.py
++++ b/tests/unit/test_parser.py
+@@ -564,16 +564,19 @@ Feature: Stuff
+             ('then', 'Then', 'stuff is in buckets', None, None),
+         ])
+ 
++    @pytest.mark.filterwarnings("ignore:invalid escape sequence")
+     def test_parses_feature_with_table_and_escaped_pipe_in_cell_values(self):
++        # -- HINT py37: DeprecationWarning: invalid escape sequence '\|'
++        # USE: Double escaped-backslashes.
+         doc = u'''
+ Feature:
+   Scenario:
+     Given we have special cell values:
+       | name   | value    |
+-      | alice  | one\|two |
+-      | bob    |\|one     |
+-      | charly |     one\||
+-      | doro   | one\|two\|three\|four |
++      | alice  | one\\|two |
++      | bob    |\\|one     |
++      | charly |     one\\||
++      | doro   | one\\|two\\|three\\|four |
+ '''.lstrip()
+         feature = parser.parse_feature(doc)
+         assert len(feature.scenarios) == 1
diff --git a/meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch b/meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch
new file mode 100644
index 000000000..85c1bc16a
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch
@@ -0,0 +1,55 @@
+From 21a399bf6e2e2eb09c98d173f1d0975bcecbf1e5 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 13:36:59 +0200
+Subject: [PATCH] Use cucumber-tag-expressions 1.1.2 (to fix warnings).
+
+py.requirements: Add twine, bump2version
+---
+ py.requirements/basic.txt   | 2 +-
+ py.requirements/develop.txt | 6 +++++-
+ setup.py                    | 2 +-
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index 3b71bfb..ad5b9a6 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -8,7 +8,7 @@
+ #  * http://www.pip-installer.org/
+ # ============================================================================
+ 
+-cucumber-tag-expressions >= 1.1.1
++cucumber-tag-expressions >= 1.1.2
+ parse >= 1.8.2
+ parse_type >= 0.4.2
+ six >= 1.12.0
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index d823389..a16d7bf 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -11,7 +11,11 @@ pathlib;    python_version <= '3.4'
+ pycmd
+ 
+ # -- CONFIGURATION MANAGEMENT (helpers):
+-bumpversion >= 0.4.0
++# FORMER: bumpversion >= 0.4.0
++bump2version >= 0.5.6
++
++# -- RELEASE MANAGEMENT: Push package to pypi.
++twine >= 1.13.0
+ 
+ # -- DEVELOPMENT SUPPORT:
+ tox   >= 1.8.1
+diff --git a/setup.py b/setup.py
+index 9c7560d..cea4392 100644
+--- a/setup.py
++++ b/setup.py
+@@ -76,7 +76,7 @@ setup(
+     # SUPPORT: python2.7, python3.3 (or higher)
+     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*",
+     install_requires=[
+-        "cucumber-tag-expressions >= 1.1.1",
++        "cucumber-tag-expressions >= 1.1.2",
+         "parse >= 1.8.2",
+         "parse_type >= 0.4.2",
+         "six >= 1.12.0",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch b/meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch
new file mode 100644
index 000000000..6d69f4754
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch
@@ -0,0 +1,91 @@
+From 1d3c288a2eed8caef24356e2a92483425bee0378 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 14:18:16 +0200
+Subject: [PATCH] MENTION ENHANCEMENT: Support emojis in feature files and
+ steps.
+
+---
+ CHANGES.rst                        |  3 ++-
+ docs/new_and_noteworthy_v1.2.7.rst | 17 +++++++++++++++++
+ features/i18n_emoji.feature        |  7 +++++++
+ features/steps/i18n_emoji_steps.py | 10 ++++++++++
+ 4 files changed, 36 insertions(+), 1 deletion(-)
+ create mode 100644 features/i18n_emoji.feature
+ create mode 100644 features/steps/i18n_emoji_steps.py
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 01bd1bd..d165275 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -24,8 +24,9 @@ GOALS:
+ ENHANCEMENTS:
+ 
+ * Add support for Gherkin v6 grammar and syntax in ``*.feature`` files
+-* Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Use `cucumber-tag-expressions`_ with tag-matching extension (superceeds: old-style tag-expressions)
++* Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
++* Support emojis in ``*.feature`` files and steps
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ * Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index ff1cd1f..b7242f7 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -8,6 +8,7 @@ Summary:
+ * :pypi:`cucumber-tag-expressions` are extended by "tag-matching"
+   to match partial tag names, like: ``@foo.*``
+ * `Select-by-location for Scenario Containers`_ (Feature, Rule, ScenarioOutline)
++* `Support for emojis in feature files and steps`_
+ 
+ .. _`Example Mapping`: https://cucumber.io/blog/example-mapping-introduction/
+ .. _`Example Mapping Webinar`: https://cucumber.io/blog/example-mapping-webinar/
+@@ -135,3 +136,19 @@ Now you can select all entities of a **Scenario Container** (Feature, Rule, Scen
+ 
+ A file-location into a **Scenario Container** selects all its entities
+ (Scenarios, ...).
++
++
++Support for Emojis in Feature Files and Steps
++-------------------------------------------------------------------------------
++
++* Emojis can now be used in ``*.feature`` files.
++* Emojis can now be used in step definitions.
++* You can now use ``language=emoji (em)`` in ``*.feature`` files ;-)
++
++.. literalinclude:: ../features/i18n_emoji.feature
++    :prepend:  # -- FILE: features/i18n_emoji.feature
++    :language: gherkin
++
++.. literalinclude:: ../features/steps/i18n_emoji_steps.py
++    :prepend:  # -- FILE: features/steps/i18n_emoji_steps.py
++    :language: python
+diff --git a/features/i18n_emoji.feature b/features/i18n_emoji.feature
+new file mode 100644
+index 0000000..db23ac2
+--- /dev/null
++++ b/features/i18n_emoji.feature
+@@ -0,0 +1,7 @@
++# language: em
++# SOURCE: https://github.com/cucumber/cucumber/blob/master/gherkin/testdata/good/i18n_emoji.feature
++
++📚: 🙈🙉🙊
++
++  📕: 💃
++    😐🎸
+diff --git a/features/steps/i18n_emoji_steps.py b/features/steps/i18n_emoji_steps.py
+new file mode 100644
+index 0000000..381d2bb
+--- /dev/null
++++ b/features/steps/i18n_emoji_steps.py
+@@ -0,0 +1,10 @@
++# -*- coding: UTF-8 -*-
++# NEEDED-BY: features/i18n_emoji.feature
++
++from behave import given
++
++@given(u'🎸')
++def step_impl(context):
++    """Step implementation example with emoji(s)."""
++    pass
++
diff --git a/meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch b/meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch
new file mode 100644
index 000000000..00db4a627
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0042-FIX-Invalid-escape-char-in-regex-w-python3.patch
@@ -0,0 +1,250 @@
+From 281bb19a47566c01ce44e7184640728bb56d4de7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 19:06:11 +0200
+Subject: [PATCH] FIX: Invalid escape char (in regex) w/ python3.
+
+---
+ behave/formatter/ansi_escapes.py |  53 ++++++++----
+ tests/unit/test_ansi_escapes.py  | 144 ++++++++++++++++++-------------
+ 2 files changed, 122 insertions(+), 75 deletions(-)
+
+diff --git a/behave/formatter/ansi_escapes.py b/behave/formatter/ansi_escapes.py
+index 6c93e6c..3ec84db 100644
+--- a/behave/formatter/ansi_escapes.py
++++ b/behave/formatter/ansi_escapes.py
+@@ -7,6 +7,9 @@ from __future__ import absolute_import
+ import os
+ import re
+ 
++# ---------------------------------------------------------------------------
++# MODULE DATA
++# ---------------------------------------------------------------------------
+ colors = {
+     "black":        u"\x1b[30m",
+     "red":          u"\x1b[31m",
+@@ -38,27 +41,48 @@ escapes = {
+     "up":           u"\x1b[1A",
+ }
+ 
+-if "GHERKIN_COLORS" in os.environ:
+-    new_aliases = [p.split("=") for p in os.environ["GHERKIN_COLORS"].split(":")]
+-    aliases.update(dict(new_aliases))
+ 
+-for alias in aliases:
+-    escapes[alias] = "".join([colors[c] for c in aliases[alias].split(",")])
+-    arg_alias = alias + "_arg"
+-    arg_seq = aliases.get(arg_alias, aliases[alias] + ",bold")
+-    escapes[arg_alias] = "".join([colors[c] for c in arg_seq.split(",")])
++# -- NEEDED-FOR: strip_escapes(), ...
++_ANSI_ESCAPE_PATTERN = re.compile(u"\x1b\\[\\d+[mA]", re.UNICODE)
+ 
+ 
+-# pylint: disable=anomalous-backslash-in-string
++
++# ---------------------------------------------------------------------------
++# MODULE SETUP
++# ---------------------------------------------------------------------------
++def _setup_module():
++    """Setup the remaining ANSI color aliases and ANSI escape sequences.
++
++    .. note:: May modify/extend the module attributes:
++
++        * :attr:`aliases`
++        * :attr:`escapes`
++    """
++    # MAYBE: global aliases, escapes
++    if "GHERKIN_COLORS" in os.environ:
++        new_aliases = [p.split("=") for p in os.environ["GHERKIN_COLORS"].split(":")]
++        aliases.update(dict(new_aliases))
++
++    for alias in aliases:
++        escapes[alias] = "".join([colors[c] for c in aliases[alias].split(",")])
++        arg_alias = alias + "_arg"
++        arg_seq = aliases.get(arg_alias, aliases[alias] + ",bold")
++        escapes[arg_alias] = "".join([colors[c] for c in arg_seq.split(",")])
++
++
++# -- ONCE: During module-import.
++_setup_module()
++
++
++# ---------------------------------------------------------------------------
++# FUNCTIONS:
++# ---------------------------------------------------------------------------
+ def up(n):
+     return u"\x1b[%dA" % n
+ 
+ 
+-_ANSI_ESCAPE_PATTERN = re.compile(u"\x1b\[\d+[mA]", re.UNICODE)
+-# pylint: enable=anomalous-backslash-in-string
+ def strip_escapes(text):
+-    """
+-    Removes ANSI escape sequences from text (if any are contained).
++    """Removes ANSI escape sequences from text (if any are contained).
+ 
+     :param text: Text that may or may not contain ANSI escape sequences.
+     :return: Text without ANSI escape sequences.
+@@ -67,8 +91,7 @@ def strip_escapes(text):
+ 
+ 
+ def use_ansi_escape_colorbold_composites():     # pragma: no cover
+-    """
+-    Patch for "sphinxcontrib-ansi" to process the following ANSI escapes
++    """Patch for "sphinxcontrib-ansi" to process the following ANSI escapes
+     correctly (set-color set-bold sequences):
+ 
+         ESC[{color}mESC[1m  => ESC[{color};1m
+diff --git a/tests/unit/test_ansi_escapes.py b/tests/unit/test_ansi_escapes.py
+index 969f3a9..4fb78c2 100644
+--- a/tests/unit/test_ansi_escapes.py
++++ b/tests/unit/test_ansi_escapes.py
+@@ -9,65 +9,89 @@
+ from __future__ import absolute_import
+ import pytest
+ from behave.formatter import ansi_escapes
+-import unittest
+ from six.moves import range
+ 
+-class StripEscapesTest(unittest.TestCase):
+-    ALL_COLORS = list(ansi_escapes.colors.keys())
+-    CURSOR_UPS = [ ansi_escapes.up(count)  for count in range(10) ]
+-    TEXTS = [
+-        u"lorem ipsum",
+-        u"Alice\nBob\nCharly\nDennis",
+-    ]
+-
+-    @classmethod
+-    def colorize(cls, text, color):
+-        color_escape = ""
+-        if color:
+-            color_escape = ansi_escapes.colors[color]
+-        return color_escape + text + ansi_escapes.escapes["reset"]
+-
+-    @classmethod
+-    def colorize_text(cls, text, colors=None):
+-        if not colors:
+-            colors = []
+-        colors_size = len(colors)
+-        color_index = 0
+-        colored_chars = []
+-        for char in text:
+-            color = colors[color_index]
+-            colored_chars.append(cls.colorize(char, color))
+-            color_index += 1
+-            if color_index >= colors_size:
+-                color_index = 0
+-        return "".join(colored_chars)
+-
+-    def test_should_return_same_text_without_escapes(self):
+-        for text in self.TEXTS:
+-            assert text == ansi_escapes.strip_escapes(text)
+-
+-    def test_should_return_empty_string_for_any_ansi_escape(self):
+-        # XXX-JE-CHECK-PY23: If list() is really needed.
+-        for text in list(ansi_escapes.colors.values()):
+-            assert "" == ansi_escapes.strip_escapes(text)
+-        for text in list(ansi_escapes.escapes.values()):
+-            assert "" == ansi_escapes.strip_escapes(text)
+-
+-
+-    def test_should_strip_color_escapes_from_text(self):
+-        for text in self.TEXTS:
+-            colored_text = self.colorize_text(text, self.ALL_COLORS)
+-            assert text == ansi_escapes.strip_escapes(colored_text)
+-            self.assertNotEqual(text, colored_text)
+-
+-            for color in self.ALL_COLORS:
+-                colored_text = self.colorize(text, color)
+-                assert text == ansi_escapes.strip_escapes(colored_text)
+-                self.assertNotEqual(text, colored_text)
+-
+-    def test_should_strip_cursor_up_escapes_from_text(self):
+-        for text in self.TEXTS:
+-            for cursor_up in self.CURSOR_UPS:
+-                colored_text = cursor_up + text + ansi_escapes.escapes["reset"]
+-                assert text == ansi_escapes.strip_escapes(colored_text)
+-                self.assertNotEqual(text, colored_text)
++
++# --------------------------------------------------------------------------
++# TEST SUPPORT and TEST DATA
++# --------------------------------------------------------------------------
++TEXTS = [
++    u"lorem ipsum",
++    u"Alice and Bob",
++    u"Alice\nBob",
++]
++ALL_COLORS = list(ansi_escapes.colors.keys())
++CURSOR_UPS = [ansi_escapes.up(count) for count in range(10)]
++
++
++def colorize(text, color):
++    color_escape = ""
++    if color:
++        color_escape = ansi_escapes.colors[color]
++    return color_escape + text + ansi_escapes.escapes["reset"]
++
++
++def colorize_text(text, colors=None):
++    if not colors:
++        colors = []
++    colors_size = len(colors)
++    color_index = 0
++    colored_chars = []
++    for char in text:
++        color = colors[color_index]
++        colored_chars.append(colorize(char, color))
++        color_index += 1
++        if color_index >= colors_size:
++            color_index = 0
++    return "".join(colored_chars)
++
++
++# --------------------------------------------------------------------------
++# TEST SUITE
++# --------------------------------------------------------------------------
++def test_module_setup():
++    """Ensure that the module setup (aliases, escapes) occured."""
++    # colors_count = len(ansi_escapes.colors)
++    aliases_count = len(ansi_escapes.aliases)
++    escapes_count = len(ansi_escapes.escapes)
++    assert escapes_count >= (2 + aliases_count + aliases_count)
++
++
++class TestStripEscapes(object):
++
++    @pytest.mark.parametrize("text", TEXTS)
++    def test_should_return_same_text_without_escapes(self, text):
++        assert text == ansi_escapes.strip_escapes(text)
++
++    @pytest.mark.parametrize("text", ansi_escapes.colors.values())
++    def test_should_return_empty_string_for_any_ansi_escape_color(self, text):
++        assert "" == ansi_escapes.strip_escapes(text)
++
++    @pytest.mark.parametrize("text", ansi_escapes.escapes.values())
++    def test_should_return_empty_string_for_any_ansi_escape(self, text):
++        assert "" == ansi_escapes.strip_escapes(text)
++
++    @pytest.mark.parametrize("text", TEXTS)
++    def test_should_strip_color_escapes_from_all_colored_text(self, text):
++        colored_text = colorize_text(text, ALL_COLORS)
++        assert text == ansi_escapes.strip_escapes(colored_text)
++        assert text != colored_text
++
++    @pytest.mark.parametrize("text", TEXTS)
++    @pytest.mark.parametrize("color", ALL_COLORS)
++    def test_should_strip_color_escapes_from_text(self, text, color):
++        colored_text = colorize(text, color)
++        assert text == ansi_escapes.strip_escapes(colored_text)
++        assert text != colored_text
++
++        colored_text2 = colorize(text, color) + text
++        text2 = text + text
++        assert text2 == ansi_escapes.strip_escapes(colored_text2)
++        assert text2 != colored_text2
++
++    @pytest.mark.parametrize("text", TEXTS)
++    @pytest.mark.parametrize("cursor_up", CURSOR_UPS)
++    def test_should_strip_cursor_up_escapes_from_text(self, text, cursor_up):
++        colored_text = cursor_up + text + ansi_escapes.escapes["reset"]
++        assert text == ansi_escapes.strip_escapes(colored_text)
++        assert text != colored_text
diff --git a/meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch b/meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch
new file mode 100644
index 000000000..82bf8bb08
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0043-Example-related-to-question-in-756.patch
@@ -0,0 +1,335 @@
+From 8ab2ff875382a92a1a72cf82a346c4acf2ec6859 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 6 Jul 2019 19:15:44 +0200
+Subject: [PATCH] Example related to question in #756
+
+---
+ .../fixture.override_background/README.rst    | 116 ++++++++++++++++++
+ .../behave_fixture_lib/__init__.py            |   0
+ .../behave_fixture_lib/override_background.py |  80 ++++++++++++
+ .../features/environment.py                   |  35 ++++++
+ .../features/example.feature                  |  18 +++
+ .../features/steps/basic_steps.py             |  13 ++
+ .../features/steps/use_steplib_behave4cmd.py  |  12 ++
+ 7 files changed, 274 insertions(+)
+ create mode 100644 examples/fixture.override_background/README.rst
+ create mode 100644 examples/fixture.override_background/behave_fixture_lib/__init__.py
+ create mode 100644 examples/fixture.override_background/behave_fixture_lib/override_background.py
+ create mode 100644 examples/fixture.override_background/features/environment.py
+ create mode 100644 examples/fixture.override_background/features/example.feature
+ create mode 100644 examples/fixture.override_background/features/steps/basic_steps.py
+ create mode 100644 examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+
+diff --git a/examples/fixture.override_background/README.rst b/examples/fixture.override_background/README.rst
+new file mode 100644
+index 0000000..9c150cc
+--- /dev/null
++++ b/examples/fixture.override_background/README.rst
+@@ -0,0 +1,116 @@
++EXAMPLE: Override / Disable Background Inheritance Mechanism for Scenario
++===============================================================================
++
++:RELATED-TO: #756
++
++This example shows how the Background inheritance mechanism in Gherkin
++can be disabled in ``behave``.
++
++Parts of the recipe:
++
++* features/example.feature (Feature file as example)
++* features/environment.py (glue code and hooks for fixture-tag / fixture)
++* behave_fixture_lib/override_background.py (fixture implementation, workhorse)
++
++
++.. warning:: BEWARE: This shows you how can do it, not that you should do it
++
++    BETTER:
++
++    * Use Rules to group Scenarios, each with its own Background (in Gherkin v6)
++    * Split Feature aspects into multiple feature files (if needed)
++    * ... (see issue #756 above)
++
++
++Explanation
++------------------------------------------------------------------------
++
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism by using a fixture / fixture-tag.
++The fixture-tag "@ixture.behave.override_background" marks the
++location in Gherkin (which Scenario) where the fixture should be used
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.override_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.overide_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++When the feature is executed, you see that:
++
++* First Scenario "Alice": Background steps are inherited and executed first.
++* Second Scenario "Bob": No Background step is executed.
++
++.. code-block:: sh
++
++    $ ../../bin/behave -f plain features/example.feature
++    Feature: Override the Background Inheritance Mechanism in some Scenarios
++      Background:
++
++      Scenario: Alice
++        Given a background step passes ... passed
++        When a step passes ... passed
++        And note that "Background steps are executed here" ... passed
++    FIXTURE-HINT: DISABLE-BACKGROUND FOR: Bob
++
++      Scenario: Bob
++        Given I need another scenario setup ... passed
++        When another step passes ... passed
++        And note that "NO-BACKGROUND STEPS are executed here" ... passed
++
++    1 feature passed, 0 failed, 0 skipped
++    2 scenarios passed, 0 failed, 0 skipped
++    6 steps passed, 0 failed, 0 skipped, 0 undefined
++
++
++The environment file provides the glue code that the fixture is called:
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.override_background import behave_override_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.overide_background": behave_override_background,
++    }
++
++    # -----------------------------------------------------------------------------
++    # HOOKS:
++    # -----------------------------------------------------------------------------
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++
++.. code-block:: python
++
++    # -- FILE: behave_fixture_lib/override_background.py (fixture implementation)
++    from behave import fixture
++
++    @fixture(name="fixture.behave.override_background")
++    def behave_override_background(ctx):
++        # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++        current_scenario = ctx.scenario
++        if current_scenario:
++            behave_disable_background_inheritance_for_scenario(current_scenario)
++
++    # -----------------------------------------------------------------------------
++    # BEHAVE UTILITY:
++    # -----------------------------------------------------------------------------
++    def behave_disable_background_inheritance_for_scenario(scenario):
++        print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
++        scenario.background = None
+diff --git a/examples/fixture.override_background/behave_fixture_lib/__init__.py b/examples/fixture.override_background/behave_fixture_lib/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/examples/fixture.override_background/behave_fixture_lib/override_background.py b/examples/fixture.override_background/behave_fixture_lib/override_background.py
+new file mode 100644
+index 0000000..6c572cf
+--- /dev/null
++++ b/examples/fixture.override_background/behave_fixture_lib/override_background.py
+@@ -0,0 +1,80 @@
++# -*- coding: UTF-8 -*-
++# RELATED-TO: #756
++"""
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism.
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.override_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.overide_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.override_background import behave_override_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.overide_background": behave_override_background,
++    }
++
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++"""
++
++from __future__ import absolute_import, print_function
++from behave import fixture
++
++
++# -----------------------------------------------------------------------------
++# BEHAVE FIXTURES:
++# -----------------------------------------------------------------------------
++@fixture(name="fixture.behave.override_background")
++def behave_override_background(ctx):
++    """Override the Background inherintance mechanism.
++    If a Feature / Rule Background exists in a Feature,
++    all contained Scenarios inherit the Background's steps.
++
++    This fixture disables this mechanism.
++    The tagged Gherkin element will no longer inherit the background steps.
++
++    :param ctx: Context object to use (during a test run).
++    """
++    # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++    current_scenario = ctx.scenario
++    if current_scenario:
++        behave_disable_background_inheritance_for_scenario(current_scenario)
++
++
++# -----------------------------------------------------------------------------
++# BEHAVE UTILITY:
++# -----------------------------------------------------------------------------
++def behave_disable_background_inheritance_for_scenario(scenario):
++    print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
++    scenario.background = None
++    # scenario._background_steps = []
++
++
++# -----------------------------------------------------------------------------
++# MODULE SPECIFIC:
++# -----------------------------------------------------------------------------
++fixture_registry = {
++    "fixture.behave.overide_background": behave_override_background,
++}
+diff --git a/examples/fixture.override_background/features/environment.py b/examples/fixture.override_background/features/environment.py
+new file mode 100644
+index 0000000..7a4b735
+--- /dev/null
++++ b/examples/fixture.override_background/features/environment.py
+@@ -0,0 +1,35 @@
++# -*- coding: UTF-8 -*-
++# -- FILE: features/environment.py
++import os.path
++import sys
++
++# -----------------------------------------------------------------------------
++# PYTHON PATH SETUP:
++# -----------------------------------------------------------------------------
++HERE = os.path.dirname(__file__)
++TOPA = os.path.abspath(os.path.join(HERE, ".."))
++
++def setup_python_path():
++    sys.path.insert(0, TOPA)
++
++setup_python_path()
++
++# -----------------------------------------------------------------------------
++# NORMAL PART:
++# -----------------------------------------------------------------------------
++from behave_fixture_lib.override_background import behave_override_background
++from behave.fixture import use_fixture_by_tag
++
++# -- FIXTURE REGISTRY:
++fixture_registry = {
++    "fixture.behave.overide_background": behave_override_background,
++}
++
++
++# -----------------------------------------------------------------------------
++# HOOKS:
++# -----------------------------------------------------------------------------
++def before_tag(context, tag):
++    if tag.startswith("fixture."):
++        return use_fixture_by_tag(tag, context, fixture_registry)
++
+diff --git a/examples/fixture.override_background/features/example.feature b/examples/fixture.override_background/features/example.feature
+new file mode 100644
+index 0000000..5ddd874
+--- /dev/null
++++ b/examples/fixture.override_background/features/example.feature
+@@ -0,0 +1,18 @@
++Feature: Override the Background Inheritance Mechanism in some Scenarios
++
++  . BEWARE:
++  .   This is only an example how this can be done (PROOF-OF-CONCEPT).
++  .   This is not an example that you should do this !!!
++
++    Background:
++      Given a background step passes
++
++    Scenario: Alice
++      When a step passes
++      And note that "Background steps are executed here"
++
++    @fixture.behave.overide_background
++    Scenario: Bob
++      Given I need another scenario setup
++      When another step passes
++      And note that "NO-BACKGROUND STEPS are executed here"
+diff --git a/examples/fixture.override_background/features/steps/basic_steps.py b/examples/fixture.override_background/features/steps/basic_steps.py
+new file mode 100644
+index 0000000..34f2107
+--- /dev/null
++++ b/examples/fixture.override_background/features/steps/basic_steps.py
+@@ -0,0 +1,13 @@
++from behave import given, step
++
++# @step(u'{word} step passes')
++# def step_passes_with_word(context, word):
++#     pass
++
++@step(u'{word} background step passes')
++def step_background_step_passes(context, word):
++    pass
++
++@given(u'I need {word} scenario setup')
++def step_given_i_need_scenario_setup(context, word):
++    pass
+diff --git a/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py b/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+new file mode 100644
+index 0000000..bc32a32
+--- /dev/null
++++ b/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+@@ -0,0 +1,12 @@
++# -*- coding: utf-8 -*-
++"""
++Use behave4cmd0 step library (predecessor of behave4cmd).
++"""
++
++from __future__ import absolute_import
++
++# -- REGISTER-STEPS FROM STEP-LIBRARY:
++# import behave4cmd0.__all_steps__
++# import behave4cmd0.failing_steps
++import behave4cmd0.passing_steps
++import behave4cmd0.note_steps
diff --git a/meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch b/meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch
new file mode 100644
index 000000000..c383e39f5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0044-FIX-python3.8-regressions-on-CI-server.patch
@@ -0,0 +1,489 @@
+From 64e58e5721f4fccc9cdf49b524271265a0c776e4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 7 Jul 2019 12:43:19 +0200
+Subject: [PATCH] FIX: python3.8 regressions on CI server
+
+Issues w/ python3.8:
+* Traceback: Line numbers of step functions differ (+1)
+* JUnit XML: Attribute ordering of XML element differs (in output)
+---
+ behave.ini                            |  3 +-
+ features/environment.py               | 14 ++++++
+ features/step.duplicated_step.feature | 20 ++++----
+ issue.features/environment.py         | 38 ++++++++++++---
+ issue.features/issue0330.feature      | 64 ++++++++++++++++++++++++
+ issue.features/issue0446.feature      | 70 +++++++++++++++++++++++++++
+ issue.features/issue0457.feature      | 49 +++++++++++++++++++
+ tox.ini                               |  2 +-
+ 8 files changed, 242 insertions(+), 18 deletions(-)
+
+diff --git a/behave.ini b/behave.ini
+index 45c0f0d..952240d 100644
+--- a/behave.ini
++++ b/behave.ini
+@@ -15,8 +15,9 @@ show_skipped = false
+ format   = rerun
+     progress3
+ outfiles = rerun.txt
+-    reports/report_progress3.txt
++    build/behave.reports/report_progress3.txt
+ junit = true
++junit_directory = build/behave.reports
+ logging_level = INFO
+ # logging_format = LOG.%(levelname)-8s  %(name)-10s: %(message)s
+ # logging_format = LOG.%(levelname)-8s  %(asctime)s  %(name)-10s: %(message)s
+diff --git a/features/environment.py b/features/environment.py
+index 4744e89..3769ee4 100644
+--- a/features/environment.py
++++ b/features/environment.py
+@@ -1,5 +1,7 @@
+ # -*- coding: UTF-8 -*-
++# FILE: features/environemnt.py
+ 
++from __future__ import absolute_import, print_function
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+ import platform
+@@ -20,6 +22,15 @@ active_tag_value_provider = {
+ }
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
++def print_active_tags_summary():
++    active_tag_data = active_tag_value_provider
++    print("ACTIVE-TAG SUMMARY:")
++    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
++    # print("use.with_os=%s" % active_tag_data.get("os"))
++    print()
++
++
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+@@ -30,11 +41,14 @@ def before_all(context):
+     setup_python_path()
+     setup_context_with_global_params_test(context)
+     setup_command_shell_processors4behave()
++    print_active_tags_summary()
++
+ 
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/features/step.duplicated_step.feature b/features/step.duplicated_step.feature
+index 59888b0..396cca2 100644
+--- a/features/step.duplicated_step.feature
++++ b/features/step.duplicated_step.feature
+@@ -32,11 +32,11 @@ Feature: Duplicated Step Definitions
+         AmbiguousStep: @given('I call Alice') has already been defined in
+         existing step @given('I call Alice') at features/steps/alice_steps.py:3
+         """
+-    And the command output should contain:
+-        """
+-        File "features/steps/alice_steps.py", line 7, in <module>
+-        @given(u'I call Alice')
+-        """
++    # -- DISABLED: Python 3.8 traceback line numbers differ w/ decorators (+1).
++    # And the command output should contain:
++    #    """
++    #    File "features/steps/alice_steps.py", line 7, in <module>
++    #    """
+ 
+ 
+   Scenario: Duplicated Step Definition in another File
+@@ -70,11 +70,11 @@ Feature: Duplicated Step Definitions
+         AmbiguousStep: @given('I call Bob') has already been defined in
+         existing step @given('I call Bob') at features/steps/bob1_steps.py:3
+         """
+-    And the command output should contain:
+-        """
+-        File "features/steps/bob2_steps.py", line 3, in <module>
+-        @given('I call Bob')
+-        """
++    # -- DISABLED: Python 3.8 traceback line numbers differ w/ decorators (+1).
++    # And the command output should contain:
++    #    """
++    #    File "features/steps/bob2_steps.py", line 3, in <module>
++    #    """
+ 
+   @xfail
+   Scenario: Duplicated Same Step Definition via import from another File
+diff --git a/issue.features/environment.py b/issue.features/environment.py
+index 2dfec75..7e48ee0 100644
+--- a/issue.features/environment.py
++++ b/issue.features/environment.py
+@@ -1,5 +1,5 @@
+ # -*- coding: UTF-8 -*-
+-# FILE: features/environment.py
++# FILE: issue.features/environemnt.py
+ # pylint: disable=unused-argument
+ """
+ Functionality:
+@@ -7,17 +7,20 @@ Functionality:
+   * active tags
+ """
+ 
+-from __future__ import print_function
++
++from __future__ import absolute_import, print_function
+ import sys
+ import platform
+ import os.path
+ import six
+ from behave.tag_matcher import ActiveTagMatcher
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+-# PREPARED:
+-# from behave.tag_matcher import setup_active_tag_values
++# PREPARED: from behave.tag_matcher import setup_active_tag_values
+ 
+ 
++# ---------------------------------------------------------------------------
++# TEST SUPPORT: For Active Tags
++# ---------------------------------------------------------------------------
+ def require_tool(tool_name):
+     """Check if a tool (an executable program) is provided on this platform.
+ 
+@@ -45,12 +48,14 @@ def require_tool(tool_name):
+     # print("TOOL-NOT-FOUND: %s" % tool_name)
+     return False
+ 
++
+ def as_bool_string(value):
+     if bool(value):
+         return "yes"
+     else:
+         return "no"
+ 
++
+ def discover_ci_server():
+     # pylint: disable=invalid-name
+     ci_server = "none"
+@@ -67,12 +72,17 @@ def discover_ci_server():
+     return ci_server
+ 
+ 
++# ---------------------------------------------------------------------------
++# BEHAVE SUPPORT: Active Tags
++# ---------------------------------------------------------------------------
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
++python_version = "%s.%s" % sys.version_info[:2]
+ active_tag_value_provider = {
+     "platform": sys.platform,
+     "python2": str(six.PY2).lower(),
+     "python3": str(six.PY3).lower(),
++    "python.version": python_version,
+     # -- python.implementation: cpython, pypy, jython, ironpython
+     "python.implementation": platform.python_implementation().lower(),
+     "pypy":    str("__pypy__" in sys.modules).lower(),
+@@ -82,17 +92,33 @@ active_tag_value_provider = {
+ }
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
++def print_active_tags_summary():
++    active_tag_data = active_tag_value_provider
++    print("ACTIVE-TAG SUMMARY:")
++    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
++    # print("use.with_platform=%s" % active_tag_data.get("platform"))
++    # print("use.with_os=%s" % active_tag_data.get("os"))
++    print()
++
++
++# ---------------------------------------------------------------------------
++# BEHAVE HOOKS:
++# ---------------------------------------------------------------------------
+ def before_all(context):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+     # USE: behave -D browser=safari ...
+-    # NOT-NEEDED: setup_active_tag_values(active_tag_value_provider,
+-    #                                     context.config.userdata)
++    # NOT-NEEDED:
++    # setup_active_tag_values(active_tag_value_provider, context.config.userdata)
+     setup_command_shell_processors4behave()
++    print_active_tags_summary()
++
+ 
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/issue.features/issue0330.feature b/issue.features/issue0330.feature
+index dc1ebe7..81cb6e2 100644
+--- a/issue.features/issue0330.feature
++++ b/issue.features/issue0330.feature
+@@ -70,6 +70,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+     And note that "bob.feature is skipped"
+ 
+ 
++  @not.with_python.version=3.8
+   Scenario: Junit report for skipped feature is created with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+@@ -83,6 +84,23 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       <testsuite errors="0" failures="0" name="bob.Bob" skipped="1" tests="1" time="0.0">
+       """
+ 
++  @use.with_python.version=3.8
++  Scenario: Junit report for skipped feature is created with --show-skipped
++    When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
++    Then it should pass with:
++      """
++      1 feature passed, 0 failed, 1 skipped
++      """
++    And a file named "test_results/TESTS-alice.xml" exists
++    And a file named "test_results/TESTS-bob.xml" exists
++    And the file "test_results/TESTS-bob.xml" should contain:
++      """
++      <testsuite name="bob.Bob" tests="1" errors="0" failures="0" skipped="1" time="0.0">
++      """
++      # -- HINT FOR: Python < 3.8
++      # <testsuite errors="0" failures="0" name="bob.Bob" skipped="1" tests="1" time="0.0">
++
++  @not.with_python.version=3.8
+   Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+@@ -102,7 +120,30 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       """
+     And note that "Charly2 is the skipped scenarion in charly.feature"
+ 
++  @use.with_python.version=3.8
++  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
++    When I run "behave --junit -t @tag1 --no-skipped"
++    Then it should pass with:
++      """
++      2 features passed, 0 failed, 1 skipped
++      2 scenarios passed, 0 failed, 2 skipped
++      """
++    And a file named "test_results/TESTS-alice.xml" exists
++    And a file named "test_results/TESTS-charly.xml" exists
++    And the file "test_results/TESTS-charly.xml" should contain:
++      """
++      <testsuite name="charly.Charly" tests="1" errors="0" failures="0" skipped="0"
++      """
++      # -- HINT FOR: Python < 3.8
++      # <testsuite errors="0" failures="0" name="charly.Charly" skipped="0" tests="1"
++    And the file "test_results/TESTS-charly.xml" should not contain:
++      """
++      <testcase classname="charly.Charly" name="Charly2"
++      """
++    And note that "Charly2 is the skipped scenarion in charly.feature"
++
+ 
++  @not.with_python.version=3.8
+   Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+@@ -122,3 +163,26 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       """
+     And note that "Charly2 is the skipped scenarion in charly.feature"
+ 
++
++  @use.with_python.version=3.8
++  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
++    When I run "behave --junit -t @tag1 --show-skipped"
++    Then it should pass with:
++      """
++      2 features passed, 0 failed, 1 skipped
++      2 scenarios passed, 0 failed, 2 skipped
++      """
++    And a file named "test_results/TESTS-alice.xml" exists
++    And a file named "test_results/TESTS-charly.xml" exists
++    And the file "test_results/TESTS-charly.xml" should contain:
++      """
++      <testsuite name="charly.Charly" tests="2" errors="0" failures="0" skipped="1"
++      """
++      # HINT: Python < 3.8
++      # <testsuite errors="0" failures="0" name="charly.Charly" skipped="1" tests="2"
++    And the file "test_results/TESTS-charly.xml" should contain:
++      """
++      <testcase classname="charly.Charly" name="Charly2" status="skipped"
++      """
++    And note that "Charly2 is the skipped scenarion in charly.feature"
++
+diff --git a/issue.features/issue0446.feature b/issue.features/issue0446.feature
+index a2ed892..901bdec 100644
+--- a/issue.features/issue0446.feature
++++ b/issue.features/issue0446.feature
+@@ -58,6 +58,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+         behave.reporter.junit.show_hostname = False
+         """
+ 
++    @not.with_python.version=3.8
+     Scenario: Hook error in before_scenario()
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+@@ -86,6 +87,40 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+       And note that "the traceback is contained in the XML element <error/>"
+ 
+ 
++    @use.with_python.version=3.8
++    Scenario: Hook error in before_scenario()
++      When I run "behave -f plain --junit features/before_scenario_failure.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the command output should contain:
++        """
++        HOOK-ERROR in before_scenario: RuntimeError: OOPS
++        """
++      And the file "reports/TESTS-before_scenario_failure.xml" should contain:
++        """
++        <testsuite name="before_scenario_failure.Alice" tests="1" errors="1" failures="0" skipped="0"
++        """
++        # -- HINT FOR: Python < 3.8
++        # <testsuite errors="1" failures="0" name="before_scenario_failure.Alice" skipped="0" tests="1"
++      And the file "reports/TESTS-before_scenario_failure.xml" should contain:
++        """
++        <error type="RuntimeError" message="HOOK-ERROR in before_scenario: RuntimeError: OOPS">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <error message="HOOK-ERROR in before_scenario: RuntimeError: OOPS" type="RuntimeError">
++      And the file "reports/TESTS-before_scenario_failure.xml" should contain:
++        """
++        File "features/environment.py", line 6, in before_scenario
++          cause_hook_failure()
++        File "features/environment.py", line 2, in cause_hook_failure
++          raise RuntimeError("OOPS")
++        """
++      And note that "the traceback is contained in the XML element <error/>"
++
++
++    @not.with_python.version=3.8
+     Scenario: Hook error in after_scenario()
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+@@ -114,3 +149,38 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+           raise RuntimeError("OOPS")
+         """
+       And note that "the traceback is contained in the XML element <error/>"
++
++
++    @use.with_python.version=3.8
++    Scenario: Hook error in after_scenario()
++      When I run "behave -f plain --junit features/after_scenario_failure.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the command output should contain:
++        """
++          Scenario: B1
++            Given another step passes ... passed
++        HOOK-ERROR in after_scenario: RuntimeError: OOPS
++        """
++      And the file "reports/TESTS-after_scenario_failure.xml" should contain:
++        """
++        <testsuite name="after_scenario_failure.Bob" tests="1" errors="1" failures="0" skipped="0"
++        """
++        # -- HINT FOR: Python < 3.8
++        # <testsuite errors="1" failures="0" name="after_scenario_failure.Bob" skipped="0" tests="1"
++      And the file "reports/TESTS-after_scenario_failure.xml" should contain:
++        """
++        <error type="RuntimeError" message="HOOK-ERROR in after_scenario: RuntimeError: OOPS">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <error message="HOOK-ERROR in after_scenario: RuntimeError: OOPS" type="RuntimeError">
++      And the file "reports/TESTS-after_scenario_failure.xml" should contain:
++        """
++        File "features/environment.py", line 10, in after_scenario
++          cause_hook_failure()
++        File "features/environment.py", line 2, in cause_hook_failure
++          raise RuntimeError("OOPS")
++        """
++      And note that "the traceback is contained in the XML element <error/>"
+diff --git a/issue.features/issue0457.feature b/issue.features/issue0457.feature
+index f80640e..46f96e9 100644
+--- a/issue.features/issue0457.feature
++++ b/issue.features/issue0457.feature
+@@ -24,6 +24,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         """
+ 
+ 
++    @not.with_python.version=3.8
+     Scenario: Use failing assertation in a JUnit XML report
+       Given a file named "features/fails1.feature" with:
+         """
+@@ -44,6 +45,31 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         <failure message="FAILED: My name is &quot;Alice&quot;"
+         """
+ 
++    @use.with_python.version=3.8
++    Scenario: Use failing assertation in a JUnit XML report
++      Given a file named "features/fails1.feature" with:
++        """
++        Feature:
++          Scenario: Alice
++            Given a step fails with message:
++              '''
++              My name is "Alice"
++              '''
++        """
++      When I run "behave --junit features/fails1.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the file "reports/TESTS-fails1.xml" should contain:
++        """
++        <failure type="AssertionError" message="FAILED: My name is &quot;Alice&quot;">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <failure message="FAILED: My name is &quot;Alice&quot;"
++
++
++    @not.with_python.version=3.8
+     Scenario: Use exception in a JUnit XML report
+       Given a file named "features/fails2.feature" with:
+         """
+@@ -63,3 +89,26 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         """
+         <error message="My name is &quot;Bob&quot; and &lt;here&gt; I am"
+         """
++
++    @use.with_python.version=3.8
++    Scenario: Use exception in a JUnit XML report
++      Given a file named "features/fails2.feature" with:
++        """
++        Feature:
++          Scenario: Bob
++            Given a step fails with error and message:
++              '''
++              My name is "Bob" and <here> I am
++              '''
++        """
++      When I run "behave --junit features/fails2.feature"
++      Then it should fail with:
++        """
++        0 scenarios passed, 1 failed, 0 skipped
++        """
++      And the file "reports/TESTS-fails2.xml" should contain:
++        """
++        <error type="RuntimeError" message="My name is &quot;Bob&quot; and &lt;here&gt; I am">
++        """
++        # -- HINT FOR: Python < 3.8
++        # <error message="My name is &quot;Bob&quot; and &lt;here&gt; I am"
+diff --git a/tox.ini b/tox.ini
+index d2fbce2..b825921 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -28,7 +28,7 @@
+ 
+ [tox]
+ minversion   = 2.3
+-envlist      = py27, py37, py36, py35, py34, py33, pypy, docs
++envlist      = py27, py37, py38, py36, py35, pypy, docs
+ skip_missing_interpreters = True
+ sitepackages = False
+ indexserver =
diff --git a/meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch b/meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch
new file mode 100644
index 000000000..606c1318c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0045-UPDATE-Mark-issue-755-as-fixed.patch
@@ -0,0 +1,46 @@
+From ad723ba7e7c2204bbd29115e967d249827d3c8f7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 7 Jul 2019 12:59:57 +0200
+Subject: [PATCH] UPDATE: Mark issue #755 as fixed.
+
+---
+ CHANGES.rst | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d165275..312cbba 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -27,28 +27,25 @@ ENHANCEMENTS:
+ * Use `cucumber-tag-expressions`_ with tag-matching extension (superceeds: old-style tag-expressions)
+ * Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Support emojis in ``*.feature`` files and steps
++* Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+-* Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
+-
+-PARTIALLY FIXED:
+-
+-* issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ 
+ FIXED:
+ 
+-* pull  #588: Steps-catalog argument should not break configured rerun settings (provided by: Lego3)
++* issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
+ * pull  #657: Allow async steps with timeouts to fail when they raise exceptions (provided by: ALSchwalm)
+ * issue #631: ScenarioOutline variables not possible in table headings (provided by: mschnelle, pull #642)
+ * issue #619: Context __getattr__ should raise AttributeError instead of KeyError (submitted by: anxodio)
++* pull  #588: Steps-catalog argument should not break configured rerun settings (provided by: Lego3)
+ 
+ MINOR:
+ 
++* pull  #660: Fix minor typos (provided by: rrueth)
+ * pull  #655: Use pytest instead of py.test per upstream recommendation (provided by: scop)
+ * issue #654: tox.ini: pypi.python.org -> pypi.org (submitted by: pradyunsg)
+-* pull  #660: Fix minor typos (provided by: rrueth)
+ 
+ DOCUMENTATION:
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch b/meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch
new file mode 100644
index 000000000..05c33089a
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0046-UPDATE-Cucumber-gherkin-languages.json.patch
@@ -0,0 +1,57 @@
+From 8c02ce2abbab65cfa4d5b0f306bf9e4735a7195d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 7 Jul 2019 23:35:45 +0200
+Subject: [PATCH] UPDATE: Cucumber gherkin-languages.json
+
+---
+ behave/i18n.py                     | 5 ++++-
+ etc/gherkin/gherkin-languages.json | 6 +++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/behave/i18n.py b/behave/i18n.py
+index 9eb9aab..721c4c3 100644
+--- a/behave/i18n.py
++++ b/behave/i18n.py
+@@ -382,6 +382,9 @@ languages = \
+         'feature': ['Fonctionnalité'],
+         'given': ['* ',
+                   'Soit ',
++                  'Sachant que ',
++                  "Sachant qu'",
++                  'Sachant ',
+                   'Etant donné que ',
+                   "Etant donné qu'",
+                   'Etant donné ',
+@@ -399,7 +402,7 @@ languages = \
+         'rule': ['Règle'],
+         'scenario': ['Exemple', 'Scénario'],
+         'scenario_outline': ['Plan du scénario', 'Plan du Scénario'],
+-        'then': ['* ', 'Alors '],
++        'then': ['* ', 'Alors ', 'Donc '],
+         'when': ['* ', 'Quand ', 'Lorsque ', "Lorsqu'"]},
+  'ga': {'and': ['* ', 'Agus'],
+         'background': ['Cúlra'],
+diff --git a/etc/gherkin/gherkin-languages.json b/etc/gherkin/gherkin-languages.json
+index b08e0f5..913cfac 100644
+--- a/etc/gherkin/gherkin-languages.json
++++ b/etc/gherkin/gherkin-languages.json
+@@ -1256,6 +1256,9 @@
+     "given": [
+       "* ",
+       "Soit ",
++      "Sachant que ",
++      "Sachant qu'",
++      "Sachant ",
+       "Etant donné que ",
+       "Etant donné qu'",
+       "Etant donné ",
+@@ -1284,7 +1287,8 @@
+     ],
+     "then": [
+       "* ",
+-      "Alors "
++      "Alors ",
++      "Donc "
+     ],
+     "when": [
+       "* ",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch b/meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch
new file mode 100644
index 000000000..ebbaa72ed
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch
@@ -0,0 +1,202 @@
+From cf7b144c917f5bc067dd8fd2a4d98c859849dbf0 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 8 Jul 2019 00:38:26 +0200
+Subject: [PATCH] gherkin: Adding Rule keyword translation in portuguese and
+ spanish to gherkin-languages.json
+
+* Integrate changes based on merged cucumber pull-request #621
+* Update "gherkin-languages.json"
+* Update "behave/i18n.py" (generated from: gherkin-languages.json)
+
+RELATED-TO: pull #751 (same; using the official way)
+---
+ CHANGES.rst                        |  1 +
+ behave/fixture.py                  |  1 -
+ behave/i18n.py                     |  4 +--
+ etc/gherkin/gherkin-languages.json |  4 +--
+ invoke.yaml                        |  4 +++
+ tasks/__init__.py                  |  3 ++
+ tasks/develop.py                   | 58 ++++++++++++++++++++++++++++++
+ tasks/py.requirements.txt          |  3 ++
+ 8 files changed, 73 insertions(+), 5 deletions(-)
+ create mode 100644 tasks/develop.py
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 312cbba..15a4ef9 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -43,6 +43,7 @@ FIXED:
+ 
+ MINOR:
+ 
++* pull  #751: gherkin: Adding Rule keyword translation in portuguese and spanish to gherkin-languages.json (provided by: dunossauro)
+ * pull  #660: Fix minor typos (provided by: rrueth)
+ * pull  #655: Use pytest instead of py.test per upstream recommendation (provided by: scop)
+ * issue #654: tox.ini: pypi.python.org -> pypi.org (submitted by: pradyunsg)
+diff --git a/behave/fixture.py b/behave/fixture.py
+index 21093b0..3a9f1bc 100644
+--- a/behave/fixture.py
++++ b/behave/fixture.py
+@@ -348,7 +348,6 @@ def use_composite_fixture_with(context, fixture_funcs_with_params):
+     return composite_fixture
+ 
+ 
+-
+ # -------------------------------------------------------------------------------
+ # DECORATORS:
+ # -------------------------------------------------------------------------------
+diff --git a/behave/i18n.py b/behave/i18n.py
+index 721c4c3..2781afe 100644
+--- a/behave/i18n.py
++++ b/behave/i18n.py
+@@ -331,7 +331,7 @@ languages = \
+         'given': ['* ', 'Dado ', 'Dada ', 'Dados ', 'Dadas '],
+         'name': 'Spanish',
+         'native': 'español',
+-        'rule': ['Rule'],
++        'rule': ['Regla'],
+         'scenario': ['Ejemplo', 'Escenario'],
+         'scenario_outline': ['Esquema del escenario'],
+         'then': ['* ', 'Entonces '],
+@@ -762,7 +762,7 @@ languages = \
+         'given': ['* ', 'Dado ', 'Dada ', 'Dados ', 'Dadas '],
+         'name': 'Portuguese',
+         'native': 'português',
+-        'rule': ['Rule'],
++        'rule': ['Regra'],
+         'scenario': ['Exemplo', 'Cenário', 'Cenario'],
+         'scenario_outline': ['Esquema do Cenário',
+                              'Esquema do Cenario',
+diff --git a/etc/gherkin/gherkin-languages.json b/etc/gherkin/gherkin-languages.json
+index 913cfac..29cbca1 100644
+--- a/etc/gherkin/gherkin-languages.json
++++ b/etc/gherkin/gherkin-languages.json
+@@ -1084,7 +1084,7 @@
+     "name": "Spanish",
+     "native": "español",
+     "rule": [
+-      "Rule"
++      "Regla"
+     ],
+     "scenario": [
+       "Ejemplo",
+@@ -2553,7 +2553,7 @@
+     "name": "Portuguese",
+     "native": "português",
+     "rule": [
+-      "Rule"
++      "Regra"
+     ],
+     "scenario": [
+       "Exemplo",
+diff --git a/invoke.yaml b/invoke.yaml
+index 3e93cfc..d6f141c 100644
+--- a/invoke.yaml
++++ b/invoke.yaml
+@@ -38,6 +38,10 @@ cleanup:
+       - "__WORKDIR__"
+       - reports
+ 
++    extra_files:
++      - "etc/gherkin/gherkin*.json.SAVED"
++      - "etc/gherkin/i18n.py"
++
+ cleanup_all:
+     extra_directories:
+       - .hypothesis
+diff --git a/tasks/__init__.py b/tasks/__init__.py
+index 969a94a..a572465 100644
+--- a/tasks/__init__.py
++++ b/tasks/__init__.py
+@@ -39,6 +39,8 @@ from . import _tasklet_cleanup as cleanup
+ from . import docs
+ from . import test
+ from . import release
++from . import develop
++
+ 
+ # -----------------------------------------------------------------------------
+ # TASKS:
+@@ -56,6 +58,7 @@ namespace.add_collection(Collection.from_module(cleanup), name="cleanup")
+ namespace.add_collection(Collection.from_module(docs))
+ namespace.add_collection(Collection.from_module(test))
+ namespace.add_collection(Collection.from_module(release))
++namespace.add_collection(Collection.from_module(develop))
+ cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+ 
+ cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+diff --git a/tasks/develop.py b/tasks/develop.py
+new file mode 100644
+index 0000000..b08df0e
+--- /dev/null
++++ b/tasks/develop.py
+@@ -0,0 +1,58 @@
++# -*- coding: UTF-8 -*-
++"""
++Development tasks
++"""
++
++from __future__ import absolute_import, print_function
++from invoke import Collection, task
++from invoke.util import cd
++from path import Path
++import requests
++
++# -----------------------------------------------------------------------------
++# CONSTANTS:
++# -----------------------------------------------------------------------------
++GHERKIN_LANGUAGES_URL = "https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/gherkin-languages.json"
++
++
++# -----------------------------------------------------------------------------
++# TASKS:
++# -----------------------------------------------------------------------------
++@task(name="update_gherkin") # TOO-LONGS: aliases=["update_gherkin_languages"])
++def update_gherkin_languages(ctx):
++    """Update "gherkin-languages.json" file from cucumber-repo."""
++    with cd("etc/gherkin"):
++        # -- BACKUP-FILE:
++        gherkin_languages_file = Path("gherkin-languages.json")
++        gherkin_languages_file.copy("gherkin-languages.json.SAVED")
++
++        print('Downloading "gherkin-languages.json" from github:cucumber ...')
++        download_request = requests.get(GHERKIN_LANGUAGES_URL)
++        gherkin_languages_newfile = Path("gherkin-languages.json.NEW")
++        assert download_request.ok
++        print('Download finished: OK (size={0})'.format(len(download_request.content)))
++        with open(gherkin_languages_newfile, "wb") as f:
++            f.write(download_request.content)
++        gherkin_languages_newfile.rename("gherkin-languages.json")
++
++        print('Generating "i18n.py" ...')
++        ctx.run("./convert_gherkin-languages.py")
++
++
++# -----------------------------------------------------------------------------
++# TASK HELPERS:
++# -----------------------------------------------------------------------------
++def print_packages(packages):
++    print("PACKAGES[%d]:" % len(packages))
++    for package in packages:
++        package_size = package.stat().st_size
++        package_time = package.stat().st_mtime
++        print("  - %s  (size=%s)" % (package, package_size))
++
++
++# -----------------------------------------------------------------------------
++# TASK CONFIGURATION:
++# -----------------------------------------------------------------------------
++namespace = Collection()
++namespace.add_task(update_gherkin_languages)
++namespace.configure({})
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index e772d5e..a77d3bc 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -16,3 +16,6 @@ six >= 1.12.0
+ # -- PYTHON2 BACKPORTS:
+ pathlib;    python_version <= '3.4'
+ backports.shutil_which; python_version <= '3.3'
++
++# -- SECTION: develop
++requests
diff --git a/meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch b/meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch
new file mode 100644
index 000000000..939a0901e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch
@@ -0,0 +1,141 @@
+From 084f823fda5939442f48eb34d99c0ed48d675097 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 8 Jul 2019 01:07:11 +0200
+Subject: [PATCH] Tweaks to update/generate from gherkin-languages.json
+
+---
+ etc/gherkin/convert_gherkin-languages.py | 16 +++++++----
+ tasks/develop.py                         | 34 +++++++++++-------------
+ 2 files changed, 27 insertions(+), 23 deletions(-)
+
+diff --git a/etc/gherkin/convert_gherkin-languages.py b/etc/gherkin/convert_gherkin-languages.py
+index 1803ca6..9ef9b0c 100755
+--- a/etc/gherkin/convert_gherkin-languages.py
++++ b/etc/gherkin/convert_gherkin-languages.py
+@@ -68,7 +68,7 @@ def yaml_normalize(data):
+     return data
+ 
+ 
+-def data_normalize(data):
++def data_normalize(data, verbose=False):
+     """Normalize "gherkin-languages.json" data into internal format,
+     needed by behave."
+ 
+@@ -76,7 +76,8 @@ def data_normalize(data):
+     :return: Normalized data (as dictionary).
+     """
+     for language in data:
+-        print("Language: %s ..." % language)
++        if verbose:
++            print("Language: %s ..." % language)
+         # -- STEP: Normalize attribute "scenarioOutline" => "scenario_outline"
+         lang_keywords = data[language]
+         lang_keywords[u"scenario_outline"] = lang_keywords[u"scenarioOutline"]
+@@ -107,7 +108,7 @@ def data_normalize(data):
+ 
+ 
+ def gherkin_languages_to_python_module(gherkin_languages_path, output_file=None,
+-                                       encoding=None):
++                                       encoding=None, verbose=False):
+     """Workhorse.
+     Performs the conversion from "gherkin-languages.json" to "i18n.py".
+     Writes output to file or console (stdout).
+@@ -115,6 +116,7 @@ def gherkin_languages_to_python_module(gherkin_languages_path, output_file=None,
+     :param gherkin_languages_path: File path for JSON file.
+     :param output_file:     Output filename (or STDOUT for: None, "stdout", "-")
+     :param encoding:        Optional output encoding to use (default: UTF-8).
++    :param verbose:         Enable verbose mode (as bool; optional).
+     """
+     if encoding is None:
+         encoding = "UTF-8"
+@@ -122,7 +124,7 @@ def gherkin_languages_to_python_module(gherkin_languages_path, output_file=None,
+     # -- STEP 1: Load JSON data.
+     json_encoding = "UTF-8"
+     languages = json.load(open(gherkin_languages_path, encoding=json_encoding))
+-    languages = data_normalize(languages)
++    languages = data_normalize(languages, verbose=verbose)
+     # languages = yaml_normalize(languages)
+ 
+     # -- STEP 2: Generate python module with i18n data.
+@@ -178,6 +180,9 @@ def main(args=None):
+     parser.add_argument("-e", "--encoding", dest="encoding",
+                         default="UTF-8",
+                         help="Output encoding.")
++    parser.add_argument("--verbose", dest="verbose", default=False,
++                        action="store_true",
++                        help="Enable verbose mode.")
+     parser.add_argument("output_file", default="i18n.py", nargs="?",
+                 help="Filename of Python I18N module (as output).")
+     parser.add_argument("--version", action="version", version=__version__)
+@@ -191,7 +196,8 @@ def main(args=None):
+     try:
+         print("Writing %s .." % options.output_file)
+         gherkin_languages_to_python_module(options.json_file, options.output_file,
+-                                           encoding=options.encoding)
++                                           encoding=options.encoding,
++                                           verbose=options.verbose)
+     except Exception as e:
+         message = "%s: %s" % (e.__class__.__name__, e)
+         sys.exit(message)
+diff --git a/tasks/develop.py b/tasks/develop.py
+index b08df0e..9a21363 100644
+--- a/tasks/develop.py
++++ b/tasks/develop.py
+@@ -18,9 +18,15 @@ GHERKIN_LANGUAGES_URL = "https://raw.githubusercontent.com/cucumber/cucumber/mas
+ # -----------------------------------------------------------------------------
+ # TASKS:
+ # -----------------------------------------------------------------------------
+-@task(name="update_gherkin") # TOO-LONGS: aliases=["update_gherkin_languages"])
+-def update_gherkin_languages(ctx):
+-    """Update "gherkin-languages.json" file from cucumber-repo."""
++@task
++def update_gherkin(ctx, dry_run=False):
++    """Update "gherkin-languages.json" file from cucumber-repo.
++
++    * Download "gherkin-languages.json" from cucumber repo
++    * Update "gherkin-languages.json"
++    * Generate "i18n.py" file from "gherkin-languages.json"
++    * Update "behave/i18n.py" file (optional; not in dry-run mode)
++    """
+     with cd("etc/gherkin"):
+         # -- BACKUP-FILE:
+         gherkin_languages_file = Path("gherkin-languages.json")
+@@ -28,31 +34,23 @@ def update_gherkin_languages(ctx):
+ 
+         print('Downloading "gherkin-languages.json" from github:cucumber ...')
+         download_request = requests.get(GHERKIN_LANGUAGES_URL)
+-        gherkin_languages_newfile = Path("gherkin-languages.json.NEW")
+         assert download_request.ok
+         print('Download finished: OK (size={0})'.format(len(download_request.content)))
+-        with open(gherkin_languages_newfile, "wb") as f:
++        with open(gherkin_languages_file, "wb") as f:
+             f.write(download_request.content)
+-        gherkin_languages_newfile.rename("gherkin-languages.json")
+ 
+         print('Generating "i18n.py" ...')
+         ctx.run("./convert_gherkin-languages.py")
+-
+-
+-# -----------------------------------------------------------------------------
+-# TASK HELPERS:
+-# -----------------------------------------------------------------------------
+-def print_packages(packages):
+-    print("PACKAGES[%d]:" % len(packages))
+-    for package in packages:
+-        package_size = package.stat().st_size
+-        package_time = package.stat().st_mtime
+-        print("  - %s  (size=%s)" % (package, package_size))
++        ctx.run("diff i18n.py ../../behave/i18n.py")
++        if not dry_run:
++            print("Updating behave/i18n.py ...")
++            Path("i18n.py").move("../../behave/i18n.py")
+ 
+ 
+ # -----------------------------------------------------------------------------
+ # TASK CONFIGURATION:
+ # -----------------------------------------------------------------------------
++# TOO-LONG: aliases=["update_gherkin_languages"])
+ namespace = Collection()
+-namespace.add_task(update_gherkin_languages)
++namespace.add_task(update_gherkin)
+ namespace.configure({})
diff --git a/meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch b/meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch
new file mode 100644
index 000000000..8d956cdd5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch
@@ -0,0 +1,322 @@
+From d3ef06c2dfe44b2286b42b7ddcc66f7c9e6aa245 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 9 Jul 2019 08:10:26 +0200
+Subject: [PATCH] EXAMPLE: Tweak naming to @fixture.behave.no_background (was:
+ .override_background)
+
+---
+ examples/fixture.no_background/README.rst     | 110 ++++++++++++++++++
+ .../behave_fixture_lib/__init__.py            |   0
+ .../behave_fixture_lib/no_background.py       |  72 ++++++++++++
+ .../features/environment.py                   |  35 ++++++
+ .../features/example.feature                  |  18 +++
+ .../features/steps/basic_steps.py             |  13 +++
+ .../features/steps/use_steplib_behave4cmd.py  |  12 ++
+ 7 files changed, 260 insertions(+)
+ create mode 100644 examples/fixture.no_background/README.rst
+ create mode 100644 examples/fixture.no_background/behave_fixture_lib/__init__.py
+ create mode 100644 examples/fixture.no_background/behave_fixture_lib/no_background.py
+ create mode 100644 examples/fixture.no_background/features/environment.py
+ create mode 100644 examples/fixture.no_background/features/example.feature
+ create mode 100644 examples/fixture.no_background/features/steps/basic_steps.py
+ create mode 100644 examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py
+
+diff --git a/examples/fixture.no_background/README.rst b/examples/fixture.no_background/README.rst
+new file mode 100644
+index 0000000..4243f10
+--- /dev/null
++++ b/examples/fixture.no_background/README.rst
+@@ -0,0 +1,110 @@
++EXAMPLE: Disable Background Inheritance Mechanism for Scenario
++===============================================================================
++
++:RELATED-TO: #756
++
++This example shows how the Background inheritance mechanism in Gherkin
++can be disabled in ``behave``.
++
++Parts of the recipe:
++
++* features/example.feature (Feature file as example)
++* features/environment.py (glue code and hooks for fixture-tag / fixture)
++* behave_fixture_lib/no_background.py (fixture implementation, workhorse)
++
++
++.. warning:: BEWARE: This shows you how can do it, not that you should do it
++
++    BETTER:
++
++    * Use Rules to group Scenarios, each with its own Background (in Gherkin v6)
++    * Split Feature aspects into multiple feature files (if needed)
++    * ... (see issue #756 above)
++
++
++Explanation
++------------------------------------------------------------------------
++
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism by using a fixture / fixture-tag.
++The fixture-tag "@fixture.behave.no_background" marks the
++location in Gherkin (which Scenario) where the fixture should be used
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.no_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.no_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++When the feature is executed, you see that:
++
++* First Scenario "Alice": Background steps are inherited and executed first.
++* Second Scenario "Bob": No Background step is executed.
++
++.. code-block:: sh
++
++    $ ../../bin/behave -f plain features/example.feature
++    Feature: Override the Background Inheritance Mechanism in some Scenarios
++      Background:
++
++      Scenario: Alice
++        Given a background step passes ... passed
++        When a step passes ... passed
++        And note that "Background steps are executed here" ... passed
++    FIXTURE-HINT: DISABLE-BACKGROUND FOR: Bob
++
++      Scenario: Bob
++        Given I need another scenario setup ... passed
++        When another step passes ... passed
++        And note that "NO-BACKGROUND STEPS are executed here" ... passed
++
++    1 feature passed, 0 failed, 0 skipped
++    2 scenarios passed, 0 failed, 0 skipped
++    6 steps passed, 0 failed, 0 skipped, 0 undefined
++
++
++The environment file provides the glue code that the fixture is called:
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.no_background import behave_no_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.no_background": behave_no_background,
++    }
++
++    # -----------------------------------------------------------------------------
++    # HOOKS:
++    # -----------------------------------------------------------------------------
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++
++.. code-block:: python
++
++    # -- FILE: behave_fixture_lib/no_background.py (fixture implementation)
++    from behave import fixture
++
++    @fixture(name="fixture.behave.no_background")
++    def behave_no_background(ctx):
++        # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++        current_scenario = ctx.scenario
++        if current_scenario:
++            print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % current_scenario.name)
++            current_scenario.use_background = False
+diff --git a/examples/fixture.no_background/behave_fixture_lib/__init__.py b/examples/fixture.no_background/behave_fixture_lib/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/examples/fixture.no_background/behave_fixture_lib/no_background.py b/examples/fixture.no_background/behave_fixture_lib/no_background.py
+new file mode 100644
+index 0000000..47bd0b5
+--- /dev/null
++++ b/examples/fixture.no_background/behave_fixture_lib/no_background.py
+@@ -0,0 +1,72 @@
++# -*- coding: UTF-8 -*-
++# RELATED-TO: #756
++"""
++Example code how to provide a behave fixture to disable the
++background inheritance mechanism.
++
++.. code-block:: gherkin
++
++    # -- FILE: features/example.feature
++    Feature: Show how @fixture.behave.override_background is used
++
++        Background:
++          Given a background step
++
++        Scenario: Alice
++          When a step passes
++          And note that "Background steps are executed here"
++
++        @fixture.behave.no_background
++        Scenario: Bob
++          Given I need another scenario setup
++          When another step passes
++          And note that "NO-BACKGROUND STEPS are executed here"
++
++.. code-block:: python
++
++    # -- FILE: features/environment.py
++    from behave_fixture_lib.override_background import behave_override_background
++    from behave.fixture import use_fixture_by_tag
++
++    # -- FIXTURE REGISTRY:
++    fixture_registry = {
++        "fixture.behave.no_background": behave_override_background,
++    }
++
++    def before_tag(context, tag):
++        if tag.startswith("fixture."):
++            return use_fixture_by_tag(tag, context, fixture_registry)
++
++"""
++
++from __future__ import absolute_import, print_function
++from behave import fixture
++
++
++# -----------------------------------------------------------------------------
++# BEHAVE FIXTURES:
++# -----------------------------------------------------------------------------
++@fixture(name="fixture.behave.ono_background")
++def behave_no_background(ctx):
++    """Override the Background inherintance mechanism.
++    If a Feature / Rule Background exists in a Feature,
++    all contained Scenarios inherit the Background's steps.
++
++    This fixture disables this mechanism.
++    The tagged Gherkin element will no longer inherit the background steps.
++
++    :param ctx: Context object to use (during a test run).
++    """
++    # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
++    current_scenario = ctx.scenario
++    if current_scenario:
++        print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % current_scenario.name)
++        current_scenario.use_background = False
++
++
++# -----------------------------------------------------------------------------
++# MODULE SPECIFIC:
++# -----------------------------------------------------------------------------
++fixture_registry = {
++    "fixture.behave.no_background": behave_no_background,
++}
+diff --git a/examples/fixture.no_background/features/environment.py b/examples/fixture.no_background/features/environment.py
+new file mode 100644
+index 0000000..18857b9
+--- /dev/null
++++ b/examples/fixture.no_background/features/environment.py
+@@ -0,0 +1,35 @@
++# -*- coding: UTF-8 -*-
++# -- FILE: features/environment.py
++import os.path
++import sys
++
++# -----------------------------------------------------------------------------
++# PYTHON PATH SETUP:
++# -----------------------------------------------------------------------------
++HERE = os.path.dirname(__file__)
++TOPA = os.path.abspath(os.path.join(HERE, ".."))
++
++def setup_python_path():
++    sys.path.insert(0, TOPA)
++
++setup_python_path()
++
++# -----------------------------------------------------------------------------
++# NORMAL PART:
++# -----------------------------------------------------------------------------
++from behave_fixture_lib.no_background import behave_no_background
++from behave.fixture import use_fixture_by_tag
++
++# -- FIXTURE REGISTRY:
++fixture_registry = {
++    "fixture.behave.no_background": behave_no_background,
++}
++
++
++# -----------------------------------------------------------------------------
++# HOOKS:
++# -----------------------------------------------------------------------------
++def before_tag(context, tag):
++    if tag.startswith("fixture."):
++        return use_fixture_by_tag(tag, context, fixture_registry)
++
+diff --git a/examples/fixture.no_background/features/example.feature b/examples/fixture.no_background/features/example.feature
+new file mode 100644
+index 0000000..2025716
+--- /dev/null
++++ b/examples/fixture.no_background/features/example.feature
+@@ -0,0 +1,18 @@
++Feature: Disable the Background Inheritance Mechanism in some Scenarios
++
++  . BEWARE:
++  .   This is only an example how this can be done (PROOF-OF-CONCEPT).
++  .   This is not an example that you should do this !!!
++
++    Background:
++      Given a background step passes
++
++    Scenario: Alice
++      When a step passes
++      And note that "BACKGROUND STEPS are executed here"
++
++    @fixture.behave.no_background
++    Scenario: Bob
++      Given I need another scenario setup
++      When another step passes
++      And note that "NO-BACKGROUND STEPS are executed here"
+diff --git a/examples/fixture.no_background/features/steps/basic_steps.py b/examples/fixture.no_background/features/steps/basic_steps.py
+new file mode 100644
+index 0000000..34f2107
+--- /dev/null
++++ b/examples/fixture.no_background/features/steps/basic_steps.py
+@@ -0,0 +1,13 @@
++from behave import given, step
++
++# @step(u'{word} step passes')
++# def step_passes_with_word(context, word):
++#     pass
++
++@step(u'{word} background step passes')
++def step_background_step_passes(context, word):
++    pass
++
++@given(u'I need {word} scenario setup')
++def step_given_i_need_scenario_setup(context, word):
++    pass
+diff --git a/examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py b/examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py
+new file mode 100644
+index 0000000..bc32a32
+--- /dev/null
++++ b/examples/fixture.no_background/features/steps/use_steplib_behave4cmd.py
+@@ -0,0 +1,12 @@
++# -*- coding: utf-8 -*-
++"""
++Use behave4cmd0 step library (predecessor of behave4cmd).
++"""
++
++from __future__ import absolute_import
++
++# -- REGISTER-STEPS FROM STEP-LIBRARY:
++# import behave4cmd0.__all_steps__
++# import behave4cmd0.failing_steps
++import behave4cmd0.passing_steps
++import behave4cmd0.note_steps
diff --git a/meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch b/meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch
new file mode 100644
index 000000000..b630d48e7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch
@@ -0,0 +1,64 @@
+From b52d7c5d0141971f2e745ec806f829e2c7c897cf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 9 Jul 2019 08:20:25 +0200
+Subject: [PATCH] EXAMPLE: Cleanup Gherkin v6 README
+
+---
+ examples/gherkin_v6/README.rst                | 23 +++++++++++--------
+ .../features/steps/passing_steps.py           | 11 +++++++++
+ 2 files changed, 25 insertions(+), 9 deletions(-)
+ create mode 100644 examples/gherkin_v6/features/steps/passing_steps.py
+
+diff --git a/examples/gherkin_v6/README.rst b/examples/gherkin_v6/README.rst
+index 58199dd..99af1c5 100644
+--- a/examples/gherkin_v6/README.rst
++++ b/examples/gherkin_v6/README.rst
+@@ -2,17 +2,22 @@ Gherkin v6 Examples
+ =============================================================================
+ 
+ 
+-SCRATCHPAD: Problems
+------------------------------------------------------------------------------
++Provides example(s) of Gherkin v6 additions:
+ 
+-- SummaryReporter: Shows wrong counts when Rules are present::
++* Rule concept
++* New aliases for Gherkin keywords (Scenario, ScenarioOutline)
+ 
+-    ...
+-    0 features passed, 0 failed, 1 skipped XXX
+-    3 rules passed, 0 failed, 0 skipped
+-    5 scenarios passed, 0 failed, 0 skipped
+-    13 steps passed, 0 failed, 0 skipped, 0 undefined
++Rule functionality:
+ 
++* A Rule is a scenario container similar to a Feature
++* A Feature may contain many Rules
++* A Rule may not contain other Rules
++* A Rule may contain a Background (and inherits its Feature Background)
++* A Rule inherits its Feature Background if it has no Background
++* A Rule may contain many Scenarios and/or ScenarioOutlines
++* A Rule may have tags
+ 
+-- Formatters: PrettyFormatter, PlainFormatter (at least) need Rule support
++New keyword aliases:
+ 
++* "Scenario Template" for "Scenario Outline"
++* "Example" for "Scenario"
+diff --git a/examples/gherkin_v6/features/steps/passing_steps.py b/examples/gherkin_v6/features/steps/passing_steps.py
+new file mode 100644
+index 0000000..2714cb1
+--- /dev/null
++++ b/examples/gherkin_v6/features/steps/passing_steps.py
+@@ -0,0 +1,11 @@
++# -*- coding: UTF-8 -*-
++
++from behave import step
++
++@step(u'{word} step passes')
++def step_passes(ctx, word):
++    pass
++
++@step(u'{word} step fails')
++def step_fails(ctx, word):
++    assert False, "XFAIL-STEP: {0} step fails".format(word)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch b/meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch
new file mode 100644
index 000000000..764ff7869
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0051-Improve-support-for-feature.background-inheritance-f.patch
@@ -0,0 +1,1510 @@
+From 4f013b949f6528ec70105c1fb8e292f23e3a13c8 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 10 Jul 2019 22:38:13 +0200
+Subject: [PATCH] Improve support for feature.background inheritance for
+ rule.background.
+
+---
+ .gitignore                                    |   3 +
+ behave/model.py                               | 230 ++++++++++--
+ behave/parser.py                              |   9 +-
+ .../fixture.override_background/README.rst    | 116 ------
+ .../behave_fixture_lib/__init__.py            |   0
+ .../behave_fixture_lib/override_background.py |  80 -----
+ .../features/environment.py                   |  35 --
+ .../features/example.feature                  |  18 -
+ .../features/steps/basic_steps.py             |  13 -
+ .../features/steps/use_steplib_behave4cmd.py  |  12 -
+ setup.py                                      |   1 +
+ tests/unit/test_model.py                      | 117 +-----
+ tests/unit/test_model2.py                     |   4 -
+ tests/unit/test_model_core.py                 | 116 +++++-
+ tests/unit/test_parser_gherkin_v6.py          | 339 +++++++++++++++++-
+ 15 files changed, 645 insertions(+), 448 deletions(-)
+ delete mode 100644 examples/fixture.override_background/README.rst
+ delete mode 100644 examples/fixture.override_background/behave_fixture_lib/__init__.py
+ delete mode 100644 examples/fixture.override_background/behave_fixture_lib/override_background.py
+ delete mode 100644 examples/fixture.override_background/features/environment.py
+ delete mode 100644 examples/fixture.override_background/features/example.feature
+ delete mode 100644 examples/fixture.override_background/features/steps/basic_steps.py
+ delete mode 100644 examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+
+diff --git a/.gitignore b/.gitignore
+index 6196a6d..9c5c33d 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -7,6 +7,9 @@ build/
+ dist/
+ __pycache__/
+ __WORKDIR__/
++__*/
++__*.txt
++__*.rst
+ _build/
+ _WORKSPACE/
+ reports/
+diff --git a/behave/model.py b/behave/model.py
+index 7fc534a..69f38ab 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -29,6 +29,36 @@ else:
+     import traceback
+ 
+ 
++# ---------------------------------------------------------------------------
++# MODEL UTILITIES:
++# ---------------------------------------------------------------------------
++def reset_steps(steps):
++    for step in steps:
++        step.reset()
++    return steps
++
++
++def copy_steps(steps):
++    """Copy steps; needed if steps should be used in multiple run contexts.
++
++    :param steps:       List of steps to copy.
++    :return: List of copied steps.
++    """
++    return [copy.copy(step) for step in steps]
++
++
++def copy_and_reset_steps(steps):
++    """Copy steps and reset each step (status, duration, etc.)
++
++    :param steps:       List of steps to copy.
++    :return: List of copied steps.
++    """
++    return reset_steps(copy_steps(steps))
++
++
++# ---------------------------------------------------------------------------
++# MODEL CLASSES:
++# ---------------------------------------------------------------------------
+ class ScenarioContainer(TagAndStatusStatement, Replayable):
+     """Abstract base class for model elements
+     that contains the following structure:
+@@ -198,8 +228,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+         if skipped:
+             return Status.skipped
+-        else:
+-            return Status.passed
++        # -- OTHERWISE:
++        return Status.passed
+ 
+     @property
+     def duration(self):
+@@ -230,7 +260,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+                 rule = run_item
+                 if with_rules:
+                     all_scenarios.append(rule)
+-                all_scenarios.extend(rule.walk_scenarios(with_outlines=with_outlines))
++                scenarios = rule.walk_scenarios(with_outlines=with_outlines)
++                all_scenarios.extend(scenarios)
+             elif isinstance(run_item, ScenarioOutline):
+                 scenario_outline = run_item
+                 if with_outlines:
+@@ -241,6 +272,16 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+                 all_scenarios.append(run_item)
+         return all_scenarios
+ 
++    def iter_scenarios(self):
++        return iter(self.walk_scenarios())
++
++    def iter_scenario_outlines(self):
++        return iter([x for x in self.walk_scenarios(with_outlines=True)
++                     if isinstance(x, ScenarioOutline)])
++
++    def iter_rules(self):
++        return iter([x for x in self.run_items if isinstance(x, Rule)])
++
+     def should_run(self, config=None):
+         """
+         Determines if this Feature (and its scenarios) should run.
+@@ -312,7 +353,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         :param runner:  Runner to use.
+         :return: True, if test-run failed.
+         """
+-        # pylint: disable=too-many-branches
++        # pylint: disable=too-many-branches, too-many-locals, too-many-statements
+         # MAYBE: self.reset()
+         self.clear_status()
+         self.hook_failed = False
+@@ -387,7 +428,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         # -- PERFORM CONTEXT CLEANUP: May raise cleanup errors.
+         try:
+             runner.context._pop()       # pylint: disable=protected-access
+-        except Exception:
++        except Exception:               # pylint: disable=broad-except
+             # -- CLEANUP-ERROR:
+             self.set_status(Status.failed)
+ 
+@@ -509,16 +550,28 @@ class Feature(ScenarioContainer):
+     def _setup_context_for_run(self, context):
+         context.feature = self
+ 
++    def add_background(self, background):
++        self.background = background
++        self.background.parent = self
++
+     def add_rule(self, rule):
+-        """Add a rule to this feature."""
++        """Add a rule to this feature (supported in: Gherkin v6).
++
++        .. versionadded: 1.2.7
++        """
+         feature = self
+         rule.parent = feature
+         rule.feature = feature
+-        if not rule.background:
+-            # -- MAYBE: Inherit feature.background if the rule has no background.
+-            rule.background = self.background
+         self.rules.append(rule)
+         self.run_items.append(rule)
++        if self.background:
++            # -- ENSURE: Rule inherits feature.background.
++            if not rule.background:
++                # -- ENSURE: Rule has a default background.
++                # Necessary to inherit feature.background (or disable it).
++                rule_default_background = Background(rule.filename, rule.line)
++                rule.add_background(rule_default_background)
++            rule.background.inherited_background = self.background
+ 
+ 
+ class Rule(ScenarioContainer):
+@@ -630,6 +683,7 @@ class Rule(ScenarioContainer):
+                                    description, scenarios, background)
+         self.parent = parent
+         self.feature = parent
++        self._use_background_inheritance = True
+ 
+     def _setup_context_for_run(self, context):
+         context.rule = self
+@@ -638,10 +692,43 @@ class Rule(ScenarioContainer):
+         return '<Rule "%s": %d scenario(s)>' % \
+             (self.name, len(self.scenarios))
+ 
++    def add_background(self, background, inherited=None):
++        if inherited is None:
++            feature = self.feature or self.parent
++            inherited = feature.background
++
++        self.background = background
++        self.background.inherited_background = inherited
++        self.background.use_inheritance = self.use_background_inheritance
++        self.background.parent = self
++        # -- ENSURE: Normally background is added before scenarios.
++        for scenario in self.walk_scenarios():
++            scenario.background = self.background
++
++    @property
++    def use_background_inheritance(self):
++        return self._use_background_inheritance
++
++    @use_background_inheritance.setter
++    def use_background_inheritance(self, value):
++        self._use_background_inheritance = value
++        if self.background:
++            self.background.use_inheritance = value
++
+ 
+ class Background(BasicStatement, Replayable):
+     """A `background`_ parsed from a *feature file*.
+ 
++    Behaviour:
++
++    * Each scenario of a scenario container (Feature, Rule)
++      inherits the Background of its scenario container
++    * Background steps in a scenario are executed before scenario steps
++    * Rule Background inherits the Feature Background (outer background) if any
++    * Inherited Background steps are used/executed first
++    * Optionally, background inheritance can be disabled
++      (normally: by using a fixture/fixture-tag)
++
+     The attributes are:
+ 
+     .. attribute:: keyword
+@@ -679,23 +766,65 @@ class Background(BasicStatement, Replayable):
+ 
+     .. _`background`: gherkin.html#backgrounds
+     """
+-    # TODO: Background inheritance
+-    # Rule.background should inherit its Feature.background steps (if available)
+-    # Rule.background = Feature.background iff not Rule.background exists (ALREADY-SOLVED)
+-    # Rule may override background inheritance mechanism
+     type = "background"
+ 
+-    def __init__(self, filename, line, keyword, name, steps=None, description=None):
++    def __init__(self, filename, line, keyword=u"Background", name=u"",
++                 steps=None, description=None):
+         super(Background, self).__init__(filename, line, keyword, name)
+         self.description = description or []
+         self.steps = steps or []
++        self.inherited_background = None
++        self._inherited_steps = None
++        self._use_inheritance = True
+ 
+-    def __repr__(self):
+-        return '<Background "%s">' % self.name
++    @property
++    def use_inheritance(self):
++        """Indicates if this Background should inherit from an outer Background.
++        Background inheritance mechanism is enabled (per default).
++        Optionally, this mechanism can be disabled (or overridden).
+ 
+-    def __iter__(self):
++        :return: Current background inheritance state (as bool).
++
++        .. versionadded:: 1.2.7
++        """
++        return self._use_inheritance
++
++    @use_inheritance.setter
++    def use_inheritance(self, value):
++        """Enable/disable background inheritance mechanism for this Background.
++
++        :param value:   New value (as bool).
++
++        .. versionadded:: 1.2.7
++        """
++        # -- ENSURE: inherited_steps are reinitialized (later).
++        self._use_inheritance = bool(value)
++        self._inherited_steps = None
++
++    @property
++    def inherited_steps(self):
++        # versionadded:: 1.2.7
++        if self._inherited_steps is None:
++            # -- LAZY-INIT: Support enable/disable the inheritance mechanism.
++            steps = []
++            if self.inherited_background and self._use_inheritance:
++                steps = copy_and_reset_steps(self.inherited_background.steps)
++            self._inherited_steps = steps
++        return self._inherited_steps
++
++    def iter_steps(self):
++        """Returns iterator to all steps, including inherited steps (if any).
++
++        .. versionadded:: 1.2.7
++        """
++        if self.inherited_steps:
++            return itertools.chain(self.inherited_steps, self.steps)
+         return iter(self.steps)
+ 
++    @property
++    def all_steps(self):
++        return self.iter_steps()
++
+     @property
+     def duration(self):
+         duration = 0
+@@ -703,6 +832,12 @@ class Background(BasicStatement, Replayable):
+             duration += step.duration
+         return duration
+ 
++    def __repr__(self):
++        return '<Background "%s">' % self.name
++
++    def __iter__(self):
++        return self.iter_steps()
++
+ 
+ class Scenario(TagAndStatusStatement, Replayable):
+     """A `scenario`_ parsed from a *feature file*.
+@@ -799,6 +934,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+         self.feature = None  # REFER-TO: owner=Feature
+         self.hook_failed = False
+         self._background_steps = None
++        self._use_background = True
+         self._row = None
+         self.was_dry_run = False
+ 
+@@ -813,6 +949,27 @@ class Scenario(TagAndStatusStatement, Replayable):
+         for step in self.all_steps:
+             step.reset()
+ 
++    @property
++    def use_background(self):
++        """Indicates if the background is/would be used (if any exists).
++        NOTE: The Background (steps) are normally used.
++
++        .. versionadded:: 1.2.7
++        """
++        return self._use_background
++
++    @use_background.setter
++    def use_background(self, value):
++        """Enable/disable the usage of the background (steps).
++
++        :param value:  New value (as bool).
++
++        .. versionadded:: 1.2.7
++        """
++        # -- ENSURE: background_steps are reinitialized.
++        self._use_background = value
++        self._background_steps = None
++
+     @property
+     def background_steps(self):
+         """Provide background steps if feature/rule has a background.
+@@ -828,24 +985,29 @@ class Scenario(TagAndStatusStatement, Replayable):
+             # Each scenario needs own background.steps.
+             # Otherwise, background step status of the last-run scenario is used.
+             steps = []
+-            if self.background:
+-                steps = [copy.copy(step) for step in self.background.steps]
++            if self.background and self.use_background:
++                steps = copy_and_reset_steps(self.background.all_steps)
+             self._background_steps = steps
+         return self._background_steps
+ 
+-    @property
+-    def all_steps(self):
+-        """Returns iterator to all steps, including background steps if any."""
++    def iter_steps(self):
++        """Returns iterator to all steps, including background steps if any.
++
++        .. versionadded:: 1.2.7
++        """
+         if self.background is not None:
+             return itertools.chain(self.background_steps, self.steps)
+-        else:
+-            return iter(self.steps)
++        return iter(self.steps)
++
++    @property
++    def all_steps(self):
++        return self.iter_steps()
+ 
+     def __repr__(self):
+         return '<Scenario "%s">' % self.name
+ 
+     def __iter__(self):
+-        return self.all_steps
++        return self.iter_steps()
+ 
+     def compute_status(self):
+         """Compute the status of the scenario from its steps
+@@ -862,9 +1024,8 @@ class Scenario(TagAndStatusStatement, Replayable):
+                     # -- SPECIAL CASE: In dry-run with undefined-step discovery
+                     #    Undefined steps should not cause failed scenario.
+                     return Status.untested
+-                else:
+-                    # -- NORMALLY: Undefined steps cause failed scenario.
+-                    return Status.failed
++                # -- NORMALLY: Undefined steps cause failed scenario.
++                return Status.failed
+             elif step.status != Status.passed:
+                 # pylint: disable=line-too-long
+                 assert step.status in (Status.failed, Status.skipped, Status.untested)
+@@ -1029,7 +1190,6 @@ class Scenario(TagAndStatusStatement, Replayable):
+                     # BUT: Detect all remaining undefined steps.
+                     step.status = Status.skipped
+                     if dry_run_scenario:
+-                        # pylint: disable=redefined-variable-type
+                         step.status = Status.untested
+                     found_step_match = runner.step_registry.find_match(step)
+                     if not found_step_match:
+@@ -1067,7 +1227,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+         # -- PERFORM CONTEXT-CLEANUP: May raise cleanup errors.
+         try:
+             runner.context._pop()       # pylint: disable=protected-access
+-        except Exception:
++        except Exception:               # pylint: disable=broad-except
+             self.set_status(Status.failed)
+             failed = True
+ 
+@@ -1176,9 +1336,9 @@ class ScenarioOutlineBuilder(object):
+                 placeholder = u"<%s>" % name
+                 for i, cell in enumerate(new_step.table.headings):
+                     new_step.table.headings[i] = cell.replace(placeholder, value)
+-                for row in new_step.table:
+-                    for i, cell in enumerate(row.cells):
+-                        row.cells[i] = cell.replace(placeholder, value)
++                for step_row in new_step.table:
++                    for i, cell in enumerate(step_row.cells):
++                        step_row.cells[i] = cell.replace(placeholder, value)
+         return new_step
+ 
+     def build_scenarios(self, scenario_outline):
+@@ -1640,7 +1800,6 @@ class Step(BasicStatement, Replayable):
+                 match.run(runner.context)
+                 if self.status == Status.untested:
+                     # -- NOTE: Executed step may have skipped scenario and itself.
+-                    # pylint: disable=redefined-variable-type
+                     self.status = Status.passed
+             except KeyboardInterrupt as e:
+                 runner.aborted = True
+@@ -1815,8 +1974,7 @@ class Table(Replayable):
+         """
+         if self.has_column(column_name):
+             return self.get_column_index(column_name)
+-        else:
+-            return self.add_column(column_name)
++        return self.add_column(column_name)
+ 
+     def __repr__(self):
+         return "<Table: %dx%d>" % (len(self.headings), len(self.rows))
+diff --git a/behave/parser.py b/behave/parser.py
+index 993c9dc..520f678 100644
+--- a/behave/parser.py
++++ b/behave/parser.py
+@@ -249,7 +249,6 @@ class Parser(object):
+         self.rule = rule
+         self.scenario_container = rule
+         self.statement = rule
+-        # MAYBE: self.background = None
+         self.feature.add_rule(self.statement)
+         # -- RESET STATE:
+         self.tags = []
+@@ -258,11 +257,15 @@ class Parser(object):
+         if self.tags:
+             msg = u"Background supports no tags: @%s" % (u" @".join(self.tags))
+             raise ParserError(msg, self.line, self.filename, line)
++        elif self.scenario_container and self.scenario_container.background:
++            if self.scenario_container.background.steps:
++                # -- HINT: Rule may have default background w/o steps.
++                msg = u"Second Background (can have only one)"
++                raise ParserError(msg, self.line, self.filename, line)
+         name = line[len(keyword) + 1:].strip()
+         background = model.Background(self.filename, self.line, keyword, name)
++        self.scenario_container.add_background(background)
+         self.statement = background
+-        self.scenario_container.background = background
+-        # OLD: self.feature.background = self.statement
+ 
+     def _build_scenario_statement(self, keyword, line):
+         name = line[len(keyword) + 1:].strip()
+diff --git a/examples/fixture.override_background/README.rst b/examples/fixture.override_background/README.rst
+deleted file mode 100644
+index 9c150cc..0000000
+--- a/examples/fixture.override_background/README.rst
++++ /dev/null
+@@ -1,116 +0,0 @@
+-EXAMPLE: Override / Disable Background Inheritance Mechanism for Scenario
+-===============================================================================
+-
+-:RELATED-TO: #756
+-
+-This example shows how the Background inheritance mechanism in Gherkin
+-can be disabled in ``behave``.
+-
+-Parts of the recipe:
+-
+-* features/example.feature (Feature file as example)
+-* features/environment.py (glue code and hooks for fixture-tag / fixture)
+-* behave_fixture_lib/override_background.py (fixture implementation, workhorse)
+-
+-
+-.. warning:: BEWARE: This shows you how can do it, not that you should do it
+-
+-    BETTER:
+-
+-    * Use Rules to group Scenarios, each with its own Background (in Gherkin v6)
+-    * Split Feature aspects into multiple feature files (if needed)
+-    * ... (see issue #756 above)
+-
+-
+-Explanation
+-------------------------------------------------------------------------
+-
+-Example code how to provide a behave fixture to disable the
+-background inheritance mechanism by using a fixture / fixture-tag.
+-The fixture-tag "@ixture.behave.override_background" marks the
+-location in Gherkin (which Scenario) where the fixture should be used
+-
+-.. code-block:: gherkin
+-
+-    # -- FILE: features/example.feature
+-    Feature: Show how @fixture.behave.override_background is used
+-
+-        Background:
+-          Given a background step
+-
+-        Scenario: Alice
+-          When a step passes
+-          And note that "Background steps are executed here"
+-
+-        @fixture.behave.overide_background
+-        Scenario: Bob
+-          Given I need another scenario setup
+-          When another step passes
+-          And note that "NO-BACKGROUND STEPS are executed here"
+-
+-When the feature is executed, you see that:
+-
+-* First Scenario "Alice": Background steps are inherited and executed first.
+-* Second Scenario "Bob": No Background step is executed.
+-
+-.. code-block:: sh
+-
+-    $ ../../bin/behave -f plain features/example.feature
+-    Feature: Override the Background Inheritance Mechanism in some Scenarios
+-      Background:
+-
+-      Scenario: Alice
+-        Given a background step passes ... passed
+-        When a step passes ... passed
+-        And note that "Background steps are executed here" ... passed
+-    FIXTURE-HINT: DISABLE-BACKGROUND FOR: Bob
+-
+-      Scenario: Bob
+-        Given I need another scenario setup ... passed
+-        When another step passes ... passed
+-        And note that "NO-BACKGROUND STEPS are executed here" ... passed
+-
+-    1 feature passed, 0 failed, 0 skipped
+-    2 scenarios passed, 0 failed, 0 skipped
+-    6 steps passed, 0 failed, 0 skipped, 0 undefined
+-
+-
+-The environment file provides the glue code that the fixture is called:
+-
+-.. code-block:: python
+-
+-    # -- FILE: features/environment.py
+-    from behave_fixture_lib.override_background import behave_override_background
+-    from behave.fixture import use_fixture_by_tag
+-
+-    # -- FIXTURE REGISTRY:
+-    fixture_registry = {
+-        "fixture.behave.overide_background": behave_override_background,
+-    }
+-
+-    # -----------------------------------------------------------------------------
+-    # HOOKS:
+-    # -----------------------------------------------------------------------------
+-    def before_tag(context, tag):
+-        if tag.startswith("fixture."):
+-            return use_fixture_by_tag(tag, context, fixture_registry)
+-
+-
+-.. code-block:: python
+-
+-    # -- FILE: behave_fixture_lib/override_background.py (fixture implementation)
+-    from behave import fixture
+-
+-    @fixture(name="fixture.behave.override_background")
+-    def behave_override_background(ctx):
+-        # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
+-        current_scenario = ctx.scenario
+-        if current_scenario:
+-            behave_disable_background_inheritance_for_scenario(current_scenario)
+-
+-    # -----------------------------------------------------------------------------
+-    # BEHAVE UTILITY:
+-    # -----------------------------------------------------------------------------
+-    def behave_disable_background_inheritance_for_scenario(scenario):
+-        print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
+-        scenario.background = None
+diff --git a/examples/fixture.override_background/behave_fixture_lib/__init__.py b/examples/fixture.override_background/behave_fixture_lib/__init__.py
+deleted file mode 100644
+index e69de29..0000000
+diff --git a/examples/fixture.override_background/behave_fixture_lib/override_background.py b/examples/fixture.override_background/behave_fixture_lib/override_background.py
+deleted file mode 100644
+index 6c572cf..0000000
+--- a/examples/fixture.override_background/behave_fixture_lib/override_background.py
++++ /dev/null
+@@ -1,80 +0,0 @@
+-# -*- coding: UTF-8 -*-
+-# RELATED-TO: #756
+-"""
+-Example code how to provide a behave fixture to disable the
+-background inheritance mechanism.
+-
+-.. code-block:: gherkin
+-
+-    # -- FILE: features/example.feature
+-    Feature: Show how @fixture.behave.override_background is used
+-
+-        Background:
+-          Given a background step
+-
+-        Scenario: Alice
+-          When a step passes
+-          And note that "Background steps are executed here"
+-
+-        @fixture.behave.overide_background
+-        Scenario: Bob
+-          Given I need another scenario setup
+-          When another step passes
+-          And note that "NO-BACKGROUND STEPS are executed here"
+-
+-.. code-block:: python
+-
+-    # -- FILE: features/environment.py
+-    from behave_fixture_lib.override_background import behave_override_background
+-    from behave.fixture import use_fixture_by_tag
+-
+-    # -- FIXTURE REGISTRY:
+-    fixture_registry = {
+-        "fixture.behave.overide_background": behave_override_background,
+-    }
+-
+-    def before_tag(context, tag):
+-        if tag.startswith("fixture."):
+-            return use_fixture_by_tag(tag, context, fixture_registry)
+-
+-"""
+-
+-from __future__ import absolute_import, print_function
+-from behave import fixture
+-
+-
+-# -----------------------------------------------------------------------------
+-# BEHAVE FIXTURES:
+-# -----------------------------------------------------------------------------
+-@fixture(name="fixture.behave.override_background")
+-def behave_override_background(ctx):
+-    """Override the Background inherintance mechanism.
+-    If a Feature / Rule Background exists in a Feature,
+-    all contained Scenarios inherit the Background's steps.
+-
+-    This fixture disables this mechanism.
+-    The tagged Gherkin element will no longer inherit the background steps.
+-
+-    :param ctx: Context object to use (during a test run).
+-    """
+-    # -- SETUP-PART-ONLY: Disable background inheritance (for scenarios only).
+-    current_scenario = ctx.scenario
+-    if current_scenario:
+-        behave_disable_background_inheritance_for_scenario(current_scenario)
+-
+-
+-# -----------------------------------------------------------------------------
+-# BEHAVE UTILITY:
+-# -----------------------------------------------------------------------------
+-def behave_disable_background_inheritance_for_scenario(scenario):
+-    print("FIXTURE-HINT: DISABLE-BACKGROUND FOR: %s" % scenario.name)
+-    scenario.background = None
+-    # scenario._background_steps = []
+-
+-
+-# -----------------------------------------------------------------------------
+-# MODULE SPECIFIC:
+-# -----------------------------------------------------------------------------
+-fixture_registry = {
+-    "fixture.behave.overide_background": behave_override_background,
+-}
+diff --git a/examples/fixture.override_background/features/environment.py b/examples/fixture.override_background/features/environment.py
+deleted file mode 100644
+index 7a4b735..0000000
+--- a/examples/fixture.override_background/features/environment.py
++++ /dev/null
+@@ -1,35 +0,0 @@
+-# -*- coding: UTF-8 -*-
+-# -- FILE: features/environment.py
+-import os.path
+-import sys
+-
+-# -----------------------------------------------------------------------------
+-# PYTHON PATH SETUP:
+-# -----------------------------------------------------------------------------
+-HERE = os.path.dirname(__file__)
+-TOPA = os.path.abspath(os.path.join(HERE, ".."))
+-
+-def setup_python_path():
+-    sys.path.insert(0, TOPA)
+-
+-setup_python_path()
+-
+-# -----------------------------------------------------------------------------
+-# NORMAL PART:
+-# -----------------------------------------------------------------------------
+-from behave_fixture_lib.override_background import behave_override_background
+-from behave.fixture import use_fixture_by_tag
+-
+-# -- FIXTURE REGISTRY:
+-fixture_registry = {
+-    "fixture.behave.overide_background": behave_override_background,
+-}
+-
+-
+-# -----------------------------------------------------------------------------
+-# HOOKS:
+-# -----------------------------------------------------------------------------
+-def before_tag(context, tag):
+-    if tag.startswith("fixture."):
+-        return use_fixture_by_tag(tag, context, fixture_registry)
+-
+diff --git a/examples/fixture.override_background/features/example.feature b/examples/fixture.override_background/features/example.feature
+deleted file mode 100644
+index 5ddd874..0000000
+--- a/examples/fixture.override_background/features/example.feature
++++ /dev/null
+@@ -1,18 +0,0 @@
+-Feature: Override the Background Inheritance Mechanism in some Scenarios
+-
+-  . BEWARE:
+-  .   This is only an example how this can be done (PROOF-OF-CONCEPT).
+-  .   This is not an example that you should do this !!!
+-
+-    Background:
+-      Given a background step passes
+-
+-    Scenario: Alice
+-      When a step passes
+-      And note that "Background steps are executed here"
+-
+-    @fixture.behave.overide_background
+-    Scenario: Bob
+-      Given I need another scenario setup
+-      When another step passes
+-      And note that "NO-BACKGROUND STEPS are executed here"
+diff --git a/examples/fixture.override_background/features/steps/basic_steps.py b/examples/fixture.override_background/features/steps/basic_steps.py
+deleted file mode 100644
+index 34f2107..0000000
+--- a/examples/fixture.override_background/features/steps/basic_steps.py
++++ /dev/null
+@@ -1,13 +0,0 @@
+-from behave import given, step
+-
+-# @step(u'{word} step passes')
+-# def step_passes_with_word(context, word):
+-#     pass
+-
+-@step(u'{word} background step passes')
+-def step_background_step_passes(context, word):
+-    pass
+-
+-@given(u'I need {word} scenario setup')
+-def step_given_i_need_scenario_setup(context, word):
+-    pass
+diff --git a/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py b/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
+deleted file mode 100644
+index bc32a32..0000000
+--- a/examples/fixture.override_background/features/steps/use_steplib_behave4cmd.py
++++ /dev/null
+@@ -1,12 +0,0 @@
+-# -*- coding: utf-8 -*-
+-"""
+-Use behave4cmd0 step library (predecessor of behave4cmd).
+-"""
+-
+-from __future__ import absolute_import
+-
+-# -- REGISTER-STEPS FROM STEP-LIBRARY:
+-# import behave4cmd0.__all_steps__
+-# import behave4cmd0.failing_steps
+-import behave4cmd0.passing_steps
+-import behave4cmd0.note_steps
+diff --git a/setup.py b/setup.py
+index cea4392..8de3ec0 100644
+--- a/setup.py
++++ b/setup.py
+@@ -131,6 +131,7 @@ setup(
+         "Programming Language :: Python :: 3.5",
+         "Programming Language :: Python :: 3.6",
+         "Programming Language :: Python :: 3.7",
++        "Programming Language :: Python :: 3.8",
+         "Programming Language :: Python :: Implementation :: CPython",
+         "Programming Language :: Python :: Implementation :: Jython",
+         "Programming Language :: Python :: Implementation :: PyPy",
+diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py
+index c1fc424..21d6c27 100644
+--- a/tests/unit/test_model.py
++++ b/tests/unit/test_model.py
+@@ -8,7 +8,7 @@ from mock import Mock, patch
+ import six
+ from six.moves import range     # pylint: disable=redefined-builtin
+ from six.moves import zip       # pylint: disable=redefined-builtin
+-from behave.model_core import FileLocation, Status
++from behave.model_core import Status
+ from behave.model import Feature, Scenario, ScenarioOutline, Step
+ from behave.model import Table, Row
+ from behave.matchers import NoMatch
+@@ -20,19 +20,12 @@ from behave import step_registry
+ 
+ if six.PY2:
+     # pylint: disable=unused-import
+-    import traceback2 as traceback
+     traceback_modname = "traceback2"
+ else:
+     # pylint: disable=unused-import
+-    import traceback
+     traceback_modname = "traceback"
+ 
+ 
+-
+-# -- CONVENIENCE-ALIAS:
+-_text = six.text_type
+-
+-
+ class TestFeatureRun(unittest.TestCase):
+     # pylint: disable=invalid-name
+ 
+@@ -769,111 +762,3 @@ class TestModelRow(unittest.TestCase):
+         assert data1["name"] == u"Alice"
+         assert data1["sex"] == u"female"
+         assert data1["age"] == u"12"
+-
+-
+-class TestFileLocation(unittest.TestCase):
+-    # pylint: disable=invalid-name
+-    ordered_locations1 = [
+-        FileLocation("features/alice.feature", 1),
+-        FileLocation("features/alice.feature", 5),
+-        FileLocation("features/alice.feature", 10),
+-        FileLocation("features/alice.feature", 11),
+-        FileLocation("features/alice.feature", 100),
+-    ]
+-    ordered_locations2 = [
+-        FileLocation("features/alice.feature", 1),
+-        FileLocation("features/alice.feature", 10),
+-        FileLocation("features/bob.feature", 5),
+-        FileLocation("features/charly.feature", None),
+-        FileLocation("features/charly.feature", 0),
+-        FileLocation("features/charly.feature", 100),
+-    ]
+-    same_locations = [
+-        (FileLocation("alice.feature"),
+-         FileLocation("alice.feature", None),
+-        ),
+-        (FileLocation("alice.feature", 10),
+-         FileLocation("alice.feature", 10),
+-        ),
+-        (FileLocation("features/bob.feature", 11),
+-         FileLocation("features/bob.feature", 11),
+-        ),
+-    ]
+-
+-    def test_compare_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert value1 == value2
+-
+-    def test_compare_equal_with_string(self):
+-        for location in self.ordered_locations2:
+-            assert location == location.filename
+-            assert location.filename == location
+-
+-    def test_compare_not_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert not(value1 != value2)    # pylint: disable=unneeded-not, superfluous-parens
+-
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value1 != value2
+-
+-    def test_compare_less_than(self):
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value1 < value2, "FAILED: %s < %s" % (_text(value1), _text(value2))
+-                assert value1 != value2
+-
+-    def test_compare_less_than_with_string(self):
+-        locations = self.ordered_locations2
+-        for value1, value2 in zip(locations, locations[1:]):
+-            if value1.filename == value2.filename:
+-                continue
+-            assert value1 < value2.filename, \
+-                   "FAILED: %s < %s" % (_text(value1), _text(value2.filename))
+-            assert value1.filename < value2, \
+-                   "FAILED: %s < %s" % (_text(value1.filename), _text(value2))
+-
+-    def test_compare_greater_than(self):
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value2 > value1, "FAILED: %s > %s" % (_text(value2), _text(value1))
+-                assert value2 != value1
+-
+-    def test_compare_less_or_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
+-            assert value1 == value2
+-
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
+-                assert value1 != value2
+-
+-    def test_compare_greater_or_equal(self):
+-        for value1, value2 in self.same_locations:
+-            assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
+-            assert value2 == value1
+-
+-        for locations in [self.ordered_locations1, self.ordered_locations2]:
+-            for value1, value2 in zip(locations, locations[1:]):
+-                assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
+-                assert value2 != value1
+-
+-    def test_filename_should_be_same_as_self(self):
+-        for location in self.ordered_locations2:
+-            assert location == location.filename
+-            assert location.filename == location
+-
+-    def test_string_conversion(self):
+-        for location in self.ordered_locations2:
+-            expected = u"%s:%s" % (location.filename, location.line)
+-            if location.line is None:
+-                expected = location.filename
+-            assert six.text_type(location) == expected
+-
+-    def test_repr_conversion(self):
+-        for location in self.ordered_locations2:
+-            expected = u'<FileLocation: filename="%s", line=%s>' % \
+-                       (location.filename, location.line)
+-            actual = repr(location)
+-            assert actual == expected, "FAILED: %s == %s" % (actual, expected)
+diff --git a/tests/unit/test_model2.py b/tests/unit/test_model2.py
+index 7884b90..a86b80e 100644
+--- a/tests/unit/test_model2.py
++++ b/tests/unit/test_model2.py
+@@ -35,10 +35,6 @@ def step_to_text(step, indentation="    "):
+     return step_text.rstrip()
+ 
+ 
+-# -- PYTEST MARKERS/ANNOTATIONS:
+-not_implemented_yet = pytest.mark.skip("NOT-IMPLEMENTED-YET")
+-
+-
+ # ----------------------------------------------------------------------------
+ # TEST SUITE:
+ # ----------------------------------------------------------------------------
+diff --git a/tests/unit/test_model_core.py b/tests/unit/test_model_core.py
+index b5f20c4..3cb5efa 100644
+--- a/tests/unit/test_model_core.py
++++ b/tests/unit/test_model_core.py
+@@ -4,10 +4,16 @@
+ """
+ 
+ from __future__ import print_function
+-from behave.model_core import Status
++import six
++from behave.model_core import Status, FileLocation
+ import pytest
+ 
+ 
++# -- CONVENIENCE-ALIAS:
++_text = six.text_type
++
++
++
+ # -----------------------------------------------------------------------------
+ # TESTS:
+ # -----------------------------------------------------------------------------
+@@ -54,3 +60,111 @@ class TestStatus(object):
+     def test_from_name__with_unknown_name_raises_lookuperror(self, unknown_name):
+         with pytest.raises(LookupError):
+             Status.from_name(unknown_name)
++
++
++class TestFileLocation(object):
++    # pylint: disable=invalid-name
++    ordered_locations1 = [
++        FileLocation("features/alice.feature", 1),
++        FileLocation("features/alice.feature", 5),
++        FileLocation("features/alice.feature", 10),
++        FileLocation("features/alice.feature", 11),
++        FileLocation("features/alice.feature", 100),
++    ]
++    ordered_locations2 = [
++        FileLocation("features/alice.feature", 1),
++        FileLocation("features/alice.feature", 10),
++        FileLocation("features/bob.feature", 5),
++        FileLocation("features/charly.feature", None),
++        FileLocation("features/charly.feature", 0),
++        FileLocation("features/charly.feature", 100),
++    ]
++    same_locations = [
++        (FileLocation("alice.feature"),
++         FileLocation("alice.feature", None),
++        ),
++        (FileLocation("alice.feature", 10),
++         FileLocation("alice.feature", 10),
++        ),
++        (FileLocation("features/bob.feature", 11),
++         FileLocation("features/bob.feature", 11),
++        ),
++    ]
++
++    def test_compare_equal(self):
++        for value1, value2 in self.same_locations:
++            assert value1 == value2
++
++    def test_compare_equal_with_string(self):
++        for location in self.ordered_locations2:
++            assert location == location.filename
++            assert location.filename == location
++
++    def test_compare_not_equal(self):
++        for value1, value2 in self.same_locations:
++            assert not(value1 != value2)    # pylint: disable=unneeded-not, superfluous-parens
++
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value1 != value2
++
++    def test_compare_less_than(self):
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value1 < value2, "FAILED: %s < %s" % (_text(value1), _text(value2))
++                assert value1 != value2
++
++    def test_compare_less_than_with_string(self):
++        locations = self.ordered_locations2
++        for value1, value2 in zip(locations, locations[1:]):
++            if value1.filename == value2.filename:
++                continue
++            assert value1 < value2.filename, \
++                   "FAILED: %s < %s" % (_text(value1), _text(value2.filename))
++            assert value1.filename < value2, \
++                   "FAILED: %s < %s" % (_text(value1.filename), _text(value2))
++
++    def test_compare_greater_than(self):
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value2 > value1, "FAILED: %s > %s" % (_text(value2), _text(value1))
++                assert value2 != value1
++
++    def test_compare_less_or_equal(self):
++        for value1, value2 in self.same_locations:
++            assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
++            assert value1 == value2
++
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
++                assert value1 != value2
++
++    def test_compare_greater_or_equal(self):
++        for value1, value2 in self.same_locations:
++            assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
++            assert value2 == value1
++
++        for locations in [self.ordered_locations1, self.ordered_locations2]:
++            for value1, value2 in zip(locations, locations[1:]):
++                assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
++                assert value2 != value1
++
++    def test_filename_should_be_same_as_self(self):
++        for location in self.ordered_locations2:
++            assert location == location.filename
++            assert location.filename == location
++
++    def test_string_conversion(self):
++        for location in self.ordered_locations2:
++            expected = u"%s:%s" % (location.filename, location.line)
++            if location.line is None:
++                expected = location.filename
++            assert six.text_type(location) == expected
++
++    def test_repr_conversion(self):
++        for location in self.ordered_locations2:
++            expected = u'<FileLocation: filename="%s", line=%s>' % \
++                       (location.filename, location.line)
++            actual = repr(location)
++            assert actual == expected, "FAILED: %s == %s" % (actual, expected)
+diff --git a/tests/unit/test_parser_gherkin_v6.py b/tests/unit/test_parser_gherkin_v6.py
+index 991a57d..43e3d41 100644
+--- a/tests/unit/test_parser_gherkin_v6.py
++++ b/tests/unit/test_parser_gherkin_v6.py
+@@ -227,7 +227,9 @@ Feature: With Rule
+         assert rule1.description == []
+         assert rule1.tags == []
+         assert len(rule1.scenarios) == 1
+-        assert rule1.background is feature.background
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == feature.background.steps
++        assert list(rule1.background.all_steps) == feature.background.steps
+         assert_compare_steps(rule1.scenarios[0].all_steps, [
+             ("given", "Given", "feature background step 1", None, None),
+             ("when", "When", "feature background step 2", None, None),
+@@ -235,7 +237,7 @@ Feature: With Rule
+             ("when", "When", "scenario step 2", None, None),
+         ])
+ 
+-    def test_parses_rule_with_background_should_not_inherit_feature_background(self):
++    def test_parses_rule_with_background_inherits_feature_background(self):
+         """If a Rule has no Background,
+         it inherits the Feature's Background (if one exists).
+         """
+@@ -269,13 +271,15 @@ Feature: With Rule
+         assert rule1.background is not None
+         assert rule1.background is not feature.background
+         assert_compare_steps(rule1.scenarios[0].all_steps, [
++            ("given", "Given", "feature background step 1", None, None),
++            ("when",  "When",  "feature background step 2", None, None),
+             ("given", "Given", "rule background step 1", None, None),
+-            ("when", "When", "rule background step 2", None, None),
++            ("when",  "When",  "rule background step 2", None, None),
+             ("given", "Given", "scenario step 1", None, None),
+-            ("when", "When", "scenario step 2", None, None),
++            ("when",  "When",  "scenario step 2", None, None),
+         ])
+ 
+-    def test_parses_rule_with_empty_background_prevents_inheriting_feature_background(self):
++    def test_parses_rule_with_empty_background_inherits_feature_background(self):
+         """A Rule has empty Background (without any steps) prevents that
+         Feature Background is inherited (if one exists).
+         """
+@@ -308,8 +312,10 @@ Feature: With Rule
+         assert rule1.background is not feature.background
+         assert rule1.background.name == "Rule_R3C.Empty_Background"
+         assert_compare_steps(rule1.scenarios[0].all_steps, [
++            ("given", "Given", "feature background step 1", None, None),
++            ("when",  "When",  "feature background step 2", None, None),
+             ("given", "Given", "scenario step 1", None, None),
+-            ("when", "When", "scenario step 2", None, None),
++            ("when",  "When", "scenario step 2", None, None),
+         ])
+ 
+     def test_parses_rule_with_scenario(self):
+@@ -558,6 +564,7 @@ Feature: With Rule
+             ("when", "When", 'step uses "2"', None, None),
+         ])
+ 
++    # @check.duplicated
+     def test_parse_background_scenario_and_rules(self):
+         """HINT: Some Scenarios may exist before the first Rule."""
+         text = u'''
+@@ -606,10 +613,10 @@ Feature: With Scenarios and Rules
+         assert scenario1.tags == []
+         assert scenario1.description == []
+         assert_compare_steps(scenario1.all_steps, [
+-            ("given", "Given", 'feature background step_1', None, None),
+-            ("when", "When",   'feature background step_2', None, None),
+-            ("given", "Given", 'scenario_1 step_1', None, None),
+-            ("when", "When",   'scenario_1 step_2', None, None),
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"when", u"When",   u'feature background step_2', None, None),
++            (u"given", u"Given", u'scenario_1 step_1', None, None),
++            (u"when", u"When",   u'scenario_1 step_2', None, None),
+         ])
+ 
+         assert rule1.name == "R1"
+@@ -623,9 +630,11 @@ Feature: With Scenarios and Rules
+         assert rule1_scenario1.parent is rule1
+         assert rule1_scenario1.feature is feature
+         assert_compare_steps(rule1_scenario1.all_steps, [
++            ("given", "Given", 'feature background step_1', None, None),
++            ("when",  "When",  'feature background step_2', None, None),
+             ("given", "Given", 'rule R1 background step_1', None, None),
+             ("given", "Given", 'rule R1 scenario_1 step_1', None, None),
+-            ("when", "When",   'rule R1 scenario_1 step_2', None, None),
++            ("when",  "When",  'rule R1 scenario_1 step_2', None, None),
+         ])
+ 
+         assert rule2.name == "R2"
+@@ -633,16 +642,318 @@ Feature: With Scenarios and Rules
+         assert rule2.feature is feature
+         assert rule2.description == []
+         assert rule2.tags == []
+-        assert rule2.background is feature.background
++        assert rule2.background is not feature.background
++        assert list(rule2.background.inherited_steps) == list(feature.background.steps)
++        assert list(rule2.background.all_steps) == list(feature.background.steps)
+         assert len(rule2.scenarios) == 1
+         assert rule2_scenario1.name == "R2.Scenario_1"
+         assert rule2_scenario1.parent is rule2
+         assert rule2_scenario1.feature is feature
+         assert_compare_steps(rule2_scenario1.all_steps, [
+             ("given", "Given", 'feature background step_1', None, None),
+-            ("when", "When",   'feature background step_2', None, None),
++            ("when",  "When",  'feature background step_2', None, None),
+             ("given", "Given", 'rule R2 scenario_1 step_1', None, None),
+-            ("when", "When",   'rule R2 scenario_1 step_2', None, None),
++            ("when",  "When",  'rule R2 scenario_1 step_2', None, None),
++        ])
++
++
++# ---------------------------------------------------------------------------
++# TEST SUITE: Verify Feature Background to Rule Background Inheritance
++# ---------------------------------------------------------------------------
++class TestParser4Background(object):
++    """Verify feature.background to rule.background inheritance, etc."""
++
++    def test_parse__norule_scenarios_use_feature_background(self):
++        """AFFECTED: Scenarios outside of rules (before first rule)."""
++        text = u'''
++            Feature: With Scenarios and Rules
++            
++              Background: Feature.Background
++                Given feature background step_1
++            
++              Scenario: Scenario_1
++                Given scenario_1 step_1
++            
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Scenarios and Rules"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 1
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 2
++
++        scenario1 = feature.scenarios[0]
++        rule1 = feature.rules[0]
++        assert feature.run_items == [scenario1, rule1]
++
++        assert scenario1.name == "Scenario_1"
++        assert scenario1.background is feature.background
++        assert scenario1.background_steps == feature.background.steps
++        assert_compare_steps(scenario1.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__norule_scenarios_with_disabled_background(self):
++        """AFFECTED: Scenarios outside of rules (before first rule)."""
++        text = u'''
++            Feature: Scenario with disabled background
++            
++              Background: Feature.Background
++                Given feature background step_1
++            
++              @fixture.behave.disable_background
++              Scenario: Scenario_1
++                Given scenario_1 step_1
++            
++              Scenario: Scenario_2
++                Given scenario_2 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "Scenario with disabled background"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 2
++        assert len(feature.run_items) == 2
++
++        scenario1 = feature.scenarios[0]
++        scenario2 = feature.scenarios[1]
++        assert feature.run_items == [scenario1, scenario2]
++
++        scenario1.use_background = False    # -- FIXTURE-EFFECT (simulated)
++        assert scenario1.name == "Scenario_1"
++        assert scenario1.background is feature.background
++        assert scenario1.background_steps != feature.background.steps
++        assert scenario1.background_steps == []
++        assert_compare_steps(scenario1.all_steps, [
++            (u"given", u"Given", u'scenario_1 step_1', None, None),
++        ])
++
++        # -- ENSURE: Disabling of background has no effect on other scenarios.
++        assert scenario2.name == "Scenario_2"
++        assert scenario2.background is feature.background
++        assert scenario2.background_steps == feature.background.steps
++        assert_compare_steps(scenario2.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'scenario_2 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_inherit_feature_background_without_rule_background(self):
++        text = u'''
++            Feature: With Background and Rule
++    
++              Background: Feature.Background
++                Given feature background step_1
++    
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Background and Rule"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is not None
++        # assert rule1_scenario1.background is not feature.background
++        assert rule1_scenario1.background_steps == feature.background.steps
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_inherit_feature_background_with_rule_background(self):
++        text = u'''
++            Feature: With Feature.Background and Rule.Background
++
++              Background: Feature.Background
++                Given feature background step_1
++
++              Rule: R1
++                Background: R1.Background
++                  Given rule R1 background step_1
++                
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Feature.Background and Rule.Background"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1.background is not None
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == feature.background.steps
++        assert list(rule1.background.all_steps) != feature.background.steps
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'feature background step_1', None, None),
++            (u"given", u"Given", u'rule R1 background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_with_rule_background_when_background_inheritance_is_disabled(self):
++        # -- HINT: Background inheritance is enabled (by default).
++        text = u'''
++            Feature: With Feature Background Inheritance disabled
++
++              Background: Feature.Background
++                Given feature background step_1
++
++              @fixture.behave.override_background
++              Rule: R1
++                Background: R1.Background
++                  Given rule R1 background step_1
++
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Feature Background Inheritance disabled"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        rule1.use_background_inheritance = False  # FIXTURE-EFFECT (simulated)
++        assert rule1.background is not None
++        assert rule1.background.use_inheritance is False
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == []
++        assert rule1.background.inherited_steps != feature.background.steps
++        assert list(rule1.background.all_steps) != feature.background.steps
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == rule1.background.steps
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_without_rule_background_when_background_inheritance_is_disabled_without(self):
++        # -- HINT: Background inheritance is enabled (by default).
++        text = u'''
++            Feature: With Feature Background Inheritance disabled
++
++              Background: Feature.Background
++                Given feature background step_1
++
++              @fixture.behave.override_background
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "With Feature Background Inheritance disabled"
++        assert feature.background is not None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        rule1.use_background_inheritance = False  # FIXTURE-EFFECT (simulated)
++        assert rule1.background is not None
++        assert rule1.background.use_inheritance is False
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == []
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == rule1.background.steps
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_without_feature_background_and_with_rule_background(self):
++        text = u'''
++            Feature: Without Feature.Background and with Rule.Background
++
++              Rule: R1
++                Background: R1.Background
++                  Given rule R1 background step_1
++
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "Without Feature.Background and with Rule.Background"
++        assert feature.background is None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1.background is not None
++        assert rule1.background is not feature.background
++        assert rule1.background.inherited_steps == []
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == rule1.background.steps
++        assert rule1_scenario1.background_steps == list(rule1.background.all_steps)
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 background step_1', None, None),
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
++        ])
++
++    def test_parse__rule_scenarios_without_feature_and_rule_background(self):
++        text = u'''
++            Feature: Without Feature.Background and Rule.Background
++
++              Rule: R1
++                Scenario: R1.Scenario_1
++                  Given rule R1 scenario_1 step_1
++            '''.lstrip()
++        feature = parse_feature(text)
++        assert feature.name == "Without Feature.Background and Rule.Background"
++        assert feature.background is None
++        assert len(feature.scenarios) == 0
++        assert len(feature.rules) == 1
++        assert len(feature.run_items) == 1
++
++        rule1 = feature.rules[0]
++        rule1_scenario1 = rule1.scenarios[0]
++        assert feature.run_items == [rule1]
++
++        assert rule1.background is None
++
++        assert rule1_scenario1.name == "R1.Scenario_1"
++        assert rule1_scenario1.background is None
++        assert rule1_scenario1.background is rule1.background
++        assert rule1_scenario1.background_steps == []
++        assert_compare_steps(rule1_scenario1.all_steps, [
++            (u"given", u"Given", u'rule R1 scenario_1 step_1', None, None),
+         ])
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch b/meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch
new file mode 100644
index 000000000..964b83e69
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0052-Add-support-for-runtime-constraints.patch
@@ -0,0 +1,269 @@
+From 26e431c821c260a981ca8ed28f21330c8ef17af6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:18:02 +0200
+Subject: [PATCH] Add support for runtime constraints.
+
+---
+ .bumpversion.cfg                 |  2 +-
+ behave/__init__.py               |  2 +-
+ behave/__main__.py               | 13 +++++----
+ behave/api/runtime_constraint.py | 45 ++++++++++++++++++++++++++++++++
+ behave/configuration.py          |  4 ---
+ behave/exception.py              | 40 ++++++++++++++++++++++++++++
+ behave/runner.py                 |  2 +-
+ behave/runner_util.py            | 17 ++----------
+ behave/version.py                |  2 ++
+ tests/unit/test_runner.py        |  2 +-
+ 10 files changed, 101 insertions(+), 28 deletions(-)
+ create mode 100644 behave/api/runtime_constraint.py
+ create mode 100644 behave/exception.py
+ create mode 100644 behave/version.py
+
+diff --git a/.bumpversion.cfg b/.bumpversion.cfg
+index ac913c2..a5d3d2f 100644
+--- a/.bumpversion.cfg
++++ b/.bumpversion.cfg
+@@ -1,6 +1,6 @@
+ [bumpversion]
+ current_version = 1.2.7.dev1
+-files = behave/__init__.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
++files = behave/version.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
+ parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<drop>\w*)
+ serialize = {major}.{minor}.{patch}{drop}
+ commit = False
+diff --git a/behave/__init__.py b/behave/__init__.py
+index 31e4e55..53a5337 100644
+--- a/behave/__init__.py
++++ b/behave/__init__.py
+@@ -20,6 +20,7 @@ from __future__ import absolute_import
+ from behave.step_registry import *      # pylint: disable=wildcard-import
+ from behave.matchers import use_step_matcher, step_matcher, register_type
+ from behave.fixture import fixture, use_fixture
++from behave.version import VERSION as __version__
+ 
+ # pylint: disable=undefined-all-variable
+ __all__ = [
+@@ -29,4 +30,3 @@ __all__ = [
+     # -- DEPRECATING:
+     "step_matcher"
+ ]
+-__version__ = "1.2.7.dev1"
+diff --git a/behave/__main__.py b/behave/__main__.py
+index c340b25..3cae36d 100644
+--- a/behave/__main__.py
++++ b/behave/__main__.py
+@@ -4,12 +4,13 @@ from __future__ import absolute_import, print_function
+ import codecs
+ import sys
+ import six
+-from behave import __version__
+-from behave.configuration import Configuration, ConfigError
++from behave.version import VERSION as BEHAVE_VERSION
++from behave.configuration import Configuration
++from behave.exception import ConstraintError, ConfigError, \
++    FileNotFoundError, InvalidFileLocationError, InvalidFilenameError
+ from behave.parser import ParserError
+ from behave.runner import Runner
+-from behave.runner_util import print_undefined_step_snippets, reset_runtime, \
+-    InvalidFileLocationError, InvalidFilenameError, FileNotFoundError
++from behave.runner_util import print_undefined_step_snippets, reset_runtime
+ from behave.textutil import compute_words_maxsize, text as _text
+ 
+ 
+@@ -62,7 +63,7 @@ def run_behave(config, runner_class=None):
+         runner_class = Runner
+ 
+     if config.version:
+-        print("behave " + __version__)
++        print("behave " + BEHAVE_VERSION)
+         return 0
+ 
+     if config.tags_help:
+@@ -110,6 +111,8 @@ def run_behave(config, runner_class=None):
+         print(u"InvalidFileLocationError: %s" % e)
+     except InvalidFilenameError as e:
+         print(u"InvalidFilenameError: %s" % e)
++    except ConstraintError as e:
++        print(u"ConstraintError: %s" % e)
+     except Exception as e:
+         # -- DIAGNOSTICS:
+         text = _text(e)
+diff --git a/behave/api/runtime_constraint.py b/behave/api/runtime_constraint.py
+new file mode 100644
+index 0000000..310e529
+--- /dev/null
++++ b/behave/api/runtime_constraint.py
+@@ -0,0 +1,45 @@
++# -*- coding: UTF-8 -*-
++"""
++Simplifies to specify runtime constraints in
++
++* features/environment.py file
++* features/steps/*.py" files
++"""
++
++from __future__ import absolute_import
++from behave.exception import ConstraintError
++
++
++# ---------------------------------------------------------------------------
++# UTILITY FUNCTIONS:
++# ---------------------------------------------------------------------------
++def require_min_python_version(minimal_version):
++    """Simplifies to specify the minimal python version that is required.
++
++    :param minimal_version: Minimum version (as string, tuple)
++    :raises: behave.exception.ConstraintError
++    """
++    import six
++    import sys
++    python_version = sys.version_info
++    if isinstance(minimal_version, six.string_types):
++        python_version = "%s.%s" % sys.version_info[:2]
++    elif not isinstance(minimal_version, tuple):
++        raise TypeError("string or tuple (was: %s)" % type(minimal_version))
++
++    if python_version < minimal_version:
++        raise ConstraintError("python >= %s expected (was: %s)" % \
++                              (minimal_version, python_version))
++
++
++def require_min_behave_version(minimal_version):
++    """Simplifies to specify the minimal behave version that is required.
++
++    :param minimal_version: Minimum version (as string, tuple)
++    :raises: behave.exception.ConstraintError
++    """
++    # -- SIMPLISTIC IMPLEMENTATION:
++    from behave.version import VERSION as behave_version
++    if behave_version < minimal_version:
++        raise ConstraintError("behave >= %s expected (was: %s)" % \
++                              (minimal_version, behave_version))
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 861f89f..bd8b039 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -62,10 +62,6 @@ class LogLevel(object):
+         return logging.getLevelName(level)
+ 
+ 
+-class ConfigError(Exception):
+-    pass
+-
+-
+ # -----------------------------------------------------------------------------
+ # CONFIGURATION SCHEMA:
+ # -----------------------------------------------------------------------------
+diff --git a/behave/exception.py b/behave/exception.py
+new file mode 100644
+index 0000000..ba21206
+--- /dev/null
++++ b/behave/exception.py
+@@ -0,0 +1,40 @@
++# -*- coding: UTF-8 -*-
++"""
++Behave exception classes.
++
++.. versionadded:: 1.2.7
++"""
++
++
++# ---------------------------------------------------------------------------
++# EXCEPTION/ERROR CLASSES:
++# ---------------------------------------------------------------------------
++class ConstraintError(RuntimeError):
++    """Used if a constraint/precondition is not fulfilled at runtime.
++
++    .. versionadded:: 1.2.7
++    """
++
++
++class ConfigError(Exception):
++    """Used if the configuration is (partially) invalid."""
++
++
++# ---------------------------------------------------------------------------
++# EXCEPTION/ERROR CLASSES: Related to File Handling
++# ---------------------------------------------------------------------------
++class FileNotFoundError(LookupError):
++    """Used if a specified file was not found."""
++
++
++class InvalidFileLocationError(LookupError):
++    """Used if a :class:`behave.model_core.FileLocation` is invalid.
++    This occurs if the file location is no exactly correct and
++    strict checking is enabled.
++    """
++
++
++class InvalidFilenameError(ValueError):
++    """Used if a filename does not have the expected file extension, etc."""
++
++
+diff --git a/behave/runner.py b/behave/runner.py
+index f209cb0..cbedb5a 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -15,7 +15,7 @@ import six
+ 
+ from behave._types import ExceptionUtil
+ from behave.capture import CaptureController
+-from behave.configuration import ConfigError
++from behave.exception import ConfigError
+ from behave.formatter._registry import make_formatters
+ from behave.runner_util import \
+     collect_feature_locations, parse_features, \
+diff --git a/behave/runner_util.py b/behave/runner_util.py
+index 7e0807f..80b99a0 100644
+--- a/behave/runner_util.py
++++ b/behave/runner_util.py
+@@ -11,26 +11,13 @@ import re
+ import sys
+ from six import string_types
+ from behave import parser
++from behave.exception import \
++    FileNotFoundError, InvalidFileLocationError, InvalidFilenameError
+ from behave.model_core import FileLocation
+ from behave.textutil import ensure_stream_with_encoder
+ # LAZY: from behave.step_registry import setup_step_decorators
+ 
+ 
+-# -----------------------------------------------------------------------------
+-# EXCEPTIONS:
+-# -----------------------------------------------------------------------------
+-class FileNotFoundError(LookupError):
+-    pass
+-
+-
+-class InvalidFileLocationError(LookupError):
+-    pass
+-
+-
+-class InvalidFilenameError(ValueError):
+-    pass
+-
+-
+ # -----------------------------------------------------------------------------
+ # CLASS: FileLocationParser
+ # -----------------------------------------------------------------------------
+diff --git a/behave/version.py b/behave/version.py
+new file mode 100644
+index 0000000..b19cb5e
+--- /dev/null
++++ b/behave/version.py
+@@ -0,0 +1,2 @@
++# -- BEHAVE-VERSION:
++VERSION = "1.2.7.dev1"
+diff --git a/tests/unit/test_runner.py b/tests/unit/test_runner.py
+index 030dffa..f0d03cd 100644
+--- a/tests/unit/test_runner.py
++++ b/tests/unit/test_runner.py
+@@ -17,7 +17,7 @@ from behave import runner_util
+ from behave.model import Table
+ from behave.step_registry import StepRegistry
+ from behave import parser, runner
+-from behave.configuration import ConfigError
++from behave.exception import ConfigError
+ from behave.formatter.base import StreamOpener
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch b/meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch
new file mode 100644
index 000000000..8a07505bf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0053-Use-runtime-constraints.patch
@@ -0,0 +1,196 @@
+From 5917914e415c728e130d828cc1ed4e2199b1fcdc Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:19:13 +0200
+Subject: [PATCH] Use runtime constraints
+
+---
+ .../features/async_dispatch.feature           |  2 ++
+ .../async_step/features/async_run.feature     |  2 ++
+ examples/async_step/features/environment.py   | 13 +++++++++
+ .../{async_steps34.py => _async_steps34.py}   |  6 +++-
+ .../{async_steps35.py => _async_steps35.py}   |  3 +-
+ .../features/steps/async_dispatch_steps.py    | 29 +++++++++++++++----
+ .../async_step/features/steps/async_steps.py  | 12 ++++++++
+ 7 files changed, 59 insertions(+), 8 deletions(-)
+ rename examples/async_step/features/steps/{async_steps34.py => _async_steps34.py} (58%)
+ rename examples/async_step/features/steps/{async_steps35.py => _async_steps35.py} (95%)
+ create mode 100644 examples/async_step/features/steps/async_steps.py
+
+diff --git a/examples/async_step/features/async_dispatch.feature b/examples/async_step/features/async_dispatch.feature
+index 416d3d1..18e9869 100644
+--- a/examples/async_step/features/async_dispatch.feature
++++ b/examples/async_step/features/async_dispatch.feature
+@@ -1,6 +1,8 @@
+ @use.with_python.version=3.4
+ @use.with_python.version=3.5
+ @use.with_python.version=3.6
++@use.with_python.version=3.7
++@use.with_python.version=3.8
+ Feature:
+   Scenario:
+     Given I dispatch an async-call with param "Alice"
+diff --git a/examples/async_step/features/async_run.feature b/examples/async_step/features/async_run.feature
+index 9f506b4..29b8fa7 100644
+--- a/examples/async_step/features/async_run.feature
++++ b/examples/async_step/features/async_run.feature
+@@ -1,6 +1,8 @@
+ @use.with_python.version=3.4
+ @use.with_python.version=3.5
+ @use.with_python.version=3.6
++@use.with_python.version=3.7
++@use.with_python.version=3.8
+ Feature:
+   Scenario:
+     Given an async-step waits 0.3 seconds
+diff --git a/examples/async_step/features/environment.py b/examples/async_step/features/environment.py
+index 9d4302b..02c4d92 100644
+--- a/examples/async_step/features/environment.py
++++ b/examples/async_step/features/environment.py
+@@ -1,8 +1,18 @@
+ # -*- coding: UTF-8 -*-
+ 
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
++from behave.api.runtime_constraint import require_min_python_version
+ import sys
+ 
++# -----------------------------------------------------------------------------
++# REQUIRE: python >= 3.4
++# -----------------------------------------------------------------------------
++require_min_python_version("3.4")
++
++
++# -----------------------------------------------------------------------------
++# SUPPORT: Active-tags
++# -----------------------------------------------------------------------------
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+ python_version = "%s.%s" % sys.version_info[:2]
+@@ -11,6 +21,7 @@ active_tag_value_provider = {
+ }
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+@@ -18,10 +29,12 @@ def before_all(context):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+     setup_active_tag_values(active_tag_value_provider, context.config.userdata)
+ 
++
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/examples/async_step/features/steps/async_steps34.py b/examples/async_step/features/steps/_async_steps34.py
+similarity index 58%
+rename from examples/async_step/features/steps/async_steps34.py
+rename to examples/async_step/features/steps/_async_steps34.py
+index c4962ab..556500f 100644
+--- a/examples/async_step/features/steps/async_steps34.py
++++ b/examples/async_step/features/steps/_async_steps34.py
+@@ -1,8 +1,12 @@
+-# -- REQUIRES: Python >= 3.4
++# -- REQUIRES: Python >= 3.4 and Python < 3.8
++# HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++# USE:  Async generator/coroutine instead.
++
+ from behave import step
+ from behave.api.async_step import async_run_until_complete
+ import asyncio
+ 
++# -- USABLE FOR: "3.4" <= python_version < "3.8"
+ @step('an async-step waits {duration:f} seconds')
+ @async_run_until_complete
+ @asyncio.coroutine
+diff --git a/examples/async_step/features/steps/async_steps35.py b/examples/async_step/features/steps/_async_steps35.py
+similarity index 95%
+rename from examples/async_step/features/steps/async_steps35.py
+rename to examples/async_step/features/steps/_async_steps35.py
+index 018d5ef..edcbe0e 100644
+--- a/examples/async_step/features/steps/async_steps35.py
++++ b/examples/async_step/features/steps/_async_steps35.py
+@@ -1,4 +1,5 @@
+ # -- REQUIRES: Python >= 3.5
++
+ from behave import step
+ from behave.api.async_step import async_run_until_complete
+ import asyncio
+@@ -6,5 +7,5 @@ import asyncio
+ @step('an async-step waits {duration:f} seconds')
+ @async_run_until_complete
+ async def step_async_step_waits_seconds_py35(context, duration):
+-    """Simple example of a coroutine as async-step (in Python 3.5)"""
++    """Simple example of a coroutine as async-step (in Python 3.5 or newer)"""
+     await asyncio.sleep(duration)
+diff --git a/examples/async_step/features/steps/async_dispatch_steps.py b/examples/async_step/features/steps/async_dispatch_steps.py
+index b9b6e15..222e54d 100644
+--- a/examples/async_step/features/steps/async_dispatch_steps.py
++++ b/examples/async_step/features/steps/async_dispatch_steps.py
+@@ -1,21 +1,38 @@
+ # -*- coding: UTF-8 -*-
+-# REQUIRES: Python >= 3.5
++# REQUIRES: Python >= 3.4/3.5
++import sys
+ from behave import given, then, step
+-from behave.api.async_step import use_or_create_async_context, AsyncContext
++from behave.api.async_step import use_or_create_async_context
+ from hamcrest import assert_that, equal_to, empty
+ import asyncio
+ 
+-@asyncio.coroutine
+-def async_func(param):
+-    yield from asyncio.sleep(0.2)
+-    return str(param).upper()
+ 
++# ---------------------------------------------------------------------------
++# ASYNC EXAMPLE FUNCTION:
++# ---------------------------------------------------------------------------
++python_version = "%s.%s" % sys.version_info[:2]
++if python_version >= "3.5":
++    async def async_func(param):
++        await asyncio.sleep(0.2)
++        return str(param).upper()
++else:
++    # -- HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++    @asyncio.coroutine
++    def async_func(param):
++        yield from asyncio.sleep(0.2)
++        return str(param).upper()
++
++
++# ---------------------------------------------------------------------------
++# STEPS:
++# ---------------------------------------------------------------------------
+ @given('I dispatch an async-call with param "{param}"')
+ def step_dispatch_async_call(context, param):
+     async_context = use_or_create_async_context(context, "async_context1")
+     task = async_context.loop.create_task(async_func(param))
+     async_context.tasks.append(task)
+ 
++
+ @then('the collected result of the async-calls is "{expected}"')
+ def step_collected_async_call_result_is(context, expected):
+     async_context = context.async_context1
+diff --git a/examples/async_step/features/steps/async_steps.py b/examples/async_step/features/steps/async_steps.py
+new file mode 100644
+index 0000000..dc03c72
+--- /dev/null
++++ b/examples/async_step/features/steps/async_steps.py
+@@ -0,0 +1,12 @@
++# -*- coding: UTF-8 -*-
++# REQUIRES: Python >= 3.4/3.5
++"""Python import-barrier for python2 or python < 3.4."""
++
++from __future__ import absolute_import
++import sys
++
++python_version = "%s.%s" % sys.version_info[:2]
++if python_version >= "3.5":
++    import _async_steps35
++elif python_version == "3.4":
++    import _async_steps34
diff --git a/meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch b/meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch
new file mode 100644
index 000000000..aebb68589
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0054-CLEANUP-Remove-deprecated-parts.patch
@@ -0,0 +1,3937 @@
+From 484af9f2be3868f90ae736c040332dcdc04b5d02 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:20:38 +0200
+Subject: [PATCH] CLEANUP: Remove deprecated parts.
+
+---
+ .attic/convert_i18n_yaml.py |   77 +
+ .attic/i18n.yml             |  635 +++++++
+ bin/gherkin-languages.json  | 3193 -----------------------------------
+ 3 files changed, 712 insertions(+), 3193 deletions(-)
+ create mode 100755 .attic/convert_i18n_yaml.py
+ create mode 100644 .attic/i18n.yml
+ delete mode 100644 bin/gherkin-languages.json
+
+diff --git a/.attic/convert_i18n_yaml.py b/.attic/convert_i18n_yaml.py
+new file mode 100755
+index 0000000..d6a6713
+--- /dev/null
++++ b/.attic/convert_i18n_yaml.py
+@@ -0,0 +1,77 @@
++#!/usr/bin/env python
++# -*- coding: UTF-8 -*-
++# USAGE: convert_i18n_yaml.py [--data=i18n.yml] behave/i18n.py
++"""
++Generates I18N python module based on YAML description (i18n.yml).
++
++REQUIRES:
++  * argparse
++  * six
++  * PyYAML
++"""
++
++from __future__ import absolute_import, print_function
++import argparse
++import os.path
++import six
++import sys
++import pprint
++import yaml
++
++HERE = os.path.dirname(__file__)
++NAME = os.path.basename(__file__)
++__version__ = "1.0"
++
++def yaml_normalize(data):
++    for part in data:
++        keywords = data[part]
++        for k in keywords:
++            v = keywords[k]
++            # bloody YAML parser returns a mixture of unicode and str
++            if not isinstance(v, six.text_type):
++                v = v.decode("UTF-8")
++            keywords[k] = v.split("|")
++    return data
++
++def main(args=None):
++    if args is None:
++        args = sys.argv[1:]
++    parser = argparse.ArgumentParser(prog=NAME,
++                description="Generate python module i18n from YAML based data")
++    parser.add_argument("-d", "--data", dest="yaml_file",
++                default=os.path.join(HERE, "i18n.yml"),
++                help="Path to i18n.yml file (YAML file).")
++    parser.add_argument("output_file", default="stdout",
++                help="Filename of Python I18N module (as output).")
++    parser.add_argument("--version", action="version", version=__version__)
++
++    options = parser.parse_args(args)
++    if not os.path.isfile(options.yaml_file):
++        parser.error("YAML file not found: %s" % options.yaml_file)
++
++    # -- STEP 1: Load YAML data.
++    languages = yaml.load(open(options.yaml_file))
++    languages = yaml_normalize(languages)
++
++    # -- STEP 2: Generate python module with i18n data.
++    contents = u"""# -*- coding: UTF-8 -*-
++# -- FILE GENERATED BY: convert_i18n_yaml.py with i18n.yml
++# pylint: disable=line-too-long
++
++languages = \\
++"""
++    if options.output_file in ("-", "stdout"):
++        i18n_py = sys.stdout
++        should_close = False
++    else:
++        i18n_py = open(options.output_file, "w")
++        should_close = True
++    i18n_py.write(contents.encode("UTF-8"))
++    i18n_py.write(pprint.pformat(languages).encode("UTF-8"))
++    i18n_py.write(u"\n")
++    if should_close:
++        i18n_py.close()
++    return 0
++
++if __name__ == "__main__":
++    sys.exit(main())
+diff --git a/.attic/i18n.yml b/.attic/i18n.yml
+new file mode 100644
+index 0000000..82345a4
+--- /dev/null
++++ b/.attic/i18n.yml
+@@ -0,0 +1,635 @@
++# encoding: UTF-8
++#
++# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if applicable):
++# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
++# http://en.wikipedia.org/wiki/ISO_3166-1
++#
++# If you want several aliases for a keyword, just separate them
++# with a | character. The * is a step keyword alias for all translations.
++#
++# If you do *not* want a trailing space after a keyword, end it with a < character.
++# (See Chinese for examples).
++#
++# This file copyright (c) 2009-2011 Mike Sassak, Gregory Hnatiuk, Aslak Hellesøy
++#
++# Permission is hereby granted, free of charge, to any person obtaining
++# a copy of this software and associated documentation files (the
++# "Software"), to deal in the Software without restriction, including
++# without limitation the rights to use, copy, modify, merge, publish,
++# distribute, sublicense, and/or sell copies of the Software, and to
++# permit persons to whom the Software is furnished to do so, subject to
++# the following conditions:
++#
++# The above copyright notice and this permission notice shall be
++# included in all copies or substantial portions of the Software.
++#
++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++
++"en":
++  name: English
++  native: English
++  feature: Feature
++  background: Background
++  scenario: Scenario
++  scenario_outline: Scenario Outline|Scenario Template
++  examples: Examples|Scenarios
++  given: "*|Given"
++  when: "*|When"
++  then: "*|Then"
++  and: "*|And"
++  but: "*|But"
++
++# Please keep the grammars in alphabetical order by name from here and down.
++
++"ar":
++  name: Arabic
++  native: العربية
++  feature: خاصية
++  background: الخلفية
++  scenario: سيناريو
++  scenario_outline: سيناريو مخطط
++  examples: امثلة
++  given: "*|بفرض"
++  when: "*|متى|عندما"
++  then: "*|اذاً|ثم"
++  and: "*|و"
++  but: "*|لكن"
++"bg":
++  name: Bulgarian
++  native: български
++  feature: Функционалност
++  background: Предистория
++  scenario: Сценарий
++  scenario_outline: Рамка на сценарий
++  examples: Примери
++  given: "*|Дадено"
++  when: "*|Когато"
++  then: "*|То"
++  and: "*|И"
++  but: "*|Но"
++"ca":
++  name: Catalan
++  native: català
++  background: Rerefons|Antecedents
++  feature: Característica|Funcionalitat
++  scenario: Escenari
++  scenario_outline: Esquema de l'escenari
++  examples: Exemples
++  given: "*|Donat|Donada|Atès|Atesa"
++  when: "*|Quan"
++  then: "*|Aleshores|Cal"
++  and: "*|I"
++  but: "*|Però"
++"cy-GB":
++  name: Welsh
++  native: Cymraeg
++  background: Cefndir
++  feature: Arwedd
++  scenario: Scenario
++  scenario_outline: Scenario Amlinellol
++  examples: Enghreifftiau
++  given: "*|Anrhegedig a"
++  when: "*|Pryd"
++  then: "*|Yna"
++  and: "*|A"
++  but: "*|Ond"
++"cs":
++  name: Czech
++  native: Česky
++  feature: Požadavek
++  background: Pozadí|Kontext
++  scenario: Scénář
++  scenario_outline: Náčrt Scénáře|Osnova scénáře
++  examples: Příklady
++  given: "*|Pokud|Za předpokladu"
++  when: "*|Když"
++  then: "*|Pak"
++  and: "*|A|A také"
++  but: "*|Ale"
++"da":
++  name: Danish
++  native: dansk
++  feature: Egenskab
++  background: Baggrund
++  scenario: Scenarie
++  scenario_outline: Abstrakt Scenario
++  examples: Eksempler
++  given: "*|Givet"
++  when: "*|Når"
++  then: "*|Så"
++  and: "*|Og"
++  but: "*|Men"
++"de":
++  name: German
++  native: Deutsch
++  feature: Funktionalität
++  background: Grundlage
++  scenario: Szenario
++  scenario_outline: Szenariogrundriss
++  examples: Beispiele
++  given: "*|Angenommen|Gegeben sei"
++  when: "*|Wenn"
++  then: "*|Dann"
++  and: "*|Und"
++  but: "*|Aber"
++"en-au":
++  name: Australian
++  native: Australian
++  feature: Crikey
++  background: Background
++  scenario: Mate
++  scenario_outline: Blokes
++  examples: Cobber
++  given: "*|Ya know how"
++  when: "*|When"
++  then: "*|Ya gotta"
++  and: "*|N"
++  but: "*|Cept"
++"en-lol":
++  name: LOLCAT
++  native: LOLCAT
++  feature: OH HAI
++  background: B4
++  scenario: MISHUN
++  scenario_outline: MISHUN SRSLY
++  examples: EXAMPLZ
++  given: "*|I CAN HAZ"
++  when: "*|WEN"
++  then: "*|DEN"
++  and: "*|AN"
++  but: "*|BUT"
++"en-pirate":
++  name: Pirate
++  native: Pirate
++  feature: Ahoy matey!
++  background: Yo-ho-ho
++  scenario: Heave to
++  scenario_outline: Shiver me timbers
++  examples: Dead men tell no tales
++  given: "*|Gangway!"
++  when: "*|Blimey!"
++  then: "*|Let go and haul"
++  and: "*|Aye"
++  but: "*|Avast!"
++"en-Scouse":
++  name: Scouse
++  native: Scouse
++  feature: Feature
++  background: "Dis is what went down"
++  scenario: "The thing of it is"
++  scenario_outline: "Wharrimean is"
++  examples: Examples
++  given: "*|Givun|Youse know when youse got"
++  when: "*|Wun|Youse know like when"
++  then: "*|Dun|Den youse gotta"
++  and: "*|An"
++  but: "*|Buh"
++"en-tx":
++  name: Texan
++  native: Texan
++  feature: Feature
++  background: Background
++  scenario: Scenario
++  scenario_outline: All y'all
++  examples: Examples
++  given: "*|Given y'all"
++  when: "*|When y'all"
++  then: "*|Then y'all"
++  and: "*|And y'all"
++  but: "*|But y'all"
++"eo":
++  name: Esperanto
++  native: Esperanto
++  feature: Trajto
++  background: Fono
++  scenario: Scenaro
++  scenario_outline: Konturo de la scenaro
++  examples: Ekzemploj
++  given: "*|Donitaĵo"
++  when: "*|Se"
++  then: "*|Do"
++  and: "*|Kaj"
++  but: "*|Sed"
++"es":
++  name: Spanish
++  native: español
++  background: Antecedentes
++  feature: Característica
++  scenario: Escenario
++  scenario_outline: Esquema del escenario
++  examples: Ejemplos
++  given: "*|Dado|Dada|Dados|Dadas"
++  when: "*|Cuando"
++  then: "*|Entonces"
++  and: "*|Y"
++  but: "*|Pero"
++"et":
++  name: Estonian
++  native: eesti keel
++  feature: Omadus
++  background: Taust
++  scenario: Stsenaarium
++  scenario_outline: Raamstsenaarium
++  examples: Juhtumid
++  given: "*|Eeldades"
++  when: "*|Kui"
++  then: "*|Siis"
++  and: "*|Ja"
++  but: "*|Kuid"
++"fi":
++  name: Finnish
++  native: suomi
++  feature: Ominaisuus
++  background: Tausta
++  scenario: Tapaus
++  scenario_outline: Tapausaihio
++  examples: Tapaukset
++  given: "*|Oletetaan"
++  when: "*|Kun"
++  then: "*|Niin"
++  and: "*|Ja"
++  but: "*|Mutta"
++"fr":
++  name: French
++  native: français
++  feature: Fonctionnalité
++  background: Contexte
++  scenario: Scénario
++  scenario_outline: Plan du scénario|Plan du Scénario
++  examples: Exemples
++  given: "*|Soit|Etant donné|Etant donnée|Etant donnés|Etant données|Étant donné|Étant donnée|Étant donnés|Étant données"
++  when: "*|Quand|Lorsque|Lorsqu'<"
++  then: "*|Alors"
++  and: "*|Et"
++  but: "*|Mais"
++"gl":
++  name: Galician
++  native: galego
++  feature: Característica
++  background: Contexto
++  scenario: Escenario
++  scenario_outline: "Esbozo do escenario"
++  examples: Exemplos
++  given: "*|Dado|Dada|Dados|Dadas"
++  when: "*|Cando"
++  then: "*|Entón|Logo"
++  and: "*|E"
++  but: "*|Mais|Pero"
++
++"he":
++  name: Hebrew
++  native: עברית
++  feature: תכונה
++  background: רקע
++  scenario: תרחיש
++  scenario_outline: תבנית תרחיש
++  examples: דוגמאות
++  given: "*|בהינתן"
++  when: "*|כאשר"
++  then: "*|אז|אזי"
++  and: "*|וגם"
++  but: "*|אבל"
++"hr":
++  name: Croatian
++  native: hrvatski
++  feature: Osobina|Mogućnost|Mogucnost
++  background: Pozadina
++  scenario: Scenarij
++  scenario_outline: Skica|Koncept
++  examples: Primjeri|Scenariji
++  given: "*|Zadan|Zadani|Zadano"
++  when: "*|Kada|Kad"
++  then: "*|Onda"
++  and: "*|I"
++  but: "*|Ali"
++"hu":
++  name: Hungarian
++  native: magyar
++  feature: Jellemző
++  background: Háttér
++  scenario: Forgatókönyv
++  scenario_outline: Forgatókönyv vázlat
++  examples: Példák
++  given: "*|Amennyiben|Adott"
++  when: "*|Majd|Ha|Amikor"
++  then: "*|Akkor"
++  and: "*|És"
++  but: "*|De"
++"id":
++  name: Indonesian
++  native: Bahasa Indonesia
++  feature: Fitur
++  background: Dasar
++  scenario: Skenario
++  scenario_outline: Skenario konsep
++  examples: Contoh
++  given: "*|Dengan"
++  when: "*|Ketika"
++  then: "*|Maka"
++  and: "*|Dan"
++  but: "*|Tapi"
++"is":
++  name: Icelandic
++  native: Íslenska
++  feature: Eiginleiki
++  background: Bakgrunnur
++  scenario: Atburðarás
++  scenario_outline: Lýsing Atburðarásar|Lýsing Dæma
++  examples: Dæmi|Atburðarásir
++  given: "*|Ef"
++  when: "*|Þegar"
++  then: "*|Þá"
++  and: "*|Og"
++  but: "*|En"
++"it":
++  name: Italian
++  native: italiano
++  feature: Funzionalità
++  background: Contesto
++  scenario: Scenario
++  scenario_outline: Schema dello scenario
++  examples: Esempi
++  given: "*|Dato|Data|Dati|Date"
++  when: "*|Quando"
++  then: "*|Allora"
++  and: "*|E"
++  but: "*|Ma"
++"ja":
++  name: Japanese
++  native: 日本語
++  feature: フィーチャ|機能
++  background: 背景
++  scenario: シナリオ
++  scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
++  examples: 例|サンプル
++  given: "*|前提<"
++  when: "*|もし<"
++  then: "*|ならば<"
++  and: "*|かつ<"
++  but: "*|しかし<|但し<|ただし<"
++"ko":
++  name: Korean
++  native: 한국어
++  background: 배경
++  feature: 기능
++  scenario: 시나리오
++  scenario_outline: 시나리오 개요
++  examples: 예
++  given: "*|조건<|먼저<"
++  when: "*|만일<|만약<"
++  then: "*|그러면<"
++  and: "*|그리고<"
++  but: "*|하지만<|단<"
++"lt":
++  name: Lithuanian
++  native: lietuvių kalba
++  feature: Savybė
++  background: Kontekstas
++  scenario: Scenarijus
++  scenario_outline: Scenarijaus šablonas
++  examples: Pavyzdžiai|Scenarijai|Variantai
++  given: "*|Duota"
++  when: "*|Kai"
++  then: "*|Tada"
++  and: "*|Ir"
++  but: "*|Bet"
++"lu":
++  name: Luxemburgish
++  native: Lëtzebuergesch
++  feature: Funktionalitéit
++  background: Hannergrond
++  scenario: Szenario
++  scenario_outline: Plang vum Szenario
++  examples: Beispiller
++  given: "*|ugeholl"
++  when: "*|wann"
++  then: "*|dann"
++  and: "*|an|a"
++  but: "*|awer|mä"
++"lv":
++  name: Latvian
++  native: latviešu
++  feature: Funkcionalitāte|Fīča
++  background: Konteksts|Situācija
++  scenario: Scenārijs
++  scenario_outline: Scenārijs pēc parauga
++  examples: Piemēri|Paraugs
++  given: "*|Kad"
++  when: "*|Ja"
++  then: "*|Tad"
++  and: "*|Un"
++  but: "*|Bet"
++"nl":
++  name: Dutch
++  native: Nederlands
++  feature: Functionaliteit
++  background: Achtergrond
++  scenario: Scenario
++  scenario_outline: Abstract Scenario
++  examples: Voorbeelden
++  given: "*|Gegeven|Stel"
++  when: "*|Als"
++  then: "*|Dan"
++  and: "*|En"
++  but: "*|Maar"
++"no":
++  name: Norwegian
++  native: norsk
++  feature: Egenskap
++  background: Bakgrunn
++  scenario: Scenario
++  scenario_outline: Scenariomal|Abstrakt Scenario
++  examples: Eksempler
++  given: "*|Gitt"
++  when: "*|Når"
++  then: "*|Så"
++  and: "*|Og"
++  but: "*|Men"
++"pl":
++  name: Polish
++  native: polski
++  feature: Właściwość
++  background: Założenia
++  scenario: Scenariusz
++  scenario_outline: Szablon scenariusza
++  examples: Przykłady
++  given: "*|Zakładając|Mając"
++  when: "*|Jeżeli|Jeśli"
++  then: "*|Wtedy"
++  and: "*|Oraz|I"
++  but: "*|Ale"
++"pt":
++  name: Portuguese
++  native: português
++  background: Contexto
++  feature: Funcionalidade
++  scenario: Cenário|Cenario
++  scenario_outline: Esquema do Cenário|Esquema do Cenario
++  examples: Exemplos
++  given: "*|Dado|Dada|Dados|Dadas"
++  when: "*|Quando"
++  then: "*|Então|Entao"
++  and: "*|E"
++  but: "*|Mas"
++"ro":
++  name: Romanian
++  native: română
++  background: Context
++  feature: Functionalitate|Funcționalitate|Funcţionalitate
++  scenario: Scenariu
++  scenario_outline: Structura scenariu|Structură scenariu
++  examples: Exemple
++  given: "*|Date fiind|Dat fiind|Dati fiind|Dați fiind|Daţi fiind"
++  when: "*|Cand|Când"
++  then: "*|Atunci"
++  and: "*|Si|Și|Şi"
++  but: "*|Dar"
++"ru":
++  name: Russian
++  native: русский
++  feature: Функция|Функционал|Свойство
++  background: Предыстория|Контекст
++  scenario: Сценарий
++  scenario_outline: Структура сценария
++  examples: Примеры
++  given: "*|Допустим|Дано|Пусть"
++  when: "*|Если|Когда"
++  then: "*|То|Тогда"
++  and: "*|И|К тому же"
++  but: "*|Но|А"
++"sv":
++  name: Swedish
++  native: Svenska
++  feature: Egenskap
++  background: Bakgrund
++  scenario: Scenario
++  scenario_outline: Abstrakt Scenario|Scenariomall
++  examples: Exempel
++  given: "*|Givet"
++  when: "*|När"
++  then: "*|Så"
++  and: "*|Och"
++  but: "*|Men"
++"sk":
++  name: Slovak
++  native: Slovensky
++  feature: Požiadavka
++  background: Pozadie
++  scenario: Scenár
++  scenario_outline: Náčrt Scenáru
++  examples: Príklady
++  given: "*|Pokiaľ"
++  when: "*|Keď"
++  then: "*|Tak"
++  and: "*|A"
++  but: "*|Ale"
++"sr-Latn":
++  name: Serbian (Latin)
++  native: Srpski (Latinica)
++  feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
++  background: Kontekst|Osnova|Pozadina
++  scenario: Scenario|Primer
++  scenario_outline: Struktura scenarija|Skica|Koncept
++  examples: Primeri|Scenariji
++  given: "*|Zadato|Zadate|Zatati"
++  when: "*|Kada|Kad"
++  then: "*|Onda"
++  and: "*|I"
++  but: "*|Ali"
++"sr-Cyrl":
++  name: Serbian
++  native: Српски
++  feature: Функционалност|Могућност|Особина
++  background: Контекст|Основа|Позадина
++  scenario: Сценарио|Пример
++  scenario_outline: Структура сценарија|Скица|Концепт
++  examples: Примери|Сценарији
++  given: "*|Задато|Задате|Задати"
++  when: "*|Када|Кад"
++  then: "*|Онда"
++  and: "*|И"
++  but: "*|Али"
++"tr":
++  name: Turkish
++  native: Türkçe
++  feature: Özellik
++  background: Geçmiş
++  scenario: Senaryo
++  scenario_outline: Senaryo taslağı
++  examples: Örnekler
++  given: "*|Diyelim ki"
++  when: "*|Eğer ki"
++  then: "*|O zaman"
++  and: "*|Ve"
++  but: "*|Fakat|Ama"
++"uk":
++  name: Ukrainian
++  native: Українська
++  feature: Функціонал
++  background: Передумова
++  scenario: Сценарій
++  scenario_outline: Структура сценарію
++  examples: Приклади
++  given: "*|Припустимо|Припустимо, що|Нехай|Дано"
++  when: "*|Якщо|Коли"
++  then: "*|То|Тоді"
++  and: "*|І|А також|Та"
++  but: "*|Але"
++"uz":
++  name: Uzbek
++  native: Узбекча
++  feature: Функционал
++  background: Тарих
++  scenario: Сценарий
++  scenario_outline: Сценарий структураси
++  examples: Мисоллар
++  given: "*|Агар"
++  when: "*|Агар"
++  then: "*|Унда"
++  and: "*|Ва"
++  but: "*|Лекин|Бирок|Аммо"
++"vi":
++  name: Vietnamese
++  native: Tiếng Việt
++  feature: Tính năng
++  background: Bối cảnh
++  scenario: Tình huống|Kịch bản
++  scenario_outline: Khung tình huống|Khung kịch bản
++  examples: Dữ liệu
++  given: "*|Biết|Cho"
++  when: "*|Khi"
++  then: "*|Thì"
++  and: "*|Và"
++  but: "*|Nhưng"
++"zh-CN":
++  name: Chinese simplified
++  native: 简体中文
++  feature: 功能
++  background: 背景
++  scenario: 场景
++  scenario_outline: 场景大纲
++  examples: 例子
++  given: "*|假如<"
++  when: "*|当<"
++  then: "*|那么<"
++  and: "*|而且<"
++  but: "*|但是<"
++"zh-TW":
++  name: Chinese traditional
++  native: 繁體中文
++  feature: 功能
++  background: 背景
++  scenario: 場景|劇本
++  scenario_outline: 場景大綱|劇本大綱
++  examples: 例子
++  given: "*|假設<"
++  when: "*|當<"
++  then: "*|那麼<"
++  and: "*|而且<|並且<"
++  but: "*|但是<"
+diff --git a/bin/gherkin-languages.json b/bin/gherkin-languages.json
+deleted file mode 100644
+index d2d5e93..0000000
+--- a/bin/gherkin-languages.json
++++ /dev/null
+@@ -1,3193 +0,0 @@
+-{
+-  "af": {
+-    "and": [
+-      "* ",
+-      "En "
+-    ],
+-    "background": [
+-      "Agtergrond"
+-    ],
+-    "but": [
+-      "* ",
+-      "Maar "
+-    ],
+-    "examples": [
+-      "Voorbeelde"
+-    ],
+-    "feature": [
+-      "Funksie",
+-      "Besigheid Behoefte",
+-      "Vermoë"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gegewe "
+-    ],
+-    "name": "Afrikaans",
+-    "native": "Afrikaans",
+-    "scenario": [
+-      "Situasie"
+-    ],
+-    "scenarioOutline": [
+-      "Situasie Uiteensetting"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "when": [
+-      "* ",
+-      "Wanneer "
+-    ]
+-  },
+-  "am": {
+-    "and": [
+-      "* ",
+-      "Եվ "
+-    ],
+-    "background": [
+-      "Կոնտեքստ"
+-    ],
+-    "but": [
+-      "* ",
+-      "Բայց "
+-    ],
+-    "examples": [
+-      "Օրինակներ"
+-    ],
+-    "feature": [
+-      "Ֆունկցիոնալություն",
+-      "Հատկություն"
+-    ],
+-    "given": [
+-      "* ",
+-      "Դիցուք "
+-    ],
+-    "name": "Armenian",
+-    "native": "հայերեն",
+-    "scenario": [
+-      "Սցենար"
+-    ],
+-    "scenarioOutline": [
+-      "Սցենարի կառուցվացքը"
+-    ],
+-    "then": [
+-      "* ",
+-      "Ապա "
+-    ],
+-    "when": [
+-      "* ",
+-      "Եթե ",
+-      "Երբ "
+-    ]
+-  },
+-  "ar": {
+-    "and": [
+-      "* ",
+-      "و "
+-    ],
+-    "background": [
+-      "الخلفية"
+-    ],
+-    "but": [
+-      "* ",
+-      "لكن "
+-    ],
+-    "examples": [
+-      "امثلة"
+-    ],
+-    "feature": [
+-      "خاصية"
+-    ],
+-    "given": [
+-      "* ",
+-      "بفرض "
+-    ],
+-    "name": "Arabic",
+-    "native": "العربية",
+-    "scenario": [
+-      "سيناريو"
+-    ],
+-    "scenarioOutline": [
+-      "سيناريو مخطط"
+-    ],
+-    "then": [
+-      "* ",
+-      "اذاً ",
+-      "ثم "
+-    ],
+-    "when": [
+-      "* ",
+-      "متى ",
+-      "عندما "
+-    ]
+-  },
+-  "ast": {
+-    "and": [
+-      "* ",
+-      "Y ",
+-      "Ya "
+-    ],
+-    "background": [
+-      "Antecedentes"
+-    ],
+-    "but": [
+-      "* ",
+-      "Peru "
+-    ],
+-    "examples": [
+-      "Exemplos"
+-    ],
+-    "feature": [
+-      "Carauterística"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dáu ",
+-      "Dada ",
+-      "Daos ",
+-      "Daes "
+-    ],
+-    "name": "Asturian",
+-    "native": "asturianu",
+-    "scenario": [
+-      "Casu"
+-    ],
+-    "scenarioOutline": [
+-      "Esbozu del casu"
+-    ],
+-    "then": [
+-      "* ",
+-      "Entós "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cuando "
+-    ]
+-  },
+-  "az": {
+-    "and": [
+-      "* ",
+-      "Və ",
+-      "Həm "
+-    ],
+-    "background": [
+-      "Keçmiş",
+-      "Kontekst"
+-    ],
+-    "but": [
+-      "* ",
+-      "Amma ",
+-      "Ancaq "
+-    ],
+-    "examples": [
+-      "Nümunələr"
+-    ],
+-    "feature": [
+-      "Özəllik"
+-    ],
+-    "given": [
+-      "* ",
+-      "Tutaq ki ",
+-      "Verilir "
+-    ],
+-    "name": "Azerbaijani",
+-    "native": "Azərbaycanca",
+-    "scenario": [
+-      "Ssenari"
+-    ],
+-    "scenarioOutline": [
+-      "Ssenarinin strukturu"
+-    ],
+-    "then": [
+-      "* ",
+-      "O halda "
+-    ],
+-    "when": [
+-      "* ",
+-      "Əgər ",
+-      "Nə vaxt ki "
+-    ]
+-  },
+-  "bg": {
+-    "and": [
+-      "* ",
+-      "И "
+-    ],
+-    "background": [
+-      "Предистория"
+-    ],
+-    "but": [
+-      "* ",
+-      "Но "
+-    ],
+-    "examples": [
+-      "Примери"
+-    ],
+-    "feature": [
+-      "Функционалност"
+-    ],
+-    "given": [
+-      "* ",
+-      "Дадено "
+-    ],
+-    "name": "Bulgarian",
+-    "native": "български",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Рамка на сценарий"
+-    ],
+-    "then": [
+-      "* ",
+-      "То "
+-    ],
+-    "when": [
+-      "* ",
+-      "Когато "
+-    ]
+-  },
+-  "bm": {
+-    "and": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "background": [
+-      "Latar Belakang"
+-    ],
+-    "but": [
+-      "* ",
+-      "Tetapi ",
+-      "Tapi "
+-    ],
+-    "examples": [
+-      "Contoh"
+-    ],
+-    "feature": [
+-      "Fungsi"
+-    ],
+-    "given": [
+-      "* ",
+-      "Diberi ",
+-      "Bagi "
+-    ],
+-    "name": "Malay",
+-    "native": "Bahasa Melayu",
+-    "scenario": [
+-      "Senario",
+-      "Situasi",
+-      "Keadaan"
+-    ],
+-    "scenarioOutline": [
+-      "Kerangka Senario",
+-      "Kerangka Situasi",
+-      "Kerangka Keadaan",
+-      "Garis Panduan Senario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Maka ",
+-      "Kemudian "
+-    ],
+-    "when": [
+-      "* ",
+-      "Apabila "
+-    ]
+-  },
+-  "bs": {
+-    "and": [
+-      "* ",
+-      "I ",
+-      "A "
+-    ],
+-    "background": [
+-      "Pozadina"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ali "
+-    ],
+-    "examples": [
+-      "Primjeri"
+-    ],
+-    "feature": [
+-      "Karakteristika"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dato "
+-    ],
+-    "name": "Bosnian",
+-    "native": "Bosanski",
+-    "scenario": [
+-      "Scenariju",
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenariju-obris",
+-      "Scenario-outline"
+-    ],
+-    "then": [
+-      "* ",
+-      "Zatim "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kada "
+-    ]
+-  },
+-  "ca": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Rerefons",
+-      "Antecedents"
+-    ],
+-    "but": [
+-      "* ",
+-      "Però "
+-    ],
+-    "examples": [
+-      "Exemples"
+-    ],
+-    "feature": [
+-      "Característica",
+-      "Funcionalitat"
+-    ],
+-    "given": [
+-      "* ",
+-      "Donat ",
+-      "Donada ",
+-      "Atès ",
+-      "Atesa "
+-    ],
+-    "name": "Catalan",
+-    "native": "català",
+-    "scenario": [
+-      "Escenari"
+-    ],
+-    "scenarioOutline": [
+-      "Esquema de l'escenari"
+-    ],
+-    "then": [
+-      "* ",
+-      "Aleshores ",
+-      "Cal "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quan "
+-    ]
+-  },
+-  "cs": {
+-    "and": [
+-      "* ",
+-      "A také ",
+-      "A "
+-    ],
+-    "background": [
+-      "Pozadí",
+-      "Kontext"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ale "
+-    ],
+-    "examples": [
+-      "Příklady"
+-    ],
+-    "feature": [
+-      "Požadavek"
+-    ],
+-    "given": [
+-      "* ",
+-      "Pokud ",
+-      "Za předpokladu "
+-    ],
+-    "name": "Czech",
+-    "native": "Česky",
+-    "scenario": [
+-      "Scénář"
+-    ],
+-    "scenarioOutline": [
+-      "Náčrt Scénáře",
+-      "Osnova scénáře"
+-    ],
+-    "then": [
+-      "* ",
+-      "Pak "
+-    ],
+-    "when": [
+-      "* ",
+-      "Když "
+-    ]
+-  },
+-  "cy-GB": {
+-    "and": [
+-      "* ",
+-      "A "
+-    ],
+-    "background": [
+-      "Cefndir"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ond "
+-    ],
+-    "examples": [
+-      "Enghreifftiau"
+-    ],
+-    "feature": [
+-      "Arwedd"
+-    ],
+-    "given": [
+-      "* ",
+-      "Anrhegedig a "
+-    ],
+-    "name": "Welsh",
+-    "native": "Cymraeg",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenario Amlinellol"
+-    ],
+-    "then": [
+-      "* ",
+-      "Yna "
+-    ],
+-    "when": [
+-      "* ",
+-      "Pryd "
+-    ]
+-  },
+-  "da": {
+-    "and": [
+-      "* ",
+-      "Og "
+-    ],
+-    "background": [
+-      "Baggrund"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Eksempler"
+-    ],
+-    "feature": [
+-      "Egenskab"
+-    ],
+-    "given": [
+-      "* ",
+-      "Givet "
+-    ],
+-    "name": "Danish",
+-    "native": "dansk",
+-    "scenario": [
+-      "Scenarie"
+-    ],
+-    "scenarioOutline": [
+-      "Abstrakt Scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Så "
+-    ],
+-    "when": [
+-      "* ",
+-      "Når "
+-    ]
+-  },
+-  "de": {
+-    "and": [
+-      "* ",
+-      "Und "
+-    ],
+-    "background": [
+-      "Grundlage"
+-    ],
+-    "but": [
+-      "* ",
+-      "Aber "
+-    ],
+-    "examples": [
+-      "Beispiele"
+-    ],
+-    "feature": [
+-      "Funktionalität"
+-    ],
+-    "given": [
+-      "* ",
+-      "Angenommen ",
+-      "Gegeben sei ",
+-      "Gegeben seien "
+-    ],
+-    "name": "German",
+-    "native": "Deutsch",
+-    "scenario": [
+-      "Szenario"
+-    ],
+-    "scenarioOutline": [
+-      "Szenariogrundriss"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dann "
+-    ],
+-    "when": [
+-      "* ",
+-      "Wenn "
+-    ]
+-  },
+-  "el": {
+-    "and": [
+-      "* ",
+-      "Και "
+-    ],
+-    "background": [
+-      "Υπόβαθρο"
+-    ],
+-    "but": [
+-      "* ",
+-      "Αλλά "
+-    ],
+-    "examples": [
+-      "Παραδείγματα",
+-      "Σενάρια"
+-    ],
+-    "feature": [
+-      "Δυνατότητα",
+-      "Λειτουργία"
+-    ],
+-    "given": [
+-      "* ",
+-      "Δεδομένου "
+-    ],
+-    "name": "Greek",
+-    "native": "Ελληνικά",
+-    "scenario": [
+-      "Σενάριο"
+-    ],
+-    "scenarioOutline": [
+-      "Περιγραφή Σεναρίου",
+-      "Περίγραμμα Σεναρίου"
+-    ],
+-    "then": [
+-      "* ",
+-      "Τότε "
+-    ],
+-    "when": [
+-      "* ",
+-      "Όταν "
+-    ]
+-  },
+-  "em": {
+-    "and": [
+-      "* ",
+-      "😂"
+-    ],
+-    "background": [
+-      "💤"
+-    ],
+-    "but": [
+-      "* ",
+-      "😔"
+-    ],
+-    "examples": [
+-      "📓"
+-    ],
+-    "feature": [
+-      "📚"
+-    ],
+-    "given": [
+-      "* ",
+-      "😐"
+-    ],
+-    "name": "Emoji",
+-    "native": "😀",
+-    "scenario": [
+-      "📕"
+-    ],
+-    "scenarioOutline": [
+-      "📖"
+-    ],
+-    "then": [
+-      "* ",
+-      "🙏"
+-    ],
+-    "when": [
+-      "* ",
+-      "🎬"
+-    ]
+-  },
+-  "en": {
+-    "and": [
+-      "* ",
+-      "And "
+-    ],
+-    "background": [
+-      "Background"
+-    ],
+-    "but": [
+-      "* ",
+-      "But "
+-    ],
+-    "examples": [
+-      "Examples",
+-      "Scenarios"
+-    ],
+-    "feature": [
+-      "Feature",
+-      "Business Need",
+-      "Ability"
+-    ],
+-    "given": [
+-      "* ",
+-      "Given "
+-    ],
+-    "name": "English",
+-    "native": "English",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenario Outline",
+-      "Scenario Template"
+-    ],
+-    "then": [
+-      "* ",
+-      "Then "
+-    ],
+-    "when": [
+-      "* ",
+-      "When "
+-    ]
+-  },
+-  "en-Scouse": {
+-    "and": [
+-      "* ",
+-      "An "
+-    ],
+-    "background": [
+-      "Dis is what went down"
+-    ],
+-    "but": [
+-      "* ",
+-      "Buh "
+-    ],
+-    "examples": [
+-      "Examples"
+-    ],
+-    "feature": [
+-      "Feature"
+-    ],
+-    "given": [
+-      "* ",
+-      "Givun ",
+-      "Youse know when youse got "
+-    ],
+-    "name": "Scouse",
+-    "native": "Scouse",
+-    "scenario": [
+-      "The thing of it is"
+-    ],
+-    "scenarioOutline": [
+-      "Wharrimean is"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dun ",
+-      "Den youse gotta "
+-    ],
+-    "when": [
+-      "* ",
+-      "Wun ",
+-      "Youse know like when "
+-    ]
+-  },
+-  "en-au": {
+-    "and": [
+-      "* ",
+-      "Too right "
+-    ],
+-    "background": [
+-      "First off"
+-    ],
+-    "but": [
+-      "* ",
+-      "Yeah nah "
+-    ],
+-    "examples": [
+-      "You'll wanna"
+-    ],
+-    "feature": [
+-      "Pretty much"
+-    ],
+-    "given": [
+-      "* ",
+-      "Y'know "
+-    ],
+-    "name": "Australian",
+-    "native": "Australian",
+-    "scenario": [
+-      "Awww, look mate"
+-    ],
+-    "scenarioOutline": [
+-      "Reckon it's like"
+-    ],
+-    "then": [
+-      "* ",
+-      "But at the end of the day I reckon "
+-    ],
+-    "when": [
+-      "* ",
+-      "It's just unbelievable "
+-    ]
+-  },
+-  "en-lol": {
+-    "and": [
+-      "* ",
+-      "AN "
+-    ],
+-    "background": [
+-      "B4"
+-    ],
+-    "but": [
+-      "* ",
+-      "BUT "
+-    ],
+-    "examples": [
+-      "EXAMPLZ"
+-    ],
+-    "feature": [
+-      "OH HAI"
+-    ],
+-    "given": [
+-      "* ",
+-      "I CAN HAZ "
+-    ],
+-    "name": "LOLCAT",
+-    "native": "LOLCAT",
+-    "scenario": [
+-      "MISHUN"
+-    ],
+-    "scenarioOutline": [
+-      "MISHUN SRSLY"
+-    ],
+-    "then": [
+-      "* ",
+-      "DEN "
+-    ],
+-    "when": [
+-      "* ",
+-      "WEN "
+-    ]
+-  },
+-  "en-old": {
+-    "and": [
+-      "* ",
+-      "Ond ",
+-      "7 "
+-    ],
+-    "background": [
+-      "Aer",
+-      "Ær"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ac "
+-    ],
+-    "examples": [
+-      "Se the",
+-      "Se þe",
+-      "Se ðe"
+-    ],
+-    "feature": [
+-      "Hwaet",
+-      "Hwæt"
+-    ],
+-    "given": [
+-      "* ",
+-      "Thurh ",
+-      "Þurh ",
+-      "Ðurh "
+-    ],
+-    "name": "Old English",
+-    "native": "Englisc",
+-    "scenario": [
+-      "Swa"
+-    ],
+-    "scenarioOutline": [
+-      "Swa hwaer swa",
+-      "Swa hwær swa"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tha ",
+-      "Þa ",
+-      "Ða ",
+-      "Tha the ",
+-      "Þa þe ",
+-      "Ða ðe "
+-    ],
+-    "when": [
+-      "* ",
+-      "Tha ",
+-      "Þa ",
+-      "Ða "
+-    ]
+-  },
+-  "en-pirate": {
+-    "and": [
+-      "* ",
+-      "Aye "
+-    ],
+-    "background": [
+-      "Yo-ho-ho"
+-    ],
+-    "but": [
+-      "* ",
+-      "Avast! "
+-    ],
+-    "examples": [
+-      "Dead men tell no tales"
+-    ],
+-    "feature": [
+-      "Ahoy matey!"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gangway! "
+-    ],
+-    "name": "Pirate",
+-    "native": "Pirate",
+-    "scenario": [
+-      "Heave to"
+-    ],
+-    "scenarioOutline": [
+-      "Shiver me timbers"
+-    ],
+-    "then": [
+-      "* ",
+-      "Let go and haul "
+-    ],
+-    "when": [
+-      "* ",
+-      "Blimey! "
+-    ]
+-  },
+-  "eo": {
+-    "and": [
+-      "* ",
+-      "Kaj "
+-    ],
+-    "background": [
+-      "Fono"
+-    ],
+-    "but": [
+-      "* ",
+-      "Sed "
+-    ],
+-    "examples": [
+-      "Ekzemploj"
+-    ],
+-    "feature": [
+-      "Trajto"
+-    ],
+-    "given": [
+-      "* ",
+-      "Donitaĵo ",
+-      "Komence "
+-    ],
+-    "name": "Esperanto",
+-    "native": "Esperanto",
+-    "scenario": [
+-      "Scenaro",
+-      "Kazo"
+-    ],
+-    "scenarioOutline": [
+-      "Konturo de la scenaro",
+-      "Skizo",
+-      "Kazo-skizo"
+-    ],
+-    "then": [
+-      "* ",
+-      "Do "
+-    ],
+-    "when": [
+-      "* ",
+-      "Se "
+-    ]
+-  },
+-  "es": {
+-    "and": [
+-      "* ",
+-      "Y ",
+-      "E "
+-    ],
+-    "background": [
+-      "Antecedentes"
+-    ],
+-    "but": [
+-      "* ",
+-      "Pero "
+-    ],
+-    "examples": [
+-      "Ejemplos"
+-    ],
+-    "feature": [
+-      "Característica"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dado ",
+-      "Dada ",
+-      "Dados ",
+-      "Dadas "
+-    ],
+-    "name": "Spanish",
+-    "native": "español",
+-    "scenario": [
+-      "Escenario"
+-    ],
+-    "scenarioOutline": [
+-      "Esquema del escenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Entonces "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cuando "
+-    ]
+-  },
+-  "et": {
+-    "and": [
+-      "* ",
+-      "Ja "
+-    ],
+-    "background": [
+-      "Taust"
+-    ],
+-    "but": [
+-      "* ",
+-      "Kuid "
+-    ],
+-    "examples": [
+-      "Juhtumid"
+-    ],
+-    "feature": [
+-      "Omadus"
+-    ],
+-    "given": [
+-      "* ",
+-      "Eeldades "
+-    ],
+-    "name": "Estonian",
+-    "native": "eesti keel",
+-    "scenario": [
+-      "Stsenaarium"
+-    ],
+-    "scenarioOutline": [
+-      "Raamstsenaarium"
+-    ],
+-    "then": [
+-      "* ",
+-      "Siis "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kui "
+-    ]
+-  },
+-  "fa": {
+-    "and": [
+-      "* ",
+-      "و "
+-    ],
+-    "background": [
+-      "زمینه"
+-    ],
+-    "but": [
+-      "* ",
+-      "اما "
+-    ],
+-    "examples": [
+-      "نمونه ها"
+-    ],
+-    "feature": [
+-      "وِیژگی"
+-    ],
+-    "given": [
+-      "* ",
+-      "با فرض "
+-    ],
+-    "name": "Persian",
+-    "native": "فارسی",
+-    "scenario": [
+-      "سناریو"
+-    ],
+-    "scenarioOutline": [
+-      "الگوی سناریو"
+-    ],
+-    "then": [
+-      "* ",
+-      "آنگاه "
+-    ],
+-    "when": [
+-      "* ",
+-      "هنگامی "
+-    ]
+-  },
+-  "fi": {
+-    "and": [
+-      "* ",
+-      "Ja "
+-    ],
+-    "background": [
+-      "Tausta"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mutta "
+-    ],
+-    "examples": [
+-      "Tapaukset"
+-    ],
+-    "feature": [
+-      "Ominaisuus"
+-    ],
+-    "given": [
+-      "* ",
+-      "Oletetaan "
+-    ],
+-    "name": "Finnish",
+-    "native": "suomi",
+-    "scenario": [
+-      "Tapaus"
+-    ],
+-    "scenarioOutline": [
+-      "Tapausaihio"
+-    ],
+-    "then": [
+-      "* ",
+-      "Niin "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kun "
+-    ]
+-  },
+-  "fr": {
+-    "and": [
+-      "* ",
+-      "Et que ",
+-      "Et qu'",
+-      "Et "
+-    ],
+-    "background": [
+-      "Contexte"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mais que ",
+-      "Mais qu'",
+-      "Mais "
+-    ],
+-    "examples": [
+-      "Exemples"
+-    ],
+-    "feature": [
+-      "Fonctionnalité"
+-    ],
+-    "given": [
+-      "* ",
+-      "Soit ",
+-      "Etant donné que ",
+-      "Etant donné qu'",
+-      "Etant donné ",
+-      "Etant donnée ",
+-      "Etant donnés ",
+-      "Etant données ",
+-      "Étant donné que ",
+-      "Étant donné qu'",
+-      "Étant donné ",
+-      "Étant donnée ",
+-      "Étant donnés ",
+-      "Étant données "
+-    ],
+-    "name": "French",
+-    "native": "français",
+-    "scenario": [
+-      "Scénario"
+-    ],
+-    "scenarioOutline": [
+-      "Plan du scénario",
+-      "Plan du Scénario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Alors "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quand ",
+-      "Lorsque ",
+-      "Lorsqu'"
+-    ]
+-  },
+-  "ga": {
+-    "and": [
+-      "* ",
+-      "Agus"
+-    ],
+-    "background": [
+-      "Cúlra"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ach"
+-    ],
+-    "examples": [
+-      "Samplaí"
+-    ],
+-    "feature": [
+-      "Gné"
+-    ],
+-    "given": [
+-      "* ",
+-      "Cuir i gcás go",
+-      "Cuir i gcás nach",
+-      "Cuir i gcás gur",
+-      "Cuir i gcás nár"
+-    ],
+-    "name": "Irish",
+-    "native": "Gaeilge",
+-    "scenario": [
+-      "Cás"
+-    ],
+-    "scenarioOutline": [
+-      "Cás Achomair"
+-    ],
+-    "then": [
+-      "* ",
+-      "Ansin"
+-    ],
+-    "when": [
+-      "* ",
+-      "Nuair a",
+-      "Nuair nach",
+-      "Nuair ba",
+-      "Nuair nár"
+-    ]
+-  },
+-  "gj": {
+-    "and": [
+-      "* ",
+-      "અને "
+-    ],
+-    "background": [
+-      "બેકગ્રાઉન્ડ"
+-    ],
+-    "but": [
+-      "* ",
+-      "પણ "
+-    ],
+-    "examples": [
+-      "ઉદાહરણો"
+-    ],
+-    "feature": [
+-      "લક્ષણ",
+-      "વ્યાપાર જરૂર",
+-      "ક્ષમતા"
+-    ],
+-    "given": [
+-      "* ",
+-      "આપેલ છે "
+-    ],
+-    "name": "Gujarati",
+-    "native": "ગુજરાતી",
+-    "scenario": [
+-      "સ્થિતિ"
+-    ],
+-    "scenarioOutline": [
+-      "પરિદ્દશ્ય રૂપરેખા",
+-      "પરિદ્દશ્ય ઢાંચો"
+-    ],
+-    "then": [
+-      "* ",
+-      "પછી "
+-    ],
+-    "when": [
+-      "* ",
+-      "ક્યારે "
+-    ]
+-  },
+-  "gl": {
+-    "and": [
+-      "* ",
+-      "E "
+-    ],
+-    "background": [
+-      "Contexto"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mais ",
+-      "Pero "
+-    ],
+-    "examples": [
+-      "Exemplos"
+-    ],
+-    "feature": [
+-      "Característica"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dado ",
+-      "Dada ",
+-      "Dados ",
+-      "Dadas "
+-    ],
+-    "name": "Galician",
+-    "native": "galego",
+-    "scenario": [
+-      "Escenario"
+-    ],
+-    "scenarioOutline": [
+-      "Esbozo do escenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Entón ",
+-      "Logo "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cando "
+-    ]
+-  },
+-  "he": {
+-    "and": [
+-      "* ",
+-      "וגם "
+-    ],
+-    "background": [
+-      "רקע"
+-    ],
+-    "but": [
+-      "* ",
+-      "אבל "
+-    ],
+-    "examples": [
+-      "דוגמאות"
+-    ],
+-    "feature": [
+-      "תכונה"
+-    ],
+-    "given": [
+-      "* ",
+-      "בהינתן "
+-    ],
+-    "name": "Hebrew",
+-    "native": "עברית",
+-    "scenario": [
+-      "תרחיש"
+-    ],
+-    "scenarioOutline": [
+-      "תבנית תרחיש"
+-    ],
+-    "then": [
+-      "* ",
+-      "אז ",
+-      "אזי "
+-    ],
+-    "when": [
+-      "* ",
+-      "כאשר "
+-    ]
+-  },
+-  "hi": {
+-    "and": [
+-      "* ",
+-      "और ",
+-      "तथा "
+-    ],
+-    "background": [
+-      "पृष्ठभूमि"
+-    ],
+-    "but": [
+-      "* ",
+-      "पर ",
+-      "परन्तु ",
+-      "किन्तु "
+-    ],
+-    "examples": [
+-      "उदाहरण"
+-    ],
+-    "feature": [
+-      "रूप लेख"
+-    ],
+-    "given": [
+-      "* ",
+-      "अगर ",
+-      "यदि ",
+-      "चूंकि "
+-    ],
+-    "name": "Hindi",
+-    "native": "हिंदी",
+-    "scenario": [
+-      "परिदृश्य"
+-    ],
+-    "scenarioOutline": [
+-      "परिदृश्य रूपरेखा"
+-    ],
+-    "then": [
+-      "* ",
+-      "तब ",
+-      "तदा "
+-    ],
+-    "when": [
+-      "* ",
+-      "जब ",
+-      "कदा "
+-    ]
+-  },
+-  "hr": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Pozadina"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ali "
+-    ],
+-    "examples": [
+-      "Primjeri",
+-      "Scenariji"
+-    ],
+-    "feature": [
+-      "Osobina",
+-      "Mogućnost",
+-      "Mogucnost"
+-    ],
+-    "given": [
+-      "* ",
+-      "Zadan ",
+-      "Zadani ",
+-      "Zadano "
+-    ],
+-    "name": "Croatian",
+-    "native": "hrvatski",
+-    "scenario": [
+-      "Scenarij"
+-    ],
+-    "scenarioOutline": [
+-      "Skica",
+-      "Koncept"
+-    ],
+-    "then": [
+-      "* ",
+-      "Onda "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kada ",
+-      "Kad "
+-    ]
+-  },
+-  "ht": {
+-    "and": [
+-      "* ",
+-      "Ak ",
+-      "Epi ",
+-      "E "
+-    ],
+-    "background": [
+-      "Kontèks",
+-      "Istorik"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Egzanp"
+-    ],
+-    "feature": [
+-      "Karakteristik",
+-      "Mak",
+-      "Fonksyonalite"
+-    ],
+-    "given": [
+-      "* ",
+-      "Sipoze ",
+-      "Sipoze ke ",
+-      "Sipoze Ke "
+-    ],
+-    "name": "Creole",
+-    "native": "kreyòl",
+-    "scenario": [
+-      "Senaryo"
+-    ],
+-    "scenarioOutline": [
+-      "Plan senaryo",
+-      "Plan Senaryo",
+-      "Senaryo deskripsyon",
+-      "Senaryo Deskripsyon",
+-      "Dyagram senaryo",
+-      "Dyagram Senaryo"
+-    ],
+-    "then": [
+-      "* ",
+-      "Lè sa a ",
+-      "Le sa a "
+-    ],
+-    "when": [
+-      "* ",
+-      "Lè ",
+-      "Le "
+-    ]
+-  },
+-  "hu": {
+-    "and": [
+-      "* ",
+-      "És "
+-    ],
+-    "background": [
+-      "Háttér"
+-    ],
+-    "but": [
+-      "* ",
+-      "De "
+-    ],
+-    "examples": [
+-      "Példák"
+-    ],
+-    "feature": [
+-      "Jellemző"
+-    ],
+-    "given": [
+-      "* ",
+-      "Amennyiben ",
+-      "Adott "
+-    ],
+-    "name": "Hungarian",
+-    "native": "magyar",
+-    "scenario": [
+-      "Forgatókönyv"
+-    ],
+-    "scenarioOutline": [
+-      "Forgatókönyv vázlat"
+-    ],
+-    "then": [
+-      "* ",
+-      "Akkor "
+-    ],
+-    "when": [
+-      "* ",
+-      "Majd ",
+-      "Ha ",
+-      "Amikor "
+-    ]
+-  },
+-  "id": {
+-    "and": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "background": [
+-      "Dasar"
+-    ],
+-    "but": [
+-      "* ",
+-      "Tapi "
+-    ],
+-    "examples": [
+-      "Contoh"
+-    ],
+-    "feature": [
+-      "Fitur"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dengan "
+-    ],
+-    "name": "Indonesian",
+-    "native": "Bahasa Indonesia",
+-    "scenario": [
+-      "Skenario"
+-    ],
+-    "scenarioOutline": [
+-      "Skenario konsep"
+-    ],
+-    "then": [
+-      "* ",
+-      "Maka "
+-    ],
+-    "when": [
+-      "* ",
+-      "Ketika "
+-    ]
+-  },
+-  "is": {
+-    "and": [
+-      "* ",
+-      "Og "
+-    ],
+-    "background": [
+-      "Bakgrunnur"
+-    ],
+-    "but": [
+-      "* ",
+-      "En "
+-    ],
+-    "examples": [
+-      "Dæmi",
+-      "Atburðarásir"
+-    ],
+-    "feature": [
+-      "Eiginleiki"
+-    ],
+-    "given": [
+-      "* ",
+-      "Ef "
+-    ],
+-    "name": "Icelandic",
+-    "native": "Íslenska",
+-    "scenario": [
+-      "Atburðarás"
+-    ],
+-    "scenarioOutline": [
+-      "Lýsing Atburðarásar",
+-      "Lýsing Dæma"
+-    ],
+-    "then": [
+-      "* ",
+-      "Þá "
+-    ],
+-    "when": [
+-      "* ",
+-      "Þegar "
+-    ]
+-  },
+-  "it": {
+-    "and": [
+-      "* ",
+-      "E "
+-    ],
+-    "background": [
+-      "Contesto"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ma "
+-    ],
+-    "examples": [
+-      "Esempi"
+-    ],
+-    "feature": [
+-      "Funzionalità"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dato ",
+-      "Data ",
+-      "Dati ",
+-      "Date "
+-    ],
+-    "name": "Italian",
+-    "native": "italiano",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Schema dello scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Allora "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quando "
+-    ]
+-  },
+-  "ja": {
+-    "and": [
+-      "* ",
+-      "かつ"
+-    ],
+-    "background": [
+-      "背景"
+-    ],
+-    "but": [
+-      "* ",
+-      "しかし",
+-      "但し",
+-      "ただし"
+-    ],
+-    "examples": [
+-      "例",
+-      "サンプル"
+-    ],
+-    "feature": [
+-      "フィーチャ",
+-      "機能"
+-    ],
+-    "given": [
+-      "* ",
+-      "前提"
+-    ],
+-    "name": "Japanese",
+-    "native": "日本語",
+-    "scenario": [
+-      "シナリオ"
+-    ],
+-    "scenarioOutline": [
+-      "シナリオアウトライン",
+-      "シナリオテンプレート",
+-      "テンプレ",
+-      "シナリオテンプレ"
+-    ],
+-    "then": [
+-      "* ",
+-      "ならば"
+-    ],
+-    "when": [
+-      "* ",
+-      "もし"
+-    ]
+-  },
+-  "jv": {
+-    "and": [
+-      "* ",
+-      "Lan "
+-    ],
+-    "background": [
+-      "Dasar"
+-    ],
+-    "but": [
+-      "* ",
+-      "Tapi ",
+-      "Nanging ",
+-      "Ananging "
+-    ],
+-    "examples": [
+-      "Conto",
+-      "Contone"
+-    ],
+-    "feature": [
+-      "Fitur"
+-    ],
+-    "given": [
+-      "* ",
+-      "Nalika ",
+-      "Nalikaning "
+-    ],
+-    "name": "Javanese",
+-    "native": "Basa Jawa",
+-    "scenario": [
+-      "Skenario"
+-    ],
+-    "scenarioOutline": [
+-      "Konsep skenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Njuk ",
+-      "Banjur "
+-    ],
+-    "when": [
+-      "* ",
+-      "Manawa ",
+-      "Menawa "
+-    ]
+-  },
+-  "ka": {
+-    "and": [
+-      "* ",
+-      "და"
+-    ],
+-    "background": [
+-      "კონტექსტი"
+-    ],
+-    "but": [
+-      "* ",
+-      "მაგ­რამ"
+-    ],
+-    "examples": [
+-      "მაგალითები"
+-    ],
+-    "feature": [
+-      "თვისება"
+-    ],
+-    "given": [
+-      "* ",
+-      "მოცემული"
+-    ],
+-    "name": "Georgian",
+-    "native": "ქართველი",
+-    "scenario": [
+-      "სცენარის"
+-    ],
+-    "scenarioOutline": [
+-      "სცენარის ნიმუში"
+-    ],
+-    "then": [
+-      "* ",
+-      "მაშინ"
+-    ],
+-    "when": [
+-      "* ",
+-      "როდესაც"
+-    ]
+-  },
+-  "kn": {
+-    "and": [
+-      "* ",
+-      "ಮತ್ತು "
+-    ],
+-    "background": [
+-      "ಹಿನ್ನೆಲೆ"
+-    ],
+-    "but": [
+-      "* ",
+-      "ಆದರೆ "
+-    ],
+-    "examples": [
+-      "ಉದಾಹರಣೆಗಳು"
+-    ],
+-    "feature": [
+-      "ಹೆಚ್ಚಳ"
+-    ],
+-    "given": [
+-      "* ",
+-      "ನೀಡಿದ "
+-    ],
+-    "name": "Kannada",
+-    "native": "ಕನ್ನಡ",
+-    "scenario": [
+-      "ಕಥಾಸಾರಾಂಶ"
+-    ],
+-    "scenarioOutline": [
+-      "ವಿವರಣೆ"
+-    ],
+-    "then": [
+-      "* ",
+-      "ನಂತರ "
+-    ],
+-    "when": [
+-      "* ",
+-      "ಸ್ಥಿತಿಯನ್ನು "
+-    ]
+-  },
+-  "ko": {
+-    "and": [
+-      "* ",
+-      "그리고"
+-    ],
+-    "background": [
+-      "배경"
+-    ],
+-    "but": [
+-      "* ",
+-      "하지만",
+-      "단"
+-    ],
+-    "examples": [
+-      "예"
+-    ],
+-    "feature": [
+-      "기능"
+-    ],
+-    "given": [
+-      "* ",
+-      "조건",
+-      "먼저"
+-    ],
+-    "name": "Korean",
+-    "native": "한국어",
+-    "scenario": [
+-      "시나리오"
+-    ],
+-    "scenarioOutline": [
+-      "시나리오 개요"
+-    ],
+-    "then": [
+-      "* ",
+-      "그러면"
+-    ],
+-    "when": [
+-      "* ",
+-      "만일",
+-      "만약"
+-    ]
+-  },
+-  "lt": {
+-    "and": [
+-      "* ",
+-      "Ir "
+-    ],
+-    "background": [
+-      "Kontekstas"
+-    ],
+-    "but": [
+-      "* ",
+-      "Bet "
+-    ],
+-    "examples": [
+-      "Pavyzdžiai",
+-      "Scenarijai",
+-      "Variantai"
+-    ],
+-    "feature": [
+-      "Savybė"
+-    ],
+-    "given": [
+-      "* ",
+-      "Duota "
+-    ],
+-    "name": "Lithuanian",
+-    "native": "lietuvių kalba",
+-    "scenario": [
+-      "Scenarijus"
+-    ],
+-    "scenarioOutline": [
+-      "Scenarijaus šablonas"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tada "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kai "
+-    ]
+-  },
+-  "lu": {
+-    "and": [
+-      "* ",
+-      "an ",
+-      "a "
+-    ],
+-    "background": [
+-      "Hannergrond"
+-    ],
+-    "but": [
+-      "* ",
+-      "awer ",
+-      "mä "
+-    ],
+-    "examples": [
+-      "Beispiller"
+-    ],
+-    "feature": [
+-      "Funktionalitéit"
+-    ],
+-    "given": [
+-      "* ",
+-      "ugeholl "
+-    ],
+-    "name": "Luxemburgish",
+-    "native": "Lëtzebuergesch",
+-    "scenario": [
+-      "Szenario"
+-    ],
+-    "scenarioOutline": [
+-      "Plang vum Szenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "dann "
+-    ],
+-    "when": [
+-      "* ",
+-      "wann "
+-    ]
+-  },
+-  "lv": {
+-    "and": [
+-      "* ",
+-      "Un "
+-    ],
+-    "background": [
+-      "Konteksts",
+-      "Situācija"
+-    ],
+-    "but": [
+-      "* ",
+-      "Bet "
+-    ],
+-    "examples": [
+-      "Piemēri",
+-      "Paraugs"
+-    ],
+-    "feature": [
+-      "Funkcionalitāte",
+-      "Fīča"
+-    ],
+-    "given": [
+-      "* ",
+-      "Kad "
+-    ],
+-    "name": "Latvian",
+-    "native": "latviešu",
+-    "scenario": [
+-      "Scenārijs"
+-    ],
+-    "scenarioOutline": [
+-      "Scenārijs pēc parauga"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tad "
+-    ],
+-    "when": [
+-      "* ",
+-      "Ja "
+-    ]
+-  },
+-  "mk-Cyrl": {
+-    "and": [
+-      "* ",
+-      "И "
+-    ],
+-    "background": [
+-      "Контекст",
+-      "Содржина"
+-    ],
+-    "but": [
+-      "* ",
+-      "Но "
+-    ],
+-    "examples": [
+-      "Примери",
+-      "Сценарија"
+-    ],
+-    "feature": [
+-      "Функционалност",
+-      "Бизнис потреба",
+-      "Можност"
+-    ],
+-    "given": [
+-      "* ",
+-      "Дадено ",
+-      "Дадена "
+-    ],
+-    "name": "Macedonian",
+-    "native": "Македонски",
+-    "scenario": [
+-      "Сценарио",
+-      "На пример"
+-    ],
+-    "scenarioOutline": [
+-      "Преглед на сценарија",
+-      "Скица",
+-      "Концепт"
+-    ],
+-    "then": [
+-      "* ",
+-      "Тогаш "
+-    ],
+-    "when": [
+-      "* ",
+-      "Кога "
+-    ]
+-  },
+-  "mk-Latn": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Kontekst",
+-      "Sodrzhina"
+-    ],
+-    "but": [
+-      "* ",
+-      "No "
+-    ],
+-    "examples": [
+-      "Primeri",
+-      "Scenaria"
+-    ],
+-    "feature": [
+-      "Funkcionalnost",
+-      "Biznis potreba",
+-      "Mozhnost"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dadeno ",
+-      "Dadena "
+-    ],
+-    "name": "Macedonian (Latin)",
+-    "native": "Makedonski (Latinica)",
+-    "scenario": [
+-      "Scenario",
+-      "Na primer"
+-    ],
+-    "scenarioOutline": [
+-      "Pregled na scenarija",
+-      "Skica",
+-      "Koncept"
+-    ],
+-    "then": [
+-      "* ",
+-      "Togash "
+-    ],
+-    "when": [
+-      "* ",
+-      "Koga "
+-    ]
+-  },
+-  "mn": {
+-    "and": [
+-      "* ",
+-      "Мөн ",
+-      "Тэгээд "
+-    ],
+-    "background": [
+-      "Агуулга"
+-    ],
+-    "but": [
+-      "* ",
+-      "Гэхдээ ",
+-      "Харин "
+-    ],
+-    "examples": [
+-      "Тухайлбал"
+-    ],
+-    "feature": [
+-      "Функц",
+-      "Функционал"
+-    ],
+-    "given": [
+-      "* ",
+-      "Өгөгдсөн нь ",
+-      "Анх "
+-    ],
+-    "name": "Mongolian",
+-    "native": "монгол",
+-    "scenario": [
+-      "Сценар"
+-    ],
+-    "scenarioOutline": [
+-      "Сценарын төлөвлөгөө"
+-    ],
+-    "then": [
+-      "* ",
+-      "Тэгэхэд ",
+-      "Үүний дараа "
+-    ],
+-    "when": [
+-      "* ",
+-      "Хэрэв "
+-    ]
+-  },
+-  "nl": {
+-    "and": [
+-      "* ",
+-      "En "
+-    ],
+-    "background": [
+-      "Achtergrond"
+-    ],
+-    "but": [
+-      "* ",
+-      "Maar "
+-    ],
+-    "examples": [
+-      "Voorbeelden"
+-    ],
+-    "feature": [
+-      "Functionaliteit"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gegeven ",
+-      "Stel "
+-    ],
+-    "name": "Dutch",
+-    "native": "Nederlands",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Abstract Scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Dan "
+-    ],
+-    "when": [
+-      "* ",
+-      "Als ",
+-      "Wanneer "
+-    ]
+-  },
+-  "no": {
+-    "and": [
+-      "* ",
+-      "Og "
+-    ],
+-    "background": [
+-      "Bakgrunn"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Eksempler"
+-    ],
+-    "feature": [
+-      "Egenskap"
+-    ],
+-    "given": [
+-      "* ",
+-      "Gitt "
+-    ],
+-    "name": "Norwegian",
+-    "native": "norsk",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Scenariomal",
+-      "Abstrakt Scenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Så "
+-    ],
+-    "when": [
+-      "* ",
+-      "Når "
+-    ]
+-  },
+-  "pa": {
+-    "and": [
+-      "* ",
+-      "ਅਤੇ "
+-    ],
+-    "background": [
+-      "ਪਿਛੋਕੜ"
+-    ],
+-    "but": [
+-      "* ",
+-      "ਪਰ "
+-    ],
+-    "examples": [
+-      "ਉਦਾਹਰਨਾਂ"
+-    ],
+-    "feature": [
+-      "ਖਾਸੀਅਤ",
+-      "ਮੁਹਾਂਦਰਾ",
+-      "ਨਕਸ਼ ਨੁਹਾਰ"
+-    ],
+-    "given": [
+-      "* ",
+-      "ਜੇਕਰ ",
+-      "ਜਿਵੇਂ ਕਿ "
+-    ],
+-    "name": "Panjabi",
+-    "native": "ਪੰਜਾਬੀ",
+-    "scenario": [
+-      "ਪਟਕਥਾ"
+-    ],
+-    "scenarioOutline": [
+-      "ਪਟਕਥਾ ਢਾਂਚਾ",
+-      "ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ"
+-    ],
+-    "then": [
+-      "* ",
+-      "ਤਦ "
+-    ],
+-    "when": [
+-      "* ",
+-      "ਜਦੋਂ "
+-    ]
+-  },
+-  "pl": {
+-    "and": [
+-      "* ",
+-      "Oraz ",
+-      "I "
+-    ],
+-    "background": [
+-      "Założenia"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ale "
+-    ],
+-    "examples": [
+-      "Przykłady"
+-    ],
+-    "feature": [
+-      "Właściwość",
+-      "Funkcja",
+-      "Aspekt",
+-      "Potrzeba biznesowa"
+-    ],
+-    "given": [
+-      "* ",
+-      "Zakładając ",
+-      "Mając ",
+-      "Zakładając, że "
+-    ],
+-    "name": "Polish",
+-    "native": "polski",
+-    "scenario": [
+-      "Scenariusz"
+-    ],
+-    "scenarioOutline": [
+-      "Szablon scenariusza"
+-    ],
+-    "then": [
+-      "* ",
+-      "Wtedy "
+-    ],
+-    "when": [
+-      "* ",
+-      "Jeżeli ",
+-      "Jeśli ",
+-      "Gdy ",
+-      "Kiedy "
+-    ]
+-  },
+-  "pt": {
+-    "and": [
+-      "* ",
+-      "E "
+-    ],
+-    "background": [
+-      "Contexto",
+-      "Cenário de Fundo",
+-      "Cenario de Fundo",
+-      "Fundo"
+-    ],
+-    "but": [
+-      "* ",
+-      "Mas "
+-    ],
+-    "examples": [
+-      "Exemplos",
+-      "Cenários",
+-      "Cenarios"
+-    ],
+-    "feature": [
+-      "Funcionalidade",
+-      "Característica",
+-      "Caracteristica"
+-    ],
+-    "given": [
+-      "* ",
+-      "Dado ",
+-      "Dada ",
+-      "Dados ",
+-      "Dadas "
+-    ],
+-    "name": "Portuguese",
+-    "native": "português",
+-    "scenario": [
+-      "Cenário",
+-      "Cenario"
+-    ],
+-    "scenarioOutline": [
+-      "Esquema do Cenário",
+-      "Esquema do Cenario",
+-      "Delineação do Cenário",
+-      "Delineacao do Cenario"
+-    ],
+-    "then": [
+-      "* ",
+-      "Então ",
+-      "Entao "
+-    ],
+-    "when": [
+-      "* ",
+-      "Quando "
+-    ]
+-  },
+-  "ro": {
+-    "and": [
+-      "* ",
+-      "Si ",
+-      "Și ",
+-      "Şi "
+-    ],
+-    "background": [
+-      "Context"
+-    ],
+-    "but": [
+-      "* ",
+-      "Dar "
+-    ],
+-    "examples": [
+-      "Exemple"
+-    ],
+-    "feature": [
+-      "Functionalitate",
+-      "Funcționalitate",
+-      "Funcţionalitate"
+-    ],
+-    "given": [
+-      "* ",
+-      "Date fiind ",
+-      "Dat fiind ",
+-      "Dată fiind",
+-      "Dati fiind ",
+-      "Dați fiind ",
+-      "Daţi fiind "
+-    ],
+-    "name": "Romanian",
+-    "native": "română",
+-    "scenario": [
+-      "Scenariu"
+-    ],
+-    "scenarioOutline": [
+-      "Structura scenariu",
+-      "Structură scenariu"
+-    ],
+-    "then": [
+-      "* ",
+-      "Atunci "
+-    ],
+-    "when": [
+-      "* ",
+-      "Cand ",
+-      "Când "
+-    ]
+-  },
+-  "ru": {
+-    "and": [
+-      "* ",
+-      "И ",
+-      "К тому же ",
+-      "Также "
+-    ],
+-    "background": [
+-      "Предыстория",
+-      "Контекст"
+-    ],
+-    "but": [
+-      "* ",
+-      "Но ",
+-      "А "
+-    ],
+-    "examples": [
+-      "Примеры"
+-    ],
+-    "feature": [
+-      "Функция",
+-      "Функциональность",
+-      "Функционал",
+-      "Свойство"
+-    ],
+-    "given": [
+-      "* ",
+-      "Допустим ",
+-      "Дано ",
+-      "Пусть ",
+-      "Если "
+-    ],
+-    "name": "Russian",
+-    "native": "русский",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Структура сценария"
+-    ],
+-    "then": [
+-      "* ",
+-      "То ",
+-      "Затем ",
+-      "Тогда "
+-    ],
+-    "when": [
+-      "* ",
+-      "Когда "
+-    ]
+-  },
+-  "sk": {
+-    "and": [
+-      "* ",
+-      "A ",
+-      "A tiež ",
+-      "A taktiež ",
+-      "A zároveň "
+-    ],
+-    "background": [
+-      "Pozadie"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ale "
+-    ],
+-    "examples": [
+-      "Príklady"
+-    ],
+-    "feature": [
+-      "Požiadavka",
+-      "Funkcia",
+-      "Vlastnosť"
+-    ],
+-    "given": [
+-      "* ",
+-      "Pokiaľ ",
+-      "Za predpokladu "
+-    ],
+-    "name": "Slovak",
+-    "native": "Slovensky",
+-    "scenario": [
+-      "Scenár"
+-    ],
+-    "scenarioOutline": [
+-      "Náčrt Scenáru",
+-      "Náčrt Scenára",
+-      "Osnova Scenára"
+-    ],
+-    "then": [
+-      "* ",
+-      "Tak ",
+-      "Potom "
+-    ],
+-    "when": [
+-      "* ",
+-      "Keď ",
+-      "Ak "
+-    ]
+-  },
+-  "sl": {
+-    "and": [
+-      "In ",
+-      "Ter "
+-    ],
+-    "background": [
+-      "Kontekst",
+-      "Osnova",
+-      "Ozadje"
+-    ],
+-    "but": [
+-      "Toda ",
+-      "Ampak ",
+-      "Vendar "
+-    ],
+-    "examples": [
+-      "Primeri",
+-      "Scenariji"
+-    ],
+-    "feature": [
+-      "Funkcionalnost",
+-      "Funkcija",
+-      "Možnosti",
+-      "Moznosti",
+-      "Lastnost",
+-      "Značilnost"
+-    ],
+-    "given": [
+-      "Dano ",
+-      "Podano ",
+-      "Zaradi ",
+-      "Privzeto "
+-    ],
+-    "name": "Slovenian",
+-    "native": "Slovenski",
+-    "scenario": [
+-      "Scenarij",
+-      "Primer"
+-    ],
+-    "scenarioOutline": [
+-      "Struktura scenarija",
+-      "Skica",
+-      "Koncept",
+-      "Oris scenarija",
+-      "Osnutek"
+-    ],
+-    "then": [
+-      "Nato ",
+-      "Potem ",
+-      "Takrat "
+-    ],
+-    "when": [
+-      "Ko ",
+-      "Ce ",
+-      "Če ",
+-      "Kadar "
+-    ]
+-  },
+-  "sr-Cyrl": {
+-    "and": [
+-      "* ",
+-      "И "
+-    ],
+-    "background": [
+-      "Контекст",
+-      "Основа",
+-      "Позадина"
+-    ],
+-    "but": [
+-      "* ",
+-      "Али "
+-    ],
+-    "examples": [
+-      "Примери",
+-      "Сценарији"
+-    ],
+-    "feature": [
+-      "Функционалност",
+-      "Могућност",
+-      "Особина"
+-    ],
+-    "given": [
+-      "* ",
+-      "За дато ",
+-      "За дате ",
+-      "За дати "
+-    ],
+-    "name": "Serbian",
+-    "native": "Српски",
+-    "scenario": [
+-      "Сценарио",
+-      "Пример"
+-    ],
+-    "scenarioOutline": [
+-      "Структура сценарија",
+-      "Скица",
+-      "Концепт"
+-    ],
+-    "then": [
+-      "* ",
+-      "Онда "
+-    ],
+-    "when": [
+-      "* ",
+-      "Када ",
+-      "Кад "
+-    ]
+-  },
+-  "sr-Latn": {
+-    "and": [
+-      "* ",
+-      "I "
+-    ],
+-    "background": [
+-      "Kontekst",
+-      "Osnova",
+-      "Pozadina"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ali "
+-    ],
+-    "examples": [
+-      "Primeri",
+-      "Scenariji"
+-    ],
+-    "feature": [
+-      "Funkcionalnost",
+-      "Mogućnost",
+-      "Mogucnost",
+-      "Osobina"
+-    ],
+-    "given": [
+-      "* ",
+-      "Za dato ",
+-      "Za date ",
+-      "Za dati "
+-    ],
+-    "name": "Serbian (Latin)",
+-    "native": "Srpski (Latinica)",
+-    "scenario": [
+-      "Scenario",
+-      "Primer"
+-    ],
+-    "scenarioOutline": [
+-      "Struktura scenarija",
+-      "Skica",
+-      "Koncept"
+-    ],
+-    "then": [
+-      "* ",
+-      "Onda "
+-    ],
+-    "when": [
+-      "* ",
+-      "Kada ",
+-      "Kad "
+-    ]
+-  },
+-  "sv": {
+-    "and": [
+-      "* ",
+-      "Och "
+-    ],
+-    "background": [
+-      "Bakgrund"
+-    ],
+-    "but": [
+-      "* ",
+-      "Men "
+-    ],
+-    "examples": [
+-      "Exempel"
+-    ],
+-    "feature": [
+-      "Egenskap"
+-    ],
+-    "given": [
+-      "* ",
+-      "Givet "
+-    ],
+-    "name": "Swedish",
+-    "native": "Svenska",
+-    "scenario": [
+-      "Scenario"
+-    ],
+-    "scenarioOutline": [
+-      "Abstrakt Scenario",
+-      "Scenariomall"
+-    ],
+-    "then": [
+-      "* ",
+-      "Så "
+-    ],
+-    "when": [
+-      "* ",
+-      "När "
+-    ]
+-  },
+-  "ta": {
+-    "and": [
+-      "* ",
+-      "மேலும்  ",
+-      "மற்றும் "
+-    ],
+-    "background": [
+-      "பின்னணி"
+-    ],
+-    "but": [
+-      "* ",
+-      "ஆனால்  "
+-    ],
+-    "examples": [
+-      "எடுத்துக்காட்டுகள்",
+-      "காட்சிகள்",
+-      " நிலைமைகளில்"
+-    ],
+-    "feature": [
+-      "அம்சம்",
+-      "வணிக தேவை",
+-      "திறன்"
+-    ],
+-    "given": [
+-      "* ",
+-      "கொடுக்கப்பட்ட "
+-    ],
+-    "name": "Tamil",
+-    "native": "தமிழ்",
+-    "scenario": [
+-      "காட்சி"
+-    ],
+-    "scenarioOutline": [
+-      "காட்சி சுருக்கம்",
+-      "காட்சி வார்ப்புரு"
+-    ],
+-    "then": [
+-      "* ",
+-      "அப்பொழுது "
+-    ],
+-    "when": [
+-      "* ",
+-      "எப்போது "
+-    ]
+-  },
+-  "th": {
+-    "and": [
+-      "* ",
+-      "และ "
+-    ],
+-    "background": [
+-      "แนวคิด"
+-    ],
+-    "but": [
+-      "* ",
+-      "แต่ "
+-    ],
+-    "examples": [
+-      "ชุดของตัวอย่าง",
+-      "ชุดของเหตุการณ์"
+-    ],
+-    "feature": [
+-      "โครงหลัก",
+-      "ความต้องการทางธุรกิจ",
+-      "ความสามารถ"
+-    ],
+-    "given": [
+-      "* ",
+-      "กำหนดให้ "
+-    ],
+-    "name": "Thai",
+-    "native": "ไทย",
+-    "scenario": [
+-      "เหตุการณ์"
+-    ],
+-    "scenarioOutline": [
+-      "สรุปเหตุการณ์",
+-      "โครงสร้างของเหตุการณ์"
+-    ],
+-    "then": [
+-      "* ",
+-      "ดังนั้น "
+-    ],
+-    "when": [
+-      "* ",
+-      "เมื่อ "
+-    ]
+-  },
+-  "tl": {
+-    "and": [
+-      "* ",
+-      "మరియు "
+-    ],
+-    "background": [
+-      "నేపథ్యం"
+-    ],
+-    "but": [
+-      "* ",
+-      "కాని "
+-    ],
+-    "examples": [
+-      "ఉదాహరణలు"
+-    ],
+-    "feature": [
+-      "గుణము"
+-    ],
+-    "given": [
+-      "* ",
+-      "చెప్పబడినది "
+-    ],
+-    "name": "Telugu",
+-    "native": "తెలుగు",
+-    "scenario": [
+-      "సన్నివేశం"
+-    ],
+-    "scenarioOutline": [
+-      "కథనం"
+-    ],
+-    "then": [
+-      "* ",
+-      "అప్పుడు "
+-    ],
+-    "when": [
+-      "* ",
+-      "ఈ పరిస్థితిలో "
+-    ]
+-  },
+-  "tlh": {
+-    "and": [
+-      "* ",
+-      "'ej ",
+-      "latlh "
+-    ],
+-    "background": [
+-      "mo'"
+-    ],
+-    "but": [
+-      "* ",
+-      "'ach ",
+-      "'a "
+-    ],
+-    "examples": [
+-      "ghantoH",
+-      "lutmey"
+-    ],
+-    "feature": [
+-      "Qap",
+-      "Qu'meH 'ut",
+-      "perbogh",
+-      "poQbogh malja'",
+-      "laH"
+-    ],
+-    "given": [
+-      "* ",
+-      "ghu' noblu' ",
+-      "DaH ghu' bejlu' "
+-    ],
+-    "name": "Klingon",
+-    "native": "tlhIngan",
+-    "scenario": [
+-      "lut"
+-    ],
+-    "scenarioOutline": [
+-      "lut chovnatlh"
+-    ],
+-    "then": [
+-      "* ",
+-      "vaj "
+-    ],
+-    "when": [
+-      "* ",
+-      "qaSDI' "
+-    ]
+-  },
+-  "tr": {
+-    "and": [
+-      "* ",
+-      "Ve "
+-    ],
+-    "background": [
+-      "Geçmiş"
+-    ],
+-    "but": [
+-      "* ",
+-      "Fakat ",
+-      "Ama "
+-    ],
+-    "examples": [
+-      "Örnekler"
+-    ],
+-    "feature": [
+-      "Özellik"
+-    ],
+-    "given": [
+-      "* ",
+-      "Diyelim ki "
+-    ],
+-    "name": "Turkish",
+-    "native": "Türkçe",
+-    "scenario": [
+-      "Senaryo"
+-    ],
+-    "scenarioOutline": [
+-      "Senaryo taslağı"
+-    ],
+-    "then": [
+-      "* ",
+-      "O zaman "
+-    ],
+-    "when": [
+-      "* ",
+-      "Eğer ki "
+-    ]
+-  },
+-  "tt": {
+-    "and": [
+-      "* ",
+-      "Һәм ",
+-      "Вә "
+-    ],
+-    "background": [
+-      "Кереш"
+-    ],
+-    "but": [
+-      "* ",
+-      "Ләкин ",
+-      "Әмма "
+-    ],
+-    "examples": [
+-      "Үрнәкләр",
+-      "Мисаллар"
+-    ],
+-    "feature": [
+-      "Мөмкинлек",
+-      "Үзенчәлеклелек"
+-    ],
+-    "given": [
+-      "* ",
+-      "Әйтик "
+-    ],
+-    "name": "Tatar",
+-    "native": "Татарча",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Сценарийның төзелеше"
+-    ],
+-    "then": [
+-      "* ",
+-      "Нәтиҗәдә "
+-    ],
+-    "when": [
+-      "* ",
+-      "Әгәр "
+-    ]
+-  },
+-  "uk": {
+-    "and": [
+-      "* ",
+-      "І ",
+-      "А також ",
+-      "Та "
+-    ],
+-    "background": [
+-      "Передумова"
+-    ],
+-    "but": [
+-      "* ",
+-      "Але "
+-    ],
+-    "examples": [
+-      "Приклади"
+-    ],
+-    "feature": [
+-      "Функціонал"
+-    ],
+-    "given": [
+-      "* ",
+-      "Припустимо ",
+-      "Припустимо, що ",
+-      "Нехай ",
+-      "Дано "
+-    ],
+-    "name": "Ukrainian",
+-    "native": "Українська",
+-    "scenario": [
+-      "Сценарій"
+-    ],
+-    "scenarioOutline": [
+-      "Структура сценарію"
+-    ],
+-    "then": [
+-      "* ",
+-      "То ",
+-      "Тоді "
+-    ],
+-    "when": [
+-      "* ",
+-      "Якщо ",
+-      "Коли "
+-    ]
+-  },
+-  "ur": {
+-    "and": [
+-      "* ",
+-      "اور "
+-    ],
+-    "background": [
+-      "پس منظر"
+-    ],
+-    "but": [
+-      "* ",
+-      "لیکن "
+-    ],
+-    "examples": [
+-      "مثالیں"
+-    ],
+-    "feature": [
+-      "صلاحیت",
+-      "کاروبار کی ضرورت",
+-      "خصوصیت"
+-    ],
+-    "given": [
+-      "* ",
+-      "اگر ",
+-      "بالفرض ",
+-      "فرض کیا "
+-    ],
+-    "name": "Urdu",
+-    "native": "اردو",
+-    "scenario": [
+-      "منظرنامہ"
+-    ],
+-    "scenarioOutline": [
+-      "منظر نامے کا خاکہ"
+-    ],
+-    "then": [
+-      "* ",
+-      "پھر ",
+-      "تب "
+-    ],
+-    "when": [
+-      "* ",
+-      "جب "
+-    ]
+-  },
+-  "uz": {
+-    "and": [
+-      "* ",
+-      "Ва "
+-    ],
+-    "background": [
+-      "Тарих"
+-    ],
+-    "but": [
+-      "* ",
+-      "Лекин ",
+-      "Бирок ",
+-      "Аммо "
+-    ],
+-    "examples": [
+-      "Мисоллар"
+-    ],
+-    "feature": [
+-      "Функционал"
+-    ],
+-    "given": [
+-      "* ",
+-      "Агар "
+-    ],
+-    "name": "Uzbek",
+-    "native": "Узбекча",
+-    "scenario": [
+-      "Сценарий"
+-    ],
+-    "scenarioOutline": [
+-      "Сценарий структураси"
+-    ],
+-    "then": [
+-      "* ",
+-      "Унда "
+-    ],
+-    "when": [
+-      "* ",
+-      "Агар "
+-    ]
+-  },
+-  "vi": {
+-    "and": [
+-      "* ",
+-      "Và "
+-    ],
+-    "background": [
+-      "Bối cảnh"
+-    ],
+-    "but": [
+-      "* ",
+-      "Nhưng "
+-    ],
+-    "examples": [
+-      "Dữ liệu"
+-    ],
+-    "feature": [
+-      "Tính năng"
+-    ],
+-    "given": [
+-      "* ",
+-      "Biết ",
+-      "Cho "
+-    ],
+-    "name": "Vietnamese",
+-    "native": "Tiếng Việt",
+-    "scenario": [
+-      "Tình huống",
+-      "Kịch bản"
+-    ],
+-    "scenarioOutline": [
+-      "Khung tình huống",
+-      "Khung kịch bản"
+-    ],
+-    "then": [
+-      "* ",
+-      "Thì "
+-    ],
+-    "when": [
+-      "* ",
+-      "Khi "
+-    ]
+-  },
+-  "zh-CN": {
+-    "and": [
+-      "* ",
+-      "而且",
+-      "并且",
+-      "同时"
+-    ],
+-    "background": [
+-      "背景"
+-    ],
+-    "but": [
+-      "* ",
+-      "但是"
+-    ],
+-    "examples": [
+-      "例子"
+-    ],
+-    "feature": [
+-      "功能"
+-    ],
+-    "given": [
+-      "* ",
+-      "假如",
+-      "假设",
+-      "假定"
+-    ],
+-    "name": "Chinese simplified",
+-    "native": "简体中文",
+-    "scenario": [
+-      "场景",
+-      "剧本"
+-    ],
+-    "scenarioOutline": [
+-      "场景大纲",
+-      "剧本大纲"
+-    ],
+-    "then": [
+-      "* ",
+-      "那么"
+-    ],
+-    "when": [
+-      "* ",
+-      "当"
+-    ]
+-  },
+-  "zh-TW": {
+-    "and": [
+-      "* ",
+-      "而且",
+-      "並且",
+-      "同時"
+-    ],
+-    "background": [
+-      "背景"
+-    ],
+-    "but": [
+-      "* ",
+-      "但是"
+-    ],
+-    "examples": [
+-      "例子"
+-    ],
+-    "feature": [
+-      "功能"
+-    ],
+-    "given": [
+-      "* ",
+-      "假如",
+-      "假設",
+-      "假定"
+-    ],
+-    "name": "Chinese traditional",
+-    "native": "繁體中文",
+-    "scenario": [
+-      "場景",
+-      "劇本"
+-    ],
+-    "scenarioOutline": [
+-      "場景大綱",
+-      "劇本大綱"
+-    ],
+-    "then": [
+-      "* ",
+-      "那麼"
+-    ],
+-    "when": [
+-      "* ",
+-      "當"
+-    ]
+-  }
+-}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch b/meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch
new file mode 100644
index 000000000..101a887e5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0055-CLEANUP-Remove-deprecated-parts.patch
@@ -0,0 +1,736 @@
+From f66a9fd1bf7c2ed117fe697b80a0ea4b071773f3 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:21:27 +0200
+Subject: [PATCH] CLEANUP: Remove deprecated parts.
+
+---
+ bin/convert_i18n_yaml.py |  77 -----
+ bin/i18n.yml             | 635 ---------------------------------------
+ 2 files changed, 712 deletions(-)
+ delete mode 100755 bin/convert_i18n_yaml.py
+ delete mode 100644 bin/i18n.yml
+
+diff --git a/bin/convert_i18n_yaml.py b/bin/convert_i18n_yaml.py
+deleted file mode 100755
+index d6a6713..0000000
+--- a/bin/convert_i18n_yaml.py
++++ /dev/null
+@@ -1,77 +0,0 @@
+-#!/usr/bin/env python
+-# -*- coding: UTF-8 -*-
+-# USAGE: convert_i18n_yaml.py [--data=i18n.yml] behave/i18n.py
+-"""
+-Generates I18N python module based on YAML description (i18n.yml).
+-
+-REQUIRES:
+-  * argparse
+-  * six
+-  * PyYAML
+-"""
+-
+-from __future__ import absolute_import, print_function
+-import argparse
+-import os.path
+-import six
+-import sys
+-import pprint
+-import yaml
+-
+-HERE = os.path.dirname(__file__)
+-NAME = os.path.basename(__file__)
+-__version__ = "1.0"
+-
+-def yaml_normalize(data):
+-    for part in data:
+-        keywords = data[part]
+-        for k in keywords:
+-            v = keywords[k]
+-            # bloody YAML parser returns a mixture of unicode and str
+-            if not isinstance(v, six.text_type):
+-                v = v.decode("UTF-8")
+-            keywords[k] = v.split("|")
+-    return data
+-
+-def main(args=None):
+-    if args is None:
+-        args = sys.argv[1:]
+-    parser = argparse.ArgumentParser(prog=NAME,
+-                description="Generate python module i18n from YAML based data")
+-    parser.add_argument("-d", "--data", dest="yaml_file",
+-                default=os.path.join(HERE, "i18n.yml"),
+-                help="Path to i18n.yml file (YAML file).")
+-    parser.add_argument("output_file", default="stdout",
+-                help="Filename of Python I18N module (as output).")
+-    parser.add_argument("--version", action="version", version=__version__)
+-
+-    options = parser.parse_args(args)
+-    if not os.path.isfile(options.yaml_file):
+-        parser.error("YAML file not found: %s" % options.yaml_file)
+-
+-    # -- STEP 1: Load YAML data.
+-    languages = yaml.load(open(options.yaml_file))
+-    languages = yaml_normalize(languages)
+-
+-    # -- STEP 2: Generate python module with i18n data.
+-    contents = u"""# -*- coding: UTF-8 -*-
+-# -- FILE GENERATED BY: convert_i18n_yaml.py with i18n.yml
+-# pylint: disable=line-too-long
+-
+-languages = \\
+-"""
+-    if options.output_file in ("-", "stdout"):
+-        i18n_py = sys.stdout
+-        should_close = False
+-    else:
+-        i18n_py = open(options.output_file, "w")
+-        should_close = True
+-    i18n_py.write(contents.encode("UTF-8"))
+-    i18n_py.write(pprint.pformat(languages).encode("UTF-8"))
+-    i18n_py.write(u"\n")
+-    if should_close:
+-        i18n_py.close()
+-    return 0
+-
+-if __name__ == "__main__":
+-    sys.exit(main())
+diff --git a/bin/i18n.yml b/bin/i18n.yml
+deleted file mode 100644
+index 82345a4..0000000
+--- a/bin/i18n.yml
++++ /dev/null
+@@ -1,635 +0,0 @@
+-# encoding: UTF-8
+-#
+-# We use ISO 639-1 (language) and ISO 3166 alpha-2 (region - if applicable):
+-# http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+-# http://en.wikipedia.org/wiki/ISO_3166-1
+-#
+-# If you want several aliases for a keyword, just separate them
+-# with a | character. The * is a step keyword alias for all translations.
+-#
+-# If you do *not* want a trailing space after a keyword, end it with a < character.
+-# (See Chinese for examples).
+-#
+-# This file copyright (c) 2009-2011 Mike Sassak, Gregory Hnatiuk, Aslak Hellesøy
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining
+-# a copy of this software and associated documentation files (the
+-# "Software"), to deal in the Software without restriction, including
+-# without limitation the rights to use, copy, modify, merge, publish,
+-# distribute, sublicense, and/or sell copies of the Software, and to
+-# permit persons to whom the Software is furnished to do so, subject to
+-# the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be
+-# included in all copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+-
+-"en":
+-  name: English
+-  native: English
+-  feature: Feature
+-  background: Background
+-  scenario: Scenario
+-  scenario_outline: Scenario Outline|Scenario Template
+-  examples: Examples|Scenarios
+-  given: "*|Given"
+-  when: "*|When"
+-  then: "*|Then"
+-  and: "*|And"
+-  but: "*|But"
+-
+-# Please keep the grammars in alphabetical order by name from here and down.
+-
+-"ar":
+-  name: Arabic
+-  native: العربية
+-  feature: خاصية
+-  background: الخلفية
+-  scenario: سيناريو
+-  scenario_outline: سيناريو مخطط
+-  examples: امثلة
+-  given: "*|بفرض"
+-  when: "*|متى|عندما"
+-  then: "*|اذاً|ثم"
+-  and: "*|و"
+-  but: "*|لكن"
+-"bg":
+-  name: Bulgarian
+-  native: български
+-  feature: Функционалност
+-  background: Предистория
+-  scenario: Сценарий
+-  scenario_outline: Рамка на сценарий
+-  examples: Примери
+-  given: "*|Дадено"
+-  when: "*|Когато"
+-  then: "*|То"
+-  and: "*|И"
+-  but: "*|Но"
+-"ca":
+-  name: Catalan
+-  native: català
+-  background: Rerefons|Antecedents
+-  feature: Característica|Funcionalitat
+-  scenario: Escenari
+-  scenario_outline: Esquema de l'escenari
+-  examples: Exemples
+-  given: "*|Donat|Donada|Atès|Atesa"
+-  when: "*|Quan"
+-  then: "*|Aleshores|Cal"
+-  and: "*|I"
+-  but: "*|Però"
+-"cy-GB":
+-  name: Welsh
+-  native: Cymraeg
+-  background: Cefndir
+-  feature: Arwedd
+-  scenario: Scenario
+-  scenario_outline: Scenario Amlinellol
+-  examples: Enghreifftiau
+-  given: "*|Anrhegedig a"
+-  when: "*|Pryd"
+-  then: "*|Yna"
+-  and: "*|A"
+-  but: "*|Ond"
+-"cs":
+-  name: Czech
+-  native: Česky
+-  feature: Požadavek
+-  background: Pozadí|Kontext
+-  scenario: Scénář
+-  scenario_outline: Náčrt Scénáře|Osnova scénáře
+-  examples: Příklady
+-  given: "*|Pokud|Za předpokladu"
+-  when: "*|Když"
+-  then: "*|Pak"
+-  and: "*|A|A také"
+-  but: "*|Ale"
+-"da":
+-  name: Danish
+-  native: dansk
+-  feature: Egenskab
+-  background: Baggrund
+-  scenario: Scenarie
+-  scenario_outline: Abstrakt Scenario
+-  examples: Eksempler
+-  given: "*|Givet"
+-  when: "*|Når"
+-  then: "*|Så"
+-  and: "*|Og"
+-  but: "*|Men"
+-"de":
+-  name: German
+-  native: Deutsch
+-  feature: Funktionalität
+-  background: Grundlage
+-  scenario: Szenario
+-  scenario_outline: Szenariogrundriss
+-  examples: Beispiele
+-  given: "*|Angenommen|Gegeben sei"
+-  when: "*|Wenn"
+-  then: "*|Dann"
+-  and: "*|Und"
+-  but: "*|Aber"
+-"en-au":
+-  name: Australian
+-  native: Australian
+-  feature: Crikey
+-  background: Background
+-  scenario: Mate
+-  scenario_outline: Blokes
+-  examples: Cobber
+-  given: "*|Ya know how"
+-  when: "*|When"
+-  then: "*|Ya gotta"
+-  and: "*|N"
+-  but: "*|Cept"
+-"en-lol":
+-  name: LOLCAT
+-  native: LOLCAT
+-  feature: OH HAI
+-  background: B4
+-  scenario: MISHUN
+-  scenario_outline: MISHUN SRSLY
+-  examples: EXAMPLZ
+-  given: "*|I CAN HAZ"
+-  when: "*|WEN"
+-  then: "*|DEN"
+-  and: "*|AN"
+-  but: "*|BUT"
+-"en-pirate":
+-  name: Pirate
+-  native: Pirate
+-  feature: Ahoy matey!
+-  background: Yo-ho-ho
+-  scenario: Heave to
+-  scenario_outline: Shiver me timbers
+-  examples: Dead men tell no tales
+-  given: "*|Gangway!"
+-  when: "*|Blimey!"
+-  then: "*|Let go and haul"
+-  and: "*|Aye"
+-  but: "*|Avast!"
+-"en-Scouse":
+-  name: Scouse
+-  native: Scouse
+-  feature: Feature
+-  background: "Dis is what went down"
+-  scenario: "The thing of it is"
+-  scenario_outline: "Wharrimean is"
+-  examples: Examples
+-  given: "*|Givun|Youse know when youse got"
+-  when: "*|Wun|Youse know like when"
+-  then: "*|Dun|Den youse gotta"
+-  and: "*|An"
+-  but: "*|Buh"
+-"en-tx":
+-  name: Texan
+-  native: Texan
+-  feature: Feature
+-  background: Background
+-  scenario: Scenario
+-  scenario_outline: All y'all
+-  examples: Examples
+-  given: "*|Given y'all"
+-  when: "*|When y'all"
+-  then: "*|Then y'all"
+-  and: "*|And y'all"
+-  but: "*|But y'all"
+-"eo":
+-  name: Esperanto
+-  native: Esperanto
+-  feature: Trajto
+-  background: Fono
+-  scenario: Scenaro
+-  scenario_outline: Konturo de la scenaro
+-  examples: Ekzemploj
+-  given: "*|Donitaĵo"
+-  when: "*|Se"
+-  then: "*|Do"
+-  and: "*|Kaj"
+-  but: "*|Sed"
+-"es":
+-  name: Spanish
+-  native: español
+-  background: Antecedentes
+-  feature: Característica
+-  scenario: Escenario
+-  scenario_outline: Esquema del escenario
+-  examples: Ejemplos
+-  given: "*|Dado|Dada|Dados|Dadas"
+-  when: "*|Cuando"
+-  then: "*|Entonces"
+-  and: "*|Y"
+-  but: "*|Pero"
+-"et":
+-  name: Estonian
+-  native: eesti keel
+-  feature: Omadus
+-  background: Taust
+-  scenario: Stsenaarium
+-  scenario_outline: Raamstsenaarium
+-  examples: Juhtumid
+-  given: "*|Eeldades"
+-  when: "*|Kui"
+-  then: "*|Siis"
+-  and: "*|Ja"
+-  but: "*|Kuid"
+-"fi":
+-  name: Finnish
+-  native: suomi
+-  feature: Ominaisuus
+-  background: Tausta
+-  scenario: Tapaus
+-  scenario_outline: Tapausaihio
+-  examples: Tapaukset
+-  given: "*|Oletetaan"
+-  when: "*|Kun"
+-  then: "*|Niin"
+-  and: "*|Ja"
+-  but: "*|Mutta"
+-"fr":
+-  name: French
+-  native: français
+-  feature: Fonctionnalité
+-  background: Contexte
+-  scenario: Scénario
+-  scenario_outline: Plan du scénario|Plan du Scénario
+-  examples: Exemples
+-  given: "*|Soit|Etant donné|Etant donnée|Etant donnés|Etant données|Étant donné|Étant donnée|Étant donnés|Étant données"
+-  when: "*|Quand|Lorsque|Lorsqu'<"
+-  then: "*|Alors"
+-  and: "*|Et"
+-  but: "*|Mais"
+-"gl":
+-  name: Galician
+-  native: galego
+-  feature: Característica
+-  background: Contexto
+-  scenario: Escenario
+-  scenario_outline: "Esbozo do escenario"
+-  examples: Exemplos
+-  given: "*|Dado|Dada|Dados|Dadas"
+-  when: "*|Cando"
+-  then: "*|Entón|Logo"
+-  and: "*|E"
+-  but: "*|Mais|Pero"
+-
+-"he":
+-  name: Hebrew
+-  native: עברית
+-  feature: תכונה
+-  background: רקע
+-  scenario: תרחיש
+-  scenario_outline: תבנית תרחיש
+-  examples: דוגמאות
+-  given: "*|בהינתן"
+-  when: "*|כאשר"
+-  then: "*|אז|אזי"
+-  and: "*|וגם"
+-  but: "*|אבל"
+-"hr":
+-  name: Croatian
+-  native: hrvatski
+-  feature: Osobina|Mogućnost|Mogucnost
+-  background: Pozadina
+-  scenario: Scenarij
+-  scenario_outline: Skica|Koncept
+-  examples: Primjeri|Scenariji
+-  given: "*|Zadan|Zadani|Zadano"
+-  when: "*|Kada|Kad"
+-  then: "*|Onda"
+-  and: "*|I"
+-  but: "*|Ali"
+-"hu":
+-  name: Hungarian
+-  native: magyar
+-  feature: Jellemző
+-  background: Háttér
+-  scenario: Forgatókönyv
+-  scenario_outline: Forgatókönyv vázlat
+-  examples: Példák
+-  given: "*|Amennyiben|Adott"
+-  when: "*|Majd|Ha|Amikor"
+-  then: "*|Akkor"
+-  and: "*|És"
+-  but: "*|De"
+-"id":
+-  name: Indonesian
+-  native: Bahasa Indonesia
+-  feature: Fitur
+-  background: Dasar
+-  scenario: Skenario
+-  scenario_outline: Skenario konsep
+-  examples: Contoh
+-  given: "*|Dengan"
+-  when: "*|Ketika"
+-  then: "*|Maka"
+-  and: "*|Dan"
+-  but: "*|Tapi"
+-"is":
+-  name: Icelandic
+-  native: Íslenska
+-  feature: Eiginleiki
+-  background: Bakgrunnur
+-  scenario: Atburðarás
+-  scenario_outline: Lýsing Atburðarásar|Lýsing Dæma
+-  examples: Dæmi|Atburðarásir
+-  given: "*|Ef"
+-  when: "*|Þegar"
+-  then: "*|Þá"
+-  and: "*|Og"
+-  but: "*|En"
+-"it":
+-  name: Italian
+-  native: italiano
+-  feature: Funzionalità
+-  background: Contesto
+-  scenario: Scenario
+-  scenario_outline: Schema dello scenario
+-  examples: Esempi
+-  given: "*|Dato|Data|Dati|Date"
+-  when: "*|Quando"
+-  then: "*|Allora"
+-  and: "*|E"
+-  but: "*|Ma"
+-"ja":
+-  name: Japanese
+-  native: 日本語
+-  feature: フィーチャ|機能
+-  background: 背景
+-  scenario: シナリオ
+-  scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
+-  examples: 例|サンプル
+-  given: "*|前提<"
+-  when: "*|もし<"
+-  then: "*|ならば<"
+-  and: "*|かつ<"
+-  but: "*|しかし<|但し<|ただし<"
+-"ko":
+-  name: Korean
+-  native: 한국어
+-  background: 배경
+-  feature: 기능
+-  scenario: 시나리오
+-  scenario_outline: 시나리오 개요
+-  examples: 예
+-  given: "*|조건<|먼저<"
+-  when: "*|만일<|만약<"
+-  then: "*|그러면<"
+-  and: "*|그리고<"
+-  but: "*|하지만<|단<"
+-"lt":
+-  name: Lithuanian
+-  native: lietuvių kalba
+-  feature: Savybė
+-  background: Kontekstas
+-  scenario: Scenarijus
+-  scenario_outline: Scenarijaus šablonas
+-  examples: Pavyzdžiai|Scenarijai|Variantai
+-  given: "*|Duota"
+-  when: "*|Kai"
+-  then: "*|Tada"
+-  and: "*|Ir"
+-  but: "*|Bet"
+-"lu":
+-  name: Luxemburgish
+-  native: Lëtzebuergesch
+-  feature: Funktionalitéit
+-  background: Hannergrond
+-  scenario: Szenario
+-  scenario_outline: Plang vum Szenario
+-  examples: Beispiller
+-  given: "*|ugeholl"
+-  when: "*|wann"
+-  then: "*|dann"
+-  and: "*|an|a"
+-  but: "*|awer|mä"
+-"lv":
+-  name: Latvian
+-  native: latviešu
+-  feature: Funkcionalitāte|Fīča
+-  background: Konteksts|Situācija
+-  scenario: Scenārijs
+-  scenario_outline: Scenārijs pēc parauga
+-  examples: Piemēri|Paraugs
+-  given: "*|Kad"
+-  when: "*|Ja"
+-  then: "*|Tad"
+-  and: "*|Un"
+-  but: "*|Bet"
+-"nl":
+-  name: Dutch
+-  native: Nederlands
+-  feature: Functionaliteit
+-  background: Achtergrond
+-  scenario: Scenario
+-  scenario_outline: Abstract Scenario
+-  examples: Voorbeelden
+-  given: "*|Gegeven|Stel"
+-  when: "*|Als"
+-  then: "*|Dan"
+-  and: "*|En"
+-  but: "*|Maar"
+-"no":
+-  name: Norwegian
+-  native: norsk
+-  feature: Egenskap
+-  background: Bakgrunn
+-  scenario: Scenario
+-  scenario_outline: Scenariomal|Abstrakt Scenario
+-  examples: Eksempler
+-  given: "*|Gitt"
+-  when: "*|Når"
+-  then: "*|Så"
+-  and: "*|Og"
+-  but: "*|Men"
+-"pl":
+-  name: Polish
+-  native: polski
+-  feature: Właściwość
+-  background: Założenia
+-  scenario: Scenariusz
+-  scenario_outline: Szablon scenariusza
+-  examples: Przykłady
+-  given: "*|Zakładając|Mając"
+-  when: "*|Jeżeli|Jeśli"
+-  then: "*|Wtedy"
+-  and: "*|Oraz|I"
+-  but: "*|Ale"
+-"pt":
+-  name: Portuguese
+-  native: português
+-  background: Contexto
+-  feature: Funcionalidade
+-  scenario: Cenário|Cenario
+-  scenario_outline: Esquema do Cenário|Esquema do Cenario
+-  examples: Exemplos
+-  given: "*|Dado|Dada|Dados|Dadas"
+-  when: "*|Quando"
+-  then: "*|Então|Entao"
+-  and: "*|E"
+-  but: "*|Mas"
+-"ro":
+-  name: Romanian
+-  native: română
+-  background: Context
+-  feature: Functionalitate|Funcționalitate|Funcţionalitate
+-  scenario: Scenariu
+-  scenario_outline: Structura scenariu|Structură scenariu
+-  examples: Exemple
+-  given: "*|Date fiind|Dat fiind|Dati fiind|Dați fiind|Daţi fiind"
+-  when: "*|Cand|Când"
+-  then: "*|Atunci"
+-  and: "*|Si|Și|Şi"
+-  but: "*|Dar"
+-"ru":
+-  name: Russian
+-  native: русский
+-  feature: Функция|Функционал|Свойство
+-  background: Предыстория|Контекст
+-  scenario: Сценарий
+-  scenario_outline: Структура сценария
+-  examples: Примеры
+-  given: "*|Допустим|Дано|Пусть"
+-  when: "*|Если|Когда"
+-  then: "*|То|Тогда"
+-  and: "*|И|К тому же"
+-  but: "*|Но|А"
+-"sv":
+-  name: Swedish
+-  native: Svenska
+-  feature: Egenskap
+-  background: Bakgrund
+-  scenario: Scenario
+-  scenario_outline: Abstrakt Scenario|Scenariomall
+-  examples: Exempel
+-  given: "*|Givet"
+-  when: "*|När"
+-  then: "*|Så"
+-  and: "*|Och"
+-  but: "*|Men"
+-"sk":
+-  name: Slovak
+-  native: Slovensky
+-  feature: Požiadavka
+-  background: Pozadie
+-  scenario: Scenár
+-  scenario_outline: Náčrt Scenáru
+-  examples: Príklady
+-  given: "*|Pokiaľ"
+-  when: "*|Keď"
+-  then: "*|Tak"
+-  and: "*|A"
+-  but: "*|Ale"
+-"sr-Latn":
+-  name: Serbian (Latin)
+-  native: Srpski (Latinica)
+-  feature: Funkcionalnost|Mogućnost|Mogucnost|Osobina
+-  background: Kontekst|Osnova|Pozadina
+-  scenario: Scenario|Primer
+-  scenario_outline: Struktura scenarija|Skica|Koncept
+-  examples: Primeri|Scenariji
+-  given: "*|Zadato|Zadate|Zatati"
+-  when: "*|Kada|Kad"
+-  then: "*|Onda"
+-  and: "*|I"
+-  but: "*|Ali"
+-"sr-Cyrl":
+-  name: Serbian
+-  native: Српски
+-  feature: Функционалност|Могућност|Особина
+-  background: Контекст|Основа|Позадина
+-  scenario: Сценарио|Пример
+-  scenario_outline: Структура сценарија|Скица|Концепт
+-  examples: Примери|Сценарији
+-  given: "*|Задато|Задате|Задати"
+-  when: "*|Када|Кад"
+-  then: "*|Онда"
+-  and: "*|И"
+-  but: "*|Али"
+-"tr":
+-  name: Turkish
+-  native: Türkçe
+-  feature: Özellik
+-  background: Geçmiş
+-  scenario: Senaryo
+-  scenario_outline: Senaryo taslağı
+-  examples: Örnekler
+-  given: "*|Diyelim ki"
+-  when: "*|Eğer ki"
+-  then: "*|O zaman"
+-  and: "*|Ve"
+-  but: "*|Fakat|Ama"
+-"uk":
+-  name: Ukrainian
+-  native: Українська
+-  feature: Функціонал
+-  background: Передумова
+-  scenario: Сценарій
+-  scenario_outline: Структура сценарію
+-  examples: Приклади
+-  given: "*|Припустимо|Припустимо, що|Нехай|Дано"
+-  when: "*|Якщо|Коли"
+-  then: "*|То|Тоді"
+-  and: "*|І|А також|Та"
+-  but: "*|Але"
+-"uz":
+-  name: Uzbek
+-  native: Узбекча
+-  feature: Функционал
+-  background: Тарих
+-  scenario: Сценарий
+-  scenario_outline: Сценарий структураси
+-  examples: Мисоллар
+-  given: "*|Агар"
+-  when: "*|Агар"
+-  then: "*|Унда"
+-  and: "*|Ва"
+-  but: "*|Лекин|Бирок|Аммо"
+-"vi":
+-  name: Vietnamese
+-  native: Tiếng Việt
+-  feature: Tính năng
+-  background: Bối cảnh
+-  scenario: Tình huống|Kịch bản
+-  scenario_outline: Khung tình huống|Khung kịch bản
+-  examples: Dữ liệu
+-  given: "*|Biết|Cho"
+-  when: "*|Khi"
+-  then: "*|Thì"
+-  and: "*|Và"
+-  but: "*|Nhưng"
+-"zh-CN":
+-  name: Chinese simplified
+-  native: 简体中文
+-  feature: 功能
+-  background: 背景
+-  scenario: 场景
+-  scenario_outline: 场景大纲
+-  examples: 例子
+-  given: "*|假如<"
+-  when: "*|当<"
+-  then: "*|那么<"
+-  and: "*|而且<"
+-  but: "*|但是<"
+-"zh-TW":
+-  name: Chinese traditional
+-  native: 繁體中文
+-  feature: 功能
+-  background: 背景
+-  scenario: 場景|劇本
+-  scenario_outline: 場景大綱|劇本大綱
+-  examples: 例子
+-  given: "*|假設<"
+-  when: "*|當<"
+-  then: "*|那麼<"
+-  and: "*|而且<|並且<"
+-  but: "*|但是<"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch b/meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch
new file mode 100644
index 000000000..b5bac22cf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch
@@ -0,0 +1,155 @@
+From 65ec9d5d69251746a2723f7d2455c23166f3d1a9 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:22:21 +0200
+Subject: [PATCH] more.features: Perform more Gherkin v6 checks and run
+ examples.
+
+---
+ invoke.yaml                                   | 10 ++---
+ more.features/environment.py                  | 28 +++++++++++++
+ .../formatter.json.validate_output.feature    | 22 +++++++++-
+ more.features/run_examples.feature            | 41 +++++++++++++++++++
+ 4 files changed, 93 insertions(+), 8 deletions(-)
+ create mode 100644 more.features/environment.py
+ create mode 100644 more.features/run_examples.feature
+
+diff --git a/invoke.yaml b/invoke.yaml
+index d6f141c..a32345e 100644
+--- a/invoke.yaml
++++ b/invoke.yaml
+@@ -24,13 +24,6 @@ sphinx:
+       - de
+       # PREPARED: - zh-CN
+ 
+-cleanup:
+-    extra_directories:
+-      - "build"
+-      - "dist"
+-      - "__WORKDIR__"
+-      - reports
+-
+ cleanup:
+     extra_directories:
+       - "build"
+@@ -47,6 +40,9 @@ cleanup_all:
+       - .hypothesis
+       - .pytest_cache
+ 
++    extra_files:
++      - "**/testrun*.json"
++
+ behave_test:
+     scopes:
+       - features
+diff --git a/more.features/environment.py b/more.features/environment.py
+new file mode 100644
+index 0000000..9d4302b
+--- /dev/null
++++ b/more.features/environment.py
+@@ -0,0 +1,28 @@
++# -*- coding: UTF-8 -*-
++
++from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
++import sys
++
++# -- MATCHES ANY TAGS: @use.with_{category}={value}
++# NOTE: active_tag_value_provider provides category values for active tags.
++python_version = "%s.%s" % sys.version_info[:2]
++active_tag_value_provider = {
++    "python.version": python_version,
++}
++active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
++
++# -----------------------------------------------------------------------------
++# HOOKS:
++# -----------------------------------------------------------------------------
++def before_all(context):
++    # -- SETUP ACTIVE-TAG MATCHER (with userdata):
++    setup_active_tag_values(active_tag_value_provider, context.config.userdata)
++
++def before_feature(context, feature):
++    if active_tag_matcher.should_exclude_with(feature.tags):
++        feature.skip(reason=active_tag_matcher.exclude_reason)
++
++def before_scenario(context, scenario):
++    if active_tag_matcher.should_exclude_with(scenario.effective_tags):
++        scenario.skip(reason=active_tag_matcher.exclude_reason)
++
+diff --git a/more.features/formatter.json.validate_output.feature b/more.features/formatter.json.validate_output.feature
+index a5f8ab6..31550d5 100644
+--- a/more.features/formatter.json.validate_output.feature
++++ b/more.features/formatter.json.validate_output.feature
+@@ -34,4 +34,24 @@ Feature: Validate JSON Formatter Output
+     Then it should pass with:
+         """
+         validate: testrun3.json ... OK
+-        """
+\ No newline at end of file
++        """
++
++  @gherkin_v6
++  Scenario: Validate JSON output from example/gherkin_v6/ test run
++    Given I use the directory "examples/gherkin_v6" as working directory
++    When I run "behave -f json -o testrun_gherkin6_1.json features/"
++    When I run "../../bin/jsonschema_validate.py testrun_gherkin6_1.json"
++    Then it should pass with:
++        """
++        validate: testrun_gherkin6_1.json ... OK
++        """
++
++  @gherkin_v6
++  Scenario: Validate JSON output from example/gherkin_v6/ test run (case: partly failing)
++    Given I use the directory "examples/gherkin_v6" as working directory
++    When I run "behave --tags=fail -f json -o testrun_gherkin6_2.json features/"
++    When I run "../../bin/jsonschema_validate.py testrun_gherkin6_2.json"
++    Then it should pass with:
++        """
++        validate: testrun_gherkin6_2.json ... OK
++        """
+diff --git a/more.features/run_examples.feature b/more.features/run_examples.feature
+new file mode 100644
+index 0000000..4778866
+--- /dev/null
++++ b/more.features/run_examples.feature
+@@ -0,0 +1,41 @@
++Feature: Ensure that all examples are usable
++
++  Scenario Outline: Use <example_dir>
++    Given I use the directory "<example_dir>" as working directory
++    When I run "behave <behave_cmdline>"
++    Then it should <outcome>
++
++    Examples:
++      | example_dir         | behave_cmdline        | outcome |
++      | examples/env_vars   | features/             | pass    |
++      | examples/fixture.no_background | features/  | pass    |
++      | examples/gherkin_v6 | features/             | pass    |
++
++
++  Scenario: examples/gherkin_v6 -- @xfail parts
++    Given I use the directory "examples/gherkin_v6" as working directory
++    When I run "behave --tags=fail features/"
++    Then it should fail with:
++      """
++      0 features passed, 1 failed, 2 skipped
++      0 rules passed, 1 failed, 6 skipped
++      1 scenario passed, 2 failed, 12 skipped
++      2 steps passed, 2 failed, 39 skipped, 0 undefined
++      """
++    And the command output should contain:
++      """
++      Failing scenarios:
++        features/rule_fails.feature:7  F0 -- Fails
++        features/rule_fails.feature:16  F2 -- Fails
++      """
++
++
++  @use.with_python.version=3.4
++  @use.with_python.version=3.5
++  @use.with_python.version=3.6
++  @use.with_python.version=3.7
++  @use.with_python.version=3.8
++  Scenario: examples/async_step (needs: py34 or newer)
++    Given I use the directory "examples/async_step" as working directory
++    When I run "behave features/"
++    Then it should pass
diff --git a/meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch b/meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch
new file mode 100644
index 000000000..79718261c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch
@@ -0,0 +1,72 @@
+From da0a88f5311e4181a9c24a5853f6392209dceabe Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:39:49 +0200
+Subject: [PATCH] UTIL: Correct URL and python module (old was broken, no
+ longer exists).
+
+---
+ bin/behave2cucumber_json.py | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/bin/behave2cucumber_json.py b/bin/behave2cucumber_json.py
+index 738e444..541061e 100755
+--- a/bin/behave2cucumber_json.py
++++ b/bin/behave2cucumber_json.py
+@@ -3,9 +3,10 @@
+ # CONVERT: behave JSON dialect to cucumber JSON dialect
+ # =============================================================================
+ # STATUS: __PROTOTYPE__
+-# REQUIRES: Python >= 2.6
+-# REQUIRES: https://github.com/behalfinc/b2c/
+-# SEE: https://github.com/behave/behave/issues/267#issuecomment-249607191
++# REQUIRES: Python >= 2.7
++# REQUIRES: https://github.com/behalf-oss/behave2cucumber
++# SEE:
++# * https://github.com/behave/behave/issues/267#issuecomment-251746565
+ # =============================================================================
+ """
+ Convert a file with behave JSON data into a file with cucumber JSON data.
+@@ -17,15 +18,16 @@ import json
+ import sys
+ import os.path
+ try:
+-    import b2c
++    import behave2cucumber
+ except ImportError:
+-    print("REQUIRE: https://github.com/behalfinc/b2c/  (not installed yet)")
+-    print("INSTALL: pip install b2c")
++    print("REQUIRE: https://github.com/behalf-oss/behave2cucumber (not installed yet)")
++    print("INSTALL: pip install behave2cucumber")
+     sys.exit(2)
+ 
+ 
+ NAME = os.path.basename(__file__)
+ 
++
+ def convert_behave_to_cucumber_json(behave_filename, cucumber_filename,
+                                     encoding="UTF-8", pretty=True):
+     """Convert behave JSON dialect into cucumber JSON dialect.
+@@ -39,12 +41,14 @@ def convert_behave_to_cucumber_json(behave_filename, cucumber_filename,
+ 
+     with open(behave_filename, "r") as behave_json:
+         with open(cucumber_filename, "w+") as output_file:
+-            cucumber_json = b2c.convert(json.load(behave_json, encoding))
++            behave_json = json.load(behave_json, encoding)
++            cucumber_json = behave2cucumber.convert(behave_json)
+             # cucumber_text = json.dumps(cucumber_json, **dump_kwargs)
+             # output_file.write(cucumber_text)
+             json.dump(cucumber_json, output_file, **dump_kwargs)
+     return 0
+ 
++
+ def main(args=None):
+     """Main function to run the script."""
+     if args is None:
+@@ -58,6 +62,7 @@ def main(args=None):
+     cucumber_filename = args[1]
+     return convert_behave_to_cucumber_json(behave_filename, cucumber_filename)
+ 
++
+ # -- AUTO-MAIN:
+ if __name__ == "__main__":
+     sys.exit(main())
diff --git a/meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch
new file mode 100644
index 000000000..4b708fa94
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0058-UTIL-Formatting-tweaks.patch
@@ -0,0 +1,22 @@
+From 709d7c3604cc8f958dbd6360c66cabf612419c99 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 13 Jul 2019 13:40:46 +0200
+Subject: [PATCH] UTIL: Formatting tweaks.
+
+---
+ bin/behave2cucumber_json.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bin/behave2cucumber_json.py b/bin/behave2cucumber_json.py
+index 541061e..893a5ef 100755
+--- a/bin/behave2cucumber_json.py
++++ b/bin/behave2cucumber_json.py
+@@ -20,7 +20,7 @@ import os.path
+ try:
+     import behave2cucumber
+ except ImportError:
+-    print("REQUIRE: https://github.com/behalf-oss/behave2cucumber (not installed yet)")
++    print("REQUIRE: https://github.com/behalf-oss/behave2cucumber")
+     print("INSTALL: pip install behave2cucumber")
+     sys.exit(2)
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch b/meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch
new file mode 100644
index 000000000..ff0a4238f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch
@@ -0,0 +1,23 @@
+From c507804a610e09aaabe7c5da7665857ce7947736 Mon Sep 17 00:00:00 2001
+From: Jon-Pierre Gentil <jgentil@sebistar.net>
+Date: Thu, 1 Aug 2019 11:21:36 -0500
+Subject: [PATCH] Fixed a bug where use_fixture_by_tag didn't return the actual
+ fixture if the registry entry was just a direct function.
+
+---
+ behave/fixture.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/behave/fixture.py b/behave/fixture.py
+index 3a9f1bc..51e18bf 100644
+--- a/behave/fixture.py
++++ b/behave/fixture.py
+@@ -272,7 +272,7 @@ def use_fixture_by_tag(tag, context, fixture_registry):
+ 
+     if callable(fixture_data):
+         fixture_func = fixture_data
+-        use_fixture(fixture_func, context)
++        return use_fixture(fixture_func, context)
+     elif isinstance(fixture_data, (tuple, list)):
+         assert len(fixture_data) == 3
+         fixture_func, fixture_args, fixture_kwargs = fixture_data
diff --git a/meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch b/meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch
new file mode 100644
index 000000000..b35ba1448
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0060-Added-issue-unit-test.patch
@@ -0,0 +1,62 @@
+From ee4784efbbf1cbd18390e2dd36f61dee1b003858 Mon Sep 17 00:00:00 2001
+From: Jon-Pierre Gentil <jgentil@sebistar.net>
+Date: Thu, 1 Aug 2019 11:48:08 -0500
+Subject: [PATCH] Added issue unit test
+
+---
+ tests/issues/test_issue0767.py | 46 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+ create mode 100644 tests/issues/test_issue0767.py
+
+diff --git a/tests/issues/test_issue0767.py b/tests/issues/test_issue0767.py
+new file mode 100644
+index 0000000..1de3589
+--- /dev/null
++++ b/tests/issues/test_issue0767.py
+@@ -0,0 +1,46 @@
++"""
++https://github.com/behave/behave/issues/767
++
++When trying to do something like::
++
++    fixture_registry = {'fixture.foo': foo_fixture}
++    f = use_fixture_by_tag('fixture.foo', context, fixture_registry)
++
++Behave returns nothing. ::
++
++    repr(f)
++    'None'
++
++This seems to be an oversight.
++"""
++
++from mock import Mock
++
++def test_issue_767_use_feature_by_tag_has_no_return():
++    """Verifies that issue #767 is fixed."""
++    from behave.fixture import fixture, use_fixture_by_tag
++    from behave.runner import Context
++
++    @fixture(name='fixture.foo')
++    def foo_fixture(context, *args, **kwargs):
++        context.foo = 'foo'
++        return context.foo
++
++    # -- SCHEMA 1: fixture_func
++    fixture_registry1 = {
++        "fixture.foo": foo_fixture
++    }
++    # -- SCHEMA 2: fixture_func, fixture_args, fixture_kwargs
++    fixture_registry2 = {
++        "fixture.foo": (foo_fixture, (), {})
++    }
++
++    context = Context(runner=Mock())
++    f1 = use_fixture_by_tag('fixture.foo', context, fixture_registry1)
++    assert f1 == 'foo'
++    assert context.foo is f1
++
++    context = Context(runner=Mock())
++    f2 = use_fixture_by_tag('fixture.foo', context, fixture_registry2)
++    assert f2 == 'foo'
++    assert context.foo is f2
diff --git a/meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch b/meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch
new file mode 100644
index 000000000..b59ebabe1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0061-Merge-pull-request-767-with-minor-tweaks.patch
@@ -0,0 +1,60 @@
+From 2c3c2a4217d033c3f7157046765e0888bde3bfbd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 7 Aug 2019 23:14:59 +0200
+Subject: [PATCH] Merge pull-request #767 with minor tweaks. FIX:
+ use_fixture_by_tag didn't return the actual fixture in all cases.
+
+---
+ CHANGES.rst                    |  1 +
+ tests/issues/test_issue0767.py | 17 +++++++++--------
+ 2 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 15a4ef9..7a9163f 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -43,6 +43,7 @@ FIXED:
+ 
+ MINOR:
+ 
++* pull  #767: FIX: use_fixture_by_tag didn't return the actual fixture in all cases (provided by: jgentil)
+ * pull  #751: gherkin: Adding Rule keyword translation in portuguese and spanish to gherkin-languages.json (provided by: dunossauro)
+ * pull  #660: Fix minor typos (provided by: rrueth)
+ * pull  #655: Use pytest instead of py.test per upstream recommendation (provided by: scop)
+diff --git a/tests/issues/test_issue0767.py b/tests/issues/test_issue0767.py
+index 1de3589..401dbd0 100644
+--- a/tests/issues/test_issue0767.py
++++ b/tests/issues/test_issue0767.py
+@@ -15,11 +15,12 @@ This seems to be an oversight.
+ """
+ 
+ from mock import Mock
++from behave.fixture import fixture, use_fixture_by_tag
++from behave.runner import Context
++
+ 
+ def test_issue_767_use_feature_by_tag_has_no_return():
+     """Verifies that issue #767 is fixed."""
+-    from behave.fixture import fixture, use_fixture_by_tag
+-    from behave.runner import Context
+ 
+     @fixture(name='fixture.foo')
+     def foo_fixture(context, *args, **kwargs):
+@@ -36,11 +37,11 @@ def test_issue_767_use_feature_by_tag_has_no_return():
+     }
+ 
+     context = Context(runner=Mock())
+-    f1 = use_fixture_by_tag('fixture.foo', context, fixture_registry1)
+-    assert f1 == 'foo'
+-    assert context.foo is f1
++    fixture1 = use_fixture_by_tag("fixture.foo", context, fixture_registry1)
++    assert fixture1 == "foo"
++    assert context.foo is fixture1
+ 
+     context = Context(runner=Mock())
+-    f2 = use_fixture_by_tag('fixture.foo', context, fixture_registry2)
+-    assert f2 == 'foo'
+-    assert context.foo is f2
++    fixture2 = use_fixture_by_tag("fixture.foo", context, fixture_registry2)
++    assert fixture2 == "foo"
++    assert context.foo is fixture2
diff --git a/meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch b/meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch
new file mode 100644
index 000000000..0b8f63408
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch
@@ -0,0 +1,83 @@
+From 2034f2d33b24d43c9f0c120ace578ca53656fab6 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 7 Aug 2019 23:55:05 +0200
+Subject: [PATCH] CHECK: Issue #766 -- PrettyFormatter: UnicodeError
+
+---
+ issue.features/issue0766.feature        | 47 +++++++++++++++++++++++++
+ issue.features/steps/issue0766_steps.py | 12 +++++++
+ 2 files changed, 59 insertions(+)
+ create mode 100644 issue.features/issue0766.feature
+ create mode 100644 issue.features/steps/issue0766_steps.py
+
+diff --git a/issue.features/issue0766.feature b/issue.features/issue0766.feature
+new file mode 100644
+index 0000000..94d44d8
+--- /dev/null
++++ b/issue.features/issue0766.feature
+@@ -0,0 +1,47 @@
++@issue
++@not_reproducible
++Feature: Issue #766 -- UnicodeEncodeError in PrettyFormatter
++
++  Explore the described problem.
++
++  Scenario Outline:
++    Given a step with name="<name>"
++
++    Examples:
++      | name | value | comment |
++      | 😄   | 123   | Use emoticon (smiley) in a table |
++
++  Scenario:
++    Given a step with table data:
++      | name | value | comment |
++      | 😄   | 123   | Use emoticon (smiley) in a table |
++
++  Scenario: Explore problem by using the pretty formatter
++    Given a new working directory
++    And a file named "features/syndrome_766.feature" with:
++      """
++      Feature: Alice
++        Scenario Outline:
++          Given a step with name="<name>"
++
++          Examples:
++            | name | value | comment |
++            | 😄   | 123   | Use emoticon (smiley) in a table |
++      """
++    And a file named "features/steps/issue766_steps.py" with:
++      """
++      from behave import given
++
++      @given(u'a step with name="{name}"')
++      def step_with_table_data(ctx, name):
++          pass
++      """
++    When I run "behave -f pretty features/syndrome_766.feature"
++    Then it should pass with:
++      """
++      1 feature passed, 0 failed, 0 skipped
++      1 scenario passed, 0 failed, 0 skipped
++      1 step passed, 0 failed, 0 skipped, 0 undefine
++      """
++    And the command output should not contain "UnicodeEncodeError"
++    And the command output should not contain "Traceback"
+diff --git a/issue.features/steps/issue0766_steps.py b/issue.features/steps/issue0766_steps.py
+new file mode 100644
+index 0000000..33ed317
+--- /dev/null
++++ b/issue.features/steps/issue0766_steps.py
+@@ -0,0 +1,12 @@
++# -*- coding: UTF-8 -*-
++
++from __future__ import print_function
++from behave import given
++
++@given(u'a step with table data')
++def step_with_table_data(ctx):
++    assert ctx.table is not None, "REQUIRE: step.table"
++
++@given(u'a step with name="{name}"')
++def step_with_table_data(ctx, name):
++    print(u"name: {}".format(name))
diff --git a/meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch b/meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
new file mode 100644
index 000000000..ffa265eed
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
@@ -0,0 +1,74 @@
+From 82065e999bfc125461c2e3db17856bf5a1384443 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 22 Sep 2019 18:08:22 +0200
+Subject: [PATCH] FIX issue #772: ScenarioOutline.Examples without table.
+
+---
+ behave/model.py                  |  8 +++++++-
+ issue.features/issue0772.feature | 31 +++++++++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+), 1 deletion(-)
+ create mode 100644 issue.features/issue0772.feature
+
+diff --git a/behave/model.py b/behave/model.py
+index 69f38ab..f46d2c2 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -10,7 +10,7 @@ This module provides the model element class that represent a behave model:
+ * ...
+ """
+ 
+-from __future__ import absolute_import, with_statement
++from __future__ import absolute_import, with_statement, print_function
+ import copy
+ import difflib
+ import logging
+@@ -1355,6 +1355,12 @@ class ScenarioOutlineBuilder(object):
+             example.index = example_index+1
+             params["examples.name"] = example.name
+             params["examples.index"] = _text(example.index)
++            if not example.table:
++                # -- SYNDROME: Examples keyword without table
++                print("ERROR: ScenarioOutline.Examples: Has NO-TABLE syndrome ({0})"\
++                      .format(example.location))
++                continue
++
+             for row_index, row in enumerate(example.table):
+                 row.index = row_index+1
+                 row.id = "%d.%d" % (example.index, row.index)
+diff --git a/issue.features/issue0772.feature b/issue.features/issue0772.feature
+new file mode 100644
+index 0000000..eba0ea5
+--- /dev/null
++++ b/issue.features/issue0772.feature
+@@ -0,0 +1,31 @@
++@issue
++Feature: Issue #772 -- Syndrome: ScenarioOutline with Examples keyword w/o Table
++
++
++
++  Background: Setup
++    Given a new working directory
++    And a file named "features/syndrome_772.feature" with:
++      """
++      Feature: Examples without table
++
++        Scenario Outline:
++          Given a step passes
++          When another step passes
++
++          Examples: Without table
++      """
++    And a file named "features/steps/use_step_library.py" with:
++      """
++      # -- REUSE STEPS:
++      import behave4cmd0.passing_steps
++      """
++
++  Scenario: Use ScenarioOutline with Examples keyword without table
++    When I run "behave -f plain features/syndrome_772.feature"
++    Then it should pass with:
++      """
++      Feature: Examples without table
++      ERROR: ScenarioOutline.Examples: Has NO-TABLE syndrome (features/syndrome_772.feature:7)
++      """
++    And the command output should not contain "Parser failure in state"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch b/meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
new file mode 100644
index 000000000..243cb82d0
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch
@@ -0,0 +1,21 @@
+From 1d45845ffb9a30ca66806ba165bea54f7d43cd46 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 22 Sep 2019 18:09:50 +0200
+Subject: [PATCH] FIX issue #772: ScenarioOutline.Examples without table.
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 7a9163f..ba4daad 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -33,6 +33,7 @@ ENHANCEMENTS:
+ 
+ FIXED:
+ 
++* issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+ * issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+ * issue #713: Background section doesn't support description (provided by: dgou)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch b/meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch
new file mode 100644
index 000000000..683ed9275
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0065-Nibble-TravisCI-to-wake-up.patch
@@ -0,0 +1,21 @@
+From 5c181e07ca0fda2ea26cf8c8949dd8baaa2be953 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 11 Dec 2019 08:23:08 +0100
+Subject: [PATCH] Nibble TravisCI to wake up.
+
+---
+ .travis.yml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/.travis.yml b/.travis.yml
+index c6027e0..781a610 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -6,6 +6,7 @@ python:
+   - "3.7"
+   - "2.7"
+ 
++
+ # -- DISABLE-TEMPORARILY: Ensure faster builds
+ #  - "3.6"
+ #  - "3.5"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch b/meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch
new file mode 100644
index 000000000..143c178d0
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0066-Tweak-pytest-version-selection.patch
@@ -0,0 +1,37 @@
+From ba6f76873dadead64be57c215ba2f7eb40d0ea6d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 11 Dec 2019 08:30:11 +0100
+Subject: [PATCH] Tweak pytest version selection
+
+---
+ py.requirements/ci.travis.txt | 3 ++-
+ setup.py                      | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 73d65f6..5f31802 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,6 +1,7 @@
+ mock
+ PyHamcrest >= 1.9
+-pytest >= 3.0
++pytest <  5.0; python_version <  '3.0'
++pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+diff --git a/setup.py b/setup.py
+index 8de3ec0..75d6847 100644
+--- a/setup.py
++++ b/setup.py
+@@ -87,7 +87,8 @@ setup(
+         "colorama",
+     ],
+     tests_require=[
+-        "pytest >= 4.2",
++        "pytest <  5.0; python_version <  '3.0'", # >= 4.2
++        "pytest >= 5.0; python_version >= '3.0'",
+         "pytest-html >= 1.19.0",
+         "mock >= 1.1",
+         "PyHamcrest >= 1.9",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch b/meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch
new file mode 100644
index 000000000..f0e642634
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch
@@ -0,0 +1,37 @@
+From 7bd632e11a5ab75cec3e20722cf8fa3cebb1983f Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 11 Dec 2019 08:37:11 +0100
+Subject: [PATCH] Tweak pytest configuration to silence JUnit XML dialect
+ warning.
+
+---
+ pytest.ini | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/pytest.ini b/pytest.ini
+index ff2a8a2..228279c 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -16,9 +16,10 @@
+ # ============================================================================
+ 
+ [pytest]
+-minversion    = 2.8
++minversion    = 4.2
+ testpaths     = tests
+ python_files  = test_*.py
++junit_family = xunit2
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+     --metadata PACKAGE_VERSION 1.2.7.dev1
+     --html=build/testing/report.html --self-contained-html
+@@ -27,6 +28,10 @@ markers =
+     smoke
+     slow
+ 
++# -- PREPARED:
++# filterwarnings =
++#    ignore:.*invalid escape sequence.*:DeprecationWarning
++
+ # -- BACKWARD COMPATIBILITY: pytest < 2.8
+ # norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch b/meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch
new file mode 100644
index 000000000..97db40580
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch
@@ -0,0 +1,56 @@
+From 56c4ee34b403d69ed3c7092edee95ae6f3b6fd74 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 15:50:37 +0100
+Subject: [PATCH] Add basic feature-test for wildcard pattern-matching that is
+ supported by cucumber-tag-expressions (python-only).
+
+---
+ .../tags.tag_expression_v2.wildcards.feature  | 39 +++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+ create mode 100644 features/tags.tag_expression_v2.wildcards.feature
+
+diff --git a/features/tags.tag_expression_v2.wildcards.feature b/features/tags.tag_expression_v2.wildcards.feature
+new file mode 100644
+index 0000000..372a731
+--- /dev/null
++++ b/features/tags.tag_expression_v2.wildcards.feature
+@@ -0,0 +1,39 @@
++Feature: Tag Expression v2 Extension: Wildcards for tag matching
++
++  As a tester
++  I want to use a wildcard pattern to select tags following a naming scheme
++  So that it is simpler to select a subset of scenarios and features.
++
++  . SPECIFICATION: Wildcards in tag-expressions v2
++  .   * Use file-name matching wildcards (fnmatch): *, ?
++  .   * a tag expression is a boolean expression
++  .   * a tag expression supports the operators: and, or, not
++  .   * a tag expression supports '(' and ')' for grouping expressions
++  .
++  . EXAMPLES:
++  .   | Tag expression          | Comment |
++  .   | @foo.*                  | Matches any tags that start with "@foo." |
++  .   | not @foo.*              | Excludes any element that have tags that start with "@foo." |
++
++
++  Scenario: Select tags that match the "@foo.*" pattern
++    Given the tag expression "@foo.*"
++    Then the tag expression selects elements with tags:
++        | tags          | selected? |
++        |               |   no      |
++        | @foo          |   no      |
++        | @foo.one      |   yes     |
++        | @foo.two      |   yes     |
++        | @other        |   no      |
++        | @foo.3 @other |   yes     |
++
++  Scenario: Select tags that do not match the "@foo.*" pattern
++    Given the tag expression "not @foo.*"
++    Then the tag expression selects elements with tags:
++        | tags          | selected? |
++        |               |   yes     |
++        | @foo          |   yes     |
++        | @foo.one      |   no      |
++        | @foo.two      |   no      |
++        | @other        |   yes     |
++        | @foo.3 @other |   no      |
diff --git a/meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch b/meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch
new file mode 100644
index 000000000..1cdf70944
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0069-UPDATE-dependencies-path.py-path-pytest.patch
@@ -0,0 +1,141 @@
+From ff1f1e74f5f81eb634d72d472ce18f8d543bf3c0 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 20:12:14 +0100
+Subject: [PATCH] UPDATE: dependencies (path.py <=> path, pytest, ...)
+
+---
+ py.requirements/ci.tox.txt    |  8 ++++++--
+ py.requirements/ci.travis.txt | 11 ++++++++---
+ py.requirements/develop.txt   |  5 ++++-
+ py.requirements/testing.txt   |  7 +++++--
+ setup.py                      |  6 ++++--
+ tasks/py.requirements.txt     |  5 ++++-
+ 6 files changed, 31 insertions(+), 11 deletions(-)
+
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 6b3b3ae..4001bc2 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -2,8 +2,12 @@
+ # BEHAVE: PYTHON PACKAGE REQUIREMENTS: ci.tox.txt
+ # ============================================================================
+ 
+-pytest >= 4.2
++pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
++pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock >= 2.0
+ PyHamcrest >= 1.9
+-path.py >= 10.1
++
++# -- HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 5f31802..de4120a 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,12 +1,17 @@
+-mock
+-PyHamcrest >= 1.9
++# ============================================================================
++# PYTHON PACKAGE REQUIREMENTS FOR: behave -- ci.travis.txt
++# ============================================================================
+ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
++mock  >= 2.0
++PyHamcrest >= 1.9
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+-path.py >= 10.1
++# HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
+ 
+ # -- NOTE: Travis.CI tweak related w/ invalid linecache2 tests.
+ #    This problem does not exist if you use pip.
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index a16d7bf..a92ee5f 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -6,10 +6,13 @@
+ # PREPARE USAGE: invoke
+ # ALREADY: six >= 1.11.0
+ invoke >= 1.2.0
+-path.py >= 11.5.0
+ pathlib;    python_version <= '3.4'
+ pycmd
+ 
++# -- HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
++
+ # -- CONFIGURATION MANAGEMENT (helpers):
+ # FORMER: bumpversion >= 0.4.0
+ bump2version >= 0.5.6
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index a418739..85b0908 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -4,11 +4,14 @@
+ 
+ # -- TESTING: Unit tests and behave self-tests.
+ # PREPARED-FUTURE: behave4cmd0, behave4cmd
+-pytest >= 4.2
++pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
++pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+ PyHamcrest >= 1.9
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+-path.py >= 11.5.0
++# HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
+diff --git a/setup.py b/setup.py
+index 75d6847..2afc147 100644
+--- a/setup.py
++++ b/setup.py
+@@ -77,7 +77,7 @@ setup(
+     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*",
+     install_requires=[
+         "cucumber-tag-expressions >= 1.1.2",
+-        "parse >= 1.8.2",
++        "parse >= 1.9.1",
+         "parse_type >= 0.4.2",
+         "six >= 1.12.0",
+         "traceback2; python_version < '3.0'",
+@@ -92,7 +92,9 @@ setup(
+         "pytest-html >= 1.19.0",
+         "mock >= 1.1",
+         "PyHamcrest >= 1.9",
+-        "path.py >= 11.5.0"
++        # -- HINT: path.py => path (python-install-package was renamed for python3)
++        "path.py >= 11.5.0; python_version <  '3.5'",
++        "path >= 13.1.0;    python_version >= '3.5'",
+     ],
+     cmdclass = {
+         "behave_test": behave_test,
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index a77d3bc..810f834 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -9,10 +9,13 @@
+ # ============================================================================
+ 
+ invoke >= 1.2.0
+-path.py >= 11.5.0
+ pycmd
+ six >= 1.12.0
+ 
++# -- HINT: path.py => path (python-install-package was renamed for python3)
++path.py >= 11.5.0; python_version <  '3.5'
++path >= 13.1.0;    python_version >= '3.5'
++
+ # -- PYTHON2 BACKPORTS:
+ pathlib;    python_version <= '3.4'
+ backports.shutil_which; python_version <= '3.3'
diff --git a/meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch b/meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch
new file mode 100644
index 000000000..df5b0d372
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch
@@ -0,0 +1,25 @@
+From 451f88ab5d1ea7da9737ef701a4309963516f3c4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 20:16:43 +0100
+Subject: [PATCH] pytest: Disable DeprecatedWarning from distutils package.
+
+---
+ pytest.ini | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/pytest.ini b/pytest.ini
+index 228279c..b9f281a 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -29,8 +29,9 @@ markers =
+     slow
+ 
+ # -- PREPARED:
+-# filterwarnings =
+-#    ignore:.*invalid escape sequence.*:DeprecationWarning
++filterwarnings =
++   ignore:.*the imp module is deprecated in favour of importlib.*:DeprecationWarning
++#   ignore:.*invalid escape sequence.*:DeprecationWarning
+ 
+ # -- BACKWARD COMPATIBILITY: pytest < 2.8
+ # norecursedirs = .git .tox build dist py.requirements tmp* _WORKSPACE
diff --git a/meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch b/meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch
new file mode 100644
index 000000000..122a63af8
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch
@@ -0,0 +1,216 @@
+From 37fd19b56ba31634a34349d956120b6a5898e2d9 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:20:18 +0100
+Subject: [PATCH] CLEANUP: Add ContextMode enum related to #797
+
+Add ContextMode enum to cleanup weirdness related to issue #797.
+Pre-existing Context.BEHAVE/USER constants overshadowed user attributes
+in Context.attribute retrieval case.
+---
+ behave/runner.py          | 33 ++++++++++++++++++++++-----------
+ tests/unit/test_runner.py | 29 +++++++++++++++--------------
+ 2 files changed, 37 insertions(+), 25 deletions(-)
+
+diff --git a/behave/runner.py b/behave/runner.py
+index cbedb5a..bcf4ab2 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -21,6 +21,7 @@ from behave.runner_util import \
+     collect_feature_locations, parse_features, \
+     exec_file, load_step_modules, PathManager
+ from behave.step_registry import registry as the_step_registry
++from enum import Enum
+ 
+ if six.PY2:
+     # -- USE PYTHON3 BACKPORT: With unicode traceback support.
+@@ -45,6 +46,16 @@ class ContextMaskWarning(UserWarning):
+     pass
+ 
+ 
++class ContextMode(Enum):
++    """Used to distinguish between the two usage modes while using the context:
++
++    * BEHAVE: Indicates "behave" (internal) mode
++    * USER: Indicates "user" mode (in steps, hooks, fixtures, ...)
++    """
++    BEHAVE = 1
++    USER = 2
++
++
+ class Context(object):
+     """Hold contextual information during the running of tests.
+ 
+@@ -147,8 +158,8 @@ class Context(object):
+     .. _`configuration file section names`: behave.html#configuration-files
+     """
+     # pylint: disable=too-many-instance-attributes
+-    BEHAVE = "behave"
+-    USER = "user"
++    # BEHAVE = "behave"
++    # USER = "user"
+     FAIL_ON_CLEANUP_ERRORS = True
+ 
+     def __init__(self, runner):
+@@ -166,7 +177,7 @@ class Context(object):
+         self._stack = [d]
+         self._record = {}
+         self._origin = {}
+-        self._mode = self.BEHAVE
++        self._mode = ContextMode.BEHAVE
+ 
+         # -- MODEL ENTITY REFERENCES/SUPPORT:
+         self.feature = None
+@@ -260,11 +271,11 @@ class Context(object):
+ 
+     def _use_with_behave_mode(self):
+         """Provides a context manager for using the context in BEHAVE mode."""
+-        return use_context_with_mode(self, Context.BEHAVE)
++        return use_context_with_mode(self, ContextMode.BEHAVE)
+ 
+     def use_with_user_mode(self):
+         """Provides a context manager for using the context in USER mode."""
+-        return use_context_with_mode(self, Context.USER)
++        return use_context_with_mode(self, ContextMode.USER)
+ 
+     def user_mode(self):
+         warnings.warn("Use 'use_with_user_mode()' instead",
+@@ -291,11 +302,11 @@ class Context(object):
+ 
+     def _emit_warning(self, attr, params):
+         msg = ""
+-        if self._mode is self.BEHAVE and self._origin[attr] is not self.BEHAVE:
++        if self._mode is ContextMode.BEHAVE and self._origin[attr] is not ContextMode.BEHAVE:
+             msg = "behave runner is masking context attribute '%(attr)s' " \
+                   "originally set in %(function)s (%(filename)s:%(line)s)"
+-        elif self._mode is self.USER:
+-            if self._origin[attr] is not self.USER:
++        elif self._mode is ContextMode.USER:
++            if self._origin[attr] is not ContextMode.USER:
+                 msg = "user code is masking context attribute '%(attr)s' " \
+                       "originally set by behave"
+             elif self._config.verbose:
+@@ -442,13 +453,13 @@ class Context(object):
+ 
+ @contextlib.contextmanager
+ def use_context_with_mode(context, mode):
+-    """Switch context to BEHAVE or USER mode.
++    """Switch context to ContextMode.BEHAVE or ContextMode.USER mode.
+     Provides a context manager for switching between the two context modes.
+ 
+     .. sourcecode:: python
+ 
+         context = Context()
+-        with use_context_with_mode(context, Context.BEHAVE):
++        with use_context_with_mode(context, ContextMode.BEHAVE):
+             ...     # Do something
+         # -- POSTCONDITION: Original context._mode is restored.
+ 
+@@ -456,7 +467,7 @@ def use_context_with_mode(context, mode):
+     :param mode:     Mode to apply to context object.
+     """
+     # pylint: disable=protected-access
+-    assert mode in (Context.BEHAVE, Context.USER)
++    assert mode in (ContextMode.BEHAVE, ContextMode.USER)
+     current_mode = context._mode
+     try:
+         context._mode = mode
+diff --git a/tests/unit/test_runner.py b/tests/unit/test_runner.py
+index f0d03cd..beaff8f 100644
+--- a/tests/unit/test_runner.py
++++ b/tests/unit/test_runner.py
+@@ -17,6 +17,7 @@ from behave import runner_util
+ from behave.model import Table
+ from behave.step_registry import StepRegistry
+ from behave import parser, runner
++from behave.runner import ContextMode
+ from behave.exception import ConfigError
+ from behave.formatter.base import StreamOpener
+ 
+@@ -36,29 +37,29 @@ class TestContext(unittest.TestCase):
+ 
+     def test_user_mode_shall_restore_behave_mode(self):
+         # -- CASE: No exception is raised.
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         assert self.context._mode == initial_mode
+         with self.context.use_with_user_mode():
+-            assert self.context._mode == runner.Context.USER
++            assert self.context._mode == ContextMode.USER
+             self.context.thing = "stuff"
+         assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_assert_fails(self):
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                assert self.context._mode == runner.Context.USER
++                assert self.context._mode == ContextMode.USER
+                 assert False, "XFAIL"
+         except AssertionError:
+             assert self.context._mode == initial_mode
+ 
+     def test_user_mode_shall_restore_behave_mode_if_exception_is_raised(self):
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         assert self.context._mode == initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                assert self.context._mode == runner.Context.USER
++                assert self.context._mode == ContextMode.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+             assert self.context._mode == initial_mode
+@@ -66,21 +67,21 @@ class TestContext(unittest.TestCase):
+     def test_use_with_user_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         self.context._mode = initial_mode
+         with self.context.use_with_user_mode():
+-            assert self.context._mode == runner.Context.USER
++            assert self.context._mode == ContextMode.USER
+             self.context.thing = "stuff"
+         assert self.context._mode == initial_mode
+ 
+     def test_use_with_user_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.BEHAVE
++        initial_mode = ContextMode.BEHAVE
+         self.context._mode = initial_mode
+         try:
+             with self.context.use_with_user_mode():
+-                assert self.context._mode == runner.Context.USER
++                assert self.context._mode == ContextMode.USER
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+             assert self.context._mode == initial_mode
+@@ -88,21 +89,21 @@ class TestContext(unittest.TestCase):
+     def test_use_with_behave_mode__shall_restore_initial_mode(self):
+         # -- CASE: No exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.USER
++        initial_mode = ContextMode.USER
+         self.context._mode = initial_mode
+         with self.context._use_with_behave_mode():
+-            assert self.context._mode == runner.Context.BEHAVE
++            assert self.context._mode == ContextMode.BEHAVE
+             self.context.thing = "stuff"
+         assert self.context._mode == initial_mode
+ 
+     def test_use_with_behave_mode__shall_restore_initial_mode_with_error(self):
+         # -- CASE: Exception is raised.
+         # pylint: disable=protected-access
+-        initial_mode = runner.Context.USER
++        initial_mode = ContextMode.USER
+         self.context._mode = initial_mode
+         try:
+             with self.context._use_with_behave_mode():
+-                assert self.context._mode == runner.Context.BEHAVE
++                assert self.context._mode == ContextMode.BEHAVE
+                 raise RuntimeError("XFAIL")
+         except RuntimeError:
+             assert self.context._mode == initial_mode
diff --git a/meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch b/meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch
new file mode 100644
index 000000000..9b0e77d1b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0072-Cleanup-comments.patch
@@ -0,0 +1,22 @@
+From 1c3eab0fed1d0eb33da64eb568e42971822655df Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:25:00 +0100
+Subject: [PATCH] Cleanup comments
+
+---
+ behave/runner.py | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/behave/runner.py b/behave/runner.py
+index bcf4ab2..6b20937 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -158,8 +158,6 @@ class Context(object):
+     .. _`configuration file section names`: behave.html#configuration-files
+     """
+     # pylint: disable=too-many-instance-attributes
+-    # BEHAVE = "behave"
+-    # USER = "user"
+     FAIL_ON_CLEANUP_ERRORS = True
+ 
+     def __init__(self, runner):
diff --git a/meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch b/meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch
new file mode 100644
index 000000000..79755daa7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0073-FIX-sphinx-build-problem-async_steps3x.py.patch
@@ -0,0 +1,29 @@
+From f9977969e7fabad5644b57f53462954ed097e66e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:51:47 +0100
+Subject: [PATCH] FIX: sphinx-build problem: async_steps3x.py
+
+---
+ docs/new_and_noteworthy_v1.2.6.rst | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/docs/new_and_noteworthy_v1.2.6.rst b/docs/new_and_noteworthy_v1.2.6.rst
+index 848c409..2c8e865 100644
+--- a/docs/new_and_noteworthy_v1.2.6.rst
++++ b/docs/new_and_noteworthy_v1.2.6.rst
+@@ -325,13 +325,13 @@ A simple example for the implementation of the async-steps is shown for:
+ * Python 3.5 with new ``async``/``await`` keywords
+ * Python 3.4 with ``@asyncio.coroutine`` decorator and ``yield from`` keyword
+ 
+-.. literalinclude:: ../examples/async_step/features/steps/async_steps35.py
++.. literalinclude:: ../examples/async_step/features/steps/_async_steps35.py
+     :language: python
+     :prepend:
+         # -- FILE: features/steps/async_steps35.py
+ 
+ 
+-.. literalinclude:: ../examples/async_step/features/steps/async_steps34.py
++.. literalinclude:: ../examples/async_step/features/steps/_async_steps34.py
+     :language: python
+     :prepend:
+         # -- FILE: features/steps/async_steps34.py
diff --git a/meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch b/meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch
new file mode 100644
index 000000000..444ed5d14
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch
@@ -0,0 +1,185 @@
+From 70943d9fae75cce204052ac0f498e603f1c7f4c4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 21:52:53 +0100
+Subject: [PATCH] docs: Rename page 'parse_expressions' (was:
+ parse_builtin_types) and update table to current parse-1.12.1
+
+---
+ docs/appendix.rst            |  2 +-
+ docs/parse_builtin_types.rst | 59 ------------------------
+ docs/parse_expressions.rst   | 87 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 88 insertions(+), 60 deletions(-)
+ delete mode 100644 docs/parse_builtin_types.rst
+ create mode 100644 docs/parse_expressions.rst
+
+diff --git a/docs/appendix.rst b/docs/appendix.rst
+index 8c0cb05..79b5455 100644
+--- a/docs/appendix.rst
++++ b/docs/appendix.rst
+@@ -11,7 +11,7 @@ Appendix
+ 
+     formatters
+     context_attributes
+-    parse_builtin_types
++    parse_expressions
+     regular_expressions
+     test_domains
+     behave_ecosystem
+diff --git a/docs/parse_builtin_types.rst b/docs/parse_builtin_types.rst
+deleted file mode 100644
+index 32e18ec..0000000
+--- a/docs/parse_builtin_types.rst
++++ /dev/null
+@@ -1,59 +0,0 @@
+-.. _id.appendix.parse_builtin_types:
+-
+-Predefined Data Types in ``parse``
+-==============================================================================
+-
+-:pypi:`behave` uses the :pypi:`parse` module (inverse of Python `string.format`_)
+-under the hoods to parse parameters in step definitions.
+-This leads to rather simple and readable parse expressions for step parameters.
+-
+-.. code-block:: python
+-
+-    # -- FILE: features/steps/type_transform_example_steps.py
+-    from behave import given
+-
+-    @given('I have {number:d} friends')  #< Convert 'number' into int type.
+-    def step_given_i_have_number_friends(context, number):
+-        assert number > 0
+-        ...
+-
+-Therefore, the following ``parse types`` are already supported
+-in step definitions without registration of any *user-defined type*:
+-
+-
+-===== =========================================== ============
+-Type  Characters Matched                          Output Type
+-===== =========================================== ============
+- w    Letters and underscore                      str
+- W    Non-letter and underscore                   str
+- s    Whitespace                                  str
+- S    Non-whitespace                              str
+- d    Digits (effectively integer numbers)        int
+- D    Non-digit                                   str
+- n    Numbers with thousands separators (, or .)  int
+- %    Percentage (converted to value/100.0)       float
+- f    Fixed-point numbers                         float
+- e    Floating-point numbers with exponent        float
+-      e.g. 1.1e-10, NAN (all case insensitive)
+- g    General number format (either d, f or e)    float
+- b    Binary numbers                              int
+- o    Octal numbers                               int
+- x    Hexadecimal numbers (lower and upper case)  int
+- ti   ISO 8601 format date/time                   datetime
+-      e.g. 1972-01-20T10:21:36Z
+- te   RFC2822 e-mail format date/time             datetime
+-      e.g. Mon, 20 Jan 1972 10:21:36 +1000
+- tg   Global (day/month) format date/time         datetime
+-      e.g. 20/1/1972 10:21:36 AM +1:00
+- ta   US (month/day) format date/time             datetime
+-      e.g. 1/20/1972 10:21:36 PM +10:30
+- tc   ctime() format date/time                    datetime
+-      e.g. Sun Sep 16 01:03:52 1973
+- th   HTTP log format date/time                   datetime
+-      e.g. 21/Nov/2011:00:07:11 +0000
+- tt   Time                                        time
+-      e.g. 10:21:36 PM -5:30
+-===== =========================================== ============
+-
+-
+-.. _string.format: https://docs.python.org/3/library/string.html#format-string-syntax
+diff --git a/docs/parse_expressions.rst b/docs/parse_expressions.rst
+new file mode 100644
+index 0000000..36ca549
+--- /dev/null
++++ b/docs/parse_expressions.rst
+@@ -0,0 +1,87 @@
++.. _id.appendix.parse_expressions:
++
++==============================================================================
++Parse Expressions
++==============================================================================
++
++.. index:: parse expressions, regexp
++
++`Parse expressions`_ are a simplified form of regular expressions.
++The actual regular expression is hidden behind the **type** name / hint.
++
++`Parse expressions`_ are used in step definitions as a simplified alternative
++to regular expressions. They are used for parameters and type conversions
++(which are not supported for regular expression patterns).
++
++.. code-block:: python
++
++    # -- FILE: features/steps/example_steps.py
++    from behave import when
++
++    @when('we implement {number:d} tests')
++    def step_impl(context, number):  # -- NOTE: number is converted into integer
++        assert number > 1 or number == 0
++        context.tests_count = number
++
++The following tables provide a overview of the `parse expressions`_ syntax.
++See also `Python regular expressions`_ description in the Python `re module`_.
++
++===== =========================================== ========
++Type  Characters Matched                          Output
++===== =========================================== ========
++l     Letters (ASCII)                             str
++w     Letters, numbers and underscore             str
++W     Not letters, numbers and underscore         str
++s     Whitespace                                  str
++S     Non-whitespace                              str
++d     Digits (effectively integer numbers)        int
++D     Non-digit                                   str
++n     Numbers with thousands separators (, or .)  int
++%     Percentage (converted to value/100.0)       float
++f     Fixed-point numbers                         float
++F     Decimal numbers                             Decimal
++e     Floating-point numbers with exponent        float
++      e.g. 1.1e-10, NAN (all case insensitive)
++g     General number format (either d, f or e)    float
++b     Binary numbers                              int
++o     Octal numbers                               int
++x     Hexadecimal numbers (lower and upper case)  int
++ti    ISO 8601 format date/time                   datetime
++      e.g. 1972-01-20T10:21:36Z ("T" and "Z"
++      optional)
++te    RFC2822 e-mail format date/time             datetime
++      e.g. Mon, 20 Jan 1972 10:21:36 +1000
++tg    Global (day/month) format date/time         datetime
++      e.g. 20/1/1972 10:21:36 AM +1:00
++ta    US (month/day) format date/time             datetime
++      e.g. 1/20/1972 10:21:36 PM +10:30
++tc    ctime() format date/time                    datetime
++      e.g. Sun Sep 16 01:03:52 1973
++th    HTTP log format date/time                   datetime
++      e.g. 21/Nov/2011:00:07:11 +0000
++ts    Linux system log format date/time           datetime
++      e.g. Nov  9 03:37:44
++tt    Time                                        time
++      e.g. 10:21:36 PM -5:30
++===== =========================================== ========
++
++
++=====================  ==============================================================
++Cardinality            Description
++=====================  ==============================================================
++``?``                   Pattern with cardinality 0..1: optional part (question mark).
++``*``                   Pattern with cardinality zero or more, 0.. (asterisk).
++``+``                   Pattern with cardinality one or more, 1.. (plus sign).
++``{m}``                 Matches ``m`` repetitions of a pattern.
++``{m,n}``               Matches from ``m`` to ``n`` repetitions of a pattern.
++``[A-Za-z]+``           EXAMPLE: Matches one or more alphabetical characters.
++=====================  ==============================================================
++
++
++.. _parse module: https://github.com/r1chardj0n3s/parse
++.. _string.format: https://docs.python.org/3/library/string.html#format-string-syntax
++
++.. _re module: https://docs.python.org/3/library/re.html#module-re
++.. _Python regular expressions: https://docs.python.org/3/library/re.html#module-re
++.. _`regular expressions`: https://en.wikipedia.org/wiki/Regular_expression
++
diff --git a/meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch b/meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch
new file mode 100644
index 000000000..6bdf151fe
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0075-docs-parse_expression-add-links-to-parse_type-module.patch
@@ -0,0 +1,40 @@
+From f2704149ae1bc11b01b6be854a28f178e20d00e4 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 15 Dec 2019 22:08:05 +0100
+Subject: [PATCH] docs: parse_expression, add links to parse_type module and
+ CardinalityField support.
+
+---
+ docs/parse_expressions.rst | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/docs/parse_expressions.rst b/docs/parse_expressions.rst
+index 36ca549..3810222 100644
+--- a/docs/parse_expressions.rst
++++ b/docs/parse_expressions.rst
+@@ -65,6 +65,8 @@ tt    Time                                        time
+       e.g. 10:21:36 PM -5:30
+ ===== =========================================== ========
+ 
++If `parse_type`_ module is used, the cardinality of a type can be specified, too
++(by using the `CardinalityField`_ support):
+ 
+ =====================  ==============================================================
+ Cardinality            Description
+@@ -72,14 +74,13 @@ Cardinality            Description
+ ``?``                   Pattern with cardinality 0..1: optional part (question mark).
+ ``*``                   Pattern with cardinality zero or more, 0.. (asterisk).
+ ``+``                   Pattern with cardinality one or more, 1.. (plus sign).
+-``{m}``                 Matches ``m`` repetitions of a pattern.
+-``{m,n}``               Matches from ``m`` to ``n`` repetitions of a pattern.
+-``[A-Za-z]+``           EXAMPLE: Matches one or more alphabetical characters.
+ =====================  ==============================================================
+ 
+ 
+ .. _parse module: https://github.com/r1chardj0n3s/parse
++.. _parse_type: https://github.com/jenisys/parse_type
+ .. _string.format: https://docs.python.org/3/library/string.html#format-string-syntax
++.. _CardinalityField: https://github.com/jenisys/parse_type/blob/master/README.rst#extended-parser-with-cardinalityfield-support
+ 
+ .. _re module: https://docs.python.org/3/library/re.html#module-re
+ .. _Python regular expressions: https://docs.python.org/3/library/re.html#module-re
diff --git a/meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch b/meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch
new file mode 100644
index 000000000..e71056e1f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch
@@ -0,0 +1,65 @@
+From 95812437eba0154b91108890dd53aab9615f7860 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Thu, 19 Dec 2019 12:31:47 +0100
+Subject: [PATCH] BUMP-VERSION: 1.2.7.dev2 (was: 1.2.7.dev1)
+
+---
+ .bumpversion.cfg  | 2 +-
+ VERSION.txt       | 2 +-
+ behave/version.py | 2 +-
+ pytest.ini        | 2 +-
+ setup.py          | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/.bumpversion.cfg b/.bumpversion.cfg
+index a5d3d2f..4f2bb76 100644
+--- a/.bumpversion.cfg
++++ b/.bumpversion.cfg
+@@ -1,5 +1,5 @@
+ [bumpversion]
+-current_version = 1.2.7.dev1
++current_version = 1.2.7.dev2
+ files = behave/version.py setup.py VERSION.txt pytest.ini .bumpversion.cfg
+ parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?P<drop>\w*)
+ serialize = {major}.{minor}.{patch}{drop}
+diff --git a/VERSION.txt b/VERSION.txt
+index c0ef36b..c4e75f6 100644
+--- a/VERSION.txt
++++ b/VERSION.txt
+@@ -1 +1 @@
+-1.2.7.dev1
++1.2.7.dev2
+diff --git a/behave/version.py b/behave/version.py
+index b19cb5e..67f4a41 100644
+--- a/behave/version.py
++++ b/behave/version.py
+@@ -1,2 +1,2 @@
+ # -- BEHAVE-VERSION:
+-VERSION = "1.2.7.dev1"
++VERSION = "1.2.7.dev2"
+diff --git a/pytest.ini b/pytest.ini
+index b9f281a..df2a81f 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -21,7 +21,7 @@ testpaths     = tests
+ python_files  = test_*.py
+ junit_family = xunit2
+ addopts = --metadata PACKAGE_UNDER_TEST behave
+-    --metadata PACKAGE_VERSION 1.2.7.dev1
++    --metadata PACKAGE_VERSION 1.2.7.dev2
+     --html=build/testing/report.html --self-contained-html
+     --junit-xml=build/testing/report.xml
+ markers =
+diff --git a/setup.py b/setup.py
+index 2afc147..23f6654 100644
+--- a/setup.py
++++ b/setup.py
+@@ -55,7 +55,7 @@ def find_packages_by_root_package(where):
+ # -----------------------------------------------------------------------------
+ setup(
+     name="behave",
+-    version="1.2.7.dev1",
++    version="1.2.7.dev2",
+     description="behave is behaviour-driven development, Python style",
+     long_description=description,
+     author="Jens Engel, Benno Rice and Richard Jones",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch b/meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch
new file mode 100644
index 000000000..d244eea22
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch
@@ -0,0 +1,223 @@
+From dcde4bb2e1b32d676bb0ff16de80dfdf7df6b085 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 20 Dec 2019 16:45:46 +0100
+Subject: [PATCH] Gherkin parser: Cleanups related to question in #800
+ (ParseError usage)
+
+---
+ CHANGES.rst                                  |  1 +
+ behave/parser.py                             | 41 +++++++++++++-------
+ features/background.feature                  |  4 +-
+ features/parser.background.sad_cases.feature | 10 ++---
+ features/parser.feature.sad_cases.feature    |  6 +--
+ issue.features/issue0148.feature             |  2 +-
+ 6 files changed, 38 insertions(+), 26 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index ba4daad..5653492 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -44,6 +44,7 @@ FIXED:
+ 
+ MINOR:
+ 
++* issue #800: Cleanups related to Gherkin parser/ParseError question (submitted by: otstanteplz)
+ * pull  #767: FIX: use_fixture_by_tag didn't return the actual fixture in all cases (provided by: jgentil)
+ * pull  #751: gherkin: Adding Rule keyword translation in portuguese and spanish to gherkin-languages.json (provided by: dunossauro)
+ * pull  #660: Fix minor typos (provided by: rrueth)
+diff --git a/behave/parser.py b/behave/parser.py
+index 520f678..58c68be 100644
+--- a/behave/parser.py
++++ b/behave/parser.py
+@@ -132,13 +132,24 @@ def parse_tags(text):
+ 
+ 
+ class ParserError(Exception):
+-    def __init__(self, message, line, filename=None, line_text=None):
+-        if line:
+-            message += u" at line %d" % line
+-            if line_text:
+-                message += u': "%s"' % line_text.strip()
++    @staticmethod
++    def make_annotated(message, line_number, line_text=None, reason=None):
++        """Make annotated message enriched w/ line_number, line_text."""
++        if line_number:
++            message += u" at line %d" % line_number
++        if line_text:
++            message += u': "%s"' % line_text.strip()
++        if reason:
++            message += u"\nREASON: %s" % reason
++        return message
++
++    def __init__(self, message, line, filename=None, line_text=None,
++                 reason=None, use_annotated_message=True):
++        if use_annotated_message:
++            message = self.make_annotated(message, line, line_text, reason)
++
+         super(ParserError, self).__init__(message)
+-        self.line = line
++        self.line = line    # Line number of parse failure.
+         self.line_text = line_text
+         self.filename = filename
+ 
+@@ -386,14 +397,13 @@ class Parser(object):
+             line = line.strip()
+             msg = u"Parser in unknown state %s;" % self.state
+             raise ParserError(msg, self.line, self.filename, line)
++
+         if not func(line):
+             line = line.strip()
+-            msg = u'\nParser failure in state %s, at line %d: "%s"\n' % \
+-                  (self.state, self.line, line)
++            msg = u'\nParser failure in state=%s' % self.state
+             reason = self.ask_parse_failure_oracle(line)
+-            if reason:
+-                msg += u"REASON: %s" % reason
+-            raise ParserError(msg, None, self.filename)
++            raise ParserError(msg, self.line, self.filename,
++                              line_text=line, reason=reason)
+ 
+     def action_init(self, line):
+         line = line.strip()
+@@ -642,7 +652,7 @@ class Parser(object):
+             self.table = model.Table(cells, self.line)
+         else:
+             if len(cells) != len(self.table.headings):
+-                raise ParserError(u"Malformed table", self.line)
++                raise ParserError(u"Malformed table", self.line, self.filename)
+                 # MAYBE: self.filename)
+             self.table.add_row(cells, self.line)
+         return True
+@@ -704,8 +714,8 @@ class Parser(object):
+                 break   # -- COMMENT: Skip rest of line.
+             else:
+                 # -- BAD-TAG: Abort here.
+-                raise ParserError(u"tag: %s (line: %s)" % (word, line),
+-                                  self.line, self.filename)
++                message = u"tag: %s (line: %s)" % (word, line)
++                raise ParserError(message, self.line, self.filename)
+         return tags
+ 
+     def parse_step(self, line):
+@@ -723,7 +733,8 @@ class Parser(object):
+                 step_text_after_keyword = line[len(kw):].strip()
+                 if step_type in ("and", "but"):
+                     if not self.last_step:
+-                        raise ParserError(u"No previous step", self.line)
++                        raise ParserError(u"No previous step",
++                                          self.line, self.filename)
+                     step_type = self.last_step
+                 else:
+                     self.last_step = step_type
+diff --git a/features/background.feature b/features/background.feature
+index b2f5833..65c4882 100644
+--- a/features/background.feature
++++ b/features/background.feature
+@@ -362,7 +362,7 @@ Feature: Background
+     When I run "behave -f plain -T features/background_sad_example1.feature"
+     Then it should fail with:
+         """
+-        Parser failure in state steps, at line 5: "Background: B1"
++        Parser failure in state=steps at line 5: "Background: B1"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -387,6 +387,6 @@ Feature: Background
+     When I run "behave -f plain -T features/background_sad_example2.feature"
+     Then it should fail with:
+         """
+-        Parser failure in state steps, at line 5: "Background: B2 (XFAIL)"
++        Parser failure in state=steps at line 5: "Background: B2 (XFAIL)"
+         REASON: Background should not be used here.
+         """
+diff --git a/features/parser.background.sad_cases.feature b/features/parser.background.sad_cases.feature
+index 37956ad..eb234ae 100644
+--- a/features/parser.background.sad_cases.feature
++++ b/features/parser.background.sad_cases.feature
+@@ -37,7 +37,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       Then it should fail with
+         """
+         Failed to parse "{__WORKDIR__}/features/syndrome.background_with_tags.feature":
+-        Parser failure in state taggable_statement, at line 4: "Background: Oops..."
++        Parser failure in state=taggable_statement at line 4: "Background: Oops..."
+         REASON: Background does not support tags.
+         """
+ 
+@@ -57,7 +57,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       Then it should fail with
+         """
+         Failed to parse "{__WORKDIR__}/features/syndrome.background_after_scenario.feature":
+-        Parser failure in state steps, at line 6: "Background: Oops, too late (after Scenario)"
++        Parser failure in state=steps at line 6: "Background: Oops, too late (after Scenario)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -77,7 +77,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       When I run "behave -f plain -T features/syndrome.tagged_background_after_scenario.feature"
+       Then it should fail with
+         """
+-        Parser failure in state taggable_statement, at line 7: "Background: Oops, too late (after Scenario)"
++        Parser failure in state=taggable_statement at line 7: "Background: Oops, too late (after Scenario)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -100,7 +100,7 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       When I run "behave -f plain -T features/syndrome.background_after_scenario_outline.feature"
+       Then it should fail with
+         """
+-        Parser failure in state steps, at line 10: "Background: Oops, too late (after Scenario Outline)"
++        Parser failure in state=steps at line 10: "Background: Oops, too late (after Scenario Outline)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+ 
+@@ -124,6 +124,6 @@ Feature: Ensure that BAD/SAD Use cases of Background are detected
+       When I run "behave -f plain -T features/syndrome.background_after_scenario_outline.feature"
+       Then it should fail with
+         """
+-        Parser failure in state taggable_statement, at line 11: "Background: Oops, too late (after Scenario Outline)"
++        Parser failure in state=taggable_statement at line 11: "Background: Oops, too late (after Scenario Outline)"
+         REASON: Background may not occur after Scenario/ScenarioOutline.
+         """
+diff --git a/features/parser.feature.sad_cases.feature b/features/parser.feature.sad_cases.feature
+index d89d9b7..0e12d9f 100644
+--- a/features/parser.feature.sad_cases.feature
++++ b/features/parser.feature.sad_cases.feature
+@@ -84,7 +84,7 @@ Feature: Parsing a Feature File without a Feature or with several Features
+       Then it should fail with:
+         """
+         Failed to parse "{__WORKDIR__}/features/only_text.feature":
+-        Parser failure in state init, at line 1: "This File: Contains only text without keywords."
++        Parser failure in state=init at line 1: "This File: Contains only text without keywords."
+         REASON: No feature found.
+         """
+ 
+@@ -103,7 +103,7 @@ Feature: Parsing a Feature File without a Feature or with several Features
+       Then it should fail with:
+         """
+         Failed to parse "{__WORKDIR__}/features/naked_scenario_only.feature":
+-        Parser failure in state init, at line 1: "Scenario:"
++        Parser failure in state=init at line 1: "Scenario:"
+         REASON: Scenario may not occur before Feature.
+         """
+ 
+@@ -139,6 +139,6 @@ Feature: Parsing a Feature File without a Feature or with several Features
+           Then it should fail with:
+             """
+             Failed to parse "{__WORKDIR__}/features/two_features.feature":
+-            Parser failure in state steps, at line 7: "Feature: F2"
++            Parser failure in state=steps at line 7: "Feature: F2"
+             REASON: Multiple features in one file are not supported.
+             """
+diff --git a/issue.features/issue0148.feature b/issue.features/issue0148.feature
+index 4387795..667d196 100644
+--- a/issue.features/issue0148.feature
++++ b/issue.features/issue0148.feature
+@@ -67,7 +67,7 @@ Feature: Issue #148: Substeps do not fail
+     And the command output should contain:
+         """
+         ParserError: Failed to parse <string>:
+-        Parser failure in state steps, at line 2: "I do something stupid"
++        Parser failure in state=steps at line 2: "I do something stupid"
+         """
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch b/meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch
new file mode 100644
index 000000000..60e9e9309
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch
@@ -0,0 +1,82 @@
+From 230b5bf8184beb02a3fa2678def7f11acf916e37 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 9 Feb 2020 20:30:53 +0100
+Subject: [PATCH] Clarify select-by-name uses regex pattern (related to: issue
+ #810)
+
+Clarifiy select-by-name uses regex pattern:
+
+* Adapt command-line option --name help text
+* Update command-line args docs for behave
+---
+ CHANGES.rst             |  4 ++++
+ behave/configuration.py | 10 +++++-----
+ docs/behave.rst         | 12 ++++++------
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 5653492..d0bf6fd 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -31,6 +31,10 @@ ENHANCEMENTS:
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ 
++CLARIFICATION:
++
++* issue #810: Clarify select-by-name using regex pattern (submitted by: xv-chris-w)
++
+ FIXED:
+ 
+ * issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+diff --git a/behave/configuration.py b/behave/configuration.py
+index bd8b039..65e2e3e 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -164,11 +164,11 @@ options = [
+                   override a configuration file setting.""")),
+ 
+     (("-n", "--name"),
+-     dict(action="append",
+-          help="""Only execute the feature elements which match part
+-                  of the given name. If this option is given more
+-                  than once, it will match against all the given
+-                  names.""")),
++     dict(action="append", metavar="NAME_PATTERN",
++          help="""Select feature elements (scenarios, ...) to run
++                  which match part of the given name (regex pattern).
++                  If this option is given more than once,
++                  it will match against all the given names.""")),
+ 
+     (("--no-capture",),
+      dict(action="store_false", dest="stdout_capture",
+diff --git a/docs/behave.rst b/docs/behave.rst
+index dfb390a..25ce523 100644
+--- a/docs/behave.rst
++++ b/docs/behave.rst
+@@ -95,9 +95,9 @@ You may see the same information presented below at any time using ``behave
+ 
+ .. option:: -n, --name
+ 
+-    Only execute the feature elements which match part of the given name.
+-    If this option is given more than once, it will match against all
+-    the given names.
++    Select feature elements (scenarios, ...) to run which match part of
++    the given name (regex pattern). If this option is given more than
++    once, it will match against all the given names.
+ 
+ .. option:: --no-capture
+ 
+@@ -449,9 +449,9 @@ Configuration Parameters
+ 
+ .. describe:: name : sequence<text>
+ 
+-    Only execute the feature elements which match part of the given name.
+-    If this option is given more than once, it will match against all
+-    the given names.
++    Select feature elements (scenarios, ...) to run which match part of
++    the given name (regex pattern). If this option is given more than
++    once, it will match against all the given names.
+ 
+ .. index::
+     single: configuration param; stdout_capture
diff --git a/meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch b/meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch
new file mode 100644
index 000000000..bd55ca5f2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch
@@ -0,0 +1,34 @@
+From e55569d0a3fd1aa653fd702705e09359bdd90685 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 13 Apr 2020 10:31:54 +0200
+Subject: [PATCH] FIX: Cross-reference problem (copy+paste) in Rule class
+ docstring.
+
+---
+ behave/model.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/behave/model.py b/behave/model.py
+index f46d2c2..cb69f9e 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -84,8 +84,8 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+ 
+     .. attribute:: keyword
+ 
+-       This is the keyword as seen in the *feature file*. In English this will
+-       be "Feature" or "Rule".
++       This is the keyword as seen in the *feature file*.
++       In English this will be "Feature" or "Rule".
+ 
+     .. attribute:: name
+ 
+@@ -671,7 +671,7 @@ class Rule(ScenarioContainer):
+ 
+ 
+     .. versionadded:: 1.2.7
+-    .. _`feature`: gherkin.html#rule
++    .. _`rule`: gherkin.html#rule
+     """
+     type = "rule"
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch b/meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch
new file mode 100644
index 000000000..da7b2be63
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0080-DOCS-Update-API-description-for-Runner-Operation.patch
@@ -0,0 +1,195 @@
+From 7b5f6f27a281714c6fef8e609416b7f405e8b1ba Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 13 Apr 2020 10:33:44 +0200
+Subject: [PATCH] DOCS: Update API description for "Runner Operation".
+
+* Provide description Gherkin grammar containments
+* Add description for Rule(s).
+---
+ docs/api.rst | 137 ++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 96 insertions(+), 41 deletions(-)
+
+diff --git a/docs/api.rst b/docs/api.rst
+index 5e4b7b4..39fa755 100644
+--- a/docs/api.rst
++++ b/docs/api.rst
+@@ -196,24 +196,34 @@ Environment File Functions
+ The environment.py module may define code to run before and after certain
+ events during your testing:
+ 
+-**before_step(context, step), after_step(context, step)**
+-  These run before and after every step. The step passed in is an instance
+-  of :class:`~behave.model.Step`.
++**before_all(context), after_all(context)**
++  These run before and after the whole shooting match.
++
++**before_feature(context, feature), after_feature(context, feature)**
++  These run before and after each feature is executed.
++  The feature object, that is passed in, is an instance of :class:`~behave.model.Feature`.
++
++**before_rule(context, rule), after_rule(context, rule)**
++  These run before and after each rule is execured.
++  The rule object, that is passed in, is an instance of :class:`~behave.model.Rule`.
+ 
+ **before_scenario(context, scenario), after_scenario(context, scenario)**
+-  These run before and after each scenario is run. The scenario passed in is an
+-  instance of :class:`~behave.model.Scenario`.
++  These run before and after each scenario is run.
++  The scenario object, that is passed in, is an instance of :class:`~behave.model.Scenario`.
+ 
+-**before_feature(context, feature), after_feature(context, feature)**
+-  These run before and after each feature file is exercised. The feature
+-  passed in is an instance of :class:`~behave.model.Feature`.
++**before_step(context, step), after_step(context, step)**
++  These run before and after every step.
++  The step object, that is passed in, is an instance of :class:`~behave.model.Step`.
+ 
+ **before_tag(context, tag), after_tag(context, tag)**
+   These run before and after a section tagged with the given name. They are
+   invoked for each tag encountered in the order they're found in the
+-  feature file. See  :ref:`controlling things with tags`. The tag passed in is
+-  an instance of :class:`~behave.model.Tag` and because it's a subclass of
+-  string you can do simple tests like:
++  feature file. See  :ref:`controlling things with tags`.
++
++  Taggable statements are: Feature, Rule, Scenario, ScenarioOutline, Examples.
++
++  The tag, that is passed in, is an instance of :class:`~behave.model.Tag` and
++  because it's a subclass of string you can do simple tests like:
+ 
+   .. code-block:: python
+ 
+@@ -227,8 +237,6 @@ events during your testing:
+               else:
+                   context.browser = webdriver.PlainVanilla()
+ 
+-**before_all(context), after_all(context)**
+-  These run before and after the whole shooting match.
+ 
+ 
+ Some Useful Environment Ideas
+@@ -311,42 +319,87 @@ Use Fixtures
+ Runner Operation
+ ================
+ 
+-Given all the code that could be run by *behave*, this is the order in
+-which that code is invoked (if they exist.)
++The execution of code is based on the Gherkin description in `*.feature` files.
++The following section provides a short overview of the hierarchical containment
++that is possible in the Gherkin grammer:
+ 
+ .. parsed-literal::
+ 
+-    before_all
+-    for feature in all_features:
+-        before_feature
+-        for scenario in feature.scenarios:
+-            before_scenario
+-            for step in scenario.steps:
+-                before_step
+-                    step.run()
+-                after_step
+-            after_scenario
+-        after_feature
+-    after_all
++    # -- SIMPLIFIED GHERKIN GRAMMAR (for Gherkin v6):
++    # CARDINALITY DECORATOR: '*' means 0..N (many), '?' means 0..1 (optional)
++    # EXAMPLE: Feature
++    #   A Feature can have many Tags (as TaggableStatement: zero or more tags before its keyword).
++    #   A Feature can have an optional Background.
++    #   A Feature can have many Scenario(s), meaning zero or more Scenarios.
++    #   A Feature can have many ScenarioOutline(s).
++    #   A Feature can have many Rule(s).
++    Feature(TaggableStatement):
++        Background?
++        Scenario*
++        ScenarioOutline*
++        Rule*
++
++    Background:
++        Step*           # Background steps are injected into any Scenario of its scope.
++
++    Scenario(TaggableStatement):
++        Step*
+ 
+-If the feature contains scenario outlines then there is an additional loop
+-over all the scenarios in the outline making the running look like this:
++    ScenarioOutline(ScenarioTemplateWithPlaceholders):
++        Scenario*       # Rendered Template by using ScenarioOutline.Examples.rows placeholder values.
++
++    Rule(TaggableStatement):
++        Background?     # Behave-specific extension (after removal from final Gherkin v6).
++        Scenario*
++        ScenarioOutline*
++
++
++Given all the code that could be run by *behave*,
++this is the order in which that code is invoked (if they exist.)
+ 
+ .. parsed-literal::
+ 
+-    before_all
++    # -- PSEUDO-CODE:
++    # HOOK: before_tag(), after_tag() is called for Feature, Rule, Scenario
++    ctx = createContext()
++    call-optional-hook before_all(ctx)
+     for feature in all_features:
+-        before_feature
+-        for outline in feature.scenarios:
+-            for scenario in outline.scenarios:
+-                before_scenario
+-                for step in scenario.steps:
+-                    before_step
+-                        step.run()
+-                    after_step
+-                after_scenario
+-        after_feature
+-    after_all
++        for tag in feature.tags: call-optional-hook before_tag(ctx, tag)
++        call-optional-hook before_feature(ctx, feature)
++        for run_item in feature.run_items:  # CAN BE: Rule, Scenario, ScenarioOutline
++            execute_run_item(ctx, run_item)
++        call-optional-hook after_feature(ctx, feature)
++        for tag in feature.tags: call-optional-hook after_tag(ctx, tag)
++    call-optional-hook after_all(ctx)
++
++    function execute_run_item(run_item, ctx):
++        if run_item isa Rule:
++            # -- CASE: Rule
++            rule = run_item
++            for tag in rule.tags: call-optional-hook before_tag(ctx, tag)
++            call-optional-hook before_rule(ctx, rule)
++            for run_item in rule.run_items:     # CAN BE: Scenario, ScenarioOutline
++                execute_run_item(run_item, ctx)
++            call-optional-hook after_rule(ctx, rule)
++            for tag in rule.tags: call-optional-hook after_tag(ctx, tag)
++        else if run_item isa ScenarioOutline:
++            # -- CASE: ScenarioOutline
++            # HINT: All Scenarios are already created from Example(s) rows.
++            scenario_outline = run_item
++            for scenario in scenario_outline.scenarios:
++                execute_run_item(scenario, ctx)
++        else if run_item isa Scenario:
++            # -- CASE: Scenario
++            # HINT: Background steps are injected before scenario steps.
++            scenario = run_item
++            for tag in scenario.tags: call-optional-hook before_tag(ctx, tag)
++            call-optional-hook before_scenario(ctx, scenario)
++            for step in scenario.steps:
++                call-optional-hook before_step(ctx, step)
++                step.run(ctx)
++                call-optional-hook after_step(ctx, step)
++            call-optional-hook after_scenario(ctx, scenario)
++            for tag in scenario.tags: call-optional-hook after_tag(ctx, tag)
+ 
+ 
+ Model Objects
+@@ -397,6 +450,8 @@ be:
+ 
+ .. autoclass:: behave.model.Feature
+ 
++.. autoclass:: behave.model.Rule
++
+ .. autoclass:: behave.model.Background
+ 
+ .. autoclass:: behave.model.Scenario
diff --git a/meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch b/meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch
new file mode 100644
index 000000000..3b6b83a1b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0081-FIX-DOCS-Runner-operations-typo.patch
@@ -0,0 +1,22 @@
+From 07ad7958eab96a4dadae514f7f963fa73d356191 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 13 Apr 2020 10:38:17 +0200
+Subject: [PATCH] FIX DOCS: Runner operations typo.
+
+---
+ docs/api.rst | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/docs/api.rst b/docs/api.rst
+index 39fa755..4763ad6 100644
+--- a/docs/api.rst
++++ b/docs/api.rst
+@@ -367,7 +367,7 @@ this is the order in which that code is invoked (if they exist.)
+         for tag in feature.tags: call-optional-hook before_tag(ctx, tag)
+         call-optional-hook before_feature(ctx, feature)
+         for run_item in feature.run_items:  # CAN BE: Rule, Scenario, ScenarioOutline
+-            execute_run_item(ctx, run_item)
++            execute_run_item(run_item, ctx)
+         call-optional-hook after_feature(ctx, feature)
+         for tag in feature.tags: call-optional-hook after_tag(ctx, tag)
+     call-optional-hook after_all(ctx)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch b/meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch
new file mode 100644
index 000000000..843f53113
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch
@@ -0,0 +1,295 @@
+From 2cf10215b5e8fcbb9162bde48456b60786d828cf Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 23 Sep 2020 23:22:45 +0200
+Subject: [PATCH] issue #740: Enhancement: Context.add_cleanup() with
+ layer-name
+
+Context.add_cleanup() can choose which cleanup layer to use (outer layer).
+This provides the possibility that a cleanup-funcion, registered with
+Context.add_cleanup(cleanup_func, ...) to be called upon leaving
+the outer context stack frames.
+
+Submitted by: nizwiz
+Requested by: dcvmoole
+---
+ CHANGES.rst                         |  7 +++
+ behave/model.py                     |  4 +-
+ behave/runner.py                    | 45 ++++++++++++---
+ tests/unit/test_context_cleanups.py | 86 ++++++++++++++++++++++++++++-
+ 4 files changed, 130 insertions(+), 12 deletions(-)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d0bf6fd..d758364 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -28,6 +28,7 @@ ENHANCEMENTS:
+ * Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Support emojis in ``*.feature`` files and steps
+ * Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
++* issue #740: Enhancement: possibility to add cleanup to be called upon leaving outer context stack frames (submitted by: nizwiz, dcvmoole)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
+ 
+@@ -65,6 +66,12 @@ DOCUMENTATION:
+ * pull  #684: Fix typo in "install.rst" (provided by: mstred)
+ * pull  #628: Changed pythonhosted.org links to readthedocs.io (provided by: chrisbrake)
+ 
++BREAKING CHANGES (naming):
++
++* behave.runner.Context._push(layer=None): Was Context._push(layer_name=None)
++* behave.runner.scoped_context_layer(context, layer=None):
++  Was scoped_context_layer(context.layer_name=None)
++
+ 
+ .. _`cucumber-tag-expressions`: https://pypi.org/project/cucumber-tag-expressions/
+ 
+diff --git a/behave/model.py b/behave/model.py
+index cb69f9e..f1ec725 100644
+--- a/behave/model.py
++++ b/behave/model.py
+@@ -363,7 +363,7 @@ class ScenarioContainer(TagAndStatusStatement, Replayable):
+         hook_before_entity = "before_{0}".format(entity_name)
+         hook_after_entity = "after_{0}".format(entity_name)
+ 
+-        runner.context._push(layer_name=entity_name)      # pylint: disable=protected-access
++        runner.context._push(layer=entity_name)      # pylint: disable=protected-access
+         runner.context.tags = set(self.tags)
+         self._setup_context_for_run(runner.context)
+ 
+@@ -1136,7 +1136,7 @@ class Scenario(TagAndStatusStatement, Replayable):
+         dry_run_scenario = run_scenario and runner.config.dry_run
+         self.was_dry_run = dry_run_scenario
+ 
+-        runner.context._push(layer_name="scenario")      # pylint: disable=protected-access
++        runner.context._push(layer="scenario")      # pylint: disable=protected-access
+         runner.context.scenario = self
+         runner.context.tags = set(self.effective_tags)
+ 
+diff --git a/behave/runner.py b/behave/runner.py
+index 6b20937..d01bff0 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -145,7 +145,7 @@ class Context(object):
+     tries to overwrite a user-set variable.
+ 
+     You may use the "in" operator to test whether a certain value has been set
+-    on the context, for example:
++    on the context, for example::
+ 
+         "feature" in context
+ 
+@@ -158,6 +158,7 @@ class Context(object):
+     .. _`configuration file section names`: behave.html#configuration-files
+     """
+     # pylint: disable=too-many-instance-attributes
++    LAYER_NAMES = ["testrun", "feature", "rule", "scenario"]
+     FAIL_ON_CLEANUP_ERRORS = True
+ 
+     def __init__(self, runner):
+@@ -245,16 +246,15 @@ class Context(object):
+             del cleanup_errors  # -- ENSURE: Release other exception frames.
+             six.reraise(*first_cleanup_erro_info)
+ 
+-
+-    def _push(self, layer_name=None):
++    def _push(self, layer=None):
+         """Push a new layer on the context stack.
+-        HINT: Use layer_name values: "scenario", "feature", "testrun".
++        HINT: Use layer values: "testrun", "feature", "rule, "scenario".
+ 
+-        :param layer_name:   Layer name to use (or None).
++        :param layer:   Layer name to use (or None).
+         """
+         initial_data = {"@cleanups": []}
+-        if layer_name:
+-            initial_data["@layer"] = layer_name
++        if layer:
++            initial_data["@layer"] = layer
+         self._stack.insert(0, initial_data)
+ 
+     def _pop(self):
+@@ -426,6 +426,20 @@ class Context(object):
+             self.text = original_text
+         return True
+ 
++    def _select_stack_frame_by_layer(self, layer):
++        """Select context stack frame by layer name.
++
++        :param layer:   Layer name (as string).
++        :return: Selected frame object (if any)
++        :raises: LookupError, if layer was not found.
++        """
++        for frame in self._stack:
++            frame_layer = frame.get("@layer", None)
++            if layer == frame_layer:
++                return frame
++        # -- OOPS, NOT FOUND:
++        raise LookupError("Context.stack: layer=%s not found" % layer)
++
+     def add_cleanup(self, cleanup_func, *args, **kwargs):
+         """Adds a cleanup function that is called when :meth:`Context._pop()`
+         is called. This is intended for user-cleanups.
+@@ -433,10 +447,21 @@ class Context(object):
+         :param cleanup_func:    Callable function
+         :param args:            Args for cleanup_func() call (optional).
+         :param kwargs:          Kwargs for cleanup_func() call (optional).
++
++        .. note:: RESERVED :obj:`layer` : optional-string
++
++            The keyword argument ``layer="LAYER_NAME"`` can to be used to
++            assign the :obj:`cleanup_func` to specific a layer on the context stack
++            (instead of the current layer).
++
++            Known layer names are: "testrun", "feature", "rule", "scenario"
++
++        .. seealso:: :attr:`.Context.LAYER_NAMES`
+         """
+         # MAYBE:
+         assert callable(cleanup_func), "REQUIRES: callable(cleanup_func)"
+         assert self._stack
++        layer = kwargs.pop("layer", None)
+         if args or kwargs:
+             def internal_cleanup_func():
+                 cleanup_func(*args, **kwargs)
+@@ -444,6 +469,8 @@ class Context(object):
+             internal_cleanup_func = cleanup_func
+ 
+         current_frame = self._stack[0]
++        if layer:
++            current_frame = self._select_stack_frame_by_layer(layer)
+         if cleanup_func not in current_frame["@cleanups"]:
+             # -- AVOID DUPLICATES:
+             current_frame["@cleanups"].append(internal_cleanup_func)
+@@ -477,7 +504,7 @@ def use_context_with_mode(context, mode):
+ 
+ 
+ @contextlib.contextmanager
+-def scoped_context_layer(context, layer_name=None):
++def scoped_context_layer(context, layer=None):
+     """Provides context manager for context layer (push/do-something/pop cycle).
+ 
+     .. code-block::
+@@ -487,7 +514,7 @@ def scoped_context_layer(context, layer_name=None):
+     """
+     # pylint: disable=protected-access
+     try:
+-        context._push(layer_name)
++        context._push(layer)
+         yield context
+     finally:
+         context._pop()
+diff --git a/tests/unit/test_context_cleanups.py b/tests/unit/test_context_cleanups.py
+index bf0ab50..c32c572 100644
+--- a/tests/unit/test_context_cleanups.py
++++ b/tests/unit/test_context_cleanups.py
+@@ -23,6 +23,9 @@ import pytest
+ def cleanup_func():
+     pass
+ 
++def cleanup_func_with_args(*args, **kwargs):
++    pass
++
+ class CleanupFunction(object):
+     def __init__(self, name="CLEANUP-FUNC", listener=None):
+         self.name = name
+@@ -42,7 +45,6 @@ class CallListener(object):
+         self.collected.append(message)
+ 
+ 
+-
+ # ------------------------------------------------------------------------------
+ # TESTS:
+ # ------------------------------------------------------------------------------
+@@ -145,6 +147,24 @@ class TestContextCleanup(object):
+         my_cleanup_B2M.assert_called_once()
+         my_cleanup_B3M.assert_called_once()
+ 
++    def test_add_cleanup_with_args(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context):
++            context.add_cleanup(my_cleanup, 1, 2, 3)
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(1, 2, 3)
++
++    def test_add_cleanup_with_args_and_kwargs(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context):
++            context.add_cleanup(my_cleanup, 1, 2, 3, name="alice")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(1, 2, 3, name="alice")
++
+     def test_add_cleanup__rejects_noncallable_cleanup_func(self):
+         class NonCallable(object): pass
+         non_callable = NonCallable()
+@@ -218,3 +238,67 @@ class TestContextCleanup(object):
+         assert collect_cleanup_error.collected[0][:-1] == expected[0][:-1]
+         assert collect_cleanup_error.collected[1][:-1] == expected[1][:-1]
+ 
++
++class TestContextCleanupWithLayer(object):
++    """Tests :meth:`behave.runner.Context.add_cleanup()`
++    with layer parameter.
++
++    :meth:`cleanup_func()` is called when Context layer is removed/popped.
++    """
++
++    def test_add_cleanup_with_known_layer(self):
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="scenario"):
++            context.add_cleanup(my_cleanup, layer="scenario")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once()
++
++    def test_add_cleanup_with_known_layer_and_args(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="scenario"):
++            context.add_cleanup(my_cleanup, 1, 2, 3, layer="scenario")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(1, 2, 3)
++
++    def test_add_cleanup_with_known_layer_and_kwargs(self):
++        my_cleanup = Mock(spec=cleanup_func_with_args)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="scenario"):
++            context.add_cleanup(my_cleanup, layer="scenario", name="alice")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once_with(name="alice")
++
++    def test_add_cleanup_with_known_deeper_layer2(self):
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="feature"):
++            with scoped_context_layer(context, layer="scenario"):
++                context.add_cleanup(my_cleanup, layer="feature")
++            my_cleanup.assert_not_called()
++        # CALLS-HERE: context._pop()
++        my_cleanup.assert_called_once()
++
++    def test_add_cleanup_with_known_deeper_layer3(self):
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context, layer="testrun"):
++            with scoped_context_layer(context, layer="feature"):
++                with scoped_context_layer(context, layer="scenario"):
++                    context.add_cleanup(my_cleanup, layer="feature")
++                my_cleanup.assert_not_called()
++            my_cleanup.assert_called_once()     # LEFT: layer="feature"
++        my_cleanup.assert_called_once()
++
++    def test_add_cleanup_with_unknown_layer_raises_lookup_error(self):
++        """Cleanup function is not registered"""
++        my_cleanup = Mock(spec=cleanup_func)
++        context = Context(runner=Mock())
++        with scoped_context_layer(context):   # CALLS-HERE: context._push()
++            with pytest.raises(LookupError) as error:
++                context.add_cleanup(my_cleanup, layer="other")
++        my_cleanup.assert_not_called()
diff --git a/meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch b/meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch
new file mode 100644
index 000000000..d03a7ccae
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch
@@ -0,0 +1,37 @@
+From a53e82fa963696988c743aaca2341390332e7e3b Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 20 Oct 2020 22:40:46 +0200
+Subject: [PATCH] UPDATE: parse >= 1.18.0 (parse versions: 1.16.0 .. 1.17.x has
+ a problem; parse issue #119, #121)
+
+---
+ py.requirements/basic.txt | 2 +-
+ setup.py                  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index ad5b9a6..f976748 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -9,7 +9,7 @@
+ # ============================================================================
+ 
+ cucumber-tag-expressions >= 1.1.2
+-parse >= 1.8.2
++parse >= 1.18.0
+ parse_type >= 0.4.2
+ six >= 1.12.0
+ 
+diff --git a/setup.py b/setup.py
+index 23f6654..fd89bda 100644
+--- a/setup.py
++++ b/setup.py
+@@ -77,7 +77,7 @@ setup(
+     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*",
+     install_requires=[
+         "cucumber-tag-expressions >= 1.1.2",
+-        "parse >= 1.9.1",
++        "parse >= 1.18.0",
+         "parse_type >= 0.4.2",
+         "six >= 1.12.0",
+         "traceback2; python_version < '3.0'",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch b/meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch
new file mode 100644
index 000000000..32304e345
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch
@@ -0,0 +1,34 @@
+From fb3f43735f7c9b8363940595d12d7b59544f64c0 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 2 Nov 2020 17:50:10 +0100
+Subject: [PATCH] RELATED TO: Duplicated steps/AmbiguousStepErrors
+
+* Remove @xfail from third scenario (it worked already for some time).
+* Added more detailled description to third scenario.
+---
+ features/step.duplicated_step.feature | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/features/step.duplicated_step.feature b/features/step.duplicated_step.feature
+index 396cca2..f204307 100644
+--- a/features/step.duplicated_step.feature
++++ b/features/step.duplicated_step.feature
+@@ -76,8 +76,17 @@ Feature: Duplicated Step Definitions
+     #    File "features/steps/bob2_steps.py", line 3, in <module>
+     #    """
+ 
+-  @xfail
++
+   Scenario: Duplicated Same Step Definition via import from another File
++
++    VERIFY THAT: Duplicated step-detection works.
++    Duplicated step-registration occured through a twice imported step-module:
++    First registration may occurs by step-loading the step-module,
++    second registration due to import of first step-module.
++
++    The step registry detects that the same step-function should be registered
++    another time and ignores it (step is already registered).
++
+     Given a new working directory
+     And a file named "features/steps/charly1_steps.py" with:
+       """
diff --git a/meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch b/meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch
new file mode 100644
index 000000000..8b0f22d8f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0085-Add-renovate.json.patch
@@ -0,0 +1,21 @@
+From d65b38953bfe1cc346a2548a8e617229df87058b Mon Sep 17 00:00:00 2001
+From: Renovate Bot <bot@renovateapp.com>
+Date: Wed, 4 Nov 2020 08:43:32 +0000
+Subject: [PATCH] Add renovate.json
+
+---
+ renovate.json | 5 +++++
+ 1 file changed, 5 insertions(+)
+ create mode 100644 renovate.json
+
+diff --git a/renovate.json b/renovate.json
+new file mode 100644
+index 0000000..f45d8f1
+--- /dev/null
++++ b/renovate.json
+@@ -0,0 +1,5 @@
++{
++  "extends": [
++    "config:base"
++  ]
++}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch b/meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch
new file mode 100644
index 000000000..39a6d76c2
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0086-PRPEPARE-RENOVATE-With-adaptions.patch
@@ -0,0 +1,175 @@
+From 61f3a341b7accd0580af7c7b2e8db4cb6a7f4bec Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 10:28:59 +0100
+Subject: [PATCH] PRPEPARE-RENOVATE: With adaptions
+
+* Provide locations/patterns for pip requirements file(s)
+* Move "renovate.json" to ".github/"
+---
+ .github/renovate.json                         | 13 ++++++++
+ MANIFEST.in                                   |  4 +--
+ issue.features/README.rst                     | 32 +++++++++++++++++++
+ issue.features/README.txt                     | 17 ----------
+ .../{requirements.txt => py.requirements.txt} |  7 ++--
+ py.requirements/{README.txt => README.rst}    |  0
+ py.requirements/testing.txt                   |  4 ++-
+ renovate.json                                 |  5 ---
+ 8 files changed, 53 insertions(+), 29 deletions(-)
+ create mode 100644 .github/renovate.json
+ create mode 100644 issue.features/README.rst
+ delete mode 100644 issue.features/README.txt
+ rename issue.features/{requirements.txt => py.requirements.txt} (82%)
+ rename py.requirements/{README.txt => README.rst} (100%)
+ delete mode 100644 renovate.json
+
+diff --git a/.github/renovate.json b/.github/renovate.json
+new file mode 100644
+index 0000000..3399a00
+--- /dev/null
++++ b/.github/renovate.json
+@@ -0,0 +1,13 @@
++{
++  "extends": [
++    "config:base"
++  ],
++  "pip_requirements": {
++    "fileMatch": [
++        "py.requirements/all.txt",
++        "py.requirements/*.txt",
++        "tasks/py.requirements.txt",
++        "issue.features/py.requirements.txt"
++    ]
++}
++}
+diff --git a/MANIFEST.in b/MANIFEST.in
+index 60c2601..84d20f4 100644
+--- a/MANIFEST.in
++++ b/MANIFEST.in
+@@ -28,8 +28,8 @@ recursive-include tasks         *.py *.zip *.txt *.rst
+ recursive-include tools         *.feature *.py *.yml *.sh
+ recursive-include features      *.feature *.py *.txt
+ recursive-include issue.features  *.feature *.py *.txt
+-recursive-include more.features *.feature *.py *.txt
+-recursive-include py.requirements  *.txt
++recursive-include more.features *.feature *.py *.txt *.rst
++recursive-include py.requirements  *.txt *.rst
+ 
+ prune .tox
+ prune .venv*
+diff --git a/issue.features/README.rst b/issue.features/README.rst
+new file mode 100644
+index 0000000..1d1d980
+--- /dev/null
++++ b/issue.features/README.rst
+@@ -0,0 +1,32 @@
++issue.features:
++===============================================================================
++
++:Requires: Python >= 2.7 or Python >= 3.5
++
++This directory contains behave self-tests to ensure that behave related
++issues are fixed.
++
++PROCEDURE:
++
++    * ONCE: Install python requirements ("py.requirements.txt")
++    * Run the tests with behave
++
++.. code-block:: shell
++
++    # -- FOR:
++    # pip:  For python2.7 or python3 (depends on platform and/or user))
++    # pip3: For python3
++    pip  install -U -r issue.features/testing.txt
++    pip3 install -U -r issue.features/testing.txt
++
++
++ALTERNATIVE:
++
++.. code-block:: shell
++
++    pip  install -U -r py.requirements/testing.txt
++    pip3 install -U -r py.requirements/testing.txt
++
++.. code-block:: shell
++
++    bin/behave -f progress issue.features/
+diff --git a/issue.features/README.txt b/issue.features/README.txt
+deleted file mode 100644
+index af499f3..0000000
+--- a/issue.features/README.txt
++++ /dev/null
+@@ -1,17 +0,0 @@
+-issue.features:
+-===============================================================================
+-
+-:Status:   PREPARED (fixes are being applied).
+-:Requires: Python >= 2.6 (due to step implementations)
+-
+-This directory contains behave self-tests to ensure that behave related
+-issues are fixed.
+-
+-PROCEDURE:
+-
+-    * ONCE: Install python requirements ("requirements.txt")
+-    * Run the tests with behave
+-
+-::
+-
+-    bin/behave -f progress issue.features/
+diff --git a/issue.features/requirements.txt b/issue.features/py.requirements.txt
+similarity index 82%
+rename from issue.features/requirements.txt
+rename to issue.features/py.requirements.txt
+index d0c4bab..f0def9d 100644
+--- a/issue.features/requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -1,12 +1,11 @@
+ # ============================================================================
+ # PYTHON PACKAGE REQUIREMENTS: For running issue.features/
+ # ============================================================================
+-# REQUIRES: Python >= 2.5
+-# REQUIRES: Python >= 3.2
++# REQUIRES: Python >= 2.7
++# REQUIRES: Python >= 3.5
+ # DESCRIPTION:
+ #    pip install -r <THIS_FILE>
+ #
+ # ============================================================================
+ 
+-PyHamcrest >= 1.6
+-
++PyHamcrest >= 2.0.2
+diff --git a/py.requirements/README.txt b/py.requirements/README.rst
+similarity index 100%
+rename from py.requirements/README.txt
+rename to py.requirements/README.rst
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 85b0908..5ccdda8 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -8,10 +8,12 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+-PyHamcrest >= 1.9
++PyHamcrest >= 2.0.2
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+ # HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
++
++-r ../issue.features/py.requirements.txt
+diff --git a/renovate.json b/renovate.json
+deleted file mode 100644
+index f45d8f1..0000000
+--- a/renovate.json
++++ /dev/null
+@@ -1,5 +0,0 @@
+-{
+-  "extends": [
+-    "config:base"
+-  ]
+-}
diff --git a/meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch b/meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch
new file mode 100644
index 000000000..eeebd7be3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0087-Pin-dependencies.patch
@@ -0,0 +1,36 @@
+From 9271668477574b317c72099eab587f516ae082de Mon Sep 17 00:00:00 2001
+From: Renovate Bot <bot@renovateapp.com>
+Date: Wed, 4 Nov 2020 09:32:34 +0000
+Subject: [PATCH] Pin dependencies
+
+---
+ issue.features/py.requirements.txt | 2 +-
+ tasks/py.requirements.txt          | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/issue.features/py.requirements.txt b/issue.features/py.requirements.txt
+index f0def9d..38f452d 100644
+--- a/issue.features/py.requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -8,4 +8,4 @@
+ #
+ # ============================================================================
+ 
+-PyHamcrest >= 2.0.2
++PyHamcrest==2.0.2
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index 810f834..9c82d11 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -8,9 +8,9 @@
+ #  * http://www.pip-installer.org/
+ # ============================================================================
+ 
+-invoke >= 1.2.0
++invoke==1.4.1
+ pycmd
+-six >= 1.12.0
++six==1.15.0
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
diff --git a/meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch b/meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch
new file mode 100644
index 000000000..33ec83848
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0088-renovate-Extend-pip-requirements-file-list.patch
@@ -0,0 +1,31 @@
+From 85d1f009d933d356e65a548f29e4d5a1e78a72d2 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 10:54:02 +0100
+Subject: [PATCH] renovate: Extend pip requirements file list.
+
+---
+ .github/renovate.json | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/.github/renovate.json b/.github/renovate.json
+index 3399a00..9b72f76 100644
+--- a/.github/renovate.json
++++ b/.github/renovate.json
+@@ -4,10 +4,15 @@
+   ],
+   "pip_requirements": {
+     "fileMatch": [
+-        "py.requirements/all.txt",
+         "py.requirements/*.txt",
++        "py.requirements/all.txt",
++        "py.requirements/basic.txt",
++        "py.requirements/develop.txt",
++        "py.requirements/testing.txt",
++        "py.requirements/ci.tox.txt",
++        "py.requirements/ci.travis.txt",
+         "tasks/py.requirements.txt",
+         "issue.features/py.requirements.txt"
+     ]
+-}
++  }
+ }
diff --git a/meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch b/meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch
new file mode 100644
index 000000000..758bd9878
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0089-PIN-REQUIREMENTS-Extend-to-all-places.patch
@@ -0,0 +1,92 @@
+From a45ef62144036b481e8432bcd2698a5f7bfcddd2 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 10:54:48 +0100
+Subject: [PATCH] PIN REQUIREMENTS: Extend to all places. PINNED: invoke, six,
+ PyHamcrest
+
+---
+ issue.features/py.requirements.txt | 2 +-
+ py.requirements/basic.txt          | 2 +-
+ py.requirements/ci.tox.txt         | 2 +-
+ py.requirements/ci.travis.txt      | 2 +-
+ py.requirements/develop.txt        | 4 +---
+ py.requirements/testing.txt        | 2 +-
+ 6 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/issue.features/py.requirements.txt b/issue.features/py.requirements.txt
+index 38f452d..6e3cf83 100644
+--- a/issue.features/py.requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -8,4 +8,4 @@
+ #
+ # ============================================================================
+ 
+-PyHamcrest==2.0.2
++PyHamcrest == 2.0.2
+diff --git a/py.requirements/basic.txt b/py.requirements/basic.txt
+index f976748..6c644e0 100644
+--- a/py.requirements/basic.txt
++++ b/py.requirements/basic.txt
+@@ -11,7 +11,7 @@
+ cucumber-tag-expressions >= 1.1.2
+ parse >= 1.18.0
+ parse_type >= 0.4.2
+-six >= 1.12.0
++six == 1.15.0
+ 
+ traceback2;  python_version < '3.0'
+ contextlib2     # MAYBE: python_version < '3.5'
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 4001bc2..20ae791 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -6,7 +6,7 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock >= 2.0
+-PyHamcrest >= 1.9
++PyHamcrest == 2.0.2
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index de4120a..c69445c 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -5,7 +5,7 @@ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+-PyHamcrest >= 1.9
++PyHamcrest == 2.0.2
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+diff --git a/py.requirements/develop.txt b/py.requirements/develop.txt
+index a92ee5f..e7dc418 100644
+--- a/py.requirements/develop.txt
++++ b/py.requirements/develop.txt
+@@ -3,9 +3,7 @@
+ # ============================================================================
+ 
+ # -- BUILD-TOOL:
+-# PREPARE USAGE: invoke
+-# ALREADY: six >= 1.11.0
+-invoke >= 1.2.0
++invoke == 1.4.1
+ pathlib;    python_version <= '3.4'
+ pycmd
+ 
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index 5ccdda8..d3bca18 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -8,7 +8,7 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ pytest-html >= 1.19.0
+ mock  >= 2.0
+-PyHamcrest >= 2.0.2
++PyHamcrest == 2.0.2
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
diff --git a/meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch b/meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch
new file mode 100644
index 000000000..9c6735886
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch
@@ -0,0 +1,8116 @@
+From dc91d552ba45dd34022f37a4d4f328d5de5c1e17 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Wed, 4 Nov 2020 21:18:12 +0100
+Subject: [PATCH] tasks: Add invoke_cleanup (replaces: _tasklet_cleanup),
+ remove _vendor/ directory.
+
+---
+ py.requirements/docs.txt  |    3 +-
+ tasks/__init__.py         |   10 +-
+ tasks/_setup.py           |   10 +-
+ tasks/_tasklet_cleanup.py |  295 -------
+ tasks/_vendor/README.rst  |   35 -
+ tasks/_vendor/invoke.zip  |  Bin 172281 -> 0 bytes
+ tasks/_vendor/path.py     | 1725 -------------------------------------
+ tasks/_vendor/pathlib.py  | 1280 ---------------------------
+ tasks/_vendor/six.py      |  868 -------------------
+ tasks/docs.py             |   33 +-
+ tasks/invoke_cleanup.py   |  447 ++++++++++
+ tasks/py.requirements.txt |    2 +-
+ tasks/release.py          |    2 +-
+ tasks/test.py             |    3 +-
+ 14 files changed, 497 insertions(+), 4216 deletions(-)
+ delete mode 100644 tasks/_tasklet_cleanup.py
+ delete mode 100644 tasks/_vendor/README.rst
+ delete mode 100644 tasks/_vendor/invoke.zip
+ delete mode 100644 tasks/_vendor/path.py
+ delete mode 100644 tasks/_vendor/pathlib.py
+ delete mode 100644 tasks/_vendor/six.py
+ create mode 100644 tasks/invoke_cleanup.py
+
+diff --git a/py.requirements/docs.txt b/py.requirements/docs.txt
+index 6839ba9..1384e00 100644
+--- a/py.requirements/docs.txt
++++ b/py.requirements/docs.txt
+@@ -3,7 +3,8 @@
+ # ============================================================================
+ # REQUIRES: pip >= 8.0
+ 
+-Sphinx >= 1.6
++sphinx >= 1.6
++sphinx-autobuild
+ sphinx_bootstrap_theme >= 0.6.0
+ 
+ # -- SUPPORT: sphinx-doc translations (prepared)
+diff --git a/tasks/__init__.py b/tasks/__init__.py
+index a572465..9ae899b 100644
+--- a/tasks/__init__.py
++++ b/tasks/__init__.py
+@@ -20,7 +20,7 @@ from __future__ import absolute_import
+ from . import _setup    # pylint: disable=wrong-import-order
+ import os.path
+ import sys
+-INVOKE_MINVERSION = "1.2.0"
++INVOKE_MINVERSION = "1.4.0"
+ _setup.setup_path()
+ _setup.require_invoke_minversion(INVOKE_MINVERSION)
+ 
+@@ -35,7 +35,8 @@ import sys
+ from invoke import Collection
+ 
+ # -- TASK-LIBRARY:
+-from . import _tasklet_cleanup as cleanup
++# PREPARED: import invoke_cleanup as cleanup
++from . import invoke_cleanup as cleanup
+ from . import docs
+ from . import test
+ from . import release
+@@ -52,19 +53,18 @@ from . import develop
+ # TASK CONFIGURATION:
+ # -----------------------------------------------------------------------------
+ namespace = Collection()
+-# DISABLED: namespace.add_task(clean.clean)
+-# DISABLED: namespace.add_task(clean.clean_all)
+ namespace.add_collection(Collection.from_module(cleanup), name="cleanup")
+ namespace.add_collection(Collection.from_module(docs))
+ namespace.add_collection(Collection.from_module(test))
+ namespace.add_collection(Collection.from_module(release))
+ namespace.add_collection(Collection.from_module(develop))
+-cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+ 
++# -- ENSURE: python cleanup is used for this project.
+ cleanup.cleanup_tasks.add_task(cleanup.clean_python)
+ 
+ # -- INJECT: clean configuration into this namespace
+ namespace.configure(cleanup.namespace.configuration())
++namespace.configure(test.namespace.configuration())
+ if sys.platform.startswith("win"):
+     # -- OVERRIDE SETTINGS: For platform=win32, ... (Windows)
+     from ._compat_shutil import which
+diff --git a/tasks/_setup.py b/tasks/_setup.py
+index eda5ca9..e69ec82 100644
+--- a/tasks/_setup.py
++++ b/tasks/_setup.py
+@@ -14,7 +14,7 @@ import sys
+ HERE = os.path.dirname(__file__)
+ TASKS_VENDOR_DIR = os.path.join(HERE, "_vendor")
+ INVOKE_BUNDLE = os.path.join(TASKS_VENDOR_DIR, "invoke.zip")
+-INVOKE_BUNDLE_VERSION = "0.13.0"    # pylint: disable=invalid-name
++INVOKE_BUNDLE_VERSION = "1.4.0"
+ 
+ DEBUG_SYSPATH = False
+ 
+@@ -25,6 +25,7 @@ DEBUG_SYSPATH = False
+ class VersionRequirementError(SystemExit):
+     pass
+ 
++
+ # -----------------------------------------------------------------------------
+ # FUNCTIONS:
+ # -----------------------------------------------------------------------------
+@@ -32,7 +33,7 @@ def setup_path(invoke_minversion=None):
+     """Setup python search and add ``TASKS_VENDOR_DIR`` (if available)."""
+     # print("INVOKE.tasks: setup_path")
+     if not os.path.isdir(TASKS_VENDOR_DIR):
+-        print("SKIP: TASKS_VENDOR_DIR=%s is missing" % TASKS_VENDOR_DIR)
++        # SILENT: print("SKIP: TASKS_VENDOR_DIR=%s is missing" % os.path.relpath(TASKS_VENDOR_DIR))
+         return
+     elif os.path.abspath(TASKS_VENDOR_DIR) in sys.path:
+         # -- SETUP ALREADY DONE:
+@@ -86,6 +87,7 @@ def require_invoke_minversion(min_version, verbose=False):
+         os.environ["INVOKE_VERSION"] = invoke_version
+         print("USING: invoke.version=%s" % invoke_version)
+ 
++
+ def need_vendor_bundles(invoke_minversion=None):
+     invoke_minversion = invoke_minversion or "0.0.0"
+     need_vendor_answers = []
+@@ -102,6 +104,7 @@ def need_vendor_bundles(invoke_minversion=None):
+     # return need_bundle1 or need_bundle2
+     return any(need_vendor_answers)
+ 
++
+ def need_vendor_bundle_invoke(invoke_minversion="0.0.0"):
+     # -- REQUIRE: invoke
+     try:
+@@ -116,6 +119,7 @@ def need_vendor_bundle_invoke(invoke_minversion="0.0.0"):
+         need_bundle = True
+     return need_bundle
+ 
++
+ # -----------------------------------------------------------------------------
+ # UTILITY FUNCTIONS:
+ # -----------------------------------------------------------------------------
+@@ -125,11 +129,13 @@ def setup_path_for_bundle(bundle_path, pos=0):
+         return True
+     return False
+ 
++
+ def syspath_insert(pos, path):
+     if path in sys.path:
+         sys.path.remove(path)
+     sys.path.insert(pos, path)
+ 
++
+ def syspath_append(path):
+     if path in sys.path:
+         sys.path.remove(path)
+diff --git a/tasks/_tasklet_cleanup.py b/tasks/_tasklet_cleanup.py
+deleted file mode 100644
+index 2999bc6..0000000
+--- a/tasks/_tasklet_cleanup.py
++++ /dev/null
+@@ -1,295 +0,0 @@
+-# -*- coding: UTF-8 -*-
+-"""
+-Provides cleanup tasks for invoke build scripts (as generic invoke tasklet).
+-Simplifies writing common, composable and extendable cleanup tasks.
+-
+-PYTHON PACKAGE REQUIREMENTS:
+-* path.py >= 8.2.1  (as path-object abstraction)
+-* pathlib (for ant-like wildcard patterns; since: python > 3.5)
+-* pycmd (required-by: clean_python())
+-
+-clean task: Add Additional Directories and Files to be removed
+--------------------------------------------------------------------------------
+-
+-Create an invoke configuration file (YAML of JSON) with the additional
+-configuration data:
+-
+-.. code-block:: yaml
+-
+-    # -- FILE: invoke.yaml
+-    # USE: clean.directories, clean.files to override current configuration.
+-    clean:
+-        extra_directories:
+-            - **/tmp/
+-        extra_files:
+-            - **/*.log
+-            - **/*.bak
+-
+-
+-Registration of Cleanup Tasks
+-------------------------------
+-
+-Other task modules often have an own cleanup task to recover the clean state.
+-The :meth:`clean` task, that is provided here, supports the registration
+-of additional cleanup tasks. Therefore, when the :meth:`clean` task is executed,
+-all registered cleanup tasks will be executed.
+-
+-EXAMPLE::
+-
+-    # -- FILE: tasks/docs.py
+-    from __future__ import absolute_import
+-    from invoke import task, Collection
+-    from tasklet_cleanup import cleanup_tasks, cleanup_dirs
+-
+-    @task
+-    def clean(ctx, dry_run=False):
+-        "Cleanup generated documentation artifacts."
+-        cleanup_dirs(["build/docs"])
+-
+-    namespace = Collection(clean)
+-    ...
+-
+-    # -- REGISTER CLEANUP TASK:
+-    cleanup_tasks.add_task(clean, "clean_docs")
+-    cleanup_tasks.configure(namespace.configuration())
+-"""
+-
+-from __future__ import absolute_import, print_function
+-import os.path
+-import sys
+-import pathlib
+-from invoke import task, Collection
+-from invoke.executor import Executor
+-from invoke.exceptions import Exit, Failure, UnexpectedExit
+-from path import Path
+-
+-
+-# -----------------------------------------------------------------------------
+-# CLEANUP UTILITIES:
+-# -----------------------------------------------------------------------------
+-def cleanup_accept_old_config(ctx):
+-    ctx.cleanup.directories.extend(ctx.clean.directories or [])
+-    ctx.cleanup.extra_directories.extend(ctx.clean.extra_directories or [])
+-    ctx.cleanup.files.extend(ctx.clean.files or [])
+-    ctx.cleanup.extra_files.extend(ctx.clean.extra_files or [])
+-
+-    ctx.cleanup_all.directories.extend(ctx.clean_all.directories or [])
+-    ctx.cleanup_all.extra_directories.extend(ctx.clean_all.extra_directories or [])
+-    ctx.cleanup_all.files.extend(ctx.clean_all.files or [])
+-    ctx.cleanup_all.extra_files.extend(ctx.clean_all.extra_files or [])
+-
+-
+-def execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=False):
+-    """Execute several cleanup tasks as part of the cleanup.
+-
+-    REQUIRES: ``clean(ctx, dry_run=False)`` signature in cleanup tasks.
+-
+-    :param ctx:             Context object for the tasks.
+-    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
+-    :param dry_run:         Indicates dry-run mode (bool)
+-    """
+-    # pylint: disable=redefined-outer-name
+-    executor = Executor(cleanup_tasks, ctx.config)
+-    failure_count = 0
+-    for cleanup_task in cleanup_tasks.tasks:
+-        try:
+-            print("CLEANUP TASK: %s" % cleanup_task)
+-            executor.execute((cleanup_task, dict(dry_run=dry_run)))
+-        except (Exit, Failure, UnexpectedExit) as e:
+-            print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" % cleanup_task)
+-            failure_count += 1
+-
+-    if failure_count:
+-        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
+-
+-
+-def cleanup_dirs(patterns, dry_run=False, workdir="."):
+-    """Remove directories (and their contents) recursively.
+-    Skips removal if directories does not exist.
+-
+-    :param patterns:    Directory name patterns, like "**/tmp*" (as list).
+-    :param dry_run:     Dry-run mode indicator (as bool).
+-    :param workdir:     Current work directory (default=".")
+-    """
+-    current_dir = Path(workdir)
+-    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
+-    warn2_counter = 0
+-    for dir_pattern in patterns:
+-        for directory in path_glob(dir_pattern, current_dir):
+-            directory2 = directory.abspath()
+-            if sys.executable.startswith(directory2):
+-                # pylint: disable=line-too-long
+-                print("SKIP-SUICIDE: '%s' contains current python executable" % directory)
+-                continue
+-            elif directory2.startswith(python_basedir):
+-                # -- PROTECT CURRENTLY USED VIRTUAL ENVIRONMENT:
+-                if warn2_counter <= 4:
+-                    print("SKIP-SUICIDE: '%s'" % directory)
+-                warn2_counter += 1
+-                continue
+-
+-            if not directory.isdir():
+-                print("RMTREE: %s (SKIPPED: Not a directory)" % directory)
+-                continue
+-
+-            if dry_run:
+-                print("RMTREE: %s (dry-run)" % directory)
+-            else:
+-                print("RMTREE: %s" % directory)
+-                directory.rmtree_p()
+-
+-
+-def cleanup_files(patterns, dry_run=False, workdir="."):
+-    """Remove files or files selected by file patterns.
+-    Skips removal if file does not exist.
+-
+-    :param patterns:    File patterns, like "**/*.pyc" (as list).
+-    :param dry_run:     Dry-run mode indicator (as bool).
+-    :param workdir:     Current work directory (default=".")
+-    """
+-    current_dir = Path(workdir)
+-    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
+-    error_message = None
+-    error_count = 0
+-    for file_pattern in patterns:
+-        for file_ in path_glob(file_pattern, current_dir):
+-            if file_.abspath().startswith(python_basedir):
+-                # -- PROTECT CURRENTLY USED VIRTUAL ENVIRONMENT:
+-                continue
+-            if not file_.isfile():
+-                print("REMOVE: %s (SKIPPED: Not a file)" % file_)
+-                continue
+-
+-            if dry_run:
+-                print("REMOVE: %s (dry-run)" % file_)
+-            else:
+-                print("REMOVE: %s" % file_)
+-                try:
+-                    file_.remove_p()
+-                except os.error as e:
+-                    message = "%s: %s" % (e.__class__.__name__, e)
+-                    print(message + " basedir: "+ python_basedir)
+-                    error_count += 1
+-                    if not error_message:
+-                        error_message = message
+-    if False and error_message:
+-        class CleanupError(RuntimeError):
+-            pass
+-        raise CleanupError(error_message)
+-
+-
+-def path_glob(pattern, current_dir=None):
+-    """Use pathlib for ant-like patterns, like: "**/*.py"
+-
+-    :param pattern:      File/directory pattern to use (as string).
+-    :param current_dir:  Current working directory (as Path, pathlib.Path, str)
+-    :return Resolved Path (as path.Path).
+-    """
+-    if not current_dir:
+-        current_dir = pathlib.Path.cwd()
+-    elif not isinstance(current_dir, pathlib.Path):
+-        # -- CASE: string, path.Path (string-like)
+-        current_dir = pathlib.Path(str(current_dir))
+-
+-    for p in current_dir.glob(pattern):
+-        yield Path(str(p))
+-
+-
+-# -----------------------------------------------------------------------------
+-# GENERIC CLEANUP TASKS:
+-# -----------------------------------------------------------------------------
+-@task
+-def clean(ctx, dry_run=False):
+-    """Cleanup temporary dirs/files to regain a clean state."""
+-    cleanup_accept_old_config(ctx)
+-    directories = ctx.cleanup.directories or []
+-    directories.extend(ctx.cleanup.extra_directories or [])
+-    files = ctx.cleanup.files or []
+-    files.extend(ctx.cleanup.extra_files or [])
+-
+-    # -- PERFORM CLEANUP:
+-    execute_cleanup_tasks(ctx, cleanup_tasks, dry_run=dry_run)
+-    cleanup_dirs(directories, dry_run=dry_run)
+-    cleanup_files(files, dry_run=dry_run)
+-
+-
+-@task(name="all", aliases=("distclean",))
+-def clean_all(ctx, dry_run=False):
+-    """Clean up everything, even the precious stuff.
+-    NOTE: clean task is executed first.
+-    """
+-    cleanup_accept_old_config(ctx)
+-    directories = ctx.config.cleanup_all.directories or []
+-    directories.extend(ctx.config.cleanup_all.extra_directories or [])
+-    files = ctx.config.cleanup_all.files or []
+-    files.extend(ctx.config.cleanup_all.extra_files or [])
+-
+-    # -- PERFORM CLEANUP:
+-    # HINT: Remove now directories, files first before cleanup-tasks.
+-    cleanup_dirs(directories, dry_run=dry_run)
+-    cleanup_files(files, dry_run=dry_run)
+-    execute_cleanup_tasks(ctx, cleanup_all_tasks, dry_run=dry_run)
+-    clean(ctx, dry_run=dry_run)
+-
+-
+-@task(name="python")
+-def clean_python(ctx, dry_run=False):
+-    """Cleanup python related files/dirs: *.pyc, *.pyo, ..."""
+-    # MAYBE NOT: "**/__pycache__"
+-    cleanup_dirs(["build", "dist", "*.egg-info", "**/__pycache__"],
+-                 dry_run=dry_run)
+-    if not dry_run:
+-        ctx.run("py.cleanup")
+-    cleanup_files(["**/*.pyc", "**/*.pyo", "**/*$py.class"], dry_run=dry_run)
+-
+-
+-# -----------------------------------------------------------------------------
+-# TASK CONFIGURATION:
+-# -----------------------------------------------------------------------------
+-CLEANUP_EMPTY_CONFIG = {
+-    "directories": [],
+-    "files": [],
+-    "extra_directories": [],
+-    "extra_files": [],
+-}
+-def make_cleanup_config(**kwargs):
+-    config_data = CLEANUP_EMPTY_CONFIG.copy()
+-    config_data.update(kwargs)
+-    return config_data
+-
+-
+-namespace = Collection(clean_all, clean_python)
+-namespace.add_task(clean, default=True)
+-namespace.configure({
+-    "cleanup": make_cleanup_config(
+-        files=["*.bak", "*.log", "*.tmp", "**/.DS_Store", "**/*.~*~"]
+-    ),
+-    "cleanup_all": make_cleanup_config(
+-        directories=[".venv*", ".tox", "downloads", "tmp"]
+-    ),
+-    # -- BACKWARD-COMPATIBLE: OLD-STYLE
+-    "clean":     CLEANUP_EMPTY_CONFIG.copy(),
+-    "clean_all": CLEANUP_EMPTY_CONFIG.copy(),
+-})
+-
+-
+-# -- EXTENSION-POINT: CLEANUP TASKS (called by: clean, clean_all task)
+-# NOTE: Can be used by other tasklets to register cleanup tasks.
+-cleanup_tasks = Collection("cleanup_tasks")
+-cleanup_all_tasks = Collection("cleanup_all_tasks")
+-
+-# -- EXTEND NORMAL CLEANUP-TASKS:
+-# DISABLED: cleanup_tasks.add_task(clean_python)
+-#
+-# -----------------------------------------------------------------------------
+-# EXTENSION-POINT: CONFIGURATION HELPERS: Can be used from other task modules
+-# -----------------------------------------------------------------------------
+-def config_add_cleanup_dirs(directories):
+-    # pylint: disable=protected-access
+-    the_cleanup_directories = namespace._configuration["clean"]["directories"]
+-    the_cleanup_directories.extend(directories)
+-
+-def config_add_cleanup_files(files):
+-    # pylint: disable=protected-access
+-    the_cleanup_files = namespace._configuration["clean"]["files"]
+-    the_cleanup_files.extend(files)
+diff --git a/tasks/_vendor/README.rst b/tasks/_vendor/README.rst
+deleted file mode 100644
+index 68fc06a..0000000
+--- a/tasks/_vendor/README.rst
++++ /dev/null
+@@ -1,35 +0,0 @@
+-tasks/_vendor: Bundled vendor parts -- needed by tasks
+-===============================================================================
+-
+-This directory contains bundled archives that may be needed to run the tasks.
+-Especially, it contains an executable "invoke.zip" archive.
+-This archive can be used when invoke is not installed.
+-
+-To execute invoke from the bundled ZIP archive::
+-
+-
+-    python -m tasks/_vendor/invoke.zip --help
+-    python -m tasks/_vendor/invoke.zip --version
+-
+-
+-Example for a local "bin/invoke" script in a UNIX like platform environment::
+-
+-    #!/bin/bash
+-    # RUN INVOKE: From bundled ZIP file.
+-
+-    HERE=$(dirname $0)
+-
+-    python ${HERE}/../tasks/_vendor/invoke.zip $*
+-
+-Example for a local "bin/invoke.cmd" script in a Windows environment::
+-
+-    @echo off
+-    REM ==========================================================================
+-    REM RUN INVOKE: From bundled ZIP file.
+-    REM ==========================================================================
+-
+-    setlocal
+-    set HERE=%~dp0
+-    if not defined PYTHON   set PYTHON=python
+-
+-    %PYTHON% %HERE%../tasks/_vendor/invoke.zip "%*"
+diff --git a/tasks/_vendor/invoke.zip b/tasks/_vendor/invoke.zip
+deleted file mode 100644
+index bd1941289b427b6cd6beaf188c85def58ee4ce33..0000000000000000000000000000000000000000
+GIT binary patch
+literal 0
+HcmV?d00001
+
+literal 172281
+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
+zGGZqJEe%^irYHi$5Y*76Dh4>&<!%0AfH2K(?hj9A8%&MPJ$V+x5Uh_eLLl~WVHG$B
+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
+z%0A_8Np52k#hMUOO`CA<OW6@Z5`_l$nyJ@){7#Cydybi0I+8epVsPpkA)l6fpOK12
+ziWY!!`26xamx{WvjqFOQS&%!xI_dHT<P{*bJ%(a{kUluGDMe!U+`-&nTKgJ6U$8>^
+zhMZ5E+OdO{c54K2au!v^d=(bEBi!WdOj1p5zSFL^7K;_bsc6*-cyq7pSBSdKU8bye
+z{3r(2)~FXhsBn@dEiJD;O7*6FRi3s7b?yh2k<2n5z?jEys{72Ci*7r(KH!7K%XHx#
+z^j2O-2P-?mC;*dv#7&W1qeFSGDi-#p1Aga|ZBzOvZ!3J^oJj2!QdLsyH(5w{qkC|C
+zUccgwV6eqnHZ8<zCn*|YcCB#4ICsv;#ec+~28E-60trg~1AEpt`NRT66&qVXt#;~S
+zI0LOg2gH1~;fugH?;ed0fduW7rPpnNZ$XN)uj2B@K~*i}ORgH|Vr{aGri69oXU053
+z7AR8{nvhkAK}zOfDG9`U7%NPqH2z9Se9F+Y)oy>mkdFsV(+y_grzRQP_%=;wmWM%d
+zJ<6elc{IV?mKD|qyI`%<AJZaWj6uYV8QmL3{Z`sQk#c=Sst=xkH_KHj#pkK``5I()
+z)Www+*Gk(q1F$X>^RG^&!P~EPmZ?bMdV+)4Rkzy;RUbe3nryFwQp>YG+BdViS@-<g
+zDQ(<7KX0e(K3!gqkM<t+D)%m2M`y3-vHr50ivd5m@}FaZ;(zE)6i~Q8;Z+7Om+oRK
+z%W;8*R_N`acvV7ebA!$(_qQwF3Zc?m1@OXB)kEQ_00;F>CB(}!HTd&>Hv&Dc({U(0
+zMvSNcn&Q$&=y-qz(9B`0-)3TCy_;gxB4Y795)aBUEEChd4$l2c_D!#XvVBM02p_|R
+z7mO@f0DWY?Di6gESM#(Dn$w@cgFJ^3!7gnI5!RT%Y<B&#;waRL_$<MbIawz!o#RGM
+zqkr%^OJfzPk^9$#Woqdgm@u|Kn%;#UKRXb5Do#FZy<f-r>8B9%5{(%i;CWEx$DX)u
+zM)0zQcV`D((mbO#n^&K(sqy4Y3ht0HG$6FvLPiraX#HB?33t0ilU*KGR4ayeRrIVo
+z#k+i=dpYZC>!1zI5rKbA{6_t*A;yW-U;sl>83XM2K`t)^@LZUjZy3WYBdLua$TZn2
+z+&+bFd>||UhJGyab&UE;5^0P7JuK@q7tAzl=uQL<rx(3e1u)un#FO3D{?*OIr@AZP
+zns~h)b4I$8joL!2_tN<1k&D;L(>3>&iT#!3ItOAtQ!(&3F*~BT{hMX|IC%>IRaN_r
+zch;WZ(KxeXW<cZY9{HO!JZ9ZHUOHT{^PU_-YRCB*dSewODbpi*c4G5nV!%{=X^`D>
+zOIcy+$Yl!!CwGP$a)n9K1wfZscO`AO_o(YD_3wwb$+~Su^w&!Eh=x)JF12cIO7+sq
+z(?d+xU`bL*%vaXGfiC~^8lgyC-`d%IskFXadcH+)FL+BGSAC=2)v1lfOu|I9tuocj
+zJ=H3;WB2kJE3FBS^2pdOmv8U>A-eWiHgWtwvRp4+&!wvSj3^mlvJ=N0DM!;zQyUxf
+z%8scwj!GX#9k^Wjy&lz<cWlcZtK#-nh$3gT`jGRgd^X+VpqJLBH^@u6wb%cP0{<U~
+z7vle-z~U-zgKNJ;`Vr)RFH;*kIQ-9M{$yo&+e`)opA*$hBIQ1Us&bX;$dMx6N9(N*
+zC9XdK3w21ym|_z%JK5HKa7E_s;#R({Co{jdP7b<r_DS48;g4JxIzQOYOKfQFix5iy
+zS<}C9{j;%$W#_pTfxh_%fZhaaf*ER^F&=mg6<dSd;h15$y98XrGU}K_XGMG$o{%N|
+zMt!0XZ$<mDKW$2kr^G8kJn?W}?S4=pVehVl>i~%Fj)2|dLLR#T84v-#&k)=K6BeAO
+z^s%m^C7+ohPFneWrZ1eq8jfSugBgcRpZ4aMUvh@G63vG-3zow>U@UMK>U5>GiXuMn
+z2L95Bkc4iH#`AWkr6Qg24Q@s5c7FRsp73E9`Bs$3^0x8fuMrRT_LfO#=0zs=)5nr)
+z_?g=S3fi=TE19stwl(+R?!uJUUP!|Xh(v-Pe}HouMeqh<6H=AinX0k;l8p@pz3vPQ
+zrWY^?x|%wqn7L4+Ye^W87&7F*Q~QE!>cRr<#a|Dz(zm0-G_b3A{S{w{(F<7VmA75r
+zMQfP&8o9;MFqTpX$9``=t0w27P2em1=uD!5D8*R@k`4ZzYV2whQ8p_|yR!{dx+aTp
+zkgX3)x%`GT<;<z3^*-e_NH{peTmo-UL3)n6JmNW`mS$p&plMRJu3I2Q-zfU}<DhB=
+zO%pFP%#Q^t>Pi_2PkY$wSj(1F<w0q(XNV0COGx|K*ntPCE}J?qv2>&<pOhPh1RaO8
+z8<EC}wP}pZbmPC^CKhf~Yh-l^>Z}<-%4Pkc(y}b7Hxe0@Vu^O>qd7S|gyKm#2%nv+
+zW=i)dIlbhilh5_j%NlQFplE5S{#Qsjk;UzrfU?+$NfdSo`Z-W$Lx0d<IL@u#xxhUw
+zzdC%xNAr<R`nxg2v>V1arir~6W7-Q7<5|#pQXDA*<R|U2ys1-dtBdS8u`QLxT4$TQ
+z$;~Qyer-t&@Uq3hEL?Aq=hzgXvk%|@uVl{HZR{-g-{BJdJ6v%83jt&7Vr=8|9|DK}
+zkHT-a@{~;$147RON=gALLB6-2q-WSVj)yp%r<O<xdPp>~A@YV*V(Se?X0K4EdU6mj
+z-hr)8?;XNc+(u!2#!<>)04A^rwn+7#>uCb(f|!}OjYrKtx0HD#Ne*MQ#o>VRCPQi^
+zwAE=oYrGVYn1Jdq8+j*q;5%?;4cO%}g4v)!PW%5lLo~o|h%Y8JredQ(12sa?-N=jQ
+zhpM#_geQ%@i=49JR~r&F-ISqo94`);kzt2oyQ{DFNZk!a)Zy9-+MWCuy)CF{;vY^Y
+zt#VOQ#|XF6wnRsbgpr0!4?&*ck<TU<D3%H1M*&Ow*))(?vaSBEuiH?Im`kA+Q%I-)
+z7Ox?wtRueVLERd)-1Iu0RXWj@>Oe>C1}8(n*ZZmp>HXM~zR0YV&XGHDq84!z<F2JL
+zO^^*G34Ile^gy@qSvy6NzvlQ{1NAq`Xx;fd`Vl$=!DPBi-xx94Mqx3^I|=(31nqK#
+zbDlDwKdS&&iaKfK?F&uWXI2JGEW867g51(+_@S4seHJ3%JqsUQRcp{*NmTY{+J^Y?
+z1hT2!*A3D!<*H}4_K<ViLqW{#y2qJR+j!N^L^P`{u}VETqe7-{K}}EIBVf5s@R<gj
+z{otxx`I={Z6?Z-kA5=uovW95#2S(V0NguD^>0oz_Fmyyp^@fw`1eolkJ;=A^InSJ9
+zk&irG2keV=e}VmHi-_J*)!x?c6z%X!d;Yh7nU$@+(f@1_*@~Zl3t&JHdHIT1^Do&0
+z{=4~aIoQ9LaSCKTs7P*JrB@eEWLt7yveV!?%jH@N!jOX0&@QObRcLSqO7XY-Lnq2W
+zuDuqUP^c0IXzBv1p-X9fV7r{GzaVXb)Ph+RS$QeaL%*trTxCil1Dh0okeVdk4CZn9
+ztIS@M(573ijb(u{$Og~)v@UlZD&Eu6l>nq7(E%{ZSi}VL0X8*2$l2de2XI%0n_6u|
+zC&`g%<lW`MwtAyo=R(%SJ=7Un1~XOvXRy^sZJ`jxm!)?M&vG^NvgPC%KHWQU1^GX}
+zvu2ops?guInmo||zL4428X5nufjOllEgST!QhJ~!TSFi~YVc&p#8`_oec7K&E1?@K
+z(ST|ZY5du4@j`K7uOuT|2X315v<*4448$#!>~EoCsL9o}D^1J<n53u!5lYj`h*Kk^
+zSDbaq9pFBqEy-g^&QMb7De)_?Ys@hZB{c$rZ#SOe=LSW#yK(<lnbD>@DJaYZj9HQx
+zLCV%p>!vUhw}8$Nf>s4mlE!d01b6WL!=dOgpt~9h=zxMt<j)g&gs7K6*)d!(7b?vX
+zO299#uC1gFxS*CjPSGU}4Lz!u2{9nSC(BvLP-_KzaRE(fmCJp4Fy-;)v?Lm5jQM9Q
+z7V3#=Y)mIRQev?h1tFM<t!G?#4VwvG+2CjK%2PDVk(JPd%q%#lsF2uG2ni(n0pBG_
+z@$AzU|0}0)z(u}Y?J@d+0nIFw-KM7+^c{GfKAF$X>4Be*5gAo69+}}LpV^i5<d{#d
+znd5qz{<+}r3H;3$_RbhHOgE~ezZGrDdJl{FW?@r+mkulJrO7;P)pxj(D=ps}=s$m4
+z@DB-rd^iAr)L-!MzYPdGeTV-IJ|E#&Ixe(5d-?{q;F3wKz)tvFTD2z9`cKTF*=V*6
+zGGyx^6+cxQnp%VZqxrh=d~6`S&|ia`?OtJ?9ZHFr{vhS#_B=gDD|E*iJv*Uj7rYTQ
+zEj=ZJMvr6=mXDE<{g4Ht_-k@F!8GZ>BaFX7@dq=frh(@@Xb$E?F$;y;^U|Gdb1iVj
+zJ$}#5zv$xj7D8J`J4(zHJXN(Yk{X3J#hxWPVvHuc1`S{zV~@UB^TS~L^^;OysYI>}
+z|G>$EU1A<nR8}{;ixWFnH~#K}K@eD+oX6Xqk+0q3&ZSFNT8~3HFNRfZsZk<By1)o*
+z*C6X85$C6UU<?I$m0{W|T1GdDu3EOYz&M4@UgZymn0L!Oi!@ZgohnK7FkUz+_$XW$
+z6v`+EwNtQ(dK9ghe4JU}6%LDndfU}Fir?tKJx9S1Dv0@3<(wl67ysKzWu#%+0AGCO
+zC~0g^(-4e3d(2%^*nE+OM2Dk06Bn*FgoQBzN{C?qn2tu%qFDcuNSjuGv+9LXV})~(
+z`lBanIaspn`@!SV*hJvOUGGlRjO@s!&-*2v+SD-jS{m4gI8VNd6$2jF64dSq5@HO7
+z0wO1Nx6jx9=UdReKB{Z)kHcrpT0$&t$dWHNmpAis0OM+_P<(rSgKpf@<>QjC#bxtB
+zkzX1B)mjE%UX;_WewrD%w#b+tkFNSWl|{cU;-1Ibm)dPzhwvM1C9c9-U-88-7+gLp
+zdXhWrUxZh29=X)3f4~6Gm&3zHsN?qW_>%FD2w%mbGoFf0#D(L#DzVltB>*1(mM>J#
+zdE_?v{Kd0t4uRUynLGi8vEFzCsj!D65oy-sX@3pu^>)y15sqXGt<fxEXFbP5V+vP<
+zi`^d7K{w7n+dz??Q*)Z=y|tbD7DccngR&hU-PZbJ{YTq4p%7e4ep9dIuc8~99~r=u
+zqpW>~F(%L^LZ1q_;k3Xz>3;_}a{kUDdhB>gPXy`sy_VXi6szBOn40DkL$eGWQrjz;
+ztK>B@bPh5rB+trwiN|m6k)Rts4-d)uHMy|ohDZc7o<C2sz&+qdSiV?R!oazP{pbuZ
+zIJ0#2hSCuumGPU(3lb$O!Qj>zn4t-wjaCpUum=x?hR#h{Gs-s3=(7onr0sy7G9TZX
+zP)g1NZN)iQAd*?KNTWkbPSQ@_+J(Y-a`~`%IC`)GVrl{5|EwbdmcJ<8#C<^)c|Mxd
+zLfFEs>=EIWtV!Qq(D#0N`~%-&&ST~gL#~qygGls=Ip8eK);hdEfS3SCgfyn3@ysDp
+z!xik4<<rl@zn545=+k$ACM8M3?Eld5&Op}}#P8}=!50AaFzt{f@AG~SW^x}8BKd@D
+zEGV!<JDOk_b#8c`1r0fkfTHlitg54EI6a8So1<4?iDpFUHCh%7IUxW*aN)Zh($EuI
+zlPh5A9^M6^gs0>JT+iJuLG-64b`c7ZABuQFDs+<JCx4alKi$;lWXs4L0`3r9t`-;<
+zrZhPxu1u<g{1SY~_~ROVkpP}0<GlxiUP&XUx&}o((<k~$VmI@A2EaF72oeW!_vkzX
+z#OItR+gv?;!wY?&m9T|msO}Wem*dFmK|!>Sa*9mlU}Lu@3w!k`Ai^{37IIt(lVif4
+zG9atpMOCd!ItTgJUMfo(Wf|_JUwP2tK@>G`wL$$iX1P{hnX>MfIQW!wZ2@4^o5&ah
+zS8XgKM62JmK=?6)1f%~{it8(35>Jt}5I7WNGwAivuOCY&&1i?!8Xz=tnxFwM-2d`I
+zpr3tE0KMihnQB~48A!NnHi$?JR)XC^<si$-*fcFk(r*Z5*efj1=v)#Q<lt<9f_Uwi
+z+)Jbf?36NB!hQVOoW@WKpPc!<>-YgiK5aXJ8Ok_-$m;y(e7;0aDt<tYQ2JF3y^Tqt
+zEL;dh5k+0(a$L~gj+nEcMq?hDe@pI(7++`{`r?U{mhuSt1w6&QLPy!9%%HFmnG|4_
+zk0qLUug}R!PF2+Q7h&ur_@QBqV@Orvn`5Dwr>T9te`AZN7sP+#Np%^+>o)=uGN7I8
+zE1$<@Su9WC@de#M*-m;E1jbJaVb+gxhwWJkV2xxoB9ub}usvi78Y=S>rD|MHv_$8C
+z{3pP1{iOnxg!II%q!c$K^xXvX#y9R#&471ig)Pebk@0>S5eeL>_E$bYE29#Dy(hnr
+zz+H!+$g4>FBka?Z`TmL{)FEWmgyL@D(+?*+Jo_HY5A;YM+=N;mvucc<qEa9aXhe=X
+zwPRZC07s~jo!jy6SsLTv_@qk-ZG&rL5v?fy99Kkg&1IM>)V^Rk+{eeX^}1AWio)XJ
+zRhbeXKQ$GtxYw#A+A`@|1-5**4`YL_bTP|0OgU;rB#j-ps$??}5tt55<P%A5h<)1A
+z*H-B?-E~mPSwjg5RH>vE&wK=xyu1Pw?_zp~;Fc$E%cc;b9Qp-7J#(e_0BGG6#FIFF
+zt*I5pDT`VsIw>%>h`Ga6g8+{vVkaR{u_?7A*bP`lB&OLd+Me%kPHQBEMC1IY`kDnn
+zY>X&BZa(==SPBGH{V)?vL2NyNnA=v*?rGv4-=0Otj}~BgV}A{{12g>J2vb9l7-wg{
+z^N~E*zY@T5UOcfqEDtHs<hbP>Ikwp=$s>JK2KxU_2y743Yy%6CKyTJ|EO&tnLyr}!
+z52>y&)W!YT>^Y=UE!*|;IH|!Ih8N=C_HcDl2jVW&s;~ZlAtApcWQ|~^d0SJZo&lTk
+zk6kn&@XrjGl&QWT3!0dnzhOOKd`RSRNgsA%`$mVXOAvhEAeWq*=cQ0rlKWpOCM613
+zrFmfe^F|Uso+B&uCyDry1u2hg<w7m0S~)h7qZLeKiqyEyGbMCF$rg}eu5Onf-#|_R
+z%bWYuIKW7AiJV$Z4Fiu_s**JZ>(fxXW^q9g)8Fp)*~O#^CQ9{P)IBo~>qL8;ly|<t
+zBU{kS7^djSQUKJSw%gE1_xC-<Z{`%eo(s0N#-K;DIOWKcNb;#IklvFL1}m6zM%`Ww
+zvk<{R_h&c1`gbs!nb5+v=!~Kcjr29<m?&EFOtls<;&Pf$DZeKU2W!M>NgU6AQpq`!
+zJBY2iy{TlXEZm*QYJXP#OjpSk&TInC5+)oHAa!p)jgq0&b?EOKhe+<WOp8gLD#ufK
+z1j&f4aG#6m>kPWIX$hOdXB``vy!eOz>0Dc^36_t_9Mx1Wfeic&Nw(0PrTAiSzf*7w
+z1>J9j5e|^pf}_k;6J=s>G&a@JKIiD}<dn|i@3@>?rBn|{TQuHQ^R%smp+$BLQ<6{%
+z5apDe>IIHC+(4VPG@T}fL$h<#ohrOaWP|a_37FUj0mHPU9M*J+LI9GME0b^BqT%0Z
+z`!$^CM6619O3iUE=W^y5E$Cz$xrCEdHHIbv+M^0{YE@GZ?iQ6uIx;Cn&LgSynh!x4
+zOoV;)wO^d!3o%@hi%~9l;2Op_`!^qahnTehL$zl6I^#mmooRwemsu^-vBA$FpCTz5
+zYP8tcfy0s8*zg4Vy2j9pL;?8KO0-NQHsx-h$YLh1OMY^+*m<i;Nq>7J#ljT35`psO
+z5=)<1|LNCEIetH&H(<k;Q*ZIeT_>+|)^9J5vuXUdYY+`>-eVDwzNIi(dTH=wNh;LS
+z9{=QaWs<DLMnr<Q{oQ-9iCK{sHCdHXVUIva&yco0bj0Wfw*IRXC;kruiEWz@nrzyi
+z0BdnUz#)e6lm>x=GwK}J&fqd1)Iy9Epv8-3)1Q?6cv?1S+7>aJb>HC6K)4HMh%X=j
+zdEy7JUPs>j`!Y4Wqbf6hkLb^*TENOcHYdkSz3I;SW<xfBbW+$FVir>Ck!Vcs4NcE8
+zhemd~=qdR`*Gg9rZ07Crx=;?v1@V%tDJB$}?#*?I*ezdIz{Ac?E1o@NU|a&9LAO77
+zhlx+(@!>++N7!r+NBJh)k5Mki9Hmt@Tqk-LSnRiUfe+qz&oe-d&9(K|;#42syJO93
+zCe#-{(SiUCKCT!&gKgMPRXMQE97RW%AS8y$_-QzC))Vu0Audxk|L5?*tWyZqH8jw)
+zlMvxRZDM2m&$Y?9w<bJ92s_Z0ZF`x@mWf8TxD{MA7avLQU`jO-AK5Oz{3#HKP8=3c
+zccRNzya`<`?uj;E2XB9mDyZCMLCg#KK{dQEy22&Ic4K^-=b2jkOE%a?W(_#zqf5sZ
+zL4U_2T#4Sxs=gt`H-$Ce*D~8;W)bbw@&`BGM%+!K6hEV3?Y8guN0Y;<>&@bu7iY!l
+zz;?fl?6f!1kiaByXC!}@WA-5_3#J<u+NT8Tm0Po(S#vEStCMV$n7?GW+Ww6pee7R3
+zzlJcDF#}H&@cd&KQyCys7Oh|gq5lk*d83((Zp2Bg-BrG6-8T5320jJKz6{i3e)>On
+zoK096J5k*US-md~$-3LUGTH5onH32{A555Nu@O80*}=YWzTpx3`6)R(&@gGHEO_P)
+zad)Y)edISKs1;kOBmn1Yg49cgs}L?YYOBsIv9@p!c3#7twj$Mw06cTpmzp<fXZAkU
+zpFY_dt{rd3WtYG8uAjw&$4-UIGVY2k`nhXurbn$8V#?d(r{y;ta_<MQRf5B_NrV`;
+zk7I}xjg>!-WN`~p?G;U;4%QBd^W4!370gg^p;4L>E6Uk#66^eP7Fs=0lFH>G(2(D|
+zmpy@c?8r6G`!&68Q$*KPCX<cz(IDO0Q<a5}*2q5mUrF0vR{|Q5JtX9VtwgO$^u~sB
+z_aDhtWj?ImKE>7rXD`&&hRr**i-<d?>@?C2Uvt@FppXq-ib6WE*4hnsl9AuJiFYnv
+z?Dl8vuihtGUWtzz!(()uQEh(-XR7J<@54NP<xo_-H+o`pozom!b)Dr^`Ez8;j8z?)
+zx>7PsSzX-E*vbI#jks0NkNQWEny9U&%x;lyd+^t9T=uUun0fvC8pS?jL|F0*6peZ2
+znb-te3ZCgoe25gTMoEcpj|>C`DO2d5*#CL%g{pIuw*FOXj{L$V|LxrCVEq5%MNqSv
+z@2^-B`FkgK|Ck^SW+DXn@@hSgZnl6?F7GNNe=xFOntFi=*D{_oun5aE*T<EFRvsyt
+z&6^!i#%c?m&y|Od=N^XdN&)i2K+yyzfk>5RinOj-DS(uU_I9)dA<qS8{!@-h0MPV<
+z(u+=V6~#SIZ?wljZg>}_p`cCpOChf#?4P)u-s>1N2Sm*xFkJoKLO&+ePwHTZ?E;SV
+z4YW8D8EL8jnJC<?e|V=HTCunr2&RRoSx)kYSJ1vIRoty9B`N~~59JV;T93by1jYR&
+zpk#O$DO_YeskslddxqVvkRFRC9ckwg5_rH)TAY?11&5msh2gJ(mB!aEAiz(U5-xZV
+z3~TKs%et+s&N|H?Xsm0b4h7wFh}wDEEk+PIzyO+BLEF42?Xp&jKnq72RgQ=+F*6Z6
+z=$my*jeLV>BEs{&;lx7Ks_3~t3F)juNlV9EOGr}&K5Hi!bH;Yb#)mNgvPZS}Uvps=
+zK5A8z9q3rh9FHTRwkOPYPPp{oa8I7PD7XYA$PB8UkOCC~(9IpYGj7RS2>x6+nB4UW
+z1}@p)lL{u=<z&%D0<)uScif*+0dB?wpVUAO6LqvvhERHc30nmJFBfT6#7!75P5DcG
+z3rUhKe5m~0hYR?dW}f*a4vf_o7Ul3LgcH3yDRdlNePh-REEonXDyOgm7FlJS&;-*B
+z2#1!@Ss95aizazxhQplSm|J>1{D$lVN>QPojDT@)$;un)WQ*nFrB&(R3XK!gn3910
+zAcKctSOoI%krM%#);73!C6ozdJT`mLI-kCM=O#hfo|<KSJ38P*b8!qtSf4@Nb+GA}
+zlg5by)T{|(J`goFo-90+B2JpnGM1`ePAQX6;*0GBfei@}&_N3Ng~GuR(f!M*gvMgJ
+zudHD|{qP$miBk&6N6t$6QfrEC_}dZpqZhH8S>#8cD4G=s?SkLE;Ib(9^!m|qzC_kw
+zGDDbma!h7Z;*TJ*io2u>Pd_Xqb=@&(H@?0G#vSF3pWYj7t@J8bIjh<<(7n~FCo?Wf
+zTtGUqxo!etl@o4lUl1DWpRjT2)e_8HqchxAp*Gni8CyN-g5G3f4^0@9E|;gD_qs6+
+zWqI#oEA)KW>(V3I>#QV$@Uiq~hg8BtJdJm?Ls|`{^VqO`;rQc_786=FA(`Aka`~3a
+z<s+BMr@*`^TizUy&RFV7Is_z5kGpVOl}o6p>t#%NTlwr(ms*FNRt$yGKjiJhkv1uz
+z^qC?*7OTojNBH=1Rggm-c+RMmT^P}fOTB|KK3;ssHbjd&Tky4v#3Pof<wSw6ETDUa
+zLu*y7e5Gi6w5p2&%7~zkcpm|KQW`3?Avu53J+v5bUa<jL#}Du9DvV1$*cykNq^C?}
+ze3IR6ZIGs6eC$*E)H>VB6P-zx16&_f*vWGylfjKN@hm3phEK&pDgzN$xA3hwl*!jl
+zp|PGtL3O4iIGsZ7meN2itSqv2`rM8%X9c}1JaZx3z3zzfwjQ@{>b5Waq&tnoj5m>|
+zrCr02zoJj<=8~}r&i_4ri+dW>O{R{X{HUj-Hcp(p-$drs%J<=Mk~oR?OChF77s8W&
+z{?Txsm6QyYVm1a>A$^u3<IPAz2yoG%t3i*<8|`(T#q3Yn4BA#z_Nzj;c^Ye6811+W
+zFqP8S-zI(AGrD#W=6aLIwL3I;U{{e5DjfOr5xaSn)z2d!{#qfVf{$))FqX`KTST>0
+z2oJI@XfiKys8Erk#p{=9yVR9rwBXwCKPi&$yth>=m8gEQ^TB*hSriLCPGa|dxCniX
+zm5q!vz5BT6L9%&-U#?Nwz=&qDA@z|eZHAaNaJaKdxXaT#lkI;y7PG6#jdI-TU!xnb
+zjrsVLFyym!_Dqqdw=(znd@}spxVho;@%TFaYUax~Fu#FU3)jCr@|`%i1ohE5IJvra
+z<IJRq?bWjE;qDp1Kibemi!^rU&76xJHn@8x!%#-uIV*m|%cu7_4}1B$6to4voSYSI
+zgr1Q}RQlc|k@;|;*o7u*D<Y3KaO`r4b9hnA3%9W`TO^2Wcp#f9Gm)!Tei*F@6UuXL
+z3B?7?J*r1<4AR0{tRji$me5e;4M1#AM_!jdNbSP61-m-fr~Q7*s5j%E-^$)*j`a$M
+zw8Xb1&ghV2dm-9H_w`f-O&{MJ*bGh1%AU04cXrkkS{f=z$CaIa*T-%9am8>{82agl
+z_5KG`9(Ap(&{lJb|1W0OQsHR^5Shd&`1!Io^gKEXld|Ul>(%wtS2!2%73d;Qgp60`
+zTwB22(|IZXj9YBy+jO$p&MXg?E{lqHvPkb`@xCiVYmdj-Us18CYFbIn#KY4&JTcG3
+zOUYrAXp|mjE2||5(4+H_&Wv|-1753x#|?g`6F;#TtVGY1W9IITt0{?h^xPjF&%4Qd
+zR`!YKip*;pp?O^1^v@0fZ1YP_CT_5+p^t0xk)H6DATfGgVh(oBKxSzb)AfIwrTB-!
+z3Tf=`7f#V1>SoJ*W_B)IofgKPZmi>f$NP6}|8otmu1^s;{$+hvS^m2;&%xNv!PxP)
+zZ1_JbI!7ATwg+v9-#NPd-2`!2Pv==p8$e(Ur+BlVaHn_?+h`*3U>YMO$XjCxvPJ9{
+zJ-^yK7>V#A3iau$W{Pw8aA~+)cS2JR=6Us;hlWW<mqD9E+cp$mq)t(BdCEBw#}uy_
+z_Pw~5hp7Hh+;{JVMQI0DmlpGL+6j<vqhS|S_6Y5a{t6xFHQ1bVTg#dtsuqLkL&52_
+zifvr1I|kG9I^^3AyrPe(+L>t;($s`tnuXpT?;r4YHq8V%?!1N}e}f6;0*+hjboQ+}
+z5aQ1R-K|9z-3lTh0Tj!6eRmzD;PD5g2nXg-LO7}4fTQBJx0;$i>@AcR<fa4v!tk{+
+z-KG2^U$|w~3ArA(@_Ne@4YF5W_`{MNlB~-g|9%%DaL?_Aw>_M=tJ^^?fTs!5a!ED4
+zE~9AKi-~R8sU1Wn5X(y@@nKVD0I7Xx7q!_u>(2j)L{~0dHA~vhufUE+PKz@aV4a+t
+zj!=joejMhii#ysvL`Ax+gjfTQj8h2|eN2V3(P-UW9__iP<_G@{0t9*vCWiW4xD|@%
+z;r3k$Tk44)Chxywdk~E)L8v<?uh(gaJf?Q(_xf0sC0^_)7YDGt_L9q$Nw&*f&%TRM
+z9&zQC5B>=3b%;>&3;22RN;%mmnRax==bqmf*6w8QE<4<q+DgVds|I&J$=Qw<ZuN)Q
+zqWi<imGqs{?(o6%GHC4UtQ7b?AQRgLcYV@>_$g*vQk##6!~T?-h&eYpjB2bDW?ILe
+zZa+x`cmG1IbAQbJ8h`F7RUwMM2?z7_Cca1*nscm|W7sh*8Q5Fs=}En4*li=stXr!+
+zyr4{ZvZbHJY&s3UOkp<Ps2R`+fU%o#0o29yLL0<f4@1b6qu-F=(h`BhS&C(sl}^m{
+zGQIA|a)ZBG{w}tV7r!Q`8TIZyN%ZYaa~751Si?aQlIzx9+K44ld3#@YNa69Z+Et$G
+z70elVfa#s{_@eImu&DV|Rtmy~#D68yj8v0+xtaw_o?n!lORoMkb)Ex?Q+IvgyNLE8
+z<bwGSYO*u68?8c7zhtjMJ=-hlNEBXL%yBd-e;{p67%52=BWfdfJk6NSs8b!@ls(;K
+z{f@Z0u!|c?aTOm|Y@IPz;Lhe!;dd(7x`9xR1@<zyPW~Vn1(*iOZi`>J;CbG^9e^5f
+z-p{*Ya_T<%-mUY=?_A;kMx3hEzqEOtvl|{KVb?Or0+1A}l)^>4?sS}MxrFnsxeO>?
+zHaWa5^eQ!clDta!47krudgYBnHE;!gkzDqy<-33lqGNGOEK_ljM~FXsrtTZR_1bUz
+zhheH;VqNejWbLHm1wq&m1zi2S?v~UbqEIiC=Yt>WH=hi@`guyoT5>@SYTdwmRxg8A
+z)=)o!$|*=Q+qbllTUVA?1Op+fF%Y5-f$4>_lb^yOeaRUzM}-o~N^8nwFfTq&)1RV{
+z4RUkB$P5x>k<`RXeT!$Z7CrL9xS3w+5_kSboyAdpDpem;AiO$|$m=>Xf<3g~x(-l<
+z9b3>q9Cvpp?w2Bw(sVI=Pe>Owll*S(i)Yz$P(~S31H}^t;=LWf4&_?n(C{?G&m1QE
+ziL!;v$(eiTxD-R1C6c$xN<g&M9Dwamy7w{`=o#AFln0H-_c<)j0-(6FFc6}ukoKI@
+z3fHAYV|jm66Mzs}Y$8poM`!P!HD*6sZ5HY3I`bJ)B6h`tC+kc29<0th2X+}mTMM{G
+z`uL#IoCISduXH=QE(q>sjPF3THRDBqsq$ro+*J-^aEkd?w=P@9xLWkx?E}XihxC`%
+zLF7rG8`UbfKF#}5<+uDtjkz+Hp!{*gyI8=tst5@Bt^=6k$E%L2sUwuJK#|V)49ARv
+z9GlwDHL~61UTEBnq}mH>Y(&$)M}qO~2&$gAuBsJ|WMlpWky_EN%88YyhOMr7*G_dF
+zako@qvy31B#G{Pe&;EJ}M0o)l?d5eB;Kyg+09)}XQYU?<&fLYXhhG4nViXBdqY)>E
+zAWDQp2EXyqF*$%kIEI9T#U@~jog-A#3jC$HWm7w?CeWKONDFRx{14+to0lIUp{B4u
+zkm;l>F#E<$P&%#&C7F-!5_TbGsWTRl%&cJUKF|DErOL;Q*R@I<?ULhkUh&E`4x%8l
+zkVA>E;6_)B;MOqsMNv3*$hJHOd&Ga0Sfy1uZ1sx9M{<Df$i3(<H$F8Q5!n6wx&WRg
+z_cif-UzU5=nfe}E^j*$YJGXh#3l<3@no;XqVaQdhA{|xbY#iU<S}Y21)Fm1R{Jb6b
+zq;R4C#5db>-JwyuV2S;Oz$G?1R%oNpGQl01&G3mBsMkA8PxBToDg>o05|utbv2`XH
+zI;*;KYX4Q@DaRk$gFTt>#CMB#k{SFUpc2VL_q4b9x}`bNzoQMCddW6ip<DZR2Zh)f
+zVa%%);TR^mbKd03z%p#NAP&RSQJ%DLAZ`yd4r6piFQ<1jWnhiBf}p%$B!RB^WLgKR
+z+Q<U+)0uu?M#z0m-5h{2=m?4k^^aLV5KhRubs^dR_k+{>T%gj(;{!jpG1>k?BfSCl
+ze(W#k{rpmCf8h>Fa@oH^zzviQ>3SJ^sS-j!Tjgz!Dsz9Vin9G=tur9wtS{3=wzVV!
+zoo#l?0@ao@IpA}}D!XCM<G>a7L_DF#L=w}&K<DoobkpZ<5yS8`U=Gpy2^a}5@qpaS
+z8Rk<Cx->cRMSu_%5M;UyT)`<WDr%#vM;$2crxV|yh~Mh;rP2)lQu8I*?!sV-nxHo@
+z|IM+zc<Kq_cDJF|Dw=%AwI&KuC!@c^FM_;Vjz9j2I+m)1!buT+0FdB$0u#AMDy%CQ
+zbZ~{25P;+B*{%f$?fyDwRil;qmOyVE8qR1ao*x$n55EY2xv(f3#akrq^m$sZRhgga
+z(a^u+HSKbbvlb29%gUMa^FxR@tDF;|AO031R$)c)o5F**g`7opVIEgtg3iz(I)%vu
+z1)72(Eldar4m@HgjEOT2Lj+a9TVJVWm^ZFLu}$9$R|f0{+MrmCaTAhB@$E##kRph#
+z8bV&hOZXS%ttl_u-%kXh1c;+<E_@MPzz3av;$okQ2vwA-!K#ZDcPGzcpZ?Ab`ccST
+zd5L<jy`o%z!_vMp*I5>PpVoJ`%F0UA|Bg;S3AvasJ?LL6s6sKCeMAUo)OaMw-*Va}
+z5OUqkbR6QAHQ37fNL|0y5yxGl65GE2QVe0~fb?ME_llNx4FrbL<9XIwpY^&q^P`E^
+z!%blB!Heihb?PR~$mwc}{PK@Gkk(Z4P~pq*S)o_W`OU+n(`(C_Oy*YmT$)Iw6C-uC
+zw81H9OM3ZfuJ41Y!^vUXQEm1f$7gXl9;4>UZ*=|cn~+46+Cq)vS1`nd1sdQA56kI?
+zrTbD6-EDSmaW+Hw*G=>~bQ&|&M^!lziBJ0`w>li=UwWw8t2SGu^>%L)Zl^Q4>r7fs
+zc{yYhSc7b6=Tr;vR>@bjYa`f|q+?7u*zAQwC?zbvX7-EP?n&C$F3`)Q!LNkuEX`qN
+z4i3QVH<zC56iM=;)4nJ+q*fY8y2>|Y_m6|Aj2k~%pEG`wmo{%f*dKwoM_Mep0_Y8O
+zjm_@}(Qpa@ZYhAP+OzEJ*@l({R+W%+uWl);edRPlZXmS9EqjVB8-Ac5TVuR_L0s~_
+zf0x<y<DvAB?^8V#gucIX;Ev*F22eS%Hb~RYc;#4g41fg{z$g2E?x3HbuWz&=005kb
+z{=4}8cl&H><?=tb&%YT@j+vs!-`c*z?f8IJ>Gcb?vRb_!n(YUeViL%vCFNBG%vn}s
+z5EOaqIrHCFTiODf{eTv@(KHYBAD4}uzZZi84jxF%pv>ClE5Gb8cD!gmJ`v-{<SHJ$
+zXrVGvbvkVViDX)DOd*Nk$I&pu{T~fooMf?ZjOb0jQp!rZk}~U_+^()7;tQjpUF1M<
+zQc7kH%(*N4(vw8jRMqJXe6rL;_UWZV@?8s~&*#JVT3~KTo6(urn4H`qb%Qdfh1?x!
+zQ~tl6N<%jl;}c^SE9i~69jwbdY)~3*TY$2_J5S8yl$@n`&nLRg0+WrM$I=}a;i!%{
+z{2<z+e?{u30{!uMnyE>}c<k7T2^MqdxrX-tRDFW0$AJ8Z*=t8$(%rX&w4XGWXWGQY
+zV7Bpu#CM{?-=$T5l1z~pd`AS!k3_-kz#fOf$XSivdF@^<X1w-uZ^>V@TXxESnrSe>
+z8jO4<O%=$MnM7zJ0Cp*hS%SJ>Y!eD2t)^#WN5B}2unU@WxEexK89#8K<(p<G)X`WH
+zY)g`f*N<EnKKH|SE0WNNd??z{A(LCJDd-lQ=qZtWYXo7!TaDCQgJgE~=-D(u^0*N9
+zspD-!&7|C><hPNN0PUJ_BTM{i;FjsvdYJ4+#ye=;geMHc)GOd9bcZuVQb7_VGeR8G
+z16&Q*gy8Q2#nM0bBmxA2xeO36R|5g!41D_&GQnmKAYx>mKv8GMAEjT%b0?RjHbD!Q
+zor)J{4AqX)dZd{O&Xe9hb%ZfJbc2o9QNZO3c>s=cmL#Y_!+0Ac3yvg*h`@ltH;+(n
+zri>+G9=_cW;|a(F)}BcL1@fB}!0%Rv=ms5uDq7A14(HdQz7u9N0c7Q2<vtyV5)&@Q
+zN`r)V?*K6*XkmUvaaIFOA8s8{r#e;=Ae8#3hd)%P=tg-F_+GSM)v*QKDnbw-;?pJ%
+zB!MHApK5R~Kwwsck!Jkj%Etj2o+#+kcPpv3iw<95r3i_@aSu(X&6E}yo|8XW_19Jh
+zyeiM_M!2RB5~!@2%CDsdry|*BMPXF~pX-`MN{=;u2^G*%i?er@530<?zdpC%1}BS6
+zYL1Z^m_OK;1)Nq&nQ{pTQRN<uo7Z?|Lt#jY-_zfud~+VjAMDEwq8ls=pSG!?!g<m=
+z`b_B*mUL5Aq|o~9kSK`euDgIJWm$Ih<c$3C;d~Jb_JCSuSIIWilff>@T@#}$h=CoP
+zW{I@Ezdks4i~)p9d6AG~@&}NkoZzKk&nmDhXQd|!mC6v)ynnUX#jc(MNr4ynuqjwh
+zqdTL)F>Jv`@OB|nXt*JmVD>nLQVCe|s$OMP@(s`t{dHe!f~ImtpR@Fv`=)@7Eo`E)
+z2}l*S+`4zMxrMqKx4N+-sRVodPYF-?<NBE<<#~dNymhHXd4<%h#=}lYu}zj;6cyHc
+zKc)=DVl5bG>_weR6_sPfs|l-&%3LU2pT3#&g*VhAJYAITR`>q2;p8T4)sg;j(4m2|
+z=)w9n^Q?)8aQ<H5KQ@UihF_(wgKlu{vxyiJ`Gdk9FXBQ%_=NP!wS=^Rmf{5-?r6KF
+zqmNtHY)wv)Q2R9tiu68-E%3-X=ikCM#XjtkIaMsJXYajUod(RMtE}p9^%RvxPt@Yh
+zCxq$B!}IZAcWX<=^N<^i`2IsG;DEK&>nJ{~oxQqCyyIzbz~l_4aw#cO>8WRr%!>45
+zd~-5aPb9JWcH|c!J1G_Z%!qLohEkVIv8`&F{pm5VNmouDUR;q%_*98iIh(cZawCOC
+zI(A9J&bfJd?5k%%XI%?!u;_wF3w(cX)@p4@6i>8zw7fNeB3%0GFzl7HJ&5zumFbi(
+zZ7bI&rFB5z(7)0c5{@*@r0+~?Rs(veg#@cjptyLzSg&;Zt6=Bvnj#SRQcYWl?N_XA
+zunAN$k=n~HAt{cHS&1yLmEd?whHT9pN?)?L<3tw44401@RgvD@L-PzyBp2S!+RZGn
+zuQnnkSYW&x8~VU6wR+(M47PzQ4B*_mdR(oHc9cnYLi-x4y|1VaY`n;folG)V@|VD<
+zVF|cxJ-BGiVAm}?W!c&%=M1UPR_1vckEHcApH{WU(hM*czJQ9kw3d#ls$NjC8@4Qu
+z8;I`k^}rdA9m28XS3)6sMXH2TD;y=CDWdM-irP(2wiqp<thOq3RG5b41*<kqG2W{=
+zBq92rCOO$W5iGv3z6-7H7)Q*nJ@dylIfA(3wWlXjo#s6Qq@?`xKIEykr5@E3le+z`
+zDPon%-%vl(Gu1ONG%$U~=#^xlntvDEyzr+RDwo_J$NNfuWN*Du|L|P6`uMojaSZ;5
+zh3@>8V$?4+S6tkK*oU0_g-Go5vd_G$Sm0ci2?iUKXaAt-CaYEl(njL>Sz<4K+9m7m
+z?p$j1iXM}o-81Cgsq<w{R`tB%<Kf`)|LjlH_Iw|2++3Ez0aj&k!}QI;wt2wpUD!WC
+z{OLJE2W%_!@}Y?~!rumlx*J?NyzTmhYOSK@YvR2u2v&&NQML1j1bW;6l}Ml*4}$C6
+zGN$a1VHV+@Tls9t(q~RjwvLK*Le7NQ*}q3z4+*~~Z%@i~jJ`DldRt<^k?J!d=V$Vt
+z>xh+E-v7>XDat%zdluOz)82D-PUktnj7t?I8}?CFfdBQ!Q#1o*eqZs@tc9{PPDw3Y
+zP6yq|;rVe>m#J3NP03|T{7jlZQ1p=Pj0hm;7*#b)X4J|lWN<5rnU36q?OvJsq%gW8
+z3ok^`-P1OjJR)p)ev!Witg{K4V6W4R0FIFrEPE2C#uP6mq1G|S^i0d0f$>-{yTpE0
+z)EaH%n|Zl6eS7LT_d)#bHvK?(@%?|r;)!IsABU3w0F;jZcS)S1p}vjH|J<}(@mi{G
+zay0BbP~$i-Z}FOY5PW3l3#$qJqcOc-7ciOLj)N}Q@ME{>TyX(kP2b${sgz96_E@tq
+zOSt5{fakF)Cs9t8EUr*Eo9@>0#VIjQ0&n~U!bas0lh#5hXag=;C}s+GS)>v!iDYI1
+z?k&(zv0d{<`ZKq#&?`T{H*Dd~eO-0=f_-zYyVtfjS3lfab3+!)FuY(A-C6qJYhAW`
+zR=wTjlq+?@B4l%V*Wb*YeP3*CU3IT7Rf>l$&^KyzZ@NF{+^DJeJipJ;JMp?%E6+sK
+zot5KUK|7w0Zz}xWPfE2v-yWVHT03t&Ki;;VeR{F>pC__=dps0>eCxgpzh=ItpC7E>
+z>@g-27-T{P<#kA3QG0sB2P7D#OBN_-BMD?6-y+x!tOAn$1)8Ub^^;Hya!`uO-AvEP
+zr;&(>^_$$*kW0OU_`f@{&op+ud{1XD{F)aEA%0-@&uAtlc16;B!^nJheD1O&$A}VM
+z8zx&_ucH#{D1hK<Z5MH@HX(P@1=}k)7G(=^3#jk@pVqE2s;aGPAG*7{8<B2MS~{h>
+zyE_C0K^i2L2Bo{ZOS+}Iq`TugzPH3z@AbapgRvQB@Z)*rnrqfRd+j-4M2SRN#KA+*
+z(NAbDkhMUv*5p-}eZ*X{XUVw{!orqW8N$P^M4}TBAy^1M9)A&!M)Kvo+Tb0?_=Jqi
+z8pseJfSTpgZx`E_<ugFzD0K!&<j1%S90Yu$(~$ZK;q_RGJBT@I<A}{Inlo7A;^SN2
+zO&m{D?@gkTx&s(*9M}1SMPCGKBO@au{&qdodpc5M8sRw<&m4(4xU(K&22dZql-9|f
+z<Kp~kS}Ce_=YtKAMDiB53no}W{Z{(doxyg|GJ+pu5M*Lg498Z<2YT}sNqy~ns<BhV
+zR*<M^A{0~V-31Ur%1#WT<H(;5kU`SOm>e_5`x!wC!^~$gF<(Mo<57xW`bCMO)O%jz
+zKhakl!k9p+6YKEwr`Nz1w7`wonEIf*MsZ{!f09OIQ;3j@bm4EFHB3QlRlys8^4g7)
+z0Vi+l^mvoCafd2l8_eYPL*b4o0iz?zdQ|Qe-(rpJa-p;-u){Y*jEP!es|J^W@LZGN
+zcrdg80EQA)OX3w4XMd&!_r5gq@}!B+_8VXBX2Lh0K*u+}aDIXXOkG!q&22VphrU`-
+ze7Yx(>J{=<*MUWq2a-O3m{sPj<;}|$(2+RC_{e$YBK-Wr%9JjVz=Bo@@NHyvx{oM!
+zR?u%B_xCK)()ya>#u>5VaAmr`Oh4d*s^deUUh0kYu{@)v?b;9n)jFW->%H><b5~n>
+zeZEclD(n+tO9F2~N|K^Smx;WaFhw{89{06}lK(+(JH&_{@1O&67`g2TGrd84j9+!+
+zqxjTG<Ko%@fqFzZvAI^Ysm|#^J;DGgm`yOZXg}7<e0f(%!!l-a*G(ir^qYVa-*ski
+z7kd%aEvwVws6$TrvP8-EbG;D&kXp4eylG8!Ev@l8Dn!E$4!^s!n5lGazxwDiFR}|Z
+z&T$o57|M%w*gMiUG6sNxr^Vp;c3IVeZSSQTUSsgXF$@4-2^mzxrYz_29nPYz!YQuJ
+zA&I3wrfX-1heVcr6vCqWT0a&f{b}|oJ1^&q$qCIsnH#8Sn6BEZFj&y#;?Xkl^p8Qt
+zCs)&L3oLpWC=OIoY{C$%G_T}B)Jrz#>GW5N9wl9j9t4FWTi6R1(K1pEt0iV~($f^R
+zzYi0}H93w}MjYtqpa=hw8VR4mpDp$3Mqvlu-`ygMkvG~v2wnfcU^0WdT$8v4FV9LZ
+z6yc^sU1c<3#c|RB9iX+2pV@4NnjDBx_-1hAg4G`fGX?bh^Cj}YPEI*UM7gODcLSM#
+z>MH^mb$pUX?7qI9g`X}{(oG>fF~iK(AUQ?gqml;8QM!pYANT9&vRP906^W9+TjbIC
+z1lLH8e~(iK9R(<dUu|SXQ>Xg`&~(BNWzx;&S>&dqAYh|1COZ8vLN7qy@*#fHp{l96
+zb~8$gZQ!x~5csokA_)xdH@UZRIVYTsp%!nNnDyCf6tGX^v31D>L2kCQcoei=@I4V<
+zE>X~qcb1}!RaN@%>Sp(XH&{;)o|DqK7`ycOM>*(2aB5-L?m%ZuZ$Fpvf;=8qJ3=zE
+z;si5v>97dr^p^C&>FiEYOz8rp=g{2EnA{D_o*6U@?nT~hRN*~t$*_%U`;kwCDQ3yt
+z^1v>zg$d*s3B<f6f?X{314^fx3)d~w8V$Bk6~Nf|Md3riZG;h$0BwulPV-U>e&XQE
+z1nv?VkLfQ5-B`o<pFCRKbfh0|%Rh+^%ec7#D<02*N@#KK#n!_exU%pyA6PpS)3n|d
+zH*uPK>br%rH73&zTdCI(d1Ey;bRnw(-C-yS<AiD#DmY3ecf1I&MHkHL<_FI@#(!N-
+z5~o|~!)h;11w{}sUs!qzVhu|lbkU`{G?m#X%=#HteuW>(Ni-Y8KA5I}GW!wvxJ-9%
+zjDCJGuK<e}D}2k``_g;L^hYYr3WluGNs_Cen=2z+2?MRXBg*!LOK+H#a7AYHKCtZg
+zzf2u{R!9YpjhQTLfNi%FusO}vr#MM08zx-BU#4v8<yBy1PRCc`58*m*$YWk`M3{|4
+zu@LrNWB4L^%LcNcts+^6(hQFUux1Vs6OGT76&?w9=T+j3(e^>4oYq=`w9ZI*jIUmt
+zJ(&y+Hne5@E_bdmKg0QbK@ww6)d~2}>Q-0x0+OKRhPJ99r|ap-xIc575+$)xvi`IP
+z@@f3rKGP@OmDf9JvMOu%Rw;&~{A!Yf1%<6!+CDPS()f!ZLzQ2M5jmi7Qi*zQYmL#;
+z?V^mYkH%jrv~{JGL>1W4I{T(dil$0F`&c~vq9)>|FeXl1OPM%<MxsErZ3@0_KJ8Ga
+zj*WrD*|ZLqOJ=z<bKx<k^`KIv=-l){R!8UT1j7NxPBWeczOzLn@#QosPa|UJRI6_;
+z?WPsqFl=3&;Kch(21_-q)Q^n?X0)r;3f5ciap#J0KT7QO_vnW`2Njk_4S1bbVWS}~
+z@!U&SaZ-s>>`<CVGk05iyyu_~;>4OxE_>5I-sdbjqm&adYG`U@0eqhBQN{dh6&tNy
+z9UdeMF9^Zd!rqES72VUigc!^s?}1M{n>M$_p9^0hQ-@zg_RDg!m5oe?0E}3{f)?wk
+zKX!)i2~9!DP-f23o@(}C(N6N~7&3Wb%)Mgw$ku~e<-ms+B)ieM3QWVIv2J}WYln*=
+z;@VkR=!T6IxyP;<StsC`RWDo{)X3~-JZhSKikT8KY8fU`qVUA`x~7<lBtKuNv*bjg
+z6=qLJ4G%sP+ojC(@(WUK!NQAR*^#<&vst9i^PsrorZ*yArbR<u?b>l6MXgFK6t_5+
+zsvKF(NI5*#Ol<2EF6+BR9o8lZ_enG*q`_fi*2giIV-Ivp3f`B}n!y$l%2R{M$@E&G
+zUw?Hn@XBwH6_XOuBqnn58N$2;!yHfkUgXmDxclo_%6b_)p{A2SQmL#v0p$AgOts!E
+z7~1!S&b@)N(^X>1b~Ds#*zaMwSe4#AH`lhF{J>rP?yNbREA`#`nk65CQ5JYyJKV6U
+zF4OlEaW<XJB-eUlPv!d3nQ~^kYlXDqVzhS`Td>`GJ`?!yXH|x06rQp&v_=WLW~~TT
+z6H+-~lex8jiYRnz(B;mE7f(Ndr$o<JhM#alPf3asAfj60O!U10v-L@&QM<T&fv?W}
+z>C+p<<P|^T0kBZnsA}q47X4y)YY`bzlc70j%wA-Cb<H<OCk2SFRXcJ?sh643Ce2=V
+z2=*ZEmsC|g#+ZeH2nKHzMzNN3y~_^?B#=uFTqCOmZxmt&?LbXc&3g%>3o2|XV!~I_
+z8b07=B%22|M?F~2Go1@q_RQb8U@E9bt=7A3@lSgy@8RpWvF?~0hEer0GorcqWesb~
+z%+@$^BmB|L{q(4pZ>~k!(qX}}sk+y5`sL2Fqw(CPBO9Be`1h1q4iKD@dh!$}OBU*P
+z%k|myBsBZPz5$9pys|a68$nxo_9)sIf|Li7zQxq(^(U_Lx}A%Yxo^@T*@>3~wg@&r
+z(;UTd+jQ(<hA6^AH9kVVC$OLFcX)ebtyri$t?EmUw(l!k3%xq?Qi%8Y9ZyQ$0M|#0
+zG?x6=V-aOSy^d$H2EN<#!5tOJ69|)s1##$(VBiU3y<~{mD4!Cs4ec4}%Y!^Ex#?xC
+zm;&;jI~O3mxb(s+_0X#+5HQD_o)}s~)D3?$AYpBf6=6lMVr|&ZCy?w-D9xypCaA#C
+zLX3zFrvfQj?_Pn1EI{-{*jB1w3g02{LbU^f5GqY^4V4><oeMU(Pcm&~Ojo=MgkX)A
+zUjQX8_87Zhc8IqlAw&`pCKtnqA1fOsh|AKX?G@J3${FYvYelNfA-);XAor?aovh$9
+zyrOl&21VT*s4WtSFW{rF`~4{(nMP~{Fh7G>?YobNG%bTHnUv8s3T2h2Eq0jD<P)IP
+zJi1QpFl}{wTwNHf(Z)-O1!lG3grEk~l`hU-U3noI7it>~SE8kaC#5IX1^n`5T=@j_
+zc*EVyKRm>eP0mzumDWBqAU#rNLSEIGGO>T?#WgroS%OUW%>q>*DJVDOX+8o~BaOz&
+z#}NaDbX<&_lPs>RoYsb&8!{@$a*$69WiHayjDoK%>?>cB&%!0Av1NrV=O*Q<%Vktp
+z-=aS6={HR868Ep1_8YAXyNsi#K10Wh>3yz&Z{(A=6l%4EQMiti<lwJJYq&r9=G?BC
+zGI&!`Had(2Juv}X__pf=3W)(j#OeOz#fQgxns)$`f<g{=J(bT0M2;YfH;5ZD?-L%A
+zN+C&XqQ*JGIf6rOJ?-!}V<0A!i)V=zZt=j)va_=mf$Du@qS7s}yTF#&*~Fyh_PHx9
+zzJjwZ4~#q1wMd9Oe&0iPN!mpmuiL>bl+H!=KF9O<pxhHz_Hj(GLhLT2+CnmAXxc_!
+z6DI!cddjQ{#^O(lpCq6%3G{?)vqR*xw6u2TXt9>^$C2#PKs#jZO4cK@#U7ywM92~P
+zU1;4B9!%%t4wSGhT{&&H!N&L3Gho%He9CqV^;WyXsh^7@#>JjmvTc%)d<^ba>7QTQ
+zpBVbSnDyX7O5UBL!Jk1$#F$CE@KIq6Ug{e@{+0M~Hgu*_Qy2Lg?Q{3TMH54#t`dP&
+zlk3?<>FO&u7N@dV)^`w+4*qAbvUIWfhwS8Z92|OM7RCl7iUfCWh)4T8W!NpFqw^!P
+zhF?iFm@}SA-ol5juAS>YzRCfk<LM}MDjZ*4#go{0+}1^^-;rj(A?d%wM&4?&lpLhw
+z`2Iq21T1TjL0=_%e9pAB?TuwR?@}kkwD_p?TX<<bQiHv6>2j7np_%s}Jws?JirC?)
+zpVnwX4HG9~m0!16ReG(A4woD9)6tX5REv%;36IN<Eh*ms-b=@yM^ouck;&P(B!v^b
+z6T)gs=FD&>c(LY8Cq1qfaM+>jS%1y)DB=U`&ElaAV~-_#6um9}r)5ZP-X|dNk<Xkw
+zG1nmo#lj@YbJN|*I>o`?DiD=(rfY*)ppeH3-m<}<#(r3olt4A}*N}_mtf$hEizaru
+zf+p=y>=J?A$sSv1iHl&M-Kkja9VAiX<u1ZMHNl{t;P0YSQKw`icvLB?UpZ(F^~5Vu
+z{BCp)D{1zL2wcB8ijzeir0gL%>ZeUliLNl5&T{Ba9h%AOH|&S62SYW};A&C5@(HrA
+ziH10YDwWl6mY%o_ZUsTdY?L3RO^<r)D_vaVwoSiQifIRrcncgJK){%XK&%BWXc59d
+zMT3Sv=~OhU%Dg_df<mix;Fc=GEGen!mS(d!lu7R=4NXyw<}|KbyR&?<sjV5yI0P?S
+zDezHp4%%Rwjq(;#<B7<}#`urL4I<}dx?#trwXdnGQInU^+J(hwL=BH1(_Y|2w4Q8{
+z*5e{@mxPFLE`|0a!Bq$b@N(NqU=ri3tN<KI22we2$~EUKbS4jL)|bO%E1E|+F}0Tu
+z%{10y@R8%ybIGA2)G(evci^dLW-b`iM&PTq1C&|%Mm~s_;l7d;d;X#I3&I!*Qx9g0
+zVTLqCj(cggI_dkSLURSSx;O5EZbOY9ULCQNo|DoBakd!bQKLiCBrzC6C(pmMp0LSE
+z3dgPS50pJ#sPVb*bUD%-W=B+?RI~DXLy8z8CzUPy>8&TIb-tVshiEXI1fKS092AqQ
+zXHREO%UO5|2*ps3^r4>b0g3NGpjw*>RLxDMmmVUzNyJrjw{6+E#$e@YP?TD5i<@QJ
+zaBw8uQ$yLYnhB{T(y%%uLM8coI<{?7aCE&%0yEQ<q0DUFx{2ky;V-t6WiTX2S&zU?
+zI$E&mqf-)>!Am(eoqLzxu^Dw5(DUA6rYFB<OmJQHNfwgW76Y-t5vnf`6pqe(KHJI^
+z`Z@?d>P2^I=wRCky*^B_p*d-OtB|uNR|__EP`?hM(<>}jIWfoGNpSnwNY|rHL#Nn?
+zWtdZBUX}&FHo^2)_UvPI_i51>87NQk{N!aWDudKevQQZvR%1;4p!l9c2^hhS^y?M~
+zA!3?X!-@q|JdHpY)`J&-x#Ht};u(Lo6T&o~oDIsHwZ0FzJjV0t7+*M7Fo5O@v=X3k
+zhoBH5U`_8uJfZfB`+&B~wu*p-(Lo}2#2L$gmO8Q<*Y;ljbPQzkcS2OQI=Y*W7#gS7
+zh%d`GD65^X&^&79CnU?r`UIM}4@UPEuGI_qw?u97KI;lwE?wdlC->V30h~hzDw}3K
+z>-k4%c8l|w+8B;9$uNETnO4qDSVF5;f{Z^bwUx!0#TF`@Q8^Rx*5Zq?JZd6m+K4c*
+z##hcET3A8q0l&=261zX&Tbi*s=&HI{VYs_M@aF9#N<~8W0^TIQ&EI$jcgJbWFO>XI
+zb<HllJ$&5t=GI6j_t-)(4r8Kf=ryFvsFUf^YhH1>5lj7eXMS1I7(F!u|J298-eHZL
+zOL^;%#WKMTg@6lEDal@k;8a=C$kM2A>LlUn5K-Q$@|b5mi)<HRXW^m@8gtXwjUM;g
+zSsn|X9_LkE0Z((Ty}6tv6jXVyanCDT_tY52d{Jw3vdjgB8jnNdVDYA=HxX2?K=g!H
+zX?@9f-lf?_B`GB`MbgNNxc4rCpS(nJ*Jpji_JyWbL_@_^{bM(`s&G)@5{|C{ozzR`
+z*ue6bs5}KDJ<=6KMkYc>5CU_BB=drBtg%rwM}Ls0sSMjbW)ITLm&%_q8Hbe;F%QZ0
+zVTyKrVUmT|TG*j6xCe#3@}=f*1o}SOMdcsC$M<cgMnjyBp>dVG$dS%pCYEzW^_k#G
+zGuYq+gNr1ofIgi3;%pmhgvP{Tz&E%n;Hp4v0!|ITV!Hec8jDj%#GgT9ub6);1Fqbh
+z4<G(gf(hH)g=~!N>@|1}YV)WUgy_c0`EbO_6yD0HXPhw?t=#FvgE>BcwfXH_Em*pe
+z>e6Plz~F_F<lseBxFLS!z=T6&bi~xw;8-oS0Y&pbWM*<RD#T|N2^qP;&Cf<HUzxq2
+z+F^x%BIqcto|ZO&FdH~bYdHm}WT!OJ{*JTwIl;#<l9Ex){Nd&_X7}k;AwA?hF5*e6
+zanP!a`RNiea&Gxzf=FGKsD<wIBwobl!TfM2k4@>sFM#haPgmNNwxaI3YWZ{5s7cZr
+z)@|*D=X!H6)~;YY%8i}>NOse1x#dK#B+vXdk5~`}Q;vwm6MIb2Y0JN`)vQ%LYO5%N
+ztJSj3hFHQC3$fDMa#sK+`B4=ZCGcI>RudSsHX$u6wY4;*_e29r5=PrOxg?2nI}9m$
+ziznq5t{Tj5Sr4A?YDG;MO=Hy42{bT|iOQ!FhCj8jDZt{LZZAD3JNJdInqS|))2N5L
+ztn<EP70c-;AjD~pm@BhKsydMmB0HR(G;!k6(IN2=Aq!JXEKmyg(q`yPm@I6>n@Nt5
+z+Oc|I^3gX?X<X2AZcrt$nYuT2H&{8PLOg3vlBu)su<&xYjskgVth#5OU-7O$o+j&K
+zb-!SWxwU-l2bj;&A_vf^W*6b~HmKL6iCr`S@D<Ap9}90i!C$+Z6w8W6GH&6VfT@=h
+zvXRr<p^OCNa%y4bHYTgJL}1fn1lqHo1h)8tx~;>mwk*6|7l|?y1U>1;=#px2-8QW{
+zoTJvor^~B!RL_gUSGfkwR(`44vAszr(DgA@0Km;wQzURVOxPs8jSi6*btQ@b2hYJu
+zFFuqCI1^d$M~&sGn_W>w9hvK?wfvyMHZwZCmCHKolzND1lA(B{<&xuqcBov!Ke&RI
+zag(PO87l$5khx_M!AlUrTvfHd(}$p=&KJ3ErzBTRQy*L#CJVP+9V!orR&v0zV(QS(
+z3WeDwRhk`P1|c#}{X&D>J_?|Ltp-YS!K8rYk;X%trpcfdljZoVV!T3JsK2#f#%cj#
+z0hQAX1A4x!=xF(IZI->V=o?GcO&vp!b!=R7vo`24*cR1cpG~bIJb3?sWv5b6Sp7KD
+zNU}~6SO~cbk;-$Iv$F&Ev}A<JD4GJq#sg+9y5(ndk3+5bwlsE?N)ett7a%p3HKF&I
+zzU^XPjzBQ8ZF)-b7+zIpH0;g+S1j?auOM{kT6UB0_TFzCQB(y3Sw4$gwYl(9`YVk3
+zHH~eAp2CC=A~{Fh#2OW!hjxxI(fC+V2m58U@E{bf7LmehsXX+jO$h7sL+fY#s07-N
+z5D=VHs}J?w&#r7^qtiOFW(GRp%RB>L#tJMqCw?R7zHeQmvAy0S7wE1PJpfmMQFh~V
+z0bTz%KYV4S$)$a&at%)riAG=oYhlDkw)e<Kc04~&cGGF@QQb`PZq2j_`*G9E%*HM(
+zKSE>gc7NMo)9x1gbDPp7g<gFlZ{+NnSU;pezjJet%X!<Lrvm%r`xQyppb_UYo1Af2
+z%h+h0#s#^FC=<N=DZta@<8v5vYz2&-$k`uPs0Z|rbmzdoOphA@d-q0^X2__`E5kWB
+zDL1s5861rtaZ#yNr6^~0m+Vgv1bmoJF{1q--HxI6L6bEpMn&|1Q~T{w&(mw&q^R&1
+zcl3NbH)}5N0_9M0x9b3Hd2q8OoK{H~T~oVCv;y;L;{)F<aKO&zhGhiSN7PQIxm&*G
+z;Cb5vg;g#p(K`wKpJ(*Yqxq;5JEJMo2>c4cM*EI=`hw&GRC|ZxQP^CxK1&7Bum&+O
+zB^l_PsER$>i)0#B3%Wd^o>xGtjfsb-NHtL^XEzj$WAnIbUB|i)3-WK5rM-~ayI{3u
+zrgwMC$CWff_S|W{WY1N<sKKh2*3(?$Md+oj!F`KeAhfq>yLUp)pJ3v!!pb}D+^mR|
+z-s=$!jV)VmT?ETMu2~xsz0b)SW{Iyh-Nw8Z1-OtS2o{niw<C1gwy{rnM7_-LDtthr
+zxPC?~XYPHZRt;eeLI%iru@PA8^euL#NKphkrRqTk?oigjQ=Fb4KU+W$gAn`*v&~>y
+z_*nw`7N^f*IHsd=;5uKU21io)$q50qe2h!f2M|p(t39@-+mIayPj?U|^^1LR1G-re
+zBx0P4#c9a8k>9Y41Sh^~NTY+qA8V=2N5~IgR)jE)U9XysIIEE*m7z{;nBOE)OFV;U
+zZjn3rToB1^T|fp=E&!ZmSn!dnn!>p6*^|s0Ga_|%vhHytWrWPasu(2voq^gRrpdSC
+z#Z^rRGmmW+PVb5ep4`ms-yd{6@!FpyWob{%^YFBmC6InxKKLppYg9R8TZo{a>SD};
+zWw$oyN;oYdiHjgeQ|I=j&B6qxw8S#~kfrwFay3E|fvtyzYr~^N?JlL)vSQAanFhC0
+z925|a_vP(bX16x+$p{8lH_l-Y?^2C@%-;w*L$RRu!a+LjbmL(K-n-^BWyf7j^Nx?p
+z@7A1DwzgCxjcMbxOY@R2%sjWsA9C&|kb1$M0?k&N<cuihzYQK@plFrWUxKye4B7mM
+z8IPQIzj~JBiSgv|$JScbKCMn^p%~4Uv|1}g=|mEjW5M!nzFX9H222bQs&1<+c=W`X
+zv-RUID=;_Sbqt1Rnj|6^u&Fi+IeYKLTFB4vrY9O*jcbhP`Z`t2j0ejfa9pJbC~WMX
+z^p>^3tl6zHjt{S4*o6u+%A_;O7GhJA`Xz^g2QMc;A0xiivgaNVlC^y@>0FZ#8hb@g
+zYe_?smbS%3U}e}0Elx`gmCXs~pg@;P{wfuY{5TN0rsVCE={)o?p}X5luRM-)+AKOd
+zI36<KsoES9rZa|lPZRAy`p)<Yw*1XtLW?Vz(G!0*pQ|xL1ly{qj}1oW3spH=J5+T9
+zk{x@%N1NMo860&*DK`5%Umv9wBWdN>1nd-?3ZI3wvBgTKVdYlES$Hq+%Wj=79G@HA
+z-a*~n$$1vfXE|M3-Q5}7-obc#t2Zqy?H^y=D&Fzu&KFtOzS_DKvZ@cDD@~!Bo)Nk{
+zi)ivvYq_{Xy1A7<eWBrdtJ#o65#;UG-$Z@mIRagEy!E9}phQxBn*@v%tLVj`b^}IH
+z<7c1RSj2%PeGI#UOH>SKreQ0V1*coqr)6zzBB=Wp`0T_nT8CDroZQ#;2WF=m<?o<u
+zeH1!-qcIG(_fFy0^u1E~%TF~{BQ16|g%rvB!%mVKu$5rgPX>k2Qs20Zb?$}rvVKmr
+zRMf%O;?mqn^`zUPxayG0ju7&9KFq(^YQ#%vs!G@yvNBFxDHa#5=27aW$>Vii=Jsla
+z%HlSnB~g5@Z{1WSF*D<pon>uhIQydX*zsJ=l^GIbt;8iKOM{xb<Wp{DCWCI$bJ>Q=
+za6l(~M?}3XWck2#Jjs<kD6=gtC2iqUDTJdr6j5L&aHg0*uh-UAnlRCPnO2+bZFsVK
+zr(fSS^rz8hdBSaC!NVGiX~JbsW;Pu%Mkvpl3t&?>O9thxxKyn~4q)MF`WX~DOq^ho
+z5lhtX1WaeTArTf?3h(B@!p>m#&zftMZG7ZJ^^vQvdm6sLYJO=a3uYGUK(Dw#;n9jz
+zF#AYz<X&>=(vXT;U|Hp6Vy5oY=HkV0Q)s<|`Pe%+xRL9mJ6V;Rv(ugMSh}r#RLV(5
+zbh{Hz@UX{Nzlhcjy=+MCsD!&Ls?-hpsX5#m!qyC;mj$I3?`MZp)|49MO#>TRc@upX
+z&zSAzJMlZalDjHDWt%a7_A8U#D(sGioa-+xdR)w_)8<)wp#Q-rO$h^&Ra+mu8+^t0
+zf`Tq)SayPig={P9%gL->7~O%=1jh|laFAgv-Vx$#LGlz4yzdpVNLi}i+Kq2en&awD
+zhGm~=^O!xjdZh}pMY@*rGQM;f^rj)i>RE2CX9F^Oz?U8YgYY|ywRgsw9d{CauoUks
+zi+84@Bsv*wW#IC7I4V$-JZ13#<r&C(W-Hm(+Bry{Ii5TAwHT)~9#oJ~Pq`lnR?fLI
+zL-t+@VQU;2Et`U8R9Tz#&GVb~OYoR}iOZ5@1>>k>9MA5Z^%>L`(^|!N$J#NB0uqff
+z5V4%7P%FzEc^^ARw36)omb@_x&d^!4-yFP>kR1PNXvl0~!VF>c=uq999)4PTpEpK_
+z%CVyi8E(UfYvy9FZVF>P3diVj$_48%;DSfWzAB1Btu}61tCmMW;uu4}Lz!=F#|e^Z
+z>PE2PbiHzeA~Y!{4ZRdqG8krmGkdH`^fV}s{Y6j1Y-&-IA+oMqgogeA%gY46pkBKz
+zU7aLStwajyXLU&|BgM^p>%DSqS~OtGf?B(fq$`dLVcN-t)%f}fYVlfEYlv4PS4i~<
+zh|}DG9R;>Wl<e?%L`$b(Z_FGsX;nG-_86Ra?#3-UZOpv46Lyr}%r$j&`cnpbfZfY*
+z+-pCv7Yi$wEEjscM2S~5h)d<(Xu65SuVvaHYESk)XQQ)RG2GYxUU?nOXMns_L7HYK
+zzBppenAC4ua?hl?+elGDU*@otv5-_UI1NlV22ym#(_JhZk6D$%dN(_vgL=~U$&-oC
+zD4ic`v&!-o>$W*>=fvIWv<snY-Iv^Hb|$=p?8&hX4Z$^Dn4^2*j${;rXrANOr$}AU
+z%i`$xC11??W%8HLa(YNe#<KCcHSOet3RvSgqE*Vpw?l$upPls+Zkb@ozs(n%qiO2M
+z$=ExgV7a}ytSbm@@+`YtZ1NY&sJp-3)hl}9dVbe<o*jPqk#Nnv4WBpO-1KcWQuGtl
+zf#P(V;l|*a!>hnBO#x!bCw&$M!VGQc9}ABfWESlC4iS018<addGkfFf65W9ZQ8rU5
+zTgS0N#9d0febvqVcz7Kb3~i6012iJ9Fl)5Z;E`s?aB%Uei$WWX2uNUa-x-S1^P;!F
+zB9sM+P{-8R(NwF49W*Aq62u8=f$oIxKJhp{ay<2Tkq}$0`o#)&<vdF%s5tDrueob2
+zM>Sh`nNJ4H4fqnoc=)b4eN{IIqy9@erIrOqeW6*j`{3%1audwWoO?cqkxEePlS$R5
+z!dw#&?e}4VPr%*Nh)x83f^3tcozkw3K`TKPn9w?`Tk}$QIOO^x?ckCz<n5!#q#P!$
+zt9*Cmx;7|f^#sE`SOxsr3?w*M`-AfADCdV#GNQ04(^j`yl058XcI3^L?bW<7F^jLS
+zo;*C3t;1_M9t8#fh#&(1BtPke3hc;dre|s9{*Pyz8kDtcMj6q)_KV)cXHp_R7pj-;
+z5rPomwFDb(NHq(}Uv*Zk7B87Ad3mv~$s?oBBU2e;=4KXk{ly_XoUhlRRW(^m&5=z9
+zEX!|rp?Sm1u%Upn=<>#$edfR&@6po+QOCNxnvljvgM;M_Z1aK?A{Jg&jml0i6J2U8
+zZ;&HZNcQY0vdW-S2)GfvWKE{4>s{}^9DlyCce-1%bgOBF=reQkJSt4&I74NZPaX~G
+z;SGl<mc|u$K1NYsT^d~bO39-FX?7R;(U8isR-=_6Z@*mD6zi98>MHBfZ}HOZ-}{ee
+zNIW_NJ*vcYp14Ec<Z_D1JJurwc$Cf^I&E6kiaa^C*-Vf1aXwwa6@hbo$1&QQ{={1g
+zO95lSg0OV4+i*VKA@_>cZWkgCB6}aU{)P4_A}t>soNTR~VD=DG*1$<Qm}O4L=eJ-}
+zg&59sz}XB5m%0q%%zeYBr;&^xNd)mTuQig;Xmy{is}T5Tvdw`vO5`VkB6bU5GZfc<
+zmiyvK;9A>CvdNcg{k*p^(>J&@M1Mur_<2mfCgpI`sz+N;hB01Ta~}h{1&_V2K3qVd
+zP1!bvhYn_>iLpfZQb6sb4GLevf+(OAMcmG)Fy^riNk}wTZUlMSTww?CM10t$$bO_~
+zsFeBZL{%BFpumpQ#!CdgDnTdsQWfq_l2eNG7{yKkXGw5_dIglvdX1O2xC{B0uD<vy
+z!mrFegL!9@wMeO(Hk@UrV!Zu8J8f66v_ZIr!Z5p5IVehSjaq3wN2_ZmImurfO>Cr;
+zTDNhkjdNlv<IJP95s3MsnUAnN_e3C6*Y$`~HfdY|(;Hd9+HdldGI-t@5q~uqZ}}oF
+zenrmp>9nVHrmM<wwXcHk2S1)X0!ONJqqjmq^6b~w=2F9Pv`%GqPBE(j3RmxVoXuN^
+zsx!o1Uh{7doBK;()CGIS4?yVog)`=W!@O>nk=s`HluD~cl6v&wqkR6AR6?%+GdW7w
+zo1J%_3ZhAL;{b5x<xsU=qRdeX_06$&qn>ZCDhq)pK(=`&2-H?sLiJRq$DQ6I*x<Si
+z5|3(M0iR3q-T4goDHG7o^S=wPj9KXL05^fdL^CHSS=j_nm@d9jv2Gb@3V_Uy-<b`s
+zW0l3wki}QBq(gjpyUe}_J;q6GP*o)qebW?R`O$khM0yo2^rD%p7cXmINGF$4hVk)`
+z&xjx7U?T`)RGj0o8FO;@{ddP11+HUL8G)UT5&mXuv7?QJk@Y_}SnV}mVML$1rUR##
+zgybNSqhu*BFT<Hu`_M-To;Jx*h^rw%Q9}WLyq^(}Qn2=6NU-7!`hvqi!^RfM2Z%`2
+zxnqLjH#USM&ksd>PP%o288bs@L&#t{*aZ|&(rm@s83dY{>vD&Uv4`s0QbocU!PyKE
+z%wii7LC?|$rWC0pU}|&FpY^NnF8Wkz60<0-D=`h2=H^+^^rvdHS2L?dsWr--BEM$0
+zz%CL)?W4e=4XS(7orfCF{H_iB^|6?YS~;wVJrf$q`?P10RMb#LtXsxkWbJM;qqY0B
+z8l3{rQfXTvV#AD?E2k?s>g2JvF~}%%6CI5@1Z>yO4!6z=W+blj>RgO(O)?K`5`011
+zMIb?O_7~cSZSyT?PZ~!}u<bp@@&!!aZrH}>qMk?v!OHN^_@{RCv%;$)5R@E4B^7qk
+z$XfNr`fs^tWN7+pr)=$W(DMw8=kTm6z!0xFDw{D`4P?03+I8VL?mBrxK_RO4u=LpD
+zT@3|KgH@wrF2)KCDmLU2AaOfAKX9z_%aZ7AacpCU%<Z+E{G4F)+WOOrB1vu$VB-||
+zcQj~Wd<O?*i;t<)R1v7N(63!sKM8wnm!P9vct5(s!uL!idbAl{lfggPvCTlc6vIn2
+z#swp-zG);7c(Mo2B!4gM-lcdN_;`dulBoK?qj;&vdO3Mj8!Bj3r{Ts(0(N-;%&bjJ
+zdIwH$sv7I~RIYiGhj*!$b}J(3$;xTvb2Sh?sFrW~)k8T2i;qZr=%)d8#QA~>0HFSr
+zbX@ct4NQ&f|Fk_m6=~HUblpx;ZLyzWM{c;LlQYVURfvhwoTFs1PH?sl<f#}XTn>Sb
+zq=RD<u>}m3zW>y8{s{0Y)siadN>?7Tc+%_oY<I-`v)PJY8X89O>_kNVa}NjmQYLpQ
+z*xI6O2Z<`>_D9|ky9Y7zW-i)?q~lanRL{u@FyauqT)f3qtUmQcm81{HSYnz`fj%jl
+z>hn$xwl!`VkM-OAd`G8N5(Py<N99OIkMhDTBRy6Ib|3xBSyZLHE*Q;bhnZ(ygKG0d
+z-bBy}Ny)Hu#<{If;yrLsU?oitvaob!dnt;7Qf&b|*U`kL_Fk=j`tC+Ly$anpZIyb=
+zM>)&{w<&oCWG|{jO!7P{SiL|EC+{+hk)ZjrQZ;uL((uEYdEUV$jYL!P5=wb-p@c@g
+zJRUd6;-`W(!e-ZD4Rc_sL1%_g*xVT(eDj7CCueC?AkjYzhC{tn&w|fC?_7**bGj(E
+zd>;pFN3uKywe6A8;r>bQ*<s`Jn8I68%NC-UX(|a1`))`%K;wM5DoRge<hDOScxPr;
+zK|IT5cS)6((4#Y+n@>dTZ3@}1V8MquAwGaejH*6GEr?kYKv}#hNs0H;iVdbfR(RH_
+z%_jW}j&Tle4Vl3pNVm&U7&B>^cR4Z>Gk4b=>sT8-eLQSnU>RhVXUXLqRm2_!K&4=l
+zJPw6=*d1JVD$-U|xr&fuMrFnjY4~%h{91fsH+?f2$xCWl)l%o8C8dI`voRRng&-RU
+zoD44YPDV9B^16Y9$UbZUH0!75!Jr>oh)umbB*zXBji!Kau;Vh67o_tzvrSFYK{4me
+z0d8;`gQXXgwIT12IM*Ukbt73wK(MK^)%}SAo2{&vtIo!XaC#JFI~2i}D%GZatO`6f
+za^8q7wq9rmLVmz&gK?SBC*^0eA{}v%>^H`N(`E8!**Q_b7|W(_V|W7y9#(LCAN<T{
+z$HY?_y&Ht~j>{m+nRJD2CnWAt@~LW(-427!Mr9A;YcmYMQA}+n-uRV={|E&7GpQG9
+z2OWe{DPwDGLGVs(YzUh$z{4X!V#ACI0#U^GHt$Gzh@YO~Q5u<piEC}3$?%#22+`4f
+z<nO_&CcHDSL0JTycivF4v^Xo}gy!0!Qs|@Nc~8_OS*wMS8I3JYtBRDmTwUuHRBE4s
+zFpAAnchlR?e6FPzdrzJWKTY%wwMd(CFqs%(2&9zZ1CtGBW23r0tfT|BfUDo*!@>+<
+zQn2fI4yLT-OrLXO=i8TL)pwkteN32xgT@gZni!v1nYxrnl=+)GSL?pu!R%J=_X+7k
+z6!|x2S!-EAF<(kuo``htji^Hl$kmmGfLv8_mtZ<ZZgtUINNH-_*xNx)k?nQl!c^Ev
+zLg9f5U^^0Bvf{3TV;)Kznm=`^<pmEoU9zhcAPGKK^<rWs$5r3u9o!XGU~avLqVr^t
+zm0Rbq_R~G@d&~L^i^|qkrQ(yWO+!do1x{&AjEh79z4U$!w5!a)NH^4}HM8C&=u9vB
+zYJkV+q<KJ(#Dps|tfG*^MQ%C-rq7^2Pkc}sajzaTO>mYJyx}>!fAKpBm=LP)ux|g+
+zM;^$hOsm14$7(mU^VKMV0?gg=BO?2la%52s=Q_p{${1UpzH^Nh!aBYRAq;?RuBwka
+z%pKg`j-wI%!tC)hA+}Y8jrlxJ3Bi)$l)5wti{2Fhw@$YP-ix%~$pdu}!Y=Dv=;Y<>
+z+x<8fb-nav#&;sDa##NNE9jRA!)&{jW=*Y~wlh#oD?0}3qaOz`I@@|odq<{0Q7UlO
+z7<NO8ubAoBi~Sh5Wk0r_7q?=@1@~QD7p|MZg3O7g=()>gxuExt8$3%`^3Rc&q7n=l
+zT;>^;<Js88TIshd4TbEgy*~m!l&U{nq3?DS6NP7Dcw1=uiY`#rwq*vh_UL154xyqE
+z#`=5tI?=Sipoqr|9XUvAj!dDvA$@3}k_gxF#>Xd)V`cZzu5&)t2YBN1Bc3ix9Ar}n
+zYb-LA@mj3uxwF2*n?W81wgMAuO>j@CTtArS2*^GwV5086K*gMYq7;25uOa9Q2PUD$
+zdz7ip3~ce(Qj_i17CJwfWa*yr?yzEWY4f5YQum#uvG{?F?Xf|&&=IBx^QCQL{8>s1
+zbDZ9u>vVAoLPOg4WHx2592;;f+G@QX<c$i$eY=-`YcVT43=MQk<24s&-n%ieCj1Lq
+zyK3gT!}^!6UafD+$j?<{JBBO3qVR{LV0qexEB7ivAC2I^r#Vw@CS{V<7`&LoxY=4-
+z3ph3Hf<Fa_V6FO_(YXl<xa@UtRd!R*N<yP?Cnm){YMQ7=EjzYzuV@T-w>_1Gl~QEV
+z_WDKc&B+no@nwP<NGkFP>!PraaIyGi@TYY-!Ep2;{JT|E%>xhdX5ui6Sy%HX;)oTC
+z7x&mVmGJ?07sy<Cn=xN#Hrhg!4%`XeU~|2}tmbEYNdXzZtXdK^bPM<JPHzfy`79kc
+zk6<2n!2y%5j*gX{nYE4%18~^05)1(BnaY*Q*UQNj4gdmv2JFHQ{&m6(TWAY#`T)HD
+zzDE#joE|tYE@~L|py(h%kB{i*NGoJFk9UGLw@pR2D_Z>AbVThn%P{^^=l&w_U-(~V
+z0lT4s?o~Os!v+%bVQ;roTV{JT6<9kjD`?SCbG&6UteKD?tvpeF6R7&(38{0ByBqJ*
+zYH`0*Ol03sXd@Vu^uj=t48dmR0yf+?z?bdR0L7Jv6ONS=PpEiRh>q+LSa?dMP!A#G
+zBtbw4!GIMl@aJoF@t+UB|A7Kv|NaRXuq*KOqnWicu)ux%TnPdI_O-zHZn?jK{We<1
+z+A&xhqa5|EKCoi81x_SD{T&Rb8o-B_U(tRC)6p@rHgo)4l|Wo#<-f&s0OATgrc31m
+zBFF=;hq(Jdwm)!z??OA6*;xN)i-5Sae~<g@wYa!@^@3I=u&gTJ0RYe+$m<Hc%l{qM
+zz{b+j$iVR%<R5JOx0?8hOzi>d+62^sKGOFRTVj5LY-MX{<Y@GV#Q%Wn3)IAUok=7I
+zKJcDI0{}pNAh8SZzkf<>ZER-p2P$yp^55-S5D*pe%3n4F_?-qbJph360QG|NTU19Q
+zSI0kK75^Ugs}i1C6P#ZGl~4dw0>T5>L7?6JF07HY^B<7^u>Lrpqy^H8f!Xi?KsxdF
+zJBBRx7o@9!k?q$F`>i+z+Jf~z3tP)>IUNWG02~03AKDnC);GvT22PH@kA?!`{)5C{
+zm7wqR7~`uyTqAtHV>70I;(jyQ<kwJVF)E{if!@#sybvF#Hpco-)UP4yA9ed%DEKNV
+z5bDpLKQO<_yenX8^C#wSGbetF2*0rU#S_T{BOq!g@WOc@XYqewejgZq0Ui&g@Y4ct
+zWXu52Bp$+>+I}yxp1p~a6|mvhKWgN+c=lBz5+>)<<iLHaAp-zq|1CKF7SG;0eGhM7
+z1MFq?mwWtz@F^6xR#-r<lVSq^upXcz`+kr9&8UxmHjo6Mqd4O&Qk4KZNDQHUZ_ch!
+ze}P--IU3v8Tm7LD=f8K83?S|#V<#p&4gg@M^nIvsO8g7g-p0gU?@!p5e-B#?gnhMo
+z-;c}%0Nho458DU)&+nna-s$VBqklSe-rvL417R=W^70!o001F=008NMimCShgmu(&
+z0FFEVn%IG=E&qGa79gnHSg>9QP_@25L;1r`ezOV&2#`Nyb#gSb`~$P*XPCd@d!UGa
+zVgjdZ8QR$YgYW$q^AG3v>fj$<O8gh*FZ<q);r}q--@--Gf597DI++=oIlBFW?0<P)
+zvP8U{8Bo@C;6?gi<Mw_I{>zK_i>K{K0TCF60Rg~^<^fL`()W7*a}oM_1{N-Q_J$4y
+zHdeNJ|0bXqp(!A}1ePpZz?en&fbIqIPwAw@g+yc&MgC)+zYtb(i;G}!f#$hK^7SFb
+zw?Rt<?WY`8dIqLu*8g0I{CN8@f2a9v`}^>|r?E70H3P=SU*3Ji+ZKthH8m4ZO%IoV
+zkN-35|6%iw26}8^fD}T&5Ks0%Q&xmOqX9nJ(R0u-G&A@&+YV)SdXoaQFe%`gs2&iF
+zlKzy)(b3*a-^tPF-;#Y!iYv+j+88OY=pcAVM)otZe_>)PzzFzGRa)JE004OF^nDdJ
+zO!+;9gPH3eaq#Nj#lb%+^53lLmGJk-ZhBUh%)e|?+8gM`RKTxM87aTERQlE}hJJ$l
+zKUmZR845Zt(4x42S@$7{9B}V{Ph-D_@!!P%8bWOTnBw)%sr_qJGW*Ic=muCfaOr;^
+z8`tE1Mq=&YXzyh3?<!Y&tMQ#Spv6uDi!1yG8spRd3D4Ix{juA>5UT1;LyRnd3@N~{
+z^3YV34S&pF=wxO4`;*mQQ`VL8WPLoampp0C_YoJ{_{S7RR%VWWbfx_@jwO4esx6?$
+z-NSsZDCn0z;rMgD?5{CA9K!jn@jmnW2?Nl|ejmyCYZRz-buqKR7-b1G--mlq=>KDi
+ze|^*PaA4uLt5^cgG5nEt{58Jt*A`L5j?+~MoSN5Z@ckkh1Aol$uL|q0-j~STO{Ncw
+zBkKPdQ1I;{dgFgg@y)n`Ut7haAn`>dU{2Z+{@%g;Qh!GAu$%I)@qlw=>U#n!1$f}?
+z&BJKLTKF@bZ+g!C8VRmSAWjuI01(^%y#vBj{g~w27BRoZp`FBr{2mP0Py`qiAJz-l
+zvp?Z@cuM2fXdXTg{&wpT7Jp3h&Ew&}qxf-E^)UZMFaL;w<(Kmxr{29P63}h~D8Aq9
+z<)0w`5BaaloL-X#7(h_|EB{Gs{aF0}A^$mVqwo#^cX|Zq<PYx+`u2WC^1tN2`?nTC
+zU-RGmf91c6`=9Xq%lwyeoVj2LWXSlh{D%Sx`h$ST^7vopzf8oHNC#l3>dE@v{l>t4
+zO!4pY-@}RO-}*%g;ZHdJ-}2u8$xj&mZT@>Wf%w}+u#*3n;{P%KnNs|i;@{@Khf`y}
+zU4#hLj~V`T{(Cr}=UWOs_8(LH>-_g{e!#aBApAe0_+Rqh!!E1e@(79ljOSnHzlTlH
+zz9qSo|1rtG&wmfkC4S2>?fest|KI%A?fzq$U(A2MeIN7Rhh4s1iLBS36c3KR0Q2fU
+tJem4hwLN^E_ZP0u%XUA|hfnu@mZ%{hfz>fU9QezL2LR-~1{VB){{tZ({`CL=
+
+diff --git a/tasks/_vendor/path.py b/tasks/_vendor/path.py
+deleted file mode 100644
+index 2c7a71c..0000000
+--- a/tasks/_vendor/path.py
++++ /dev/null
+@@ -1,1725 +0,0 @@
+-#
+-# SOURCE: https://pypi.python.org/pypi/path.py
+-# VERSION: 8.2.1
+-# -----------------------------------------------------------------------------
+-# Copyright (c) 2010 Mikhail Gusarov
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy
+-# of this software and associated documentation files (the "Software"), to deal
+-# in the Software without restriction, including without limitation the rights
+-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-# copies of the Software, and to permit persons to whom the Software is
+-# furnished to do so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in
+-# all copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+-#
+-
+-"""
+-path.py - An object representing a path to a file or directory.
+-
+-https://github.com/jaraco/path.py
+-
+-Example::
+-
+-    from path import Path
+-    d = Path('/home/guido/bin')
+-    for f in d.files('*.py'):
+-        f.chmod(0o755)
+-"""
+-
+-from __future__ import unicode_literals
+-
+-import sys
+-import warnings
+-import os
+-import fnmatch
+-import glob
+-import shutil
+-import codecs
+-import hashlib
+-import errno
+-import tempfile
+-import functools
+-import operator
+-import re
+-import contextlib
+-import io
+-from distutils import dir_util
+-import importlib
+-
+-try:
+-    import win32security
+-except ImportError:
+-    pass
+-
+-try:
+-    import pwd
+-except ImportError:
+-    pass
+-
+-try:
+-    import grp
+-except ImportError:
+-    pass
+-
+-##############################################################################
+-# Python 2/3 support
+-PY3 = sys.version_info >= (3,)
+-PY2 = not PY3
+-
+-string_types = str,
+-text_type = str
+-getcwdu = os.getcwd
+-
+-def surrogate_escape(error):
+-    """
+-    Simulate the Python 3 ``surrogateescape`` handler, but for Python 2 only.
+-    """
+-    chars = error.object[error.start:error.end]
+-    assert len(chars) == 1
+-    val = ord(chars)
+-    val += 0xdc00
+-    return __builtin__.unichr(val), error.end
+-
+-if PY2:
+-    import __builtin__
+-    string_types = __builtin__.basestring,
+-    text_type = __builtin__.unicode
+-    getcwdu = os.getcwdu
+-    codecs.register_error('surrogateescape', surrogate_escape)
+-
+-@contextlib.contextmanager
+-def io_error_compat():
+-    try:
+-        yield
+-    except IOError as io_err:
+-        # On Python 2, io.open raises IOError; transform to OSError for
+-        # future compatibility.
+-        os_err = OSError(*io_err.args)
+-        os_err.filename = getattr(io_err, 'filename', None)
+-        raise os_err
+-
+-##############################################################################
+-
+-__all__ = ['Path', 'CaseInsensitivePattern']
+-
+-
+-LINESEPS = ['\r\n', '\r', '\n']
+-U_LINESEPS = LINESEPS + ['\u0085', '\u2028', '\u2029']
+-NEWLINE = re.compile('|'.join(LINESEPS))
+-U_NEWLINE = re.compile('|'.join(U_LINESEPS))
+-NL_END = re.compile(r'(?:{0})$'.format(NEWLINE.pattern))
+-U_NL_END = re.compile(r'(?:{0})$'.format(U_NEWLINE.pattern))
+-
+-
+-try:
+-    import pkg_resources
+-    __version__ = pkg_resources.require('path.py')[0].version
+-except Exception:
+-    __version__ = '8.2.1'   # XXX-MODIFIED-WAS: 'unknown'
+-
+-
+-class TreeWalkWarning(Warning):
+-    pass
+-
+-
+-# from jaraco.functools
+-def compose(*funcs):
+-    compose_two = lambda f1, f2: lambda *args, **kwargs: f1(f2(*args, **kwargs))
+-    return functools.reduce(compose_two, funcs)
+-
+-
+-def simple_cache(func):
+-    """
+-    Save results for the :meth:'path.using_module' classmethod.
+-    When Python 3.2 is available, use functools.lru_cache instead.
+-    """
+-    saved_results = {}
+-
+-    def wrapper(cls, module):
+-        if module in saved_results:
+-            return saved_results[module]
+-        saved_results[module] = func(cls, module)
+-        return saved_results[module]
+-    return wrapper
+-
+-
+-class ClassProperty(property):
+-    def __get__(self, cls, owner):
+-        return self.fget.__get__(None, owner)()
+-
+-
+-class multimethod(object):
+-    """
+-    Acts like a classmethod when invoked from the class and like an
+-    instancemethod when invoked from the instance.
+-    """
+-    def __init__(self, func):
+-        self.func = func
+-
+-    def __get__(self, instance, owner):
+-        return (
+-            functools.partial(self.func, owner) if instance is None
+-            else functools.partial(self.func, owner, instance)
+-        )
+-
+-
+-class Path(text_type):
+-    """
+-    Represents a filesystem path.
+-
+-    For documentation on individual methods, consult their
+-    counterparts in :mod:`os.path`.
+-
+-    Some methods are additionally included from :mod:`shutil`.
+-    The functions are linked directly into the class namespace
+-    such that they will be bound to the Path instance. For example,
+-    ``Path(src).copy(target)`` is equivalent to
+-    ``shutil.copy(src, target)``. Therefore, when referencing
+-    the docs for these methods, assume `src` references `self`,
+-    the Path instance.
+-    """
+-
+-    module = os.path
+-    """ The path module to use for path operations.
+-
+-    .. seealso:: :mod:`os.path`
+-    """
+-
+-    def __init__(self, other=''):
+-        if other is None:
+-            raise TypeError("Invalid initial value for path: None")
+-
+-    @classmethod
+-    @simple_cache
+-    def using_module(cls, module):
+-        subclass_name = cls.__name__ + '_' + module.__name__
+-        if PY2:
+-            subclass_name = str(subclass_name)
+-        bases = (cls,)
+-        ns = {'module': module}
+-        return type(subclass_name, bases, ns)
+-
+-    @ClassProperty
+-    @classmethod
+-    def _next_class(cls):
+-        """
+-        What class should be used to construct new instances from this class
+-        """
+-        return cls
+-
+-    @classmethod
+-    def _always_unicode(cls, path):
+-        """
+-        Ensure the path as retrieved from a Python API, such as :func:`os.listdir`,
+-        is a proper Unicode string.
+-        """
+-        if PY3 or isinstance(path, text_type):
+-            return path
+-        return path.decode(sys.getfilesystemencoding(), 'surrogateescape')
+-
+-    # --- Special Python methods.
+-
+-    def __repr__(self):
+-        return '%s(%s)' % (type(self).__name__, super(Path, self).__repr__())
+-
+-    # Adding a Path and a string yields a Path.
+-    def __add__(self, more):
+-        try:
+-            return self._next_class(super(Path, self).__add__(more))
+-        except TypeError:  # Python bug
+-            return NotImplemented
+-
+-    def __radd__(self, other):
+-        if not isinstance(other, string_types):
+-            return NotImplemented
+-        return self._next_class(other.__add__(self))
+-
+-    # The / operator joins Paths.
+-    def __div__(self, rel):
+-        """ fp.__div__(rel) == fp / rel == fp.joinpath(rel)
+-
+-        Join two path components, adding a separator character if
+-        needed.
+-
+-        .. seealso:: :func:`os.path.join`
+-        """
+-        return self._next_class(self.module.join(self, rel))
+-
+-    # Make the / operator work even when true division is enabled.
+-    __truediv__ = __div__
+-
+-    # The / operator joins Paths the other way around
+-    def __rdiv__(self, rel):
+-        """ fp.__rdiv__(rel) == rel / fp
+-
+-        Join two path components, adding a separator character if
+-        needed.
+-
+-        .. seealso:: :func:`os.path.join`
+-        """
+-        return self._next_class(self.module.join(rel, self))
+-
+-    # Make the / operator work even when true division is enabled.
+-    __rtruediv__ = __rdiv__
+-
+-    def __enter__(self):
+-        self._old_dir = self.getcwd()
+-        os.chdir(self)
+-        return self
+-
+-    def __exit__(self, *_):
+-        os.chdir(self._old_dir)
+-
+-    @classmethod
+-    def getcwd(cls):
+-        """ Return the current working directory as a path object.
+-
+-        .. seealso:: :func:`os.getcwdu`
+-        """
+-        return cls(getcwdu())
+-
+-    #
+-    # --- Operations on Path strings.
+-
+-    def abspath(self):
+-        """ .. seealso:: :func:`os.path.abspath` """
+-        return self._next_class(self.module.abspath(self))
+-
+-    def normcase(self):
+-        """ .. seealso:: :func:`os.path.normcase` """
+-        return self._next_class(self.module.normcase(self))
+-
+-    def normpath(self):
+-        """ .. seealso:: :func:`os.path.normpath` """
+-        return self._next_class(self.module.normpath(self))
+-
+-    def realpath(self):
+-        """ .. seealso:: :func:`os.path.realpath` """
+-        return self._next_class(self.module.realpath(self))
+-
+-    def expanduser(self):
+-        """ .. seealso:: :func:`os.path.expanduser` """
+-        return self._next_class(self.module.expanduser(self))
+-
+-    def expandvars(self):
+-        """ .. seealso:: :func:`os.path.expandvars` """
+-        return self._next_class(self.module.expandvars(self))
+-
+-    def dirname(self):
+-        """ .. seealso:: :attr:`parent`, :func:`os.path.dirname` """
+-        return self._next_class(self.module.dirname(self))
+-
+-    def basename(self):
+-        """ .. seealso:: :attr:`name`, :func:`os.path.basename` """
+-        return self._next_class(self.module.basename(self))
+-
+-    def expand(self):
+-        """ Clean up a filename by calling :meth:`expandvars()`,
+-        :meth:`expanduser()`, and :meth:`normpath()` on it.
+-
+-        This is commonly everything needed to clean up a filename
+-        read from a configuration file, for example.
+-        """
+-        return self.expandvars().expanduser().normpath()
+-
+-    @property
+-    def namebase(self):
+-        """ The same as :meth:`name`, but with one file extension stripped off.
+-
+-        For example,
+-        ``Path('/home/guido/python.tar.gz').name == 'python.tar.gz'``,
+-        but
+-        ``Path('/home/guido/python.tar.gz').namebase == 'python.tar'``.
+-        """
+-        base, ext = self.module.splitext(self.name)
+-        return base
+-
+-    @property
+-    def ext(self):
+-        """ The file extension, for example ``'.py'``. """
+-        f, ext = self.module.splitext(self)
+-        return ext
+-
+-    @property
+-    def drive(self):
+-        """ The drive specifier, for example ``'C:'``.
+-
+-        This is always empty on systems that don't use drive specifiers.
+-        """
+-        drive, r = self.module.splitdrive(self)
+-        return self._next_class(drive)
+-
+-    parent = property(
+-        dirname, None, None,
+-        """ This path's parent directory, as a new Path object.
+-
+-        For example,
+-        ``Path('/usr/local/lib/libpython.so').parent ==
+-        Path('/usr/local/lib')``
+-
+-        .. seealso:: :meth:`dirname`, :func:`os.path.dirname`
+-        """)
+-
+-    name = property(
+-        basename, None, None,
+-        """ The name of this file or directory without the full path.
+-
+-        For example,
+-        ``Path('/usr/local/lib/libpython.so').name == 'libpython.so'``
+-
+-        .. seealso:: :meth:`basename`, :func:`os.path.basename`
+-        """)
+-
+-    def splitpath(self):
+-        """ p.splitpath() -> Return ``(p.parent, p.name)``.
+-
+-        .. seealso:: :attr:`parent`, :attr:`name`, :func:`os.path.split`
+-        """
+-        parent, child = self.module.split(self)
+-        return self._next_class(parent), child
+-
+-    def splitdrive(self):
+-        """ p.splitdrive() -> Return ``(p.drive, <the rest of p>)``.
+-
+-        Split the drive specifier from this path.  If there is
+-        no drive specifier, :samp:`{p.drive}` is empty, so the return value
+-        is simply ``(Path(''), p)``.  This is always the case on Unix.
+-
+-        .. seealso:: :func:`os.path.splitdrive`
+-        """
+-        drive, rel = self.module.splitdrive(self)
+-        return self._next_class(drive), rel
+-
+-    def splitext(self):
+-        """ p.splitext() -> Return ``(p.stripext(), p.ext)``.
+-
+-        Split the filename extension from this path and return
+-        the two parts.  Either part may be empty.
+-
+-        The extension is everything from ``'.'`` to the end of the
+-        last path segment.  This has the property that if
+-        ``(a, b) == p.splitext()``, then ``a + b == p``.
+-
+-        .. seealso:: :func:`os.path.splitext`
+-        """
+-        filename, ext = self.module.splitext(self)
+-        return self._next_class(filename), ext
+-
+-    def stripext(self):
+-        """ p.stripext() -> Remove one file extension from the path.
+-
+-        For example, ``Path('/home/guido/python.tar.gz').stripext()``
+-        returns ``Path('/home/guido/python.tar')``.
+-        """
+-        return self.splitext()[0]
+-
+-    def splitunc(self):
+-        """ .. seealso:: :func:`os.path.splitunc` """
+-        unc, rest = self.module.splitunc(self)
+-        return self._next_class(unc), rest
+-
+-    @property
+-    def uncshare(self):
+-        """
+-        The UNC mount point for this path.
+-        This is empty for paths on local drives.
+-        """
+-        unc, r = self.module.splitunc(self)
+-        return self._next_class(unc)
+-
+-    @multimethod
+-    def joinpath(cls, first, *others):
+-        """
+-        Join first to zero or more :class:`Path` components, adding a separator
+-        character (:samp:`{first}.module.sep`) if needed.  Returns a new instance of
+-        :samp:`{first}._next_class`.
+-
+-        .. seealso:: :func:`os.path.join`
+-        """
+-        if not isinstance(first, cls):
+-            first = cls(first)
+-        return first._next_class(first.module.join(first, *others))
+-
+-    def splitall(self):
+-        r""" Return a list of the path components in this path.
+-
+-        The first item in the list will be a Path.  Its value will be
+-        either :data:`os.curdir`, :data:`os.pardir`, empty, or the root
+-        directory of this path (for example, ``'/'`` or ``'C:\\'``).  The
+-        other items in the list will be strings.
+-
+-        ``path.Path.joinpath(*result)`` will yield the original path.
+-        """
+-        parts = []
+-        loc = self
+-        while loc != os.curdir and loc != os.pardir:
+-            prev = loc
+-            loc, child = prev.splitpath()
+-            if loc == prev:
+-                break
+-            parts.append(child)
+-        parts.append(loc)
+-        parts.reverse()
+-        return parts
+-
+-    def relpath(self, start='.'):
+-        """ Return this path as a relative path,
+-        based from `start`, which defaults to the current working directory.
+-        """
+-        cwd = self._next_class(start)
+-        return cwd.relpathto(self)
+-
+-    def relpathto(self, dest):
+-        """ Return a relative path from `self` to `dest`.
+-
+-        If there is no relative path from `self` to `dest`, for example if
+-        they reside on different drives in Windows, then this returns
+-        ``dest.abspath()``.
+-        """
+-        origin = self.abspath()
+-        dest = self._next_class(dest).abspath()
+-
+-        orig_list = origin.normcase().splitall()
+-        # Don't normcase dest!  We want to preserve the case.
+-        dest_list = dest.splitall()
+-
+-        if orig_list[0] != self.module.normcase(dest_list[0]):
+-            # Can't get here from there.
+-            return dest
+-
+-        # Find the location where the two paths start to differ.
+-        i = 0
+-        for start_seg, dest_seg in zip(orig_list, dest_list):
+-            if start_seg != self.module.normcase(dest_seg):
+-                break
+-            i += 1
+-
+-        # Now i is the point where the two paths diverge.
+-        # Need a certain number of "os.pardir"s to work up
+-        # from the origin to the point of divergence.
+-        segments = [os.pardir] * (len(orig_list) - i)
+-        # Need to add the diverging part of dest_list.
+-        segments += dest_list[i:]
+-        if len(segments) == 0:
+-            # If they happen to be identical, use os.curdir.
+-            relpath = os.curdir
+-        else:
+-            relpath = self.module.join(*segments)
+-        return self._next_class(relpath)
+-
+-    # --- Listing, searching, walking, and matching
+-
+-    def listdir(self, pattern=None):
+-        """ D.listdir() -> List of items in this directory.
+-
+-        Use :meth:`files` or :meth:`dirs` instead if you want a listing
+-        of just files or just subdirectories.
+-
+-        The elements of the list are Path objects.
+-
+-        With the optional `pattern` argument, this only lists
+-        items whose names match the given pattern.
+-
+-        .. seealso:: :meth:`files`, :meth:`dirs`
+-        """
+-        if pattern is None:
+-            pattern = '*'
+-        return [
+-            self / child
+-            for child in map(self._always_unicode, os.listdir(self))
+-            if self._next_class(child).fnmatch(pattern)
+-        ]
+-
+-    def dirs(self, pattern=None):
+-        """ D.dirs() -> List of this directory's subdirectories.
+-
+-        The elements of the list are Path objects.
+-        This does not walk recursively into subdirectories
+-        (but see :meth:`walkdirs`).
+-
+-        With the optional `pattern` argument, this only lists
+-        directories whose names match the given pattern.  For
+-        example, ``d.dirs('build-*')``.
+-        """
+-        return [p for p in self.listdir(pattern) if p.isdir()]
+-
+-    def files(self, pattern=None):
+-        """ D.files() -> List of the files in this directory.
+-
+-        The elements of the list are Path objects.
+-        This does not walk into subdirectories (see :meth:`walkfiles`).
+-
+-        With the optional `pattern` argument, this only lists files
+-        whose names match the given pattern.  For example,
+-        ``d.files('*.pyc')``.
+-        """
+-
+-        return [p for p in self.listdir(pattern) if p.isfile()]
+-
+-    def walk(self, pattern=None, errors='strict'):
+-        """ D.walk() -> iterator over files and subdirs, recursively.
+-
+-        The iterator yields Path objects naming each child item of
+-        this directory and its descendants.  This requires that
+-        ``D.isdir()``.
+-
+-        This performs a depth-first traversal of the directory tree.
+-        Each directory is returned just before all its children.
+-
+-        The `errors=` keyword argument controls behavior when an
+-        error occurs.  The default is ``'strict'``, which causes an
+-        exception.  Other allowed values are ``'warn'`` (which
+-        reports the error via :func:`warnings.warn()`), and ``'ignore'``.
+-        `errors` may also be an arbitrary callable taking a msg parameter.
+-        """
+-        class Handlers:
+-            def strict(msg):
+-                raise
+-
+-            def warn(msg):
+-                warnings.warn(msg, TreeWalkWarning)
+-
+-            def ignore(msg):
+-                pass
+-
+-        if not callable(errors) and errors not in vars(Handlers):
+-            raise ValueError("invalid errors parameter")
+-        errors = vars(Handlers).get(errors, errors)
+-
+-        try:
+-            childList = self.listdir()
+-        except Exception:
+-            exc = sys.exc_info()[1]
+-            tmpl = "Unable to list directory '%(self)s': %(exc)s"
+-            msg = tmpl % locals()
+-            errors(msg)
+-            return
+-
+-        for child in childList:
+-            if pattern is None or child.fnmatch(pattern):
+-                yield child
+-            try:
+-                isdir = child.isdir()
+-            except Exception:
+-                exc = sys.exc_info()[1]
+-                tmpl = "Unable to access '%(child)s': %(exc)s"
+-                msg = tmpl % locals()
+-                errors(msg)
+-                isdir = False
+-
+-            if isdir:
+-                for item in child.walk(pattern, errors):
+-                    yield item
+-
+-    def walkdirs(self, pattern=None, errors='strict'):
+-        """ D.walkdirs() -> iterator over subdirs, recursively.
+-
+-        With the optional `pattern` argument, this yields only
+-        directories whose names match the given pattern.  For
+-        example, ``mydir.walkdirs('*test')`` yields only directories
+-        with names ending in ``'test'``.
+-
+-        The `errors=` keyword argument controls behavior when an
+-        error occurs.  The default is ``'strict'``, which causes an
+-        exception.  The other allowed values are ``'warn'`` (which
+-        reports the error via :func:`warnings.warn()`), and ``'ignore'``.
+-        """
+-        if errors not in ('strict', 'warn', 'ignore'):
+-            raise ValueError("invalid errors parameter")
+-
+-        try:
+-            dirs = self.dirs()
+-        except Exception:
+-            if errors == 'ignore':
+-                return
+-            elif errors == 'warn':
+-                warnings.warn(
+-                    "Unable to list directory '%s': %s"
+-                    % (self, sys.exc_info()[1]),
+-                    TreeWalkWarning)
+-                return
+-            else:
+-                raise
+-
+-        for child in dirs:
+-            if pattern is None or child.fnmatch(pattern):
+-                yield child
+-            for subsubdir in child.walkdirs(pattern, errors):
+-                yield subsubdir
+-
+-    def walkfiles(self, pattern=None, errors='strict'):
+-        """ D.walkfiles() -> iterator over files in D, recursively.
+-
+-        The optional argument `pattern` limits the results to files
+-        with names that match the pattern.  For example,
+-        ``mydir.walkfiles('*.tmp')`` yields only files with the ``.tmp``
+-        extension.
+-        """
+-        if errors not in ('strict', 'warn', 'ignore'):
+-            raise ValueError("invalid errors parameter")
+-
+-        try:
+-            childList = self.listdir()
+-        except Exception:
+-            if errors == 'ignore':
+-                return
+-            elif errors == 'warn':
+-                warnings.warn(
+-                    "Unable to list directory '%s': %s"
+-                    % (self, sys.exc_info()[1]),
+-                    TreeWalkWarning)
+-                return
+-            else:
+-                raise
+-
+-        for child in childList:
+-            try:
+-                isfile = child.isfile()
+-                isdir = not isfile and child.isdir()
+-            except:
+-                if errors == 'ignore':
+-                    continue
+-                elif errors == 'warn':
+-                    warnings.warn(
+-                        "Unable to access '%s': %s"
+-                        % (self, sys.exc_info()[1]),
+-                        TreeWalkWarning)
+-                    continue
+-                else:
+-                    raise
+-
+-            if isfile:
+-                if pattern is None or child.fnmatch(pattern):
+-                    yield child
+-            elif isdir:
+-                for f in child.walkfiles(pattern, errors):
+-                    yield f
+-
+-    def fnmatch(self, pattern, normcase=None):
+-        """ Return ``True`` if `self.name` matches the given `pattern`.
+-
+-        `pattern` - A filename pattern with wildcards,
+-            for example ``'*.py'``. If the pattern contains a `normcase`
+-            attribute, it is applied to the name and path prior to comparison.
+-
+-        `normcase` - (optional) A function used to normalize the pattern and
+-            filename before matching. Defaults to :meth:`self.module`, which defaults
+-            to :meth:`os.path.normcase`.
+-
+-        .. seealso:: :func:`fnmatch.fnmatch`
+-        """
+-        default_normcase = getattr(pattern, 'normcase', self.module.normcase)
+-        normcase = normcase or default_normcase
+-        name = normcase(self.name)
+-        pattern = normcase(pattern)
+-        return fnmatch.fnmatchcase(name, pattern)
+-
+-    def glob(self, pattern):
+-        """ Return a list of Path objects that match the pattern.
+-
+-        `pattern` - a path relative to this directory, with wildcards.
+-
+-        For example, ``Path('/users').glob('*/bin/*')`` returns a list
+-        of all the files users have in their :file:`bin` directories.
+-
+-        .. seealso:: :func:`glob.glob`
+-        """
+-        cls = self._next_class
+-        return [cls(s) for s in glob.glob(self / pattern)]
+-
+-    #
+-    # --- Reading or writing an entire file at once.
+-
+-    def open(self, *args, **kwargs):
+-        """ Open this file and return a corresponding :class:`file` object.
+-
+-        Keyword arguments work as in :func:`io.open`.  If the file cannot be
+-        opened, an :class:`~exceptions.OSError` is raised.
+-        """
+-        with io_error_compat():
+-            return io.open(self, *args, **kwargs)
+-
+-    def bytes(self):
+-        """ Open this file, read all bytes, return them as a string. """
+-        with self.open('rb') as f:
+-            return f.read()
+-
+-    def chunks(self, size, *args, **kwargs):
+-        """ Returns a generator yielding chunks of the file, so it can
+-            be read piece by piece with a simple for loop.
+-
+-           Any argument you pass after `size` will be passed to :meth:`open`.
+-
+-           :example:
+-
+-               >>> hash = hashlib.md5()
+-               >>> for chunk in Path("path.py").chunks(8192, mode='rb'):
+-               ...     hash.update(chunk)
+-
+-            This will read the file by chunks of 8192 bytes.
+-        """
+-        with self.open(*args, **kwargs) as f:
+-            for chunk in iter(lambda: f.read(size) or None, None):
+-                yield chunk
+-
+-    def write_bytes(self, bytes, append=False):
+-        """ Open this file and write the given bytes to it.
+-
+-        Default behavior is to overwrite any existing file.
+-        Call ``p.write_bytes(bytes, append=True)`` to append instead.
+-        """
+-        if append:
+-            mode = 'ab'
+-        else:
+-            mode = 'wb'
+-        with self.open(mode) as f:
+-            f.write(bytes)
+-
+-    def text(self, encoding=None, errors='strict'):
+-        r""" Open this file, read it in, return the content as a string.
+-
+-        All newline sequences are converted to ``'\n'``.  Keyword arguments
+-        will be passed to :meth:`open`.
+-
+-        .. seealso:: :meth:`lines`
+-        """
+-        with self.open(mode='r', encoding=encoding, errors=errors) as f:
+-            return U_NEWLINE.sub('\n', f.read())
+-
+-    def write_text(self, text, encoding=None, errors='strict',
+-                   linesep=os.linesep, append=False):
+-        r""" Write the given text to this file.
+-
+-        The default behavior is to overwrite any existing file;
+-        to append instead, use the `append=True` keyword argument.
+-
+-        There are two differences between :meth:`write_text` and
+-        :meth:`write_bytes`: newline handling and Unicode handling.
+-        See below.
+-
+-        Parameters:
+-
+-          `text` - str/unicode - The text to be written.
+-
+-          `encoding` - str - The Unicode encoding that will be used.
+-              This is ignored if `text` isn't a Unicode string.
+-
+-          `errors` - str - How to handle Unicode encoding errors.
+-              Default is ``'strict'``.  See ``help(unicode.encode)`` for the
+-              options.  This is ignored if `text` isn't a Unicode
+-              string.
+-
+-          `linesep` - keyword argument - str/unicode - The sequence of
+-              characters to be used to mark end-of-line.  The default is
+-              :data:`os.linesep`.  You can also specify ``None`` to
+-              leave all newlines as they are in `text`.
+-
+-          `append` - keyword argument - bool - Specifies what to do if
+-              the file already exists (``True``: append to the end of it;
+-              ``False``: overwrite it.)  The default is ``False``.
+-
+-
+-        --- Newline handling.
+-
+-        ``write_text()`` converts all standard end-of-line sequences
+-        (``'\n'``, ``'\r'``, and ``'\r\n'``) to your platform's default
+-        end-of-line sequence (see :data:`os.linesep`; on Windows, for example,
+-        the end-of-line marker is ``'\r\n'``).
+-
+-        If you don't like your platform's default, you can override it
+-        using the `linesep=` keyword argument.  If you specifically want
+-        ``write_text()`` to preserve the newlines as-is, use ``linesep=None``.
+-
+-        This applies to Unicode text the same as to 8-bit text, except
+-        there are three additional standard Unicode end-of-line sequences:
+-        ``u'\x85'``, ``u'\r\x85'``, and ``u'\u2028'``.
+-
+-        (This is slightly different from when you open a file for
+-        writing with ``fopen(filename, "w")`` in C or ``open(filename, 'w')``
+-        in Python.)
+-
+-
+-        --- Unicode
+-
+-        If `text` isn't Unicode, then apart from newline handling, the
+-        bytes are written verbatim to the file.  The `encoding` and
+-        `errors` arguments are not used and must be omitted.
+-
+-        If `text` is Unicode, it is first converted to :func:`bytes` using the
+-        specified `encoding` (or the default encoding if `encoding`
+-        isn't specified).  The `errors` argument applies only to this
+-        conversion.
+-
+-        """
+-        if isinstance(text, text_type):
+-            if linesep is not None:
+-                text = U_NEWLINE.sub(linesep, text)
+-            text = text.encode(encoding or sys.getdefaultencoding(), errors)
+-        else:
+-            assert encoding is None
+-            text = NEWLINE.sub(linesep, text)
+-        self.write_bytes(text, append=append)
+-
+-    def lines(self, encoding=None, errors='strict', retain=True):
+-        r""" Open this file, read all lines, return them in a list.
+-
+-        Optional arguments:
+-            `encoding` - The Unicode encoding (or character set) of
+-                the file.  The default is ``None``, meaning the content
+-                of the file is read as 8-bit characters and returned
+-                as a list of (non-Unicode) str objects.
+-            `errors` - How to handle Unicode errors; see help(str.decode)
+-                for the options.  Default is ``'strict'``.
+-            `retain` - If ``True``, retain newline characters; but all newline
+-                character combinations (``'\r'``, ``'\n'``, ``'\r\n'``) are
+-                translated to ``'\n'``.  If ``False``, newline characters are
+-                stripped off.  Default is ``True``.
+-
+-        This uses ``'U'`` mode.
+-
+-        .. seealso:: :meth:`text`
+-        """
+-        if encoding is None and retain:
+-            with self.open('U') as f:
+-                return f.readlines()
+-        else:
+-            return self.text(encoding, errors).splitlines(retain)
+-
+-    def write_lines(self, lines, encoding=None, errors='strict',
+-                    linesep=os.linesep, append=False):
+-        r""" Write the given lines of text to this file.
+-
+-        By default this overwrites any existing file at this path.
+-
+-        This puts a platform-specific newline sequence on every line.
+-        See `linesep` below.
+-
+-            `lines` - A list of strings.
+-
+-            `encoding` - A Unicode encoding to use.  This applies only if
+-                `lines` contains any Unicode strings.
+-
+-            `errors` - How to handle errors in Unicode encoding.  This
+-                also applies only to Unicode strings.
+-
+-            linesep - The desired line-ending.  This line-ending is
+-                applied to every line.  If a line already has any
+-                standard line ending (``'\r'``, ``'\n'``, ``'\r\n'``,
+-                ``u'\x85'``, ``u'\r\x85'``, ``u'\u2028'``), that will
+-                be stripped off and this will be used instead.  The
+-                default is os.linesep, which is platform-dependent
+-                (``'\r\n'`` on Windows, ``'\n'`` on Unix, etc.).
+-                Specify ``None`` to write the lines as-is, like
+-                :meth:`file.writelines`.
+-
+-        Use the keyword argument ``append=True`` to append lines to the
+-        file.  The default is to overwrite the file.
+-
+-        .. warning ::
+-
+-            When you use this with Unicode data, if the encoding of the
+-            existing data in the file is different from the encoding
+-            you specify with the `encoding=` parameter, the result is
+-            mixed-encoding data, which can really confuse someone trying
+-            to read the file later.
+-        """
+-        with self.open('ab' if append else 'wb') as f:
+-            for l in lines:
+-                isUnicode = isinstance(l, text_type)
+-                if linesep is not None:
+-                    pattern = U_NL_END if isUnicode else NL_END
+-                    l = pattern.sub('', l) + linesep
+-                if isUnicode:
+-                    l = l.encode(encoding or sys.getdefaultencoding(), errors)
+-                f.write(l)
+-
+-    def read_md5(self):
+-        """ Calculate the md5 hash for this file.
+-
+-        This reads through the entire file.
+-
+-        .. seealso:: :meth:`read_hash`
+-        """
+-        return self.read_hash('md5')
+-
+-    def _hash(self, hash_name):
+-        """ Returns a hash object for the file at the current path.
+-
+-            `hash_name` should be a hash algo name (such as ``'md5'`` or ``'sha1'``)
+-            that's available in the :mod:`hashlib` module.
+-        """
+-        m = hashlib.new(hash_name)
+-        for chunk in self.chunks(8192, mode="rb"):
+-            m.update(chunk)
+-        return m
+-
+-    def read_hash(self, hash_name):
+-        """ Calculate given hash for this file.
+-
+-        List of supported hashes can be obtained from :mod:`hashlib` package.
+-        This reads the entire file.
+-
+-        .. seealso:: :meth:`hashlib.hash.digest`
+-        """
+-        return self._hash(hash_name).digest()
+-
+-    def read_hexhash(self, hash_name):
+-        """ Calculate given hash for this file, returning hexdigest.
+-
+-        List of supported hashes can be obtained from :mod:`hashlib` package.
+-        This reads the entire file.
+-
+-        .. seealso:: :meth:`hashlib.hash.hexdigest`
+-        """
+-        return self._hash(hash_name).hexdigest()
+-
+-    # --- Methods for querying the filesystem.
+-    # N.B. On some platforms, the os.path functions may be implemented in C
+-    # (e.g. isdir on Windows, Python 3.2.2), and compiled functions don't get
+-    # bound. Playing it safe and wrapping them all in method calls.
+-
+-    def isabs(self):
+-        """ .. seealso:: :func:`os.path.isabs` """
+-        return self.module.isabs(self)
+-
+-    def exists(self):
+-        """ .. seealso:: :func:`os.path.exists` """
+-        return self.module.exists(self)
+-
+-    def isdir(self):
+-        """ .. seealso:: :func:`os.path.isdir` """
+-        return self.module.isdir(self)
+-
+-    def isfile(self):
+-        """ .. seealso:: :func:`os.path.isfile` """
+-        return self.module.isfile(self)
+-
+-    def islink(self):
+-        """ .. seealso:: :func:`os.path.islink` """
+-        return self.module.islink(self)
+-
+-    def ismount(self):
+-        """ .. seealso:: :func:`os.path.ismount` """
+-        return self.module.ismount(self)
+-
+-    def samefile(self, other):
+-        """ .. seealso:: :func:`os.path.samefile` """
+-        if not hasattr(self.module, 'samefile'):
+-            other = Path(other).realpath().normpath().normcase()
+-            return self.realpath().normpath().normcase() == other
+-        return self.module.samefile(self, other)
+-
+-    def getatime(self):
+-        """ .. seealso:: :attr:`atime`, :func:`os.path.getatime` """
+-        return self.module.getatime(self)
+-
+-    atime = property(
+-        getatime, None, None,
+-        """ Last access time of the file.
+-
+-        .. seealso:: :meth:`getatime`, :func:`os.path.getatime`
+-        """)
+-
+-    def getmtime(self):
+-        """ .. seealso:: :attr:`mtime`, :func:`os.path.getmtime` """
+-        return self.module.getmtime(self)
+-
+-    mtime = property(
+-        getmtime, None, None,
+-        """ Last-modified time of the file.
+-
+-        .. seealso:: :meth:`getmtime`, :func:`os.path.getmtime`
+-        """)
+-
+-    def getctime(self):
+-        """ .. seealso:: :attr:`ctime`, :func:`os.path.getctime` """
+-        return self.module.getctime(self)
+-
+-    ctime = property(
+-        getctime, None, None,
+-        """ Creation time of the file.
+-
+-        .. seealso:: :meth:`getctime`, :func:`os.path.getctime`
+-        """)
+-
+-    def getsize(self):
+-        """ .. seealso:: :attr:`size`, :func:`os.path.getsize` """
+-        return self.module.getsize(self)
+-
+-    size = property(
+-        getsize, None, None,
+-        """ Size of the file, in bytes.
+-
+-        .. seealso:: :meth:`getsize`, :func:`os.path.getsize`
+-        """)
+-
+-    if hasattr(os, 'access'):
+-        def access(self, mode):
+-            """ Return ``True`` if current user has access to this path.
+-
+-            mode - One of the constants :data:`os.F_OK`, :data:`os.R_OK`,
+-            :data:`os.W_OK`, :data:`os.X_OK`
+-
+-            .. seealso:: :func:`os.access`
+-            """
+-            return os.access(self, mode)
+-
+-    def stat(self):
+-        """ Perform a ``stat()`` system call on this path.
+-
+-        .. seealso:: :meth:`lstat`, :func:`os.stat`
+-        """
+-        return os.stat(self)
+-
+-    def lstat(self):
+-        """ Like :meth:`stat`, but do not follow symbolic links.
+-
+-        .. seealso:: :meth:`stat`, :func:`os.lstat`
+-        """
+-        return os.lstat(self)
+-
+-    def __get_owner_windows(self):
+-        """
+-        Return the name of the owner of this file or directory. Follow
+-        symbolic links.
+-
+-        Return a name of the form ``r'DOMAIN\\User Name'``; may be a group.
+-
+-        .. seealso:: :attr:`owner`
+-        """
+-        desc = win32security.GetFileSecurity(
+-            self, win32security.OWNER_SECURITY_INFORMATION)
+-        sid = desc.GetSecurityDescriptorOwner()
+-        account, domain, typecode = win32security.LookupAccountSid(None, sid)
+-        return domain + '\\' + account
+-
+-    def __get_owner_unix(self):
+-        """
+-        Return the name of the owner of this file or directory. Follow
+-        symbolic links.
+-
+-        .. seealso:: :attr:`owner`
+-        """
+-        st = self.stat()
+-        return pwd.getpwuid(st.st_uid).pw_name
+-
+-    def __get_owner_not_implemented(self):
+-        raise NotImplementedError("Ownership not available on this platform.")
+-
+-    if 'win32security' in globals():
+-        get_owner = __get_owner_windows
+-    elif 'pwd' in globals():
+-        get_owner = __get_owner_unix
+-    else:
+-        get_owner = __get_owner_not_implemented
+-
+-    owner = property(
+-        get_owner, None, None,
+-        """ Name of the owner of this file or directory.
+-
+-        .. seealso:: :meth:`get_owner`""")
+-
+-    if hasattr(os, 'statvfs'):
+-        def statvfs(self):
+-            """ Perform a ``statvfs()`` system call on this path.
+-
+-            .. seealso:: :func:`os.statvfs`
+-            """
+-            return os.statvfs(self)
+-
+-    if hasattr(os, 'pathconf'):
+-        def pathconf(self, name):
+-            """ .. seealso:: :func:`os.pathconf` """
+-            return os.pathconf(self, name)
+-
+-    #
+-    # --- Modifying operations on files and directories
+-
+-    def utime(self, times):
+-        """ Set the access and modified times of this file.
+-
+-        .. seealso:: :func:`os.utime`
+-        """
+-        os.utime(self, times)
+-        return self
+-
+-    def chmod(self, mode):
+-        """
+-        Set the mode. May be the new mode (os.chmod behavior) or a `symbolic
+-        mode <http://en.wikipedia.org/wiki/Chmod#Symbolic_modes>`_.
+-
+-        .. seealso:: :func:`os.chmod`
+-        """
+-        if isinstance(mode, string_types):
+-            mask = _multi_permission_mask(mode)
+-            mode = mask(self.stat().st_mode)
+-        os.chmod(self, mode)
+-        return self
+-
+-    def chown(self, uid=-1, gid=-1):
+-        """
+-        Change the owner and group by names rather than the uid or gid numbers.
+-
+-        .. seealso:: :func:`os.chown`
+-        """
+-        if hasattr(os, 'chown'):
+-            if 'pwd' in globals() and isinstance(uid, string_types):
+-                uid = pwd.getpwnam(uid).pw_uid
+-            if 'grp' in globals() and isinstance(gid, string_types):
+-                gid = grp.getgrnam(gid).gr_gid
+-            os.chown(self, uid, gid)
+-        else:
+-            raise NotImplementedError("Ownership not available on this platform.")
+-        return self
+-
+-    def rename(self, new):
+-        """ .. seealso:: :func:`os.rename` """
+-        os.rename(self, new)
+-        return self._next_class(new)
+-
+-    def renames(self, new):
+-        """ .. seealso:: :func:`os.renames` """
+-        os.renames(self, new)
+-        return self._next_class(new)
+-
+-    #
+-    # --- Create/delete operations on directories
+-
+-    def mkdir(self, mode=0o777):
+-        """ .. seealso:: :func:`os.mkdir` """
+-        os.mkdir(self, mode)
+-        return self
+-
+-    def mkdir_p(self, mode=0o777):
+-        """ Like :meth:`mkdir`, but does not raise an exception if the
+-        directory already exists. """
+-        try:
+-            self.mkdir(mode)
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    def makedirs(self, mode=0o777):
+-        """ .. seealso:: :func:`os.makedirs` """
+-        os.makedirs(self, mode)
+-        return self
+-
+-    def makedirs_p(self, mode=0o777):
+-        """ Like :meth:`makedirs`, but does not raise an exception if the
+-        directory already exists. """
+-        try:
+-            self.makedirs(mode)
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    def rmdir(self):
+-        """ .. seealso:: :func:`os.rmdir` """
+-        os.rmdir(self)
+-        return self
+-
+-    def rmdir_p(self):
+-        """ Like :meth:`rmdir`, but does not raise an exception if the
+-        directory is not empty or does not exist. """
+-        try:
+-            self.rmdir()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOTEMPTY and e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    def removedirs(self):
+-        """ .. seealso:: :func:`os.removedirs` """
+-        os.removedirs(self)
+-        return self
+-
+-    def removedirs_p(self):
+-        """ Like :meth:`removedirs`, but does not raise an exception if the
+-        directory is not empty or does not exist. """
+-        try:
+-            self.removedirs()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOTEMPTY and e.errno != errno.EEXIST:
+-                raise
+-        return self
+-
+-    # --- Modifying operations on files
+-
+-    def touch(self):
+-        """ Set the access/modified times of this file to the current time.
+-        Create the file if it does not exist.
+-        """
+-        fd = os.open(self, os.O_WRONLY | os.O_CREAT, 0o666)
+-        os.close(fd)
+-        os.utime(self, None)
+-        return self
+-
+-    def remove(self):
+-        """ .. seealso:: :func:`os.remove` """
+-        os.remove(self)
+-        return self
+-
+-    def remove_p(self):
+-        """ Like :meth:`remove`, but does not raise an exception if the
+-        file does not exist. """
+-        try:
+-            self.unlink()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOENT:
+-                raise
+-        return self
+-
+-    def unlink(self):
+-        """ .. seealso:: :func:`os.unlink` """
+-        os.unlink(self)
+-        return self
+-
+-    def unlink_p(self):
+-        """ Like :meth:`unlink`, but does not raise an exception if the
+-        file does not exist. """
+-        self.remove_p()
+-        return self
+-
+-    # --- Links
+-
+-    if hasattr(os, 'link'):
+-        def link(self, newpath):
+-            """ Create a hard link at `newpath`, pointing to this file.
+-
+-            .. seealso:: :func:`os.link`
+-            """
+-            os.link(self, newpath)
+-            return self._next_class(newpath)
+-
+-    if hasattr(os, 'symlink'):
+-        def symlink(self, newlink):
+-            """ Create a symbolic link at `newlink`, pointing here.
+-
+-            .. seealso:: :func:`os.symlink`
+-            """
+-            os.symlink(self, newlink)
+-            return self._next_class(newlink)
+-
+-    if hasattr(os, 'readlink'):
+-        def readlink(self):
+-            """ Return the path to which this symbolic link points.
+-
+-            The result may be an absolute or a relative path.
+-
+-            .. seealso:: :meth:`readlinkabs`, :func:`os.readlink`
+-            """
+-            return self._next_class(os.readlink(self))
+-
+-        def readlinkabs(self):
+-            """ Return the path to which this symbolic link points.
+-
+-            The result is always an absolute path.
+-
+-            .. seealso:: :meth:`readlink`, :func:`os.readlink`
+-            """
+-            p = self.readlink()
+-            if p.isabs():
+-                return p
+-            else:
+-                return (self.parent / p).abspath()
+-
+-    # High-level functions from shutil
+-    # These functions will be bound to the instance such that
+-    # Path(name).copy(target) will invoke shutil.copy(name, target)
+-
+-    copyfile = shutil.copyfile
+-    copymode = shutil.copymode
+-    copystat = shutil.copystat
+-    copy = shutil.copy
+-    copy2 = shutil.copy2
+-    copytree = shutil.copytree
+-    if hasattr(shutil, 'move'):
+-        move = shutil.move
+-    rmtree = shutil.rmtree
+-
+-    def rmtree_p(self):
+-        """ Like :meth:`rmtree`, but does not raise an exception if the
+-        directory does not exist. """
+-        try:
+-            self.rmtree()
+-        except OSError:
+-            _, e, _ = sys.exc_info()
+-            if e.errno != errno.ENOENT:
+-                raise
+-        return self
+-
+-    def chdir(self):
+-        """ .. seealso:: :func:`os.chdir` """
+-        os.chdir(self)
+-
+-    cd = chdir
+-
+-    def merge_tree(self, dst, symlinks=False, *args, **kwargs):
+-        """
+-        Copy entire contents of self to dst, overwriting existing
+-        contents in dst with those in self.
+-
+-        If the additional keyword `update` is True, each
+-        `src` will only be copied if `dst` does not exist,
+-        or `src` is newer than `dst`.
+-
+-        Note that the technique employed stages the files in a temporary
+-        directory first, so this function is not suitable for merging
+-        trees with large files, especially if the temporary directory
+-        is not capable of storing a copy of the entire source tree.
+-        """
+-        update = kwargs.pop('update', False)
+-        with tempdir() as _temp_dir:
+-            # first copy the tree to a stage directory to support
+-            #  the parameters and behavior of copytree.
+-            stage = _temp_dir / str(hash(self))
+-            self.copytree(stage, symlinks, *args, **kwargs)
+-            # now copy everything from the stage directory using
+-            #  the semantics of dir_util.copy_tree
+-            dir_util.copy_tree(stage, dst, preserve_symlinks=symlinks,
+-                update=update)
+-
+-    #
+-    # --- Special stuff from os
+-
+-    if hasattr(os, 'chroot'):
+-        def chroot(self):
+-            """ .. seealso:: :func:`os.chroot` """
+-            os.chroot(self)
+-
+-    if hasattr(os, 'startfile'):
+-        def startfile(self):
+-            """ .. seealso:: :func:`os.startfile` """
+-            os.startfile(self)
+-            return self
+-
+-    # in-place re-writing, courtesy of Martijn Pieters
+-    # http://www.zopatista.com/python/2013/11/26/inplace-file-rewriting/
+-    @contextlib.contextmanager
+-    def in_place(self, mode='r', buffering=-1, encoding=None, errors=None,
+-            newline=None, backup_extension=None):
+-        """
+-        A context in which a file may be re-written in-place with new content.
+-
+-        Yields a tuple of :samp:`({readable}, {writable})` file objects, where `writable`
+-        replaces `readable`.
+-
+-        If an exception occurs, the old file is restored, removing the
+-        written data.
+-
+-        Mode *must not* use ``'w'``, ``'a'``, or ``'+'``; only read-only-modes are
+-        allowed. A :exc:`ValueError` is raised on invalid modes.
+-
+-        For example, to add line numbers to a file::
+-
+-            p = Path(filename)
+-            assert p.isfile()
+-            with p.in_place() as (reader, writer):
+-                for number, line in enumerate(reader, 1):
+-                    writer.write('{0:3}: '.format(number)))
+-                    writer.write(line)
+-
+-        Thereafter, the file at `filename` will have line numbers in it.
+-        """
+-        import io
+-
+-        if set(mode).intersection('wa+'):
+-            raise ValueError('Only read-only file modes can be used')
+-
+-        # move existing file to backup, create new file with same permissions
+-        # borrowed extensively from the fileinput module
+-        backup_fn = self + (backup_extension or os.extsep + 'bak')
+-        try:
+-            os.unlink(backup_fn)
+-        except os.error:
+-            pass
+-        os.rename(self, backup_fn)
+-        readable = io.open(backup_fn, mode, buffering=buffering,
+-            encoding=encoding, errors=errors, newline=newline)
+-        try:
+-            perm = os.fstat(readable.fileno()).st_mode
+-        except OSError:
+-            writable = open(self, 'w' + mode.replace('r', ''),
+-                buffering=buffering, encoding=encoding, errors=errors,
+-                newline=newline)
+-        else:
+-            os_mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
+-            if hasattr(os, 'O_BINARY'):
+-                os_mode |= os.O_BINARY
+-            fd = os.open(self, os_mode, perm)
+-            writable = io.open(fd, "w" + mode.replace('r', ''),
+-                buffering=buffering, encoding=encoding, errors=errors,
+-                newline=newline)
+-            try:
+-                if hasattr(os, 'chmod'):
+-                    os.chmod(self, perm)
+-            except OSError:
+-                pass
+-        try:
+-            yield readable, writable
+-        except Exception:
+-            # move backup back
+-            readable.close()
+-            writable.close()
+-            try:
+-                os.unlink(self)
+-            except os.error:
+-                pass
+-            os.rename(backup_fn, self)
+-            raise
+-        else:
+-            readable.close()
+-            writable.close()
+-        finally:
+-            try:
+-                os.unlink(backup_fn)
+-            except os.error:
+-                pass
+-
+-    @ClassProperty
+-    @classmethod
+-    def special(cls):
+-        """
+-        Return a SpecialResolver object suitable referencing a suitable
+-        directory for the relevant platform for the given
+-        type of content.
+-
+-        For example, to get a user config directory, invoke:
+-
+-            dir = Path.special().user.config
+-
+-        Uses the `appdirs
+-        <https://pypi.python.org/pypi/appdirs/1.4.0>`_ to resolve
+-        the paths in a platform-friendly way.
+-
+-        To create a config directory for 'My App', consider:
+-
+-            dir = Path.special("My App").user.config.makedirs_p()
+-
+-        If the ``appdirs`` module is not installed, invocation
+-        of special will raise an ImportError.
+-        """
+-        return functools.partial(SpecialResolver, cls)
+-
+-
+-class SpecialResolver(object):
+-    class ResolverScope:
+-        def __init__(self, paths, scope):
+-            self.paths = paths
+-            self.scope = scope
+-
+-        def __getattr__(self, class_):
+-            return self.paths.get_dir(self.scope, class_)
+-
+-    def __init__(self, path_class, *args, **kwargs):
+-        appdirs = importlib.import_module('appdirs')
+-
+-        # let appname default to None until
+-        # https://github.com/ActiveState/appdirs/issues/55 is solved.
+-        not args and kwargs.setdefault('appname', None)
+-
+-        vars(self).update(
+-            path_class=path_class,
+-            wrapper=appdirs.AppDirs(*args, **kwargs),
+-        )
+-
+-    def __getattr__(self, scope):
+-        return self.ResolverScope(self, scope)
+-
+-    def get_dir(self, scope, class_):
+-        """
+-        Return the callable function from appdirs, but with the
+-        result wrapped in self.path_class
+-        """
+-        prop_name = '{scope}_{class_}_dir'.format(**locals())
+-        value = getattr(self.wrapper, prop_name)
+-        MultiPath = Multi.for_class(self.path_class)
+-        return MultiPath.detect(value)
+-
+-
+-class Multi:
+-    """
+-    A mix-in for a Path which may contain multiple Path separated by pathsep.
+-    """
+-    @classmethod
+-    def for_class(cls, path_cls):
+-        name = 'Multi' + path_cls.__name__
+-        if PY2:
+-            name = str(name)
+-        return type(name, (cls, path_cls), {})
+-
+-    @classmethod
+-    def detect(cls, input):
+-        if os.pathsep not in input:
+-            cls = cls._next_class
+-        return cls(input)
+-
+-    def __iter__(self):
+-        return iter(map(self._next_class, self.split(os.pathsep)))
+-
+-    @ClassProperty
+-    @classmethod
+-    def _next_class(cls):
+-        """
+-        Multi-subclasses should use the parent class
+-        """
+-        return next(
+-            class_
+-            for class_ in cls.__mro__
+-            if not issubclass(class_, Multi)
+-        )
+-
+-
+-class tempdir(Path):
+-    """
+-    A temporary directory via :func:`tempfile.mkdtemp`, and constructed with the
+-    same parameters that you can use as a context manager.
+-
+-    Example:
+-
+-        with tempdir() as d:
+-            # do stuff with the Path object "d"
+-
+-        # here the directory is deleted automatically
+-
+-    .. seealso:: :func:`tempfile.mkdtemp`
+-    """
+-
+-    @ClassProperty
+-    @classmethod
+-    def _next_class(cls):
+-        return Path
+-
+-    def __new__(cls, *args, **kwargs):
+-        dirname = tempfile.mkdtemp(*args, **kwargs)
+-        return super(tempdir, cls).__new__(cls, dirname)
+-
+-    def __init__(self, *args, **kwargs):
+-        pass
+-
+-    def __enter__(self):
+-        return self
+-
+-    def __exit__(self, exc_type, exc_value, traceback):
+-        if not exc_value:
+-            self.rmtree()
+-
+-
+-def _multi_permission_mask(mode):
+-    """
+-    Support multiple, comma-separated Unix chmod symbolic modes.
+-
+-    >>> _multi_permission_mask('a=r,u+w')(0) == 0o644
+-    True
+-    """
+-    compose = lambda f, g: lambda *args, **kwargs: g(f(*args, **kwargs))
+-    return functools.reduce(compose, map(_permission_mask, mode.split(',')))
+-
+-
+-def _permission_mask(mode):
+-    """
+-    Convert a Unix chmod symbolic mode like ``'ugo+rwx'`` to a function
+-    suitable for applying to a mask to affect that change.
+-
+-    >>> mask = _permission_mask('ugo+rwx')
+-    >>> mask(0o554) == 0o777
+-    True
+-
+-    >>> _permission_mask('go-x')(0o777) == 0o766
+-    True
+-
+-    >>> _permission_mask('o-x')(0o445) == 0o444
+-    True
+-
+-    >>> _permission_mask('a+x')(0) == 0o111
+-    True
+-
+-    >>> _permission_mask('a=rw')(0o057) == 0o666
+-    True
+-
+-    >>> _permission_mask('u=x')(0o666) == 0o166
+-    True
+-
+-    >>> _permission_mask('g=')(0o157) == 0o107
+-    True
+-    """
+-    # parse the symbolic mode
+-    parsed = re.match('(?P<who>[ugoa]+)(?P<op>[-+=])(?P<what>[rwx]*)$', mode)
+-    if not parsed:
+-        raise ValueError("Unrecognized symbolic mode", mode)
+-
+-    # generate a mask representing the specified permission
+-    spec_map = dict(r=4, w=2, x=1)
+-    specs = (spec_map[perm] for perm in parsed.group('what'))
+-    spec = functools.reduce(operator.or_, specs, 0)
+-
+-    # now apply spec to each subject in who
+-    shift_map = dict(u=6, g=3, o=0)
+-    who = parsed.group('who').replace('a', 'ugo')
+-    masks = (spec << shift_map[subj] for subj in who)
+-    mask = functools.reduce(operator.or_, masks)
+-
+-    op = parsed.group('op')
+-
+-    # if op is -, invert the mask
+-    if op == '-':
+-        mask ^= 0o777
+-
+-    # if op is =, retain extant values for unreferenced subjects
+-    if op == '=':
+-        masks = (0o7 << shift_map[subj] for subj in who)
+-        retain = functools.reduce(operator.or_, masks) ^ 0o777
+-
+-    op_map = {
+-        '+': operator.or_,
+-        '-': operator.and_,
+-        '=': lambda mask, target: target & retain ^ mask,
+-    }
+-    return functools.partial(op_map[op], mask)
+-
+-
+-class CaseInsensitivePattern(text_type):
+-    """
+-    A string with a ``'normcase'`` property, suitable for passing to
+-    :meth:`listdir`, :meth:`dirs`, :meth:`files`, :meth:`walk`,
+-    :meth:`walkdirs`, or :meth:`walkfiles` to match case-insensitive.
+-
+-    For example, to get all files ending in .py, .Py, .pY, or .PY in the
+-    current directory::
+-
+-        from path import Path, CaseInsensitivePattern as ci
+-        Path('.').files(ci('*.py'))
+-    """
+-
+-    @property
+-    def normcase(self):
+-        return __import__('ntpath').normcase
+-
+-########################
+-# Backward-compatibility
+-class path(Path):
+-    def __new__(cls, *args, **kwargs):
+-        msg = "path is deprecated. Use Path instead."
+-        warnings.warn(msg, DeprecationWarning)
+-        return Path.__new__(cls, *args, **kwargs)
+-
+-
+-__all__ += ['path']
+-########################
+diff --git a/tasks/_vendor/pathlib.py b/tasks/_vendor/pathlib.py
+deleted file mode 100644
+index 9ab0e70..0000000
+--- a/tasks/_vendor/pathlib.py
++++ /dev/null
+@@ -1,1280 +0,0 @@
+-import fnmatch
+-import functools
+-import io
+-import ntpath
+-import os
+-import posixpath
+-import re
+-import sys
+-import time
+-from collections import Sequence
+-from contextlib import contextmanager
+-from errno import EINVAL, ENOENT
+-from operator import attrgetter
+-from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
+-try:
+-    from urllib import quote as urlquote, quote as urlquote_from_bytes
+-except ImportError:
+-    from urllib.parse import quote as urlquote, quote_from_bytes as urlquote_from_bytes
+-
+-
+-try:
+-    intern = intern
+-except NameError:
+-    intern = sys.intern
+-try:
+-    basestring = basestring
+-except NameError:
+-    basestring = str
+-
+-supports_symlinks = True
+-try:
+-    import nt
+-except ImportError:
+-    nt = None
+-else:
+-    if sys.getwindowsversion()[:2] >= (6, 0) and sys.version_info >= (3, 2):
+-        from nt import _getfinalpathname
+-    else:
+-        supports_symlinks = False
+-        _getfinalpathname = None
+-
+-
+-__all__ = [
+-    "PurePath", "PurePosixPath", "PureWindowsPath",
+-    "Path", "PosixPath", "WindowsPath",
+-    ]
+-
+-#
+-# Internals
+-#
+-
+-_py2 = sys.version_info < (3,)
+-_py2_fs_encoding = 'ascii'
+-
+-def _py2_fsencode(parts):
+-    # py2 => minimal unicode support
+-    return [part.encode(_py2_fs_encoding) if isinstance(part, unicode)
+-            else part for part in parts]
+-
+-def _is_wildcard_pattern(pat):
+-    # Whether this pattern needs actual matching using fnmatch, or can
+-    # be looked up directly as a file.
+-    return "*" in pat or "?" in pat or "[" in pat
+-
+-
+-class _Flavour(object):
+-    """A flavour implements a particular (platform-specific) set of path
+-    semantics."""
+-
+-    def __init__(self):
+-        self.join = self.sep.join
+-
+-    def parse_parts(self, parts):
+-        if _py2:
+-            parts = _py2_fsencode(parts)
+-        parsed = []
+-        sep = self.sep
+-        altsep = self.altsep
+-        drv = root = ''
+-        it = reversed(parts)
+-        for part in it:
+-            if not part:
+-                continue
+-            if altsep:
+-                part = part.replace(altsep, sep)
+-            drv, root, rel = self.splitroot(part)
+-            if sep in rel:
+-                for x in reversed(rel.split(sep)):
+-                    if x and x != '.':
+-                        parsed.append(intern(x))
+-            else:
+-                if rel and rel != '.':
+-                    parsed.append(intern(rel))
+-            if drv or root:
+-                if not drv:
+-                    # If no drive is present, try to find one in the previous
+-                    # parts. This makes the result of parsing e.g.
+-                    # ("C:", "/", "a") reasonably intuitive.
+-                    for part in it:
+-                        drv = self.splitroot(part)[0]
+-                        if drv:
+-                            break
+-                break
+-        if drv or root:
+-            parsed.append(drv + root)
+-        parsed.reverse()
+-        return drv, root, parsed
+-
+-    def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2):
+-        """
+-        Join the two paths represented by the respective
+-        (drive, root, parts) tuples.  Return a new (drive, root, parts) tuple.
+-        """
+-        if root2:
+-            if not drv2 and drv:
+-                return drv, root2, [drv + root2] + parts2[1:]
+-        elif drv2:
+-            if drv2 == drv or self.casefold(drv2) == self.casefold(drv):
+-                # Same drive => second path is relative to the first
+-                return drv, root, parts + parts2[1:]
+-        else:
+-            # Second path is non-anchored (common case)
+-            return drv, root, parts + parts2
+-        return drv2, root2, parts2
+-
+-
+-class _WindowsFlavour(_Flavour):
+-    # Reference for Windows paths can be found at
+-    # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
+-
+-    sep = '\\'
+-    altsep = '/'
+-    has_drv = True
+-    pathmod = ntpath
+-
+-    is_supported = (nt is not None)
+-
+-    drive_letters = (
+-        set(chr(x) for x in range(ord('a'), ord('z') + 1)) |
+-        set(chr(x) for x in range(ord('A'), ord('Z') + 1))
+-    )
+-    ext_namespace_prefix = '\\\\?\\'
+-
+-    reserved_names = (
+-        set(['CON', 'PRN', 'AUX', 'NUL']) |
+-        set(['COM%d' % i for i in range(1, 10)]) |
+-        set(['LPT%d' % i for i in range(1, 10)])
+-        )
+-
+-    # Interesting findings about extended paths:
+-    # - '\\?\c:\a', '//?/c:\a' and '//?/c:/a' are all supported
+-    #   but '\\?\c:/a' is not
+-    # - extended paths are always absolute; "relative" extended paths will
+-    #   fail.
+-
+-    def splitroot(self, part, sep=sep):
+-        first = part[0:1]
+-        second = part[1:2]
+-        if (second == sep and first == sep):
+-            # XXX extended paths should also disable the collapsing of "."
+-            # components (according to MSDN docs).
+-            prefix, part = self._split_extended_path(part)
+-            first = part[0:1]
+-            second = part[1:2]
+-        else:
+-            prefix = ''
+-        third = part[2:3]
+-        if (second == sep and first == sep and third != sep):
+-            # is a UNC path:
+-            # vvvvvvvvvvvvvvvvvvvvv root
+-            # \\machine\mountpoint\directory\etc\...
+-            #            directory ^^^^^^^^^^^^^^
+-            index = part.find(sep, 2)
+-            if index != -1:
+-                index2 = part.find(sep, index + 1)
+-                # a UNC path can't have two slashes in a row
+-                # (after the initial two)
+-                if index2 != index + 1:
+-                    if index2 == -1:
+-                        index2 = len(part)
+-                    if prefix:
+-                        return prefix + part[1:index2], sep, part[index2+1:]
+-                    else:
+-                        return part[:index2], sep, part[index2+1:]
+-        drv = root = ''
+-        if second == ':' and first in self.drive_letters:
+-            drv = part[:2]
+-            part = part[2:]
+-            first = third
+-        if first == sep:
+-            root = first
+-            part = part.lstrip(sep)
+-        return prefix + drv, root, part
+-
+-    def casefold(self, s):
+-        return s.lower()
+-
+-    def casefold_parts(self, parts):
+-        return [p.lower() for p in parts]
+-
+-    def resolve(self, path):
+-        s = str(path)
+-        if not s:
+-            return os.getcwd()
+-        if _getfinalpathname is not None:
+-            return self._ext_to_normal(_getfinalpathname(s))
+-        # Means fallback on absolute
+-        return None
+-
+-    def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix):
+-        prefix = ''
+-        if s.startswith(ext_prefix):
+-            prefix = s[:4]
+-            s = s[4:]
+-            if s.startswith('UNC\\'):
+-                prefix += s[:3]
+-                s = '\\' + s[3:]
+-        return prefix, s
+-
+-    def _ext_to_normal(self, s):
+-        # Turn back an extended path into a normal DOS-like path
+-        return self._split_extended_path(s)[1]
+-
+-    def is_reserved(self, parts):
+-        # NOTE: the rules for reserved names seem somewhat complicated
+-        # (e.g. r"..\NUL" is reserved but not r"foo\NUL").
+-        # We err on the side of caution and return True for paths which are
+-        # not considered reserved by Windows.
+-        if not parts:
+-            return False
+-        if parts[0].startswith('\\\\'):
+-            # UNC paths are never reserved
+-            return False
+-        return parts[-1].partition('.')[0].upper() in self.reserved_names
+-
+-    def make_uri(self, path):
+-        # Under Windows, file URIs use the UTF-8 encoding.
+-        drive = path.drive
+-        if len(drive) == 2 and drive[1] == ':':
+-            # It's a path on a local drive => 'file:///c:/a/b'
+-            rest = path.as_posix()[2:].lstrip('/')
+-            return 'file:///%s/%s' % (
+-                drive, urlquote_from_bytes(rest.encode('utf-8')))
+-        else:
+-            # It's a path on a network drive => 'file://host/share/a/b'
+-            return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8'))
+-
+-
+-class _PosixFlavour(_Flavour):
+-    sep = '/'
+-    altsep = ''
+-    has_drv = False
+-    pathmod = posixpath
+-
+-    is_supported = (os.name != 'nt')
+-
+-    def splitroot(self, part, sep=sep):
+-        if part and part[0] == sep:
+-            stripped_part = part.lstrip(sep)
+-            # According to POSIX path resolution:
+-            # http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11
+-            # "A pathname that begins with two successive slashes may be
+-            # interpreted in an implementation-defined manner, although more
+-            # than two leading slashes shall be treated as a single slash".
+-            if len(part) - len(stripped_part) == 2:
+-                return '', sep * 2, stripped_part
+-            else:
+-                return '', sep, stripped_part
+-        else:
+-            return '', '', part
+-
+-    def casefold(self, s):
+-        return s
+-
+-    def casefold_parts(self, parts):
+-        return parts
+-
+-    def resolve(self, path):
+-        sep = self.sep
+-        accessor = path._accessor
+-        seen = {}
+-        def _resolve(path, rest):
+-            if rest.startswith(sep):
+-                path = ''
+-
+-            for name in rest.split(sep):
+-                if not name or name == '.':
+-                    # current dir
+-                    continue
+-                if name == '..':
+-                    # parent dir
+-                    path, _, _ = path.rpartition(sep)
+-                    continue
+-                newpath = path + sep + name
+-                if newpath in seen:
+-                    # Already seen this path
+-                    path = seen[newpath]
+-                    if path is not None:
+-                        # use cached value
+-                        continue
+-                    # The symlink is not resolved, so we must have a symlink loop.
+-                    raise RuntimeError("Symlink loop from %r" % newpath)
+-                # Resolve the symbolic link
+-                try:
+-                    target = accessor.readlink(newpath)
+-                except OSError as e:
+-                    if e.errno != EINVAL:
+-                        raise
+-                    # Not a symlink
+-                    path = newpath
+-                else:
+-                    seen[newpath] = None # not resolved symlink
+-                    path = _resolve(path, target)
+-                    seen[newpath] = path # resolved symlink
+-
+-            return path
+-        # NOTE: according to POSIX, getcwd() cannot contain path components
+-        # which are symlinks.
+-        base = '' if path.is_absolute() else os.getcwd()
+-        return _resolve(base, str(path)) or sep
+-
+-    def is_reserved(self, parts):
+-        return False
+-
+-    def make_uri(self, path):
+-        # We represent the path using the local filesystem encoding,
+-        # for portability to other applications.
+-        bpath = bytes(path)
+-        return 'file://' + urlquote_from_bytes(bpath)
+-
+-
+-_windows_flavour = _WindowsFlavour()
+-_posix_flavour = _PosixFlavour()
+-
+-
+-class _Accessor:
+-    """An accessor implements a particular (system-specific or not) way of
+-    accessing paths on the filesystem."""
+-
+-
+-class _NormalAccessor(_Accessor):
+-
+-    def _wrap_strfunc(strfunc):
+-        @functools.wraps(strfunc)
+-        def wrapped(pathobj, *args):
+-            return strfunc(str(pathobj), *args)
+-        return staticmethod(wrapped)
+-
+-    def _wrap_binary_strfunc(strfunc):
+-        @functools.wraps(strfunc)
+-        def wrapped(pathobjA, pathobjB, *args):
+-            return strfunc(str(pathobjA), str(pathobjB), *args)
+-        return staticmethod(wrapped)
+-
+-    stat = _wrap_strfunc(os.stat)
+-
+-    lstat = _wrap_strfunc(os.lstat)
+-
+-    open = _wrap_strfunc(os.open)
+-
+-    listdir = _wrap_strfunc(os.listdir)
+-
+-    chmod = _wrap_strfunc(os.chmod)
+-
+-    if hasattr(os, "lchmod"):
+-        lchmod = _wrap_strfunc(os.lchmod)
+-    else:
+-        def lchmod(self, pathobj, mode):
+-            raise NotImplementedError("lchmod() not available on this system")
+-
+-    mkdir = _wrap_strfunc(os.mkdir)
+-
+-    unlink = _wrap_strfunc(os.unlink)
+-
+-    rmdir = _wrap_strfunc(os.rmdir)
+-
+-    rename = _wrap_binary_strfunc(os.rename)
+-
+-    if sys.version_info >= (3, 3):
+-        replace = _wrap_binary_strfunc(os.replace)
+-
+-    if nt:
+-        if supports_symlinks:
+-            symlink = _wrap_binary_strfunc(os.symlink)
+-        else:
+-            def symlink(a, b, target_is_directory):
+-                raise NotImplementedError("symlink() not available on this system")
+-    else:
+-        # Under POSIX, os.symlink() takes two args
+-        @staticmethod
+-        def symlink(a, b, target_is_directory):
+-            return os.symlink(str(a), str(b))
+-
+-    utime = _wrap_strfunc(os.utime)
+-
+-    # Helper for resolve()
+-    def readlink(self, path):
+-        return os.readlink(path)
+-
+-
+-_normal_accessor = _NormalAccessor()
+-
+-
+-#
+-# Globbing helpers
+-#
+-
+-@contextmanager
+-def _cached(func):
+-    try:
+-        func.__cached__
+-        yield func
+-    except AttributeError:
+-        cache = {}
+-        def wrapper(*args):
+-            try:
+-                return cache[args]
+-            except KeyError:
+-                value = cache[args] = func(*args)
+-                return value
+-        wrapper.__cached__ = True
+-        try:
+-            yield wrapper
+-        finally:
+-            cache.clear()
+-
+-def _make_selector(pattern_parts):
+-    pat = pattern_parts[0]
+-    child_parts = pattern_parts[1:]
+-    if pat == '**':
+-        cls = _RecursiveWildcardSelector
+-    elif '**' in pat:
+-        raise ValueError("Invalid pattern: '**' can only be an entire path component")
+-    elif _is_wildcard_pattern(pat):
+-        cls = _WildcardSelector
+-    else:
+-        cls = _PreciseSelector
+-    return cls(pat, child_parts)
+-
+-if hasattr(functools, "lru_cache"):
+-    _make_selector = functools.lru_cache()(_make_selector)
+-
+-
+-class _Selector:
+-    """A selector matches a specific glob pattern part against the children
+-    of a given path."""
+-
+-    def __init__(self, child_parts):
+-        self.child_parts = child_parts
+-        if child_parts:
+-            self.successor = _make_selector(child_parts)
+-        else:
+-            self.successor = _TerminatingSelector()
+-
+-    def select_from(self, parent_path):
+-        """Iterate over all child paths of `parent_path` matched by this
+-        selector.  This can contain parent_path itself."""
+-        path_cls = type(parent_path)
+-        is_dir = path_cls.is_dir
+-        exists = path_cls.exists
+-        listdir = parent_path._accessor.listdir
+-        return self._select_from(parent_path, is_dir, exists, listdir)
+-
+-
+-class _TerminatingSelector:
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        yield parent_path
+-
+-
+-class _PreciseSelector(_Selector):
+-
+-    def __init__(self, name, child_parts):
+-        self.name = name
+-        _Selector.__init__(self, child_parts)
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        if not is_dir(parent_path):
+-            return
+-        path = parent_path._make_child_relpath(self.name)
+-        if exists(path):
+-            for p in self.successor._select_from(path, is_dir, exists, listdir):
+-                yield p
+-
+-
+-class _WildcardSelector(_Selector):
+-
+-    def __init__(self, pat, child_parts):
+-        self.pat = re.compile(fnmatch.translate(pat))
+-        _Selector.__init__(self, child_parts)
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        if not is_dir(parent_path):
+-            return
+-        cf = parent_path._flavour.casefold
+-        for name in listdir(parent_path):
+-            casefolded = cf(name)
+-            if self.pat.match(casefolded):
+-                path = parent_path._make_child_relpath(name)
+-                for p in self.successor._select_from(path, is_dir, exists, listdir):
+-                    yield p
+-
+-
+-class _RecursiveWildcardSelector(_Selector):
+-
+-    def __init__(self, pat, child_parts):
+-        _Selector.__init__(self, child_parts)
+-
+-    def _iterate_directories(self, parent_path, is_dir, listdir):
+-        yield parent_path
+-        for name in listdir(parent_path):
+-            path = parent_path._make_child_relpath(name)
+-            if is_dir(path):
+-                for p in self._iterate_directories(path, is_dir, listdir):
+-                    yield p
+-
+-    def _select_from(self, parent_path, is_dir, exists, listdir):
+-        if not is_dir(parent_path):
+-            return
+-        with _cached(listdir) as listdir:
+-            yielded = set()
+-            try:
+-                successor_select = self.successor._select_from
+-                for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
+-                    for p in successor_select(starting_point, is_dir, exists, listdir):
+-                        if p not in yielded:
+-                            yield p
+-                            yielded.add(p)
+-            finally:
+-                yielded.clear()
+-
+-
+-#
+-# Public API
+-#
+-
+-class _PathParents(Sequence):
+-    """This object provides sequence-like access to the logical ancestors
+-    of a path.  Don't try to construct it yourself."""
+-    __slots__ = ('_pathcls', '_drv', '_root', '_parts')
+-
+-    def __init__(self, path):
+-        # We don't store the instance to avoid reference cycles
+-        self._pathcls = type(path)
+-        self._drv = path._drv
+-        self._root = path._root
+-        self._parts = path._parts
+-
+-    def __len__(self):
+-        if self._drv or self._root:
+-            return len(self._parts) - 1
+-        else:
+-            return len(self._parts)
+-
+-    def __getitem__(self, idx):
+-        if idx < 0 or idx >= len(self):
+-            raise IndexError(idx)
+-        return self._pathcls._from_parsed_parts(self._drv, self._root,
+-                                                self._parts[:-idx - 1])
+-
+-    def __repr__(self):
+-        return "<{0}.parents>".format(self._pathcls.__name__)
+-
+-
+-class PurePath(object):
+-    """PurePath represents a filesystem path and offers operations which
+-    don't imply any actual filesystem I/O.  Depending on your system,
+-    instantiating a PurePath will return either a PurePosixPath or a
+-    PureWindowsPath object.  You can also instantiate either of these classes
+-    directly, regardless of your system.
+-    """
+-    __slots__ = (
+-        '_drv', '_root', '_parts',
+-        '_str', '_hash', '_pparts', '_cached_cparts',
+-    )
+-
+-    def __new__(cls, *args):
+-        """Construct a PurePath from one or several strings and or existing
+-        PurePath objects.  The strings and path objects are combined so as
+-        to yield a canonicalized path, which is incorporated into the
+-        new PurePath object.
+-        """
+-        if cls is PurePath:
+-            cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
+-        return cls._from_parts(args)
+-
+-    def __reduce__(self):
+-        # Using the parts tuple helps share interned path parts
+-        # when pickling related paths.
+-        return (self.__class__, tuple(self._parts))
+-
+-    @classmethod
+-    def _parse_args(cls, args):
+-        # This is useful when you don't want to create an instance, just
+-        # canonicalize some constructor arguments.
+-        parts = []
+-        for a in args:
+-            if isinstance(a, PurePath):
+-                parts += a._parts
+-            elif isinstance(a, basestring):
+-                parts.append(a)
+-            else:
+-                raise TypeError(
+-                    "argument should be a path or str object, not %r"
+-                    % type(a))
+-        return cls._flavour.parse_parts(parts)
+-
+-    @classmethod
+-    def _from_parts(cls, args, init=True):
+-        # We need to call _parse_args on the instance, so as to get the
+-        # right flavour.
+-        self = object.__new__(cls)
+-        drv, root, parts = self._parse_args(args)
+-        self._drv = drv
+-        self._root = root
+-        self._parts = parts
+-        if init:
+-            self._init()
+-        return self
+-
+-    @classmethod
+-    def _from_parsed_parts(cls, drv, root, parts, init=True):
+-        self = object.__new__(cls)
+-        self._drv = drv
+-        self._root = root
+-        self._parts = parts
+-        if init:
+-            self._init()
+-        return self
+-
+-    @classmethod
+-    def _format_parsed_parts(cls, drv, root, parts):
+-        if drv or root:
+-            return drv + root + cls._flavour.join(parts[1:])
+-        else:
+-            return cls._flavour.join(parts)
+-
+-    def _init(self):
+-        # Overriden in concrete Path
+-        pass
+-
+-    def _make_child(self, args):
+-        drv, root, parts = self._parse_args(args)
+-        drv, root, parts = self._flavour.join_parsed_parts(
+-            self._drv, self._root, self._parts, drv, root, parts)
+-        return self._from_parsed_parts(drv, root, parts)
+-
+-    def __str__(self):
+-        """Return the string representation of the path, suitable for
+-        passing to system calls."""
+-        try:
+-            return self._str
+-        except AttributeError:
+-            self._str = self._format_parsed_parts(self._drv, self._root,
+-                                                  self._parts) or '.'
+-            return self._str
+-
+-    def as_posix(self):
+-        """Return the string representation of the path with forward (/)
+-        slashes."""
+-        f = self._flavour
+-        return str(self).replace(f.sep, '/')
+-
+-    def __bytes__(self):
+-        """Return the bytes representation of the path.  This is only
+-        recommended to use under Unix."""
+-        if sys.version_info < (3, 2):
+-            raise NotImplementedError("needs Python 3.2 or later")
+-        return os.fsencode(str(self))
+-
+-    def __repr__(self):
+-        return "{0}({1!r})".format(self.__class__.__name__, self.as_posix())
+-
+-    def as_uri(self):
+-        """Return the path as a 'file' URI."""
+-        if not self.is_absolute():
+-            raise ValueError("relative path can't be expressed as a file URI")
+-        return self._flavour.make_uri(self)
+-
+-    @property
+-    def _cparts(self):
+-        # Cached casefolded parts, for hashing and comparison
+-        try:
+-            return self._cached_cparts
+-        except AttributeError:
+-            self._cached_cparts = self._flavour.casefold_parts(self._parts)
+-            return self._cached_cparts
+-
+-    def __eq__(self, other):
+-        if not isinstance(other, PurePath):
+-            return NotImplemented
+-        return self._cparts == other._cparts and self._flavour is other._flavour
+-
+-    def __ne__(self, other):
+-        return not self == other
+-
+-    def __hash__(self):
+-        try:
+-            return self._hash
+-        except AttributeError:
+-            self._hash = hash(tuple(self._cparts))
+-            return self._hash
+-
+-    def __lt__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts < other._cparts
+-
+-    def __le__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts <= other._cparts
+-
+-    def __gt__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts > other._cparts
+-
+-    def __ge__(self, other):
+-        if not isinstance(other, PurePath) or self._flavour is not other._flavour:
+-            return NotImplemented
+-        return self._cparts >= other._cparts
+-
+-    drive = property(attrgetter('_drv'),
+-                     doc="""The drive prefix (letter or UNC path), if any.""")
+-
+-    root = property(attrgetter('_root'),
+-                    doc="""The root of the path, if any.""")
+-
+-    @property
+-    def anchor(self):
+-        """The concatenation of the drive and root, or ''."""
+-        anchor = self._drv + self._root
+-        return anchor
+-
+-    @property
+-    def name(self):
+-        """The final path component, if any."""
+-        parts = self._parts
+-        if len(parts) == (1 if (self._drv or self._root) else 0):
+-            return ''
+-        return parts[-1]
+-
+-    @property
+-    def suffix(self):
+-        """The final component's last suffix, if any."""
+-        name = self.name
+-        i = name.rfind('.')
+-        if 0 < i < len(name) - 1:
+-            return name[i:]
+-        else:
+-            return ''
+-
+-    @property
+-    def suffixes(self):
+-        """A list of the final component's suffixes, if any."""
+-        name = self.name
+-        if name.endswith('.'):
+-            return []
+-        name = name.lstrip('.')
+-        return ['.' + suffix for suffix in name.split('.')[1:]]
+-
+-    @property
+-    def stem(self):
+-        """The final path component, minus its last suffix."""
+-        name = self.name
+-        i = name.rfind('.')
+-        if 0 < i < len(name) - 1:
+-            return name[:i]
+-        else:
+-            return name
+-
+-    def with_name(self, name):
+-        """Return a new path with the file name changed."""
+-        if not self.name:
+-            raise ValueError("%r has an empty name" % (self,))
+-        return self._from_parsed_parts(self._drv, self._root,
+-                                       self._parts[:-1] + [name])
+-
+-    def with_suffix(self, suffix):
+-        """Return a new path with the file suffix changed (or added, if none)."""
+-        # XXX if suffix is None, should the current suffix be removed?
+-        drv, root, parts = self._flavour.parse_parts((suffix,))
+-        if drv or root or len(parts) != 1:
+-            raise ValueError("Invalid suffix %r" % (suffix))
+-        suffix = parts[0]
+-        if not suffix.startswith('.'):
+-            raise ValueError("Invalid suffix %r" % (suffix))
+-        name = self.name
+-        if not name:
+-            raise ValueError("%r has an empty name" % (self,))
+-        old_suffix = self.suffix
+-        if not old_suffix:
+-            name = name + suffix
+-        else:
+-            name = name[:-len(old_suffix)] + suffix
+-        return self._from_parsed_parts(self._drv, self._root,
+-                                       self._parts[:-1] + [name])
+-
+-    def relative_to(self, *other):
+-        """Return the relative path to another path identified by the passed
+-        arguments.  If the operation is not possible (because this is not
+-        a subpath of the other path), raise ValueError.
+-        """
+-        # For the purpose of this method, drive and root are considered
+-        # separate parts, i.e.:
+-        #   Path('c:/').relative_to('c:')  gives Path('/')
+-        #   Path('c:/').relative_to('/')   raise ValueError
+-        if not other:
+-            raise TypeError("need at least one argument")
+-        parts = self._parts
+-        drv = self._drv
+-        root = self._root
+-        if root:
+-            abs_parts = [drv, root] + parts[1:]
+-        else:
+-            abs_parts = parts
+-        to_drv, to_root, to_parts = self._parse_args(other)
+-        if to_root:
+-            to_abs_parts = [to_drv, to_root] + to_parts[1:]
+-        else:
+-            to_abs_parts = to_parts
+-        n = len(to_abs_parts)
+-        cf = self._flavour.casefold_parts
+-        if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts):
+-            formatted = self._format_parsed_parts(to_drv, to_root, to_parts)
+-            raise ValueError("{!r} does not start with {!r}"
+-                             .format(str(self), str(formatted)))
+-        return self._from_parsed_parts('', root if n == 1 else '',
+-                                       abs_parts[n:])
+-
+-    @property
+-    def parts(self):
+-        """An object providing sequence-like access to the
+-        components in the filesystem path."""
+-        # We cache the tuple to avoid building a new one each time .parts
+-        # is accessed.  XXX is this necessary?
+-        try:
+-            return self._pparts
+-        except AttributeError:
+-            self._pparts = tuple(self._parts)
+-            return self._pparts
+-
+-    def joinpath(self, *args):
+-        """Combine this path with one or several arguments, and return a
+-        new path representing either a subpath (if all arguments are relative
+-        paths) or a totally different path (if one of the arguments is
+-        anchored).
+-        """
+-        return self._make_child(args)
+-
+-    def __truediv__(self, key):
+-        return self._make_child((key,))
+-
+-    def __rtruediv__(self, key):
+-        return self._from_parts([key] + self._parts)
+-
+-    if sys.version_info < (3,):
+-        __div__ = __truediv__
+-        __rdiv__ = __rtruediv__
+-
+-    @property
+-    def parent(self):
+-        """The logical parent of the path."""
+-        drv = self._drv
+-        root = self._root
+-        parts = self._parts
+-        if len(parts) == 1 and (drv or root):
+-            return self
+-        return self._from_parsed_parts(drv, root, parts[:-1])
+-
+-    @property
+-    def parents(self):
+-        """A sequence of this path's logical parents."""
+-        return _PathParents(self)
+-
+-    def is_absolute(self):
+-        """True if the path is absolute (has both a root and, if applicable,
+-        a drive)."""
+-        if not self._root:
+-            return False
+-        return not self._flavour.has_drv or bool(self._drv)
+-
+-    def is_reserved(self):
+-        """Return True if the path contains one of the special names reserved
+-        by the system, if any."""
+-        return self._flavour.is_reserved(self._parts)
+-
+-    def match(self, path_pattern):
+-        """
+-        Return True if this path matches the given pattern.
+-        """
+-        cf = self._flavour.casefold
+-        path_pattern = cf(path_pattern)
+-        drv, root, pat_parts = self._flavour.parse_parts((path_pattern,))
+-        if not pat_parts:
+-            raise ValueError("empty pattern")
+-        if drv and drv != cf(self._drv):
+-            return False
+-        if root and root != cf(self._root):
+-            return False
+-        parts = self._cparts
+-        if drv or root:
+-            if len(pat_parts) != len(parts):
+-                return False
+-            pat_parts = pat_parts[1:]
+-        elif len(pat_parts) > len(parts):
+-            return False
+-        for part, pat in zip(reversed(parts), reversed(pat_parts)):
+-            if not fnmatch.fnmatchcase(part, pat):
+-                return False
+-        return True
+-
+-
+-class PurePosixPath(PurePath):
+-    _flavour = _posix_flavour
+-    __slots__ = ()
+-
+-
+-class PureWindowsPath(PurePath):
+-    _flavour = _windows_flavour
+-    __slots__ = ()
+-
+-
+-# Filesystem-accessing classes
+-
+-
+-class Path(PurePath):
+-    __slots__ = (
+-        '_accessor',
+-    )
+-
+-    def __new__(cls, *args, **kwargs):
+-        if cls is Path:
+-            cls = WindowsPath if os.name == 'nt' else PosixPath
+-        self = cls._from_parts(args, init=False)
+-        if not self._flavour.is_supported:
+-            raise NotImplementedError("cannot instantiate %r on your system"
+-                                      % (cls.__name__,))
+-        self._init()
+-        return self
+-
+-    def _init(self,
+-              # Private non-constructor arguments
+-              template=None,
+-              ):
+-        if template is not None:
+-            self._accessor = template._accessor
+-        else:
+-            self._accessor = _normal_accessor
+-
+-    def _make_child_relpath(self, part):
+-        # This is an optimization used for dir walking.  `part` must be
+-        # a single part relative to this path.
+-        parts = self._parts + [part]
+-        return self._from_parsed_parts(self._drv, self._root, parts)
+-
+-    def _opener(self, name, flags, mode=0o666):
+-        # A stub for the opener argument to built-in open()
+-        return self._accessor.open(self, flags, mode)
+-
+-    def _raw_open(self, flags, mode=0o777):
+-        """
+-        Open the file pointed by this path and return a file descriptor,
+-        as os.open() does.
+-        """
+-        return self._accessor.open(self, flags, mode)
+-
+-    # Public API
+-
+-    @classmethod
+-    def cwd(cls):
+-        """Return a new path pointing to the current working directory
+-        (as returned by os.getcwd()).
+-        """
+-        return cls(os.getcwd())
+-
+-    def iterdir(self):
+-        """Iterate over the files in this directory.  Does not yield any
+-        result for the special paths '.' and '..'.
+-        """
+-        for name in self._accessor.listdir(self):
+-            if name in ('.', '..'):
+-                # Yielding a path object for these makes little sense
+-                continue
+-            yield self._make_child_relpath(name)
+-
+-    def glob(self, pattern):
+-        """Iterate over this subtree and yield all existing files (of any
+-        kind, including directories) matching the given pattern.
+-        """
+-        pattern = self._flavour.casefold(pattern)
+-        drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
+-        if drv or root:
+-            raise NotImplementedError("Non-relative patterns are unsupported")
+-        selector = _make_selector(tuple(pattern_parts))
+-        for p in selector.select_from(self):
+-            yield p
+-
+-    def rglob(self, pattern):
+-        """Recursively yield all existing files (of any kind, including
+-        directories) matching the given pattern, anywhere in this subtree.
+-        """
+-        pattern = self._flavour.casefold(pattern)
+-        drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
+-        if drv or root:
+-            raise NotImplementedError("Non-relative patterns are unsupported")
+-        selector = _make_selector(("**",) + tuple(pattern_parts))
+-        for p in selector.select_from(self):
+-            yield p
+-
+-    def absolute(self):
+-        """Return an absolute version of this path.  This function works
+-        even if the path doesn't point to anything.
+-
+-        No normalization is done, i.e. all '.' and '..' will be kept along.
+-        Use resolve() to get the canonical path to a file.
+-        """
+-        # XXX untested yet!
+-        if self.is_absolute():
+-            return self
+-        # FIXME this must defer to the specific flavour (and, under Windows,
+-        # use nt._getfullpathname())
+-        obj = self._from_parts([os.getcwd()] + self._parts, init=False)
+-        obj._init(template=self)
+-        return obj
+-
+-    def resolve(self):
+-        """
+-        Make the path absolute, resolving all symlinks on the way and also
+-        normalizing it (for example turning slashes into backslashes under
+-        Windows).
+-        """
+-        s = self._flavour.resolve(self)
+-        if s is None:
+-            # No symlink resolution => for consistency, raise an error if
+-            # the path doesn't exist or is forbidden
+-            self.stat()
+-            s = str(self.absolute())
+-        # Now we have no symlinks in the path, it's safe to normalize it.
+-        normed = self._flavour.pathmod.normpath(s)
+-        obj = self._from_parts((normed,), init=False)
+-        obj._init(template=self)
+-        return obj
+-
+-    def stat(self):
+-        """
+-        Return the result of the stat() system call on this path, like
+-        os.stat() does.
+-        """
+-        return self._accessor.stat(self)
+-
+-    def owner(self):
+-        """
+-        Return the login name of the file owner.
+-        """
+-        import pwd
+-        return pwd.getpwuid(self.stat().st_uid).pw_name
+-
+-    def group(self):
+-        """
+-        Return the group name of the file gid.
+-        """
+-        import grp
+-        return grp.getgrgid(self.stat().st_gid).gr_name
+-
+-    def open(self, mode='r', buffering=-1, encoding=None,
+-             errors=None, newline=None):
+-        """
+-        Open the file pointed by this path and return a file object, as
+-        the built-in open() function does.
+-        """
+-        if sys.version_info >= (3, 3):
+-            return io.open(str(self), mode, buffering, encoding, errors, newline,
+-                           opener=self._opener)
+-        else:
+-            return io.open(str(self), mode, buffering, encoding, errors, newline)
+-
+-    def touch(self, mode=0o666, exist_ok=True):
+-        """
+-        Create this file with the given access mode, if it doesn't exist.
+-        """
+-        if exist_ok:
+-            # First try to bump modification time
+-            # Implementation note: GNU touch uses the UTIME_NOW option of
+-            # the utimensat() / futimens() functions.
+-            t = time.time()
+-            try:
+-                self._accessor.utime(self, (t, t))
+-            except OSError:
+-                # Avoid exception chaining
+-                pass
+-            else:
+-                return
+-        flags = os.O_CREAT | os.O_WRONLY
+-        if not exist_ok:
+-            flags |= os.O_EXCL
+-        fd = self._raw_open(flags, mode)
+-        os.close(fd)
+-
+-    def mkdir(self, mode=0o777, parents=False):
+-        if not parents:
+-            self._accessor.mkdir(self, mode)
+-        else:
+-            try:
+-                self._accessor.mkdir(self, mode)
+-            except OSError as e:
+-                if e.errno != ENOENT:
+-                    raise
+-                self.parent.mkdir(parents=True)
+-                self._accessor.mkdir(self, mode)
+-
+-    def chmod(self, mode):
+-        """
+-        Change the permissions of the path, like os.chmod().
+-        """
+-        self._accessor.chmod(self, mode)
+-
+-    def lchmod(self, mode):
+-        """
+-        Like chmod(), except if the path points to a symlink, the symlink's
+-        permissions are changed, rather than its target's.
+-        """
+-        self._accessor.lchmod(self, mode)
+-
+-    def unlink(self):
+-        """
+-        Remove this file or link.
+-        If the path is a directory, use rmdir() instead.
+-        """
+-        self._accessor.unlink(self)
+-
+-    def rmdir(self):
+-        """
+-        Remove this directory.  The directory must be empty.
+-        """
+-        self._accessor.rmdir(self)
+-
+-    def lstat(self):
+-        """
+-        Like stat(), except if the path points to a symlink, the symlink's
+-        status information is returned, rather than its target's.
+-        """
+-        return self._accessor.lstat(self)
+-
+-    def rename(self, target):
+-        """
+-        Rename this path to the given path.
+-        """
+-        self._accessor.rename(self, target)
+-
+-    def replace(self, target):
+-        """
+-        Rename this path to the given path, clobbering the existing
+-        destination if it exists.
+-        """
+-        if sys.version_info < (3, 3):
+-            raise NotImplementedError("replace() is only available "
+-                                      "with Python 3.3 and later")
+-        self._accessor.replace(self, target)
+-
+-    def symlink_to(self, target, target_is_directory=False):
+-        """
+-        Make this path a symlink pointing to the given path.
+-        Note the order of arguments (self, target) is the reverse of os.symlink's.
+-        """
+-        self._accessor.symlink(target, self, target_is_directory)
+-
+-    # Convenience functions for querying the stat results
+-
+-    def exists(self):
+-        """
+-        Whether this path exists.
+-        """
+-        try:
+-            self.stat()
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            return False
+-        return True
+-
+-    def is_dir(self):
+-        """
+-        Whether this path is a directory.
+-        """
+-        try:
+-            return S_ISDIR(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_file(self):
+-        """
+-        Whether this path is a regular file (also True for symlinks pointing
+-        to regular files).
+-        """
+-        try:
+-            return S_ISREG(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_symlink(self):
+-        """
+-        Whether this path is a symbolic link.
+-        """
+-        try:
+-            return S_ISLNK(self.lstat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist
+-            return False
+-
+-    def is_block_device(self):
+-        """
+-        Whether this path is a block device.
+-        """
+-        try:
+-            return S_ISBLK(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_char_device(self):
+-        """
+-        Whether this path is a character device.
+-        """
+-        try:
+-            return S_ISCHR(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_fifo(self):
+-        """
+-        Whether this path is a FIFO.
+-        """
+-        try:
+-            return S_ISFIFO(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-    def is_socket(self):
+-        """
+-        Whether this path is a socket.
+-        """
+-        try:
+-            return S_ISSOCK(self.stat().st_mode)
+-        except OSError as e:
+-            if e.errno != ENOENT:
+-                raise
+-            # Path doesn't exist or is a broken symlink
+-            # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
+-            return False
+-
+-
+-class PosixPath(Path, PurePosixPath):
+-    __slots__ = ()
+-
+-class WindowsPath(Path, PureWindowsPath):
+-    __slots__ = ()
+-
+diff --git a/tasks/_vendor/six.py b/tasks/_vendor/six.py
+deleted file mode 100644
+index 190c023..0000000
+--- a/tasks/_vendor/six.py
++++ /dev/null
+@@ -1,868 +0,0 @@
+-"""Utilities for writing code that runs on Python 2 and 3"""
+-
+-# Copyright (c) 2010-2015 Benjamin Peterson
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy
+-# of this software and associated documentation files (the "Software"), to deal
+-# in the Software without restriction, including without limitation the rights
+-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-# copies of the Software, and to permit persons to whom the Software is
+-# furnished to do so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+-
+-from __future__ import absolute_import
+-
+-import functools
+-import itertools
+-import operator
+-import sys
+-import types
+-
+-__author__ = "Benjamin Peterson <benjamin@python.org>"
+-__version__ = "1.10.0"
+-
+-
+-# Useful for very coarse version differentiation.
+-PY2 = sys.version_info[0] == 2
+-PY3 = sys.version_info[0] == 3
+-PY34 = sys.version_info[0:2] >= (3, 4)
+-
+-if PY3:
+-    string_types = str,
+-    integer_types = int,
+-    class_types = type,
+-    text_type = str
+-    binary_type = bytes
+-
+-    MAXSIZE = sys.maxsize
+-else:
+-    string_types = basestring,
+-    integer_types = (int, long)
+-    class_types = (type, types.ClassType)
+-    text_type = unicode
+-    binary_type = str
+-
+-    if sys.platform.startswith("java"):
+-        # Jython always uses 32 bits.
+-        MAXSIZE = int((1 << 31) - 1)
+-    else:
+-        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+-        class X(object):
+-
+-            def __len__(self):
+-                return 1 << 31
+-        try:
+-            len(X())
+-        except OverflowError:
+-            # 32-bit
+-            MAXSIZE = int((1 << 31) - 1)
+-        else:
+-            # 64-bit
+-            MAXSIZE = int((1 << 63) - 1)
+-        del X
+-
+-
+-def _add_doc(func, doc):
+-    """Add documentation to a function."""
+-    func.__doc__ = doc
+-
+-
+-def _import_module(name):
+-    """Import module, returning the module after the last dot."""
+-    __import__(name)
+-    return sys.modules[name]
+-
+-
+-class _LazyDescr(object):
+-
+-    def __init__(self, name):
+-        self.name = name
+-
+-    def __get__(self, obj, tp):
+-        result = self._resolve()
+-        setattr(obj, self.name, result)  # Invokes __set__.
+-        try:
+-            # This is a bit ugly, but it avoids running this again by
+-            # removing this descriptor.
+-            delattr(obj.__class__, self.name)
+-        except AttributeError:
+-            pass
+-        return result
+-
+-
+-class MovedModule(_LazyDescr):
+-
+-    def __init__(self, name, old, new=None):
+-        super(MovedModule, self).__init__(name)
+-        if PY3:
+-            if new is None:
+-                new = name
+-            self.mod = new
+-        else:
+-            self.mod = old
+-
+-    def _resolve(self):
+-        return _import_module(self.mod)
+-
+-    def __getattr__(self, attr):
+-        _module = self._resolve()
+-        value = getattr(_module, attr)
+-        setattr(self, attr, value)
+-        return value
+-
+-
+-class _LazyModule(types.ModuleType):
+-
+-    def __init__(self, name):
+-        super(_LazyModule, self).__init__(name)
+-        self.__doc__ = self.__class__.__doc__
+-
+-    def __dir__(self):
+-        attrs = ["__doc__", "__name__"]
+-        attrs += [attr.name for attr in self._moved_attributes]
+-        return attrs
+-
+-    # Subclasses should override this
+-    _moved_attributes = []
+-
+-
+-class MovedAttribute(_LazyDescr):
+-
+-    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+-        super(MovedAttribute, self).__init__(name)
+-        if PY3:
+-            if new_mod is None:
+-                new_mod = name
+-            self.mod = new_mod
+-            if new_attr is None:
+-                if old_attr is None:
+-                    new_attr = name
+-                else:
+-                    new_attr = old_attr
+-            self.attr = new_attr
+-        else:
+-            self.mod = old_mod
+-            if old_attr is None:
+-                old_attr = name
+-            self.attr = old_attr
+-
+-    def _resolve(self):
+-        module = _import_module(self.mod)
+-        return getattr(module, self.attr)
+-
+-
+-class _SixMetaPathImporter(object):
+-
+-    """
+-    A meta path importer to import six.moves and its submodules.
+-
+-    This class implements a PEP302 finder and loader. It should be compatible
+-    with Python 2.5 and all existing versions of Python3
+-    """
+-
+-    def __init__(self, six_module_name):
+-        self.name = six_module_name
+-        self.known_modules = {}
+-
+-    def _add_module(self, mod, *fullnames):
+-        for fullname in fullnames:
+-            self.known_modules[self.name + "." + fullname] = mod
+-
+-    def _get_module(self, fullname):
+-        return self.known_modules[self.name + "." + fullname]
+-
+-    def find_module(self, fullname, path=None):
+-        if fullname in self.known_modules:
+-            return self
+-        return None
+-
+-    def __get_module(self, fullname):
+-        try:
+-            return self.known_modules[fullname]
+-        except KeyError:
+-            raise ImportError("This loader does not know module " + fullname)
+-
+-    def load_module(self, fullname):
+-        try:
+-            # in case of a reload
+-            return sys.modules[fullname]
+-        except KeyError:
+-            pass
+-        mod = self.__get_module(fullname)
+-        if isinstance(mod, MovedModule):
+-            mod = mod._resolve()
+-        else:
+-            mod.__loader__ = self
+-        sys.modules[fullname] = mod
+-        return mod
+-
+-    def is_package(self, fullname):
+-        """
+-        Return true, if the named module is a package.
+-
+-        We need this method to get correct spec objects with
+-        Python 3.4 (see PEP451)
+-        """
+-        return hasattr(self.__get_module(fullname), "__path__")
+-
+-    def get_code(self, fullname):
+-        """Return None
+-
+-        Required, if is_package is implemented"""
+-        self.__get_module(fullname)  # eventually raises ImportError
+-        return None
+-    get_source = get_code  # same as get_code
+-
+-_importer = _SixMetaPathImporter(__name__)
+-
+-
+-class _MovedItems(_LazyModule):
+-
+-    """Lazy loading of moved objects"""
+-    __path__ = []  # mark as package
+-
+-
+-_moved_attributes = [
+-    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+-    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+-    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+-    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+-    MovedAttribute("intern", "__builtin__", "sys"),
+-    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+-    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+-    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+-    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+-    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+-    MovedAttribute("reduce", "__builtin__", "functools"),
+-    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+-    MovedAttribute("StringIO", "StringIO", "io"),
+-    MovedAttribute("UserDict", "UserDict", "collections"),
+-    MovedAttribute("UserList", "UserList", "collections"),
+-    MovedAttribute("UserString", "UserString", "collections"),
+-    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+-    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+-    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+-    MovedModule("builtins", "__builtin__"),
+-    MovedModule("configparser", "ConfigParser"),
+-    MovedModule("copyreg", "copy_reg"),
+-    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+-    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+-    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+-    MovedModule("http_cookies", "Cookie", "http.cookies"),
+-    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+-    MovedModule("html_parser", "HTMLParser", "html.parser"),
+-    MovedModule("http_client", "httplib", "http.client"),
+-    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+-    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+-    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+-    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+-    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+-    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+-    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+-    MovedModule("cPickle", "cPickle", "pickle"),
+-    MovedModule("queue", "Queue"),
+-    MovedModule("reprlib", "repr"),
+-    MovedModule("socketserver", "SocketServer"),
+-    MovedModule("_thread", "thread", "_thread"),
+-    MovedModule("tkinter", "Tkinter"),
+-    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+-    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+-    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+-    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+-    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+-    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+-    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+-    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+-    MovedModule("tkinter_colorchooser", "tkColorChooser",
+-                "tkinter.colorchooser"),
+-    MovedModule("tkinter_commondialog", "tkCommonDialog",
+-                "tkinter.commondialog"),
+-    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+-    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+-    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+-    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+-                "tkinter.simpledialog"),
+-    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+-    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+-    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+-    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+-    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+-    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+-]
+-# Add windows specific modules.
+-if sys.platform == "win32":
+-    _moved_attributes += [
+-        MovedModule("winreg", "_winreg"),
+-    ]
+-
+-for attr in _moved_attributes:
+-    setattr(_MovedItems, attr.name, attr)
+-    if isinstance(attr, MovedModule):
+-        _importer._add_module(attr, "moves." + attr.name)
+-del attr
+-
+-_MovedItems._moved_attributes = _moved_attributes
+-
+-moves = _MovedItems(__name__ + ".moves")
+-_importer._add_module(moves, "moves")
+-
+-
+-class Module_six_moves_urllib_parse(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_parse"""
+-
+-
+-_urllib_parse_moved_attributes = [
+-    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+-    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+-    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+-    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+-    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+-    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+-    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+-    MovedAttribute("quote", "urllib", "urllib.parse"),
+-    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+-    MovedAttribute("unquote", "urllib", "urllib.parse"),
+-    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+-    MovedAttribute("urlencode", "urllib", "urllib.parse"),
+-    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+-    MovedAttribute("splittag", "urllib", "urllib.parse"),
+-    MovedAttribute("splituser", "urllib", "urllib.parse"),
+-    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+-    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+-]
+-for attr in _urllib_parse_moved_attributes:
+-    setattr(Module_six_moves_urllib_parse, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+-                      "moves.urllib_parse", "moves.urllib.parse")
+-
+-
+-class Module_six_moves_urllib_error(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_error"""
+-
+-
+-_urllib_error_moved_attributes = [
+-    MovedAttribute("URLError", "urllib2", "urllib.error"),
+-    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+-    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+-]
+-for attr in _urllib_error_moved_attributes:
+-    setattr(Module_six_moves_urllib_error, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+-                      "moves.urllib_error", "moves.urllib.error")
+-
+-
+-class Module_six_moves_urllib_request(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_request"""
+-
+-
+-_urllib_request_moved_attributes = [
+-    MovedAttribute("urlopen", "urllib2", "urllib.request"),
+-    MovedAttribute("install_opener", "urllib2", "urllib.request"),
+-    MovedAttribute("build_opener", "urllib2", "urllib.request"),
+-    MovedAttribute("pathname2url", "urllib", "urllib.request"),
+-    MovedAttribute("url2pathname", "urllib", "urllib.request"),
+-    MovedAttribute("getproxies", "urllib", "urllib.request"),
+-    MovedAttribute("Request", "urllib2", "urllib.request"),
+-    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+-    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+-    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+-    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+-    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+-    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+-    MovedAttribute("URLopener", "urllib", "urllib.request"),
+-    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+-    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+-]
+-for attr in _urllib_request_moved_attributes:
+-    setattr(Module_six_moves_urllib_request, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+-                      "moves.urllib_request", "moves.urllib.request")
+-
+-
+-class Module_six_moves_urllib_response(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_response"""
+-
+-
+-_urllib_response_moved_attributes = [
+-    MovedAttribute("addbase", "urllib", "urllib.response"),
+-    MovedAttribute("addclosehook", "urllib", "urllib.response"),
+-    MovedAttribute("addinfo", "urllib", "urllib.response"),
+-    MovedAttribute("addinfourl", "urllib", "urllib.response"),
+-]
+-for attr in _urllib_response_moved_attributes:
+-    setattr(Module_six_moves_urllib_response, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+-                      "moves.urllib_response", "moves.urllib.response")
+-
+-
+-class Module_six_moves_urllib_robotparser(_LazyModule):
+-
+-    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+-
+-
+-_urllib_robotparser_moved_attributes = [
+-    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+-]
+-for attr in _urllib_robotparser_moved_attributes:
+-    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+-del attr
+-
+-Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+-
+-_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+-                      "moves.urllib_robotparser", "moves.urllib.robotparser")
+-
+-
+-class Module_six_moves_urllib(types.ModuleType):
+-
+-    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+-    __path__ = []  # mark as package
+-    parse = _importer._get_module("moves.urllib_parse")
+-    error = _importer._get_module("moves.urllib_error")
+-    request = _importer._get_module("moves.urllib_request")
+-    response = _importer._get_module("moves.urllib_response")
+-    robotparser = _importer._get_module("moves.urllib_robotparser")
+-
+-    def __dir__(self):
+-        return ['parse', 'error', 'request', 'response', 'robotparser']
+-
+-_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+-                      "moves.urllib")
+-
+-
+-def add_move(move):
+-    """Add an item to six.moves."""
+-    setattr(_MovedItems, move.name, move)
+-
+-
+-def remove_move(name):
+-    """Remove item from six.moves."""
+-    try:
+-        delattr(_MovedItems, name)
+-    except AttributeError:
+-        try:
+-            del moves.__dict__[name]
+-        except KeyError:
+-            raise AttributeError("no such move, %r" % (name,))
+-
+-
+-if PY3:
+-    _meth_func = "__func__"
+-    _meth_self = "__self__"
+-
+-    _func_closure = "__closure__"
+-    _func_code = "__code__"
+-    _func_defaults = "__defaults__"
+-    _func_globals = "__globals__"
+-else:
+-    _meth_func = "im_func"
+-    _meth_self = "im_self"
+-
+-    _func_closure = "func_closure"
+-    _func_code = "func_code"
+-    _func_defaults = "func_defaults"
+-    _func_globals = "func_globals"
+-
+-
+-try:
+-    advance_iterator = next
+-except NameError:
+-    def advance_iterator(it):
+-        return it.next()
+-next = advance_iterator
+-
+-
+-try:
+-    callable = callable
+-except NameError:
+-    def callable(obj):
+-        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+-
+-
+-if PY3:
+-    def get_unbound_function(unbound):
+-        return unbound
+-
+-    create_bound_method = types.MethodType
+-
+-    def create_unbound_method(func, cls):
+-        return func
+-
+-    Iterator = object
+-else:
+-    def get_unbound_function(unbound):
+-        return unbound.im_func
+-
+-    def create_bound_method(func, obj):
+-        return types.MethodType(func, obj, obj.__class__)
+-
+-    def create_unbound_method(func, cls):
+-        return types.MethodType(func, None, cls)
+-
+-    class Iterator(object):
+-
+-        def next(self):
+-            return type(self).__next__(self)
+-
+-    callable = callable
+-_add_doc(get_unbound_function,
+-         """Get the function out of a possibly unbound function""")
+-
+-
+-get_method_function = operator.attrgetter(_meth_func)
+-get_method_self = operator.attrgetter(_meth_self)
+-get_function_closure = operator.attrgetter(_func_closure)
+-get_function_code = operator.attrgetter(_func_code)
+-get_function_defaults = operator.attrgetter(_func_defaults)
+-get_function_globals = operator.attrgetter(_func_globals)
+-
+-
+-if PY3:
+-    def iterkeys(d, **kw):
+-        return iter(d.keys(**kw))
+-
+-    def itervalues(d, **kw):
+-        return iter(d.values(**kw))
+-
+-    def iteritems(d, **kw):
+-        return iter(d.items(**kw))
+-
+-    def iterlists(d, **kw):
+-        return iter(d.lists(**kw))
+-
+-    viewkeys = operator.methodcaller("keys")
+-
+-    viewvalues = operator.methodcaller("values")
+-
+-    viewitems = operator.methodcaller("items")
+-else:
+-    def iterkeys(d, **kw):
+-        return d.iterkeys(**kw)
+-
+-    def itervalues(d, **kw):
+-        return d.itervalues(**kw)
+-
+-    def iteritems(d, **kw):
+-        return d.iteritems(**kw)
+-
+-    def iterlists(d, **kw):
+-        return d.iterlists(**kw)
+-
+-    viewkeys = operator.methodcaller("viewkeys")
+-
+-    viewvalues = operator.methodcaller("viewvalues")
+-
+-    viewitems = operator.methodcaller("viewitems")
+-
+-_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+-_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+-_add_doc(iteritems,
+-         "Return an iterator over the (key, value) pairs of a dictionary.")
+-_add_doc(iterlists,
+-         "Return an iterator over the (key, [values]) pairs of a dictionary.")
+-
+-
+-if PY3:
+-    def b(s):
+-        return s.encode("latin-1")
+-
+-    def u(s):
+-        return s
+-    unichr = chr
+-    import struct
+-    int2byte = struct.Struct(">B").pack
+-    del struct
+-    byte2int = operator.itemgetter(0)
+-    indexbytes = operator.getitem
+-    iterbytes = iter
+-    import io
+-    StringIO = io.StringIO
+-    BytesIO = io.BytesIO
+-    _assertCountEqual = "assertCountEqual"
+-    if sys.version_info[1] <= 1:
+-        _assertRaisesRegex = "assertRaisesRegexp"
+-        _assertRegex = "assertRegexpMatches"
+-    else:
+-        _assertRaisesRegex = "assertRaisesRegex"
+-        _assertRegex = "assertRegex"
+-else:
+-    def b(s):
+-        return s
+-    # Workaround for standalone backslash
+-
+-    def u(s):
+-        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+-    unichr = unichr
+-    int2byte = chr
+-
+-    def byte2int(bs):
+-        return ord(bs[0])
+-
+-    def indexbytes(buf, i):
+-        return ord(buf[i])
+-    iterbytes = functools.partial(itertools.imap, ord)
+-    import StringIO
+-    StringIO = BytesIO = StringIO.StringIO
+-    _assertCountEqual = "assertItemsEqual"
+-    _assertRaisesRegex = "assertRaisesRegexp"
+-    _assertRegex = "assertRegexpMatches"
+-_add_doc(b, """Byte literal""")
+-_add_doc(u, """Text literal""")
+-
+-
+-def assertCountEqual(self, *args, **kwargs):
+-    return getattr(self, _assertCountEqual)(*args, **kwargs)
+-
+-
+-def assertRaisesRegex(self, *args, **kwargs):
+-    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+-
+-
+-def assertRegex(self, *args, **kwargs):
+-    return getattr(self, _assertRegex)(*args, **kwargs)
+-
+-
+-if PY3:
+-    exec_ = getattr(moves.builtins, "exec")
+-
+-    def reraise(tp, value, tb=None):
+-        if value is None:
+-            value = tp()
+-        if value.__traceback__ is not tb:
+-            raise value.with_traceback(tb)
+-        raise value
+-
+-else:
+-    def exec_(_code_, _globs_=None, _locs_=None):
+-        """Execute code in a namespace."""
+-        if _globs_ is None:
+-            frame = sys._getframe(1)
+-            _globs_ = frame.f_globals
+-            if _locs_ is None:
+-                _locs_ = frame.f_locals
+-            del frame
+-        elif _locs_ is None:
+-            _locs_ = _globs_
+-        exec("""exec _code_ in _globs_, _locs_""")
+-
+-    exec_("""def reraise(tp, value, tb=None):
+-    raise tp, value, tb
+-""")
+-
+-
+-if sys.version_info[:2] == (3, 2):
+-    exec_("""def raise_from(value, from_value):
+-    if from_value is None:
+-        raise value
+-    raise value from from_value
+-""")
+-elif sys.version_info[:2] > (3, 2):
+-    exec_("""def raise_from(value, from_value):
+-    raise value from from_value
+-""")
+-else:
+-    def raise_from(value, from_value):
+-        raise value
+-
+-
+-print_ = getattr(moves.builtins, "print", None)
+-if print_ is None:
+-    def print_(*args, **kwargs):
+-        """The new-style print function for Python 2.4 and 2.5."""
+-        fp = kwargs.pop("file", sys.stdout)
+-        if fp is None:
+-            return
+-
+-        def write(data):
+-            if not isinstance(data, basestring):
+-                data = str(data)
+-            # If the file has an encoding, encode unicode with it.
+-            if (isinstance(fp, file) and
+-                    isinstance(data, unicode) and
+-                    fp.encoding is not None):
+-                errors = getattr(fp, "errors", None)
+-                if errors is None:
+-                    errors = "strict"
+-                data = data.encode(fp.encoding, errors)
+-            fp.write(data)
+-        want_unicode = False
+-        sep = kwargs.pop("sep", None)
+-        if sep is not None:
+-            if isinstance(sep, unicode):
+-                want_unicode = True
+-            elif not isinstance(sep, str):
+-                raise TypeError("sep must be None or a string")
+-        end = kwargs.pop("end", None)
+-        if end is not None:
+-            if isinstance(end, unicode):
+-                want_unicode = True
+-            elif not isinstance(end, str):
+-                raise TypeError("end must be None or a string")
+-        if kwargs:
+-            raise TypeError("invalid keyword arguments to print()")
+-        if not want_unicode:
+-            for arg in args:
+-                if isinstance(arg, unicode):
+-                    want_unicode = True
+-                    break
+-        if want_unicode:
+-            newline = unicode("\n")
+-            space = unicode(" ")
+-        else:
+-            newline = "\n"
+-            space = " "
+-        if sep is None:
+-            sep = space
+-        if end is None:
+-            end = newline
+-        for i, arg in enumerate(args):
+-            if i:
+-                write(sep)
+-            write(arg)
+-        write(end)
+-if sys.version_info[:2] < (3, 3):
+-    _print = print_
+-
+-    def print_(*args, **kwargs):
+-        fp = kwargs.get("file", sys.stdout)
+-        flush = kwargs.pop("flush", False)
+-        _print(*args, **kwargs)
+-        if flush and fp is not None:
+-            fp.flush()
+-
+-_add_doc(reraise, """Reraise an exception.""")
+-
+-if sys.version_info[0:2] < (3, 4):
+-    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+-              updated=functools.WRAPPER_UPDATES):
+-        def wrapper(f):
+-            f = functools.wraps(wrapped, assigned, updated)(f)
+-            f.__wrapped__ = wrapped
+-            return f
+-        return wrapper
+-else:
+-    wraps = functools.wraps
+-
+-
+-def with_metaclass(meta, *bases):
+-    """Create a base class with a metaclass."""
+-    # This requires a bit of explanation: the basic idea is to make a dummy
+-    # metaclass for one level of class instantiation that replaces itself with
+-    # the actual metaclass.
+-    class metaclass(meta):
+-
+-        def __new__(cls, name, this_bases, d):
+-            return meta(name, bases, d)
+-    return type.__new__(metaclass, 'temporary_class', (), {})
+-
+-
+-def add_metaclass(metaclass):
+-    """Class decorator for creating a class with a metaclass."""
+-    def wrapper(cls):
+-        orig_vars = cls.__dict__.copy()
+-        slots = orig_vars.get('__slots__')
+-        if slots is not None:
+-            if isinstance(slots, str):
+-                slots = [slots]
+-            for slots_var in slots:
+-                orig_vars.pop(slots_var)
+-        orig_vars.pop('__dict__', None)
+-        orig_vars.pop('__weakref__', None)
+-        return metaclass(cls.__name__, cls.__bases__, orig_vars)
+-    return wrapper
+-
+-
+-def python_2_unicode_compatible(klass):
+-    """
+-    A decorator that defines __unicode__ and __str__ methods under Python 2.
+-    Under Python 3 it does nothing.
+-
+-    To support Python 2 and 3 with a single code base, define a __str__ method
+-    returning text and apply this decorator to the class.
+-    """
+-    if PY2:
+-        if '__str__' not in klass.__dict__:
+-            raise ValueError("@python_2_unicode_compatible cannot be applied "
+-                             "to %s because it doesn't define __str__()." %
+-                             klass.__name__)
+-        klass.__unicode__ = klass.__str__
+-        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+-    return klass
+-
+-
+-# Complete the moves implementation.
+-# This code is at the end of this module to speed up module loading.
+-# Turn this module into a package.
+-__path__ = []  # required for PEP 302 and PEP 451
+-__package__ = __name__  # see PEP 366 @ReservedAssignment
+-if globals().get("__spec__") is not None:
+-    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+-# Remove other six meta path importers, since they cause problems. This can
+-# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+-# this for some reason.)
+-if sys.meta_path:
+-    for i, importer in enumerate(sys.meta_path):
+-        # Here's some real nastiness: Another "instance" of the six module might
+-        # be floating around. Therefore, we can't use isinstance() to check for
+-        # the six meta path importer, since the other six instance will have
+-        # inserted an importer with different class.
+-        if (type(importer).__name__ == "_SixMetaPathImporter" and
+-                importer.name == __name__):
+-            del sys.meta_path[i]
+-            break
+-    del i, importer
+-# Finally, add the importer to the meta path import hook.
+-sys.meta_path.append(_importer)
+diff --git a/tasks/docs.py b/tasks/docs.py
+index 3360279..77c1d83 100644
+--- a/tasks/docs.py
++++ b/tasks/docs.py
+@@ -11,7 +11,8 @@ from invoke.util import cd
+ from path import Path
+ 
+ # -- TASK-LIBRARY:
+-from ._tasklet_cleanup import cleanup_tasks, cleanup_dirs
++# PREPARED: from invoke_cleanup import cleanup_tasks, cleanup_dirs
++from .invoke_cleanup import cleanup_tasks, cleanup_dirs
+ 
+ 
+ # -----------------------------------------------------------------------------
+@@ -69,6 +70,7 @@ def build(ctx, builder="html", language=None, options=""):
+                             opts=options)
+         ctx.run(command)
+ 
++
+ @task(help={
+     "builder": "Builder to use (html, ...)",
+     "language": "Language to use (en, ...)",
+@@ -81,12 +83,38 @@ def rebuild(ctx, builder="html", language=None, options=""):
+     clean(ctx)
+     build(ctx, builder=builder, language=None, options=options)
+ 
++
++@task(aliases=["auto", "watch"],
++    help={
++        "builder": "Builder to use (html, ...)",
++        "language": "Language to use (en, ...)",
++        "options": "Additional options for sphinx-build",
++})
++def autobuild(ctx, builder="html", language=None, options=""):
++    """Build docs with sphinx-build"""
++    language = _sphinxdoc_get_language(ctx, language)
++    sourcedir = ctx.config.sphinx.sourcedir
++    destdir = _sphinxdoc_get_destdir(ctx, builder, language=language)
++    destdir = destdir.abspath()
++    with cd(sourcedir):
++        destdir_relative = Path(".").relpathto(destdir)
++        command = "sphinx-autobuild {opts} -b {builder} -D language={language} {sourcedir} {destdir}" \
++                    .format(builder=builder, sourcedir=".",
++                            destdir=destdir_relative,
++                            language=language,
++                            opts=options)
++        ctx.run(command)
++
++
+ @task
+ def linkcheck(ctx):
+     """Check if all links are corect."""
+     build(ctx, builder="linkcheck")
+ 
+-@task(help={"language": "Language to use (en, ...)"})
++
++@task(aliases=["open"],
++    help={"language": "Language to use (en, ...)"}
++)
+ def browse(ctx, language=None):
+     """Open documentation in web browser."""
+     output_dir = _sphinxdoc_get_destdir(ctx, "html", language=language)
+@@ -182,6 +210,7 @@ def update_translation(ctx, language="all"):
+ # -----------------------------------------------------------------------------
+ namespace = Collection(clean, rebuild, linkcheck, browse, save, update_translation)
+ namespace.add_task(build, default=True)
++namespace.add_task(autobuild)
+ namespace.configure({
+     "sphinx": {
+         # -- FOR TASKS: docs.build, docs.rebuild, docs.clean, ...
+diff --git a/tasks/invoke_cleanup.py b/tasks/invoke_cleanup.py
+new file mode 100644
+index 0000000..4e631c4
+--- /dev/null
++++ b/tasks/invoke_cleanup.py
+@@ -0,0 +1,447 @@
++# -*- coding: UTF-8 -*-
++"""
++Provides cleanup tasks for invoke build scripts (as generic invoke tasklet).
++Simplifies writing common, composable and extendable cleanup tasks.
++
++PYTHON PACKAGE DEPENDENCIES:
++
++* path (python >= 3.5) or path.py >= 11.5.0 (as path-object abstraction)
++* pathlib (for ant-like wildcard patterns; since: python > 3.5)
++* pycmd (required-by: clean_python())
++
++
++cleanup task: Add Additional Directories and Files to be removed
++-------------------------------------------------------------------------------
++
++Create an invoke configuration file (YAML of JSON) with the additional
++configuration data:
++
++.. code-block:: yaml
++
++    # -- FILE: invoke.yaml
++    # USE: cleanup.directories, cleanup.files to override current configuration.
++    cleanup:
++        # directories: Default directory patterns (can be overwritten).
++        # files:       Default file patterns      (can be ovewritten).
++        extra_directories:
++            - **/tmp/
++        extra_files:
++            - **/*.log
++            - **/*.bak
++
++
++Registration of Cleanup Tasks
++------------------------------
++
++Other task modules often have an own cleanup task to recover the clean state.
++The :meth:`cleanup` task, that is provided here, supports the registration
++of additional cleanup tasks. Therefore, when the :meth:`cleanup` task is executed,
++all registered cleanup tasks will be executed.
++
++EXAMPLE::
++
++    # -- FILE: tasks/docs.py
++    from __future__ import absolute_import
++    from invoke import task, Collection
++    from invoke_cleanup import cleanup_tasks, cleanup_dirs
++
++    @task
++    def clean(ctx):
++        "Cleanup generated documentation artifacts."
++        dry_run = ctx.config.run.dry
++        cleanup_dirs(["build/docs"], dry_run=dry_run)
++
++    namespace = Collection(clean)
++    ...
++
++    # -- REGISTER CLEANUP TASK:
++    cleanup_tasks.add_task(clean, "clean_docs")
++    cleanup_tasks.configure(namespace.configuration())
++"""
++
++from __future__ import absolute_import, print_function
++import os
++import sys
++from invoke import task, Collection
++from invoke.executor import Executor
++from invoke.exceptions import Exit, Failure, UnexpectedExit
++from invoke.util import cd
++from path import Path
++
++# -- PYTHON BACKWARD COMPATIBILITY:
++python_version = sys.version_info[:2]
++python35 = (3, 5)   # HINT: python3.8 does not raise OSErrors.
++if python_version < python35:   # noqa
++    import pathlib2 as pathlib
++else:
++    import pathlib              # noqa
++
++
++# -----------------------------------------------------------------------------
++# CONSTANTS:
++# -----------------------------------------------------------------------------
++VERSION = "0.3.6"
++
++
++# -----------------------------------------------------------------------------
++# CLEANUP UTILITIES:
++# -----------------------------------------------------------------------------
++def execute_cleanup_tasks(ctx, cleanup_tasks, workdir=".", verbose=False):
++    """Execute several cleanup tasks as part of the cleanup.
++
++    :param ctx:             Context object for the tasks.
++    :param cleanup_tasks:   Collection of cleanup tasks (as Collection).
++    """
++    # pylint: disable=redefined-outer-name
++    executor = Executor(cleanup_tasks, ctx.config)
++    failure_count = 0
++    with cd(workdir) as cwd:
++        for cleanup_task in cleanup_tasks.tasks:
++            try:
++                print("CLEANUP TASK: %s" % cleanup_task)
++                executor.execute(cleanup_task)
++            except (Exit, Failure, UnexpectedExit) as e:
++                print(e)
++                print("FAILURE in CLEANUP TASK: %s (GRACEFULLY-IGNORED)" % cleanup_task)
++                failure_count += 1
++
++    if failure_count:
++        print("CLEANUP TASKS: %d failure(s) occured" % failure_count)
++
++
++def make_excluded(excluded, config_dir=None, workdir=None):
++    workdir = workdir or Path.getcwd()
++    config_dir = config_dir or workdir
++    workdir = Path(workdir)
++    config_dir = Path(config_dir)
++
++    excluded2 = []
++    for p in excluded:
++        assert p, "REQUIRE: non-empty"
++        p = Path(p)
++        if p.isabs():
++            excluded2.append(p.normpath())
++        else:
++            # -- RELATIVE PATH:
++            # Described relative to config_dir.
++            # Recompute it relative to current workdir.
++            p = Path(config_dir)/p
++            p = workdir.relpathto(p)
++            excluded2.append(p.normpath())
++            excluded2.append(p.abspath())
++    return set(excluded2)
++
++
++def is_directory_excluded(directory, excluded):
++    directory = Path(directory).normpath()
++    directory2 = directory.abspath()
++    if (directory in excluded) or (directory2 in excluded):
++        return True
++    # -- OTHERWISE:
++    return False
++
++
++def cleanup_dirs(patterns, workdir=".", excluded=None,
++                 dry_run=False, verbose=False, show_skipped=False):
++    """Remove directories (and their contents) recursively.
++    Skips removal if directories does not exist.
++
++    :param patterns:    Directory name patterns, like "**/tmp*" (as list).
++    :param workdir:     Current work directory (default=".")
++    :param dry_run:     Dry-run mode indicator (as bool).
++    """
++    excluded = excluded or []
++    excluded = set([Path(p) for p in excluded])
++    show_skipped = show_skipped or verbose
++    current_dir = Path(workdir)
++    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
++    warn2_counter = 0
++    for dir_pattern in patterns:
++        for directory in path_glob(dir_pattern, current_dir):
++            if is_directory_excluded(directory, excluded):
++                print("SKIP-DIR: %s (excluded)" % directory)
++                continue
++            directory2 = directory.abspath()
++            if sys.executable.startswith(directory2):
++                # -- PROTECT VIRTUAL ENVIRONMENT (currently in use):
++                # pylint: disable=line-too-long
++                print("SKIP-SUICIDE: '%s' contains current python executable" % directory)
++                continue
++            elif directory2.startswith(python_basedir):
++                # -- PROTECT VIRTUAL ENVIRONMENT (currently in use):
++                # HINT: Limit noise in DIAGNOSTIC OUTPUT to X messages.
++                if warn2_counter <= 4:  # noqa
++                    print("SKIP-SUICIDE: '%s'" % directory)
++                warn2_counter += 1
++                continue
++
++            if not directory.isdir():
++                if show_skipped:
++                    print("RMTREE: %s (SKIPPED: Not a directory)" % directory)
++                continue
++
++            if dry_run:
++                print("RMTREE: %s (dry-run)" % directory)
++            else:
++                try:
++                    # -- MAYBE: directory.rmtree(ignore_errors=True)
++                    print("RMTREE: %s" % directory)
++                    directory.rmtree_p()
++                except OSError as e:
++                    print("RMTREE-FAILED: %s (for: %s)" % (e, directory))
++
++
++def cleanup_files(patterns, workdir=".", dry_run=False, verbose=False, show_skipped=False):
++    """Remove files or files selected by file patterns.
++    Skips removal if file does not exist.
++
++    :param patterns:    File patterns, like "**/*.pyc" (as list).
++    :param workdir:     Current work directory (default=".")
++    :param dry_run:     Dry-run mode indicator (as bool).
++    """
++    show_skipped = show_skipped or verbose
++    current_dir = Path(workdir)
++    python_basedir = Path(Path(sys.executable).dirname()).joinpath("..").abspath()
++    error_message = None
++    error_count = 0
++    for file_pattern in patterns:
++        for file_ in path_glob(file_pattern, current_dir):
++            if file_.abspath().startswith(python_basedir):
++                # -- PROTECT VIRTUAL ENVIRONMENT (currently in use):
++                continue
++            if not file_.isfile():
++                if show_skipped:
++                    print("REMOVE: %s (SKIPPED: Not a file)" % file_)
++                continue
++
++            if dry_run:
++                print("REMOVE: %s (dry-run)" % file_)
++            else:
++                print("REMOVE: %s" % file_)
++                try:
++                    file_.remove_p()
++                except os.error as e:
++                    message = "%s: %s" % (e.__class__.__name__, e)
++                    print(message + " basedir: "+ python_basedir)
++                    error_count += 1
++                    if not error_message:
++                        error_message = message
++    if False and error_message: # noqa
++        class CleanupError(RuntimeError):
++            pass
++        raise CleanupError(error_message)
++
++
++def path_glob(pattern, current_dir=None):
++    """Use pathlib for ant-like patterns, like: "**/*.py"
++
++    :param pattern:      File/directory pattern to use (as string).
++    :param current_dir:  Current working directory (as Path, pathlib.Path, str)
++    :return Resolved Path (as path.Path).
++    """
++    if not current_dir: # noqa
++        current_dir = pathlib.Path.cwd()
++    elif not isinstance(current_dir, pathlib.Path):
++        # -- CASE: string, path.Path (string-like)
++        current_dir = pathlib.Path(str(current_dir))
++
++    pattern_path = Path(pattern)
++    if pattern_path.isabs():
++        # -- SPECIAL CASE: Path.glob() only supports relative-path(s) / pattern(s).
++        if pattern_path.isdir():
++            yield pattern_path
++        return
++
++    # -- HINT: OSError is no longer raised in pathlib2 or python35.pathlib
++    # try:
++    for p in current_dir.glob(pattern):
++        yield Path(str(p))
++    # except OSError as e:
++    #     # -- CORNER-CASE 1: x.glob(pattern) may fail with:
++    #     # OSError: [Errno 13] Permission denied: <filename>
++    #     # HINT: Directory lacks excutable permissions for traversal.
++    #     # -- CORNER-CASE 2: symlinked endless loop
++    #     # OSError: [Errno 62] Too many levels of symbolic links: <filename>
++    #     print("{0}: {1}".format(e.__class__.__name__, e))
++
++
++# -----------------------------------------------------------------------------
++# GENERIC CLEANUP TASKS:
++# -----------------------------------------------------------------------------
++@task(help={
++    "workdir": "Directory to clean(up) (default: $CWD).",
++    "verbose": "Enable verbose mode (default: OFF).",
++})
++def clean(ctx, workdir=".", verbose=False):
++    """Cleanup temporary dirs/files to regain a clean state."""
++    dry_run = ctx.config.run.dry
++    config_dir = getattr(ctx.config, "config_dir", workdir)
++    directories = list(ctx.config.cleanup.directories or [])
++    directories.extend(ctx.config.cleanup.extra_directories or [])
++    files = list(ctx.config.cleanup.files or [])
++    files.extend(ctx.config.cleanup.extra_files or [])
++    excluded_directories = list(ctx.config.cleanup.excluded_directories or [])
++    excluded_directories = make_excluded(excluded_directories,
++                                         config_dir=config_dir, workdir=".")
++
++    # -- PERFORM CLEANUP:
++    execute_cleanup_tasks(ctx, cleanup_tasks)
++    cleanup_dirs(directories, workdir=workdir, excluded=excluded_directories,
++                 dry_run=dry_run, verbose=verbose)
++    cleanup_files(files, workdir=workdir, dry_run=dry_run, verbose=verbose)
++
++    # -- CONFIGURABLE EXTENSION-POINT:
++    # use_cleanup_python = ctx.config.cleanup.use_cleanup_python or False
++    # if use_cleanup_python:
++    #     clean_python(ctx)
++
++
++@task(name="all", aliases=("distclean",),
++      help={
++        "workdir": "Directory to clean(up) (default: $CWD).",
++        "verbose": "Enable verbose mode (default: OFF).",
++})
++def clean_all(ctx, workdir=".", verbose=False):
++    """Clean up everything, even the precious stuff.
++    NOTE: clean task is executed last.
++    """
++    dry_run = ctx.config.run.dry
++    config_dir = getattr(ctx.config, "config_dir", workdir)
++    directories = list(ctx.config.cleanup_all.directories or [])
++    directories.extend(ctx.config.cleanup_all.extra_directories or [])
++    files = list(ctx.config.cleanup_all.files or [])
++    files.extend(ctx.config.cleanup_all.extra_files or [])
++    excluded_directories = list(ctx.config.cleanup_all.excluded_directories or [])
++    excluded_directories.extend(ctx.config.cleanup.excluded_directories or [])
++    excluded_directories = make_excluded(excluded_directories,
++                                         config_dir=config_dir, workdir=".")
++
++    # -- PERFORM CLEANUP:
++    # HINT: Remove now directories, files first before cleanup-tasks.
++    cleanup_dirs(directories, workdir=workdir, excluded=excluded_directories,
++                 dry_run=dry_run, verbose=verbose)
++    cleanup_files(files, workdir=workdir, dry_run=dry_run, verbose=verbose)
++    execute_cleanup_tasks(ctx, cleanup_all_tasks)
++    clean(ctx, workdir=workdir, verbose=verbose)
++
++    # -- CONFIGURABLE EXTENSION-POINT:
++    # use_cleanup_python1 = ctx.config.cleanup.use_cleanup_python or False
++    # use_cleanup_python2 = ctx.config.cleanup_all.use_cleanup_python or False
++    # if use_cleanup_python2 and not use_cleanup_python1:
++    #     clean_python(ctx)
++
++
++@task(aliases=["python"])
++def clean_python(ctx, workdir=".", verbose=False):
++    """Cleanup python related files/dirs: *.pyc, *.pyo, ..."""
++    dry_run = ctx.config.run.dry or False
++    # MAYBE NOT: "**/__pycache__"
++    cleanup_dirs(["build", "dist", "*.egg-info", "**/__pycache__"],
++                 workdir=workdir, dry_run=dry_run, verbose=verbose)
++    if not dry_run:
++        ctx.run("py.cleanup")
++    cleanup_files(["**/*.pyc", "**/*.pyo", "**/*$py.class"],
++                  workdir=workdir, dry_run=dry_run, verbose=verbose)
++
++
++@task(help={
++    "path": "Path to cleanup.",
++    "interactive": "Enable interactive mode.",
++    "force": "Enable force mode.",
++    "options": "Additional git-clean options",
++})
++def git_clean(ctx, path=None, interactive=False, force=False,
++              dry_run=False, options=None):
++    """Perform git-clean command to cleanup the worktree of a git repository.
++
++    BEWARE: This may remove any precious files that are not checked in.
++    WARNING: DANGEROUS COMMAND.
++    """
++    args = []
++    force = force or ctx.config.git_clean.force
++    path = path or ctx.config.git_clean.path or "."
++    interactive = interactive or ctx.config.git_clean.interactive
++    dry_run = dry_run or ctx.config.run.dry or ctx.config.git_clean.dry_run
++
++    if interactive:
++        args.append("--interactive")
++    if force:
++        args.append("--force")
++    if dry_run:
++        args.append("--dry-run")
++    args.append(options or "")
++    args = " ".join(args).strip()
++
++    ctx.run("git clean {options} {path}".format(options=args, path=path))
++
++
++# -----------------------------------------------------------------------------
++# TASK CONFIGURATION:
++# -----------------------------------------------------------------------------
++CLEANUP_EMPTY_CONFIG = {
++    "directories": [],
++    "files": [],
++    "extra_directories": [],
++    "extra_files": [],
++    "excluded_directories": [],
++    "excluded_files": [],
++    "use_cleanup_python": False,
++}
++def make_cleanup_config(**kwargs):
++    config_data = CLEANUP_EMPTY_CONFIG.copy()
++    config_data.update(kwargs)
++    return config_data
++
++
++namespace = Collection(clean_all, clean_python)
++namespace.add_task(clean, default=True)
++namespace.add_task(git_clean)
++namespace.configure({
++    "cleanup": make_cleanup_config(
++        files=["**/*.bak", "**/*.log", "**/*.tmp", "**/.DS_Store"],
++        excluded_directories=[".git", ".hg", ".bzr", ".svn"],
++    ),
++    "cleanup_all": make_cleanup_config(
++        directories=[".venv*", ".tox", "downloads", "tmp"],
++    ),
++    "git_clean": {
++        "interactive": True,
++        "force": False,
++        "path": ".",
++        "dry_run": False,
++    },
++})
++
++
++# -- EXTENSION-POINT: CLEANUP TASKS (called by: clean, clean_all task)
++# NOTE: Can be used by other tasklets to register cleanup tasks.
++cleanup_tasks = Collection("cleanup_tasks")
++cleanup_all_tasks = Collection("cleanup_all_tasks")
++
++# -- EXTEND NORMAL CLEANUP-TASKS:
++# DISABLED: cleanup_tasks.add_task(clean_python)
++
++# -----------------------------------------------------------------------------
++# EXTENSION-POINT: CONFIGURATION HELPERS: Can be used from other task modules
++# -----------------------------------------------------------------------------
++def config_add_cleanup_dirs(directories):
++    # pylint: disable=protected-access
++    the_cleanup_directories = namespace._configuration["cleanup"]["directories"]
++    the_cleanup_directories.extend(directories)
++
++def config_add_cleanup_files(files):
++    # pylint: disable=protected-access
++    the_cleanup_files = namespace._configuration["cleanup"]["files"]
++    the_cleanup_files.extend(files)
++    # namespace.configure({"cleanup": {"files": files}})
++    # print("DIAG cleanup.config.cleanup: %r" % namespace.configuration())
++
++def config_add_cleanup_all_dirs(directories):
++    # pylint: disable=protected-access
++    the_cleanup_directories = namespace._configuration["cleanup_all"]["directories"]
++    the_cleanup_directories.extend(directories)
++
++def config_add_cleanup_all_files(files):
++    # pylint: disable=protected-access
++    the_cleanup_files = namespace._configuration["cleanup_all"]["files"]
++    the_cleanup_files.extend(files)
+diff --git a/tasks/py.requirements.txt b/tasks/py.requirements.txt
+index 9c82d11..ac19e94 100644
+--- a/tasks/py.requirements.txt
++++ b/tasks/py.requirements.txt
+@@ -13,8 +13,8 @@ pycmd
+ six==1.15.0
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+-path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
++path.py >= 11.5.0; python_version <  '3.5'
+ 
+ # -- PYTHON2 BACKPORTS:
+ pathlib;    python_version <= '3.4'
+diff --git a/tasks/release.py b/tasks/release.py
+index dba85c8..e17a46f 100644
+--- a/tasks/release.py
++++ b/tasks/release.py
+@@ -51,7 +51,7 @@ Configuration file for pypi repositories:
+ 
+ from __future__ import absolute_import, print_function
+ from invoke import Collection, task
+-from ._tasklet_cleanup import path_glob
++from .invoke_cleanup import path_glob
+ from ._dry_run import DryRunContext
+ 
+ 
+diff --git a/tasks/test.py b/tasks/test.py
+index bfa2d80..d6b4189 100644
+--- a/tasks/test.py
++++ b/tasks/test.py
+@@ -9,7 +9,8 @@ import sys
+ from invoke import task, Collection
+ 
+ # -- TASK-LIBRARY:
+-from ._tasklet_cleanup import cleanup_tasks, cleanup_dirs, cleanup_files
++# PREPARED: from invoke_cleanup import cleanup_tasks, cleanup_dirs, cleanup_files
++from .invoke_cleanup import cleanup_tasks, cleanup_dirs, cleanup_files
+ 
+ 
+ # ---------------------------------------------------------------------------
diff --git a/meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch b/meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch
new file mode 100644
index 000000000..b849cc5e1
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0091-Docs-change-code-blocks-from-bash-to-console.patch
@@ -0,0 +1,36 @@
+From 87f19edd9048494b22d7c18c737c54844b1a8138 Mon Sep 17 00:00:00 2001
+From: Daniel Lemm <61800298+ffe4@users.noreply.github.com>
+Date: Fri, 26 Jun 2020 11:27:10 +0200
+Subject: [PATCH] Docs: change code blocks from bash to console
+
+---
+ README.rst              | 2 +-
+ docs/practical_tips.rst | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/README.rst b/README.rst
+index 4a905ab..22b0352 100644
+--- a/README.rst
++++ b/README.rst
+@@ -76,7 +76,7 @@ In that directory create a file called "example_steps.py" containing:
+ 
+ Run behave:
+ 
+-.. code-block:: bash
++.. code-block:: console
+ 
+     $ behave
+     Feature: Showing off behave # features/example.feature:2
+diff --git a/docs/practical_tips.rst b/docs/practical_tips.rst
+index b70569f..75bc736 100644
+--- a/docs/practical_tips.rst
++++ b/docs/practical_tips.rst
+@@ -30,7 +30,7 @@ For example, if you want to use the feature files in the same directory for
+ testing the model layer and the UI layer, this can be done by using the
+ ``--stage`` option, like with:
+ 
+-.. code-block:: bash
++.. code-block:: console
+ 
+     $ behave --stage=model features/
+     $ behave --stage=ui    features/  # NOTE: Normally used on a subset of features.
diff --git a/meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch b/meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch
new file mode 100644
index 000000000..69a82b784
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0092-Fix-typo-in-tutorial.patch
@@ -0,0 +1,24 @@
+From b8c3a3f553f8f45342f366c98bde08c5d50b98ed Mon Sep 17 00:00:00 2001
+From: Alex McLarty <alexjmclarty@gmail.com>
+Date: Fri, 12 Jul 2019 08:22:31 +0100
+Subject: [PATCH] Fix typo in tutorial
+
+---
+ docs/tutorial.rst | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/docs/tutorial.rst b/docs/tutorial.rst
+index 04b2f63..27698a4 100644
+--- a/docs/tutorial.rst
++++ b/docs/tutorial.rst
+@@ -157,8 +157,8 @@ basic actions. You may use a Scenario Outline to achieve this:
+ 
+   Scenario Outline: Blenders
+      Given I put <thing> in a blender,
+-      when I switch the blender on
+-      then it should transform into <other thing>
++      When I switch the blender on
++      Then it should transform into <other thing>
+ 
+    Examples: Amphibians
+      | thing         | other thing |
diff --git a/meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch b/meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch
new file mode 100644
index 000000000..ef86a84c3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch
@@ -0,0 +1,80 @@
+From de1d5c096cabbbc63e597d1289350c4e33151f14 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 1 Dec 2020 23:19:51 +0100
+Subject: [PATCH] py.requirements: Use PyHamcrest < 2.0 for python2.7
+
+---
+ issue.features/py.requirements.txt | 3 ++-
+ py.requirements/ci.tox.txt         | 6 ++++--
+ py.requirements/ci.travis.txt      | 7 +++++--
+ py.requirements/testing.txt        | 6 ++++--
+ 4 files changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/issue.features/py.requirements.txt b/issue.features/py.requirements.txt
+index 6e3cf83..f8a2f8d 100644
+--- a/issue.features/py.requirements.txt
++++ b/issue.features/py.requirements.txt
+@@ -8,4 +8,5 @@
+ #
+ # ============================================================================
+ 
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 20ae791..5bee524 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -4,9 +4,11 @@
+ 
+ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+-pytest-html >= 1.19.0
++
++pytest-html >= 1.19.0,<2.0
+ mock >= 2.0
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index c69445c..372116a 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -1,11 +1,14 @@
+ # ============================================================================
+ # PYTHON PACKAGE REQUIREMENTS FOR: behave -- ci.travis.txt
+ # ============================================================================
++
+ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+-pytest-html >= 1.19.0
++
++pytest-html >= 1.19.0,<2.0
+ mock  >= 2.0
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index d3bca18..fc8fd82 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -6,9 +6,11 @@
+ # PREPARED-FUTURE: behave4cmd0, behave4cmd
+ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+-pytest-html >= 1.19.0
++
++pytest-html >= 1.19.0,<2.0
+ mock  >= 2.0
+-PyHamcrest == 2.0.2
++PyHamcrest >= 2.0.2; python_version >= '3.0'
++PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+ # -- NEEDED: By some tests (as proof of concept)
+ # NOTE: path.py-10.1 is required for python2.6
diff --git a/meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch b/meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch
new file mode 100644
index 000000000..d20deff2e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0094-UPDATE-PR-877-was-merged.patch
@@ -0,0 +1,21 @@
+From bce68e9ff14ebf7ee69ad7e75bf5f13ab475c462 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 5 Dec 2020 00:33:22 +0100
+Subject: [PATCH] UPDATE: PR #877 was merged.
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index d758364..4e20bb8 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -58,6 +58,7 @@ MINOR:
+ 
+ DOCUMENTATION:
+ 
++* pull  #877: docs: API reference - Capitalizing Step Keywords in example (provided by: Ibrian93)
+ * pull  #731: Update links to Django docs (provided by: bittner)
+ * pull  #722: DOC remove remaining pythonhosted links (provided by: leszekhanusz)
+ * pull  #701: behave/runner.py docstrings (provided by: spitGlued)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch b/meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch
new file mode 100644
index 000000000..fcf7651d4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0095-capitalizing-steps.patch
@@ -0,0 +1,28 @@
+From da598db70063a591e065857cf5135070f6d85704 Mon Sep 17 00:00:00 2001
+From: Brian Icochea <ibrian93@gmail.com>
+Date: Sun, 15 Nov 2020 18:35:16 +0100
+Subject: [PATCH] capitalizing steps
+
+---
+ docs/api.rst | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/docs/api.rst b/docs/api.rst
+index 4763ad6..7463863 100644
+--- a/docs/api.rst
++++ b/docs/api.rst
+@@ -74,10 +74,10 @@ the name of their preceding keyword, so given the following feature file:
+ .. code-block:: gherkin
+ 
+     Given some known state
+-      and some other known state
+-     when some action is taken
+-     then some outcome is observed
+-      but some other outcome is not observed.
++      And some other known state
++     When some action is taken
++     Then some outcome is observed
++      But some other outcome is not observed.
+ 
+ the first "and" step will be renamed internally to "given" and *behave*
+ will look for a step implementation decorated with either "given" or "step":
diff --git a/meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch b/meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch
new file mode 100644
index 000000000..05220be2f
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch
@@ -0,0 +1,56 @@
+From cdaa39ca2ac2ef603e94f26da575fa8dca160865 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Fri, 11 Dec 2020 20:51:44 +0100
+Subject: [PATCH] FIX: invoke-task develop.update-gherkin that aborted after
+ diff
+
+* Show now if "gherkin-languages.json" does not change
+* Add --verbose option to show diff output if file has changed
+---
+ tasks/develop.py | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/tasks/develop.py b/tasks/develop.py
+index 9a21363..eb5fedd 100644
+--- a/tasks/develop.py
++++ b/tasks/develop.py
+@@ -9,6 +9,7 @@ from invoke.util import cd
+ from path import Path
+ import requests
+ 
++
+ # -----------------------------------------------------------------------------
+ # CONSTANTS:
+ # -----------------------------------------------------------------------------
+@@ -18,8 +19,8 @@ GHERKIN_LANGUAGES_URL = "https://raw.githubusercontent.com/cucumber/cucumber/mas
+ # -----------------------------------------------------------------------------
+ # TASKS:
+ # -----------------------------------------------------------------------------
+-@task
+-def update_gherkin(ctx, dry_run=False):
++@task(aliases=["update-languages"])
++def update_gherkin(ctx, dry_run=False, verbose=False):
+     """Update "gherkin-languages.json" file from cucumber-repo.
+ 
+     * Download "gherkin-languages.json" from cucumber repo
+@@ -41,8 +42,18 @@ def update_gherkin(ctx, dry_run=False):
+ 
+         print('Generating "i18n.py" ...')
+         ctx.run("./convert_gherkin-languages.py")
+-        ctx.run("diff i18n.py ../../behave/i18n.py")
+-        if not dry_run:
++
++        # -- DIFF: Returns normally w/ non-zero exitcode => NEEDS: warn=True
++        languages_have_changed = False
++        result = ctx.run("diff i18n.py ../../behave/i18n.py", warn=True, hide=True)
++        languages_have_changed = not result.ok
++        if verbose and languages_have_changed:
++            # -- SHOW DIFF:
++            print(result.stdout)
++
++        if not languages_have_changed:
++            print("NO_CHANGED: gherkin-languages.json")
++        elif not dry_run:
+             print("Updating behave/i18n.py ...")
+             Path("i18n.py").move("../../behave/i18n.py")
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch b/meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch
new file mode 100644
index 000000000..829eea2e4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0097-Test-against-PowerPC-CPU-support-Travis-867.patch
@@ -0,0 +1,22 @@
+From 6f9f088271161adf4ce7a4bdc840b16ddd95b39e Mon Sep 17 00:00:00 2001
+From: santosh653 <70637961+santosh653@users.noreply.github.com>
+Date: Mon, 14 Dec 2020 12:05:50 -0500
+Subject: [PATCH] Test against PowerPC CPU support (Travis) (#867)
+
+Run test suite against both AMD and PowerPC architecture
+---
+ .travis.yml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/.travis.yml b/.travis.yml
+index 781a610..2b78d97 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -1,3 +1,7 @@
++arch: 
++  - amd64
++  - ppc64le
++  
+ language: python
+ sudo: false
+ dist: xenial   # required for Python >= 3.7
diff --git a/meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch b/meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch
new file mode 100644
index 000000000..ac0197202
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0098-Add-Context.attach-docs-and-test.patch
@@ -0,0 +1,132 @@
+From e1be95bbc0080eacb20bc5b263a838784c2a1ea2 Mon Sep 17 00:00:00 2001
+From: Korijn van Golen <k.vangolen@clinicalgraphics.com>
+Date: Sat, 28 Nov 2020 11:39:28 +0100
+Subject: [PATCH] Add Context.attach, docs and test
+
+---
+ behave/formatter/json.py        |  6 +++--
+ behave/runner.py                | 11 +++++++++
+ docs/formatters.rst             | 18 ++++++++++++++
+ features/formatter.json.feature | 42 +++++++++++++++++++++++++++++++++
+ 4 files changed, 75 insertions(+), 2 deletions(-)
+
+diff --git a/behave/formatter/json.py b/behave/formatter/json.py
+index 6da0d59..edfe3d7 100644
+--- a/behave/formatter/json.py
++++ b/behave/formatter/json.py
+@@ -168,10 +168,12 @@ class JSONFormatter(Formatter):
+         self._step_index += 1
+ 
+     def embedding(self, mime_type, data):
+-        step = self.current_feature_element["steps"][-1]
++        step = self.current_feature_element["steps"][self._step_index]
++        if "embeddings" not in step:
++            step["embeddings"] = []
+         step["embeddings"].append({
+             "mime_type": mime_type,
+-            "data": base64.b64encode(data).replace("\n", ""),
++            "data": base64.b64encode(data).decode(self.stream.encoding or "utf-8"),
+         })
+ 
+     def eof(self):
+diff --git a/behave/runner.py b/behave/runner.py
+index d01bff0..c583caf 100644
+--- a/behave/runner.py
++++ b/behave/runner.py
+@@ -475,6 +475,17 @@ class Context(object):
+             # -- AVOID DUPLICATES:
+             current_frame["@cleanups"].append(internal_cleanup_func)
+ 
++    def attach(self, mime_type, data):
++        """Embeds data (e.g. a screenshot) in reports for all
++        formatters that support it, such as the JSON formatter.
++
++        :param mime_type:       MIME type of the binary data.
++        :param data:            Bytes-like object to embed.
++        """
++        is_compatible = lambda f: hasattr(f, "embedding")
++        for formatter in filter(is_compatible, self._runner.formatters):
++            formatter.embedding(mime_type, data)
++
+ 
+ @contextlib.contextmanager
+ def use_context_with_mode(context, mode):
+diff --git a/docs/formatters.rst b/docs/formatters.rst
+index a40fd8d..534468a 100644
+--- a/docs/formatters.rst
++++ b/docs/formatters.rst
+@@ -116,3 +116,21 @@ teamcity       :pypi:`behave-teamcity`, a formatter for Jetbrains TeamCity CI te
+     [behave.formatters]
+     allure   = allure_behave.formatter:AllureFormatter
+     teamcity = behave_teamcity:TeamcityFormatter
++
++
++Embedding data (e.g. screenshots) in reports
++------------------------------------------------------------------------------
++
++You can embed data in reports with the :class:`~behave.runner.Context` method
++:func:`~behave.runner.Context.attach`, if you have configured a formatter that
++supports it. Currently only the JSON formatter supports embedding data.
++
++For example:
++
++.. code-block:: python
++
++    @when(u'I open the Google webpage')
++    def step_impl(context):
++        context.browser.get('http://www.google.com')
++        img = context.browser.get_full_page_screenshot_as_png()
++        context.attach("image/png", img)
+diff --git a/features/formatter.json.feature b/features/formatter.json.feature
+index 96b28c7..67c97ae 100644
+--- a/features/formatter.json.feature
++++ b/features/formatter.json.feature
+@@ -309,6 +309,48 @@ Feature: JSON Formatter
+       But note that "both matched arguments.values are provided as string"
+ 
+ 
++    Scenario: Use JSON formatter and embed binary data in report from two steps
++      Given a file named "features/json_embeddings.feature" with:
++          """
++          Feature:
++            Scenario: Use embeddings
++                Given "foobar" as plain text
++                And "red" as plain text
++          """
++      And a file named "features/steps/json_embeddings_steps.py" with:
++          """
++          from behave import step
++
++          @step('"{data}" as plain text')
++          def step_string(context, data):
++              context.attach("text/plain", data.encode("utf-8"))
++          """
++      When I run "behave -f json.pretty features/json_embeddings.feature"
++      Then it should pass with:
++          """
++          1 feature passed, 0 failed, 0 skipped
++          1 scenario passed, 0 failed, 0 skipped
++          """
++      And the command output should contain:
++          """
++                    "embeddings": [
++                      {
++                        "data": "Zm9vYmFy",
++                        "mime_type": "text/plain"
++                      }
++                    ],
++          """
++      And the command output should contain:
++          """
++                    "embeddings": [
++                      {
++                        "data": "cmVk",
++                        "mime_type": "text/plain"
++                      }
++                    ],
++          """
++
++
+     @xfail
+     @regression_problem.with_duration
+     Scenario: Use JSON formatter with feature and one scenario with steps
diff --git a/meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch b/meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch
new file mode 100644
index 000000000..63b4e7ce5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0099-Add-Contributing-chapter.patch
@@ -0,0 +1,125 @@
+From 5838eafe65cf0ebcda3d192318015326a8afb52a Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Sat, 12 Dec 2020 19:45:26 +0100
+Subject: [PATCH] Add Contributing chapter
+
+---
+ docs/conf.py          |  2 +-
+ docs/contributing.rst | 82 +++++++++++++++++++++++++++++++++++++++++++
+ docs/index.rst        |  1 +
+ 3 files changed, 84 insertions(+), 1 deletion(-)
+ create mode 100644 docs/contributing.rst
+
+diff --git a/docs/conf.py b/docs/conf.py
+index e55fb21..1579a36 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -108,7 +108,7 @@ if USE_SPHINX_INTERNATIONAL:
+ # -----------------------------------------------------------------------------
+ project = u"behave"
+ authors = u"Jens Engel, Benno Rice and Richard Jones"
+-copyright = u"2012-2019, %s" % authors
++copyright = u"2012-2020, %s" % authors
+ 
+ # The version info for the project you're documenting, acts as replacement for
+ # |version| and |release|, also used in various other places throughout the
+diff --git a/docs/contributing.rst b/docs/contributing.rst
+new file mode 100644
+index 0000000..78f36bd
+--- /dev/null
++++ b/docs/contributing.rst
+@@ -0,0 +1,82 @@
++Contributing
++============
++
++If you find a bug you can fix or want to contribute an enhancement you're
++welcome to `open an issue`_ on GitHub or create a `pull request`_ directly.
++
++.. _open an issue: https://github.com/behave/behave/issues
++.. _pull request: https://github.com/behave/behave/pulls
++
++Using ``invoke`` for Development
++--------------------------------
++
++For most development tasks we have `invoke`_ commands.
++
++Install all requirements for running tasks using Pip, e.g.
++
++.. code-block:: console
++
++    python3 -m pip install -r tasks/py.requirements.txt
++
++Display all available ``invoke`` commands like this:
++
++.. code-block:: console
++
++    invoke -l
++
++If you're curious, all ``invoke`` tasks are located in the ``tasks/``
++folder.
++
++.. _invoke: https://www.pyinvoke.org/
++
++Update Gherkin Language Specification
++-------------------------------------
++
++An ``invoke`` command will download the latest Gherkin language
++specification and update the `behave/i18n.py`_ module:
++
++.. code-block:: console
++
++    invoke develop.update-gherkin
++
++If there were changes this command will have updated two files:
++
++#. ``etc/gherkin/gherkin-languages.json`` (original Cucumber JSON spec)
++#. ``behave/i18n.py`` (Python module generated from the JSON spec)
++
++Put both under version control and open a PR to merge them.
++
++.. _behave/i18n.py:
++    https://github.com/behave/behave/blob/master/behave/i18n.py
++
++Update Documentation
++--------------------
++
++Our documentation is written in `reStructuredText`_, and built and hosted
++on `ReadTheDocs`_. Make your changes to the files in the ``docs/`` folder
++and build the documentation with:
++
++.. code-block:: console
++
++    invoke docs
++
++or, alternatively, using Tox:
++
++.. code-block:: console
++
++    tox -e docs
++
++.. hint::
++
++    Building the docs requires Sphinx and DocUtils. If your build fails
++    because those are missing, run:
++
++        python3 -m pip install -r py.requirements/docs.txt
++
++Once the docs are built successfully, ``sphinx`` will tell you where it
++generated the HTML output (typically ``build/docs/html``), which you can
++then inspect locally.
++
++.. _reStructuredText:
++    https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
++.. _ReadTheDocs: https://readthedocs.org/
+diff --git a/docs/index.rst b/docs/index.rst
+index f0dd20e..e00079c 100644
+--- a/docs/index.rst
++++ b/docs/index.rst
+@@ -43,6 +43,7 @@ Contents
+    comparison
+    new_and_noteworthy
+    more_info
++   contributing
+    appendix
+ 
+ .. seealso::
diff --git a/meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch b/meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch
new file mode 100644
index 000000000..4dd3996a3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0100-Adapt-Tox-target-for-building-the-docs.patch
@@ -0,0 +1,34 @@
+From 25c2601d1d8d8836c9673dcbbf852515297e926a Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Sat, 12 Dec 2020 19:46:29 +0100
+Subject: [PATCH] Adapt Tox target for building the docs
+
+This will generate the HTML docs in the same location as `invoke docs`.
+---
+ tox.ini | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/tox.ini b/tox.ini
+index b825921..8ccb58b 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -77,12 +77,9 @@ setenv =
+ 
+ 
+ [testenv:docs]
+-basepython= python2
+ changedir = docs
+-commands=
+-    sphinx-build -W -b html -D language=en -d {envtmpdir}/doctrees . {envtmpdir}/html/en
+-deps=
+-    -r{toxinidir}/py.requirements/docs.txt
++commands = sphinx-build -W -b html -D language=en -d {toxinidir}/build/docs/doctrees . {toxinidir}/build/docs/html/en
++deps = -r{toxinidir}/py.requirements/docs.txt
+ 
+ 
+ [testenv:cleanroom2]
+@@ -146,4 +143,3 @@ commands=
+ deps=
+     jit
+     {[testenv]deps}
+-
diff --git a/meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch b/meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch
new file mode 100644
index 000000000..048e927bf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0101-Mention-HTML-formatter-in-documentation.patch
@@ -0,0 +1,83 @@
+From 3bfc68099983191d1bc095d9ff4491fff41157eb Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Tue, 15 Dec 2020 11:30:17 +0100
+Subject: [PATCH] Mention HTML formatter in documentation
+
+---
+ docs/formatters.rst | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/docs/formatters.rst b/docs/formatters.rst
+index 534468a..6080fc4 100644
+--- a/docs/formatters.rst
++++ b/docs/formatters.rst
+@@ -1,8 +1,8 @@
+ .. _id.appendix.formatters:
+ 
+-==============================================================================
++========================
+ Formatters and Reporters
+-==============================================================================
++========================
+ 
+ :pypi:`behave` provides 2 different concepts for reporting results of a test run:
+ 
+@@ -15,7 +15,7 @@ The ``Reporter`` has a more coarse-grained API.
+ 
+ 
+ Reporters
+-------------------------------------------------------------------------------
++---------
+ 
+ The following reporters are currently supported:
+ 
+@@ -28,7 +28,7 @@ summary         Provides a summary of the test run.
+ 
+ 
+ Formatters
+-------------------------------------------------------------------------------
++----------
+ 
+ The following formatters are currently supported:
+ 
+@@ -62,7 +62,7 @@ tags.location  dry-run  Shows tags and the location where they are used.
+ 
+ 
+ User-Defined Formatters
+-------------------------------------------------------------------------------
++-----------------------
+ 
+ Behave allows you to provide your own formatter (class)::
+ 
+@@ -96,16 +96,16 @@ to provide them. The formatter should use the attribute schema:
+ 
+ 
+ More Formatters
+-------------------------------------------------------------------------------
++---------------
+ 
+-The following formatters are currently known:
++The following contributed formatters are currently known:
+ 
+ ============== =========================================================================
+ Name           Description
+ ============== =========================================================================
+-allure         :pypi:`allure-behave`, an Allure formatter for behave:
+-               ``allure_behave.formatter:AllureFormatter``
+-teamcity       :pypi:`behave-teamcity`, a formatter for Jetbrains TeamCity CI testruns
++allure         :pypi:`allure-behave`, an Allure formatter for behave.
++html           :pypi:`behave-html-formatter`, a simple HTML formatter for behave.
++teamcity       :pypi:`behave-teamcity`, a formatter for JetBrains TeamCity CI testruns
+                with behave.
+ ============== =========================================================================
+ 
+@@ -114,7 +114,8 @@ teamcity       :pypi:`behave-teamcity`, a formatter for Jetbrains TeamCity CI te
+     # -- FILE: behave.ini
+     # FORMATTER ALIASES: behave -f allure ...
+     [behave.formatters]
+-    allure   = allure_behave.formatter:AllureFormatter
++    allure = allure_behave.formatter:AllureFormatter
++    html = behave_html_formatter:HTMLFormatter
+     teamcity = behave_teamcity:TeamcityFormatter
+ 
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch b/meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch
new file mode 100644
index 000000000..6b09b9360
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0102-Use-console-highlighting-for-pip-install-docs.patch
@@ -0,0 +1,22 @@
+From 709c32be819afbbb7c7aecc392fac4986e9ae90f Mon Sep 17 00:00:00 2001
+From: Peter Bittner <django@bittner.it>
+Date: Tue, 15 Dec 2020 12:44:52 +0100
+Subject: [PATCH] Use console highlighting for `pip install` (docs)
+
+---
+ docs/contributing.rst | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/docs/contributing.rst b/docs/contributing.rst
+index 78f36bd..f3deb87 100644
+--- a/docs/contributing.rst
++++ b/docs/contributing.rst
+@@ -71,6 +71,8 @@ or, alternatively, using Tox:
+     Building the docs requires Sphinx and DocUtils. If your build fails
+     because those are missing, run:
+ 
++    .. code-block:: console
++
+         python3 -m pip install -r py.requirements/docs.txt
+ 
+ Once the docs are built successfully, ``sphinx`` will tell you where it
diff --git a/meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch b/meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch
new file mode 100644
index 000000000..f216c29a7
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0103-docs-fix-simple-typo-tuorial-tutorial.patch
@@ -0,0 +1,52 @@
+From 7a122510a7d4843b5f8c64c0a34a807757184a26 Mon Sep 17 00:00:00 2001
+From: Tim Gates <tim.gates@iress.com>
+Date: Sun, 27 Dec 2020 08:16:16 +1100
+Subject: [PATCH] docs: fix simple typo, tuorial -> tutorial
+
+There is a small typo in docs/more_info.rst.
+
+Should read `tutorial` rather than `tuorial`.
+---
+ docs/more_info.rst | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/docs/more_info.rst b/docs/more_info.rst
+index d0b9fcd..0d87a9c 100644
+--- a/docs/more_info.rst
++++ b/docs/more_info.rst
+@@ -66,7 +66,7 @@ Presentation Videos
+ * Benno Rice: `Making Your Application Behave`_ (30min),
+   2012-08-12, PyCon Australia.
+ 
+-* Selenium: `First behave python tuorial with selenium`_ (8min), 2015-01-28,
++* Selenium: `First behave python tutorial with selenium`_ (8min), 2015-01-28,
+   http://www.seleniumframework.com/python-basic/first-behave-gherkin/
+ 
+ * Jessica Ingrasselino: `Automation with Python and Behave`_ (67min), 2015-12-16
+@@ -84,7 +84,7 @@ Presentation Videos
+         * Benno Rice: `Making Your Application Behave`_ (30min),
+           PyCon Australia, 2012-08-12
+ 
+-        * Selenium: `First behave python tuorial with selenium`_ (8min), 2015-01-28,
++        * Selenium: `First behave python tutorial with selenium`_ (8min), 2015-01-28,
+           http://www.seleniumframework.com/python-basic/first-behave-gherkin/
+ 
+         * Jessica Ingrasselino: `Automation with Python and Behave`_ (67min), 2015-12-16
+@@ -112,7 +112,7 @@ Presentation Videos
+             :width: 600
+             :height: 400
+ 
+-        Selenium: `First behave python tuorial with selenium`_
++        Selenium: `First behave python tutorial with selenium`_
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 
+         :Date: 2015-01-28
+@@ -146,7 +146,7 @@ Presentation Videos
+ 
+ 
+ .. _`Making Your Application Behave`: https://www.youtube.com/watch?v=u8BOKuNkmhg
+-.. _`First behave python tuorial with selenium`: https://www.youtube.com/watch?v=D24_QrGUCFk
++.. _`First behave python tutorial with selenium`: https://www.youtube.com/watch?v=D24_QrGUCFk
+ .. _`Automation with Python and Behave`: https://www.youtube.com/watch?v=e78c7h6DRDQ
+ .. _`Selenium Python Webdriver Tutorial - Behave (BDD)`: https://www.youtube.com/watch?v=mextSo0UExc
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch b/meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch
new file mode 100644
index 000000000..dcdbc4cf3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0104-Add-support-for-python3.9-by-using-active-tags.patch
@@ -0,0 +1,227 @@
+From 5c6fd7eaeba958759ccedaaa483fe213859cfa6d Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 12 Oct 2020 21:52:25 +0200
+Subject: [PATCH] Add support for python3.9 (by using active-tags).
+
+---
+ features/step.async_steps.feature | 21 +++++++++++++++++++++
+ issue.features/issue0330.feature  |  6 ++++++
+ issue.features/issue0446.feature  |  4 ++++
+ issue.features/issue0457.feature  |  5 +++++
+ issue.features/issue0657.feature  |  3 +++
+ 5 files changed, 39 insertions(+)
+
+diff --git a/features/step.async_steps.feature b/features/step.async_steps.feature
+index 3a18fa9..06709d9 100644
+--- a/features/step.async_steps.feature
++++ b/features/step.async_steps.feature
+@@ -32,6 +32,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use async-step with @async_run_until_complete (async)
+       Given a new working directory
+       And a file named "features/steps/async_steps35.py" with:
+@@ -63,6 +66,9 @@ Feature: Async-Test Support (async-step, ...)
+     @use.with_python.version=3.4
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use async-step with @async_run_until_complete (@coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps34.py" with:
+@@ -93,6 +99,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (async)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout35.py" with:
+@@ -128,6 +137,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     @async_step_fails
+     Scenario: Use @async_run_until_complete and async-step fails
+       Given a new working directory
+@@ -170,6 +182,9 @@ Feature: Async-Test Support (async-step, ...)
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     @async_step_fails
+     Scenario: Use @async_run_until_complete and async-step raises error
+       Given a new working directory
+@@ -213,6 +228,9 @@ Feature: Async-Test Support (async-step, ...)
+     @use.with_python.version=3.4
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (@coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout34.py" with:
+@@ -250,6 +268,9 @@ Feature: Async-Test Support (async-step, ...)
+     @use.with_python.version=3.4
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use async-dispatch and async-collect concepts
+       Given a new working directory
+       And a file named "features/steps/async_dispatch_steps.py" with:
+diff --git a/issue.features/issue0330.feature b/issue.features/issue0330.feature
+index 81cb6e2..be4d378 100644
+--- a/issue.features/issue0330.feature
++++ b/issue.features/issue0330.feature
+@@ -71,6 +71,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+ 
+   @not.with_python.version=3.8
++  @not.with_python.version=3.9
+   Scenario: Junit report for skipped feature is created with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+@@ -85,6 +86,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       """
+ 
+   @use.with_python.version=3.8
++  @use.with_python.version=3.9
+   Scenario: Junit report for skipped feature is created with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+@@ -101,6 +103,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+       # <testsuite errors="0" failures="0" name="bob.Bob" skipped="1" tests="1" time="0.0">
+ 
+   @not.with_python.version=3.8
++  @not.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+@@ -121,6 +124,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+     And note that "Charly2 is the skipped scenarion in charly.feature"
+ 
+   @use.with_python.version=3.8
++  @use.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+@@ -144,6 +148,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+ 
+   @not.with_python.version=3.8
++  @not.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+@@ -165,6 +170,7 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+ 
+   @use.with_python.version=3.8
++  @use.with_python.version=3.9
+   Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+diff --git a/issue.features/issue0446.feature b/issue.features/issue0446.feature
+index 901bdec..12de37a 100644
+--- a/issue.features/issue0446.feature
++++ b/issue.features/issue0446.feature
+@@ -59,6 +59,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+         """
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Hook error in before_scenario()
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+@@ -88,6 +89,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+ 
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Hook error in before_scenario()
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+@@ -121,6 +123,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Hook error in after_scenario()
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+@@ -152,6 +155,7 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+ 
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Hook error in after_scenario()
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+diff --git a/issue.features/issue0457.feature b/issue.features/issue0457.feature
+index 46f96e9..6d2f48f 100644
+--- a/issue.features/issue0457.feature
++++ b/issue.features/issue0457.feature
+@@ -25,6 +25,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Use failing assertation in a JUnit XML report
+       Given a file named "features/fails1.feature" with:
+         """
+@@ -46,6 +47,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         """
+ 
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use failing assertation in a JUnit XML report
+       Given a file named "features/fails1.feature" with:
+         """
+@@ -70,6 +72,7 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+ 
+     @not.with_python.version=3.8
++    @not.with_python.version=3.9
+     Scenario: Use exception in a JUnit XML report
+       Given a file named "features/fails2.feature" with:
+         """
+@@ -90,7 +93,9 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+         <error message="My name is &quot;Bob&quot; and &lt;here&gt; I am"
+         """
+ 
++
+     @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     Scenario: Use exception in a JUnit XML report
+       Given a file named "features/fails2.feature" with:
+         """
+diff --git a/issue.features/issue0657.feature b/issue.features/issue0657.feature
+index f667893..aeaefd2 100644
+--- a/issue.features/issue0657.feature
++++ b/issue.features/issue0657.feature
+@@ -5,6 +5,9 @@ Feature: Issue #657 -- Allow async steps with timeouts to fail when they raise e
+ 
+     @use.with_python.version=3.5
+     @use.with_python.version=3.6
++    @use.with_python.version=3.7
++    @use.with_python.version=3.8
++    @use.with_python.version=3.9
+     @async_step_fails
+     Scenario: Use @async_run_until_complete and async-step fails
+       Given a new working directory
diff --git a/meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch b/meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch
new file mode 100644
index 000000000..27c77b7b5
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0105-PREFER-python3-from-now-on.patch
@@ -0,0 +1,19 @@
+From 1ff8338ea1d8a27a5c45492507ed64154cc2cfc7 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 12 Oct 2020 22:14:59 +0200
+Subject: [PATCH] PREFER: python3 from now on.
+
+---
+ bin/behave | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bin/behave b/bin/behave
+index c02e8d3..9ebb584 100755
+--- a/bin/behave
++++ b/bin/behave
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/env python3
+ # -*- coding: utf-8 -*-
+ 
+ from __future__ import absolute_import
diff --git a/meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch b/meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch
new file mode 100644
index 000000000..cbbfe6d6b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0106-REMOVE-invoke-scripts.patch
@@ -0,0 +1,41 @@
+From c947c0726673bcb8d8d3114d0e39fc926040559e Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 21:52:04 +0100
+Subject: [PATCH] REMOVE: invoke scripts
+
+---
+ bin/invoke     | 8 --------
+ bin/invoke.cmd | 9 ---------
+ 2 files changed, 17 deletions(-)
+ delete mode 100755 bin/invoke
+ delete mode 100644 bin/invoke.cmd
+
+diff --git a/bin/invoke b/bin/invoke
+deleted file mode 100755
+index e9800e8..0000000
+--- a/bin/invoke
++++ /dev/null
+@@ -1,8 +0,0 @@
+-#!/bin/sh
+-#!/bin/bash
+-# RUN INVOKE: From bundled ZIP file.
+-
+-HERE=$(dirname $0)
+-export INVOKE_TASKS_USE_VENDOR_BUNDLES="yes"
+-
+-python ${HERE}/../tasks/_vendor/invoke.zip $*
+diff --git a/bin/invoke.cmd b/bin/invoke.cmd
+deleted file mode 100644
+index 9303432..0000000
+--- a/bin/invoke.cmd
++++ /dev/null
+@@ -1,9 +0,0 @@
+-@echo off
+-REM RUN INVOKE: From bundled ZIP file.
+-
+-setlocal
+-set HERE=%~dp0
+-set INVOKE_TASKS_USE_VENDOR_BUNDLES="yes"
+-if not defined PYTHON   set PYTHON=python
+-
+-%PYTHON% %HERE%../tasks/_vendor/invoke.zip "%*"
diff --git a/meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch b/meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch
new file mode 100644
index 000000000..e4cb51acf
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0107-FIX-Deprecated-warnings-for-Python-3.x.patch
@@ -0,0 +1,124 @@
+From 3fb11ef19d2265b6e29fc69191079b32c79225dd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 21:52:42 +0100
+Subject: [PATCH] FIX: Deprecated warnings for Python 3.x
+
+---
+ bin/json.format.py         | 15 ++++++++++-----
+ bin/jsonschema_validate.py | 23 ++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 12 deletions(-)
+
+diff --git a/bin/json.format.py b/bin/json.format.py
+index b7eb05f..b75d88a 100755
+--- a/bin/json.format.py
++++ b/bin/json.format.py
+@@ -10,8 +10,8 @@ LICENSE:  BSD
+ from __future__ import absolute_import
+ 
+ __author__    = "Jens Engel"
+-__copyright__ = "(c) 2011-2013 by Jens Engel"
+-VERSION = "0.2.2"
++__copyright__ = "(c) 2011-2021 by Jens Engel"
++VERSION = "0.3.0"
+ 
+ # -- IMPORTS:
+ import os.path
+@@ -29,6 +29,7 @@ except ImportError:
+ # CONSTANTS:
+ # ----------------------------------------------------------------------------
+ DEFAULT_INDENT_SIZE = 2
++PYTHON_VERSION = sys.version_info[:2]
+ 
+ # ----------------------------------------------------------------------------
+ # FUNCTIONS:
+@@ -58,7 +59,11 @@ def json_format(filename, indent=DEFAULT_INDENT_SIZE, **kwargs):
+ #        return 0
+ 
+     contents = open(filename, "r").read()
+-    data      = json.loads(contents, encoding=encoding)
++    if PYTHON_VERSION >= (3, 1):
++        # -- NOTE: encoding keyword is deprecated since python 3.1
++        data = json.loads(contents)
++    else:
++        data = json.loads(contents, encoding=encoding)
+     contents2 = json.dumps(data, indent=indent, sort_keys=sort_keys)
+     contents2 = contents2.strip()
+     contents2 = "%s\n" % contents2
+@@ -69,7 +74,7 @@ def json_format(filename, indent=DEFAULT_INDENT_SIZE, **kwargs):
+         outfile = open(filename, "w")
+         outfile.write(contents2)
+         outfile.close()
+-        console.warn("%s OK", message)
++        console.warning("%s OK", message)
+         return 1 #< OK
+ 
+ def json_formatall(filenames, indent=DEFAULT_INDENT_SIZE, dry_run=False):
+@@ -143,7 +148,7 @@ Format/Beautify one or more JSON file(s)."""
+                 console.info("SKIP %s, no JSON files found in dir.", filename)
+                 skipped += 1
+         elif not os.path.exists(filename):
+-            console.warn("SKIP %s, file not found.", filename)
++            console.warning("SKIP %s, file not found.", filename)
+             skipped += 1
+             continue
+         else:
+diff --git a/bin/jsonschema_validate.py b/bin/jsonschema_validate.py
+index db2edb1..fe7596e 100755
+--- a/bin/jsonschema_validate.py
++++ b/bin/jsonschema_validate.py
+@@ -18,11 +18,11 @@ from __future__ import absolute_import, print_function
+ __author__  = "Jens Engel"
+ __version__ = "0.1.0"
+ 
+-from jsonschema import validate
+ import argparse
+ import os.path
+ import sys
+ import textwrap
++from jsonschema import validate
+ try:
+     import json
+ except ImportError:
+@@ -38,16 +38,28 @@ except ImportError:
+ HERE = os.path.dirname(__file__)
+ TOP  = os.path.normpath(os.path.join(HERE, ".."))
+ SCHEMA = os.path.join(TOP, "etc", "json", "behave.json-schema")
++PYTHON_VERSION = sys.version_info[:2]
+ 
+ 
+ # -----------------------------------------------------------------------------
+ # FUNCTIONS:
+ # -----------------------------------------------------------------------------
+-def jsonschema_validate(filename, schema, encoding=None):
++def json_loads(text, encoding=None):
++    kwargs = {}
++    if encoding and PYTHON_VERSION < (3, 1):
++        # -- NOTE: encoding keyword is deprecated since python 3.1
++        kwargs["encoding"] = encoding
++    return json.loads(text, **kwargs)
++
++def json_load(filename, encoding=None):
+     f = open(filename, "r")
+     contents = f.read()
+     f.close()
+-    data = json.loads(contents, encoding=encoding)
++    data = json_loads(contents, encoding=encoding)
++    return data
++
++def jsonschema_validate(filename, schema, encoding=None):
++    data = json_load(filename, encoding=encoding)
+     return validate(data, schema)
+ 
+ 
+@@ -89,10 +101,7 @@ def main(args=None):
+         parser.error("SCHEMA not found: %s" % options.schema)
+ 
+     try:
+-        f = open(options.schema, "r")
+-        contents = f.read()
+-        f.close()
+-        schema = json.loads(contents, encoding=options.encoding)
++        schema = json_load(options.schema, encoding=options.encoding)
+     except Exception as e:
+         msg = "ERROR: %s: %s (while loading schema)" % (e.__class__.__name__, e)
+         sys.exit(msg)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch b/meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch
new file mode 100644
index 000000000..615d10bd6
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch
@@ -0,0 +1,18 @@
+From 961e4f93259a0c1176a53a34d8e8de592c03db55 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 21:53:32 +0100
+Subject: [PATCH] FIX: Python2 problems in virtualenvs w/ behave4cmd0 steps.
+
+---
+ bin/behave | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/bin/behave b/bin/behave
+index 9ebb584..0f37dec 100755
+--- a/bin/behave
++++ b/bin/behave
+@@ -1,3 +1,4 @@
++#!/usr/bin/env python
+ #!/usr/bin/env python3
+ # -*- coding: utf-8 -*-
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch b/meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch
new file mode 100644
index 000000000..d45aba3d4
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0109-FIX-Active-tag-logic.patch
@@ -0,0 +1,875 @@
+From 2c38a8787409ddb50ff9ee93006d5e30a40110de Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 22:04:18 +0100
+Subject: [PATCH] FIX: Active-tag logic
+
+Fix active-tag computation logic if multiple active-tags exist
+that use the same category. It is now possible to use
+positive (use.with_xxx) and negative (not.with_xxx) tags
+on the same model element (Feature, Scenario, ...).
+---
+ behave/api/runtime_constraint.py     |  12 +-
+ behave/tag_matcher.py                |  82 ++++-
+ features/tags.active_tags.feature    |  22 +-
+ tests/functional/test_active_tags.py | 529 +++++++++++++++++++++++++++
+ tests/unit/test_tag_matcher.py       |  45 +--
+ 5 files changed, 624 insertions(+), 66 deletions(-)
+ create mode 100644 tests/functional/test_active_tags.py
+
+diff --git a/behave/api/runtime_constraint.py b/behave/api/runtime_constraint.py
+index 310e529..e5a36a0 100644
+--- a/behave/api/runtime_constraint.py
++++ b/behave/api/runtime_constraint.py
+@@ -7,6 +7,8 @@ Simplifies to specify runtime constraints in
+ """
+ 
+ from __future__ import absolute_import
++import six
++import sys
+ from behave.exception import ConstraintError
+ 
+ 
+@@ -19,11 +21,10 @@ def require_min_python_version(minimal_version):
+     :param minimal_version: Minimum version (as string, tuple)
+     :raises: behave.exception.ConstraintError
+     """
+-    import six
+-    import sys
+     python_version = sys.version_info
+     if isinstance(minimal_version, six.string_types):
+-        python_version = "%s.%s" % sys.version_info[:2]
++        python_version = float("%s.%s" % sys.version_info[:2])
++        minimal_version = float(minimal_version)
+     elif not isinstance(minimal_version, tuple):
+         raise TypeError("string or tuple (was: %s)" % type(minimal_version))
+ 
+@@ -40,6 +41,9 @@ def require_min_behave_version(minimal_version):
+     """
+     # -- SIMPLISTIC IMPLEMENTATION:
+     from behave.version import VERSION as behave_version
+-    if behave_version < minimal_version:
++    behave_version2 = behave_version.split(".")
++    minimal_version2 = minimal_version.split(".")
++    if behave_version2 < minimal_version2:
++        # -- USE: Tuple comparison as version comparison.
+         raise ConstraintError("behave >= %s expected (was: %s)" % \
+                               (minimal_version, behave_version))
+diff --git a/behave/tag_matcher.py b/behave/tag_matcher.py
+index 5f9dce0..e2b1e82 100644
+--- a/behave/tag_matcher.py
++++ b/behave/tag_matcher.py
+@@ -1,7 +1,7 @@
+ # -*- coding: UTF-8 -*-
+ """
+-Contains classes and functionality to provide a skip-if logic based on tags
+-in feature files.
++Contains classes and functionality to provide the active-tag mechanism.
++Active-tags provide a skip-if logic based on tags in feature files.
+ """
+ 
+ from __future__ import absolute_import
+@@ -10,6 +10,11 @@ import operator
+ import six
+ 
+ 
++def bool_to_string(value):
++    """Converts a Boolean value into its normalized string representation."""
++    return str(bool(value)).lower()
++
++
+ class TagMatcher(object):
+     """Abstract base class that defines the TagMatcher protocol."""
+ 
+@@ -36,12 +41,13 @@ class TagMatcher(object):
+ class ActiveTagMatcher(TagMatcher):
+     """Provides an active tag matcher for many categories.
+ 
+-    TAG SCHEMA:
++    TAG SCHEMA 1 (preferred):
+       * use.with_{category}={value}
+       * not.with_{category}={value}
++
++    TAG SCHEMA 2:
+       * active.with_{category}={value}
+       * not_active.with_{category}={value}
+-      * only.with_{category}={value}        (NOTE: For backward compatibility)
+ 
+     TAG LOGIC
+     ----------
+@@ -52,7 +58,7 @@ class ActiveTagMatcher(TagMatcher):
+         active_group.enabled := enabled(group.tag1) or enabled(group.tag2) or ...
+         active_tags.enabled  := enabled(group1) and enabled(group2) and ...
+ 
+-    All active-tag groups must be turned "on".
++    All active-tag groups must be turned "on" (enabled).
+     Otherwise, the model element should be excluded.
+ 
+     CONCEPT: ValueProvider
+@@ -81,12 +87,12 @@ class ActiveTagMatcher(TagMatcher):
+         # -- FILE: features/alice.feature
+         Feature:
+ 
+-          @active.with_os=win32
++          @use.with_os=win32
+           Scenario: Alice (Run only on Windows)
+             Given I do something
+             ...
+ 
+-          @not_active.with_browser=chrome
++          @not.with_browser=chrome
+           Scenario: Bob (Excluded with Web-Browser Chrome)
+             Given I do something else
+             ...
+@@ -116,7 +122,7 @@ class ActiveTagMatcher(TagMatcher):
+                 scenario.skip(exclude_reason)   #< LATE-EXCLUDE from run-set.
+     """
+     value_separator = "="
+-    tag_prefixes = ["active", "not_active", "use", "not", "only"]
++    tag_prefixes = ["use", "not", "active", "not_active", "only"]
+     tag_schema = r"^(?P<prefix>%s)\.with_(?P<category>\w+(\.\w+)*)%s(?P<value>.*)$"
+     ignore_unknown_categories = True
+     use_exclude_reason = False
+@@ -163,21 +169,49 @@ class ActiveTagMatcher(TagMatcher):
+ 
+     def is_tag_group_enabled(self, group_category, group_tag_pairs):
+         """Provides boolean logic to determine if all active-tags
+-        which use the same category result in a enabled value.
+-
+-        Use LOGICAL-OR expression for active-tags with same category::
+-
+-            category_tag_group.enabled := enabled(tag1) or enabled(tag2) or ...
++        which use the same category result in an enabled value.
+ 
+         .. code-block:: gherkin
+ 
+             @use.with_xxx=alice
+             @use.with_xxx=bob
+             @not.with_xxx=charly
++            @not.with_xxx=doro
+             Scenario:
+                 Given a step passes
+                 ...
+ 
++        Use LOGICAL expression for active-tags with same category::
++
++            category_tag_group.enabled := positive-tag-expression and not negative-tag-expression
++              positive-tag-expression  := enabled(tag1) or enabled(tag2) or ...
++              negative-tag-expression  := enabled(tag3) or enabled(tag4) or ...
++               tag1, tag2 are positive-tags, like @use.with_category=value
++               tag3, tag4 are negative-tags, like @not.with_category=value
++
++             xxx   | Only use parts: (xxx == "alice") or (xxx == "bob")
++            -------+-------------------
++            alice  | true
++            bob    | true
++            other  | false
++
++             xxx   | Only not parts:
++                   | (not xxx == "charly") and (not xxx == "doro")
++                   | = not((xxx == "charly") or (xxx == "doro"))
++            -------+-------------------
++            charly | false
++            doro   | false
++            other  | true
++
++             xxx   | Use and not parts:
++                   | ((xxx == "alice") or (xxx == "bob")) and not((xxx == "charly") or (xxx == "doro"))
++            -------+-------------------
++            alice  | true
++            bob    | true
++            charly | false
++            doro   | false
++            other  | false
++
+         :param group_category:      Category for this tag-group (as string).
+         :param category_tag_group:  List of active-tag match-pairs.
+         :return: True, if tag-group is enabled.
+@@ -191,20 +225,28 @@ class ActiveTagMatcher(TagMatcher):
+             # -- CASE: Unknown category, ignore it.
+             return True
+ 
+-        tags_enabled = []
++        positive_tags_matched = []
++        negative_tags_matched = []
+         for category_tag, tag_match in group_tag_pairs:
+             tag_prefix = tag_match.group("prefix")
+             category = tag_match.group("category")
+             tag_value = tag_match.group("value")
+             assert category == group_category
+ 
+-            is_category_tag_switched_on = operator.eq       # equal_to
+             if self.is_tag_negated(tag_prefix):
+-                is_category_tag_switched_on = operator.ne   # not_equal_to
+-
+-            tag_enabled = is_category_tag_switched_on(tag_value, current_value)
+-            tags_enabled.append(tag_enabled)
+-        return any(tags_enabled)    # -- PROVIDES: LOGICAL-OR expression
++                # -- CASE: @not.with_CATEGORY=VALUE
++                tag_matched = (tag_value == current_value)
++                negative_tags_matched.append(tag_matched)
++            else:
++                # -- CASE: @use.with_CATEGORY=VALUE
++                tag_matched = (tag_value == current_value)
++                positive_tags_matched.append(tag_matched)
++        tag_expression1 = any(positive_tags_matched)    #< LOGICAL-OR expression
++        tag_expression2 = any(negative_tags_matched)    #< LOGICAL-OR expression
++        if not positive_tags_matched:
++            tag_expression1 = True
++        tag_group_enabled = bool(tag_expression1 and not tag_expression2)
++        return tag_group_enabled
+ 
+     def should_exclude_with(self, tags):
+         group_categories = self.group_active_tags_by_category(tags)
+diff --git a/features/tags.active_tags.feature b/features/tags.active_tags.feature
+index 4ab55c2..6adcb60 100644
+--- a/features/tags.active_tags.feature
++++ b/features/tags.active_tags.feature
+@@ -240,9 +240,25 @@ Feature: Active Tags
+         | tags                                      | enabled? | Comment |
+         | @use.with_foo=xxx   @use.with_foo=other   |  yes     | Enabled: tag1 |
+         | @use.with_foo=xxx   @not.with_foo=other   |  yes     | Enabled: tag1, tag2|
+-        | @use.with_foo=xxx   @not.with_foo=xxx     |  yes     | Enabled: tag1 (BAD-SPEC) |
+-        | @use.with_foo=other @not.with_foo=xxx     |  no      | Enabled: none |
+-        | @not.with_foo=other @not.with_foo=xxx     |  yes     | Enabled: tag1 |
++        | @use.with_foo=other @not.with_foo=xxx     |  no      | Disabled: none |
++        | @not.with_foo=other @not.with_foo=xxx     |  no      | Disabled: tag1 |
++        | @use.with_foo=xxx   @not.with_foo=xxx     |  no      | Disabled: tag1 (BAD-SPEC, CONFLICTS) |
++
++
++  Scenario: Tag logic with three active tags of same category
++      Given I setup the current values for active tags with:
++        | category | value |
++        | foo      | xxx   |
++      Then the following active tag combinations are enabled:
++        | tags                                                        | enabled? | Comment |
++        | @use.with_foo=xxx  @use.with_foo=other @use.with_foo=other2|  yes     | Enabled: tag1  |
++        | @use.with_foo=xxx  @use.with_foo=other @not.with_foo=other2|  yes     | Enabled: tag1  |
++        | @use.with_foo=xxx  @not.with_foo=other @use.with_foo=other2|  yes     | Enabled: tag1  |
++        | @use.with_foo=xxx  @not.with_foo=other @not.with_foo=other2|  yes     | Enabled: tag1  |
++        | @not.with_foo=xxx  @use.with_foo=other @use.with_foo=other2|  no      | Disabled: tag1 |
++        | @not.with_foo=xxx  @use.with_foo=other @not.with_foo=other2|  no      | Disabled: tag1 |
++        | @not.with_foo=xxx  @not.with_foo=other @use.with_foo=other2|  no      | Disabled: tag1 |
++        | @not.with_foo=xxx  @not.with_foo=other @not.with_foo=other2|  no      | Disabled: tag1 |
+ 
+ 
+     Scenario: Tag logic with unknown categories (case: ignored)
+diff --git a/tests/functional/test_active_tags.py b/tests/functional/test_active_tags.py
+new file mode 100644
+index 0000000..fd6138f
+--- /dev/null
++++ b/tests/functional/test_active_tags.py
+@@ -0,0 +1,529 @@
++# -*- coding: utf-8 -*-
++"""
++Functionals tests for active tag-matcher (mod:`behave.tag_matcher`).
++"""
++
++from __future__ import absolute_import, print_function
++import pytest
++from behave.tag_matcher import ActiveTagMatcher
++
++# =============================================================================
++# TEST DATA:
++# =============================================================================
++# VALUE_PROVIDER = {
++#     "foo": "alice",
++#     "bar": "BOB",
++# }
++
++# =============================================================================
++# PYTEST FIXTURES:
++# =============================================================================
++# @pytest.fixture
++# def active_tag_matcher():
++#     tag_matcher = ActiveTagMatcher(VALUE_PROVIDER)
++#     return tag_matcher
++
++
++# =============================================================================
++# TEST SUITE:
++# =============================================================================
++class TestActivateTags(object):
++    VALUE_PROVIDER = {
++        "foo": "Frank",
++        "bar": "Bob",
++        # "OTHER": "VALUE",
++    }
++
++    def check_should_run_with_active_tags(self, case, expected, tags):
++        # -- tag_matcher.should_run_with(tags).result := expected
++        case += " (tags: {tags})"
++        tag_matcher = ActiveTagMatcher(self.VALUE_PROVIDER)
++        actual_result1 = tag_matcher.should_run_with(tags)
++        actual_result2 = tag_matcher.should_exclude_with(tags)
++        assert expected == actual_result1, case.format(tags=tags)
++        assert (not expected) == actual_result2
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("use.with_foo=VALUE matches",     True, ["use.with_foo=Frank"]),
++        ("use.with_foo=VALUE mismatches", False, ["use.with_foo=OTHER"]),
++        ("not.with_foo=VALUE matches",    False, ["not.with_foo=Frank"]),
++        ("not.with_foo=VALUE mismatches",  True, ["not.with_foo=OTHER"]),
++        ("NO_TAGS", True, []),
++    ])
++    def test_one_tag_for_category1(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("use.with_bar=Bob matches",       True, ["use.with_bar=Bob"]),
++        ("use.with_bar=VALUE mismatches", False, ["use.with_bar=OTHER"]),
++        ("not.with_bar=VALUE matches",    False, ["not.with_bar=Bob"]),
++        ("not.with_bar=VALUE mismatches",  True, ["not.with_bar=OTHER"]),
++    ])
++    def test_one_tag_for_category2(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    # @pytest.mark.parametrize("case, expected, tags", [
++    #     ("use.with_OTHER=VALUE matches",     True, ["use.with_OTHER=VALUE"]),
++    #     ("use.with_OTHER=VALUE mismatches", False, ["use.with_OTHER=OTHER"]),
++    #     ("not.with_OTHER=VALUE matches",    False, ["not.with_OTHER=VALUE"]),
++    #     ("not.with_OTHER=VALUE mismatches",  True, ["not.with_OTHER=OTHER"]),
++    # ])
++    # def test_one_tag_for_other_category(self, case, expected, tags):
++    #     self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("2x use.with_foo=VALUE: one matches", True,
++         ["use.with_foo=Frank", "use.with_foo=OTHER"]),
++        ("2x not.with_foo=VALUE: one matches", False,
++         ["not.with_foo=Frank", "not.with_foo=OTHER"]),
++        ("1x use./not.with_foo=VALUE: use-matches", True,
++         ["use.with_foo=Frank", "not.with_foo=OTHER"]),
++        ("1x use./not.with_foo=VALUE: not-matches", False,
++         ["not.with_foo=Frank", "use.with_foo=OTHER"]),
++    ])
++    def test_one_category_with_two_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        ("3x use.with_foo=VALUE: one matches", True,
++         ["use.with_foo=Frank", "use.with_foo=OTHER_1", "use.with_foo=OTHER_2"]),
++        ("3x not.with_foo=VALUE: one matches", False,
++         ["not.with_foo=Frank", "not.with_foo=OTHER_1", "not.with_foo=OTHER_2"]),
++        ("2x use.with_foo=VALUE: use-matches", True,
++         ["use.with_foo=Frank", "use.with_foo=OTHER_1", "not.with_foo=OTHER_2"]),
++        ("2x not.with_foo=VALUE: not-matches", False,
++         ["not.with_foo=Frank", "not.with_foo=OTHER_1", "use.with_foo=OTHER_2"]),
++        ("1x use.with_foo=VALUE: use-matches", True,
++         ["use.with_foo=Frank", "not.with_foo=OTHER_1", "not.with_foo=OTHER_2"]),
++        ("1x not.with_foo=VALUE: not-matches", False,
++         ["not.with_foo=Frank", "use.with_foo=OTHER_1", "use.with_foo=OTHER_2"]),
++    ])
++    def test_one_category_with_three_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- use.with_CATEGORY=VALUE
++        ("use.with_... 2x matches",      True, ["use.with_foo=Frank", "use.with_bar=Bob"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=Frank", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_bar=Bob"]),
++        ("use.with_... 0x matches",     False, ["use.with_foo=OTHER", "use.with_bar=OTHER"]),
++        # -- not.with_CATEGORY=VALUE
++        ("not.with_... 2x matches", False, ["not.with_foo=Frank", "not.with_bar=Bob"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=Frank", "not.with_bar=OTHER"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("not.with_... 0x matches",  True, ["not.with_foo=OTHER", "not.with_bar=OTHER"]),
++        # -- use.with_CATEGORY_1=VALUE_1, not.with_CATEGORY_2=VALUE_2
++        ("use./not.with_... use-matches",  True, ["use.with_foo=Frank", "not.with_bar=OTHER"]),
++        ("use./not.with_... not-matches", False, ["use.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("use./not.with_... 2x matches",  False, ["use.with_foo=Frank", "not.with_bar=Bob"]),
++        ("use./not.with_... 0x matches",  False, ["use.with_foo=OTHER", "not.with_bar=OTHER"]),
++    ])
++    def test_two_categories_with_two_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- use.with_CATEGORY=VALUE
++        ("use.with_... 2x matches",      True, ["use.with_foo=Frank", "use.with_foo=OTHER", "use.with_bar=Bob"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=Frank", "use.with_foo=OTHER", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_foo=Frank", "use.with_bar=OTHER"]),
++        ("use.with_... 1x matches",     False, ["use.with_foo=OTHER", "use.with_foo=OTHER2", "use.with_bar=Bob"]),
++        ("use.with_... 0x matches",     False, ["use.with_foo=OTHER", "use.with_bar=OTHER2", "use.with_bar=OTHER"]),
++        # -- not.with_CATEGORY=VALUE
++        ("not.with_... 2x matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "not.with_bar=OTHER"]),
++        ("not.with_... 1x matches", False, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "not.with_bar=Bob"]),
++        ("not.with_... 0x matches",  True, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "not.with_bar=OTHER"]),
++        # -- use.with_CATEGORY_1=VALUE_1, not.with_CATEGORY_2=VALUE_2
++        ("use./not.with_... use-matches",  True, ["use.with_foo=Frank", "use.with_foo=OTHER", "not.with_bar=OTHER"]),
++        ("use./not.with_... not-matches", False, ["use.with_foo=OTHER", "use.with_foo=OTHER2", "not.with_bar=Bob"]),
++        ("use./not.with_... 2x matches",  False, ["use.with_foo=Frank", "use.with_foo=OTHER", "not.with_bar=Bob"]),
++        ("use./not.with_... 0x matches",  False, ["use.with_foo=OTHER", "use.with_foo=OTHER2", "not.with_bar=OTHER"]),
++        # -- not.with_CATEGORY_1=VALUE_1, use.with_CATEGORY_2=VALUE_2
++        ("use./not.with_... not-matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "use.with_bar=OTHER"]),
++        ("use./not.with_... use-matches", True, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "use.with_bar=Bob"]),
++        ("use./not.with_... 2x matches", False, ["not.with_foo=Frank", "not.with_foo=OTHER", "use.with_bar=Bob"]),
++        ("use./not.with_... 0x matches", False, ["not.with_foo=OTHER", "not.with_foo=OTHER2", "use.with_bar=OTHER"]),
++    ])
++    def test_two_categories_with_three_tags(self, case, expected, tags):
++        self.check_should_run_with_active_tags(case, expected, tags)
++
++'''
++class Traits4ActiveTagMatcher(object):
++    TagMatcher = ActiveTagMatcher
++    value_provider = {
++        "foo": "alice",
++        "bar": "BOB",
++    }
++
++    category1_enabled_tag = TagMatcher.make_category_tag("foo", "alice")
++    category1_disabled_tag = TagMatcher.make_category_tag("foo", "bob")
++    category1_disabled_tag2 = TagMatcher.make_category_tag("foo", "charly")
++    category1_similar_tag = TagMatcher.make_category_tag("foo", "alice2")
++    category2_enabled_tag = TagMatcher.make_category_tag("bar", "BOB")
++    category2_disabled_tag = TagMatcher.make_category_tag("bar", "CHARLY")
++    category2_similar_tag = TagMatcher.make_category_tag("bar", "BOB2")
++    unknown_category_tag = TagMatcher.make_category_tag("UNKNOWN", "one")
++
++    # -- NEGATED TAGS:
++    category1_not_enabled_tag = \
++        TagMatcher.make_category_tag("foo", "alice", "not_active")
++    category1_not_enabled_tag2 = \
++        TagMatcher.make_category_tag("foo", "alice", "not")
++    category1_not_disabled_tag = \
++        TagMatcher.make_category_tag("foo", "bob", "not_active")
++    category1_negated_similar_tag1 = \
++        TagMatcher.make_category_tag("foo", "alice2", "not_active")
++
++
++    active_tags1 = [
++        category1_enabled_tag, category1_disabled_tag, category1_similar_tag,
++        category1_not_enabled_tag, category1_not_enabled_tag2,
++    ]
++    active_tags2 = [
++        category2_enabled_tag, category2_disabled_tag, category2_similar_tag,
++    ]
++    active_tags = active_tags1 + active_tags2
++
++
++# -- REQUIRES: pytest
++class TestActiveTagMatcher2(object):
++    TagMatcher = ActiveTagMatcher
++    traits = Traits4ActiveTagMatcher
++
++    @classmethod
++    def make_tag_matcher(cls):
++        value_provider = {
++            "foo": "alice",
++            "bar": "BOB",
++        }
++        tag_matcher = cls.TagMatcher(value_provider)
++        return tag_matcher
++
++    @pytest.mark.parametrize("case, expected_len, tags", [
++        ("case: Two enabled tags", 2,
++         [traits.category1_enabled_tag, traits.category2_enabled_tag]),
++        ("case: Active enabled and normal tag", 1,
++         [traits.category1_enabled_tag,  "foo"]),
++        ("case: Active disabled and normal tag", 1,
++         [traits.category1_disabled_tag, "foo"]),
++        ("case: Normal and active negated tag", 1,
++         ["foo", traits.category1_not_enabled_tag]),
++        ("case: Two normal tags", 0,
++         ["foo", "bar"]),
++    ])
++    def test_select_active_tags__with_two_tags(self, case, expected_len, tags):
++        tag_matcher = self.make_tag_matcher()
++        selected = tag_matcher.select_active_tags(tags)
++        selected = list(selected)
++        assert len(selected) == expected_len, case
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- GROUP: With positive logic (non-negated tags)
++        ("case P00: 2 disabled tags", True,
++         [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
++        ("case P01: disabled and enabled tag", True,
++         [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
++        ("case P10: enabled and disabled tag", True,
++         [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
++        ("case P11: 2 enabled tags", False,  # -- SHOULD-RUN
++         [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
++        # -- GROUP: With negated tag
++        ("case N00: not-enabled and disabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category2_disabled_tag]),
++        ("case N01: not-enabled and enabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category2_enabled_tag]),
++        ("case N10: not-disabled and disabled tag", True,
++         [ traits.category1_not_disabled_tag, traits.category2_disabled_tag]),
++        ("case N11: not-disabled and enabled tag", False, # -- SHOULD-RUN
++         [ traits.category1_not_disabled_tag, traits.category2_enabled_tag]),
++        # -- GROUP: With unknown category
++        ("case U0x: disabled and unknown tag", True,
++         [ traits.category1_disabled_tag, traits.unknown_category_tag]),
++        ("case U1x: enabled and unknown tag", False,  # -- SHOULD-RUN
++         [ traits.category1_enabled_tag, traits.unknown_category_tag]),
++    ])
++    def test_should_exclude_with__combinations_of_2_categories(self, case, expected, tags):
++        tag_matcher = self.make_tag_matcher()
++        actual_result = tag_matcher.should_exclude_with(tags)
++        assert expected == actual_result, case
++
++    @pytest.mark.parametrize("case, expected, tags", [
++        # -- GROUP: With positive logic (non-negated tags)
++        ("case P00: 2 disabled tags", True,
++         [ traits.category1_disabled_tag, traits.category1_disabled_tag2]),
++        ("case P01: disabled and enabled tag", False,
++         [ traits.category1_disabled_tag, traits.category1_enabled_tag]),
++        ("case P10: enabled and disabled tag", False,
++         [ traits.category1_enabled_tag, traits.category1_disabled_tag]),
++        ("case P11: 2 enabled tags (same)", False,  # -- SHOULD-RUN
++         [ traits.category1_enabled_tag, traits.category1_enabled_tag]),
++        # -- GROUP: With negated tag
++        ("case N00: not-enabled and disabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category1_disabled_tag]),
++        ("case N01: not-enabled and enabled tag", True,
++         [ traits.category1_not_enabled_tag, traits.category1_enabled_tag]),
++        ("case N10: not-disabled and disabled tag", True,
++         [ traits.category1_not_disabled_tag, traits.category1_disabled_tag]),
++        ("case N11: not-disabled and enabled tag", False, # -- SHOULD-RUN
++         [ traits.category1_not_disabled_tag, traits.category1_enabled_tag]),
++    ])
++    def test_should_exclude_with__combinations_with_same_category(self,
++                                                        case, expected, tags):
++        tag_matcher = self.make_tag_matcher()
++        print("tags: {}".format(tags) )
++        print("tag_matcher.value: {}".format(tag_matcher.value_provider) )
++        actual_result = tag_matcher.should_exclude_with(tags)
++        assert expected == actual_result, case
++
++
++class TestActiveTags(TestCase):
++    TagMatcher = ActiveTagMatcher
++    traits = Traits4ActiveTagMatcher
++
++    @classmethod
++    def make_tag_matcher(cls):
++        tag_matcher = cls.TagMatcher(cls.traits.value_provider)
++        return tag_matcher
++
++    def setUp(self):
++        self.tag_matcher = self.make_tag_matcher()
++
++    def test_select_active_tags__basics(self):
++        active_tag = "active.with_CATEGORY=VALUE"
++        tags = ["foo", active_tag, "bar"]
++        selected = list(self.tag_matcher.select_active_tags(tags))
++        self.assertEqual(len(selected), 1)
++        selected_tag, selected_match = selected[0]
++        self.assertEqual(selected_tag, active_tag)
++
++    def test_select_active_tags__matches_tag_parts(self):
++        tags = ["active.with_CATEGORY=VALUE"]
++        selected = list(self.tag_matcher.select_active_tags(tags))
++        self.assertEqual(len(selected), 1)
++        selected_tag, selected_match = selected[0]
++        self.assertEqual(selected_match.group("prefix"), "active")
++        self.assertEqual(selected_match.group("category"), "CATEGORY")
++        self.assertEqual(selected_match.group("value"), "VALUE")
++
++    def test_select_active_tags__finds_tag_with_any_valid_tag_prefix(self):
++        TagMatcher = self.TagMatcher
++        for tag_prefix in TagMatcher.tag_prefixes:
++            tag = TagMatcher.make_category_tag("foo", "alice", tag_prefix)
++            tags = [ tag ]
++            selected = self.tag_matcher.select_active_tags(tags)
++            selected = list(selected)
++            self.assertEqual(len(selected), 1)
++            selected_tag0 = selected[0][0]
++            self.assertEqual(selected_tag0, tag)
++            self.assertTrue(selected_tag0.startswith(tag_prefix))
++
++    def test_select_active_tags__ignores_invalid_active_tags(self):
++        invalid_active_tags = [
++            ("foo.alice",               "case: Normal tag"),
++            ("with_foo=Frank",          "case: Subset of an active tag"),
++            ("ACTIVE.with_foo.alice",   "case: Wrong tag_prefix (uppercase)"),
++            ("only.with_foo.alice",     "case: Wrong value_separator"),
++        ]
++        for invalid_tag, case in invalid_active_tags:
++            tags = [ invalid_tag ]
++            selected = self.tag_matcher.select_active_tags(tags)
++            selected = list(selected)
++            self.assertEqual(len(selected), 0, case)
++
++    def test_select_active_tags__with_two_tags(self):
++        # XXX-JE-DUPLICATED:
++        traits = self.traits
++        test_patterns = [
++            ("case: Two enabled tags",
++             [traits.category1_enabled_tag, traits.category2_enabled_tag]),
++            ("case: Active enabled and normal tag",
++             [traits.category1_enabled_tag,  "foo"]),
++            ("case: Active disabled and normal tag",
++             [traits.category1_disabled_tag, "foo"]),
++            ("case: Active negated and normal tag",
++             [traits.category1_not_enabled_tag, "foo"]),
++        ]
++        for case, tags in test_patterns:
++            selected = self.tag_matcher.select_active_tags(tags)
++            selected = list(selected)
++            self.assertTrue(len(selected) >= 1, case)
++
++
++    def test_should_exclude_with__returns_false_with_enabled_tag(self):
++        traits = self.traits
++        tags1 = [ traits.category1_enabled_tag ]
++        tags2 = [ traits.category2_enabled_tag ]
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags1))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags2))
++
++    def test_should_exclude_with__returns_false_with_disabled_tag_and_more(self):
++        # -- NOTE: Need 1+ enabled active-tags of same category => ENABLED
++        # pylint: disable=line-too-long
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
++            ([ traits.category1_disabled_tag, traits.category1_enabled_tag ], "case: last"),
++            ([ "foo", traits.category1_enabled_tag, traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        enabled = True  # EXPECTED
++        for tags, case in test_patterns:
++            self.assertEqual(not enabled, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_disabled_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_other_tag_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_disabled_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_disabled_tag ], "case: last"),
++            ([ "foo", traits.category1_disabled_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_true_with_similar_tag(self):
++        traits = self.traits
++        tags = [ traits.category1_similar_tag ]
++        self.assertEqual(True, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__returns_true_with_similar_and_more(self):
++        traits = self.traits
++        test_patterns = [
++            ([ traits.category1_similar_tag, "foo" ], "case: first"),
++            ([ "foo", traits.category1_similar_tag ], "case: last"),
++            ([ "foo", traits.category1_similar_tag, "bar" ], "case: middle"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(True, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_without_category_tag(self):
++        test_patterns = [
++            ([ ],           "case: No tags"),
++            ([ "foo" ],     "case: One tag"),
++            ([ "foo", "bar" ], "case: Two tags"),
++        ]
++        for tags, case in test_patterns:
++            self.assertEqual(False, self.tag_matcher.should_exclude_with(tags),
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_exclude_with__returns_false_with_unknown_category_tag(self):
++        """Tags from unknown categories, not supported by value_provider,
++        should not be excluded.
++        """
++        traits = self.traits
++        tags = [ traits.unknown_category_tag ]
++        self.assertEqual("use.with_UNKNOWN=one", traits.unknown_category_tag)
++        self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
++        self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
++
++    def test_should_exclude_with__combinations_of_2_categories(self):
++        # XXX-JE-DUPLICATED:
++        traits = self.traits
++        test_patterns = [
++            ("case P00: 2 disabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_disabled_tag]),
++            ("case P01: disabled and enabled category tags", True,
++             [ traits.category1_disabled_tag, traits.category2_enabled_tag]),
++            ("case P10: enabled and disabled category tags", True,
++             [ traits.category1_enabled_tag, traits.category2_disabled_tag]),
++            ("case P11: 2 enabled category tags", False,  # -- SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.category2_enabled_tag]),
++            # -- SPECIAL CASE: With negated category
++            ("case N00: not-enabled and disabled category tags", True,
++             [ traits.category1_not_enabled_tag, traits.category2_disabled_tag]),
++            ("case N01: not-enabled and enabled category tags", True,
++             [ traits.category1_not_enabled_tag, traits.category2_enabled_tag]),
++            ("case N10: not-disabled and disabled category tags", True,
++             [ traits.category1_not_disabled_tag, traits.category2_disabled_tag]),
++            ("case N11: not-enabled and enabled category tags", False,  # -- SHOULD-RUN
++             [ traits.category1_not_disabled_tag, traits.category2_enabled_tag]),
++            # -- SPECIAL CASE: With unknown category
++            ("case 0x: disabled and unknown category tags", True,
++             [ traits.category1_disabled_tag, traits.unknown_category_tag]),
++            ("case 1x: enabled and unknown category tags", False,  # SHOULD-RUN
++             [ traits.category1_enabled_tag, traits.unknown_category_tag]),
++        ]
++        for case, expected, tags in test_patterns:
++            actual_result = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(expected, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++    def test_should_run_with__negates_result_of_should_exclude_with(self):
++        traits = self.traits
++        test_patterns = [
++            ([ ],                   "case: No tags"),
++            ([ "foo" ],             "case: One non-category tag"),
++            ([ "foo", "bar" ],      "case: Two non-category tags"),
++            ([ traits.category1_enabled_tag ],   "case: enabled tag"),
++            ([ traits.category1_enabled_tag, traits.category1_disabled_tag ],  "case: enabled and other tag"),
++            ([ traits.category1_enabled_tag, "foo" ],    "case: enabled and foo tag"),
++            ([ traits.category1_disabled_tag ],            "case: other tag"),
++            ([ traits.category1_disabled_tag, "foo" ],     "case: other and foo tag"),
++            ([ traits.category1_similar_tag ],          "case: similar tag"),
++            ([ "foo", traits.category1_similar_tag ],   "case: foo and similar tag"),
++        ]
++        for tags, case in test_patterns:
++            result1 = self.tag_matcher.should_run_with(tags)
++            result2 = self.tag_matcher.should_exclude_with(tags)
++            self.assertEqual(result1, not result2, "%s: tags=%s" % (case, tags))
++            self.assertEqual(not result1, result2, "%s: tags=%s" % (case, tags))
++
++
++class TestCompositeTagMatcher(TestCase):
++
++    @staticmethod
++    def count_tag_matcher_with_result(tag_matchers, tags, result_value):
++        count = 0
++        for tag_matcher in tag_matchers:
++            current_result = tag_matcher.should_exclude_with(tags)
++            if current_result == result_value:
++                count += 1
++        return count
++
++    def setUp(self):
++        predicate_false = lambda tags: False
++        predicate_contains_foo = lambda tags: any(x == "foo" for x in tags)
++        self.tag_matcher_false = PredicateTagMatcher(predicate_false)
++        self.tag_matcher_foo = PredicateTagMatcher(predicate_contains_foo)
++        tag_matchers = [
++            self.tag_matcher_foo,
++            self.tag_matcher_false
++        ]
++        self.ctag_matcher = CompositeTagMatcher(tag_matchers)
++
++    def test_should_exclude_with__returns_true_when_any_tag_matcher_returns_true(self):
++        test_patterns = [
++            ("case: with foo",  ["foo", "bar"]),
++            ("case: with foo2", ["foozy", "foo", "bar"]),
++        ]
++        for case, tags in test_patterns:
++            actual_result = self.ctag_matcher.should_exclude_with(tags)
++            self.assertEqual(True, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++            actual_true_count = self.count_tag_matcher_with_result(
++                                self.ctag_matcher.tag_matchers, tags, True)
++            self.assertEqual(1, actual_true_count)
++
++    def test_should_exclude_with__returns_false_when_no_tag_matcher_return_true(self):
++        test_patterns = [
++            ("case: without foo",   ["fool", "bar"]),
++            ("case: without foo2",  ["foozy", "bar"]),
++        ]
++        for case, tags in test_patterns:
++            actual_result = self.ctag_matcher.should_exclude_with(tags)
++            self.assertEqual(False, actual_result,
++                             "%s: tags=%s" % (case, tags))
++
++            actual_true_count = self.count_tag_matcher_with_result(
++                                    self.ctag_matcher.tag_matchers, tags, True)
++            self.assertEqual(0, actual_true_count)
++'''
++
+diff --git a/tests/unit/test_tag_matcher.py b/tests/unit/test_tag_matcher.py
+index a04c1d4..43f5af0 100644
+--- a/tests/unit/test_tag_matcher.py
++++ b/tests/unit/test_tag_matcher.py
+@@ -128,9 +128,9 @@ class TestActiveTagMatcher2(object):
+         # -- GROUP: With negated tag
+         ("case N00: not-enabled and disabled tag", True,
+          [ traits.category1_not_enabled_tag, traits.category1_disabled_tag]),
+-        ("case N01: not-enabled and enabled tag", False,
++        ("case N01: not-enabled and enabled tag", True,
+          [ traits.category1_not_enabled_tag, traits.category1_enabled_tag]),
+-        ("case N10: not-disabled and disabled tag", False,
++        ("case N10: not-disabled and disabled tag", True,
+          [ traits.category1_not_disabled_tag, traits.category1_disabled_tag]),
+         ("case N11: not-disabled and enabled tag", False, # -- SHOULD-RUN
+          [ traits.category1_not_disabled_tag, traits.category1_enabled_tag]),
+@@ -138,6 +138,8 @@ class TestActiveTagMatcher2(object):
+     def test_should_exclude_with__combinations_with_same_category(self,
+                                                         case, expected, tags):
+         tag_matcher = self.make_tag_matcher()
++        print("tags: {}".format(tags) )
++        print("tag_matcher.value: {}".format(tag_matcher.value_provider) )
+         actual_result = tag_matcher.should_exclude_with(tags)
+         assert expected == actual_result, case
+ 
+@@ -224,6 +226,7 @@ class TestActiveTagMatcher1(TestCase):
+ 
+     def test_should_exclude_with__returns_false_with_disabled_tag_and_more(self):
+         # -- NOTE: Need 1+ enabled active-tags of same category => ENABLED
++        # pylint: disable=line-too-long
+         traits = self.traits
+         test_patterns = [
+             ([ traits.category1_enabled_tag, traits.category1_disabled_tag ], "case: first"),
+@@ -283,7 +286,7 @@ class TestActiveTagMatcher1(TestCase):
+         """
+         traits = self.traits
+         tags = [ traits.unknown_category_tag ]
+-        self.assertEqual("active.with_UNKNOWN=one", traits.unknown_category_tag)
++        self.assertEqual("use.with_UNKNOWN=one", traits.unknown_category_tag)
+         self.assertEqual(None, self.tag_matcher.value_provider.get("UNKNOWN"))
+         self.assertEqual(False, self.tag_matcher.should_exclude_with(tags))
+ 
+@@ -376,42 +379,6 @@ class TestPredicateTagMatcher(TestCase):
+         self.assertEqual(False, predicate_always_false(tags))
+ 
+ 
+-class TestPredicateTagMatcher(TestCase):
+-
+-    def test_exclude_with__mechanics(self):
+-        predicate_function_blueprint = lambda tags: False
+-        predicate_function = Mock(predicate_function_blueprint)
+-        predicate_function.return_value = True
+-        tag_matcher = PredicateTagMatcher(predicate_function)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(True, tag_matcher.should_exclude_with(tags))
+-        predicate_function.assert_called_once_with(tags)
+-        self.assertEqual(True, predicate_function(tags))
+-
+-    def test_should_exclude_with__returns_true_when_predicate_is_true(self):
+-        predicate_always_true = lambda tags: True
+-        tag_matcher1 = PredicateTagMatcher(predicate_always_true)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(True, tag_matcher1.should_exclude_with(tags))
+-        self.assertEqual(True, predicate_always_true(tags))
+-
+-    def test_should_exclude_with__returns_true_when_predicate_is_true2(self):
+-        # -- CASE: Use predicate function instead of lambda.
+-        def predicate_contains_foo(tags):
+-            return any(x == "foo" for x in tags)
+-        tag_matcher2 = PredicateTagMatcher(predicate_contains_foo)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(True, tag_matcher2.should_exclude_with(tags))
+-        self.assertEqual(True, predicate_contains_foo(tags))
+-
+-    def test_should_exclude_with__returns_false_when_predicate_is_false(self):
+-        predicate_always_false = lambda tags: False
+-        tag_matcher1 = PredicateTagMatcher(predicate_always_false)
+-        tags = [ "foo", "bar" ]
+-        self.assertEqual(False, tag_matcher1.should_exclude_with(tags))
+-        self.assertEqual(False, predicate_always_false(tags))
+-
+-
+ class TestCompositeTagMatcher(TestCase):
+ 
+     @staticmethod
diff --git a/meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch b/meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch
new file mode 100644
index 000000000..35e26b0bd
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0110-FIX-Tests-w-more.features.patch
@@ -0,0 +1,56 @@
+From 63e15e8f89e0e9144bda18df3e08e96e8c9bfe50 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 22:09:59 +0100
+Subject: [PATCH] FIX: Tests w/ more.features/
+
+---
+ py.requirements/ci.tox.txt    | 2 ++
+ py.requirements/ci.travis.txt | 2 ++
+ tox.ini                       | 4 ++--
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/ci.tox.txt b/py.requirements/ci.tox.txt
+index 5bee524..387e905 100644
+--- a/py.requirements/ci.tox.txt
++++ b/py.requirements/ci.tox.txt
+@@ -13,3 +13,5 @@ PyHamcrest <  2.0;   python_version <  '3.0'
+ # -- HINT: path.py => path (python-install-package was renamed for python3)
+ path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
++
++jsonschema
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index 372116a..cbc60c0 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -16,6 +16,8 @@ PyHamcrest <  2.0;   python_version <  '3.0'
+ path.py >= 11.5.0; python_version <  '3.5'
+ path >= 13.1.0;    python_version >= '3.5'
+ 
++jsonschema
++
+ # -- NOTE: Travis.CI tweak related w/ invalid linecache2 tests.
+ #    This problem does not exist if you use pip.
+ linecache2 >= 1.0; python_version < '3.0'
+diff --git a/tox.ini b/tox.ini
+index 8ccb58b..c145b51 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -6,7 +6,7 @@
+ #   Use tox to run tasks (tests, ...) in a clean virtual environment.
+ #   Afterwards you can run tox in offline mode, like:
+ #
+-#       tox -e py27
++#       tox -e py38
+ #
+ #   Tox can be configured for offline usage.
+ #   Initialize local workspace once (download packages, create PyPI index):
+@@ -28,7 +28,7 @@
+ 
+ [tox]
+ minversion   = 2.3
+-envlist      = py27, py37, py38, py36, py35, pypy, docs
++envlist      = py39, py38, py27, py37, py36, py35, pypy3, pypy, docs
+ skip_missing_interpreters = True
+ sitepackages = False
+ indexserver =
diff --git a/meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch b/meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch
new file mode 100644
index 000000000..5d560ad3d
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0111-FIX-Some-regressions-with-Python-3.9.patch
@@ -0,0 +1,741 @@
+From 3c207ac9ac83d3966a7a84b8782394dc603030cd Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 22:11:38 +0100
+Subject: [PATCH] FIX: Some regressions with Python 3.9
+
+* async-steps: Use more stable active-tags now.
+* JUnit XML related: Adapt to XML attribute ordering changes since Python 3.8.
+* Prepare active-tags usage for Python 3.10
+* Behave jsonschema: Add some extra elements (related to: gherkin v6 Rule).
+---
+ .gitignore                                    |  1 +
+ CHANGES.rst                                   |  2 +
+ behave/python_feature.py                      | 81 +++++++++++++++++++
+ etc/json/behave.json-schema                   | 28 ++++++-
+ .../features/async_dispatch.feature           |  7 +-
+ .../async_step/features/async_run.feature     |  7 +-
+ examples/async_step/features/environment.py   | 16 ++--
+ .../features/steps/_async_steps34.py          |  4 +-
+ .../features/steps/async_dispatch_steps.py    | 13 +--
+ .../async_step/features/steps/async_steps.py  |  6 +-
+ features/environment.py                       | 12 ++-
+ features/step.async_steps.feature             | 64 ++++-----------
+ issue.features/issue0330.feature              | 18 +++--
+ issue.features/issue0446.feature              | 12 ++-
+ issue.features/issue0457.feature              | 12 ++-
+ issue.features/issue0657.feature              | 11 +--
+ more.features/environment.py                  | 10 +--
+ more.features/run_examples.feature            |  9 +--
+ 18 files changed, 195 insertions(+), 118 deletions(-)
+ create mode 100644 behave/python_feature.py
+
+diff --git a/.gitignore b/.gitignore
+index 9c5c33d..8d7c28e 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -25,3 +25,4 @@ tools/virtualenvs
+ .ropeproject
+ nosetests.xml
+ rerun.txt
++testrun*.json
+diff --git a/CHANGES.rst b/CHANGES.rst
+index 4e20bb8..a3398d8 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -38,6 +38,8 @@ CLARIFICATION:
+ 
+ FIXED:
+ 
++* FIXED: Some tests related to python3.9
++* FIXED: active-tag logic if multiple tags with same category exists.
+ * issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+ * issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
+diff --git a/behave/python_feature.py b/behave/python_feature.py
+new file mode 100644
+index 0000000..4e134de
+--- /dev/null
++++ b/behave/python_feature.py
+@@ -0,0 +1,81 @@
++# -*- coding: UTF-8 -*-
++"""
++Provides a knowledge database if some Python features are supported
++in the current python version.
++"""
++
++from __future__ import absolute_import
++import sys
++import six
++from behave.tag_matcher import bool_to_string
++
++
++# -----------------------------------------------------------------------------
++# CONSTANTS:
++# -----------------------------------------------------------------------------
++PYTHON_VERSION = sys.version_info[:2]
++
++
++# -----------------------------------------------------------------------------
++# CLASSES:
++# -----------------------------------------------------------------------------
++class PythonFeature(object):
++
++    @staticmethod
++    def has_asyncio_coroutine_decorator():
++        """Indicates if python supports ``@asyncio.coroutine`` decorator.
++
++        EXAMPLE::
++
++            import asyncio
++            @asyncio.coroutine
++            def async_waits_seconds(duration):
++                yield from asyncio.sleep(duration)
++
++        :returns: True, if this python version supports this feature.
++
++        .. since:: Python >= 3.4
++        .. deprecated:: Since Python 3.8 (use async-function instead)
++        """
++        # -- NOTE: @asyncio.coroutine is deprecated in py3.8, removed in py3.10
++        return (3, 4) <= PYTHON_VERSION < (3, 10)
++
++    @staticmethod
++    def has_async_function():
++        """Indicates if python supports async-functions / async-keyword.
++
++        EXAMPLE::
++
++            import asyncio
++            async def async_waits_seconds(duration):
++                yield from asyncio.sleep(duration)
++
++        :returns: True, if this python version supports this feature.
++        .. since:: Python >= 3.5
++        """
++        return (3, 5) <= PYTHON_VERSION
++
++    @classmethod
++    def has_coroutine(cls):
++        return cls.has_async_function() or cls.has_asyncio_coroutine_decorator()
++
++
++# -----------------------------------------------------------------------------
++# SUPPORTED: ACTIVE-TAGS
++# -----------------------------------------------------------------------------
++PYTHON_HAS_ASYNCIO_COROUTINE_DECORATOR = PythonFeature.has_asyncio_coroutine_decorator()
++PYTHON_HAS_ASYNC_FUNCTION = PythonFeature.has_async_function()
++PYTHON_HAS_COROUTINE = PythonFeature.has_coroutine()
++ACTIVE_TAG_VALUE_PROVIDER = {
++    "python2": bool_to_string(six.PY2),
++    "python3": bool_to_string(six.PY3),
++    "python.version": "%s.%s" % PYTHON_VERSION,
++    "os":      sys.platform.lower(),
++
++    # -- PYTHON FEATURE, like: @use.with_py.feature_asyncio.coroutine
++    "python_has_coroutine": bool_to_string(PYTHON_HAS_COROUTINE),
++    "python_has_asyncio.coroutine_decorator":
++        bool_to_string(PYTHON_HAS_ASYNCIO_COROUTINE_DECORATOR),
++    "python_has_async_function": bool_to_string(PYTHON_HAS_ASYNC_FUNCTION),
++    "python_has_async_keyword": bool_to_string(PYTHON_HAS_ASYNC_FUNCTION),
++}
+diff --git a/etc/json/behave.json-schema b/etc/json/behave.json-schema
+index 9cf3e62..110e240 100644
+--- a/etc/json/behave.json-schema
++++ b/etc/json/behave.json-schema
+@@ -28,10 +28,36 @@
+             "type": "object",
+             "anyOf": [
+                 { "$ref": "#/definitions/Background" },
++                { "$ref": "#/definitions/Rule" },
+                 { "$ref": "#/definitions/Scenario" },
+                 { "$ref": "#/definitions/ScenarioOutline" }
+             ]
+         },
++        "Rule": {
++            "type": "object",
++            "description": "Represents a Rule object.",
++            "properties": {
++                "name":     { "type": "string" },
++                "keyword":  { "type": "string" },
++                "location": { "type": "string" },
++                "status":   { "type": "string" },
++                "tags":     { "$ref": "#/definitions/Tags" },
++                "description": { "$ref": "#/definitions/MultiLineText" },
++                "elements": {
++                    "type": "array",
++                    "items": { "$ref": "#/definitions/RuleElement" }
++                }
++            },
++            "required": [ "name", "keyword", "location" ]
++        },
++        "RuleElement": {
++            "type": "object",
++            "anyOf": [
++                { "$ref": "#/definitions/Scenario" },
++                { "$ref": "#/definitions/ScenarioOutline" },
++                { "$ref": "#/definitions/Background" }
++            ]
++        },
+         "Background": {
+             "type": "object",
+             "properties": {
+@@ -169,4 +195,4 @@
+             "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
+         }
+     }
+-}
+\ No newline at end of file
++}
+diff --git a/examples/async_step/features/async_dispatch.feature b/examples/async_step/features/async_dispatch.feature
+index 18e9869..e0eba1e 100644
+--- a/examples/async_step/features/async_dispatch.feature
++++ b/examples/async_step/features/async_dispatch.feature
+@@ -1,8 +1,5 @@
+-@use.with_python.version=3.4
+-@use.with_python.version=3.5
+-@use.with_python.version=3.6
+-@use.with_python.version=3.7
+-@use.with_python.version=3.8
++@use.with_python_has_async_function=true
++@use.with_python_has_asyncio.coroutine_decorator=true
+ Feature:
+   Scenario:
+     Given I dispatch an async-call with param "Alice"
+diff --git a/examples/async_step/features/async_run.feature b/examples/async_step/features/async_run.feature
+index 29b8fa7..8b6e555 100644
+--- a/examples/async_step/features/async_run.feature
++++ b/examples/async_step/features/async_run.feature
+@@ -1,8 +1,5 @@
+-@use.with_python.version=3.4
+-@use.with_python.version=3.5
+-@use.with_python.version=3.6
+-@use.with_python.version=3.7
+-@use.with_python.version=3.8
++@use.with_python_has_async_function=true
++@use.with_python_has_asyncio.coroutine_decorator=true
+ Feature:
+   Scenario:
+     Given an async-step waits 0.3 seconds
+diff --git a/examples/async_step/features/environment.py b/examples/async_step/features/environment.py
+index 02c4d92..3fa9604 100644
+--- a/examples/async_step/features/environment.py
++++ b/examples/async_step/features/environment.py
+@@ -2,7 +2,8 @@
+ 
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+ from behave.api.runtime_constraint import require_min_python_version
+-import sys
++from behave import python_feature
++
+ 
+ # -----------------------------------------------------------------------------
+ # REQUIRE: python >= 3.4
+@@ -15,27 +16,24 @@ require_min_python_version("3.4")
+ # -----------------------------------------------------------------------------
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+-python_version = "%s.%s" % sys.version_info[:2]
+-active_tag_value_provider = {
+-    "python.version": python_version,
+-}
++active_tag_value_provider = python_feature.ACTIVE_TAG_VALUE_PROVIDER.copy()
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+-def before_all(context):
++def before_all(ctx):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+-    setup_active_tag_values(active_tag_value_provider, context.config.userdata)
++    setup_active_tag_values(active_tag_value_provider, ctx.config.userdata)
+ 
+ 
+-def before_feature(context, feature):
++def before_feature(ctx, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
+ 
+-def before_scenario(context, scenario):
++def before_scenario(ctx, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+ 
+diff --git a/examples/async_step/features/steps/_async_steps34.py b/examples/async_step/features/steps/_async_steps34.py
+index 556500f..fc4c8d1 100644
+--- a/examples/async_step/features/steps/_async_steps34.py
++++ b/examples/async_step/features/steps/_async_steps34.py
+@@ -1,5 +1,5 @@
+-# -- REQUIRES: Python >= 3.4 and Python < 3.8
+-# HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++# -- REQUIRES: Python >= 3.4 and Python < 3.10 (removed in: 3.10)
++# HINT: @asyncio.coroutine decorator is deprecated since python 3.8
+ # USE:  Async generator/coroutine instead.
+ 
+ from behave import step
+diff --git a/examples/async_step/features/steps/async_dispatch_steps.py b/examples/async_step/features/steps/async_dispatch_steps.py
+index 222e54d..def9616 100644
+--- a/examples/async_step/features/steps/async_dispatch_steps.py
++++ b/examples/async_step/features/steps/async_dispatch_steps.py
+@@ -1,8 +1,9 @@
+ # -*- coding: UTF-8 -*-
+ # REQUIRES: Python >= 3.4/3.5
+-import sys
++
+ from behave import given, then, step
+ from behave.api.async_step import use_or_create_async_context
++from behave.python_feature import PythonFeature
+ from hamcrest import assert_that, equal_to, empty
+ import asyncio
+ 
+@@ -10,13 +11,15 @@ import asyncio
+ # ---------------------------------------------------------------------------
+ # ASYNC EXAMPLE FUNCTION:
+ # ---------------------------------------------------------------------------
+-python_version = "%s.%s" % sys.version_info[:2]
+-if python_version >= "3.5":
++if PythonFeature.has_async_function():
++    # -- USE: async-function as coroutine-function
++    # SINCE: Python 3.5 (preferred)
+     async def async_func(param):
+         await asyncio.sleep(0.2)
+         return str(param).upper()
+-else:
+-    # -- HINT: Decorator @asyncio.coroutine is prohibited in python 3.8
++elif PythonFeature.has_asyncio_coroutine_decorator():
++    # -- USE: @asyncio.coroutine decorator
++    # SINCE: Python 3.4, deprecated since Python 3.8, removed in Python 3.10
+     @asyncio.coroutine
+     def async_func(param):
+         yield from asyncio.sleep(0.2)
+diff --git a/examples/async_step/features/steps/async_steps.py b/examples/async_step/features/steps/async_steps.py
+index dc03c72..33d2392 100644
+--- a/examples/async_step/features/steps/async_steps.py
++++ b/examples/async_step/features/steps/async_steps.py
+@@ -5,8 +5,8 @@
+ from __future__ import absolute_import
+ import sys
+ 
+-python_version = "%s.%s" % sys.version_info[:2]
+-if python_version >= "3.5":
++python_version = sys.version_info[:2]
++if python_version >= (3, 5):
+     import _async_steps35
+-elif python_version == "3.4":
++elif python_version == (3, 4):
+     import _async_steps34
+diff --git a/features/environment.py b/features/environment.py
+index 3769ee4..6faf4e2 100644
+--- a/features/environment.py
++++ b/features/environment.py
+@@ -4,22 +4,19 @@
+ from __future__ import absolute_import, print_function
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
++from behave import python_feature
+ import platform
+ import sys
+-import six
++
+ 
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+-python_version = "%s.%s" % sys.version_info[:2]
+ active_tag_value_provider = {
+-    "python2": str(six.PY2).lower(),
+-    "python3": str(six.PY3).lower(),
+-    "python.version": python_version,
+     # -- python.implementation: cpython, pypy, jython, ironpython
+     "python.implementation": platform.python_implementation().lower(),
+     "pypy":    str("__pypy__" in sys.modules).lower(),
+-    "os":      sys.platform,
+ }
++active_tag_value_provider.update(python_feature.ACTIVE_TAG_VALUE_PROVIDER)
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+@@ -27,7 +24,7 @@ def print_active_tags_summary():
+     active_tag_data = active_tag_value_provider
+     print("ACTIVE-TAG SUMMARY:")
+     print("use.with_python.version=%s" % active_tag_data.get("python.version"))
+-    # print("use.with_os=%s" % active_tag_data.get("os"))
++    print("use.with_os=%s" % active_tag_data.get("os"))
+     print()
+ 
+ 
+@@ -53,6 +50,7 @@ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ # -----------------------------------------------------------------------------
+ # SPECIFIC FUNCTIONALITY:
+ # -----------------------------------------------------------------------------
+diff --git a/features/step.async_steps.feature b/features/step.async_steps.feature
+index 06709d9..5919397 100644
+--- a/features/step.async_steps.feature
++++ b/features/step.async_steps.feature
+@@ -1,4 +1,5 @@
+ @not.with_python2=true
++@use.with_python_has_coroutine=true
+ Feature: Async-Test Support (async-step, ...)
+ 
+   As a test writer and step provider
+@@ -16,11 +17,11 @@ Feature: Async-Test Support (async-step, ...)
+   .    * an async-function as coroutine using async/await keywords (Python 3.5)
+   .    * an async-function tagged with @asyncio.coroutine and using "yield from"
+   .
+-  .  # -- EXAMPLE CASE 1 (since Python 3.5):
++  .  # -- EXAMPLE CASE 1 (since Python 3.5; preferred):
+   .  async def coroutine1(duration):
+   .      await asyncio.sleep(duration)
+   .
+-  .  # -- EXAMPLE CASE 2 (since Python 3.4):
++  .  # -- EXAMPLE CASE 2 (since Python 3.4; deprecated since Python 3.8; removed in Python 3.10):
+   .  @asyncio.coroutine
+   .  def coroutine2(duration):
+   .      yield from asyncio.sleep(duration)
+@@ -30,12 +31,8 @@ Feature: Async-Test Support (async-step, ...)
+   .   The async-step can directly interact with other async-functions.
+ 
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use async-step with @async_run_until_complete (async)
++    @use.with_python_has_async_function=true
++    Scenario: Use async-step with @async_run_until_complete (async; requires: py.version >= 3.5)
+       Given a new working directory
+       And a file named "features/steps/async_steps35.py" with:
+         """
+@@ -63,13 +60,8 @@ Feature: Async-Test Support (async-step, ...)
+         """
+ 
+ 
+-    @use.with_python.version=3.4
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use async-step with @async_run_until_complete (@coroutine)
++    @use.with_python_has_asyncio.coroutine_decorator=true
++    Scenario: Use async-step with @async_run_until_complete (@asyncio.coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps34.py" with:
+         """
+@@ -97,12 +89,8 @@ Feature: Async-Test Support (async-step, ...)
+              Given an async-step waits 0.3 seconds ... passed in 0.3
+         """
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (async)
++    @use.with_python_has_async_function=true
++    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (async-function)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout35.py" with:
+         """
+@@ -135,13 +123,9 @@ Feature: Async-Test Support (async-step, ...)
+         Assertion Failed: TIMEOUT-OCCURED: timeout=0.1
+         """
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
++    @use.with_python_has_async_function=true
+     @async_step_fails
+-    Scenario: Use @async_run_until_complete and async-step fails
++    Scenario: Use @async_run_until_complete and async-step fails (async-function)
+       Given a new working directory
+       And a file named "features/steps/async_steps_fails35.py" with:
+         """
+@@ -180,13 +164,9 @@ Feature: Async-Test Support (async-step, ...)
+         Assertion Failed: XFAIL in async-step
+         """
+ 
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
++    @use.with_python_has_async_function=true
+     @async_step_fails
+-    Scenario: Use @async_run_until_complete and async-step raises error
++    Scenario: Use @async_run_until_complete and async-step raises error (async-function)
+       Given a new working directory
+       And a file named "features/steps/async_steps_exception35.py" with:
+         """
+@@ -225,13 +205,8 @@ Feature: Async-Test Support (async-step, ...)
+         raise RuntimeError("XFAIL in async-step")
+         """
+ 
+-    @use.with_python.version=3.4
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (@coroutine)
++    @use.with_python_has_asyncio.coroutine_decorator=true
++    Scenario: Use @async_run_until_complete(timeout=...) and TIMEOUT occurs (@asyncio.coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_steps_timeout34.py" with:
+         """
+@@ -265,13 +240,8 @@ Feature: Async-Test Support (async-step, ...)
+         Assertion Failed: TIMEOUT-OCCURED: timeout=0.2
+         """
+ 
+-    @use.with_python.version=3.4
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
+-    Scenario: Use async-dispatch and async-collect concepts
++    @use.with_python_has_asyncio.coroutine_decorator=true
++    Scenario: Use async-dispatch and async-collect concepts (@asyncio.coroutine)
+       Given a new working directory
+       And a file named "features/steps/async_dispatch_steps.py" with:
+         """
+diff --git a/issue.features/issue0330.feature b/issue.features/issue0330.feature
+index be4d378..56ac238 100644
+--- a/issue.features/issue0330.feature
++++ b/issue.features/issue0330.feature
+@@ -72,7 +72,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @not.with_python.version=3.8
+   @not.with_python.version=3.9
+-  Scenario: Junit report for skipped feature is created with --show-skipped
++  @not.with_python.version=3.10
++  Scenario: Junit report for skipped feature is created with --show-skipped (py.version < 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+       """
+@@ -87,7 +88,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @use.with_python.version=3.8
+   @use.with_python.version=3.9
+-  Scenario: Junit report for skipped feature is created with --show-skipped
++  @use.with_python.version=3.10
++  Scenario: Junit report for skipped feature is created with --show-skipped (py.version >= 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped @alice_and_bob.featureset"
+     Then it should pass with:
+       """
+@@ -104,7 +106,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @not.with_python.version=3.8
+   @not.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
++  @not.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped (py.version < 3.8)
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+       """
+@@ -125,7 +128,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @use.with_python.version=3.8
+   @use.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped
++  @use.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is neither shown nor counted with --no-skipped (py.version >= 3.8)
+     When I run "behave --junit -t @tag1 --no-skipped"
+     Then it should pass with:
+       """
+@@ -149,7 +153,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @not.with_python.version=3.8
+   @not.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
++  @not.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped (py.version < 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+       """
+@@ -171,7 +176,8 @@ Feature: Issue #330: Skipped scenarios are included in junit reports when --no-s
+ 
+   @use.with_python.version=3.8
+   @use.with_python.version=3.9
+-  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped
++  @use.with_python.version=3.10
++  Scenario: Junit report for skipped scenario is shown and counted with --show-skipped (py.version >= 3.8)
+     When I run "behave --junit -t @tag1 --show-skipped"
+     Then it should pass with:
+       """
+diff --git a/issue.features/issue0446.feature b/issue.features/issue0446.feature
+index 12de37a..d7db764 100644
+--- a/issue.features/issue0446.feature
++++ b/issue.features/issue0446.feature
+@@ -60,7 +60,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Hook error in before_scenario()
++    @not.with_python.version=3.10
++    Scenario: Hook error in before_scenario() (py.version < 3.8)
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+         """
+@@ -90,7 +91,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Hook error in before_scenario()
++    @use.with_python.version=3.10
++    Scenario: Hook error in before_scenario() (py.version >= 3.8)
+       When I run "behave -f plain --junit features/before_scenario_failure.feature"
+       Then it should fail with:
+         """
+@@ -124,7 +126,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Hook error in after_scenario()
++    @not.with_python.version=3.10
++    Scenario: Hook error in after_scenario() (py.version < 3.8)
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+         """
+@@ -156,7 +159,8 @@ Feature: Issue #446 -- Support scenario hook-errors with JUnitReporter
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Hook error in after_scenario()
++    @use.with_python.version=3.10
++    Scenario: Hook error in after_scenario() (py.version >= 3.8)
+       When I run "behave -f plain --junit features/after_scenario_failure.feature"
+       Then it should fail with:
+         """
+diff --git a/issue.features/issue0457.feature b/issue.features/issue0457.feature
+index 6d2f48f..c14c7a4 100644
+--- a/issue.features/issue0457.feature
++++ b/issue.features/issue0457.feature
+@@ -26,7 +26,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Use failing assertation in a JUnit XML report
++    @not.with_python.version=3.10
++    Scenario: Use failing assertation in a JUnit XML report (py.version < 3.8)
+       Given a file named "features/fails1.feature" with:
+         """
+         Feature:
+@@ -48,7 +49,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Use failing assertation in a JUnit XML report
++    @use.with_python.version=3.10
++    Scenario: Use failing assertation in a JUnit XML report (py.version >= 3.8)
+       Given a file named "features/fails1.feature" with:
+         """
+         Feature:
+@@ -73,7 +75,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @not.with_python.version=3.8
+     @not.with_python.version=3.9
+-    Scenario: Use exception in a JUnit XML report
++    @not.with_python.version=3.10
++    Scenario: Use exception in a JUnit XML report (py.version < 3.8)
+       Given a file named "features/fails2.feature" with:
+         """
+         Feature:
+@@ -96,7 +99,8 @@ Feature: Issue #457 -- Double-quotes in error messages of JUnit XML reports
+ 
+     @use.with_python.version=3.8
+     @use.with_python.version=3.9
+-    Scenario: Use exception in a JUnit XML report
++    @use.with_python.version=3.10
++    Scenario: Use exception in a JUnit XML report (py.version >= 3.8)
+       Given a file named "features/fails2.feature" with:
+         """
+         Feature:
+diff --git a/issue.features/issue0657.feature b/issue.features/issue0657.feature
+index aeaefd2..a674a26 100644
+--- a/issue.features/issue0657.feature
++++ b/issue.features/issue0657.feature
+@@ -1,15 +1,10 @@
+-@not.with_python2=true
+ @issue
++@not.with_python2=true
+ Feature: Issue #657 -- Allow async steps with timeouts to fail when they raise exceptions
+ 
+-
+-    @use.with_python.version=3.5
+-    @use.with_python.version=3.6
+-    @use.with_python.version=3.7
+-    @use.with_python.version=3.8
+-    @use.with_python.version=3.9
++    @use.with_python_has_async_function=true
+     @async_step_fails
+-    Scenario: Use @async_run_until_complete and async-step fails
++    Scenario: Use @async_run_until_complete and async-step fails (py.version >= 3.8)
+       Given a new working directory
+       And a file named "features/steps/async_steps_fails35.py" with:
+         """
+diff --git a/more.features/environment.py b/more.features/environment.py
+index 9d4302b..14d904c 100644
+--- a/more.features/environment.py
++++ b/more.features/environment.py
+@@ -1,16 +1,14 @@
+ # -*- coding: UTF-8 -*-
+ 
+ from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
+-import sys
++from behave import python_feature
+ 
+ # -- MATCHES ANY TAGS: @use.with_{category}={value}
+ # NOTE: active_tag_value_provider provides category values for active tags.
+-python_version = "%s.%s" % sys.version_info[:2]
+-active_tag_value_provider = {
+-    "python.version": python_version,
+-}
++active_tag_value_provider = python_feature.ACTIVE_TAG_VALUE_PROVIDER.copy()
+ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
++
+ # -----------------------------------------------------------------------------
+ # HOOKS:
+ # -----------------------------------------------------------------------------
+@@ -18,10 +16,12 @@ def before_all(context):
+     # -- SETUP ACTIVE-TAG MATCHER (with userdata):
+     setup_active_tag_values(active_tag_value_provider, context.config.userdata)
+ 
++
+ def before_feature(context, feature):
+     if active_tag_matcher.should_exclude_with(feature.tags):
+         feature.skip(reason=active_tag_matcher.exclude_reason)
+ 
++
+ def before_scenario(context, scenario):
+     if active_tag_matcher.should_exclude_with(scenario.effective_tags):
+         scenario.skip(reason=active_tag_matcher.exclude_reason)
+diff --git a/more.features/run_examples.feature b/more.features/run_examples.feature
+index 4778866..14acf98 100644
+--- a/more.features/run_examples.feature
++++ b/more.features/run_examples.feature
+@@ -29,13 +29,8 @@ Feature: Ensure that all examples are usable
+         features/rule_fails.feature:16  F2 -- Fails
+       """
+ 
+-
+-  @use.with_python.version=3.4
+-  @use.with_python.version=3.5
+-  @use.with_python.version=3.6
+-  @use.with_python.version=3.7
+-  @use.with_python.version=3.8
+-  Scenario: examples/async_step (needs: py34 or newer)
++  @use.with_python_has_coroutine=true
++  Scenario: examples/async_step (requires: python.version >= 3.4)
+     Given I use the directory "examples/async_step" as working directory
+     When I run "behave features/"
+     Then it should pass
diff --git a/meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch b/meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch
new file mode 100644
index 000000000..d8ecc09ac
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0112-docs-Update-new-and-noteworthy.patch
@@ -0,0 +1,84 @@
+From d38703153f7df501ceb48395f756b2427ee15e57 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sat, 9 Jan 2021 23:48:52 +0100
+Subject: [PATCH] docs: Update new and noteworthy
+
+* Add section on improved active-tag logic
+---
+ docs/conf.py                       |  2 +-
+ docs/new_and_noteworthy_v1.2.7.rst | 45 ++++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/docs/conf.py b/docs/conf.py
+index 1579a36..cece86a 100644
+--- a/docs/conf.py
++++ b/docs/conf.py
+@@ -108,7 +108,7 @@ if USE_SPHINX_INTERNATIONAL:
+ # -----------------------------------------------------------------------------
+ project = u"behave"
+ authors = u"Jens Engel, Benno Rice and Richard Jones"
+-copyright = u"2012-2020, %s" % authors
++copyright = u"2012-2021, %s" % authors
+ 
+ # The version info for the project you're documenting, acts as replacement for
+ # |version| and |release|, also used in various other places throughout the
+diff --git a/docs/new_and_noteworthy_v1.2.7.rst b/docs/new_and_noteworthy_v1.2.7.rst
+index b7242f7..2eb94ad 100644
+--- a/docs/new_and_noteworthy_v1.2.7.rst
++++ b/docs/new_and_noteworthy_v1.2.7.rst
+@@ -9,6 +9,7 @@ Summary:
+   to match partial tag names, like: ``@foo.*``
+ * `Select-by-location for Scenario Containers`_ (Feature, Rule, ScenarioOutline)
+ * `Support for emojis in feature files and steps`_
++* `Improve Active-Tags Logic`_
+ 
+ .. _`Example Mapping`: https://cucumber.io/blog/example-mapping-introduction/
+ .. _`Example Mapping Webinar`: https://cucumber.io/blog/example-mapping-webinar/
+@@ -152,3 +153,47 @@ Support for Emojis in Feature Files and Steps
+ .. literalinclude:: ../features/steps/i18n_emoji_steps.py
+     :prepend:  # -- FILE: features/steps/i18n_emoji_steps.py
+     :language: python
++
++
++Improve Active-Tags Logic
++-------------------------------------------------------------------------------
++
++The active-tag computation logic was slightly changed (and fixed):
++
++* if multiple active-tags with same category are used
++* combination of positive active-tags (``use.with_{category}={value}``) and
++  negative active-tags (``not.with_{category}={value}``) with same category
++  are now supported
++
++All active-tags with same category are combined into one category tag-group.
++The following logical expression is used for active-tags with the same category::
++
++    category_tag_group.enabled := positive-tag-expression and not negative-tag-expression
++      positive-tag-expression  := enabled(tag1) or enabled(tag2) or ...
++      negative-tag-expression  := enabled(tag3) or enabled(tag4) or ...
++       tag1, tag2 are positive-tags, like @use.with_category=value
++       tag3, tag4 are negative-tags, like @not.with_category=value
++
++
++EXAMPLE:
++
++.. code-block:: gherkin
++
++    Feature: Active-Tag Example
++
++      @use.with_browser=Safari
++      @use.with_browser=Chrome
++      @not.with_browser=Firefox
++      Scenario: Use one active-tag group/category
++
++        HINT: Only executed with web browser Safari and Chrome, Firefox is explicitly excluded.
++        ...
++
++      @use.with_browser=Firefox
++      @use.with_os=linux
++      @use.with_os=darwin
++      Scenario: Use two active-tag groups/categories
++
++        HINT 1: Only executed with browser: Firefox
++        HINT 2: Only executed on OS: Linux and Darwin (macOS)
++        ...
diff --git a/meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch b/meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch
new file mode 100644
index 000000000..83b6b982e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0113-Add-diagnostic-helper-function-to-print-the-current-.patch
@@ -0,0 +1,278 @@
+From 18261d6c2dfd563ac542eb69d12a8ad648575c67 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 10 Jan 2021 13:40:26 +0100
+Subject: [PATCH] * Add diagnostic helper function to print the current values
+ of active-tags. * Add helper classes for active-tag value providers.
+
+---
+ behave/compat/collections.py  |  25 ++++++
+ behave/tag_matcher.py         | 145 +++++++++++++++++++++++++++++++---
+ features/environment.py       |   9 +--
+ issue.features/environment.py |   9 +--
+ 4 files changed, 166 insertions(+), 22 deletions(-)
+
+diff --git a/behave/compat/collections.py b/behave/compat/collections.py
+index 00444f4..f4eea2c 100644
+--- a/behave/compat/collections.py
++++ b/behave/compat/collections.py
+@@ -18,3 +18,28 @@ except ImportError:     # pragma: no cover
+         warnings.warn(message)
+         # -- BACKWARD-COMPATIBLE: Better than nothing (for behave use case).
+         OrderedDict = dict
++
++try:
++    from collections import UserDict
++except ImportError:      # pragma: no cover
++    class UserDict(object):
++        """Emulate collections.UserDict class in python3."""
++        def __init__(self, data=None):
++            if data is None:
++                data = {}
++            self.data = data
++
++        def __len__(self):
++            return len(self.data)
++
++        def __iter__(self):
++            return len(self.data)
++
++        def keys(self):
++            return self.data.keys()
++
++        def values(self):
++            return self.data.values()
++
++        def items(self):
++            return self.data.items()
+diff --git a/behave/tag_matcher.py b/behave/tag_matcher.py
+index e2b1e82..78d7061 100644
+--- a/behave/tag_matcher.py
++++ b/behave/tag_matcher.py
+@@ -4,17 +4,16 @@ Contains classes and functionality to provide the active-tag mechanism.
+ Active-tags provide a skip-if logic based on tags in feature files.
+ """
+ 
+-from __future__ import absolute_import
++from __future__ import absolute_import, print_function
+ import re
+-import operator
+ import six
++from ._types import Unknown
++from .compat.collections import UserDict
+ 
+ 
+-def bool_to_string(value):
+-    """Converts a Boolean value into its normalized string representation."""
+-    return str(bool(value)).lower()
+-
+-
++# -----------------------------------------------------------------------------
++# CLASSES FOR: Active-Tags and ActiveTagMatchers
++# -----------------------------------------------------------------------------
+ class TagMatcher(object):
+     """Abstract base class that defines the TagMatcher protocol."""
+ 
+@@ -220,8 +219,8 @@ class ActiveTagMatcher(TagMatcher):
+             # -- CASE: Empty group is always enabled (CORNER-CASE).
+             return True
+ 
+-        current_value = self.value_provider.get(group_category, None)
+-        if current_value is None and self.ignore_unknown_categories:
++        current_value = self.value_provider.get(group_category, Unknown)
++        if current_value is Unknown and self.ignore_unknown_categories:
+             # -- CASE: Unknown category, ignore it.
+             return True
+ 
+@@ -320,6 +319,115 @@ class CompositeTagMatcher(TagMatcher):
+         return False
+ 
+ 
++# -----------------------------------------------------------------------------
++# ACTIVE TAG VALUE PROVIDER CLASSES:
++# -----------------------------------------------------------------------------
++class IActiveTagValueProvider(object):
++    """Protocol/Interface for active-tag value providers."""
++
++    def get(self, category, default=None):
++        return NotImplemented
++
++
++class ActiveTagValueProvider(UserDict):
++    def __init__(self, data=None):
++        if data is None:
++            data = {}
++        UserDict.__init__(self, data)
++
++    @staticmethod
++    def use_value(value):
++        if callable(value):
++            # -- RE-EVALUATE VALUE: Each time
++            value_func = value
++            value = value_func()
++        return value
++
++    def __getitem__(self, name):
++        value = self.data[name]
++        return self.use_value(value)
++
++    def get(self, category, default=None):
++        value = self.data.get(category, default)
++        return self.use_value(value)
++
++    def values(self):
++        for value in self.data.values(self):
++            yield self.use_value(value)
++
++    def items(self):
++        for category, value in self.data.items():
++            yield (category, self.use_value(value))
++
++    def categories(self):
++        return self.keys()
++
++
++class CompositeActiveTagValueProvider(ActiveTagValueProvider):
++    """Provides a composite helper class to resolve active-tag values
++    from a list of value-providers.
++    """
++
++    def __init__(self, value_providers=None):
++        if value_providers is None:
++            value_providers = []
++        super(CompositeActiveTagValueProvider, self).__init__()
++        self.value_providers = list(value_providers)
++
++    def get(self, category, default=None):
++        # -- FIRST: Check category cached-map (=self.data)
++        value = self.data.get(category, Unknown)
++        if value is Unknown:
++            # -- NOT DISCOVERED: Search over value_providers.
++            for value_provider in self.value_providers:
++                value = value_provider.get(category, Unknown)
++                if value is Unknown:
++                    continue
++
++                # -- FOUND CATEGORY:
++                self.data[category] = value
++                break
++            # -- FOUND-CATEGORY or NOT-FOUND:
++            if value is Unknown:
++                value = default
++
++        return self.use_value(value)
++
++    # -- MORE: Provide a dict-like interface.
++    def keys(self):
++        for value_provider in self.value_providers:
++            try:
++                for category in value_provider.keys():
++                    yield category
++            except AttributeError:
++                # -- keys() method not supported.
++                pass
++
++    def values(self):
++        for category in self.keys():
++            value = self.get(category)
++            yield value
++
++    def items(self):
++        for category in self.keys():
++            value = self.get(category)
++            yield (category, value)
++
++
++
++# -----------------------------------------------------------------------------
++# UTILITY FUNCTIONS:
++# -----------------------------------------------------------------------------
++def bool_to_string(value):
++    """Converts a boolean active-tag value into its normalized
++    string representation.
++
++    :param value:  Boolean value to use (or value converted into bool).
++    :returns: Boolean value converted into a normalized string.
++    """
++    return str(bool(value)).lower()
++
++
+ def setup_active_tag_values(active_tag_values, data):
+     """Setup/update active_tag values with dict-like data.
+     Only values for keys that are already present are updated.
+@@ -330,3 +438,22 @@ def setup_active_tag_values(active_tag_values, data):
+     for category in list(active_tag_values.keys()):
+         if category in data:
+             active_tag_values[category] = data[category]
++
++
++def print_active_tags(active_tag_value_provider, categories=None):
++    """Print a summary of the current active-tag values."""
++    if categories is None:
++        try:
++            categories = list(active_tag_value_provider)
++        except TypeError:   # TypeError: object is not iterable
++            categories = []
++
++    active_tag_data = active_tag_value_provider
++    print("ACTIVE-TAGS:")
++    for category in categories:
++        active_tag_value = active_tag_data.get(category)
++        print("use.with_{category}={value}".format(
++            category=category, value=active_tag_value))
++
++    # -- FINALLY: TRAILING NEW-LINE
++    print()
+diff --git a/features/environment.py b/features/environment.py
+index 6faf4e2..72ebaa0 100644
+--- a/features/environment.py
++++ b/features/environment.py
+@@ -2,7 +2,8 @@
+ # FILE: features/environemnt.py
+ 
+ from __future__ import absolute_import, print_function
+-from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
++from behave.tag_matcher import \
++    ActiveTagMatcher, setup_active_tag_values, print_active_tags
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+ from behave import python_feature
+ import platform
+@@ -21,11 +22,7 @@ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+ def print_active_tags_summary():
+-    active_tag_data = active_tag_value_provider
+-    print("ACTIVE-TAG SUMMARY:")
+-    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
+-    print("use.with_os=%s" % active_tag_data.get("os"))
+-    print()
++    print_active_tags(active_tag_value_provider, ["python.version", "os"])
+ 
+ 
+ # -----------------------------------------------------------------------------
+diff --git a/issue.features/environment.py b/issue.features/environment.py
+index 7e48ee0..ab85e6c 100644
+--- a/issue.features/environment.py
++++ b/issue.features/environment.py
+@@ -13,7 +13,7 @@ import sys
+ import platform
+ import os.path
+ import six
+-from behave.tag_matcher import ActiveTagMatcher
++from behave.tag_matcher import ActiveTagMatcher, print_active_tags
+ from behave4cmd0.setup_command_shell import setup_command_shell_processors4behave
+ # PREPARED: from behave.tag_matcher import setup_active_tag_values
+ 
+@@ -94,12 +94,7 @@ active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
+ 
+ 
+ def print_active_tags_summary():
+-    active_tag_data = active_tag_value_provider
+-    print("ACTIVE-TAG SUMMARY:")
+-    print("use.with_python.version=%s" % active_tag_data.get("python.version"))
+-    # print("use.with_platform=%s" % active_tag_data.get("platform"))
+-    # print("use.with_os=%s" % active_tag_data.get("os"))
+-    print()
++    print_active_tags(active_tag_value_provider, ["python.version", "os"])
+ 
+ 
+ # ---------------------------------------------------------------------------
diff --git a/meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch b/meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch
new file mode 100644
index 000000000..9d370c299
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch
@@ -0,0 +1,541 @@
+From 715079cc08a7672d51c376a9d884873469ffa009 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 12 Jan 2021 13:21:44 +0100
+Subject: [PATCH] UPDATE: i18n/gherkin-languages.json from cucumber repository.
+
+CONTAINS: PR #827 (Estonian language updates contained)
+LAST COMMIT: 2021-01-07 (in Cucumber repository)
+LANGUAGE CHANGES:
+
+* Swedish: Rule keyword
+* Telugu: Fixing ISO 639-1 code
+* Russian: Rule keyword
+* Hebrew: Rule keyword
+* German: Addition keywords
+* Estonian: Rule keyword, ScenarioOutline keyword
+* Indonesian: Given keywords, whitespace
+---
+ behave/i18n.py                     |  92 ++++++++++++------
+ etc/gherkin/gherkin-languages.json | 145 +++++++++++++++++++++++++----
+ features/cmdline.lang_list.feature |  64 +++++++++----
+ issue.features/issue0309.feature   |   2 +-
+ 4 files changed, 240 insertions(+), 63 deletions(-)
+
+diff --git a/behave/i18n.py b/behave/i18n.py
+index 2781afe..a572626 100644
+--- a/behave/i18n.py
++++ b/behave/i18n.py
+@@ -188,16 +188,19 @@ languages = \
+         'then': ['* ', 'Så '],
+         'when': ['* ', 'Når ']},
+  'de': {'and': ['* ', 'Und '],
+-        'background': ['Grundlage'],
++        'background': ['Grundlage',
++                       'Hintergrund',
++                       'Voraussetzungen',
++                       'Vorbedingungen'],
+         'but': ['* ', 'Aber '],
+         'examples': ['Beispiele'],
+-        'feature': ['Funktionalität'],
++        'feature': ['Funktionalität', 'Funktion'],
+         'given': ['* ', 'Angenommen ', 'Gegeben sei ', 'Gegeben seien '],
+         'name': 'German',
+         'native': 'Deutsch',
+-        'rule': ['Rule'],
++        'rule': ['Rule', 'Regel'],
+         'scenario': ['Beispiel', 'Szenario'],
+-        'scenario_outline': ['Szenariogrundriss'],
++        'scenario_outline': ['Szenariogrundriss', 'Szenarien'],
+         'then': ['* ', 'Dann '],
+         'when': ['* ', 'Wenn ']},
+  'el': {'and': ['* ', 'Και '],
+@@ -344,9 +347,9 @@ languages = \
+         'given': ['* ', 'Eeldades '],
+         'name': 'Estonian',
+         'native': 'eesti keel',
+-        'rule': ['Rule'],
++        'rule': ['Reegel'],
+         'scenario': ['Juhtum', 'Stsenaarium'],
+-        'scenario_outline': ['Raamstjuhtum', 'Raamstsenaarium'],
++        'scenario_outline': ['Raamjuhtum', 'Raamstsenaarium'],
+         'then': ['* ', 'Siis '],
+         'when': ['* ', 'Kui ']},
+  'fa': {'and': ['* ', 'و '],
+@@ -455,7 +458,7 @@ languages = \
+         'given': ['* ', 'בהינתן '],
+         'name': 'Hebrew',
+         'native': 'עברית',
+-        'rule': ['Rule'],
++        'rule': ['כלל'],
+         'scenario': ['דוגמא', 'תרחיש'],
+         'scenario_outline': ['תבנית תרחיש'],
+         'then': ['* ', 'אז ', 'אזי '],
+@@ -518,17 +521,22 @@ languages = \
+         'then': ['* ', 'Akkor '],
+         'when': ['* ', 'Majd ', 'Ha ', 'Amikor ']},
+  'id': {'and': ['* ', 'Dan '],
+-        'background': ['Dasar'],
+-        'but': ['* ', 'Tapi '],
+-        'examples': ['Contoh'],
++        'background': ['Dasar', 'Latar Belakang'],
++        'but': ['* ', 'Tapi ', 'Tetapi '],
++        'examples': ['Contoh', 'Misal'],
+         'feature': ['Fitur'],
+-        'given': ['* ', 'Dengan '],
++        'given': ['* ',
++                  'Dengan ',
++                  'Diketahui ',
++                  'Diasumsikan ',
++                  'Bila ',
++                  'Jika '],
+         'name': 'Indonesian',
+         'native': 'Bahasa Indonesia',
+-        'rule': ['Rule'],
++        'rule': ['Rule', 'Aturan'],
+         'scenario': ['Skenario'],
+-        'scenario_outline': ['Skenario konsep'],
+-        'then': ['* ', 'Maka '],
++        'scenario_outline': ['Skenario konsep', 'Garis-Besar Skenario'],
++        'then': ['* ', 'Maka ', 'Kemudian '],
+         'when': ['* ', 'Ketika ']},
+  'is': {'and': ['* ', 'Og '],
+         'background': ['Bakgrunnur'],
+@@ -699,6 +707,32 @@ languages = \
+         'scenario_outline': ['Сценарын төлөвлөгөө'],
+         'then': ['* ', 'Тэгэхэд ', 'Үүний дараа '],
+         'when': ['* ', 'Хэрэв ']},
++ 'mr': {'and': ['* ', 'आणि ', 'तसेच '],
++        'background': ['पार्श्वभूमी'],
++        'but': ['* ', 'पण ', 'परंतु '],
++        'examples': ['उदाहरण'],
++        'feature': ['वैशिष्ट्य', 'सुविधा'],
++        'given': ['* ', 'जर', 'दिलेल्या प्रमाणे '],
++        'name': 'Marathi',
++        'native': 'मराठी',
++        'rule': ['नियम'],
++        'scenario': ['परिदृश्य'],
++        'scenario_outline': ['परिदृश्य रूपरेखा'],
++        'then': ['* ', 'मग ', 'तेव्हा '],
++        'when': ['* ', 'जेव्हा ']},
++ 'ne': {'and': ['* ', 'र ', 'अनी '],
++        'background': ['पृष्ठभूमी'],
++        'but': ['* ', 'तर '],
++        'examples': ['उदाहरण', 'उदाहरणहरु'],
++        'feature': ['सुविधा', 'विशेषता'],
++        'given': ['* ', 'दिइएको ', 'दिएको ', 'यदि '],
++        'name': 'Nepali',
++        'native': 'नेपाली',
++        'rule': ['नियम'],
++        'scenario': ['परिदृश्य'],
++        'scenario_outline': ['परिदृश्य रूपरेखा'],
++        'then': ['* ', 'त्यसपछि ', 'अनी '],
++        'when': ['* ', 'जब ']},
+  'nl': {'and': ['* ', 'En '],
+         'background': ['Achtergrond'],
+         'but': ['* ', 'Maar '],
+@@ -797,7 +831,7 @@ languages = \
+         'given': ['* ', 'Допустим ', 'Дано ', 'Пусть '],
+         'name': 'Russian',
+         'native': 'русский',
+-        'rule': ['Rule'],
++        'rule': ['Правило'],
+         'scenario': ['Пример', 'Сценарий'],
+         'scenario_outline': ['Структура сценария'],
+         'then': ['* ', 'То ', 'Затем ', 'Тогда '],
+@@ -873,7 +907,7 @@ languages = \
+         'given': ['* ', 'Givet '],
+         'name': 'Swedish',
+         'native': 'Svenska',
+-        'rule': ['Rule'],
++        'rule': ['Regel'],
+         'scenario': ['Scenario'],
+         'scenario_outline': ['Abstrakt Scenario', 'Scenariomall'],
+         'then': ['* ', 'Så '],
+@@ -891,6 +925,19 @@ languages = \
+         'scenario_outline': ['காட்சி சுருக்கம்', 'காட்சி வார்ப்புரு'],
+         'then': ['* ', 'அப்பொழுது '],
+         'when': ['* ', 'எப்போது ']},
++ 'te': {'and': ['* ', 'మరియు '],
++        'background': ['నేపథ్యం'],
++        'but': ['* ', 'కాని '],
++        'examples': ['ఉదాహరణలు'],
++        'feature': ['గుణము'],
++        'given': ['* ', 'చెప్పబడినది '],
++        'name': 'Telugu',
++        'native': 'తెలుగు',
++        'rule': ['Rule'],
++        'scenario': ['ఉదాహరణ', 'సన్నివేశం'],
++        'scenario_outline': ['కథనం'],
++        'then': ['* ', 'అప్పుడు '],
++        'when': ['* ', 'ఈ పరిస్థితిలో ']},
+  'th': {'and': ['* ', 'และ '],
+         'background': ['แนวคิด'],
+         'but': ['* ', 'แต่ '],
+@@ -904,19 +951,6 @@ languages = \
+         'scenario_outline': ['สรุปเหตุการณ์', 'โครงสร้างของเหตุการณ์'],
+         'then': ['* ', 'ดังนั้น '],
+         'when': ['* ', 'เมื่อ ']},
+- 'tl': {'and': ['* ', 'మరియు '],
+-        'background': ['నేపథ్యం'],
+-        'but': ['* ', 'కాని '],
+-        'examples': ['ఉదాహరణలు'],
+-        'feature': ['గుణము'],
+-        'given': ['* ', 'చెప్పబడినది '],
+-        'name': 'Telugu',
+-        'native': 'తెలుగు',
+-        'rule': ['Rule'],
+-        'scenario': ['ఉదాహరణ', 'సన్నివేశం'],
+-        'scenario_outline': ['కథనం'],
+-        'then': ['* ', 'అప్పుడు '],
+-        'when': ['* ', 'ఈ పరిస్థితిలో ']},
+  'tlh': {'and': ['* ', "'ej ", 'latlh '],
+          'background': ["mo'"],
+          'but': ['* ', "'ach ", "'a "],
+diff --git a/etc/gherkin/gherkin-languages.json b/etc/gherkin/gherkin-languages.json
+index 29cbca1..6069664 100644
+--- a/etc/gherkin/gherkin-languages.json
++++ b/etc/gherkin/gherkin-languages.json
+@@ -605,7 +605,10 @@
+       "Und "
+     ],
+     "background": [
+-      "Grundlage"
++      "Grundlage",
++      "Hintergrund",
++      "Voraussetzungen",
++      "Vorbedingungen"
+     ],
+     "but": [
+       "* ",
+@@ -615,7 +618,8 @@
+       "Beispiele"
+     ],
+     "feature": [
+-      "Funktionalität"
++      "Funktionalität",
++      "Funktion"
+     ],
+     "given": [
+       "* ",
+@@ -626,14 +630,16 @@
+     "name": "German",
+     "native": "Deutsch",
+     "rule": [
+-      "Rule"
++      "Rule",
++      "Regel"
+     ],
+     "scenario": [
+       "Beispiel",
+       "Szenario"
+     ],
+     "scenarioOutline": [
+-      "Szenariogrundriss"
++      "Szenariogrundriss",
++      "Szenarien"
+     ],
+     "then": [
+       "* ",
+@@ -1127,14 +1133,14 @@
+     "name": "Estonian",
+     "native": "eesti keel",
+     "rule": [
+-      "Rule"
++      "Reegel"
+     ],
+     "scenario": [
+       "Juhtum",
+       "Stsenaarium"
+     ],
+     "scenarioOutline": [
+-      "Raamstjuhtum",
++      "Raamjuhtum",
+       "Raamstsenaarium"
+     ],
+     "then": [
+@@ -1465,7 +1471,7 @@
+     "name": "Hebrew",
+     "native": "עברית",
+     "rule": [
+-      "Rule"
++      "כלל"
+     ],
+     "scenario": [
+       "דוגמא",
+@@ -1692,36 +1698,46 @@
+       "Dan "
+     ],
+     "background": [
+-      "Dasar"
++      "Dasar",
++      "Latar Belakang"
+     ],
+     "but": [
+       "* ",
+-      "Tapi "
++      "Tapi ",
++      "Tetapi "
+     ],
+     "examples": [
+-      "Contoh"
++      "Contoh",
++      "Misal"
+     ],
+     "feature": [
+       "Fitur"
+     ],
+     "given": [
+       "* ",
+-      "Dengan "
++      "Dengan ",
++      "Diketahui ",
++      "Diasumsikan ",
++      "Bila ",
++      "Jika "
+     ],
+     "name": "Indonesian",
+     "native": "Bahasa Indonesia",
+     "rule": [
+-      "Rule"
++      "Rule",
++      "Aturan"
+     ],
+     "scenario": [
+       "Skenario"
+     ],
+     "scenarioOutline": [
+-      "Skenario konsep"
++      "Skenario konsep",
++      "Garis-Besar Skenario"
+     ],
+     "then": [
+       "* ",
+-      "Maka "
++      "Maka ",
++      "Kemudian "
+     ],
+     "when": [
+       "* ",
+@@ -2330,6 +2346,54 @@
+       "Хэрэв "
+     ]
+   },
++  "ne": {
++    "and": [
++      "* ",
++      "र ",
++      "अनी "
++    ],
++    "background": [
++      "पृष्ठभूमी"
++    ],
++    "but": [
++      "* ",
++      "तर "
++    ],
++    "examples": [
++      "उदाहरण",
++      "उदाहरणहरु"
++    ],
++    "feature": [
++      "सुविधा",
++      "विशेषता"
++    ],
++    "given": [
++      "* ",
++      "दिइएको ",
++      "दिएको ",
++      "यदि "
++    ],
++    "name": "Nepali",
++    "native": "नेपाली",
++    "rule": [
++      "नियम"
++    ],
++    "scenario": [
++      "परिदृश्य"
++    ],
++    "scenarioOutline": [
++      "परिदृश्य रूपरेखा"
++    ],
++    "then": [
++      "* ",
++      "त्यसपछि ",
++      "अनी "
++    ],
++    "when": [
++      "* ",
++      "जब "
++    ]
++  },
+   "nl": {
+     "and": [
+       "* ",
+@@ -2665,7 +2729,7 @@
+     "name": "Russian",
+     "native": "русский",
+     "rule": [
+-      "Rule"
++      "Правило"
+     ],
+     "scenario": [
+       "Пример",
+@@ -2933,7 +2997,7 @@
+     "name": "Swedish",
+     "native": "Svenska",
+     "rule": [
+-      "Rule"
++      "Regel"
+     ],
+     "scenario": [
+       "Scenario"
+@@ -3046,7 +3110,7 @@
+       "เมื่อ "
+     ]
+   },
+-  "tl": {
++  "te": {
+     "and": [
+       "* ",
+       "మరియు "
+@@ -3510,5 +3574,52 @@
+       "* ",
+       "當"
+     ]
++  },
++  "mr": {
++    "and": [
++      "* ",
++      "आणि ",
++      "तसेच "
++    ],
++    "background": [
++      "पार्श्वभूमी"
++    ],
++    "but": [
++      "* ",
++      "पण ",
++      "परंतु "
++    ],
++    "examples": [
++      "उदाहरण"
++    ],
++    "feature": [
++      "वैशिष्ट्य",
++      "सुविधा"
++    ],
++    "given": [
++      "* ",
++      "जर",
++      "दिलेल्या प्रमाणे "
++    ],
++    "name": "Marathi",
++    "native": "मराठी",
++    "rule": [
++      "नियम"
++    ],
++    "scenario": [
++      "परिदृश्य"
++    ],
++    "scenarioOutline": [
++      "परिदृश्य रूपरेखा"
++    ],
++    "then": [
++      "* ",
++      "मग ",
++      "तेव्हा "
++    ],
++    "when": [
++      "* ",
++      "जेव्हा "
++    ]
+   }
+ }
+diff --git a/features/cmdline.lang_list.feature b/features/cmdline.lang_list.feature
+index f77e747..20822ec 100644
+--- a/features/cmdline.lang_list.feature
++++ b/features/cmdline.lang_list.feature
+@@ -39,21 +39,53 @@ Feature: Command-line options: Use behave --lang-list
+           fa: فارسی / Persian
+           fi: suomi / Finnish
+           fr: français / French
+-        """
+-    And the command output should contain:
+-        """
+-        sv: Svenska / Swedish
+-        ta: தமிழ் / Tamil
+-        th: ไทย / Thai
+-        tl: తెలుగు / Telugu
+-        tlh: tlhIngan / Klingon
+-        tr: Türkçe / Turkish
+-        tt: Татарча / Tatar
+-        uk: Українська / Ukrainian
+-        ur: اردو / Urdu
+-        uz: Узбекча / Uzbek
+-        vi: Tiếng Việt / Vietnamese
+-        zh-CN: 简体中文 / Chinese simplified
+-        zh-TW: 繁體中文 / Chinese traditional
++          ga: Gaeilge / Irish
++          gj: ગુજરાતી / Gujarati
++          gl: galego / Galician
++          he: עברית / Hebrew
++          hi: हिंदी / Hindi
++          hr: hrvatski / Croatian
++          ht: kreyòl / Creole
++          hu: magyar / Hungarian
++          id: Bahasa Indonesia / Indonesian
++          is: Íslenska / Icelandic
++          it: italiano / Italian
++          ja: 日本語 / Japanese
++          jv: Basa Jawa / Javanese
++          ka: ქართველი / Georgian
++          kn: ಕನ್ನಡ / Kannada
++          ko: 한국어 / Korean
++          lt: lietuvių kalba / Lithuanian
++          lu: Lëtzebuergesch / Luxemburgish
++          lv: latviešu / Latvian
++          mk-Cyrl: Македонски / Macedonian
++          mk-Latn: Makedonski (Latinica) / Macedonian (Latin)
++          mn: монгол / Mongolian
++          mr: मराठी / Marathi
++          ne: नेपाली / Nepali
++          nl: Nederlands / Dutch
++          no: norsk / Norwegian
++          pa: ਪੰਜਾਬੀ / Panjabi
++          pl: polski / Polish
++          pt: português / Portuguese
++          ro: română / Romanian
++          ru: русский / Russian
++          sk: Slovensky / Slovak
++          sl: Slovenski / Slovenian
++          sr-Cyrl: Српски / Serbian
++          sr-Latn: Srpski (Latinica) / Serbian (Latin)
++          sv: Svenska / Swedish
++          ta: தமிழ் / Tamil
++          te: తెలుగు / Telugu
++          th: ไทย / Thai
++          tlh: tlhIngan / Klingon
++          tr: Türkçe / Turkish
++          tt: Татарча / Tatar
++          uk: Українська / Ukrainian
++          ur: اردو / Urdu
++          uz: Узбекча / Uzbek
++          vi: Tiếng Việt / Vietnamese
++          zh-CN: 简体中文 / Chinese simplified
++          zh-TW: 繁體中文 / Chinese traditional
+         """
+     But the command output should not contain "Traceback"
+diff --git a/issue.features/issue0309.feature b/issue.features/issue0309.feature
+index c8a8857..b50e32d 100644
+--- a/issue.features/issue0309.feature
++++ b/issue.features/issue0309.feature
+@@ -52,8 +52,8 @@ Feature: Issue #309 -- behave --lang-list fails on Python3
+         """
+         sv: Svenska / Swedish
+         ta: தமிழ் / Tamil
++        te: తెలుగు / Telugu
+         th: ไทย / Thai
+-        tl: తెలుగు / Telugu
+         tlh: tlhIngan / Klingon
+         tr: Türkçe / Turkish
+         tt: Татарча / Tatar
diff --git a/meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch b/meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch
new file mode 100644
index 000000000..44532ab9b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch
@@ -0,0 +1,22 @@
+From cfbf492ce859c817703e4c986d9ab9dcea30223a Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 12 Jan 2021 13:40:58 +0100
+Subject: [PATCH] UPDATE CHANGES: Related to PR #895 and #827
+
+---
+ CHANGES.rst | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index a3398d8..ff82132 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -28,6 +28,8 @@ ENHANCEMENTS:
+ * Use cucumber "gherkin-languages.json" now (simplify: Gherkin v6 aliases, language usage)
+ * Support emojis in ``*.feature`` files and steps
+ * Select-by-location: Add support for "Scenario container" (Feature, Rule, ScenarioOutline) (related to: #391)
++* pull  #895: UPDATE: i18n/gherkin-languages.json from cucumber repository #895 (related to: #827)
++* pull  #827: Fixed keyword translation in Estonian #827 (provided by: ookull)
+ * issue #740: Enhancement: possibility to add cleanup to be called upon leaving outer context stack frames (submitted by: nizwiz, dcvmoole)
+ * issue #678: Scenario Outline: Support tags with commas and semicolons (provided by: lawnmowerlatte, pull #679)
+ * issue #675: Feature files cannot be found within symlink directories (provided by: smadness, pull #680)
diff --git a/meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch b/meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch
new file mode 100644
index 000000000..78127d14e
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch
@@ -0,0 +1,39 @@
+From ac1d98381de62b900af89aee5127c901fbe82c38 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Tue, 12 Jan 2021 13:51:02 +0100
+Subject: [PATCH] FIX CI-TRAVIS: For python 2.7 builds (mock >= 4.0 only for
+ python.version >= 3.6)
+
+---
+ py.requirements/ci.travis.txt | 3 ++-
+ py.requirements/testing.txt   | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/py.requirements/ci.travis.txt b/py.requirements/ci.travis.txt
+index cbc60c0..1d6e050 100644
+--- a/py.requirements/ci.travis.txt
++++ b/py.requirements/ci.travis.txt
+@@ -6,7 +6,8 @@ pytest <  5.0; python_version <  '3.0'
+ pytest >= 5.0; python_version >= '3.0'
+ 
+ pytest-html >= 1.19.0,<2.0
+-mock  >= 2.0
++mock  <  4.0;   python_version <  '3.6'
++mock  >= 4.0;   python_version >= '3.6'
+ PyHamcrest >= 2.0.2; python_version >= '3.0'
+ PyHamcrest <  2.0;   python_version <  '3.0'
+ 
+diff --git a/py.requirements/testing.txt b/py.requirements/testing.txt
+index fc8fd82..9230c1f 100644
+--- a/py.requirements/testing.txt
++++ b/py.requirements/testing.txt
+@@ -8,7 +8,8 @@ pytest <  5.0; python_version <  '3.0' # pytest >= 4.2
+ pytest >= 5.0; python_version >= '3.0'
+ 
+ pytest-html >= 1.19.0,<2.0
+-mock  >= 2.0
++mock  <  4.0;   python_version <  '3.6'
++mock  >= 4.0;   python_version >= '3.6'
+ PyHamcrest >= 2.0.2; python_version >= '3.0'
+ PyHamcrest <  2.0;   python_version <  '3.0'
+ 
diff --git a/meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch b/meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch
new file mode 100644
index 000000000..17ee076d8
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch
@@ -0,0 +1,126 @@
+From 346aa055cd0cde2cc6a1fe92d874644b06dbdb17 Mon Sep 17 00:00:00 2001
+From: kingbuzzman <buzzi.javier@gmail.com>
+Date: Fri, 19 Jun 2020 09:18:51 -0400
+Subject: [PATCH] Adds the ability to use a custom runner in the behave command
+
+---
+ behave/__main__.py               |  2 +-
+ behave/configuration.py          | 16 ++++++++++++++++
+ docs/behave.rst                  |  5 +++++
+ tests/unit/test_configuration.py | 19 +++++++++++++++++++
+ 4 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/behave/__main__.py b/behave/__main__.py
+index 3cae36d..edb99c4 100644
+--- a/behave/__main__.py
++++ b/behave/__main__.py
+@@ -215,7 +215,7 @@ def main(args=None):
+     :return: 0, if successful. Non-zero, in case of errors/failures.
+     """
+     config = Configuration(args)
+-    return run_behave(config)
++    return run_behave(config, runner_class=config.runner_class)
+ 
+ 
+ if __name__ == "__main__":
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 65e2e3e..04c014a 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -8,6 +8,7 @@ import re
+ import sys
+ import shlex
+ import six
++from importlib import import_module
+ from six.moves import configparser
+ 
+ from behave.model import ScenarioOutline
+@@ -65,6 +66,16 @@ class LogLevel(object):
+ # -----------------------------------------------------------------------------
+ # CONFIGURATION SCHEMA:
+ # -----------------------------------------------------------------------------
++
++def valid_python_module(path):
++    try:
++        module_path, class_name = path.rsplit('.', 1)
++        module = import_module(module_path)
++        return getattr(module, class_name)
++    except (ValueError, AttributeError, ImportError):
++        raise argparse.ArgumentTypeError("No module named '%s' was found." % path)
++
++
+ options = [
+     (("-c", "--no-color"),
+      dict(action="store_false", dest="color",
+@@ -111,6 +122,11 @@ options = [
+      dict(metavar="PATH", dest="junit_directory",
+           default="reports",
+           help="""Directory in which to store JUnit reports.""")),
++    
++    (("--runner-class",),
++     dict(action="store",
++          default="behave.runner.Runner", type=valid_python_module,
++          help="Tells Behave to use a specific runner. (default: %(default)s)")),
+ 
+     ((),  # -- CONFIGFILE only
+      dict(dest="default_format",
+diff --git a/docs/behave.rst b/docs/behave.rst
+index 25ce523..8c1c125 100644
+--- a/docs/behave.rst
++++ b/docs/behave.rst
+@@ -55,6 +55,11 @@ You may see the same information presented below at any time using ``behave
+ 
+     Directory in which to store JUnit reports.
+ 
++.. option:: --runner-class
++
++    This allows you to use your own custom runner. The default is 
++    ``behave.runner.Runner``.
++
+ .. option:: -f, --format
+ 
+     Specify a formatter. If none is specified the default formatter is
+diff --git a/tests/unit/test_configuration.py b/tests/unit/test_configuration.py
+index c96cf63..025a6d0 100644
+--- a/tests/unit/test_configuration.py
++++ b/tests/unit/test_configuration.py
+@@ -5,6 +5,7 @@ import six
+ import pytest
+ from behave import configuration
+ from behave.configuration import Configuration, UserData
++from behave.runner import Runner as BaseRunner
+ from unittest import TestCase
+ 
+ 
+@@ -37,6 +38,10 @@ if sys.platform.startswith("win"):
+     ROOTDIR_PREFIX = os.environ.get("BEHAVE_ROOTDIR_PREFIX", ROOTDIR_PREFIX_DEFAULT)
+ 
+ 
++class CustomTestRunner(BaseRunner):
++    """Custom, dummy runner"""
++
++
+ class TestConfiguration(object):
+ 
+     def test_read_file(self):
+@@ -92,6 +97,20 @@ class TestConfiguration(object):
+         assert "STAGE2_environment.py" == config.environment_file
+         del os.environ["BEHAVE_STAGE"]
+ 
++    def test_settings_runner_class(self, capsys):
++        config = Configuration("")
++        assert BaseRunner == config.runner_class
++
++    def test_settings_runner_class_custom(self, capsys):
++        config = Configuration(["--runner-class=tests.unit.test_configuration.CustomTestRunner"])
++        assert CustomTestRunner == config.runner_class
++
++    def test_settings_runner_class_invalid(self, capsys):
++        with pytest.raises(SystemExit):
++            Configuration(["--runner-class=does.not.exist.Runner"])
++        captured = capsys.readouterr()
++        assert "No module named 'does.not.exist.Runner' was found." in captured.err
++
+ 
+ class TestConfigurationUserData(TestCase):
+     """Test userdata aspects in behave.configuration.Configuration class."""
diff --git a/meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch b/meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch
new file mode 100644
index 000000000..dc39f98db
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0118-Allow-forcing-color-with-color-always.patch
@@ -0,0 +1,59 @@
+From ccccbe478ac05d6093a076f61aaa00d8867b8760 Mon Sep 17 00:00:00 2001
+From: Marc Abramowitz <abramowi@adobe.com>
+Date: Thu, 3 Aug 2017 07:29:38 -0700
+Subject: [PATCH] Allow forcing color with --color=always
+
+even if stdout is not a tty (e.g.: Jenkins)
+---
+ behave/configuration.py    |  7 ++++---
+ behave/formatter/pretty.py | 12 +++++++++---
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 04c014a..1b0bc2b 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -82,9 +82,10 @@ options = [
+           help="Disable the use of ANSI color escapes.")),
+ 
+     (("--color",),
+-     dict(action="store_true", dest="color",
+-          help="""Use ANSI color escapes. This is the default
+-                  behaviour. This switch is used to override a
++     dict(dest="color", choices=["never", "always", "auto"],
++          default="auto", const="auto", nargs="?",
++          help="""Use ANSI color escapes. Defaults to %(const)r.
++                  This switch is used to override a
+                   configuration file setting.""")),
+ 
+     (("-d", "--dry-run"),
+diff --git a/behave/formatter/pretty.py b/behave/formatter/pretty.py
+index 794e1d7..b97438a 100644
+--- a/behave/formatter/pretty.py
++++ b/behave/formatter/pretty.py
+@@ -66,9 +66,7 @@ class PrettyFormatter(Formatter):
+         super(PrettyFormatter, self).__init__(stream_opener, config)
+         # -- ENSURE: Output stream is open.
+         self.stream = self.open()
+-        isatty = getattr(self.stream, "isatty", lambda: True)
+-        stream_supports_colors = isatty()
+-        self.monochrome = not config.color or not stream_supports_colors
++        self.monochrome = self._get_monochrome(config)
+         self.show_source = config.show_source
+         self.show_timings = config.show_timings
+         self.show_multiline = config.show_multiline
+@@ -83,6 +81,14 @@ class PrettyFormatter(Formatter):
+         self.indentations = []
+         self.step_lines = 0
+ 
++    def _get_monochrome(self, config):
++        isatty = getattr(self.stream, "isatty", lambda: True)
++        if config.color == 'always':
++            return False
++        elif config.color == 'never':
++            return True
++        else:
++            return not isatty()
+ 
+     def reset(self):
+         # -- UNUSED: self.tag_statement = None
diff --git a/meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch b/meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch
new file mode 100644
index 000000000..cc4e52676
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0119-Allow-color-with-no-value-followed-by-posarg.patch
@@ -0,0 +1,43 @@
+From 0821f7664961e3dae0d0f6bcf939b1a63ccdaa80 Mon Sep 17 00:00:00 2001
+From: Marc Abramowitz <abramowi@adobe.com>
+Date: Thu, 3 Aug 2017 09:11:22 -0700
+Subject: [PATCH] Allow --color with no value followed by posarg
+
+Allow commands like `--color features/whizbang.feature` to work
+Without this, argparse will treat the positional arg as the value to
+--color and we'd get:
+  argument --color: invalid choice: 'features/whizbang.feature'
+---
+ behave/configuration.py | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 1b0bc2b..0fdfd5e 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -83,7 +83,7 @@ options = [
+ 
+     (("--color",),
+      dict(dest="color", choices=["never", "always", "auto"],
+-          default="auto", const="auto", nargs="?",
++          default=None, const="auto", nargs="?",
+           help="""Use ANSI color escapes. Defaults to %(const)r.
+                   This switch is used to override a
+                   configuration file setting.""")),
+@@ -562,6 +562,16 @@ class Configuration(object):
+             # -- AUTO-DISCOVER: Verbose mode from command-line args.
+             verbose = ("-v" in command_args) or ("--verbose" in command_args)
+ 
++        # Allow commands like `--color features/whizbang.feature` to work
++        # Without this, argparse will treat the positional arg as the value to
++        # --color and we'd get:
++        #   argument --color: invalid choice: 'features/whizbang.feature'
++        #   (choose from 'never', 'always', 'auto')
++        if '--color' in command_args:
++            color_arg_pos = command_args.index('--color')
++            if os.path.exists(command_args[color_arg_pos + 1]):
++                command_args.insert(color_arg_pos + 1, '--')
++
+         self.version = None
+         self.tags_help = None
+         self.lang_list = None
diff --git a/meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch b/meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch
new file mode 100644
index 000000000..63975a42b
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0120-Add-BEHAVE_COLOR-env-var.patch
@@ -0,0 +1,31 @@
+From a59dc80e1a8292e3a465c69e79bd7591ed513eb7 Mon Sep 17 00:00:00 2001
+From: Marc Abramowitz <abramowi@adobe.com>
+Date: Thu, 3 Aug 2017 13:29:55 -0700
+Subject: [PATCH] Add BEHAVE_COLOR env var
+
+---
+ behave/configuration.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/behave/configuration.py b/behave/configuration.py
+index 0fdfd5e..e7d385d 100644
+--- a/behave/configuration.py
++++ b/behave/configuration.py
+@@ -83,7 +83,7 @@ options = [
+ 
+     (("--color",),
+      dict(dest="color", choices=["never", "always", "auto"],
+-          default=None, const="auto", nargs="?",
++          default=os.getenv('BEHAVE_COLOR'), const="auto", nargs="?",
+           help="""Use ANSI color escapes. Defaults to %(const)r.
+                   This switch is used to override a
+                   configuration file setting.""")),
+@@ -507,7 +507,7 @@ class Configuration(object):
+     """Configuration object for behave and behave runners."""
+     # pylint: disable=too-many-instance-attributes
+     defaults = dict(
+-        color=sys.platform != "win32",
++        color='never' if sys.platform == "win32" else os.getenv('BEHAVE_COLOR', 'auto'),
+         show_snippets=True,
+         show_skipped=True,
+         dry_run=False,
diff --git a/meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch b/meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch
new file mode 100644
index 000000000..9c54c8abe
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0121-fix-malformed-table-rows-warning.patch
@@ -0,0 +1,33 @@
+From 8463e94459382e8e21d0b5bd19a23356bc674c28 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pablo=20Dom=C3=ADnguez?=
+ <pablo.dominguezsantana@telefonica.com>
+Date: Thu, 9 Sep 2021 12:19:21 +0200
+Subject: [PATCH] fix: malformed table rows warning
+
+---
+ behave/parser.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/behave/parser.py b/behave/parser.py
+index 58c68be..b71adfe 100644
+--- a/behave/parser.py
++++ b/behave/parser.py
+@@ -41,6 +41,7 @@ Keyword aliases:
+ # pylint: enable=line-too-long
+ 
+ from __future__ import absolute_import, with_statement
++import logging
+ import re
+ import sys
+ import six
+@@ -644,6 +645,10 @@ class Parser(object):
+             self.state = "steps"
+             return self.action_steps(line)
+ 
++        if not re.match(r"^(|.+)\|$", line):
++            logger = logging.getLogger("behave")
++            logger.warning(u"Malformed table row at %s: line %i", self.feature.filename, self.line)
++
+         # -- SUPPORT: Escaped-pipe(s) in Gherkin cell values.
+         #    Search for pipe(s) that are not preceeded with an escape char.
+         cells = [cell.replace("\\|", "|").strip()
diff --git a/meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch b/meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch
new file mode 100644
index 000000000..34886e1f3
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0122-FIX-955-setup-Remove-attribute-use_2to3.patch
@@ -0,0 +1,42 @@
+From e7353c14b2a6b877eb31ebd029c613c91f8b7f11 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Sun, 12 Sep 2021 16:07:32 +0200
+Subject: [PATCH] FIX #955: setup: Remove attribute 'use_2to3'
+
+REASON:
+* This attribute is deprecated since setuptools >= v58.0.2 (2021-09-06).
+* 2to3 conversion should not be needed anymore.
+  Currently, code should run on python2 and python3 (by using six, etc.).
+---
+ setup.py | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/setup.py b/setup.py
+index fd89bda..ba407fd 100644
+--- a/setup.py
++++ b/setup.py
+@@ -118,8 +118,8 @@ setup(
+             "pylint",
+         ],
+     },
+-    # MAYBE-DISABLE: use_2to3
+-    use_2to3= bool(python_version >= 3.0),
++    # DISABLED: use_2to3= bool(python_version >= 3.0),
++    # DEPRECATED SINCE: setuptools v58.0.2 (2021-09-06)
+     license="BSD",
+     classifiers=[
+         "Development Status :: 4 - Beta",
+@@ -129,12 +129,11 @@ setup(
+         "Programming Language :: Python :: 2",
+         "Programming Language :: Python :: 2.7",
+         "Programming Language :: Python :: 3",
+-        "Programming Language :: Python :: 3.3",
+-        "Programming Language :: Python :: 3.4",
+         "Programming Language :: Python :: 3.5",
+         "Programming Language :: Python :: 3.6",
+         "Programming Language :: Python :: 3.7",
+         "Programming Language :: Python :: 3.8",
++        "Programming Language :: Python :: 3.9",
+         "Programming Language :: Python :: Implementation :: CPython",
+         "Programming Language :: Python :: Implementation :: Jython",
+         "Programming Language :: Python :: Implementation :: PyPy",
diff --git a/meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch b/meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch
new file mode 100644
index 000000000..7806d9e9c
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-behave/0123-Add-info-for-fixed-issue-955.patch
@@ -0,0 +1,21 @@
+From c6e1f74e9e670ba789467888bc34d64e71999a24 Mon Sep 17 00:00:00 2001
+From: jenisys <jenisys@users.noreply.github.com>
+Date: Mon, 20 Sep 2021 16:13:59 +0200
+Subject: [PATCH] Add info for fixed issue #955
+
+---
+ CHANGES.rst | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/CHANGES.rst b/CHANGES.rst
+index ff82132..880fd91 100644
+--- a/CHANGES.rst
++++ b/CHANGES.rst
+@@ -42,6 +42,7 @@ FIXED:
+ 
+ * FIXED: Some tests related to python3.9
+ * FIXED: active-tag logic if multiple tags with same category exists.
++* issue #955: setup: Remove attribute 'use_2to3' (submitted by: krisgesling)
+ * issue #772: ScenarioOutline.Examples without table (submitted by: The-QA-Geek)
+ * issue #755: Failures with Python 3.8 (submitted by: hroncok)
+ * issue #725: Scenario Outline description lines seem to be ignored (submitted by: nizwiz)
diff --git a/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb b/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
index 1dcc7d218..745d1e2b2 100644
--- a/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
+++ b/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb
@@ -4,8 +4,131 @@ LICENSE = "BSD-2-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=d950439e8ea6ed233e4288f5e1a49c06"
 
 PV .= "+git${SRCREV}"
-SRCREV = "9520119376046aeff73804b5f1ea05d87a63f370"
-SRC_URI += "git://github.com/behave/behave;branch=master;protocol=https"
+SRCREV = "c0f3faf47ff05f549ec049599eb2f24069b0e51e"
+SRC_URI += "file://0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch \
+           file://0002-UPDATE-FIXED-725.patch \
+           file://0003-ADD-TEST-to-verify-that-issue-725-is-fixed.patch \
+           file://0004-FIX-SummaryReporter-counts-computation-when-Rules-ar.patch \
+           file://0005-SummaryReporter.print_summary-Simplify-if-Rules-are-.patch \
+           file://0006-Formatter-Add-basic-support-output-for-Rules.patch \
+           file://0007-BUMP-VERSION-1.2.7.dev1-was-1.2.7.dev0.patch \
+           file://0008-Correct-examples-and-docstring.patch \
+           file://0009-FIX-feature.run_items-processing-with-Rule-s.patch \
+           file://0010-docs-Disable-sphinx-intl-support-for-READTHEDOCS.patch \
+           file://0011-Cleanup-Dependent-package-versions-in-requirements.patch \
+           file://0012-docs-conf.py-tweaks.patch \
+           file://0013-FIX-Misspelled-after_rule-hook-was-after_after.patch \
+           file://0014-Add-hints-on-Gherkin-v6-grammar-issues.patch \
+           file://0015-README-ReST-tweaks.patch \
+           file://0016-Example-using-Gherkin-v6-grammar.patch \
+           file://0017-PREPARE-Python-3.8-support.patch \
+           file://0018-py3.8-Try-to-fix-logging.Formatter-validate-problem.patch \
+           file://0019-travis.ci-Temporarily-move-py38-dev-to-front-build-f.patch \
+           file://0020-travis.ci-Tweaks-for-faster-builds-temporarily.patch \
+           file://0021-FIX-py3.8-logging.Formatter.validate-problem.patch \
+           file://0022-PREPARE-FOR-Python-3.8-asyncio.coroutine-is-deprecat.patch \
+           file://0023-UPDATE-Add-755-info.patch \
+           file://0024-FIX-WARNING-Related-to-docstring-example-and-weird-b.patch \
+           file://0025-FIX-invalid-escape-sequence-warnings-w-regex-pattern.patch \
+           file://0026-DEPRECATING-CLEANUP-Move-deprecated-tag-matcher-clas.patch \
+           file://0027-Comment-tweaks.patch \
+           file://0028-FIX-warnings-related-to-invalid-escapes-in-regex.patch \
+           file://0029-Steps-catalog-should-not-break-configured-rerun-sett.patch \
+           file://0030-Add-feature-w-rules-and-failing-scenarios-enable-via.patch \
+           file://0031-examples-gherkin_v6-Tweak-ScenarioOutline-Examples-t.patch \
+           file://0032-Add-info-on-merged-pull-588.patch \
+           file://0033-Tweak-tests-required-by-pytest-5.0.patch \
+           file://0034-CLEANUP-Use-pytest-instead-of-nose-to-remove-nose.im.patch \
+           file://0035-REMOVE-DEPENDENCY-nose-to-avoid-nose.importer-warnin.patch \
+           file://0036-FIX-Remove-test-from-pytest-run.patch \
+           file://0037-Select-by-location-Add-support-for-Scenario-containe.patch \
+           file://0038-docs-Add-description-for-Select-by-location-for-Scen.patch \
+           file://0039-tests-Fix-warnings-for-python3.patch \
+           file://0040-Use-cucumber-tag-expressions-1.1.2-to-fix-warnings.patch \
+           file://0041-MENTION-ENHANCEMENT-Support-emojis-in-feature-files-.patch \
+           file://0042-FIX-Invalid-escape-char-in-regex-w-python3.patch \
+           file://0043-Example-related-to-question-in-756.patch \
+           file://0044-FIX-python3.8-regressions-on-CI-server.patch \
+           file://0045-UPDATE-Mark-issue-755-as-fixed.patch \
+           file://0046-UPDATE-Cucumber-gherkin-languages.json.patch \
+           file://0047-gherkin-Adding-Rule-keyword-translation-in-portugues.patch \
+           file://0048-Tweaks-to-update-generate-from-gherkin-languages.jso.patch \
+           file://0049-EXAMPLE-Tweak-naming-to-fixture.behave.no_background.patch \
+           file://0050-EXAMPLE-Cleanup-Gherkin-v6-README.patch \
+           file://0051-Improve-support-for-feature.background-inheritance-f.patch \
+           file://0052-Add-support-for-runtime-constraints.patch \
+           file://0053-Use-runtime-constraints.patch \
+           file://0054-CLEANUP-Remove-deprecated-parts.patch \
+           file://0055-CLEANUP-Remove-deprecated-parts.patch \
+           file://0056-more.features-Perform-more-Gherkin-v6-checks-and-run.patch \
+           file://0057-UTIL-Correct-URL-and-python-module-old-was-broken-no.patch \
+           file://0058-UTIL-Formatting-tweaks.patch \
+           file://0059-Fixed-a-bug-where-use_fixture_by_tag-didn-t-return-t.patch \
+           file://0060-Added-issue-unit-test.patch \
+           file://0061-Merge-pull-request-767-with-minor-tweaks.patch \
+           file://0062-CHECK-Issue-766-PrettyFormatter-UnicodeError.patch \
+           file://0063-FIX-issue-772-ScenarioOutline.Examples-without-table.patch \
+           file://0064-FIX-issue-772-ScenarioOutline.Examples-without-table.patch \
+           file://0065-Nibble-TravisCI-to-wake-up.patch \
+           file://0066-Tweak-pytest-version-selection.patch \
+           file://0067-Tweak-pytest-configuration-to-silence-JUnit-XML-dial.patch \
+           file://0068-Add-basic-feature-test-for-wildcard-pattern-matching.patch \
+           file://0069-UPDATE-dependencies-path.py-path-pytest.patch \
+           file://0070-pytest-Disable-DeprecatedWarning-from-distutils-pack.patch \
+           file://0071-CLEANUP-Add-ContextMode-enum-related-to-797.patch \
+           file://0072-Cleanup-comments.patch \
+           file://0073-FIX-sphinx-build-problem-async_steps3x.py.patch \
+           file://0074-docs-Rename-page-parse_expressions-was-parse_builtin.patch \
+           file://0075-docs-parse_expression-add-links-to-parse_type-module.patch \
+           file://0076-BUMP-VERSION-1.2.7.dev2-was-1.2.7.dev1.patch \
+           file://0077-Gherkin-parser-Cleanups-related-to-question-in-800-P.patch \
+           file://0078-Clarify-select-by-name-uses-regex-pattern-related-to.patch \
+           file://0079-FIX-Cross-reference-problem-copy-paste-in-Rule-class.patch \
+           file://0080-DOCS-Update-API-description-for-Runner-Operation.patch \
+           file://0081-FIX-DOCS-Runner-operations-typo.patch \
+           file://0082-issue-740-Enhancement-Context.add_cleanup-with-layer.patch \
+           file://0083-UPDATE-parse-1.18.0-parse-versions-1.16.0-.-1.17.x-h.patch \
+           file://0084-RELATED-TO-Duplicated-steps-AmbiguousStepErrors.patch \
+           file://0085-Add-renovate.json.patch \
+           file://0086-PRPEPARE-RENOVATE-With-adaptions.patch \
+           file://0087-Pin-dependencies.patch \
+           file://0088-renovate-Extend-pip-requirements-file-list.patch \
+           file://0089-PIN-REQUIREMENTS-Extend-to-all-places.patch \
+           file://0090-tasks-Add-invoke_cleanup-replaces-_tasklet_cleanup-r.patch \
+           file://0091-Docs-change-code-blocks-from-bash-to-console.patch \
+           file://0092-Fix-typo-in-tutorial.patch \
+           file://0093-py.requirements-Use-PyHamcrest-2.0-for-python2.7.patch \
+           file://0094-UPDATE-PR-877-was-merged.patch \
+           file://0095-capitalizing-steps.patch \
+           file://0096-FIX-invoke-task-develop.update-gherkin-that-aborted-.patch \
+           file://0097-Test-against-PowerPC-CPU-support-Travis-867.patch \
+           file://0098-Add-Context.attach-docs-and-test.patch \
+           file://0099-Add-Contributing-chapter.patch \
+           file://0100-Adapt-Tox-target-for-building-the-docs.patch \
+           file://0101-Mention-HTML-formatter-in-documentation.patch \
+           file://0102-Use-console-highlighting-for-pip-install-docs.patch \
+           file://0103-docs-fix-simple-typo-tuorial-tutorial.patch \
+           file://0104-Add-support-for-python3.9-by-using-active-tags.patch \
+           file://0105-PREFER-python3-from-now-on.patch \
+           file://0106-REMOVE-invoke-scripts.patch \
+           file://0107-FIX-Deprecated-warnings-for-Python-3.x.patch \
+           file://0108-FIX-Python2-problems-in-virtualenvs-w-behave4cmd0-st.patch \
+           file://0109-FIX-Active-tag-logic.patch \
+           file://0110-FIX-Tests-w-more.features.patch \
+           file://0111-FIX-Some-regressions-with-Python-3.9.patch \
+           file://0112-docs-Update-new-and-noteworthy.patch \
+           file://0113-Add-diagnostic-helper-function-to-print-the-current-.patch \
+           file://0114-UPDATE-i18n-gherkin-languages.json-from-cucumber-rep.patch \
+           file://0115-UPDATE-CHANGES-Related-to-PR-895-and-827.patch \
+           file://0116-FIX-CI-TRAVIS-For-python-2.7-builds-mock-4.0-only-fo.patch \
+           file://0117-Adds-the-ability-to-use-a-custom-runner-in-the-behav.patch \
+           file://0118-Allow-forcing-color-with-color-always.patch \
+           file://0119-Allow-color-with-no-value-followed-by-posarg.patch \
+           file://0120-Add-BEHAVE_COLOR-env-var.patch \
+           file://0121-fix-malformed-table-rows-warning.patch \
+           file://0122-FIX-955-setup-Remove-attribute-use_2to3.patch \
+           file://0123-Add-info-for-fixed-issue-955.patch \
+           "
 
 S = "${WORKDIR}/git"
 
@@ -16,3 +139,5 @@ RDEPENDS:${PN} += " \
     ${PYTHON_PN}-setuptools \
     ${PYTHON_PN}-six \
     "
+
+PV = "6"
-- 
2.25.1


[-- Attachment #3: bitbake-output-qemux86-64.txt --]
[-- Type: text/plain, Size: 6011 bytes --]

Loading cache...done.
Loaded 12618 entries from dependency cache.
Parsing recipes...done.
Parsing of 7305 .bb files complete (7302 cached, 3 parsed). 12567 targets, 310 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
NOTE: Resolving any missing task queue dependencies
NOTE: Resolving any missing task queue dependencies
NOTE: Resolving any missing task queue dependencies
NOTE: Resolving any missing task queue dependencies
NOTE: Resolving any missing task queue dependencies

Build Configuration (mc:default):
BB_VERSION           = "2.4.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "x86_64-poky-linux"
MACHINE              = "qemux86-64"
DISTRO               = "poky"
DISTRO_VERSION       = "4.2"
TUNE_FEATURES        = "m64 core2"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:a43fa36614977745fcbd6441d1c3c20321a8201d"
meta-oe              
meta-python          
meta-perl            = "tmp-auh-upgrades:402fc96d7b589d9e22aca46789f0320134cf223b"
workspace            = "<unknown>:<unknown>"


Build Configuration (mc:qemux86-musl):
BB_VERSION           = "2.4.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "x86_64-poky-linux-musl"
MACHINE              = "qemux86-64"
DISTRO               = "poky"
DISTRO_VERSION       = "4.2"
TUNE_FEATURES        = "m64 core2"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:a43fa36614977745fcbd6441d1c3c20321a8201d"
meta-oe              
meta-python          
meta-perl            = "tmp-auh-upgrades:402fc96d7b589d9e22aca46789f0320134cf223b"
workspace            = "<unknown>:<unknown>"


Build Configuration (mc:qemuarm64):
BB_VERSION           = "2.4.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "x86_64-poky-linux"
MACHINE              = "qemux86-64"
DISTRO               = "poky"
DISTRO_VERSION       = "4.2"
TUNE_FEATURES        = "m64 core2"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:a43fa36614977745fcbd6441d1c3c20321a8201d"
meta-oe              
meta-python          
meta-perl            = "tmp-auh-upgrades:402fc96d7b589d9e22aca46789f0320134cf223b"
workspace            = "<unknown>:<unknown>"

Initialising tasks...done.
Checking sstate mirror object availability...done.
Sstate summary: Wanted 261 Local 23 Mirrors 228 Missed 10 Current 156 (96% match, 97% complete)
NOTE: Executing Tasks
NOTE: Running task 1089 of 1443 (/home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_fetch)
NOTE: recipe python3-behave-6-r0: task do_fetch: Started
NOTE: recipe python3-behave-6-r0: task do_fetch: Succeeded
NOTE: Running task 1427 of 1443 (/home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_unpack)
NOTE: Running task 1428 of 1443 (/home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_prepare_recipe_sysroot)
NOTE: recipe python3-behave-6-r0: task do_unpack: Started
NOTE: recipe python3-behave-6-r0: task do_prepare_recipe_sysroot: Started
NOTE: recipe python3-behave-6-r0: task do_prepare_recipe_sysroot: Succeeded
NOTE: recipe python3-behave-6-r0: task do_unpack: Succeeded
NOTE: Running task 1429 of 1443 (/home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_patch)
NOTE: Running task 1430 of 1443 (/home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_collect_spdx_deps)
NOTE: recipe python3-behave-6-r0: task do_patch: Started
NOTE: recipe python3-behave-6-r0: task do_patch: Failed
NOTE: recipe python3-behave-6-r0: task do_collect_spdx_deps: Started
NOTE: recipe python3-behave-6-r0: task do_collect_spdx_deps: Succeeded
NOTE: Tasks Summary: Attempted 1430 tasks of which 1425 didn't need to be rerun and 1 failed.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 3 seconds
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 3 seconds
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 3 seconds

Summary: 1 task failed:
  /home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_patch
Summary: There was 1 ERROR message, returning a non-zero exit code.
ERROR: python3-behave-6-r0 do_patch: Applying patch '0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch' on target directory '/scratch1/auh/build-auh/tmp/work/core2-64-poky-linux/python3-behave/6-r0/git'
CmdError('quilt --quiltrc /scratch1/auh/build-auh/tmp/work/core2-64-poky-linux/python3-behave/6-r0/recipe-sysroot-native/etc/quiltrc push', 0, "stdout: Applying patch 0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch
can't find file to patch at input line 15
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|From b941f353c129f73934853082f3f3a01cebe6f944 Mon Sep 17 00:00:00 2001
|From: jenisys <jenisys@users.noreply.github.com>
|Date: Mon, 11 Mar 2019 22:37:04 +0100
|Subject: [PATCH] FIXES #725: ScenarioOutlineBuilder was not copying
| description to created Scenario.
|
|---
| behave/model.py | 1 +
| 1 file changed, 1 insertion(+)
|
|diff --git a/behave/model.py b/behave/model.py
|index 4ad4b9d..9dd68fd 100644
|--- a/behave/model.py
|+++ b/behave/model.py
--------------------------
No file to patch.  Skipping patch.
1 out of 1 hunk ignored
Patch 0001-FIXES-725-ScenarioOutlineBuilder-was-not-copying-des.patch does not apply (enforce with -f)

stderr: ")
ERROR: Logfile of failure stored in: /scratch1/auh/build-auh/tmp/work/core2-64-poky-linux/python3-behave/6-r0/temp/log.do_patch.448638
ERROR: Task (/home/auh/Projects/meta-openembedded/meta-python/recipes-devtools/python/python3-behave_1.2.6.bb:do_patch) failed with exit code '1'

             reply	other threads:[~2023-07-12  5:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-12  5:30 auh [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-07-31  5:08 [AUH] python3-behave: upgrading to 6 FAILED auh
2023-08-05  7:38 auh
2023-11-04  1:38 auh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230712053010.DA7C6C001DC@smtp.lore.kernel.org \
    --to=auh@moto-timo.dev \
    --cc=openembedded-devel@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox